#!/usr/bin/env bun import data from "./sources.json"; const leaningLabels: Record = { left: "left", "center-left": "center-left", center: "center", "center-right": "center-right", right: "right", state: "state-controlled", }; function escapeHtml(str: string): string { return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); } function generateNav(): string { const links = data.regions .map((r) => `${r.name}`) .join("\n "); return ``; } function generateCountry(country: { name: string; sources: Array<{ name: string; url: string; leaning: string; description: string }> }): string { const sources = country.sources .map((s) => { const leaningClass = s.leaning.replace("-", "-"); const leaningText = leaningLabels[s.leaning] || s.leaning; return `
${escapeHtml(s.name)} ${leaningText}
${escapeHtml(s.description)}
`; }) .join("\n"); return `

${escapeHtml(country.name)}

${sources}
`; } function generateRegion(region: { name: string; countries: Array<{ name: string; sources: Array<{ name: string; url: string; leaning: string; description: string }> }> }): string { const countries = region.countries.map(generateCountry).join("\n"); return `

${escapeHtml(region.name)}

${countries}
`; } function generateHtml(): string { const nav = generateNav(); const regions = data.regions.map(generateRegion).join("\n\n"); const totalSources = data.regions.reduce( (acc, r) => acc + r.countries.reduce((a, c) => a + c.sources.length, 0), 0 ); const totalCountries = data.regions.reduce((acc, r) => acc + r.countries.length, 0); return ` world news sources

world news sources

${totalSources} sources from ${totalCountries} countries

news from journalists in their own countries, not filtered through us media

${nav} ${regions} `; } const html = generateHtml(); await Bun.write("index.html", html); console.log("built index.html");