Render documentation diagrams as static Mermaid assets
This commit is contained in:
80
docs/scripts/render-mermaid-assets.mjs
Normal file
80
docs/scripts/render-mermaid-assets.mjs
Normal file
@@ -0,0 +1,80 @@
|
||||
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { diagramSources } from '../.vitepress/theme/components/diagramSources.ts';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const docsRoot = path.resolve(__dirname, '..');
|
||||
const publicRoot = path.join(docsRoot, 'public');
|
||||
const diagramsDir = path.join(publicRoot, 'diagrams');
|
||||
const prototypesDir = path.join(publicRoot, 'prototypes');
|
||||
const puppeteerConfig = path.join(__dirname, 'puppeteer-config.json');
|
||||
const mermaidConfig = path.join(__dirname, 'mermaid-config.json');
|
||||
|
||||
const prototypeNames = new Set([
|
||||
'dashboard',
|
||||
'catalog-grid',
|
||||
'product-card',
|
||||
'cart',
|
||||
'client-order',
|
||||
'bonus-cabinet',
|
||||
'manager-order',
|
||||
'manager-orders',
|
||||
]);
|
||||
|
||||
function runCommand(command, args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(command, args, {
|
||||
cwd: docsRoot,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
child.on('exit', (code) => {
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
reject(new Error(`${command} ${args.join(' ')} exited with code ${code ?? 'unknown'}`));
|
||||
});
|
||||
|
||||
child.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
async function renderDiagram(name, source) {
|
||||
const targetDir = prototypeNames.has(name) ? prototypesDir : diagramsDir;
|
||||
const tmpDir = await mkdtemp(path.join(os.tmpdir(), `mermaid-${name}-`));
|
||||
const inputFile = path.join(tmpDir, `${name}.mmd`);
|
||||
const outputFile = path.join(targetDir, `${name}.svg`);
|
||||
|
||||
try {
|
||||
await writeFile(inputFile, source, 'utf8');
|
||||
await runCommand('pnpm', [
|
||||
'exec',
|
||||
'mmdc',
|
||||
'-i',
|
||||
inputFile,
|
||||
'-o',
|
||||
outputFile,
|
||||
'-b',
|
||||
'transparent',
|
||||
'-c',
|
||||
mermaidConfig,
|
||||
'-p',
|
||||
puppeteerConfig,
|
||||
]);
|
||||
} finally {
|
||||
await rm(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
await mkdir(diagramsDir, { recursive: true });
|
||||
await mkdir(prototypesDir, { recursive: true });
|
||||
|
||||
for (const [name, source] of Object.entries(diagramSources)) {
|
||||
await renderDiagram(name, source);
|
||||
}
|
||||
Reference in New Issue
Block a user