import {readdirSync, readFileSync, writeFileSync, mkdirSync, copyFileSync, renameSync, rmSync} from 'node:fs'; import {join} from 'node:path'; import {execFileSync} from 'node:child_process'; const cli = 'vendor/archify/bin/archify.mjs'; const types = new Set(['architecture','workflow','sequence','dataflow','lifecycle']); const inlineStyles = readFileSync(new URL('./inline-viewer.css', import.meta.url), 'utf8'); const themeBridge = readFileSync(new URL('./viewer-theme-bridge.js', import.meta.url), 'utf8'); // This directory is generated-only and ignored by Git. Remove stale artifacts. rmSync('static/diagrams', {recursive: true, force: true}); mkdirSync('static/diagrams', {recursive: true}); mkdirSync('.cache/archify', {recursive: true}); const names = new Set(); for (const file of readdirSync('diagrams').sort()) { const match = /^([a-z0-9]+(?:-[a-z0-9]+)*)\.([a-z]+)\.json$/.exec(file); if (!match || !types.has(match[2])) throw new Error(`Unsupported diagram source: ${file}`); const [,name,type] = match; if (names.has(name)) throw new Error(`Duplicate diagram output: ${name}`); names.add(name); const input = join('diagrams',file); const spec = JSON.parse(readFileSync(input,'utf8')); const output = `static/diagrams/${name}/index.html`; mkdirSync(`static/diagrams/${name}`, {recursive: true}); if (spec.diagram_type !== type || spec.meta.output !== output) throw new Error(`Diagram type/output mismatch: ${file}`); const run = args => execFileSync(process.execPath,[cli,...args],{stdio:'inherit',env:{...process.env,ARCHIFY_UPDATE_CHECK_DISABLED:'1'}}); run(['validate',type,input,'--quality','showcase','--json']); run(['deliver',type,input,output,'--quality','showcase','--json']); run(['check',output,'--json','--require-provenance']); // Verify the upstream artifact first, then add the scoped portal integration. let viewer = readFileSync(output, 'utf8'); // Upstream intentionally disables preset selection in gallery embeds. Enable // only those two guards; fail closed if a future vendor update changes them. const start = viewer.indexOf('Archify.preset = (function () {'); const end = viewer.indexOf('Archify.theme = (function () {', start); const preset = viewer.slice(start, end); const guard = "if (html.getAttribute('data-embed') === 'true') return false;"; if (start < 0 || end < start || preset.split(guard).length !== 3) throw new Error('Archify preset integration drift'); viewer = viewer.slice(0, start) + preset.replaceAll(guard, '') + viewer.slice(end); if (!viewer.includes('') || !viewer.includes('')) throw new Error(`Invalid viewer: ${output}`); writeFileSync(output, viewer.replace('', ``) .replace('', ``)); renameSync(`static/diagrams/${name}/index.delivery.json`, `.cache/archify/${name}.delivery.json`); } copyFileSync('vendor/archify/LICENSE','static/diagrams/ARCHIFY-LICENSE.txt'); copyFileSync('vendor/archify/THIRD_PARTY_NOTICES.md','static/diagrams/THIRD-PARTY-NOTICES.md');