export const thIgnore = [ "🎹Worst Comps & Edits", "🎹 Yedits", "🎹 Comps & Edits", "Comps & Edits", "Worst Comps & Edits", "Yedits", "AI Models", "🎹 BPM & Key Tracker", "🎹Comps & Edits", "🎹 Worst Comps & Edits", "Allegations", "Rap Disses Timeline", "Underground Artists", "bpmkeytracker", ] export function jsonToCsv(data: unknown|unknown[]) { const arr = Array.isArray(data) ? data : [data]; const headers = [...new Set(arr.flatMap(o => Object.keys(o)))]; const escape = (v: string )=> `"${String(v ?? "").replace(/"/g, '""')}"`; const rows = arr.map(o => headers.map(h => escape(o[h])).join(",") ); return [headers.join(","), ...rows].join("\n"); } export enum TripleBool { MOSTLY = 2, YES = 1, NO = 0 } export interface Entry { name: string, url: string, credit: string, updated: TripleBool, links_work: TripleBool, best: boolean }; export type Change = | { op: "delete"; name: string } | { op: "create"; name: string; item: Entry } | { op: "update"; name: string; changes: Partial }; const TripleBoolStrings: Record = { [TripleBool.MOSTLY]: "Mostly", [TripleBool.YES]: "Yes", [TripleBool.NO]: "No", }; export function tripleBoolToString(v: TripleBool): string { return TripleBoolStrings[v]; } export function tripleBool(bool: string): TripleBool { if(bool.toLowerCase() == "mostly") { return TripleBool.MOSTLY; } else if(bool.toLowerCase() == "yes") { return TripleBool.YES } else if(bool.toLowerCase() == "no") { return TripleBool.NO } throw new Error("tripleBool conversion function errored, mysteriously! Passed in: " + bool) } export function prettyStringify(z: unknown) { return JSON.stringify(z, null, 2).replace(/\n {2}"/g, ' "').replace(/\n}/, " }") } export function requireBasicAuth(req: Request): Response | null { const auth = req.headers.get("authorization"); if (!auth || !auth.startsWith("Basic ")) { return new Response("Auth required", { status: 401, headers: { "WWW-Authenticate": 'Basic realm="acx-sheets"' } }); } const decoded = Buffer.from(auth.slice(6), "base64").toString("utf8"); const [user, pass] = decoded.split(":"); if ( user !== process.env.MERGE_USER || pass !== process.env.MERGE_PASS ) { return new Response("Forbidden", { status: 403 }); } return null; } export function ndjsonToJson(ndjson: string): unknown[] { return ndjson.split("\n").map(z => { try { return JSON.parse(z) } catch { return undefined; } }).filter(Boolean); }