mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 04:06:42 +00:00
Every role README carries a ```mermaid flowchart and the documentation showed it as source. A post-transform now replaces those literal blocks with <pre class="mermaid"> in html builds, which the runtime picks up; every other builder keeps the fence as it was. sphinxcontrib-mermaid injects an inline init script, which this deployment's CSP refuses, so the runtime and its initialisation are two linked files instead: mermaid-init.js calls mermaid.initialize with securityLevel strict and follows the reader's colour scheme. The diagram source is html-escaped before it is embedded, or an & or < in a node label would break the page. The runtime is fetched at image build time through ADD --checksum, so a changed upstream file fails the build rather than shipping. Version and digest are not ARG defaults, which test_arg_without_default forbids; they travel meta/services.yml -> vars/main.yml -> compose.yml.j2 the way DOCS_IMAGE and DOCS_VERSION already do, and an update block registers the pin with the npm version watcher instead of exempting it. Verified by building a page with sphinx: the diagram arrives as <pre class="mermaid"> with its source escaped, a bash fence stays a highlighted block, and both scripts are linked. A missing mermaid.min.js does not fail that build, so a local run without the image stays green. scripts/lint/mermaid.sh keeps validating diagram syntax through mmdc, which npm installs unpinned. It therefore checks against a newer mermaid than the 11.4.1 readers get, and a diagram using syntax from in between would pass the lint and render blank. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
54 lines
1.4 KiB
JavaScript
54 lines
1.4 KiB
JavaScript
const test = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const fs = require("node:fs");
|
|
const path = require("node:path");
|
|
const vm = require("node:vm");
|
|
|
|
const SOURCE = path.join(
|
|
__dirname,
|
|
"..", "..", "..", "..", "..", "..",
|
|
"roles", "web-app-docs", "files", "javascript", "mermaid-init.js",
|
|
);
|
|
|
|
function run({ mermaid, dark }) {
|
|
const context = {
|
|
window: {
|
|
mermaid,
|
|
matchMedia: (query) => ({ matches: dark && query.includes("dark") }),
|
|
},
|
|
};
|
|
context.window.window = context.window;
|
|
vm.runInNewContext(fs.readFileSync(SOURCE, "utf8"), context);
|
|
return context;
|
|
}
|
|
|
|
function recorder() {
|
|
const calls = [];
|
|
return { initialize: (options) => calls.push(options), calls };
|
|
}
|
|
|
|
test("it initializes mermaid once the runtime is present", () => {
|
|
const mermaid = recorder();
|
|
|
|
run({ mermaid, dark: false });
|
|
|
|
assert.equal(mermaid.calls.length, 1);
|
|
assert.equal(mermaid.calls[0].startOnLoad, true);
|
|
assert.equal(mermaid.calls[0].securityLevel, "strict");
|
|
});
|
|
|
|
test("it follows the reader's colour scheme", () => {
|
|
const light = recorder();
|
|
const dark = recorder();
|
|
|
|
run({ mermaid: light, dark: false });
|
|
run({ mermaid: dark, dark: true });
|
|
|
|
assert.equal(light.calls[0].theme, "default");
|
|
assert.equal(dark.calls[0].theme, "dark");
|
|
});
|
|
|
|
test("it stays silent when the runtime failed to load", () => {
|
|
assert.doesNotThrow(() => run({ mermaid: undefined, dark: false }));
|
|
});
|