@drzl/cli 0.2.0 → 0.3.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 +4 -4
- package/dist/chunk-MEPFGJIF.js +164 -0
- package/dist/chunk-MEPFGJIF.js.map +1 -0
- package/dist/cli.cjs +299 -68
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +213 -35
- package/dist/cli.js.map +1 -1
- package/dist/config.cjs +92 -31
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +7 -1
- package/dist/config.d.ts +7 -1
- package/dist/config.js +9 -3
- package/package.json +7 -7
- package/dist/chunk-AWFAECUZ.js +0 -105
- package/dist/chunk-AWFAECUZ.js.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -24,14 +24,20 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/cli.ts
|
|
27
|
-
var
|
|
27
|
+
var import_analyzer = require("@drzl/analyzer");
|
|
28
|
+
var import_generator_orpc = require("@drzl/generator-orpc");
|
|
28
29
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
29
|
-
var
|
|
30
|
+
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
30
31
|
var import_cli_progress = __toESM(require("cli-progress"), 1);
|
|
32
|
+
var import_commander = require("commander");
|
|
33
|
+
var path2 = __toESM(require("path"), 1);
|
|
34
|
+
var import_ora = __toESM(require("ora"), 1);
|
|
31
35
|
|
|
32
36
|
// src/config.ts
|
|
37
|
+
var fs = __toESM(require("fs"), 1);
|
|
38
|
+
var import_node_module = require("module");
|
|
39
|
+
var path = __toESM(require("path"), 1);
|
|
33
40
|
var import_zod = require("zod");
|
|
34
|
-
var import_meta = {};
|
|
35
41
|
var NamingSchema = import_zod.z.object({
|
|
36
42
|
routerSuffix: import_zod.z.string().default("Router"),
|
|
37
43
|
procedureCase: import_zod.z.enum(["camel", "kebab", "snake"]).default("camel")
|
|
@@ -55,7 +61,7 @@ var GeneratorSchema = import_zod.z.object({
|
|
|
55
61
|
dataAccess: import_zod.z.enum(["stub", "drizzle"]).default("stub").optional(),
|
|
56
62
|
dbImportPath: import_zod.z.string().optional(),
|
|
57
63
|
schemaImportPath: import_zod.z.string().optional(),
|
|
58
|
-
// zod generator specific options
|
|
64
|
+
// zod/valibot/arktype generator specific options
|
|
59
65
|
schemaSuffix: import_zod.z.string().optional(),
|
|
60
66
|
fileSuffix: import_zod.z.string().optional(),
|
|
61
67
|
// orpc validation sharing
|
|
@@ -84,49 +90,99 @@ var ConfigSchema = import_zod.z.object({
|
|
|
84
90
|
generators: import_zod.z.array(GeneratorSchema).min(1).default([{ kind: "orpc" }])
|
|
85
91
|
});
|
|
86
92
|
async function loadConfig(customPath) {
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
|
|
93
|
+
const fsp = await import("fs/promises");
|
|
94
|
+
const candidates = customPath ? [customPath] : [
|
|
95
|
+
"drzl.config.ts",
|
|
96
|
+
"drzl.config.mjs",
|
|
97
|
+
"drzl.config.js",
|
|
98
|
+
"drzl.config.cjs",
|
|
99
|
+
"drzl.config.json"
|
|
100
|
+
];
|
|
90
101
|
for (const c of candidates) {
|
|
91
102
|
const p = path.resolve(process.cwd(), c);
|
|
92
103
|
try {
|
|
93
|
-
await
|
|
104
|
+
await fsp.access(p);
|
|
94
105
|
} catch {
|
|
95
106
|
continue;
|
|
96
107
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return ConfigSchema.parse(raw);
|
|
102
|
-
} catch (e2) {
|
|
103
|
-
throw new Error(`Failed to load config from ${p}: ${String(e2)}`);
|
|
104
|
-
}
|
|
108
|
+
const ext = path.extname(p).toLowerCase();
|
|
109
|
+
if (ext === ".json") {
|
|
110
|
+
const raw2 = JSON.parse(await fsp.readFile(p, "utf8"));
|
|
111
|
+
return ConfigSchema.parse(raw2);
|
|
105
112
|
}
|
|
113
|
+
const { createJiti } = await import("jiti");
|
|
114
|
+
const stat = await fsp.stat(p);
|
|
115
|
+
const base = typeof __filename !== "undefined" ? __filename : path.join(process.cwd(), "index.js");
|
|
116
|
+
const jiti = createJiti(base, {
|
|
117
|
+
moduleCache: false,
|
|
118
|
+
// re-evaluate each time
|
|
119
|
+
fsCache: true,
|
|
120
|
+
// keep transform cache
|
|
121
|
+
cacheVersion: String(stat.mtimeMs),
|
|
122
|
+
// bump on edit
|
|
123
|
+
interopDefault: true,
|
|
124
|
+
tryNative: false
|
|
125
|
+
// <— prevent native import of .ts
|
|
126
|
+
// debug: true,
|
|
127
|
+
});
|
|
128
|
+
const mod = await jiti.import(p);
|
|
129
|
+
const raw = mod?.default ?? mod;
|
|
130
|
+
return ConfigSchema.parse(raw);
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
function computeGeneratorOutputDirs(cfg, cwd = process.cwd()) {
|
|
135
|
+
const abs = (p) => path.resolve(cwd, p);
|
|
136
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
137
|
+
dirs.add(abs(cfg.outDir));
|
|
138
|
+
for (const g of cfg.generators) {
|
|
139
|
+
if (g.kind === "service") dirs.add(abs(g.path ?? "src/services"));
|
|
140
|
+
if (g.kind === "zod") dirs.add(abs(g.path ?? "src/validators/zod"));
|
|
141
|
+
if (g.kind === "valibot") dirs.add(abs(g.path ?? "src/validators/valibot"));
|
|
142
|
+
if (g.kind === "arktype") dirs.add(abs(g.path ?? "src/validators/arktype"));
|
|
143
|
+
}
|
|
144
|
+
return [...dirs];
|
|
145
|
+
}
|
|
146
|
+
function resolveTemplateDirsSync(cfg, cwd = process.cwd()) {
|
|
147
|
+
const results = [];
|
|
148
|
+
const req = (0, import_node_module.createRequire)(
|
|
149
|
+
typeof __filename !== "undefined" ? __filename : path.join(process.cwd(), "index.js")
|
|
150
|
+
);
|
|
151
|
+
for (const g of cfg.generators) {
|
|
152
|
+
const t = g.template;
|
|
153
|
+
if (!t || t === "standard" || t === "minimal") continue;
|
|
154
|
+
let pkgDir = null;
|
|
106
155
|
try {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
} catch (e2) {
|
|
119
|
-
throw new Error(`Failed to load config from ${p}: ${String(e2)}`);
|
|
120
|
-
}
|
|
156
|
+
const pkg = req.resolve(`${t}/package.json`, { paths: [cwd] });
|
|
157
|
+
pkgDir = path.dirname(pkg);
|
|
158
|
+
} catch {
|
|
159
|
+
}
|
|
160
|
+
if (pkgDir) {
|
|
161
|
+
results.push(pkgDir);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (/[./\\]/.test(t)) {
|
|
165
|
+
const abs = path.resolve(cwd, t);
|
|
166
|
+
if (fs.existsSync(abs)) results.push(abs);
|
|
121
167
|
}
|
|
122
168
|
}
|
|
123
|
-
return
|
|
169
|
+
return Array.from(new Set(results));
|
|
170
|
+
}
|
|
171
|
+
function computeWatchTargets(cfg, cwd = process.cwd()) {
|
|
172
|
+
const abs = (p) => path.resolve(cwd, p);
|
|
173
|
+
const schemaAbs = abs(cfg.schema);
|
|
174
|
+
const targets = /* @__PURE__ */ new Set([
|
|
175
|
+
path.join(path.dirname(schemaAbs), "**/*.{ts,tsx,js}"),
|
|
176
|
+
abs("drzl.config.ts"),
|
|
177
|
+
abs("drzl.config.js"),
|
|
178
|
+
abs("drzl.config.mjs"),
|
|
179
|
+
abs("drzl.config.cjs")
|
|
180
|
+
]);
|
|
181
|
+
for (const t of resolveTemplateDirsSync(cfg, cwd)) targets.add(t);
|
|
182
|
+
return [...targets];
|
|
124
183
|
}
|
|
125
184
|
|
|
126
185
|
// src/cli.ts
|
|
127
|
-
var import_analyzer = require("@drzl/analyzer");
|
|
128
|
-
var import_generator_orpc = require("@drzl/generator-orpc");
|
|
129
|
-
var import_chokidar = __toESM(require("chokidar"), 1);
|
|
130
186
|
var program = new import_commander.Command();
|
|
131
187
|
program.name("drzl").description("DRZL - Drizzle Developer Toolkit").version("0.0.1");
|
|
132
188
|
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) => {
|
|
@@ -143,8 +199,8 @@ program.command("analyze").argument("<schema>", "path to drizzle schema (TS)").o
|
|
|
143
199
|
if (opts.json) {
|
|
144
200
|
console.log(json);
|
|
145
201
|
} else if (opts.out) {
|
|
146
|
-
const
|
|
147
|
-
await
|
|
202
|
+
const fs2 = await import("fs/promises");
|
|
203
|
+
await fs2.writeFile(opts.out, json, "utf8");
|
|
148
204
|
spinner?.succeed(import_chalk.default.green(`Analysis written to ${opts.out} in ${ms}ms`));
|
|
149
205
|
} else {
|
|
150
206
|
spinner?.succeed(import_chalk.default.green(`Analyzed in ${ms}ms`));
|
|
@@ -333,21 +389,84 @@ program.command("generate:orpc").argument("<schema>", "path to drizzle schema (T
|
|
|
333
389
|
process.exit(1);
|
|
334
390
|
}
|
|
335
391
|
});
|
|
336
|
-
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).action(async (opts) => {
|
|
337
|
-
|
|
392
|
+
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
|
+
let cfg = await loadConfig(opts.config);
|
|
338
394
|
if (!cfg) {
|
|
339
395
|
console.error(import_chalk.default.red("No config found. Create drzl.config.ts or pass --config."));
|
|
340
396
|
process.exit(2);
|
|
341
397
|
return;
|
|
342
398
|
}
|
|
399
|
+
const abs = (p) => path2.resolve(process.cwd(), p);
|
|
400
|
+
const isInside = (child, parent) => {
|
|
401
|
+
const rel = path2.relative(parent, child);
|
|
402
|
+
return !!rel && !rel.startsWith("..") && !path2.isAbsolute(rel);
|
|
403
|
+
};
|
|
404
|
+
const ignoredOutDirs = new Set(computeGeneratorOutputDirs(cfg).map(abs));
|
|
405
|
+
const currentTargets = new Set(computeWatchTargets(cfg).map(abs));
|
|
406
|
+
const syncWatcherTargets = (watcher2, next) => {
|
|
407
|
+
const add = [];
|
|
408
|
+
const del = [];
|
|
409
|
+
for (const p of next) if (!currentTargets.has(p)) add.push(p);
|
|
410
|
+
for (const p of currentTargets) if (!next.has(p)) del.push(p);
|
|
411
|
+
if (add.length) watcher2.add(add);
|
|
412
|
+
if (del.length) watcher2.unwatch(del);
|
|
413
|
+
currentTargets.clear();
|
|
414
|
+
next.forEach((p) => currentTargets.add(p));
|
|
415
|
+
};
|
|
416
|
+
const rebuildIgnoreDirsFrom = (cfgNow) => {
|
|
417
|
+
ignoredOutDirs.clear();
|
|
418
|
+
for (const d of computeGeneratorOutputDirs(cfgNow)) ignoredOutDirs.add(abs(d));
|
|
419
|
+
};
|
|
420
|
+
const ignoredFn = (p) => {
|
|
421
|
+
const full = abs(p);
|
|
422
|
+
for (const dir of ignoredOutDirs) {
|
|
423
|
+
if (full === dir || isInside(full, dir)) return true;
|
|
424
|
+
}
|
|
425
|
+
return false;
|
|
426
|
+
};
|
|
427
|
+
const watcher = import_chokidar.default.watch(Array.from(currentTargets), {
|
|
428
|
+
ignoreInitial: true,
|
|
429
|
+
awaitWriteFinish: { stabilityThreshold: 400, pollInterval: 50 },
|
|
430
|
+
usePolling: !!opts.poll,
|
|
431
|
+
ignored: ignoredFn
|
|
432
|
+
});
|
|
433
|
+
const logTrigger = (type, file) => {
|
|
434
|
+
if (opts.json) console.log(JSON.stringify({ event: "trigger", type, file }));
|
|
435
|
+
};
|
|
436
|
+
watcher.on("add", (p) => {
|
|
437
|
+
logTrigger("add", p);
|
|
438
|
+
trigger(p);
|
|
439
|
+
}).on("change", (p) => {
|
|
440
|
+
logTrigger("change", p);
|
|
441
|
+
trigger(p);
|
|
442
|
+
}).on("unlink", (p) => {
|
|
443
|
+
logTrigger("unlink", p);
|
|
444
|
+
trigger(p);
|
|
445
|
+
});
|
|
343
446
|
let lastFiles = [];
|
|
344
447
|
const run = async () => {
|
|
345
448
|
try {
|
|
449
|
+
const reloaded = await loadConfig(opts.config);
|
|
450
|
+
if (!reloaded) throw new Error("Config disappeared during watch.");
|
|
451
|
+
cfg = reloaded;
|
|
452
|
+
rebuildIgnoreDirsFrom(cfg);
|
|
453
|
+
const nextTargets = new Set(computeWatchTargets(cfg).map(abs));
|
|
454
|
+
syncWatcherTargets(watcher, nextTargets);
|
|
346
455
|
if (!opts.json) console.clear();
|
|
456
|
+
if (opts.json) {
|
|
457
|
+
console.log(
|
|
458
|
+
JSON.stringify({
|
|
459
|
+
event: "watch_config_applied",
|
|
460
|
+
targets: Array.from(currentTargets),
|
|
461
|
+
ignored: Array.from(ignoredOutDirs)
|
|
462
|
+
})
|
|
463
|
+
);
|
|
464
|
+
}
|
|
347
465
|
const analyzer = new import_analyzer.SchemaAnalyzer(cfg.schema);
|
|
348
466
|
const analysis = await analyzer.analyze({
|
|
349
467
|
includeRelations: cfg.analyzer.includeRelations,
|
|
350
|
-
validateConstraints: cfg.analyzer.validateConstraints
|
|
468
|
+
validateConstraints: cfg.analyzer.validateConstraints,
|
|
469
|
+
includeHeuristicRelations: cfg.analyzer.includeHeuristicRelations
|
|
351
470
|
});
|
|
352
471
|
if (opts.pipeline === "analyze") {
|
|
353
472
|
if (opts.json) {
|
|
@@ -365,62 +484,174 @@ program.command("watch").description("Watch schema and regenerate on changes").o
|
|
|
365
484
|
}
|
|
366
485
|
const newFiles = [];
|
|
367
486
|
for (const g of cfg.generators) {
|
|
368
|
-
if (
|
|
487
|
+
if (opts.pipeline !== "all" && !(opts.pipeline === "generate-orpc" && g.kind === "orpc")) {
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
if (g.kind === "orpc") {
|
|
369
491
|
const gen = new import_generator_orpc.ORPCGenerator(analysis);
|
|
370
492
|
const { files } = await gen.generate({
|
|
371
493
|
outputDir: cfg.outDir,
|
|
372
494
|
template: g.template,
|
|
373
495
|
includeRelations: g.includeRelations,
|
|
374
|
-
naming: g.naming
|
|
496
|
+
naming: g.naming,
|
|
497
|
+
outputHeader: g.outputHeader,
|
|
498
|
+
format: g.format,
|
|
499
|
+
templateOptions: g.templateOptions,
|
|
500
|
+
validation: g.validation
|
|
375
501
|
});
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
502
|
+
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
503
|
+
import_chalk.default.green(`Generated (${g.kind}):`),
|
|
504
|
+
files.map((f) => import_chalk.default.cyan(f)).join(", ")
|
|
505
|
+
);
|
|
506
|
+
newFiles.push(...files);
|
|
507
|
+
} else if (g.kind === "service") {
|
|
508
|
+
try {
|
|
509
|
+
const { ServiceGenerator } = await import("@drzl/generator-service");
|
|
510
|
+
const gen = new ServiceGenerator(analysis);
|
|
511
|
+
const target = g.path ?? "src/services";
|
|
512
|
+
const files = await gen.generate({
|
|
513
|
+
outDir: target,
|
|
514
|
+
outputHeader: g.outputHeader,
|
|
515
|
+
format: g.format,
|
|
516
|
+
dataAccess: g.dataAccess,
|
|
517
|
+
dbImportPath: g.dbImportPath,
|
|
518
|
+
schemaImportPath: g.schemaImportPath
|
|
519
|
+
});
|
|
520
|
+
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
521
|
+
import_chalk.default.green(`Generated (service): ${files.length} files`),
|
|
381
522
|
files.map((f) => import_chalk.default.cyan(f)).join(", ")
|
|
382
523
|
);
|
|
524
|
+
newFiles.push(...files);
|
|
525
|
+
} catch (e) {
|
|
526
|
+
console.error(
|
|
527
|
+
import_chalk.default.red("Service generator missing."),
|
|
528
|
+
import_chalk.default.yellow("\nInstall with: npm install @drzl/generator-service")
|
|
529
|
+
);
|
|
530
|
+
console.error(import_chalk.default.gray("Error details:"), e?.message ?? e);
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
} else if (g.kind === "zod") {
|
|
534
|
+
try {
|
|
535
|
+
const { ZodGenerator } = await import("@drzl/generator-zod");
|
|
536
|
+
const gen = new ZodGenerator(analysis);
|
|
537
|
+
const target = g.path ?? "src/validators/zod";
|
|
538
|
+
const files = await gen.generate({
|
|
539
|
+
outDir: target,
|
|
540
|
+
outputHeader: g.outputHeader,
|
|
541
|
+
format: g.format,
|
|
542
|
+
schemaSuffix: g.schemaSuffix,
|
|
543
|
+
fileSuffix: g.fileSuffix
|
|
544
|
+
});
|
|
545
|
+
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
546
|
+
import_chalk.default.green(`Generated (zod): ${files.length} files`),
|
|
547
|
+
files.map((f) => import_chalk.default.cyan(f)).join(", ")
|
|
548
|
+
);
|
|
549
|
+
newFiles.push(...files);
|
|
550
|
+
} catch (e) {
|
|
551
|
+
console.error(
|
|
552
|
+
import_chalk.default.red("Zod generator missing."),
|
|
553
|
+
import_chalk.default.yellow("\nInstall with: npm install @drzl/generator-zod")
|
|
554
|
+
);
|
|
555
|
+
console.error(import_chalk.default.gray("Error details:"), e?.message ?? e);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
} else if (g.kind === "valibot") {
|
|
559
|
+
try {
|
|
560
|
+
const { ValibotGenerator } = await import("@drzl/generator-valibot");
|
|
561
|
+
const gen = new ValibotGenerator(analysis);
|
|
562
|
+
const target = g.path ?? "src/validators/valibot";
|
|
563
|
+
const files = await gen.generate({
|
|
564
|
+
outDir: target,
|
|
565
|
+
outputHeader: g.outputHeader,
|
|
566
|
+
format: g.format,
|
|
567
|
+
schemaSuffix: g.schemaSuffix,
|
|
568
|
+
fileSuffix: g.fileSuffix
|
|
569
|
+
});
|
|
570
|
+
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
571
|
+
import_chalk.default.green(`Generated (valibot): ${files.length} files`),
|
|
572
|
+
files.map((f) => import_chalk.default.cyan(f)).join(", ")
|
|
573
|
+
);
|
|
574
|
+
newFiles.push(...files);
|
|
575
|
+
} catch (e) {
|
|
576
|
+
console.error(
|
|
577
|
+
import_chalk.default.red("Valibot generator missing."),
|
|
578
|
+
import_chalk.default.yellow("\nInstall with: npm install @drzl/generator-valibot")
|
|
579
|
+
);
|
|
580
|
+
console.error(import_chalk.default.gray("Error details:"), e?.message ?? e);
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
} else if (g.kind === "arktype") {
|
|
584
|
+
try {
|
|
585
|
+
const { ArkTypeGenerator } = await import("@drzl/generator-arktype");
|
|
586
|
+
const gen = new ArkTypeGenerator(analysis);
|
|
587
|
+
const target = g.path ?? "src/validators/arktype";
|
|
588
|
+
const files = await gen.generate({
|
|
589
|
+
outDir: target,
|
|
590
|
+
outputHeader: g.outputHeader,
|
|
591
|
+
format: g.format,
|
|
592
|
+
schemaSuffix: g.schemaSuffix,
|
|
593
|
+
fileSuffix: g.fileSuffix
|
|
594
|
+
});
|
|
595
|
+
opts.json ? console.log(JSON.stringify({ event: "generate_complete", kind: g.kind, files })) : console.log(
|
|
596
|
+
import_chalk.default.green(`Generated (arktype): ${files.length} files`),
|
|
597
|
+
files.map((f) => import_chalk.default.cyan(f)).join(", ")
|
|
598
|
+
);
|
|
599
|
+
newFiles.push(...files);
|
|
600
|
+
} catch (e) {
|
|
601
|
+
console.error(
|
|
602
|
+
import_chalk.default.red("ArkType generator missing."),
|
|
603
|
+
import_chalk.default.yellow("\nInstall with: npm install @drzl/generator-arktype")
|
|
604
|
+
);
|
|
605
|
+
console.error(import_chalk.default.gray("Error details:"), e?.message ?? e);
|
|
606
|
+
return;
|
|
383
607
|
}
|
|
384
|
-
newFiles.push(...files);
|
|
385
608
|
}
|
|
386
609
|
}
|
|
387
610
|
const added = newFiles.filter((f) => !lastFiles.includes(f));
|
|
388
611
|
const removed = lastFiles.filter((f) => !newFiles.includes(f));
|
|
389
|
-
|
|
390
|
-
console.log(JSON.stringify({ event: "diff", added, removed }));
|
|
391
|
-
} else {
|
|
612
|
+
opts.json ? console.log(JSON.stringify({ event: "diff", added, removed })) : (() => {
|
|
392
613
|
if (added.length) console.log(import_chalk.default.blue(`Added: ${added.join(", ")}`));
|
|
393
614
|
if (removed.length) console.log(import_chalk.default.yellow(`Removed: ${removed.join(", ")}`));
|
|
394
|
-
}
|
|
615
|
+
})();
|
|
395
616
|
lastFiles = newFiles;
|
|
396
617
|
} catch (e) {
|
|
397
|
-
|
|
398
|
-
console.log(JSON.stringify({ event: "error", message: String(e?.message ?? e) }));
|
|
399
|
-
else console.error(import_chalk.default.red("Watch pipeline failed:"), e?.message ?? e);
|
|
618
|
+
opts.json ? console.log(JSON.stringify({ event: "error", message: String(e?.message ?? e) })) : console.error(import_chalk.default.red("Watch pipeline failed:"), e?.message ?? e);
|
|
400
619
|
}
|
|
401
620
|
};
|
|
402
621
|
const debounced = Number(opts.debounce) || 200;
|
|
403
622
|
let timer = null;
|
|
404
623
|
const trigger = (file) => {
|
|
405
|
-
if (file
|
|
406
|
-
|
|
624
|
+
if (file) {
|
|
625
|
+
const full = abs(file);
|
|
626
|
+
for (const dir of ignoredOutDirs) {
|
|
627
|
+
if (full === dir || isInside(full, dir)) return;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
if (timer) clearTimeout(timer);
|
|
407
631
|
timer = setTimeout(run, debounced);
|
|
408
632
|
};
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
633
|
+
if (opts.json) {
|
|
634
|
+
console.log(
|
|
635
|
+
JSON.stringify({
|
|
636
|
+
event: "watching",
|
|
637
|
+
targets: Array.from(currentTargets),
|
|
638
|
+
ignored: Array.from(ignoredOutDirs)
|
|
639
|
+
})
|
|
640
|
+
);
|
|
641
|
+
} else {
|
|
642
|
+
console.log(
|
|
643
|
+
import_chalk.default.gray(
|
|
644
|
+
"Watching:\n " + Array.from(currentTargets).map((p) => path2.relative(process.cwd(), p)).join("\n ")
|
|
645
|
+
)
|
|
646
|
+
);
|
|
415
647
|
}
|
|
416
|
-
|
|
417
|
-
import_chokidar.default.watch(Array.from(watchSet), { ignoreInitial: true }).on("add", (p) => trigger(p)).on("change", (p) => trigger(p)).on("unlink", (p) => trigger(p));
|
|
648
|
+
watcher.on("add", (p) => trigger(p)).on("change", (p) => trigger(p)).on("unlink", (p) => trigger(p)).on("error", (err) => console.error(import_chalk.default.red("Watcher error:"), err));
|
|
418
649
|
await run();
|
|
419
650
|
});
|
|
420
651
|
program.command("init").description("Scaffold a drzl.config.ts").option("-y, --yes", "accept defaults").action(async (_opts) => {
|
|
421
|
-
const
|
|
422
|
-
const
|
|
423
|
-
const target =
|
|
652
|
+
const fs2 = await import("fs/promises");
|
|
653
|
+
const path3 = await import("path");
|
|
654
|
+
const target = path3.resolve(process.cwd(), "drzl.config.ts");
|
|
424
655
|
const template = `export default {
|
|
425
656
|
schema: 'src/db/schema.ts',
|
|
426
657
|
outDir: 'src/api',
|
|
@@ -431,7 +662,7 @@ program.command("init").description("Scaffold a drzl.config.ts").option("-y, --y
|
|
|
431
662
|
} as const
|
|
432
663
|
`;
|
|
433
664
|
try {
|
|
434
|
-
await
|
|
665
|
+
await fs2.writeFile(target, template, { flag: "wx" });
|
|
435
666
|
console.log(import_chalk.default.green(`Created ${target}`));
|
|
436
667
|
} catch (e) {
|
|
437
668
|
console.error(import_chalk.default.red("Init failed:"), e?.message ?? e);
|