// Pré-rend les diagrammes Mermaid du guide (#105 PDF) en PNG. // Usage: node scripts/render_guide_diagram.mjs // Lit le(s) code(s) Mermaid via --input JSON {sha: code} et écrit // backend/assets/guide_diagrams/.png (rendu chromium + mermaid v11 CDN, // scale 2, fond blanc). import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import { createRequire } from 'module'; const require = createRequire(import.meta.url); const { chromium } = require('playwright'); const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, '..'); const OUT_DIR = path.join(ROOT, 'backend', 'assets', 'guide_diagrams'); (async () => { const jobs = JSON.parse(fs.readFileSync(process.argv[2], 'utf8')); // {sha: code} fs.mkdirSync(OUT_DIR, { recursive: true }); const browser = await chromium.launch(); const page = await browser.newPage({ viewport: { width: 1800, height: 1400 }, deviceScaleFactor: 2 }); await page.goto('about:blank'); await page.addScriptTag({ url: 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js' }); await page.waitForFunction(() => typeof window.mermaid !== 'undefined'); for (const [sha, code] of Object.entries(jobs)) { const out = await page.evaluate(async (src) => { window.mermaid.initialize({ startOnLoad: false, theme: 'default', securityLevel: 'loose', fontFamily: 'DejaVu Sans, Arial, sans-serif' }); try { const { svg } = await window.mermaid.render('d_' + Math.random().toString(36).slice(2), src); const box = document.createElement('div'); box.innerHTML = svg; box.style.background = 'white'; document.body.replaceChildren(box); const svgEl = box.querySelector('svg'); if (!svgEl) return { err: 'no svg' }; svgEl.style.maxWidth = 'none'; const r = svgEl.getBoundingClientRect(); return { w: Math.min(Math.ceil(r.width), 2000), h: Math.min(Math.ceil(r.height), 2600), ok: true }; } catch (e) { return { err: String(e).slice(0, 300) }; } }, code); if (out.err) { console.error(sha, 'RENDER ERROR', out.err); process.exitCode = 1; continue; } const file = path.join(OUT_DIR, sha + '.png'); await page.screenshot({ path: file, clip: { x: 0, y: 0, width: out.w, height: out.h } }); console.log(sha, '->', file, out.w + 'x' + out.h); } await browser.close(); })();