codegen.test.ts86 lines · main
1import { test } from 'node:test';
2import { strict as assert } from 'node:assert';
3
4import { generate, type SchemaSnapshot } from './codegen.js';
5
6test('generate emits dataModel.d.ts with Doc<T> for each table', () => {
7 const snapshot: SchemaSnapshot = {
8 version: 1,
9 tables: {
10 notes: {
11 columns: {
12 id: { sqlType: 'text', nullable: false, primaryKey: true, unique: false },
13 body: { sqlType: 'text', nullable: false, primaryKey: false, unique: false },
14 archived: { sqlType: 'boolean', nullable: true, primaryKey: false, unique: false },
15 },
16 indexes: [],
17 },
18 },
19 };
20 const out = generate(snapshot, []);
21 const dm = out.get('briven/_generated/dataModel.d.ts');
22 assert.ok(dm, 'dataModel.d.ts must be emitted');
23 assert.match(dm, /export interface Notes \{/);
24 assert.match(dm, /id: string;/);
25 assert.match(dm, /body: string;/);
26 assert.match(dm, /archived: boolean \| null;/);
27 assert.match(dm, /export type Doc<T extends keyof Tables> = Tables\[T\];/);
28});
29
30test('generate emits api.ts with imports + typed api object', () => {
31 const snapshot: SchemaSnapshot = { version: 1, tables: {} };
32 const out = generate(snapshot, ['listNotes.ts', 'createNote.ts']);
33 const api = out.get('briven/_generated/api.ts');
34 assert.ok(api, 'api.ts must be emitted');
35 assert.match(api, /import listNotes from '\.\.\/functions\/listNotes\.js';/);
36 assert.match(api, /import createNote from '\.\.\/functions\/createNote\.js';/);
37 assert.match(api, /export const api = \{/);
38 assert.match(api, / {2}listNotes,/);
39 assert.match(api, / {2}createNote,/);
40});
41
42test('generate maps every supported sql type to TS', () => {
43 const snapshot: SchemaSnapshot = {
44 version: 1,
45 tables: {
46 t: {
47 columns: {
48 a: { sqlType: 'text', nullable: false, primaryKey: true, unique: false },
49 b: { sqlType: 'integer', nullable: false, primaryKey: false, unique: false },
50 c: { sqlType: 'bigint', nullable: false, primaryKey: false, unique: false },
51 d: { sqlType: 'boolean', nullable: false, primaryKey: false, unique: false },
52 e: { sqlType: 'timestamptz', nullable: false, primaryKey: false, unique: false },
53 f: { sqlType: 'jsonb', nullable: false, primaryKey: false, unique: false },
54 g: { sqlType: 'uuid', nullable: false, primaryKey: false, unique: false },
55 h: { sqlType: 'varchar(255)', nullable: false, primaryKey: false, unique: false },
56 i: { sqlType: 'vector(1536)', nullable: false, primaryKey: false, unique: false },
57 },
58 indexes: [],
59 },
60 },
61 };
62 const dm = generate(snapshot, []).get('briven/_generated/dataModel.d.ts')!;
63 assert.match(dm, /a: string;/);
64 assert.match(dm, /b: number;/);
65 assert.match(dm, /c: bigint;/);
66 assert.match(dm, /d: boolean;/);
67 assert.match(dm, /e: string;/);
68 assert.match(dm, /f: unknown;/);
69 assert.match(dm, /g: string;/);
70 assert.match(dm, /h: string;/);
71 assert.match(dm, /i: number\[\];/);
72});
73
74test('generate always includes a README in _generated', () => {
75 const out = generate({ version: 1, tables: {} }, []);
76 const readme = out.get('briven/_generated/README.md');
77 assert.ok(readme);
78 assert.match(readme, /Generated by briven cli\. Do not edit by hand\./);
79});
80
81test('generate emits empty api object when no functions', () => {
82 const out = generate({ version: 1, tables: {} }, []);
83 const api = out.get('briven/_generated/api.ts');
84 assert.ok(api);
85 assert.match(api, /export const api = \{\} as const;/);
86});