Spaces:
Running
Running
| import Papa from "papaparse"; | |
| export async function loadExtensionsCSV(path, fetchOptions = {}) { | |
| const url = path + (path.includes("?") ? "&" : "?") + "t=" + Date.now(); | |
| const res = await fetch(url, fetchOptions); | |
| if (!res.ok) | |
| throw new Error(`Failed to load CSV: ${res.status} ${res.statusText}`); | |
| const text = await res.text(); | |
| const { data } = Papa.parse(text, { | |
| header: true, | |
| skipEmptyLines: true, | |
| transformHeader: (header) => header.trim(), | |
| }); | |
| return { rows: data.map(normalizeRow) }; | |
| } | |
| function normalizeRow(r) { | |
| const clone = { ...r }; | |
| // Normalize numeric fields | |
| clone.likes_count = safeNumber(r.likes_count || r.followers_count); | |
| clone.github_stars = safeNumber(r.github_stars); | |
| clone.reviews_count = safeNumber(r.reviews_count); | |
| clone.rating = safeNumber(r.rating || r.rating_average); | |
| clone.github_open_issues = safeNumber(r.github_open_issues); | |
| // Keep original name | |
| clone.name = r.name || r.title; | |
| // Other fields as is | |
| clone.tags = typeof r.tags === "string" ? r.tags : ""; | |
| clone.publisher = r.developed_by_name || r.publisher || "(unknown)"; | |
| return clone; | |
| } | |
| function safeNumber(v) { | |
| if (v === null || v === undefined || v === "") return 0; | |
| const cleaned = String(v).replace(/,/g, "").replace(/\s+/g, "").trim(); | |
| const n = Number(cleaned); | |
| return Number.isFinite(n) ? n : 0; | |
| } | |