// Appends a batch of new cards to a category file. // node tools/add-cards.mjs // The batch is a JSON array of cards. Ids must be new across ALL card files, and every card's // `category` must match. Existing cards are kept as they are. The file is rewritten in a compact // layout (small objects on one line). Run `go test ./server` afterwards for the full validation. import fs from "node:fs"; import { fileURLToPath } from "node:url"; import { format } from "./cardfmt.mjs"; const dir = fileURLToPath(new URL("../web/data/cards/", import.meta.url)); const [category, batchPath] = process.argv.slice(2); if (!category || !batchPath) { console.error("usage: node tools/add-cards.mjs "); process.exit(2); } const manifest = JSON.parse(fs.readFileSync(dir + "index.json", "utf8")).files; const file = `${category}.json`; if (!manifest.includes(file)) { console.error(`unknown category "${category}" (known: ${manifest.map((f) => f.replace(".json", "")).join(", ")})`); process.exit(2); } const existing = {}; const used = new Set(); for (const f of manifest) { existing[f] = JSON.parse(fs.readFileSync(dir + f, "utf8")); for (const c of existing[f]) used.add(c.id); } let batch; try { batch = JSON.parse(fs.readFileSync(batchPath, "utf8")); } catch (e) { console.error(`cannot read the batch: ${e.message}`); process.exit(1); } if (!Array.isArray(batch)) { console.error("the batch must be a JSON array of cards"); process.exit(1); } const problems = []; const seen = new Set(); for (const [i, c] of batch.entries()) { const who = c?.id ?? `#${i}`; if (!c?.id) problems.push(`${who}: missing id`); else if (used.has(c.id) || seen.has(c.id)) problems.push(`${who}: id already exists`); seen.add(c?.id); if (c?.category !== category) problems.push(`${who}: category must be "${category}"`); if (!c?.title || !c?.body || !c?.yes || !c?.no) problems.push(`${who}: needs title, body, yes and no`); } if (problems.length) { console.error("batch rejected, nothing written:\n " + problems.join("\n ")); process.exit(1); } const all = [...existing[file], ...batch]; fs.writeFileSync(dir + file, `${format(all)}\n`); console.log(`${file}: +${batch.length} cards, ${all.length} in total`);