node-type-registry 0.11.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,250 +0,0 @@
1
- /**
2
- * Generate SQL seed scripts from TypeScript node type definitions.
3
- *
4
- * Uses pgsql-deparser to produce individual INSERT statements per node type,
5
- * suitable for use as separate pgpm migration files.
6
- *
7
- * Usage:
8
- * npx ts-node src/codegen/generate-seed.ts [--outdir <dir>] [--single] [--pgpm <dir>]
9
- *
10
- * --outdir <dir> Directory to write individual SQL files (default: stdout)
11
- * --single Emit a single combined seed.sql instead of per-node files
12
- * --pgpm <dir> Generate deploy/revert/verify files in pgpm package layout.
13
- * <dir> is the pgpm package root (e.g. packages/metaschema).
14
- * Files are written relative to this root at:
15
- * deploy/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
16
- * revert/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
17
- * verify/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
18
- *
19
- * Examples:
20
- * # Print all INSERT statements to stdout
21
- * npx ts-node src/codegen/generate-seed.ts
22
- *
23
- * # Generate individual migration files
24
- * npx ts-node src/codegen/generate-seed.ts --outdir ./deploy/seed
25
- *
26
- * # Generate a single combined seed file
27
- * npx ts-node src/codegen/generate-seed.ts --single --outdir ./deploy
28
- *
29
- * # Generate pgpm deploy/revert/verify files
30
- * npx ts-node src/codegen/generate-seed.ts --pgpm ../../constructive-db/packages/metaschema
31
- */
32
- import { writeFileSync, mkdirSync, existsSync } from 'fs';
33
- import { join } from 'path';
34
- import { deparse } from 'pgsql-deparser';
35
- import { ast, nodes } from '@pgsql/utils';
36
- import { allNodeTypes } from '../index';
37
- // ---------------------------------------------------------------------------
38
- // Constants
39
- // ---------------------------------------------------------------------------
40
- const MIGRATION_PATH = 'schemas/metaschema_public/tables/node_type_registry/data/seed';
41
- // ---------------------------------------------------------------------------
42
- // AST helpers
43
- // ---------------------------------------------------------------------------
44
- const astr = (val) => nodes.aConst({ sval: ast.string({ sval: val }) });
45
- const makeCast = (arg, typeName) => ({
46
- TypeCast: {
47
- arg,
48
- typeName: {
49
- names: [{ String: { sval: typeName } }],
50
- typemod: -1,
51
- },
52
- },
53
- });
54
- const makeArrayExpr = (elements) => ({
55
- A_ArrayExpr: { elements },
56
- });
57
- // ---------------------------------------------------------------------------
58
- // Build a single INSERT statement for one node type
59
- // ---------------------------------------------------------------------------
60
- function buildInsertStmt(nt) {
61
- const cols = [
62
- 'name',
63
- 'slug',
64
- 'category',
65
- 'display_name',
66
- 'description',
67
- 'parameter_schema',
68
- 'tags',
69
- ];
70
- const vals = [
71
- astr(nt.name),
72
- astr(nt.slug),
73
- astr(nt.category),
74
- astr(nt.display_name),
75
- astr(nt.description),
76
- makeCast(astr(JSON.stringify(nt.parameter_schema)), 'jsonb'),
77
- makeArrayExpr(nt.tags.map((t) => astr(t))),
78
- ];
79
- return {
80
- RawStmt: {
81
- stmt: {
82
- InsertStmt: {
83
- relation: {
84
- schemaname: 'metaschema_public',
85
- relname: 'node_type_registry',
86
- inh: true,
87
- relpersistence: 'p',
88
- },
89
- cols: cols.map((name) => nodes.resTarget({ name })),
90
- selectStmt: {
91
- SelectStmt: {
92
- valuesLists: [
93
- {
94
- List: { items: vals },
95
- },
96
- ],
97
- op: 'SETOP_NONE',
98
- limitOption: 'LIMIT_OPTION_DEFAULT',
99
- },
100
- },
101
- onConflictClause: {
102
- action: 'ONCONFLICT_NOTHING',
103
- infer: {
104
- indexElems: [
105
- {
106
- IndexElem: {
107
- name: 'slug',
108
- ordering: 'SORTBY_DEFAULT',
109
- nulls_ordering: 'SORTBY_NULLS_DEFAULT',
110
- },
111
- },
112
- ],
113
- },
114
- },
115
- override: 'OVERRIDING_NOT_SET',
116
- },
117
- },
118
- stmt_len: 1,
119
- },
120
- };
121
- }
122
- // ---------------------------------------------------------------------------
123
- // pgpm file generators
124
- // ---------------------------------------------------------------------------
125
- const GENERATED_HEADER = [
126
- '-- GENERATED FILE — DO NOT EDIT',
127
- '--',
128
- '-- Regenerate with:',
129
- '-- cd graphql/node-type-registry && pnpm generate:seed --pgpm ../../constructive-db/packages/metaschema',
130
- '--',
131
- '',
132
- ].join('\n');
133
- async function buildDeploySql() {
134
- const header = [
135
- `-- Deploy ${MIGRATION_PATH} to pg`,
136
- '',
137
- GENERATED_HEADER,
138
- '-- requires: schemas/metaschema_public/tables/node_type_registry/table',
139
- '',
140
- ].join('\n');
141
- const stmts = allNodeTypes.map(buildInsertStmt);
142
- const body = await deparse(stmts);
143
- return header + body + '\n';
144
- }
145
- function buildRevertSql() {
146
- const names = allNodeTypes.map((nt) => ` '${nt.name}'`);
147
- // Wrap names at ~4 per line for readability
148
- const chunks = [];
149
- for (let i = 0; i < names.length; i += 4) {
150
- chunks.push(names.slice(i, i + 4).join(', '));
151
- }
152
- return [
153
- `-- Revert ${MIGRATION_PATH} from pg`,
154
- '',
155
- GENERATED_HEADER,
156
- 'DELETE FROM metaschema_public.node_type_registry',
157
- 'WHERE name IN (',
158
- chunks.join(',\n'),
159
- ');',
160
- '',
161
- ].join('\n');
162
- }
163
- function buildVerifySql() {
164
- // Pick one representative from each category
165
- const categories = new Map();
166
- for (const nt of allNodeTypes) {
167
- if (!categories.has(nt.category)) {
168
- categories.set(nt.category, nt);
169
- }
170
- }
171
- const checks = Array.from(categories.values()).map((nt) => `SELECT 1 FROM metaschema_public.node_type_registry WHERE name = '${nt.name}';`);
172
- return [
173
- `-- Verify ${MIGRATION_PATH} on pg`,
174
- '',
175
- GENERATED_HEADER,
176
- ...checks,
177
- '',
178
- ].join('\n');
179
- }
180
- // ---------------------------------------------------------------------------
181
- // File writer helper
182
- // ---------------------------------------------------------------------------
183
- function writeFile(filePath, content) {
184
- const dir = join(filePath, '..');
185
- if (!existsSync(dir))
186
- mkdirSync(dir, { recursive: true });
187
- writeFileSync(filePath, content);
188
- }
189
- // ---------------------------------------------------------------------------
190
- // CLI
191
- // ---------------------------------------------------------------------------
192
- async function main() {
193
- const args = process.argv.slice(2);
194
- const outdirIdx = args.indexOf('--outdir');
195
- const outdir = outdirIdx !== -1 ? args[outdirIdx + 1] : undefined;
196
- const single = args.includes('--single');
197
- const pgpmIdx = args.indexOf('--pgpm');
198
- const pgpmRoot = pgpmIdx !== -1 ? args[pgpmIdx + 1] : undefined;
199
- // --pgpm mode: generate deploy/revert/verify in pgpm package layout
200
- if (pgpmRoot) {
201
- const relPath = 'schemas/metaschema_public/tables/node_type_registry/data/seed.sql';
202
- const deployPath = join(pgpmRoot, 'deploy', relPath);
203
- const revertPath = join(pgpmRoot, 'revert', relPath);
204
- const verifyPath = join(pgpmRoot, 'verify', relPath);
205
- writeFile(deployPath, await buildDeploySql());
206
- writeFile(revertPath, buildRevertSql());
207
- writeFile(verifyPath, buildVerifySql());
208
- console.log(`Wrote ${allNodeTypes.length} node types to pgpm layout:`);
209
- console.log(` deploy: ${deployPath}`);
210
- console.log(` revert: ${revertPath}`);
211
- console.log(` verify: ${verifyPath}`);
212
- return;
213
- }
214
- if (single) {
215
- // Emit all INSERT statements as a single SQL string
216
- const stmts = allNodeTypes.map(buildInsertStmt);
217
- const sql = await deparse(stmts);
218
- if (outdir) {
219
- if (!existsSync(outdir))
220
- mkdirSync(outdir, { recursive: true });
221
- writeFileSync(join(outdir, 'seed.sql'), sql + '\n');
222
- console.log(`Wrote ${allNodeTypes.length} node types to ${join(outdir, 'seed.sql')}`);
223
- }
224
- else {
225
- process.stdout.write(sql + '\n');
226
- }
227
- return;
228
- }
229
- // Emit individual SQL files per node type
230
- const stmts = await Promise.all(allNodeTypes.map(async (nt) => ({
231
- nt,
232
- sql: await deparse([buildInsertStmt(nt)]),
233
- })));
234
- if (outdir) {
235
- if (!existsSync(outdir))
236
- mkdirSync(outdir, { recursive: true });
237
- for (const { nt, sql } of stmts) {
238
- const filename = `${nt.slug}.sql`;
239
- writeFileSync(join(outdir, filename), sql + '\n');
240
- }
241
- console.log(`Wrote ${stmts.length} individual migration files to ${outdir}/`);
242
- }
243
- else {
244
- for (const { nt, sql } of stmts) {
245
- console.log(`-- ${nt.name} (${nt.slug})`);
246
- console.log(sql + ';\n');
247
- }
248
- }
249
- }
250
- main();