fix(diagram): accept bom specs in artifact cli

This commit is contained in:
aliyun1121003339 2026-07-05 15:45:01 +08:00
parent 66a6609b0f
commit be3130efb2
4 changed files with 40 additions and 3 deletions

View file

@ -9,7 +9,7 @@ topic: diagram-artifact-export-cli
`scripts/export-diagram-artifact.js` is the offline CLI boundary for the diagram figure work that came from the Cloudy-style technical-diagram reference and the Drawnix reference spike.
It accepts a checked `DiagramSpec` JSON file and writes one artifact without requiring Obsidian, `obsidian-cli`, diagrams.net Desktop, Drawnix, Plait, or a browser runtime.
It accepts a checked `DiagramSpec` JSON file and writes one artifact without requiring Obsidian, `obsidian-cli`, diagrams.net Desktop, Drawnix, Plait, or a browser runtime. The input may be UTF-8 with or without a BOM, which keeps files produced by Windows PowerShell usable without a separate normalization step.
```bash
npm run diagram:export-artifact -- --input spec.json --target editable-html-svg --output figure.html

View file

@ -9,7 +9,7 @@ topic: diagram-artifact-export-cli
`scripts/export-diagram-artifact.js` 是图形扩展工作的离线 CLI 边界,覆盖 Cloudy 风格技术图参考与 Drawnix 参考 spike 产生的 artifact 导出需求。
它读取已验证结构的 `DiagramSpec` JSON 文件,并写出一个 artifact不需要 Obsidian、`obsidian-cli`、diagrams.net Desktop、Drawnix、Plait 或浏览器运行时。
它读取已验证结构的 `DiagramSpec` JSON 文件,并写出一个 artifact不需要 Obsidian、`obsidian-cli`、diagrams.net Desktop、Drawnix、Plait 或浏览器运行时。输入文件可以是带 BOM 或不带 BOM 的 UTF-8这样 Windows PowerShell 生成的 JSON 不需要额外归一化也能直接使用。
```bash
npm run diagram:export-artifact -- --input spec.json --target editable-html-svg --output figure.html

View file

@ -79,7 +79,8 @@ function assertSupportedTarget(target) {
}
function loadDiagramSpec(inputPath) {
return JSON.parse(fs.readFileSync(inputPath, 'utf8'));
const source = fs.readFileSync(inputPath, 'utf8').replace(/^\uFEFF/, '');
return JSON.parse(source);
}
function ensureOutputDirectory(outputPath) {

View file

@ -50,6 +50,8 @@ describe('diagram artifact export CLI', () => {
expect(runbook).toContain('DiagramSpec');
expect(runbook).toContain('SemanticFigureModel');
expect(runbook).toContain('no Obsidian runtime');
expect(runbook).toContain('UTF-8');
expect(runbook).toContain('BOM');
}
});
@ -125,6 +127,40 @@ describe('diagram artifact export CLI', () => {
}
}, 30000);
test('accepts UTF-8 BOM DiagramSpec files produced by Windows PowerShell', () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'notemd-diagram-artifact-cli-bom-'));
const specPath = path.join(tempRoot, 'spec.json');
const outputPath = path.join(tempRoot, 'figure.drawio');
fs.writeFileSync(specPath, `\uFEFF${JSON.stringify(createSpec(), null, 2)}`, 'utf8');
try {
const stdout = execFileSync(
process.execPath,
[
scriptPath,
'--input', specPath,
'--target', 'drawio',
'--output', outputPath
],
{
cwd: repoRoot,
encoding: 'utf8'
}
);
const result = JSON.parse(stdout);
expect(result).toEqual(expect.objectContaining({
target: 'drawio',
outputPath,
nodeCount: 3,
edgeCount: 2
}));
expect(fs.readFileSync(outputPath, 'utf8')).toContain('<mxfile');
} finally {
fs.rmSync(tempRoot, { recursive: true, force: true });
}
}, 30000);
test('fails before writing output for unsupported targets', () => {
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'notemd-diagram-artifact-cli-bad-target-'));
const specPath = path.join(tempRoot, 'spec.json');