@forinda/kickjs-cli 3.1.0 → 3.1.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.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-cli v3.1.
|
|
2
|
+
* @forinda/kickjs-cli v3.1.2
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -1703,7 +1703,7 @@ const OPTIONAL_PACKAGES = [
|
|
|
1703
1703
|
}
|
|
1704
1704
|
];
|
|
1705
1705
|
function registerInitCommand(program) {
|
|
1706
|
-
program.command("new [name]").alias("init").description("Create a new KickJS project (use \".\" for current directory)").option("-d, --directory <dir>", "Target directory (defaults to project name)").option("--pm <manager>", "Package manager: pnpm | npm | yarn").option("--git", "Initialize git repository").option("--no-git", "Skip git initialization").option("--install", "Install dependencies after scaffolding").option("--no-install", "Skip dependency installation").option("-f, --force", "Remove existing files without prompting").option("-t, --template <type>", "Project template: rest | graphql | ddd | cqrs | minimal").option("-r, --repo <type>", "Default repository: prisma | drizzle | inmemory | custom").option("--packages <packages>", "Comma-separated packages to include (e.g. auth,swagger,otel)").action(async (name, opts) => {
|
|
1706
|
+
program.command("new [name]").alias("init").description("Create a new KickJS project (use \".\" for current directory)").option("-d, --directory <dir>", "Target directory (defaults to project name)").option("--pm <manager>", "Package manager: pnpm | npm | yarn | bun").option("--git", "Initialize git repository").option("--no-git", "Skip git initialization").option("--install", "Install dependencies after scaffolding").option("--no-install", "Skip dependency installation").option("-f, --force", "Remove existing files without prompting").option("-t, --template <type>", "Project template: rest | graphql | ddd | cqrs | minimal").option("-r, --repo <type>", "Default repository: prisma | drizzle | inmemory | custom").option("--packages <packages>", "Comma-separated packages to include (e.g. auth,swagger,otel)").action(async (name, opts) => {
|
|
1707
1707
|
intro("KickJS — Create a new project");
|
|
1708
1708
|
if (!name) name = await text({
|
|
1709
1709
|
message: "Project name",
|
|
@@ -1784,6 +1784,10 @@ function registerInitCommand(program) {
|
|
|
1784
1784
|
{
|
|
1785
1785
|
value: "yarn",
|
|
1786
1786
|
label: "yarn"
|
|
1787
|
+
},
|
|
1788
|
+
{
|
|
1789
|
+
value: "bun",
|
|
1790
|
+
label: "bun"
|
|
1787
1791
|
}
|
|
1788
1792
|
]
|
|
1789
1793
|
});
|
|
@@ -3332,7 +3336,7 @@ export class Prisma${pascal}Repository implements I${pascal}Repository {
|
|
|
3332
3336
|
//#region src/generators/patterns/minimal.ts
|
|
3333
3337
|
async function generateMinimalFiles(ctx) {
|
|
3334
3338
|
const { pascal, kebab, plural, write } = ctx;
|
|
3335
|
-
await write(
|
|
3339
|
+
await write(`${kebab}.module.ts`, generateMinimalModuleIndex({
|
|
3336
3340
|
pascal,
|
|
3337
3341
|
kebab,
|
|
3338
3342
|
plural
|
|
@@ -3355,7 +3359,7 @@ export class ${pascal}Controller {
|
|
|
3355
3359
|
//#region src/generators/patterns/rest.ts
|
|
3356
3360
|
async function generateRestFiles(ctx) {
|
|
3357
3361
|
const { pascal, kebab, plural, pluralPascal, repo, noTests, prismaClientPath, write } = ctx;
|
|
3358
|
-
await write(
|
|
3362
|
+
await write(`${kebab}.module.ts`, generateRestModuleIndex({
|
|
3359
3363
|
pascal,
|
|
3360
3364
|
kebab,
|
|
3361
3365
|
plural,
|
|
@@ -3451,7 +3455,7 @@ async function generateRestFiles(ctx) {
|
|
|
3451
3455
|
//#region src/generators/patterns/cqrs.ts
|
|
3452
3456
|
async function generateCqrsFiles(ctx) {
|
|
3453
3457
|
const { pascal, kebab, plural, pluralPascal, repo, noTests, prismaClientPath, write } = ctx;
|
|
3454
|
-
await write(
|
|
3458
|
+
await write(`${kebab}.module.ts`, generateCqrsModuleIndex({
|
|
3455
3459
|
pascal,
|
|
3456
3460
|
kebab,
|
|
3457
3461
|
plural,
|
|
@@ -3560,7 +3564,7 @@ async function generateCqrsFiles(ctx) {
|
|
|
3560
3564
|
//#region src/generators/patterns/ddd.ts
|
|
3561
3565
|
async function generateDddFiles(ctx) {
|
|
3562
3566
|
const { pascal, kebab, plural, pluralPascal, repo, noEntity, noTests, prismaClientPath, write } = ctx;
|
|
3563
|
-
await write(
|
|
3567
|
+
await write(`${kebab}.module.ts`, generateModuleIndex({
|
|
3564
3568
|
pascal,
|
|
3565
3569
|
kebab,
|
|
3566
3570
|
plural,
|
|
@@ -3735,22 +3739,24 @@ async function generateModule(options) {
|
|
|
3735
3739
|
await generateDddFiles(ctx);
|
|
3736
3740
|
break;
|
|
3737
3741
|
}
|
|
3738
|
-
if (!dryRun) await autoRegisterModule$1(modulesDir, pascal, plural);
|
|
3742
|
+
if (!dryRun) await autoRegisterModule$1(modulesDir, pascal, plural, kebab);
|
|
3739
3743
|
return files;
|
|
3740
3744
|
}
|
|
3741
3745
|
/** Add the new module to src/modules/index.ts */
|
|
3742
|
-
async function autoRegisterModule$1(modulesDir, pascal, plural) {
|
|
3746
|
+
async function autoRegisterModule$1(modulesDir, pascal, plural, kebab) {
|
|
3743
3747
|
const indexPath = join(modulesDir, "index.ts");
|
|
3744
|
-
|
|
3748
|
+
const exists = await fileExists(indexPath);
|
|
3749
|
+
const importPath = `./${plural}/${kebab}.module`;
|
|
3750
|
+
if (!exists) {
|
|
3745
3751
|
await writeFileSafe(indexPath, `import type { AppModuleClass } from '@forinda/kickjs'
|
|
3746
|
-
import { ${pascal}Module } from '
|
|
3752
|
+
import { ${pascal}Module } from '${importPath}'
|
|
3747
3753
|
|
|
3748
3754
|
export const modules: AppModuleClass[] = [${pascal}Module]
|
|
3749
3755
|
`);
|
|
3750
3756
|
return;
|
|
3751
3757
|
}
|
|
3752
3758
|
let content = await readFile(indexPath, "utf-8");
|
|
3753
|
-
const importLine = `import { ${pascal}Module } from '
|
|
3759
|
+
const importLine = `import { ${pascal}Module } from '${importPath}'`;
|
|
3754
3760
|
if (!content.includes(`${pascal}Module`)) {
|
|
3755
3761
|
const lastImportIdx = content.lastIndexOf("import ");
|
|
3756
3762
|
if (lastImportIdx !== -1) {
|
|
@@ -4813,7 +4819,7 @@ async function generateScaffold(options) {
|
|
|
4813
4819
|
await writeFileSafe(fullPath, content);
|
|
4814
4820
|
files.push(fullPath);
|
|
4815
4821
|
};
|
|
4816
|
-
await write(
|
|
4822
|
+
await write(`${kebab}.module.ts`, genModuleIndex(pascal, kebab, plural));
|
|
4817
4823
|
await write("constants.ts", genConstants(pascal, fields));
|
|
4818
4824
|
await write(`presentation/${kebab}.controller.ts`, genController(pascal, kebab, plural, pluralPascal));
|
|
4819
4825
|
await write(`application/dtos/create-${kebab}.dto.ts`, genCreateDTO(pascal, fields));
|
|
@@ -4828,7 +4834,7 @@ async function generateScaffold(options) {
|
|
|
4828
4834
|
await write(`domain/entities/${kebab}.entity.ts`, genEntity(pascal, kebab, fields));
|
|
4829
4835
|
await write(`domain/value-objects/${kebab}-id.vo.ts`, genValueObject(pascal));
|
|
4830
4836
|
}
|
|
4831
|
-
await autoRegisterModule(modulesDir, pascal, plural);
|
|
4837
|
+
await autoRegisterModule(modulesDir, pascal, plural, kebab);
|
|
4832
4838
|
return files;
|
|
4833
4839
|
}
|
|
4834
4840
|
function genCreateDTO(pascal, fields) {
|
|
@@ -5211,14 +5217,16 @@ export class Delete${pascal}UseCase {
|
|
|
5211
5217
|
}
|
|
5212
5218
|
];
|
|
5213
5219
|
}
|
|
5214
|
-
async function autoRegisterModule(modulesDir, pascal, plural) {
|
|
5220
|
+
async function autoRegisterModule(modulesDir, pascal, plural, kebab) {
|
|
5215
5221
|
const indexPath = join(modulesDir, "index.ts");
|
|
5216
|
-
|
|
5217
|
-
|
|
5222
|
+
const exists = await fileExists(indexPath);
|
|
5223
|
+
const importPath = `./${plural}/${kebab}.module`;
|
|
5224
|
+
if (!exists) {
|
|
5225
|
+
await writeFileSafe(indexPath, `import type { AppModuleClass } from '@forinda/kickjs'\nimport { ${pascal}Module } from '${importPath}'\n\nexport const modules: AppModuleClass[] = [${pascal}Module]\n`);
|
|
5218
5226
|
return;
|
|
5219
5227
|
}
|
|
5220
5228
|
let content = await readFile(indexPath, "utf-8");
|
|
5221
|
-
const importLine = `import { ${pascal}Module } from '
|
|
5229
|
+
const importLine = `import { ${pascal}Module } from '${importPath}'`;
|
|
5222
5230
|
if (!content.includes(`${pascal}Module`)) {
|
|
5223
5231
|
const lastImportIdx = content.lastIndexOf("import ");
|
|
5224
5232
|
if (lastImportIdx !== -1) {
|
|
@@ -6367,7 +6375,7 @@ async function safeRun(opts, silent) {
|
|
|
6367
6375
|
//#region src/commands/generate.ts
|
|
6368
6376
|
/** Check if --dry-run was passed on the parent generate command */
|
|
6369
6377
|
function isDryRun(cmd) {
|
|
6370
|
-
return cmd.parent?.opts()?.dryRun ?? false;
|
|
6378
|
+
return (cmd.parent?.opts())?.dryRun ?? false;
|
|
6371
6379
|
}
|
|
6372
6380
|
function printGenerated(files, dryRun = false) {
|
|
6373
6381
|
const cwd = process.cwd();
|
|
@@ -6455,39 +6463,55 @@ function printGeneratorList() {
|
|
|
6455
6463
|
for (const g of GENERATORS) console.log(` kick g ${g.name.padEnd(maxName + 2)} ${g.description}`);
|
|
6456
6464
|
console.log();
|
|
6457
6465
|
}
|
|
6466
|
+
/**
|
|
6467
|
+
* Generate one or more modules. Shared by `kick g module <names...>` and
|
|
6468
|
+
* the bare `kick g <names...>` shortcut.
|
|
6469
|
+
*/
|
|
6470
|
+
async function runModuleGeneration(names, opts, dryRun) {
|
|
6471
|
+
const config = await loadKickConfig(process.cwd());
|
|
6472
|
+
const mc = resolveModuleConfig(config);
|
|
6473
|
+
const modulesDir = opts.modulesDir ?? mc.dir ?? "src/modules";
|
|
6474
|
+
const repo = opts.repo ?? resolveRepoType(mc.repo);
|
|
6475
|
+
const pattern = opts.pattern ?? config?.pattern ?? "ddd";
|
|
6476
|
+
const shouldPluralize = opts.pluralize === false ? false : mc.pluralize ?? true;
|
|
6477
|
+
const allFiles = [];
|
|
6478
|
+
for (const name of names) {
|
|
6479
|
+
const files = await generateModule({
|
|
6480
|
+
name,
|
|
6481
|
+
modulesDir: resolve(modulesDir),
|
|
6482
|
+
noEntity: opts.entity === false,
|
|
6483
|
+
noTests: opts.tests === false,
|
|
6484
|
+
repo,
|
|
6485
|
+
minimal: opts.minimal,
|
|
6486
|
+
force: opts.force,
|
|
6487
|
+
pattern,
|
|
6488
|
+
dryRun,
|
|
6489
|
+
pluralize: shouldPluralize,
|
|
6490
|
+
prismaClientPath: mc.prismaClientPath
|
|
6491
|
+
});
|
|
6492
|
+
allFiles.push(...files);
|
|
6493
|
+
}
|
|
6494
|
+
printGenerated(allFiles, dryRun);
|
|
6495
|
+
await runPostTypegen(dryRun);
|
|
6496
|
+
}
|
|
6458
6497
|
function registerGenerateCommand(program) {
|
|
6459
|
-
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) => {
|
|
6460
|
-
if (opts.list)
|
|
6461
|
-
|
|
6498
|
+
const gen = program.command("generate [names...]").alias("g").description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option("--list", "List all available generators").option("--dry-run", "Preview files that would be generated without writing them").option("--no-entity", "Skip entity and value object generation (module shortcut)").option("--no-tests", "Skip test file generation (module shortcut)").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("--no-pluralize", "Use singular names (skip auto-pluralization)").option("-f, --force", "Overwrite existing files without prompting").action(async (names, opts, cmd) => {
|
|
6499
|
+
if (opts.list) {
|
|
6500
|
+
printGeneratorList();
|
|
6501
|
+
return;
|
|
6502
|
+
}
|
|
6503
|
+
if (!names || names.length === 0) {
|
|
6504
|
+
gen.help();
|
|
6505
|
+
return;
|
|
6506
|
+
}
|
|
6507
|
+
const dryRun = isDryRun(cmd);
|
|
6508
|
+
setDryRun(dryRun);
|
|
6509
|
+
await runModuleGeneration(names, opts, dryRun);
|
|
6462
6510
|
});
|
|
6463
6511
|
gen.command("module <names...>").description("Generate one or more modules (e.g. kick g module user task project)").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("--no-pluralize", "Use singular names (skip auto-pluralization)").option("-f, --force", "Overwrite existing files without prompting").action(async (names, opts, cmd) => {
|
|
6464
6512
|
const dryRun = isDryRun(cmd);
|
|
6465
6513
|
setDryRun(dryRun);
|
|
6466
|
-
|
|
6467
|
-
const mc = resolveModuleConfig(config);
|
|
6468
|
-
const modulesDir = opts.modulesDir ?? mc.dir ?? "src/modules";
|
|
6469
|
-
const repo = opts.repo ?? resolveRepoType(mc.repo);
|
|
6470
|
-
const pattern = opts.pattern ?? config?.pattern ?? "ddd";
|
|
6471
|
-
const shouldPluralize = opts.pluralize === false ? false : mc.pluralize ?? true;
|
|
6472
|
-
const allFiles = [];
|
|
6473
|
-
for (const name of names) {
|
|
6474
|
-
const files = await generateModule({
|
|
6475
|
-
name,
|
|
6476
|
-
modulesDir: resolve(modulesDir),
|
|
6477
|
-
noEntity: opts.entity === false,
|
|
6478
|
-
noTests: opts.tests === false,
|
|
6479
|
-
repo,
|
|
6480
|
-
minimal: opts.minimal,
|
|
6481
|
-
force: opts.force,
|
|
6482
|
-
pattern,
|
|
6483
|
-
dryRun,
|
|
6484
|
-
pluralize: shouldPluralize,
|
|
6485
|
-
prismaClientPath: mc.prismaClientPath
|
|
6486
|
-
});
|
|
6487
|
-
allFiles.push(...files);
|
|
6488
|
-
}
|
|
6489
|
-
printGenerated(allFiles, dryRun);
|
|
6490
|
-
await runPostTypegen(dryRun);
|
|
6514
|
+
await runModuleGeneration(names, opts, dryRun);
|
|
6491
6515
|
});
|
|
6492
6516
|
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) => {
|
|
6493
6517
|
const dryRun = isDryRun(cmd);
|
|
@@ -8017,7 +8041,7 @@ async function removeModule(options) {
|
|
|
8017
8041
|
if (await fileExists(indexPath)) {
|
|
8018
8042
|
let content = await readFile(indexPath, "utf-8");
|
|
8019
8043
|
const originalContent = content;
|
|
8020
|
-
const importPattern = new RegExp(`^import\\s*\\{\\s*${pascal}Module\\s*\\}\\s*from\\s*['"][^'"]*${plural}['"].*\\n?`, "gm");
|
|
8044
|
+
const importPattern = new RegExp(`^import\\s*\\{\\s*${pascal}Module\\s*\\}\\s*from\\s*['"][^'"]*${plural}(?:/[^'"]*)?['"].*\\n?`, "gm");
|
|
8021
8045
|
content = content.replace(importPattern, "");
|
|
8022
8046
|
content = content.replace(new RegExp(`\\s*,?\\s*${pascal}Module\\s*,?`, "g"), (match) => {
|
|
8023
8047
|
const startsWithComma = match.trimStart().startsWith(",");
|
package/dist/index.d.mts
CHANGED
|
@@ -299,7 +299,7 @@ type ProjectTemplate = 'rest' | 'graphql' | 'ddd' | 'cqrs' | 'minimal';
|
|
|
299
299
|
interface InitProjectOptions {
|
|
300
300
|
name: string;
|
|
301
301
|
directory: string;
|
|
302
|
-
packageManager?: 'pnpm' | 'npm' | 'yarn';
|
|
302
|
+
packageManager?: 'pnpm' | 'npm' | 'yarn' | 'bun';
|
|
303
303
|
initGit?: boolean;
|
|
304
304
|
installDeps?: boolean;
|
|
305
305
|
template?: ProjectTemplate;
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-cli v3.1.
|
|
2
|
+
* @forinda/kickjs-cli v3.1.2
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -1879,7 +1879,7 @@ export default defineConfig({
|
|
|
1879
1879
|
//#region src/generators/patterns/minimal.ts
|
|
1880
1880
|
async function generateMinimalFiles(ctx) {
|
|
1881
1881
|
const { pascal, kebab, plural, write } = ctx;
|
|
1882
|
-
await write(
|
|
1882
|
+
await write(`${kebab}.module.ts`, generateMinimalModuleIndex({
|
|
1883
1883
|
pascal,
|
|
1884
1884
|
kebab,
|
|
1885
1885
|
plural
|
|
@@ -1902,7 +1902,7 @@ export class ${pascal}Controller {
|
|
|
1902
1902
|
//#region src/generators/patterns/rest.ts
|
|
1903
1903
|
async function generateRestFiles(ctx) {
|
|
1904
1904
|
const { pascal, kebab, plural, pluralPascal, repo, noTests, prismaClientPath, write } = ctx;
|
|
1905
|
-
await write(
|
|
1905
|
+
await write(`${kebab}.module.ts`, generateRestModuleIndex({
|
|
1906
1906
|
pascal,
|
|
1907
1907
|
kebab,
|
|
1908
1908
|
plural,
|
|
@@ -1998,7 +1998,7 @@ async function generateRestFiles(ctx) {
|
|
|
1998
1998
|
//#region src/generators/patterns/cqrs.ts
|
|
1999
1999
|
async function generateCqrsFiles(ctx) {
|
|
2000
2000
|
const { pascal, kebab, plural, pluralPascal, repo, noTests, prismaClientPath, write } = ctx;
|
|
2001
|
-
await write(
|
|
2001
|
+
await write(`${kebab}.module.ts`, generateCqrsModuleIndex({
|
|
2002
2002
|
pascal,
|
|
2003
2003
|
kebab,
|
|
2004
2004
|
plural,
|
|
@@ -2107,7 +2107,7 @@ async function generateCqrsFiles(ctx) {
|
|
|
2107
2107
|
//#region src/generators/patterns/ddd.ts
|
|
2108
2108
|
async function generateDddFiles(ctx) {
|
|
2109
2109
|
const { pascal, kebab, plural, pluralPascal, repo, noEntity, noTests, prismaClientPath, write } = ctx;
|
|
2110
|
-
await write(
|
|
2110
|
+
await write(`${kebab}.module.ts`, generateModuleIndex({
|
|
2111
2111
|
pascal,
|
|
2112
2112
|
kebab,
|
|
2113
2113
|
plural,
|
|
@@ -2276,22 +2276,24 @@ async function generateModule(options) {
|
|
|
2276
2276
|
await generateDddFiles(ctx);
|
|
2277
2277
|
break;
|
|
2278
2278
|
}
|
|
2279
|
-
if (!dryRun) await autoRegisterModule(modulesDir, pascal, plural);
|
|
2279
|
+
if (!dryRun) await autoRegisterModule(modulesDir, pascal, plural, kebab);
|
|
2280
2280
|
return files;
|
|
2281
2281
|
}
|
|
2282
2282
|
/** Add the new module to src/modules/index.ts */
|
|
2283
|
-
async function autoRegisterModule(modulesDir, pascal, plural) {
|
|
2283
|
+
async function autoRegisterModule(modulesDir, pascal, plural, kebab) {
|
|
2284
2284
|
const indexPath = join(modulesDir, "index.ts");
|
|
2285
|
-
|
|
2285
|
+
const exists = await fileExists(indexPath);
|
|
2286
|
+
const importPath = `./${plural}/${kebab}.module`;
|
|
2287
|
+
if (!exists) {
|
|
2286
2288
|
await writeFileSafe(indexPath, `import type { AppModuleClass } from '@forinda/kickjs'
|
|
2287
|
-
import { ${pascal}Module } from '
|
|
2289
|
+
import { ${pascal}Module } from '${importPath}'
|
|
2288
2290
|
|
|
2289
2291
|
export const modules: AppModuleClass[] = [${pascal}Module]
|
|
2290
2292
|
`);
|
|
2291
2293
|
return;
|
|
2292
2294
|
}
|
|
2293
2295
|
let content = await readFile(indexPath, "utf-8");
|
|
2294
|
-
const importLine = `import { ${pascal}Module } from '
|
|
2296
|
+
const importLine = `import { ${pascal}Module } from '${importPath}'`;
|
|
2295
2297
|
if (!content.includes(`${pascal}Module`)) {
|
|
2296
2298
|
const lastImportIdx = content.lastIndexOf("import ");
|
|
2297
2299
|
if (lastImportIdx !== -1) {
|
|
@@ -3770,7 +3772,7 @@ async function initProject(options) {
|
|
|
3770
3772
|
}
|
|
3771
3773
|
}
|
|
3772
3774
|
try {
|
|
3773
|
-
const { runTypegen } = await import("./typegen-
|
|
3775
|
+
const { runTypegen } = await import("./typegen-D-the-Kw.mjs");
|
|
3774
3776
|
await runTypegen({
|
|
3775
3777
|
cwd: dir,
|
|
3776
3778
|
allowDuplicates: true,
|