feat: add YAML template parser

This commit is contained in:
Developer 2026-02-12 07:57:27 +00:00
parent 72b1d357e8
commit c561dae461
2 changed files with 93 additions and 0 deletions

26
src/engine/parser.ts Normal file
View 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
View 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();
});
});