diff --git a/src/engine/parser.ts b/src/engine/parser.ts new file mode 100644 index 0000000..78731ac --- /dev/null +++ b/src/engine/parser.ts @@ -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); +} diff --git a/tests/parser.test.ts b/tests/parser.test.ts new file mode 100644 index 0000000..17c499e --- /dev/null +++ b/tests/parser.test.ts @@ -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(); + }); +});