import { mkdir, writeFile } from "node:fs/promises"; const blogs = [ ["research", "research"], ["vibes", "vibes"], ["puzzles", "puzzles"], ["reflections", "reflections"], ["poetry", "poetry"], ["reviews", "reviews"], ["art", "art"], ]; const rssHostSuffix = process.env.RSS_HOST_SUFFIX ?? "neeldhara.email"; const outDir = new URL("../dist/", import.meta.url); function decodeXml(value) { return value .replace(/'/g, "'") .replace(/"/g, '"') .replace(/>/g, ">") .replace(/</g, "<") .replace(/&/g, "&"); } function escapeHtml(value) { return value .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); } function textFrom(block, tag) { const match = block.match(new RegExp(`<${tag}[^>]*>([\\s\\S]*?)`, "i")); return match ? decodeXml(match[1].trim()) : ""; } function parseItems(xml) { return [...xml.matchAll(/([\s\S]*?)<\/item>/gi)].slice(0, 2).map((match) => { const block = match[1]; const pubDate = new Date(textFrom(block, "pubDate")); return { title: textFrom(block, "title"), link: textFrom(block, "link"), date: Number.isNaN(pubDate.valueOf()) ? "" : pubDate.toISOString().slice(0, 10), }; }); } async function getPosts(slug) { const url = `https://${slug}.${rssHostSuffix}/rss.xml`; const response = await fetch(url); if (!response.ok) { throw new Error(`${url} returned ${response.status}`); } return parseItems(await response.text()); } function renderPost(post) { const date = post.date ? `${escapeHtml(post.date)} ` : ""; return `
  • ${date}${escapeHtml(post.title)}
  • `; } function renderBlog([slug, label], posts) { return `
  • ${escapeHtml(label)}
  • `; } const entries = await Promise.all( blogs.map(async (blog) => [blog, await getPosts(blog[0])]), ); const html = ` neeldhara.blog

    neeldhara.blog

    `; await mkdir(outDir, { recursive: true }); await writeFile(new URL("index.html", outDir), html);