feat: add YAML template parser
This commit is contained in:
parent
72b1d357e8
commit
c561dae461
26
src/engine/parser.ts
Normal file
26
src/engine/parser.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import YAML from 'js-yaml';
|
||||||
|
import type { Template } from '../types/template';
|
||||||
|
|
||||||
|
export function parseTemplate(yamlContent: string): Template {
|
||||||
|
try {
|
||||||
|
const parsed = YAML.load(yamlContent) as any;
|
||||||
|
|
||||||
|
// 基础验证
|
||||||
|
if (!parsed.name || !parsed.id) {
|
||||||
|
throw new Error('Template must have name and id');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(parsed.blocks)) {
|
||||||
|
throw new Error('Template must have blocks array');
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed as Template;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Failed to parse template: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadTemplate(filePath: string): Template {
|
||||||
|
const content = Bun.file(filePath).text();
|
||||||
|
return parseTemplate(content);
|
||||||
|
}
|
||||||
67
tests/parser.test.ts
Normal file
67
tests/parser.test.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { describe, it, expect } from 'bun:test';
|
||||||
|
import { parseTemplate } from '../src/engine/parser';
|
||||||
|
|
||||||
|
describe('Template Parser', () => {
|
||||||
|
it('should parse simple text template', () => {
|
||||||
|
const yaml = `
|
||||||
|
name: "Test Template"
|
||||||
|
id: "test"
|
||||||
|
width: 80mm
|
||||||
|
blocks:
|
||||||
|
- type: text
|
||||||
|
content: "Hello World"
|
||||||
|
align: center
|
||||||
|
`;
|
||||||
|
const template = parseTemplate(yaml);
|
||||||
|
expect(template.name).toBe('Test Template');
|
||||||
|
expect(template.blocks).toHaveLength(1);
|
||||||
|
expect(template.blocks[0].type).toBe('text');
|
||||||
|
expect((template.blocks[0] as any).content).toBe('Hello World');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse row with columns', () => {
|
||||||
|
const yaml = `
|
||||||
|
name: "Row Test"
|
||||||
|
id: "row-test"
|
||||||
|
width: 80mm
|
||||||
|
blocks:
|
||||||
|
- type: row
|
||||||
|
columns:
|
||||||
|
- content: "Left"
|
||||||
|
align: left
|
||||||
|
width: 50%
|
||||||
|
- content: "Right"
|
||||||
|
align: right
|
||||||
|
width: 50%
|
||||||
|
`;
|
||||||
|
const template = parseTemplate(yaml);
|
||||||
|
const row = template.blocks[0] as any;
|
||||||
|
expect(row.type).toBe('row');
|
||||||
|
expect(row.columns).toHaveLength(2);
|
||||||
|
expect(row.columns[0].align).toBe('left');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse list with item template', () => {
|
||||||
|
const yaml = `
|
||||||
|
name: "List Test"
|
||||||
|
id: "list-test"
|
||||||
|
width: 80mm
|
||||||
|
blocks:
|
||||||
|
- type: list
|
||||||
|
data: "{{items}}"
|
||||||
|
itemTemplate:
|
||||||
|
- type: text
|
||||||
|
content: "{{name}}"
|
||||||
|
`;
|
||||||
|
const template = parseTemplate(yaml);
|
||||||
|
const list = template.blocks[0] as any;
|
||||||
|
expect(list.type).toBe('list');
|
||||||
|
expect(list.data).toBe('{{items}}');
|
||||||
|
expect(list.itemTemplate).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw on invalid YAML', () => {
|
||||||
|
const yaml = 'invalid: [unclosed';
|
||||||
|
expect(() => parseTemplate(yaml)).toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user