@drzl/cli 4.19.0 → 4.23.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.
@@ -0,0 +1,350 @@
1
+ import {
2
+ tableSchemas
3
+ } from "./chunk-KKPDOZOD.js";
4
+
5
+ // ../generator-fastify/dist/index.js
6
+ import { fileWriter } from "@drzl/validation-core";
7
+ import { formatCode, importSpecifier, selectColumns } from "@drzl/validation-core";
8
+ var APP_MODULE = "index";
9
+ var lit = (v) => /['\\]/.test(v) ? JSON.stringify(v) : `'${v}'`;
10
+ var NUMERIC_SEGMENT_PATTERN = "^-?\\d+(\\.\\d+)?$";
11
+ var BIGINT_SEGMENT_PATTERN = "^-?\\d+$";
12
+ var NOT_FOUND_SCHEMA = "{ type: 'object', properties: { message: { type: 'string' } }, required: ['message'], additionalProperties: false }";
13
+ var cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
14
+ var isIdent = (s) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s);
15
+ function keyColumns(table) {
16
+ const names = table.primaryKey?.columns ?? [];
17
+ if (!names.length) return null;
18
+ const cols = names.map((n) => table.columns.find((c) => c.name === n));
19
+ if (cols.some((c) => !c)) return null;
20
+ return cols;
21
+ }
22
+ function segmentSchema(column) {
23
+ if (column.enumValues && column.enumValues.length) return { enum: [...column.enumValues] };
24
+ switch (column.tsType) {
25
+ case "number":
26
+ return { type: "string", pattern: NUMERIC_SEGMENT_PATTERN };
27
+ case "bigint":
28
+ return { type: "string", pattern: BIGINT_SEGMENT_PATTERN };
29
+ case "Date":
30
+ return { type: "string", format: "date-time" };
31
+ default:
32
+ return { type: "string" };
33
+ }
34
+ }
35
+ function paramsSchema(cols) {
36
+ return {
37
+ type: "object",
38
+ properties: Object.fromEntries(cols.map((c) => [c.name, segmentSchema(c)])),
39
+ required: cols.map((c) => c.name),
40
+ additionalProperties: false
41
+ };
42
+ }
43
+ function adaptForFastify(schema) {
44
+ const { $schema: _dialect, $id: _id, ...rest } = walk(schema);
45
+ return rest;
46
+ }
47
+ function walk(value) {
48
+ if (Array.isArray(value)) return value.map(walk);
49
+ if (value && typeof value === "object") {
50
+ const out = {};
51
+ for (const [k, v] of Object.entries(value)) {
52
+ if (k === "prefixItems") continue;
53
+ out[k] = walk(v);
54
+ }
55
+ const prefix = value.prefixItems;
56
+ if (Array.isArray(prefix) && prefix.length) out.items = walk(prefix[0]);
57
+ return out;
58
+ }
59
+ return value;
60
+ }
61
+ function rowFieldType(column) {
62
+ if (column.enumValues && column.enumValues.length) {
63
+ return column.enumValues.map((v) => `'${v.replace(/'/g, "\\'")}'`).join(" | ");
64
+ }
65
+ const s = column.shape;
66
+ if (s) {
67
+ switch (s.kind) {
68
+ case "tuple":
69
+ return `[${Array.from({ length: s.length }, () => "number").join(", ")}]`;
70
+ case "numberObject":
71
+ return `{ ${s.fields.map((f) => `${f}: number`).join("; ")} }`;
72
+ case "numberVector":
73
+ return "number[]";
74
+ default:
75
+ return "unknown";
76
+ }
77
+ }
78
+ switch (column.tsType) {
79
+ case "number":
80
+ return "number";
81
+ case "string":
82
+ return "string";
83
+ case "boolean":
84
+ return "boolean";
85
+ case "Date":
86
+ return "Date";
87
+ case "bigint":
88
+ return "bigint";
89
+ default:
90
+ return "unknown";
91
+ }
92
+ }
93
+ function objectKey(name) {
94
+ return isIdent(name) ? name : JSON.stringify(name);
95
+ }
96
+ function toCase(s, c) {
97
+ if (!c) return s;
98
+ const parts = s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").split(/\s+/);
99
+ if (c === "camel") {
100
+ return parts.map(
101
+ (p, i) => i === 0 ? p.toLowerCase() : p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()
102
+ ).join("");
103
+ }
104
+ if (c === "kebab") return parts.map((p) => p.toLowerCase()).join("-");
105
+ if (c === "snake") return parts.map((p) => p.toLowerCase()).join("_");
106
+ return s;
107
+ }
108
+ function routesExportName(table, naming) {
109
+ const base = `${table.tsName}${naming?.routerSuffix ?? "Routes"}`;
110
+ const c = naming?.procedureCase;
111
+ return toCase(base, c === "kebab" ? "camel" : c);
112
+ }
113
+ function mountPath(table, naming) {
114
+ return `/${toCase(table.tsName, naming?.procedureCase)}`;
115
+ }
116
+ var FastifyGenerator = class {
117
+ constructor(analysis) {
118
+ this.analysis = analysis;
119
+ }
120
+ async generate(opts) {
121
+ const fs = fileWriter(opts.fileSink);
122
+ const path = await import("path");
123
+ const out = path.resolve(process.cwd(), opts.outputDir);
124
+ const ctx = { out };
125
+ await fs.mkdir(out, { recursive: true });
126
+ const files = [];
127
+ const write = async (filePath, content) => {
128
+ const formatted = await formatCode(
129
+ buildHeader(opts.outputHeader) + content,
130
+ filePath,
131
+ opts.format
132
+ );
133
+ await fs.writeFile(filePath, formatted, "utf8");
134
+ files.push(filePath);
135
+ };
136
+ const barrelPath = path.join(out, `${APP_MODULE}.ts`);
137
+ const modules = [];
138
+ const total = this.analysis.tables.length;
139
+ let index = 0;
140
+ for (const table of this.analysis.tables) {
141
+ const base = `${table.tsName}${opts.naming?.routerSuffix ?? ""}`;
142
+ const filePath = path.join(out, `${toCase(base, opts.naming?.procedureCase)}.ts`);
143
+ if (filePath === barrelPath) {
144
+ throw new Error(
145
+ `@drzl/generator-fastify: the routes for table "${table.name}" would be written to ${filePath}, which is the barrel this generator also writes. Set naming.routerSuffix to move it out of the way.`
146
+ );
147
+ }
148
+ await write(filePath, renderRoutes(table, opts));
149
+ modules.push({ table, filePath, exportName: routesExportName(table, opts.naming) });
150
+ index++;
151
+ opts.onProgress?.({ index, total, table: table.name, filePath });
152
+ }
153
+ await write(barrelPath, renderBarrel(modules, ctx, path, opts));
154
+ return { files };
155
+ }
156
+ };
157
+ var index_default = FastifyGenerator;
158
+ function buildHeader(h) {
159
+ if (h && h.enabled === false) return "";
160
+ const text = h?.text?.trim();
161
+ const lines = text ? text.split(/\r?\n/).map((l) => `// ${l}`) : [
162
+ "// Generated by DRZL (@drzl/*)",
163
+ "// Generated output is granted to you under your project's license.",
164
+ "// You may use, copy, modify, and distribute without attribution."
165
+ ];
166
+ return lines.join("\n") + "\n\n";
167
+ }
168
+ function renderRoutes(table, opts) {
169
+ const insertName = `Insert${table.tsName}Schema`;
170
+ const updateName = `Update${table.tsName}Schema`;
171
+ const selectName = `Select${table.tsName}Schema`;
172
+ const paramsName = `${cap(table.tsName)}ParamsSchema`;
173
+ const rowType = `Select${table.tsName}Row`;
174
+ const writable = !table.readOnly;
175
+ const key = keyColumns(table);
176
+ const routes = [];
177
+ const notImplemented = (what) => `throw new Error('Not implemented: ${what} ${table.tsName}.');`;
178
+ const paramHint = `// Fastify has already validated req.params against ${paramsName}; numeric key segments stay strings here.`;
179
+ routes.push({
180
+ name: "list",
181
+ method: "get",
182
+ path: "/",
183
+ schema: [`response: { 200: { type: 'array', items: ${selectName} } }`],
184
+ replyType: `${rowType}[]`,
185
+ // The stub states its contract twice over: the annotated local is what a reader sees, and the
186
+ // Reply generic is what Fastify's own types hold the handler to. The response schema is what
187
+ // the serializer runs; nothing infers a client from any of them, which the docs say plainly.
188
+ body: [`const rows: ${rowType}[] = [];`, "return rows;"]
189
+ });
190
+ if (key) {
191
+ const keyPath = "/" + key.map((c) => `:${c.name}`).join("/");
192
+ routes.push({
193
+ name: "byId",
194
+ method: "get",
195
+ path: keyPath,
196
+ schema: [
197
+ `params: ${paramsName}`,
198
+ `response: { 200: ${selectName}, 404: ${NOT_FOUND_SCHEMA} }`
199
+ ],
200
+ replyType: `${rowType} | { message: string }`,
201
+ body: [
202
+ paramHint,
203
+ `const row: ${rowType} | null = null;`,
204
+ "if (row !== null) return row;",
205
+ `return reply.code(404).send({ message: ${lit(`${table.tsName} row not found`)} });`
206
+ ]
207
+ });
208
+ if (writable) {
209
+ routes.push({
210
+ name: "update",
211
+ method: "patch",
212
+ path: keyPath,
213
+ schema: [
214
+ `params: ${paramsName}`,
215
+ `body: ${updateName}`,
216
+ `response: { 200: ${selectName} }`
217
+ ],
218
+ replyType: rowType,
219
+ body: [notImplemented("update")]
220
+ });
221
+ routes.push({
222
+ name: "delete",
223
+ method: "delete",
224
+ path: keyPath,
225
+ schema: [`params: ${paramsName}`, `response: { 200: { type: 'boolean' } }`],
226
+ replyType: "boolean",
227
+ body: [paramHint, "return true;"]
228
+ });
229
+ }
230
+ }
231
+ if (writable) {
232
+ routes.push({
233
+ name: "create",
234
+ method: "post",
235
+ path: "/",
236
+ schema: [`body: ${insertName}`, `response: { 200: ${selectName} }`],
237
+ replyType: rowType,
238
+ body: [notImplemented("create")]
239
+ });
240
+ }
241
+ if (opts.includeRelations) {
242
+ routes.push(...relationRoutes(table, rowType, selectName, opts));
243
+ }
244
+ const order = ["list", "byId", "create", "update", "delete"];
245
+ const rank = (n) => order.indexOf(n) === -1 ? order.length : order.indexOf(n);
246
+ routes.sort((a, b) => rank(a.name) - rank(b.name));
247
+ const exportName = routesExportName(table, opts.naming);
248
+ const statements = routes.map((r) => {
249
+ const reads = (what) => r.body.some((line) => !line.startsWith("//") && what.test(line));
250
+ const params = reads(/\breply\./) ? reads(/\breq\./) ? "(req, reply)" : "(_req, reply)" : reads(/\breq\./) ? "(req)" : "()";
251
+ return [
252
+ ` app.${r.method}<{ Reply: ${r.replyType} }>(${lit(r.path)}, {`,
253
+ ` schema: { ${r.schema.join(", ")} },`,
254
+ ` }, async ${params} => {`,
255
+ ...r.body.map((line) => ` ${line}`),
256
+ ` });`
257
+ ].join("\n");
258
+ }).join("\n\n");
259
+ const plugin = `export const ${exportName}: FastifyPluginAsync = async (app) => {
260
+ ${statements}
261
+ };
262
+ `;
263
+ const schemas = tableSchemas(table);
264
+ const declared = [];
265
+ const emit = (name, schema) => `export const ${name} = ${JSON.stringify(adaptForFastify(schema), null, 2)} as const;`;
266
+ if (writable) {
267
+ declared.push(emit(insertName, schemas.insert));
268
+ declared.push(emit(updateName, schemas.update));
269
+ }
270
+ declared.push(emit(selectName, schemas.select));
271
+ if (key) {
272
+ declared.push(emit(paramsName, paramsSchema(key)));
273
+ }
274
+ const rowFields = selectColumns(table).map((c) => ` ${objectKey(c.name)}: ${rowFieldType(c)}${c.nullable ? " | null" : ""};`).join("\n");
275
+ declared.push(`export interface ${rowType} {
276
+ ${rowFields}
277
+ }`);
278
+ const wide = selectColumns(table).filter((c) => rowFieldType(c) === "unknown").map((c) => c.name);
279
+ const wideNote = wide.length ? `// No precise type for ${wide.length === 1 ? "this column" : "these columns"}: ${wide.join(", ")}.
280
+ // DRZL could not derive one from the schema, so these routes carry it as unknown and its
281
+ // schema constrains only what the builder could state.
282
+ ` : "";
283
+ return `// Generated by @drzl/generator-fastify
284
+ // Routes for table: ${table.name}
285
+ ${wideNote}import type { FastifyPluginAsync } from 'fastify';
286
+
287
+ ${declared.join("\n\n")}
288
+
289
+ ${plugin}`;
290
+ }
291
+ function relationRoutes(table, rowType, selectName, opts) {
292
+ const out = [];
293
+ const taken = /* @__PURE__ */ new Set();
294
+ for (const fk of table.foreignKeys ?? []) {
295
+ if (fk.columns.length !== 1) continue;
296
+ const colName = fk.columns[0];
297
+ const column = table.columns.find((c) => c.name === colName);
298
+ if (!column) continue;
299
+ const segment = toCase(`by-${colName}`, opts.naming?.procedureCase ?? "kebab");
300
+ if (taken.has(segment)) continue;
301
+ taken.add(segment);
302
+ const params = JSON.stringify(paramsSchema([column]));
303
+ out.push({
304
+ name: `listBy${cap(colName)}`,
305
+ method: "get",
306
+ path: `/${segment}/:${colName}`,
307
+ schema: [`params: ${params}`, `response: { 200: { type: 'array', items: ${selectName} } }`],
308
+ replyType: `${rowType}[]`,
309
+ body: [`const rows: ${rowType}[] = [];`, "return rows;"]
310
+ });
311
+ }
312
+ return out;
313
+ }
314
+ function renderBarrel(modules, ctx, path, opts) {
315
+ if (!modules.length) {
316
+ return `// Generated by @drzl/generator-fastify
317
+ // No tables detected in analysis. Add tables to your schema and regenerate.
318
+ import type { FastifyPluginAsync } from 'fastify';
319
+
320
+ export const routes: FastifyPluginAsync = async () => {};
321
+ `;
322
+ }
323
+ const entries = modules.map(({ filePath, exportName, table }) => ({
324
+ rel: importSpecifier(
325
+ "./" + path.relative(ctx.out, filePath).replace(/\\/g, "/"),
326
+ opts.importExtension
327
+ ),
328
+ exportName,
329
+ mount: mountPath(table, opts.naming)
330
+ }));
331
+ const imports = entries.map((e) => `import { ${e.exportName} } from '${e.rel}';`).join("\n");
332
+ const registrations = entries.map((e) => ` app.register(${e.exportName}, { prefix: ${lit(e.mount)} });`).join("\n");
333
+ const reExports = entries.map((e) => `export * from '${e.rel}';`).join("\n");
334
+ return `// Generated by @drzl/generator-fastify
335
+ import type { FastifyPluginAsync } from 'fastify';
336
+ ${imports}
337
+
338
+ export const routes: FastifyPluginAsync = async (app) => {
339
+ ${registrations}
340
+ };
341
+
342
+ ${reExports}
343
+ `;
344
+ }
345
+ export {
346
+ APP_MODULE,
347
+ FastifyGenerator,
348
+ index_default as default
349
+ };
350
+ //# sourceMappingURL=dist-KQMPKOFK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../generator-fastify/dist/index.js"],"sourcesContent":["// src/index.ts\nimport { fileWriter } from \"@drzl/validation-core\";\nimport { tableSchemas } from \"@drzl/generator-json-schema\";\nimport { formatCode, importSpecifier, selectColumns } from \"@drzl/validation-core\";\nvar APP_MODULE = \"index\";\nvar lit = (v) => /['\\\\]/.test(v) ? JSON.stringify(v) : `'${v}'`;\nvar NUMERIC_SEGMENT_PATTERN = \"^-?\\\\d+(\\\\.\\\\d+)?$\";\nvar BIGINT_SEGMENT_PATTERN = \"^-?\\\\d+$\";\nvar NOT_FOUND_SCHEMA = \"{ type: 'object', properties: { message: { type: 'string' } }, required: ['message'], additionalProperties: false }\";\nvar cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);\nvar isIdent = (s) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(s);\nfunction keyColumns(table) {\n const names = table.primaryKey?.columns ?? [];\n if (!names.length) return null;\n const cols = names.map((n) => table.columns.find((c) => c.name === n));\n if (cols.some((c) => !c)) return null;\n return cols;\n}\nfunction segmentSchema(column) {\n if (column.enumValues && column.enumValues.length) return { enum: [...column.enumValues] };\n switch (column.tsType) {\n case \"number\":\n return { type: \"string\", pattern: NUMERIC_SEGMENT_PATTERN };\n case \"bigint\":\n return { type: \"string\", pattern: BIGINT_SEGMENT_PATTERN };\n case \"Date\":\n return { type: \"string\", format: \"date-time\" };\n default:\n return { type: \"string\" };\n }\n}\nfunction paramsSchema(cols) {\n return {\n type: \"object\",\n properties: Object.fromEntries(cols.map((c) => [c.name, segmentSchema(c)])),\n required: cols.map((c) => c.name),\n additionalProperties: false\n };\n}\nfunction adaptForFastify(schema) {\n const { $schema: _dialect, $id: _id, ...rest } = walk(schema);\n return rest;\n}\nfunction walk(value) {\n if (Array.isArray(value)) return value.map(walk);\n if (value && typeof value === \"object\") {\n const out = {};\n for (const [k, v] of Object.entries(value)) {\n if (k === \"prefixItems\") continue;\n out[k] = walk(v);\n }\n const prefix = value.prefixItems;\n if (Array.isArray(prefix) && prefix.length) out.items = walk(prefix[0]);\n return out;\n }\n return value;\n}\nfunction rowFieldType(column) {\n if (column.enumValues && column.enumValues.length) {\n return column.enumValues.map((v) => `'${v.replace(/'/g, \"\\\\'\")}'`).join(\" | \");\n }\n const s = column.shape;\n if (s) {\n switch (s.kind) {\n case \"tuple\":\n return `[${Array.from({ length: s.length }, () => \"number\").join(\", \")}]`;\n case \"numberObject\":\n return `{ ${s.fields.map((f) => `${f}: number`).join(\"; \")} }`;\n case \"numberVector\":\n return \"number[]\";\n default:\n return \"unknown\";\n }\n }\n switch (column.tsType) {\n case \"number\":\n return \"number\";\n case \"string\":\n return \"string\";\n case \"boolean\":\n return \"boolean\";\n case \"Date\":\n return \"Date\";\n case \"bigint\":\n return \"bigint\";\n default:\n return \"unknown\";\n }\n}\nfunction objectKey(name) {\n return isIdent(name) ? name : JSON.stringify(name);\n}\nfunction toCase(s, c) {\n if (!c) return s;\n const parts = s.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\").replace(/[_-]/g, \" \").split(/\\s+/);\n if (c === \"camel\") {\n return parts.map(\n (p, i) => i === 0 ? p.toLowerCase() : p.charAt(0).toUpperCase() + p.slice(1).toLowerCase()\n ).join(\"\");\n }\n if (c === \"kebab\") return parts.map((p) => p.toLowerCase()).join(\"-\");\n if (c === \"snake\") return parts.map((p) => p.toLowerCase()).join(\"_\");\n return s;\n}\nfunction routesExportName(table, naming) {\n const base = `${table.tsName}${naming?.routerSuffix ?? \"Routes\"}`;\n const c = naming?.procedureCase;\n return toCase(base, c === \"kebab\" ? \"camel\" : c);\n}\nfunction mountPath(table, naming) {\n return `/${toCase(table.tsName, naming?.procedureCase)}`;\n}\nvar FastifyGenerator = class {\n constructor(analysis) {\n this.analysis = analysis;\n }\n async generate(opts) {\n const fs = fileWriter(opts.fileSink);\n const path = await import(\"path\");\n const out = path.resolve(process.cwd(), opts.outputDir);\n const ctx = { out };\n await fs.mkdir(out, { recursive: true });\n const files = [];\n const write = async (filePath, content) => {\n const formatted = await formatCode(\n buildHeader(opts.outputHeader) + content,\n filePath,\n opts.format\n );\n await fs.writeFile(filePath, formatted, \"utf8\");\n files.push(filePath);\n };\n const barrelPath = path.join(out, `${APP_MODULE}.ts`);\n const modules = [];\n const total = this.analysis.tables.length;\n let index = 0;\n for (const table of this.analysis.tables) {\n const base = `${table.tsName}${opts.naming?.routerSuffix ?? \"\"}`;\n const filePath = path.join(out, `${toCase(base, opts.naming?.procedureCase)}.ts`);\n if (filePath === barrelPath) {\n throw new Error(\n `@drzl/generator-fastify: the routes for table \"${table.name}\" would be written to ${filePath}, which is the barrel this generator also writes. Set naming.routerSuffix to move it out of the way.`\n );\n }\n await write(filePath, renderRoutes(table, opts));\n modules.push({ table, filePath, exportName: routesExportName(table, opts.naming) });\n index++;\n opts.onProgress?.({ index, total, table: table.name, filePath });\n }\n await write(barrelPath, renderBarrel(modules, ctx, path, opts));\n return { files };\n }\n};\nvar index_default = FastifyGenerator;\nfunction buildHeader(h) {\n if (h && h.enabled === false) return \"\";\n const text = h?.text?.trim();\n const lines = text ? text.split(/\\r?\\n/).map((l) => `// ${l}`) : [\n \"// Generated by DRZL (@drzl/*)\",\n \"// Generated output is granted to you under your project's license.\",\n \"// You may use, copy, modify, and distribute without attribution.\"\n ];\n return lines.join(\"\\n\") + \"\\n\\n\";\n}\nfunction renderRoutes(table, opts) {\n const insertName = `Insert${table.tsName}Schema`;\n const updateName = `Update${table.tsName}Schema`;\n const selectName = `Select${table.tsName}Schema`;\n const paramsName = `${cap(table.tsName)}ParamsSchema`;\n const rowType = `Select${table.tsName}Row`;\n const writable = !table.readOnly;\n const key = keyColumns(table);\n const routes = [];\n const notImplemented = (what) => `throw new Error('Not implemented: ${what} ${table.tsName}.');`;\n const paramHint = `// Fastify has already validated req.params against ${paramsName}; numeric key segments stay strings here.`;\n routes.push({\n name: \"list\",\n method: \"get\",\n path: \"/\",\n schema: [`response: { 200: { type: 'array', items: ${selectName} } }`],\n replyType: `${rowType}[]`,\n // The stub states its contract twice over: the annotated local is what a reader sees, and the\n // Reply generic is what Fastify's own types hold the handler to. The response schema is what\n // the serializer runs; nothing infers a client from any of them, which the docs say plainly.\n body: [`const rows: ${rowType}[] = [];`, \"return rows;\"]\n });\n if (key) {\n const keyPath = \"/\" + key.map((c) => `:${c.name}`).join(\"/\");\n routes.push({\n name: \"byId\",\n method: \"get\",\n path: keyPath,\n schema: [\n `params: ${paramsName}`,\n `response: { 200: ${selectName}, 404: ${NOT_FOUND_SCHEMA} }`\n ],\n replyType: `${rowType} | { message: string }`,\n body: [\n paramHint,\n `const row: ${rowType} | null = null;`,\n \"if (row !== null) return row;\",\n `return reply.code(404).send({ message: ${lit(`${table.tsName} row not found`)} });`\n ]\n });\n if (writable) {\n routes.push({\n name: \"update\",\n method: \"patch\",\n path: keyPath,\n schema: [\n `params: ${paramsName}`,\n `body: ${updateName}`,\n `response: { 200: ${selectName} }`\n ],\n replyType: rowType,\n body: [notImplemented(\"update\")]\n });\n routes.push({\n name: \"delete\",\n method: \"delete\",\n path: keyPath,\n schema: [`params: ${paramsName}`, `response: { 200: { type: 'boolean' } }`],\n replyType: \"boolean\",\n body: [paramHint, \"return true;\"]\n });\n }\n }\n if (writable) {\n routes.push({\n name: \"create\",\n method: \"post\",\n path: \"/\",\n schema: [`body: ${insertName}`, `response: { 200: ${selectName} }`],\n replyType: rowType,\n body: [notImplemented(\"create\")]\n });\n }\n if (opts.includeRelations) {\n routes.push(...relationRoutes(table, rowType, selectName, opts));\n }\n const order = [\"list\", \"byId\", \"create\", \"update\", \"delete\"];\n const rank = (n) => order.indexOf(n) === -1 ? order.length : order.indexOf(n);\n routes.sort((a, b) => rank(a.name) - rank(b.name));\n const exportName = routesExportName(table, opts.naming);\n const statements = routes.map((r) => {\n const reads = (what) => r.body.some((line) => !line.startsWith(\"//\") && what.test(line));\n const params = reads(/\\breply\\./) ? reads(/\\breq\\./) ? \"(req, reply)\" : \"(_req, reply)\" : reads(/\\breq\\./) ? \"(req)\" : \"()\";\n return [\n ` app.${r.method}<{ Reply: ${r.replyType} }>(${lit(r.path)}, {`,\n ` schema: { ${r.schema.join(\", \")} },`,\n ` }, async ${params} => {`,\n ...r.body.map((line) => ` ${line}`),\n ` });`\n ].join(\"\\n\");\n }).join(\"\\n\\n\");\n const plugin = `export const ${exportName}: FastifyPluginAsync = async (app) => {\n${statements}\n};\n`;\n const schemas = tableSchemas(table);\n const declared = [];\n const emit = (name, schema) => `export const ${name} = ${JSON.stringify(adaptForFastify(schema), null, 2)} as const;`;\n if (writable) {\n declared.push(emit(insertName, schemas.insert));\n declared.push(emit(updateName, schemas.update));\n }\n declared.push(emit(selectName, schemas.select));\n if (key) {\n declared.push(emit(paramsName, paramsSchema(key)));\n }\n const rowFields = selectColumns(table).map((c) => ` ${objectKey(c.name)}: ${rowFieldType(c)}${c.nullable ? \" | null\" : \"\"};`).join(\"\\n\");\n declared.push(`export interface ${rowType} {\n${rowFields}\n}`);\n const wide = selectColumns(table).filter((c) => rowFieldType(c) === \"unknown\").map((c) => c.name);\n const wideNote = wide.length ? `// No precise type for ${wide.length === 1 ? \"this column\" : \"these columns\"}: ${wide.join(\", \")}.\n// DRZL could not derive one from the schema, so these routes carry it as unknown and its\n// schema constrains only what the builder could state.\n` : \"\";\n return `// Generated by @drzl/generator-fastify\n// Routes for table: ${table.name}\n${wideNote}import type { FastifyPluginAsync } from 'fastify';\n\n${declared.join(\"\\n\\n\")}\n\n${plugin}`;\n}\nfunction relationRoutes(table, rowType, selectName, opts) {\n const out = [];\n const taken = /* @__PURE__ */ new Set();\n for (const fk of table.foreignKeys ?? []) {\n if (fk.columns.length !== 1) continue;\n const colName = fk.columns[0];\n const column = table.columns.find((c) => c.name === colName);\n if (!column) continue;\n const segment = toCase(`by-${colName}`, opts.naming?.procedureCase ?? \"kebab\");\n if (taken.has(segment)) continue;\n taken.add(segment);\n const params = JSON.stringify(paramsSchema([column]));\n out.push({\n name: `listBy${cap(colName)}`,\n method: \"get\",\n path: `/${segment}/:${colName}`,\n schema: [`params: ${params}`, `response: { 200: { type: 'array', items: ${selectName} } }`],\n replyType: `${rowType}[]`,\n body: [`const rows: ${rowType}[] = [];`, \"return rows;\"]\n });\n }\n return out;\n}\nfunction renderBarrel(modules, ctx, path, opts) {\n if (!modules.length) {\n return `// Generated by @drzl/generator-fastify\n// No tables detected in analysis. Add tables to your schema and regenerate.\nimport type { FastifyPluginAsync } from 'fastify';\n\nexport const routes: FastifyPluginAsync = async () => {};\n`;\n }\n const entries = modules.map(({ filePath, exportName, table }) => ({\n rel: importSpecifier(\n \"./\" + path.relative(ctx.out, filePath).replace(/\\\\/g, \"/\"),\n opts.importExtension\n ),\n exportName,\n mount: mountPath(table, opts.naming)\n }));\n const imports = entries.map((e) => `import { ${e.exportName} } from '${e.rel}';`).join(\"\\n\");\n const registrations = entries.map((e) => ` app.register(${e.exportName}, { prefix: ${lit(e.mount)} });`).join(\"\\n\");\n const reExports = entries.map((e) => `export * from '${e.rel}';`).join(\"\\n\");\n return `// Generated by @drzl/generator-fastify\nimport type { FastifyPluginAsync } from 'fastify';\n${imports}\n\nexport const routes: FastifyPluginAsync = async (app) => {\n${registrations}\n};\n\n${reExports}\n`;\n}\nexport {\n APP_MODULE,\n FastifyGenerator,\n index_default as default\n};\n"],"mappings":"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","names":[]}