#!/usr/bin/env node // Site build for the delivery-arc page (CSP-clean: script-src 'self', no inline JS). // Reads pilot/arc.tpl.html, splits the app "); if (i < 0 || j < i) throw new Error("app script block not found"); let app = tpl.slice(i + 8, j) .replace("__MAN_DOCKER__", man("docker")) .replace("__MAN_CLUSTER__", man("cluster")) .replace("__MAN_GITOPS__", man("gitops")) .replace("__MAN_SUPPLY__", man("supply")) .replace("__MAN_HELM__", man("helm")); let body = tpl.slice(0, i) + tpl.slice(j + 9); const heroes = { __HERO_DOCKER__: "docker-layers.webp", __HERO_CLUSTER__: "course-II-cluster.webp", __HERO_GITOPS__: "course-VI-gitops.webp", __HERO_SUPPLY__: "course-VII-supply-chain.webp", __HERO_HELM__: "course-VIII-helm-press.webp", __HERO_APPENDIX__: "appendix-dependency-ledger.webp", }; // content-fingerprint everything under /assets/ (immutable-cached by nginx): a fresh // index.html can then never pair with a stale script or image from a previous deploy. mkdirSync(join(DIST, "assets"), { recursive: true }); const fp = buf => createHash("sha256").update(buf).digest("hex").slice(0, 8); const emit = (srcPath, base, ext) => { const buf = readFileSync(srcPath); const name = `${base}.${fp(buf)}.${ext}`; writeFileSync(join(DIST, "assets", name), buf); return "/assets/" + name; }; for (const [ph, file] of Object.entries(heroes)) { const base = file.replace(/\.webp$/, ""); body = body.replace(ph, emit(join(ROOT, "assets/dist", file), base, "webp")); } body = body.replace("__DIAG_FLOW__", emit(join(ROOT, "assets/dist/delivery-flow.svg"), "delivery-flow", "svg")); if (body.includes("__HERO_") || body.includes("__DIAG_") || app.includes("__MAN_")) throw new Error("unfilled placeholder"); const favicon = "data:image/svg+xml," + encodeURIComponent( ``); const gsapRef = emit(join(ROOT, "gsap.min.js"), "gsap.min", "js"); const stRef = emit(join(ROOT, "st.min.js"), "st.min", "js"); const appName = `arc.${fp(app)}.js`; writeFileSync(join(DIST, "assets", appName), app); const appRef = "/assets/" + appName; const html = ` The Exploded Cluster ${body} `; writeFileSync(join(DIST, "index.html"), html); // CSP gate: no inline