@drzl/cli 1.0.0 → 2.0.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.
- package/README.md +14 -0
- package/dist/chunk-HHT7INUJ.js +301 -0
- package/dist/chunk-HHT7INUJ.js.map +1 -0
- package/dist/cli.cjs +305 -80
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +178 -77
- package/dist/cli.js.map +1 -1
- package/dist/config.cjs +136 -4
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +200 -1
- package/dist/config.d.ts +200 -1
- package/dist/config.js +7 -1
- package/package.json +12 -7
- package/dist/chunk-MEPFGJIF.js +0 -164
- package/dist/chunk-MEPFGJIF.js.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -26,14 +26,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
// src/cli.ts
|
|
27
27
|
var import_analyzer = require("@drzl/analyzer");
|
|
28
28
|
var import_generator_orpc = require("@drzl/generator-orpc");
|
|
29
|
-
var
|
|
29
|
+
var import_chalk2 = __toESM(require("chalk"), 1);
|
|
30
30
|
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
31
31
|
var import_cli_progress = __toESM(require("cli-progress"), 1);
|
|
32
32
|
var import_commander = require("commander");
|
|
33
|
-
var
|
|
33
|
+
var path3 = __toESM(require("path"), 1);
|
|
34
34
|
var import_ora = __toESM(require("ora"), 1);
|
|
35
35
|
|
|
36
36
|
// src/config.ts
|
|
37
|
+
var import_validation_core = require("@drzl/validation-core");
|
|
37
38
|
var fs = __toESM(require("fs"), 1);
|
|
38
39
|
var import_node_module = require("module");
|
|
39
40
|
var path = __toESM(require("path"), 1);
|
|
@@ -42,8 +43,41 @@ var NamingSchema = import_zod.z.object({
|
|
|
42
43
|
routerSuffix: import_zod.z.string().default("Router"),
|
|
43
44
|
procedureCase: import_zod.z.enum(["camel", "kebab", "snake"]).default("camel")
|
|
44
45
|
}).partial();
|
|
46
|
+
var AffixValueSchema = import_zod.z.union(
|
|
47
|
+
[
|
|
48
|
+
import_zod.z.string(),
|
|
49
|
+
import_zod.z.object({
|
|
50
|
+
insert: import_zod.z.string().optional(),
|
|
51
|
+
update: import_zod.z.string().optional(),
|
|
52
|
+
select: import_zod.z.string().optional()
|
|
53
|
+
}).strict()
|
|
54
|
+
],
|
|
55
|
+
{
|
|
56
|
+
error: 'Expected a string to use for every mode, or an object with any of the keys "insert", "update" and "select". Those keys are lowercase, matching the mode names drzl uses everywhere else.'
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
var AffixPartSchema = import_zod.z.object({
|
|
60
|
+
prefix: AffixValueSchema.optional(),
|
|
61
|
+
suffix: AffixValueSchema.optional()
|
|
62
|
+
}).strict();
|
|
63
|
+
var AffixSchema = import_zod.z.object({
|
|
64
|
+
/**
|
|
65
|
+
* `preserve` (default) keeps today's output: the Drizzle export name goes into the
|
|
66
|
+
* identifier verbatim, so `export const users` yields `InsertusersSchema`. `pascal`
|
|
67
|
+
* upper-camels it first, yielding `InsertUsersSchema`.
|
|
68
|
+
*/
|
|
69
|
+
tableCase: import_zod.z.enum(["preserve", "pascal"]).optional(),
|
|
70
|
+
schema: AffixPartSchema.optional(),
|
|
71
|
+
type: AffixPartSchema.optional()
|
|
72
|
+
}).strict();
|
|
73
|
+
var ImportExtensionSchema = import_zod.z.enum(import_validation_core.IMPORT_EXTENSIONS);
|
|
45
74
|
var GeneratorSchema = import_zod.z.object({
|
|
46
75
|
kind: import_zod.z.enum(["orpc", "service", "zod", "valibot", "arktype"]),
|
|
76
|
+
/**
|
|
77
|
+
* Overrides the top-level `importExtension` for this generator alone, for a project whose
|
|
78
|
+
* generated directories are compiled by different tsconfigs.
|
|
79
|
+
*/
|
|
80
|
+
importExtension: ImportExtensionSchema.optional(),
|
|
47
81
|
template: import_zod.z.string().optional(),
|
|
48
82
|
includeRelations: import_zod.z.boolean().optional(),
|
|
49
83
|
naming: NamingSchema.optional(),
|
|
@@ -64,12 +98,22 @@ var GeneratorSchema = import_zod.z.object({
|
|
|
64
98
|
// zod/valibot/arktype generator specific options
|
|
65
99
|
schemaSuffix: import_zod.z.string().optional(),
|
|
66
100
|
fileSuffix: import_zod.z.string().optional(),
|
|
101
|
+
/**
|
|
102
|
+
* Prefixes, suffixes and table casing for generated identifiers (zod/valibot/arktype).
|
|
103
|
+
* Omitting it reproduces the output of every previous release exactly.
|
|
104
|
+
*/
|
|
105
|
+
affix: AffixSchema.optional(),
|
|
67
106
|
// orpc validation sharing
|
|
68
107
|
validation: import_zod.z.object({
|
|
69
108
|
useShared: import_zod.z.boolean().default(false).optional(),
|
|
70
109
|
library: import_zod.z.enum(["zod", "valibot", "arktype"]).default("zod").optional(),
|
|
71
110
|
importPath: import_zod.z.string().optional(),
|
|
72
|
-
schemaSuffix: import_zod.z.string().optional()
|
|
111
|
+
schemaSuffix: import_zod.z.string().optional(),
|
|
112
|
+
/**
|
|
113
|
+
* How the validation generator named its exports. Usually left unset: the CLI copies
|
|
114
|
+
* it from the sibling generator whose `kind` matches `library`.
|
|
115
|
+
*/
|
|
116
|
+
affix: AffixSchema.optional()
|
|
73
117
|
}).optional(),
|
|
74
118
|
// template options
|
|
75
119
|
templateOptions: import_zod.z.record(import_zod.z.string(), import_zod.z.any()).optional()
|
|
@@ -82,13 +126,95 @@ var AnalyzerSchema = import_zod.z.object({
|
|
|
82
126
|
var ConfigSchema = import_zod.z.object({
|
|
83
127
|
schema: import_zod.z.string(),
|
|
84
128
|
outDir: import_zod.z.string().default("src/api"),
|
|
129
|
+
/**
|
|
130
|
+
* How every relative specifier drzl invents spells its extension, for every generator.
|
|
131
|
+
* A generator may override it. Defaults to `js`, which is the only form that resolves
|
|
132
|
+
* under every `moduleResolution` without a compiler flag.
|
|
133
|
+
*/
|
|
134
|
+
importExtension: ImportExtensionSchema.default(import_validation_core.DEFAULT_IMPORT_EXTENSION),
|
|
85
135
|
analyzer: AnalyzerSchema.default({
|
|
86
136
|
includeRelations: true,
|
|
87
137
|
validateConstraints: true,
|
|
88
138
|
includeHeuristicRelations: false
|
|
89
139
|
}),
|
|
90
140
|
generators: import_zod.z.array(GeneratorSchema).min(1).default([{ kind: "orpc" }])
|
|
141
|
+
}).superRefine((cfg, ctx) => {
|
|
142
|
+
cfg.generators.forEach((g, i) => {
|
|
143
|
+
const report = (base, affix, schemaSuffix) => {
|
|
144
|
+
for (const issue of (0, import_validation_core.validateAffix)(affix, schemaSuffix)) {
|
|
145
|
+
ctx.addIssue({
|
|
146
|
+
code: "custom",
|
|
147
|
+
path: ["generators", i, ...base, ...issue.path],
|
|
148
|
+
message: issue.message
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
report(["affix"], g.affix, g.schemaSuffix);
|
|
153
|
+
report(
|
|
154
|
+
["validation", "affix"],
|
|
155
|
+
g.validation?.affix,
|
|
156
|
+
g.validation?.schemaSuffix
|
|
157
|
+
);
|
|
158
|
+
});
|
|
91
159
|
});
|
|
160
|
+
function sharedSchemaNames(opts) {
|
|
161
|
+
const resolved = (0, import_validation_core.resolveAffix)(opts);
|
|
162
|
+
return import_validation_core.NAME_MODES.map((mode) => (0, import_validation_core.schemaName)(mode, import_validation_core.AFFIX_PROBE_TABLE, resolved));
|
|
163
|
+
}
|
|
164
|
+
function resolveConfig(cfg) {
|
|
165
|
+
const warnings = [];
|
|
166
|
+
const generators = cfg.generators.map((g) => ({
|
|
167
|
+
...g,
|
|
168
|
+
importExtension: g.importExtension ?? cfg.importExtension
|
|
169
|
+
}));
|
|
170
|
+
for (const g of generators) {
|
|
171
|
+
if (g.kind !== "orpc") continue;
|
|
172
|
+
const v = g.validation;
|
|
173
|
+
if (!v?.useShared) continue;
|
|
174
|
+
const library = v.library ?? "zod";
|
|
175
|
+
const siblings = generators.filter((s) => s.kind === library);
|
|
176
|
+
if (siblings.length !== 1) continue;
|
|
177
|
+
const sibling = siblings[0];
|
|
178
|
+
const theirs = sharedSchemaNames({
|
|
179
|
+
affix: sibling.affix,
|
|
180
|
+
schemaSuffix: sibling.schemaSuffix
|
|
181
|
+
});
|
|
182
|
+
if (!v.affix) {
|
|
183
|
+
if (sibling.affix) {
|
|
184
|
+
g.validation = {
|
|
185
|
+
...v,
|
|
186
|
+
affix: (0, import_validation_core.resolveAffix)({
|
|
187
|
+
affix: sibling.affix,
|
|
188
|
+
schemaSuffix: sibling.schemaSuffix
|
|
189
|
+
})
|
|
190
|
+
};
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const mine2 = sharedSchemaNames({ schemaSuffix: v.schemaSuffix });
|
|
194
|
+
if (mine2.join(",") !== theirs.join(",")) {
|
|
195
|
+
warnings.push(
|
|
196
|
+
`drzl config: the "orpc" generator's validation.schemaSuffix (${JSON.stringify(v.schemaSuffix ?? "Schema")}) does not match the "${library}" generator's schemaSuffix (${JSON.stringify(sibling.schemaSuffix ?? "Schema")}). The router will import ${mine2.join(", ")} but the "${library}" generator exports ${theirs.join(", ")}, so the generated router will not compile. Set both to the same value, or move to "affix", which is inherited automatically.`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const mine = sharedSchemaNames({
|
|
202
|
+
affix: v.affix,
|
|
203
|
+
schemaSuffix: v.schemaSuffix
|
|
204
|
+
});
|
|
205
|
+
if (mine.join(",") !== theirs.join(",")) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`drzl config: the "orpc" generator imports shared ${library} schemas, but its validation.affix disagrees with the "${library}" generator's own naming. The router would import ${mine.join(", ")} while the "${library}" generator exports ${theirs.join(", ")}. Make them match, or drop validation.affix and let it be inherited from the "${library}" generator.`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return { config: { ...cfg, generators }, warnings };
|
|
212
|
+
}
|
|
213
|
+
function finalize(raw) {
|
|
214
|
+
const { config, warnings } = resolveConfig(ConfigSchema.parse(raw));
|
|
215
|
+
for (const w of warnings) console.warn(w);
|
|
216
|
+
return config;
|
|
217
|
+
}
|
|
92
218
|
async function loadConfig(customPath) {
|
|
93
219
|
const fsp = await import("fs/promises");
|
|
94
220
|
const candidates = customPath ? [customPath] : [
|
|
@@ -108,7 +234,7 @@ async function loadConfig(customPath) {
|
|
|
108
234
|
const ext = path.extname(p).toLowerCase();
|
|
109
235
|
if (ext === ".json") {
|
|
110
236
|
const raw2 = JSON.parse(await fsp.readFile(p, "utf8"));
|
|
111
|
-
return
|
|
237
|
+
return finalize(raw2);
|
|
112
238
|
}
|
|
113
239
|
const { createJiti } = await import("jiti");
|
|
114
240
|
const stat = await fsp.stat(p);
|
|
@@ -122,12 +248,12 @@ async function loadConfig(customPath) {
|
|
|
122
248
|
// bump on edit
|
|
123
249
|
interopDefault: true,
|
|
124
250
|
tryNative: false
|
|
125
|
-
//
|
|
251
|
+
// <-- prevent native import of .ts
|
|
126
252
|
// debug: true,
|
|
127
253
|
});
|
|
128
254
|
const mod = await jiti.import(p);
|
|
129
255
|
const raw = mod?.default ?? mod;
|
|
130
|
-
return
|
|
256
|
+
return finalize(raw);
|
|
131
257
|
}
|
|
132
258
|
return null;
|
|
133
259
|
}
|
|
@@ -182,9 +308,84 @@ function computeWatchTargets(cfg, cwd = process.cwd()) {
|
|
|
182
308
|
return [...targets];
|
|
183
309
|
}
|
|
184
310
|
|
|
311
|
+
// src/sponsor.ts
|
|
312
|
+
var import_chalk = __toESM(require("chalk"), 1);
|
|
313
|
+
var import_node_fs = require("fs");
|
|
314
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
315
|
+
var CACHE_DIR = import_node_path.default.join(process.cwd(), "node_modules", ".cache", "@drzl");
|
|
316
|
+
var CACHE_FILE = import_node_path.default.join(CACHE_DIR, "sponsor-message.json");
|
|
317
|
+
var DEFAULT_INTERVAL_MS = 1e3 * 60 * 15;
|
|
318
|
+
var shownThisProcess = false;
|
|
319
|
+
var tips = [
|
|
320
|
+
"Pair DRZL watch mode with drizzle-kit to keep schema & API synced.",
|
|
321
|
+
"Templatize your ORPC routers to roll out new endpoints safely.",
|
|
322
|
+
"Need typed validators? Enable the zod, valibot, or arktype generators.",
|
|
323
|
+
"Use output headers to track generated files and trim noisy diffs."
|
|
324
|
+
];
|
|
325
|
+
var green = (msg) => import_chalk.default.hex("#6ee7b7")(msg);
|
|
326
|
+
var cyan = (msg) => import_chalk.default.cyan(msg);
|
|
327
|
+
var gray = (msg) => import_chalk.default.gray(msg);
|
|
328
|
+
function maybeShowSponsorMessage({
|
|
329
|
+
reason = "generate",
|
|
330
|
+
minIntervalMs = DEFAULT_INTERVAL_MS,
|
|
331
|
+
force = false
|
|
332
|
+
} = {}) {
|
|
333
|
+
const hideViaEnv = process.env.DRZL_HIDE_SPONSOR?.toLowerCase();
|
|
334
|
+
const hideRequested = hideViaEnv === "1" || hideViaEnv === "true";
|
|
335
|
+
if (hideRequested || process.env.CI && !force || shownThisProcess && !force) return;
|
|
336
|
+
try {
|
|
337
|
+
(0, import_node_fs.mkdirSync)(CACHE_DIR, { recursive: true });
|
|
338
|
+
const payload = readCache();
|
|
339
|
+
payload.runs += 1;
|
|
340
|
+
const now = Date.now();
|
|
341
|
+
const shouldShow = force || now - (payload.lastShownAt ?? 0) >= minIntervalMs;
|
|
342
|
+
if (shouldShow) {
|
|
343
|
+
payload.lastShownAt = now;
|
|
344
|
+
payload.lastReason = reason;
|
|
345
|
+
}
|
|
346
|
+
writeCache(payload);
|
|
347
|
+
if (!shouldShow) return;
|
|
348
|
+
shownThisProcess = true;
|
|
349
|
+
const tip = tips[payload.runs % tips.length];
|
|
350
|
+
console.log(
|
|
351
|
+
`
|
|
352
|
+
${cyan(`\u{1F680} DRZL finished a ${reason} run (#${payload.runs.toLocaleString()}).`)}
|
|
353
|
+
|
|
354
|
+
${green("\u2728 Sponsors keep DRZL shipping. Consider supporting ongoing dev:")}
|
|
355
|
+
${green("GitHub Sponsors")} ${gray("\u2192 https://github.com/sponsors/omar-dulaimi")}
|
|
356
|
+
|
|
357
|
+
${green("Pro tip:")} ${tip}
|
|
358
|
+
`
|
|
359
|
+
);
|
|
360
|
+
} catch {
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function readCache() {
|
|
364
|
+
if (!(0, import_node_fs.existsSync)(CACHE_FILE)) {
|
|
365
|
+
return { runs: 0 };
|
|
366
|
+
}
|
|
367
|
+
try {
|
|
368
|
+
const data = JSON.parse((0, import_node_fs.readFileSync)(CACHE_FILE, "utf8"));
|
|
369
|
+
if (typeof data.runs !== "number") return { runs: 0 };
|
|
370
|
+
return data;
|
|
371
|
+
} catch {
|
|
372
|
+
return { runs: 0 };
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
function writeCache(payload) {
|
|
376
|
+
(0, import_node_fs.writeFileSync)(CACHE_FILE, JSON.stringify(payload, null, 2), "utf8");
|
|
377
|
+
}
|
|
378
|
+
|
|
185
379
|
// src/cli.ts
|
|
186
380
|
var program = new import_commander.Command();
|
|
187
381
|
program.name("drzl").description("DRZL - Drizzle Developer Toolkit").version("0.0.1");
|
|
382
|
+
program.addHelpText(
|
|
383
|
+
"afterAll",
|
|
384
|
+
`
|
|
385
|
+
Need a template, adapter, or generator DRZL doesn't ship yet?
|
|
386
|
+
\u2192 DM @omardulaimidev on X: https://x.com/omardulaimidev
|
|
387
|
+
`
|
|
388
|
+
);
|
|
188
389
|
program.command("analyze").argument("<schema>", "path to drizzle schema (TS)").option("--relations", "include relations", true).option("--validate", "validate constraints", true).option("--out <file>", "write analysis JSON to file").option("--json", "print JSON to stdout (overrides --out)", false).action(async (schema, opts) => {
|
|
189
390
|
try {
|
|
190
391
|
const analyzer = new import_analyzer.SchemaAnalyzer(schema);
|
|
@@ -201,9 +402,9 @@ program.command("analyze").argument("<schema>", "path to drizzle schema (TS)").o
|
|
|
201
402
|
} else if (opts.out) {
|
|
202
403
|
const fs2 = await import("fs/promises");
|
|
203
404
|
await fs2.writeFile(opts.out, json, "utf8");
|
|
204
|
-
spinner?.succeed(
|
|
405
|
+
spinner?.succeed(import_chalk2.default.green(`Analysis written to ${opts.out} in ${ms}ms`));
|
|
205
406
|
} else {
|
|
206
|
-
spinner?.succeed(
|
|
407
|
+
spinner?.succeed(import_chalk2.default.green(`Analyzed in ${ms}ms`));
|
|
207
408
|
console.log(json);
|
|
208
409
|
}
|
|
209
410
|
process.exit(res.issues.some((i) => i.level === "error") ? 2 : 0);
|
|
@@ -213,7 +414,7 @@ program.command("analyze").argument("<schema>", "path to drizzle schema (TS)").o
|
|
|
213
414
|
console.log(JSON.stringify({ event: "error", code: "DRZL_CLI_ANALYZE", message: msg }));
|
|
214
415
|
else
|
|
215
416
|
console.error(
|
|
216
|
-
|
|
417
|
+
import_chalk2.default.red("Analyze failed (DRZL_CLI_ANALYZE):"),
|
|
217
418
|
msg,
|
|
218
419
|
"\nTip: run with --json for structured output."
|
|
219
420
|
);
|
|
@@ -225,7 +426,7 @@ program.command("generate").description("Run configured generators (drzl.config.
|
|
|
225
426
|
const cfg = await loadConfig(opts.config);
|
|
226
427
|
if (!cfg) {
|
|
227
428
|
console.error(
|
|
228
|
-
|
|
429
|
+
import_chalk2.default.red("No config found (DRZL_CFG_001). Create drzl.config.ts or pass --config.")
|
|
229
430
|
);
|
|
230
431
|
process.exit(2);
|
|
231
432
|
return;
|
|
@@ -256,12 +457,13 @@ program.command("generate").description("Run configured generators (drzl.config.
|
|
|
256
457
|
outputHeader: g.outputHeader,
|
|
257
458
|
format: g.format,
|
|
258
459
|
templateOptions: g.templateOptions,
|
|
460
|
+
importExtension: g.importExtension,
|
|
259
461
|
validation: g.validation,
|
|
260
462
|
onProgress: ({ index }) => progress.update(index)
|
|
261
463
|
});
|
|
262
464
|
progress.stop();
|
|
263
|
-
(0, import_ora.default)().succeed(
|
|
264
|
-
files.forEach((f) => console.log(" -",
|
|
465
|
+
(0, import_ora.default)().succeed(import_chalk2.default.green(`Generated (${g.kind}): ${files.length} files`));
|
|
466
|
+
files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
|
|
265
467
|
} else if (g.kind === "service") {
|
|
266
468
|
try {
|
|
267
469
|
const { ServiceGenerator } = await import("@drzl/generator-service");
|
|
@@ -273,18 +475,19 @@ program.command("generate").description("Run configured generators (drzl.config.
|
|
|
273
475
|
format: g.format,
|
|
274
476
|
dataAccess: g.dataAccess,
|
|
275
477
|
dbImportPath: g.dbImportPath,
|
|
276
|
-
schemaImportPath: g.schemaImportPath
|
|
478
|
+
schemaImportPath: g.schemaImportPath,
|
|
479
|
+
importExtension: g.importExtension
|
|
277
480
|
});
|
|
278
481
|
progress.stop();
|
|
279
|
-
(0, import_ora.default)().succeed(
|
|
280
|
-
files.forEach((f) => console.log(" -",
|
|
482
|
+
(0, import_ora.default)().succeed(import_chalk2.default.green(`Generated (service): ${files.length} files`));
|
|
483
|
+
files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
|
|
281
484
|
} catch (e) {
|
|
282
485
|
progress.stop();
|
|
283
486
|
console.error(
|
|
284
|
-
|
|
285
|
-
|
|
487
|
+
import_chalk2.default.red("Service generator missing."),
|
|
488
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-service")
|
|
286
489
|
);
|
|
287
|
-
console.error(
|
|
490
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
288
491
|
process.exit(1);
|
|
289
492
|
}
|
|
290
493
|
} else if (g.kind === "zod") {
|
|
@@ -297,18 +500,20 @@ program.command("generate").description("Run configured generators (drzl.config.
|
|
|
297
500
|
outputHeader: g.outputHeader,
|
|
298
501
|
format: g.format,
|
|
299
502
|
schemaSuffix: g.schemaSuffix,
|
|
300
|
-
fileSuffix: g.fileSuffix
|
|
503
|
+
fileSuffix: g.fileSuffix,
|
|
504
|
+
importExtension: g.importExtension,
|
|
505
|
+
affix: g.affix
|
|
301
506
|
});
|
|
302
507
|
progress.stop();
|
|
303
|
-
(0, import_ora.default)().succeed(
|
|
304
|
-
files.forEach((f) => console.log(" -",
|
|
508
|
+
(0, import_ora.default)().succeed(import_chalk2.default.green(`Generated (zod): ${files.length} files`));
|
|
509
|
+
files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
|
|
305
510
|
} catch (e) {
|
|
306
511
|
progress.stop();
|
|
307
512
|
console.error(
|
|
308
|
-
|
|
309
|
-
|
|
513
|
+
import_chalk2.default.red("Zod generator missing."),
|
|
514
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-zod")
|
|
310
515
|
);
|
|
311
|
-
console.error(
|
|
516
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
312
517
|
process.exit(1);
|
|
313
518
|
}
|
|
314
519
|
} else if (g.kind === "valibot") {
|
|
@@ -321,18 +526,20 @@ program.command("generate").description("Run configured generators (drzl.config.
|
|
|
321
526
|
outputHeader: g.outputHeader,
|
|
322
527
|
format: g.format,
|
|
323
528
|
schemaSuffix: g.schemaSuffix,
|
|
324
|
-
fileSuffix: g.fileSuffix
|
|
529
|
+
fileSuffix: g.fileSuffix,
|
|
530
|
+
importExtension: g.importExtension,
|
|
531
|
+
affix: g.affix
|
|
325
532
|
});
|
|
326
533
|
progress.stop();
|
|
327
|
-
(0, import_ora.default)().succeed(
|
|
328
|
-
files.forEach((f) => console.log(" -",
|
|
534
|
+
(0, import_ora.default)().succeed(import_chalk2.default.green(`Generated (valibot): ${files.length} files`));
|
|
535
|
+
files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
|
|
329
536
|
} catch (e) {
|
|
330
537
|
progress.stop();
|
|
331
538
|
console.error(
|
|
332
|
-
|
|
333
|
-
|
|
539
|
+
import_chalk2.default.red("Valibot generator missing."),
|
|
540
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-valibot")
|
|
334
541
|
);
|
|
335
|
-
console.error(
|
|
542
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
336
543
|
process.exit(1);
|
|
337
544
|
}
|
|
338
545
|
} else if (g.kind === "arktype") {
|
|
@@ -345,25 +552,30 @@ program.command("generate").description("Run configured generators (drzl.config.
|
|
|
345
552
|
outputHeader: g.outputHeader,
|
|
346
553
|
format: g.format,
|
|
347
554
|
schemaSuffix: g.schemaSuffix,
|
|
348
|
-
fileSuffix: g.fileSuffix
|
|
555
|
+
fileSuffix: g.fileSuffix,
|
|
556
|
+
importExtension: g.importExtension,
|
|
557
|
+
affix: g.affix
|
|
349
558
|
});
|
|
350
559
|
progress.stop();
|
|
351
|
-
(0, import_ora.default)().succeed(
|
|
352
|
-
files.forEach((f) => console.log(" -",
|
|
560
|
+
(0, import_ora.default)().succeed(import_chalk2.default.green(`Generated (arktype): ${files.length} files`));
|
|
561
|
+
files.forEach((f) => console.log(" -", import_chalk2.default.cyan(f)));
|
|
353
562
|
} catch (e) {
|
|
354
563
|
progress.stop();
|
|
355
564
|
console.error(
|
|
356
|
-
|
|
357
|
-
|
|
565
|
+
import_chalk2.default.red("ArkType generator missing."),
|
|
566
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-arktype")
|
|
358
567
|
);
|
|
359
|
-
console.error(
|
|
568
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
360
569
|
process.exit(1);
|
|
361
570
|
}
|
|
362
571
|
}
|
|
363
572
|
}
|
|
573
|
+
if (cfg.generators.length) {
|
|
574
|
+
maybeShowSponsorMessage({ reason: "generate" });
|
|
575
|
+
}
|
|
364
576
|
} catch (e) {
|
|
365
577
|
console.error(
|
|
366
|
-
|
|
578
|
+
import_chalk2.default.red("Generate failed (DRZL_GEN_001):"),
|
|
367
579
|
e?.message ?? e,
|
|
368
580
|
"\nTip: check your drzl.config.ts and template path."
|
|
369
581
|
);
|
|
@@ -383,23 +595,24 @@ program.command("generate:orpc").argument("<schema>", "path to drizzle schema (T
|
|
|
383
595
|
template: opts.template,
|
|
384
596
|
includeRelations: !!opts.includeRelations
|
|
385
597
|
});
|
|
386
|
-
console.log(
|
|
598
|
+
console.log(import_chalk2.default.green(`Generated:`), files.map((f) => import_chalk2.default.cyan(f)).join(", "));
|
|
599
|
+
maybeShowSponsorMessage({ reason: "generate:orpc" });
|
|
387
600
|
} catch (e) {
|
|
388
|
-
console.error(
|
|
601
|
+
console.error(import_chalk2.default.red("Generate orpc failed:"), e?.message ?? e);
|
|
389
602
|
process.exit(1);
|
|
390
603
|
}
|
|
391
604
|
});
|
|
392
605
|
program.command("watch").description("Watch schema and regenerate on changes").option("-c, --config <path>", "path to drzl.config").option("--pipeline <name>", "all | analyze | generate-orpc", "all").option("--debounce <ms>", "debounce ms", "200").option("--json", "emit JSON logs", false).option("--poll", "force polling (helps WSL/Docker/remote FS)", false).action(async (opts) => {
|
|
393
606
|
let cfg = await loadConfig(opts.config);
|
|
394
607
|
if (!cfg) {
|
|
395
|
-
console.error(
|
|
608
|
+
console.error(import_chalk2.default.red("No config found. Create drzl.config.ts or pass --config."));
|
|
396
609
|
process.exit(2);
|
|
397
610
|
return;
|
|
398
611
|
}
|
|
399
|
-
const abs = (p) =>
|
|
612
|
+
const abs = (p) => path3.resolve(process.cwd(), p);
|
|
400
613
|
const isInside = (child, parent) => {
|
|
401
|
-
const rel =
|
|
402
|
-
return !!rel && !rel.startsWith("..") && !
|
|
614
|
+
const rel = path3.relative(parent, child);
|
|
615
|
+
return !!rel && !rel.startsWith("..") && !path3.isAbsolute(rel);
|
|
403
616
|
};
|
|
404
617
|
const ignoredOutDirs = new Set(computeGeneratorOutputDirs(cfg).map(abs));
|
|
405
618
|
const currentTargets = new Set(computeWatchTargets(cfg).map(abs));
|
|
@@ -478,7 +691,7 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
478
691
|
})
|
|
479
692
|
);
|
|
480
693
|
} else {
|
|
481
|
-
console.log(
|
|
694
|
+
console.log(import_chalk2.default.green("Analyze complete."));
|
|
482
695
|
}
|
|
483
696
|
return;
|
|
484
697
|
}
|
|
@@ -497,11 +710,12 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
497
710
|
outputHeader: g.outputHeader,
|
|
498
711
|
format: g.format,
|
|
499
712
|
templateOptions: g.templateOptions,
|
|
713
|
+
importExtension: g.importExtension,
|
|
500
714
|
validation: g.validation
|
|
501
715
|
});
|
|
502
716
|
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
503
|
-
|
|
504
|
-
files.map((f) =>
|
|
717
|
+
import_chalk2.default.green(`Generated (${g.kind}):`),
|
|
718
|
+
files.map((f) => import_chalk2.default.cyan(f)).join(", ")
|
|
505
719
|
);
|
|
506
720
|
newFiles.push(...files);
|
|
507
721
|
} else if (g.kind === "service") {
|
|
@@ -515,19 +729,20 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
515
729
|
format: g.format,
|
|
516
730
|
dataAccess: g.dataAccess,
|
|
517
731
|
dbImportPath: g.dbImportPath,
|
|
518
|
-
schemaImportPath: g.schemaImportPath
|
|
732
|
+
schemaImportPath: g.schemaImportPath,
|
|
733
|
+
importExtension: g.importExtension
|
|
519
734
|
});
|
|
520
735
|
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
521
|
-
|
|
522
|
-
files.map((f) =>
|
|
736
|
+
import_chalk2.default.green(`Generated (service): ${files.length} files`),
|
|
737
|
+
files.map((f) => import_chalk2.default.cyan(f)).join(", ")
|
|
523
738
|
);
|
|
524
739
|
newFiles.push(...files);
|
|
525
740
|
} catch (e) {
|
|
526
741
|
console.error(
|
|
527
|
-
|
|
528
|
-
|
|
742
|
+
import_chalk2.default.red("Service generator missing."),
|
|
743
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-service")
|
|
529
744
|
);
|
|
530
|
-
console.error(
|
|
745
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
531
746
|
return;
|
|
532
747
|
}
|
|
533
748
|
} else if (g.kind === "zod") {
|
|
@@ -540,19 +755,21 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
540
755
|
outputHeader: g.outputHeader,
|
|
541
756
|
format: g.format,
|
|
542
757
|
schemaSuffix: g.schemaSuffix,
|
|
543
|
-
fileSuffix: g.fileSuffix
|
|
758
|
+
fileSuffix: g.fileSuffix,
|
|
759
|
+
importExtension: g.importExtension,
|
|
760
|
+
affix: g.affix
|
|
544
761
|
});
|
|
545
762
|
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
546
|
-
|
|
547
|
-
files.map((f) =>
|
|
763
|
+
import_chalk2.default.green(`Generated (zod): ${files.length} files`),
|
|
764
|
+
files.map((f) => import_chalk2.default.cyan(f)).join(", ")
|
|
548
765
|
);
|
|
549
766
|
newFiles.push(...files);
|
|
550
767
|
} catch (e) {
|
|
551
768
|
console.error(
|
|
552
|
-
|
|
553
|
-
|
|
769
|
+
import_chalk2.default.red("Zod generator missing."),
|
|
770
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-zod")
|
|
554
771
|
);
|
|
555
|
-
console.error(
|
|
772
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
556
773
|
return;
|
|
557
774
|
}
|
|
558
775
|
} else if (g.kind === "valibot") {
|
|
@@ -565,19 +782,21 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
565
782
|
outputHeader: g.outputHeader,
|
|
566
783
|
format: g.format,
|
|
567
784
|
schemaSuffix: g.schemaSuffix,
|
|
568
|
-
fileSuffix: g.fileSuffix
|
|
785
|
+
fileSuffix: g.fileSuffix,
|
|
786
|
+
importExtension: g.importExtension,
|
|
787
|
+
affix: g.affix
|
|
569
788
|
});
|
|
570
789
|
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
571
|
-
|
|
572
|
-
files.map((f) =>
|
|
790
|
+
import_chalk2.default.green(`Generated (valibot): ${files.length} files`),
|
|
791
|
+
files.map((f) => import_chalk2.default.cyan(f)).join(", ")
|
|
573
792
|
);
|
|
574
793
|
newFiles.push(...files);
|
|
575
794
|
} catch (e) {
|
|
576
795
|
console.error(
|
|
577
|
-
|
|
578
|
-
|
|
796
|
+
import_chalk2.default.red("Valibot generator missing."),
|
|
797
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-valibot")
|
|
579
798
|
);
|
|
580
|
-
console.error(
|
|
799
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
581
800
|
return;
|
|
582
801
|
}
|
|
583
802
|
} else if (g.kind === "arktype") {
|
|
@@ -590,19 +809,21 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
590
809
|
outputHeader: g.outputHeader,
|
|
591
810
|
format: g.format,
|
|
592
811
|
schemaSuffix: g.schemaSuffix,
|
|
593
|
-
fileSuffix: g.fileSuffix
|
|
812
|
+
fileSuffix: g.fileSuffix,
|
|
813
|
+
importExtension: g.importExtension,
|
|
814
|
+
affix: g.affix
|
|
594
815
|
});
|
|
595
816
|
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
596
|
-
|
|
597
|
-
files.map((f) =>
|
|
817
|
+
import_chalk2.default.green(`Generated (arktype): ${files.length} files`),
|
|
818
|
+
files.map((f) => import_chalk2.default.cyan(f)).join(", ")
|
|
598
819
|
);
|
|
599
820
|
newFiles.push(...files);
|
|
600
821
|
} catch (e) {
|
|
601
822
|
console.error(
|
|
602
|
-
|
|
603
|
-
|
|
823
|
+
import_chalk2.default.red("ArkType generator missing."),
|
|
824
|
+
import_chalk2.default.yellow("\nInstall with: npm install @drzl/generator-arktype")
|
|
604
825
|
);
|
|
605
|
-
console.error(
|
|
826
|
+
console.error(import_chalk2.default.gray("Error details:"), e?.message ?? e);
|
|
606
827
|
return;
|
|
607
828
|
}
|
|
608
829
|
}
|
|
@@ -610,12 +831,16 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
610
831
|
const added = newFiles.filter((f) => !lastFiles.includes(f));
|
|
611
832
|
const removed = lastFiles.filter((f) => !newFiles.includes(f));
|
|
612
833
|
opts.json ? console.log(JSON.stringify({ event: "diff", added, removed })) : (() => {
|
|
613
|
-
if (added.length) console.log(
|
|
614
|
-
if (removed.length) console.log(
|
|
834
|
+
if (added.length) console.log(import_chalk2.default.blue(`Added: ${added.join(", ")}`));
|
|
835
|
+
if (removed.length) console.log(import_chalk2.default.yellow(`Removed: ${removed.join(", ")}`));
|
|
615
836
|
})();
|
|
837
|
+
if (newFiles.length && !opts.json) {
|
|
838
|
+
const reason = opts.pipeline && opts.pipeline !== "all" ? `watch:${opts.pipeline}` : "watch";
|
|
839
|
+
maybeShowSponsorMessage({ reason });
|
|
840
|
+
}
|
|
616
841
|
lastFiles = newFiles;
|
|
617
842
|
} catch (e) {
|
|
618
|
-
opts.json ? console.log(JSON.stringify({ event: "error", message: String(e?.message ?? e) })) : console.error(
|
|
843
|
+
opts.json ? console.log(JSON.stringify({ event: "error", message: String(e?.message ?? e) })) : console.error(import_chalk2.default.red("Watch pipeline failed:"), e?.message ?? e);
|
|
619
844
|
}
|
|
620
845
|
};
|
|
621
846
|
const debounced = Number(opts.debounce) || 200;
|
|
@@ -640,18 +865,18 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
640
865
|
);
|
|
641
866
|
} else {
|
|
642
867
|
console.log(
|
|
643
|
-
|
|
644
|
-
"Watching:\n " + Array.from(currentTargets).map((p) =>
|
|
868
|
+
import_chalk2.default.gray(
|
|
869
|
+
"Watching:\n " + Array.from(currentTargets).map((p) => path3.relative(process.cwd(), p)).join("\n ")
|
|
645
870
|
)
|
|
646
871
|
);
|
|
647
872
|
}
|
|
648
|
-
watcher.on("add", (p) => trigger(p)).on("change", (p) => trigger(p)).on("unlink", (p) => trigger(p)).on("error", (err) => console.error(
|
|
873
|
+
watcher.on("add", (p) => trigger(p)).on("change", (p) => trigger(p)).on("unlink", (p) => trigger(p)).on("error", (err) => console.error(import_chalk2.default.red("Watcher error:"), err));
|
|
649
874
|
await run();
|
|
650
875
|
});
|
|
651
876
|
program.command("init").description("Scaffold a drzl.config.ts").option("-y, --yes", "accept defaults").action(async (_opts) => {
|
|
652
877
|
const fs2 = await import("fs/promises");
|
|
653
|
-
const
|
|
654
|
-
const target =
|
|
878
|
+
const path4 = await import("path");
|
|
879
|
+
const target = path4.resolve(process.cwd(), "drzl.config.ts");
|
|
655
880
|
const template = `export default {
|
|
656
881
|
schema: 'src/db/schema.ts',
|
|
657
882
|
outDir: 'src/api',
|
|
@@ -663,9 +888,9 @@ program.command("init").description("Scaffold a drzl.config.ts").option("-y, --y
|
|
|
663
888
|
`;
|
|
664
889
|
try {
|
|
665
890
|
await fs2.writeFile(target, template, { flag: "wx" });
|
|
666
|
-
console.log(
|
|
891
|
+
console.log(import_chalk2.default.green(`Created ${target}`));
|
|
667
892
|
} catch (e) {
|
|
668
|
-
console.error(
|
|
893
|
+
console.error(import_chalk2.default.red("Init failed:"), e?.message ?? e);
|
|
669
894
|
process.exit(1);
|
|
670
895
|
}
|
|
671
896
|
});
|