// emit.mjs — project the engine's deploy adapter into a target dir. // // node engine/emit.mjs // e.g. node engine/emit.mjs cloudflare site-instruments // // Rule (uniform for every generated file): READ the target for its per-target // values, then REBUILD all adapter files from the plugin templates carrying // those values. Structural template changes propagate to every target on the // next run; hand-added values (name/TITLE) survive because they're read back // out of the target. content/ is AUTHORED — never generated, never touched. import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "node:fs"; import { join, dirname } from "node:path"; import { fileURLToPath } from "node:url"; import { execFileSync } from "node:child_process"; const ENGINE = dirname(fileURLToPath(import.meta.url)); // .../engine const [target, dir] = process.argv.slice(2); if (!target || !dir) { console.error("usage: node engine/emit.mjs "); process.exit(1); } const plugin = join(ENGINE, target); if (!existsSync(plugin)) { console.error(`no deploy plugin '${target}' (expected ${plugin}/)`); process.exit(1); } // --- read per-target values out of the existing target (preserve across rebuild) --- const tomlPath = join(dir, "wrangler.toml"); const prior = existsSync(tomlPath) ? readFileSync(tomlPath, "utf8") : ""; const NAME = (prior.match(/^name\s*=\s*"([^"]*)"/m) || [])[1] || "{{NAME}}"; const TITLE = (prior.match(/TITLE\s*=\s*"([^"]*)"/m) || [])[1] || "{{TITLE}}"; // --- regenerate every adapter file from templates, injecting preserved values --- mkdirSync(join(dir, "content"), { recursive: true }); // ensure authored dir exists (untouched if present) const fill = s => s.replaceAll("{{NAME}}", NAME).replaceAll("{{TITLE}}", TITLE); for (const f of readdirSync(plugin)) { const out = f === "gitignore" ? ".gitignore" : f; // stored dotless in the plugin; dotted in the target writeFileSync(join(dir, out), fill(readFileSync(join(plugin, f), "utf8"))); } // --- manifest from authored content (gen owns _manifest.js; content is read-only to us) --- execFileSync("node", [join(ENGINE, "gen.mjs"), "--src", "content", "--target", "_manifest.js"], { cwd: dir, stdio: "inherit" }); // --- first-scaffold notice: values with no prior source stay as placeholders --- const todo = []; if (NAME === "{{NAME}}") todo.push("name"); if (TITLE === "{{TITLE}}") todo.push("TITLE"); console.log(`emit: ${target} → ${dir}/ (adapter files regenerated)`); if (todo.length) console.log(` fill in ${todo.join(" and ")} in ${dir}/wrangler.toml before deploy`);