// Saves the staged post files in content/blog through savePost, one at a time. // Idempotent: unchanged posts are left alone, and a post edited in the // database since its last seed is skipped unless --force. // // pnpm blog:seed every file // pnpm blog:seed --only a,b just those slugs // pnpm blog:seed --force overwrite database edits import { listPostFiles, readPostFile } from "@/lib/blog/files"; import { savePost } from "@/lib/blog/write"; const args = process.argv.slice(2); const only = args.includes("--only") ? args[args.indexOf("--only") + 1]?.split(",") : null; const force = args.includes("--force"); async function revalidate() { const url = process.env.BLOG_REVALIDATE_URL; const secret = process.env.BLOG_REVALIDATE_SECRET; if (!url || !secret) { console.log( "BLOG_REVALIDATE_URL or BLOG_REVALIDATE_SECRET not set: pages refresh on the next deploy", ); return; } const res = await fetch(url, { method: "POST", headers: { Authorization: `Bearer ${secret}` }, }); console.log(`revalidate ${url}: ${res.status}`); } async function main() { const slugs = listPostFiles().filter((s) => !only || only.includes(s)); if (only) for (const s of only) if (!slugs.includes(s)) throw new Error(`no file content/blog/${s}.md`); const counts: Record = {}; let failed = 0; for (const slug of slugs) { try { const result = await savePost(readPostFile(slug), { force }); counts[result.outcome] = (counts[result.outcome] ?? 0) + 1; if (result.outcome !== "unchanged") console.log(`${result.outcome.padEnd(15)} ${slug}`); } catch (e) { failed += 1; console.error( `FAILED ${slug}\n${e instanceof Error ? e.message : e}`, ); } } console.log( `\n${slugs.length} files: ${Object.entries(counts) .map(([k, v]) => `${v} ${k}`) .join(", ")}${failed ? `, ${failed} failed` : ""}`, ); if (Object.keys(counts).some((k) => k !== "unchanged")) await revalidate(); if (failed) process.exit(1); } main().catch((e) => { console.error(e); process.exit(1); });