This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
Expand file tree
/
Copy pathverify.ts
More file actions
70 lines (62 loc) · 2.78 KB
/
Copy pathverify.ts
File metadata and controls
70 lines (62 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/* Standalone functional verification (run with tsx — no vitest infra needed). */
import assert from 'node:assert/strict';
import { compile, generateDts, manifestFromConfigs } from './src/index.ts';
const manifest = manifestFromConfigs([
{ type: 'flex', namespace: 'ui', isContainer: true, inputs: [
{ name: 'direction', type: 'enum', enum: ['row', 'col'] },
{ name: 'gap', type: 'number' },
{ name: 'wrap', type: 'boolean' },
{ name: 'children', type: 'slot' },
] },
{ type: 'card', namespace: 'ui', isContainer: true, inputs: [{ name: 'title', type: 'string' }, { name: 'children', type: 'slot' }] },
{ type: 'object-table', namespace: 'plugin-grid', isContainer: false, inputs: [
{ name: 'object', type: 'string', required: true, binding: 'object' },
{ name: 'columns', type: 'array' },
{ name: 'pageSize', type: 'number' },
] },
]);
const check = (_name: string, fn: () => void) => {
fn();
};
check('compiles valid JSX → tree + requires + bindings', () => {
const r = compile(
`<flex direction="row" gap={4} wrap>
<object-table object="account" columns={["name","amount"]} pageSize={25} />
</flex>`,
manifest,
);
assert.equal(r.ok, true);
assert.deepEqual(r.diagnostics, []);
assert.equal(r.tree?.type, 'flex');
assert.equal((r.tree as any).gap, 4);
assert.equal((r.tree as any).wrap, true);
assert.deepEqual(r.requires.sort(), ['plugin-grid', 'ui']);
assert.deepEqual(r.bindings, [{ tag: 'object-table', input: 'object', kind: 'object', value: 'account' }]);
});
check('rejects unknown component via whitelist', () => {
const r = compile(`<flex><script>alert(1)</script></flex>`, manifest);
assert.equal(r.ok, false);
assert.ok(r.diagnostics.some((d) => d.code === 'forbidden-tag'));
});
check('flags missing required prop', () => {
const r = compile(`<object-table columns={[]} />`, manifest);
assert.equal(r.ok, false);
assert.ok(r.diagnostics.some((d) => d.code === 'missing-required-prop'));
});
check('flags illegal enum + coarse type mismatch', () => {
const r = compile(`<flex direction="diagonal" gap="big" />`, manifest);
const codes = r.diagnostics.map((d) => d.code);
assert.ok(codes.includes('invalid-enum'));
assert.ok(codes.includes('type-mismatch'));
});
check('rejects event handlers + raw-html injection', () => {
const r = compile(`<card onClick="steal()" dangerouslySetInnerHTML={{}} />`, manifest);
assert.equal(r.diagnostics.filter((d) => d.code === 'forbidden-attr').length, 2);
});
check('codegen emits a JSX.IntrinsicElements augmentation', () => {
const dts = generateDts(manifest);
assert.ok(dts.includes('"object-table": ObjectTableProps;'));
assert.ok(dts.includes('object: string;'));
assert.ok(dts.includes('pageSize?: number;'));
assert.ok(dts.includes('direction?: "row" | "col";'));
});