@forinda/kickjs-cli 1.2.0 → 1.2.2
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/dist/cli.js +73 -30
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -22,7 +22,13 @@ import { fileURLToPath } from "url";
|
|
|
22
22
|
// src/utils/fs.ts
|
|
23
23
|
import { writeFile, mkdir, access, readFile } from "fs/promises";
|
|
24
24
|
import { dirname } from "path";
|
|
25
|
+
var _dryRun = false;
|
|
26
|
+
function setDryRun(enabled) {
|
|
27
|
+
_dryRun = enabled;
|
|
28
|
+
}
|
|
29
|
+
__name(setDryRun, "setDryRun");
|
|
25
30
|
async function writeFileSafe(filePath, content) {
|
|
31
|
+
if (_dryRun) return;
|
|
26
32
|
await mkdir(dirname(filePath), {
|
|
27
33
|
recursive: true
|
|
28
34
|
});
|
|
@@ -1926,7 +1932,7 @@ function promptUser(question) {
|
|
|
1926
1932
|
}
|
|
1927
1933
|
__name(promptUser, "promptUser");
|
|
1928
1934
|
async function generateModule(options) {
|
|
1929
|
-
const { name, modulesDir, noEntity, noTests, repo = "inmemory", force } = options;
|
|
1935
|
+
const { name, modulesDir, noEntity, noTests, repo = "inmemory", force, dryRun } = options;
|
|
1930
1936
|
let pattern = options.pattern ?? "ddd";
|
|
1931
1937
|
if (options.minimal) pattern = "minimal";
|
|
1932
1938
|
const kebab = toKebabCase(name);
|
|
@@ -1938,6 +1944,10 @@ async function generateModule(options) {
|
|
|
1938
1944
|
let overwriteAll = force ?? false;
|
|
1939
1945
|
const write = /* @__PURE__ */ __name(async (relativePath, content) => {
|
|
1940
1946
|
const fullPath = join2(moduleDir, relativePath);
|
|
1947
|
+
if (dryRun) {
|
|
1948
|
+
files.push(fullPath);
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1941
1951
|
if (!overwriteAll && await fileExists(fullPath)) {
|
|
1942
1952
|
const answer = await promptUser(` File already exists: ${relativePath}
|
|
1943
1953
|
Overwrite? (y/n/a = yes/no/all) `);
|
|
@@ -1979,7 +1989,9 @@ async function generateModule(options) {
|
|
|
1979
1989
|
await generateDddFiles(ctx);
|
|
1980
1990
|
break;
|
|
1981
1991
|
}
|
|
1982
|
-
|
|
1992
|
+
if (!dryRun) {
|
|
1993
|
+
await autoRegisterModule(modulesDir, pascal, plural);
|
|
1994
|
+
}
|
|
1983
1995
|
return files;
|
|
1984
1996
|
}
|
|
1985
1997
|
__name(generateModule, "generateModule");
|
|
@@ -3299,13 +3311,19 @@ async function loadKickConfig(cwd) {
|
|
|
3299
3311
|
__name(loadKickConfig, "loadKickConfig");
|
|
3300
3312
|
|
|
3301
3313
|
// src/commands/generate.ts
|
|
3302
|
-
function
|
|
3314
|
+
function isDryRun(cmd) {
|
|
3315
|
+
return cmd.parent?.opts()?.dryRun ?? false;
|
|
3316
|
+
}
|
|
3317
|
+
__name(isDryRun, "isDryRun");
|
|
3318
|
+
function printGenerated(files, dryRun = false) {
|
|
3303
3319
|
const cwd = process.cwd();
|
|
3320
|
+
const label = dryRun ? "Would generate" : "Generated";
|
|
3304
3321
|
console.log(`
|
|
3305
|
-
|
|
3322
|
+
${label} ${files.length} file${files.length === 1 ? "" : "s"}:`);
|
|
3306
3323
|
for (const f of files) {
|
|
3307
3324
|
console.log(` ${f.replace(cwd + "/", "")}`);
|
|
3308
3325
|
}
|
|
3326
|
+
if (dryRun) console.log("\n (dry run \u2014 no files were written)");
|
|
3309
3327
|
console.log();
|
|
3310
3328
|
}
|
|
3311
3329
|
__name(printGenerated, "printGenerated");
|
|
@@ -3369,14 +3387,16 @@ function printGeneratorList() {
|
|
|
3369
3387
|
}
|
|
3370
3388
|
__name(printGeneratorList, "printGeneratorList");
|
|
3371
3389
|
function registerGenerateCommand(program) {
|
|
3372
|
-
const gen = program.command("generate").alias("g").description("Generate code scaffolds").option("--list", "List all available generators").action((opts) => {
|
|
3390
|
+
const gen = program.command("generate").alias("g").description("Generate code scaffolds").option("--list", "List all available generators").option("--dry-run", "Preview files that would be generated without writing them").action((opts) => {
|
|
3373
3391
|
if (opts.list) {
|
|
3374
3392
|
printGeneratorList();
|
|
3375
3393
|
} else {
|
|
3376
3394
|
gen.help();
|
|
3377
3395
|
}
|
|
3378
3396
|
});
|
|
3379
|
-
gen.command("module <name>").description("Generate a module (structure depends on project pattern)").option("--no-entity", "Skip entity and value object generation").option("--no-tests", "Skip test file generation").option("--repo <type>", "Repository implementation: inmemory | drizzle | prisma").option("--pattern <pattern>", "Override project pattern: rest | ddd | cqrs | minimal").option("--minimal", "Shorthand for --pattern minimal").option("--modules-dir <dir>", "Modules directory").option("-f, --force", "Overwrite existing files without prompting").action(async (name, opts) => {
|
|
3397
|
+
gen.command("module <name>").description("Generate a module (structure depends on project pattern)").option("--no-entity", "Skip entity and value object generation").option("--no-tests", "Skip test file generation").option("--repo <type>", "Repository implementation: inmemory | drizzle | prisma").option("--pattern <pattern>", "Override project pattern: rest | ddd | cqrs | minimal").option("--minimal", "Shorthand for --pattern minimal").option("--modules-dir <dir>", "Modules directory").option("-f, --force", "Overwrite existing files without prompting").action(async (name, opts, cmd) => {
|
|
3398
|
+
const dryRun = isDryRun(cmd);
|
|
3399
|
+
setDryRun(dryRun);
|
|
3380
3400
|
const config = await loadKickConfig(process.cwd());
|
|
3381
3401
|
const modulesDir = opts.modulesDir ?? config?.modulesDir ?? "src/modules";
|
|
3382
3402
|
const repo = opts.repo ?? config?.defaultRepo ?? "inmemory";
|
|
@@ -3389,18 +3409,23 @@ function registerGenerateCommand(program) {
|
|
|
3389
3409
|
repo,
|
|
3390
3410
|
minimal: opts.minimal,
|
|
3391
3411
|
force: opts.force,
|
|
3392
|
-
pattern
|
|
3412
|
+
pattern,
|
|
3413
|
+
dryRun
|
|
3393
3414
|
});
|
|
3394
|
-
printGenerated(files);
|
|
3415
|
+
printGenerated(files, dryRun);
|
|
3395
3416
|
});
|
|
3396
|
-
gen.command("adapter <name>").description("Generate an AppAdapter with lifecycle hooks and middleware support").option("-o, --out <dir>", "Output directory", "src/adapters").action(async (name, opts) => {
|
|
3417
|
+
gen.command("adapter <name>").description("Generate an AppAdapter with lifecycle hooks and middleware support").option("-o, --out <dir>", "Output directory", "src/adapters").action(async (name, opts, cmd) => {
|
|
3418
|
+
const dryRun = isDryRun(cmd);
|
|
3419
|
+
setDryRun(dryRun);
|
|
3397
3420
|
const files = await generateAdapter({
|
|
3398
3421
|
name,
|
|
3399
3422
|
outDir: resolve4(opts.out)
|
|
3400
3423
|
});
|
|
3401
|
-
printGenerated(files);
|
|
3424
|
+
printGenerated(files, dryRun);
|
|
3402
3425
|
});
|
|
3403
|
-
gen.command("middleware <name>").description("Generate an Express middleware function\n Use -m to scope it to a module: kick g middleware auth -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts) => {
|
|
3426
|
+
gen.command("middleware <name>").description("Generate an Express middleware function\n Use -m to scope it to a module: kick g middleware auth -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts, cmd) => {
|
|
3427
|
+
const dryRun = isDryRun(cmd);
|
|
3428
|
+
setDryRun(dryRun);
|
|
3404
3429
|
const config = await loadKickConfig(process.cwd());
|
|
3405
3430
|
const modulesDir = config?.modulesDir ?? "src/modules";
|
|
3406
3431
|
const files = await generateMiddleware({
|
|
@@ -3410,9 +3435,11 @@ function registerGenerateCommand(program) {
|
|
|
3410
3435
|
modulesDir,
|
|
3411
3436
|
pattern: config?.pattern
|
|
3412
3437
|
});
|
|
3413
|
-
printGenerated(files);
|
|
3438
|
+
printGenerated(files, dryRun);
|
|
3414
3439
|
});
|
|
3415
|
-
gen.command("guard <name>").description("Generate a route guard (auth, roles, etc.)\n Use -m to scope it to a module: kick g guard admin -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts) => {
|
|
3440
|
+
gen.command("guard <name>").description("Generate a route guard (auth, roles, etc.)\n Use -m to scope it to a module: kick g guard admin -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts, cmd) => {
|
|
3441
|
+
const dryRun = isDryRun(cmd);
|
|
3442
|
+
setDryRun(dryRun);
|
|
3416
3443
|
const config = await loadKickConfig(process.cwd());
|
|
3417
3444
|
const modulesDir = config?.modulesDir ?? "src/modules";
|
|
3418
3445
|
const files = await generateGuard({
|
|
@@ -3422,9 +3449,11 @@ function registerGenerateCommand(program) {
|
|
|
3422
3449
|
modulesDir,
|
|
3423
3450
|
pattern: config?.pattern
|
|
3424
3451
|
});
|
|
3425
|
-
printGenerated(files);
|
|
3452
|
+
printGenerated(files, dryRun);
|
|
3426
3453
|
});
|
|
3427
|
-
gen.command("service <name>").description("Generate a @Service() class\n Use -m to scope it to a module: kick g service payment -m orders").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts) => {
|
|
3454
|
+
gen.command("service <name>").description("Generate a @Service() class\n Use -m to scope it to a module: kick g service payment -m orders").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts, cmd) => {
|
|
3455
|
+
const dryRun = isDryRun(cmd);
|
|
3456
|
+
setDryRun(dryRun);
|
|
3428
3457
|
const config = await loadKickConfig(process.cwd());
|
|
3429
3458
|
const modulesDir = config?.modulesDir ?? "src/modules";
|
|
3430
3459
|
const files = await generateService({
|
|
@@ -3434,9 +3463,11 @@ function registerGenerateCommand(program) {
|
|
|
3434
3463
|
modulesDir,
|
|
3435
3464
|
pattern: config?.pattern
|
|
3436
3465
|
});
|
|
3437
|
-
printGenerated(files);
|
|
3466
|
+
printGenerated(files, dryRun);
|
|
3438
3467
|
});
|
|
3439
|
-
gen.command("controller <name>").description("Generate a @Controller() class with basic routes\n Use -m to scope it to a module: kick g controller auth -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts) => {
|
|
3468
|
+
gen.command("controller <name>").description("Generate a @Controller() class with basic routes\n Use -m to scope it to a module: kick g controller auth -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts, cmd) => {
|
|
3469
|
+
const dryRun = isDryRun(cmd);
|
|
3470
|
+
setDryRun(dryRun);
|
|
3440
3471
|
const config = await loadKickConfig(process.cwd());
|
|
3441
3472
|
const modulesDir = config?.modulesDir ?? "src/modules";
|
|
3442
3473
|
const files = await generateController2({
|
|
@@ -3446,9 +3477,11 @@ function registerGenerateCommand(program) {
|
|
|
3446
3477
|
modulesDir,
|
|
3447
3478
|
pattern: config?.pattern
|
|
3448
3479
|
});
|
|
3449
|
-
printGenerated(files);
|
|
3480
|
+
printGenerated(files, dryRun);
|
|
3450
3481
|
});
|
|
3451
|
-
gen.command("dto <name>").description("Generate a Zod DTO schema\n Use -m to scope it to a module: kick g dto create-user -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts) => {
|
|
3482
|
+
gen.command("dto <name>").description("Generate a Zod DTO schema\n Use -m to scope it to a module: kick g dto create-user -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module folder").action(async (name, opts, cmd) => {
|
|
3483
|
+
const dryRun = isDryRun(cmd);
|
|
3484
|
+
setDryRun(dryRun);
|
|
3452
3485
|
const config = await loadKickConfig(process.cwd());
|
|
3453
3486
|
const modulesDir = config?.modulesDir ?? "src/modules";
|
|
3454
3487
|
const files = await generateDto({
|
|
@@ -3458,9 +3491,11 @@ function registerGenerateCommand(program) {
|
|
|
3458
3491
|
modulesDir,
|
|
3459
3492
|
pattern: config?.pattern
|
|
3460
3493
|
});
|
|
3461
|
-
printGenerated(files);
|
|
3494
|
+
printGenerated(files, dryRun);
|
|
3462
3495
|
});
|
|
3463
|
-
gen.command("test <name>").description("Generate a Vitest test scaffold\n Use -m to scope it to a module: kick g test user-service -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module's __tests__/ folder").action(async (name, opts) => {
|
|
3496
|
+
gen.command("test <name>").description("Generate a Vitest test scaffold\n Use -m to scope it to a module: kick g test user-service -m users").option("-o, --out <dir>", "Output directory (overrides --module)").option("-m, --module <module>", "Place inside a module's __tests__/ folder").action(async (name, opts, cmd) => {
|
|
3497
|
+
const dryRun = isDryRun(cmd);
|
|
3498
|
+
setDryRun(dryRun);
|
|
3464
3499
|
const config = await loadKickConfig(process.cwd());
|
|
3465
3500
|
const modulesDir = config?.modulesDir ?? "src/modules";
|
|
3466
3501
|
const files = await generateTest({
|
|
@@ -3469,24 +3504,30 @@ function registerGenerateCommand(program) {
|
|
|
3469
3504
|
moduleName: opts.module,
|
|
3470
3505
|
modulesDir
|
|
3471
3506
|
});
|
|
3472
|
-
printGenerated(files);
|
|
3507
|
+
printGenerated(files, dryRun);
|
|
3473
3508
|
});
|
|
3474
|
-
gen.command("resolver <name>").description("Generate a GraphQL @Resolver class with @Query and @Mutation methods").option("-o, --out <dir>", "Output directory", "src/resolvers").action(async (name, opts) => {
|
|
3509
|
+
gen.command("resolver <name>").description("Generate a GraphQL @Resolver class with @Query and @Mutation methods").option("-o, --out <dir>", "Output directory", "src/resolvers").action(async (name, opts, cmd) => {
|
|
3510
|
+
const dryRun = isDryRun(cmd);
|
|
3511
|
+
setDryRun(dryRun);
|
|
3475
3512
|
const files = await generateResolver({
|
|
3476
3513
|
name,
|
|
3477
3514
|
outDir: resolve4(opts.out)
|
|
3478
3515
|
});
|
|
3479
|
-
printGenerated(files);
|
|
3516
|
+
printGenerated(files, dryRun);
|
|
3480
3517
|
});
|
|
3481
|
-
gen.command("job <name>").description("Generate a @Job queue processor with @Process handlers").option("-o, --out <dir>", "Output directory", "src/jobs").option("-q, --queue <name>", "Queue name (default: <name>-queue)").action(async (name, opts) => {
|
|
3518
|
+
gen.command("job <name>").description("Generate a @Job queue processor with @Process handlers").option("-o, --out <dir>", "Output directory", "src/jobs").option("-q, --queue <name>", "Queue name (default: <name>-queue)").action(async (name, opts, cmd) => {
|
|
3519
|
+
const dryRun = isDryRun(cmd);
|
|
3520
|
+
setDryRun(dryRun);
|
|
3482
3521
|
const files = await generateJob({
|
|
3483
3522
|
name,
|
|
3484
3523
|
outDir: resolve4(opts.out),
|
|
3485
3524
|
queue: opts.queue
|
|
3486
3525
|
});
|
|
3487
|
-
printGenerated(files);
|
|
3526
|
+
printGenerated(files, dryRun);
|
|
3488
3527
|
});
|
|
3489
|
-
gen.command("scaffold <name> [fields...]").description("Generate a full CRUD module from field definitions\n Example: kick g scaffold Post title:string body:text published:boolean?\n Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c\n Append ? for optional fields: description:text?").option("--no-entity", "Skip entity and value object generation").option("--no-tests", "Skip test file generation").option("--modules-dir <dir>", "Modules directory").action(async (name, rawFields, opts) => {
|
|
3528
|
+
gen.command("scaffold <name> [fields...]").description("Generate a full CRUD module from field definitions\n Example: kick g scaffold Post title:string body:text published:boolean?\n Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c\n Append ? for optional fields: description:text?").option("--no-entity", "Skip entity and value object generation").option("--no-tests", "Skip test file generation").option("--modules-dir <dir>", "Modules directory").action(async (name, rawFields, opts, cmd) => {
|
|
3529
|
+
const dryRun = isDryRun(cmd);
|
|
3530
|
+
setDryRun(dryRun);
|
|
3490
3531
|
if (rawFields.length === 0) {
|
|
3491
3532
|
console.error("\n Error: At least one field is required.\n Usage: kick g scaffold <name> <field:type> [field:type...]\n Example: kick g scaffold Post title:string body:text published:boolean\n");
|
|
3492
3533
|
process.exit(1);
|
|
@@ -3506,16 +3547,18 @@ function registerGenerateCommand(program) {
|
|
|
3506
3547
|
for (const f of fields) {
|
|
3507
3548
|
console.log(` ${f.name}: ${f.type}${f.optional ? " (optional)" : ""}`);
|
|
3508
3549
|
}
|
|
3509
|
-
printGenerated(files);
|
|
3550
|
+
printGenerated(files, dryRun);
|
|
3510
3551
|
});
|
|
3511
|
-
gen.command("config").description("Generate a kick.config.ts at the project root").option("--modules-dir <dir>", "Modules directory path", "src/modules").option("--repo <type>", "Default repository type: inmemory | drizzle | prisma", "inmemory").option("-f, --force", "Overwrite existing kick.config.ts without prompting").action(async (opts) => {
|
|
3552
|
+
gen.command("config").description("Generate a kick.config.ts at the project root").option("--modules-dir <dir>", "Modules directory path", "src/modules").option("--repo <type>", "Default repository type: inmemory | drizzle | prisma", "inmemory").option("-f, --force", "Overwrite existing kick.config.ts without prompting").action(async (opts, cmd) => {
|
|
3553
|
+
const dryRun = isDryRun(cmd);
|
|
3554
|
+
setDryRun(dryRun);
|
|
3512
3555
|
const files = await generateConfig({
|
|
3513
3556
|
outDir: resolve4("."),
|
|
3514
3557
|
modulesDir: opts.modulesDir,
|
|
3515
3558
|
defaultRepo: opts.repo,
|
|
3516
3559
|
force: opts.force
|
|
3517
3560
|
});
|
|
3518
|
-
printGenerated(files);
|
|
3561
|
+
printGenerated(files, dryRun);
|
|
3519
3562
|
});
|
|
3520
3563
|
}
|
|
3521
3564
|
__name(registerGenerateCommand, "registerGenerateCommand");
|