@forinda/kickjs-cli 3.0.7 → 3.1.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/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v3.0.7
2
+ * @forinda/kickjs-cli v3.1.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -577,11 +577,14 @@ export class HelloModule implements AppModule {
577
577
  `;
578
578
  }
579
579
  /** Generate kick.config.ts CLI configuration */
580
- function generateKickConfig(template, defaultRepo = "inmemory") {
580
+ function generateKickConfig(template, defaultRepo = "inmemory", packageManager = "pnpm") {
581
581
  return `import { defineConfig } from '@forinda/kickjs-cli'
582
582
 
583
583
  export default defineConfig({
584
584
  pattern: '${template}',
585
+ // Pinned so \`kick add\` and other dep-installing commands always use the
586
+ // project's intended package manager, regardless of which lockfile exists.
587
+ packageManager: '${packageManager}',
585
588
  modules: {
586
589
  dir: 'src/modules',
587
590
  repo: ${[
@@ -1482,7 +1485,7 @@ async function initProject(options) {
1482
1485
  await writeFileSafe(join(dir, "src/modules/hello/hello.controller.ts"), generateHelloController());
1483
1486
  await writeFileSafe(join(dir, "src/modules/hello/hello.module.ts"), generateHelloModule());
1484
1487
  if (template === "graphql") await writeFileSafe(join(dir, "src/resolvers/.gitkeep"), "");
1485
- await writeFileSafe(join(dir, "kick.config.ts"), generateKickConfig(template, defaultRepo));
1488
+ await writeFileSafe(join(dir, "kick.config.ts"), generateKickConfig(template, defaultRepo, packageManager));
1486
1489
  await writeFileSafe(join(dir, "vitest.config.ts"), generateVitestConfig());
1487
1490
  await writeFileSafe(join(dir, "README.md"), generateReadme(name, template, packageManager));
1488
1491
  await writeFileSafe(join(dir, "CLAUDE.md"), generateClaude(name, template, packageManager));
@@ -5276,6 +5279,12 @@ describe('${pascal}', () => {
5276
5279
  }
5277
5280
  //#endregion
5278
5281
  //#region src/config.ts
5282
+ const PACKAGE_MANAGERS = [
5283
+ "pnpm",
5284
+ "npm",
5285
+ "yarn",
5286
+ "bun"
5287
+ ];
5279
5288
  const BUILTIN_REPO_TYPES = [
5280
5289
  "drizzle",
5281
5290
  "inmemory",
@@ -5356,6 +5365,16 @@ const DEFAULT_EXCLUDES = [
5356
5365
  */
5357
5366
  const DECORATED_CLASS_REGEX = new RegExp(String.raw`@(${DECORATOR_NAMES.join("|")})\s*\([^)]*\)` + String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*` + String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`, "g");
5358
5367
  /**
5368
+ * Match an exported class declaration that implements `AppModule`.
5369
+ * KickJS modules are not decorated — they implement the `AppModule`
5370
+ * interface — so the decorated-class scanner never picks them up. This
5371
+ * regex captures them by name so `ModuleToken` can be populated.
5372
+ *
5373
+ * Tolerates an `extends BaseClass` clause before `implements`, multiple
5374
+ * implements clauses (`implements Foo, AppModule`), and `default` exports.
5375
+ */
5376
+ const APP_MODULE_CLASS_REGEX = new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)` + String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?` + String.raw`\s+implements\s+[^{]*\bAppModule\b`, "g");
5377
+ /**
5359
5378
  * Match a `createToken<T>('name')` call with optional `export const X =`
5360
5379
  * or `const X =` prefix. Tolerates whitespace and the type parameter
5361
5380
  * being absent (`createToken('name')`).
@@ -5369,52 +5388,89 @@ const BARE_CREATE_TOKEN_REGEX = /createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+
5369
5388
  /** Match `@Inject('literal')` — only literals; computed args are skipped */
5370
5389
  const INJECT_LITERAL_REGEX = /@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
5371
5390
  /**
5372
- * Match a route decorator immediately followed by a method declaration.
5373
- * Captures the HTTP verb, path literal (or empty), and method name.
5374
- *
5375
- * Tolerates:
5376
- * - Optional second arg to the route decorator (`@Get('/path', { ... })`)
5377
- * - Stacked decorators between the route and the method (`@Get('/') @Use(...)`)
5378
- * - Path-less decorators (`@Get()` → defaults to `/`)
5379
- * - `async` modifier on the method
5380
- *
5381
- * Run within a class body slice (see extractRoutesFromSource) so the
5382
- * captured method name is unambiguously a method on that class.
5391
+ * Locate the start of a route decorator: `@Get(`, `@Post(`, etc.
5392
+ * Used by `extractRoutesFromSource`; the rest of the route declaration
5393
+ * (balanced parens, stacked decorators, method name) is parsed by walking
5394
+ * the source forward from this match. The previous all-in-one regex
5395
+ * couldn't handle nested parens in stacked decorator args (e.g.
5396
+ * `@ApiResponse(201, { schema: z.object({ id: z.string() }) })`) — see
5397
+ * forinda/kick-js#108.
5383
5398
  */
5384
- const ROUTE_METHOD_REGEX = new RegExp(String.raw`@(${[
5399
+ const ROUTE_DECORATOR_START = new RegExp(String.raw`@(${[
5385
5400
  "Get",
5386
5401
  "Post",
5387
5402
  "Put",
5388
5403
  "Delete",
5389
5404
  "Patch"
5390
- ].join("|")})\s*\(` + String.raw`(?:\s*['"\`]([^'"\`]*)['"\`])?[^)]*\)` + String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*` + String.raw`\s*(?:public\s+|private\s+|protected\s+)?(?:async\s+)?` + String.raw`([a-zA-Z_]\w*)\s*\(`, "g");
5391
- /** Extract `:placeholder` segments from an Express route path */
5392
- function extractPathParams(path) {
5393
- return (path.match(/:([a-zA-Z_]\w*)/g) ?? []).map((m) => m.slice(1));
5394
- }
5405
+ ].join("|")})\s*\(`, "g");
5395
5406
  /**
5396
- * Given the matched text of a route decorator + method declaration, return
5397
- * the substring inside the route decorator's argument list (between the
5398
- * outermost `(` and `)`). Returns `null` if no parens are found.
5399
- *
5400
- * Example input:
5401
- * `@Post('/', { body: createTaskSchema, name: 'CreateTask' }) async create(`
5402
- * Returns:
5403
- * `'/', { body: createTaskSchema, name: 'CreateTask' }`
5407
+ * Find the index of the `)` that balances the `(` at `openPos`.
5408
+ * Returns -1 if no matching `)` exists. Counts balanced parens only;
5409
+ * does not understand string literals, so a `(` or `)` inside a string
5410
+ * inside the args will skew the depth counter (matches the limitation
5411
+ * of `extractRouteOptionsArg`).
5404
5412
  */
5405
- function extractRouteOptionsArg(matchedText) {
5406
- const open = matchedText.indexOf("(");
5407
- if (open < 0) return null;
5413
+ function findBalancedClose(text, openPos) {
5408
5414
  let depth = 1;
5409
- for (let i = open + 1; i < matchedText.length; i++) {
5410
- const ch = matchedText[i];
5415
+ for (let i = openPos + 1; i < text.length; i++) {
5416
+ const ch = text[i];
5411
5417
  if (ch === "(") depth++;
5412
5418
  else if (ch === ")") {
5413
5419
  depth--;
5414
- if (depth === 0) return matchedText.slice(open + 1, i);
5420
+ if (depth === 0) return i;
5415
5421
  }
5416
5422
  }
5417
- return null;
5423
+ return -1;
5424
+ }
5425
+ /**
5426
+ * Walk forward from the end of a route decorator past any stacked
5427
+ * decorators (`@ApiOperation(...)`, `@ApiResponse(...)`, `@Middleware(fn)`,
5428
+ * etc.), then past optional `public`/`private`/`protected` and `async`,
5429
+ * and capture the method name + opening `(`.
5430
+ *
5431
+ * Returns the method name and the position immediately after the method's
5432
+ * opening `(`, or `null` if the source between the route decorator and
5433
+ * the method body doesn't fit the expected shape.
5434
+ */
5435
+ function readMethodAfterDecorators(block, startPos) {
5436
+ let pos = startPos;
5437
+ while (pos < block.length) {
5438
+ while (pos < block.length && /\s/.test(block[pos])) pos++;
5439
+ if (block[pos] !== "@") break;
5440
+ const decMatch = block.slice(pos).match(/^@([A-Z]\w*)/);
5441
+ if (!decMatch) break;
5442
+ pos += decMatch[0].length;
5443
+ while (pos < block.length && /\s/.test(block[pos])) pos++;
5444
+ if (block[pos] === "(") {
5445
+ const close = findBalancedClose(block, pos);
5446
+ if (close < 0) return null;
5447
+ pos = close + 1;
5448
+ }
5449
+ }
5450
+ while (pos < block.length && /\s/.test(block[pos])) pos++;
5451
+ for (const mod of [
5452
+ "public",
5453
+ "private",
5454
+ "protected"
5455
+ ]) if (block.slice(pos, pos + mod.length) === mod && /\s/.test(block.charAt(pos + mod.length))) {
5456
+ pos += mod.length;
5457
+ while (pos < block.length && /\s/.test(block[pos])) pos++;
5458
+ break;
5459
+ }
5460
+ if (block.slice(pos, pos + 5) === "async" && /\s/.test(block.charAt(pos + 5))) {
5461
+ pos += 5;
5462
+ while (pos < block.length && /\s/.test(block[pos])) pos++;
5463
+ }
5464
+ const methodMatch = block.slice(pos).match(/^([a-zA-Z_]\w*)\s*\(/);
5465
+ if (!methodMatch) return null;
5466
+ return {
5467
+ methodName: methodMatch[1],
5468
+ endPos: pos + methodMatch[0].length
5469
+ };
5470
+ }
5471
+ /** Extract `:placeholder` segments from an Express route path */
5472
+ function extractPathParams(path) {
5473
+ return (path.match(/:([a-zA-Z_]\w*)/g) ?? []).map((m) => m.slice(1));
5418
5474
  }
5419
5475
  /**
5420
5476
  * Extract a bare identifier value from a single field in an object literal
@@ -5545,6 +5601,19 @@ function extractClassesFromSource(source, filePath, cwd) {
5545
5601
  isDefault: Boolean(defaultMarker)
5546
5602
  });
5547
5603
  }
5604
+ APP_MODULE_CLASS_REGEX.lastIndex = 0;
5605
+ let modMatch;
5606
+ while ((modMatch = APP_MODULE_CLASS_REGEX.exec(source)) !== null) {
5607
+ const [, defaultMarker, className] = modMatch;
5608
+ if (out.some((c) => c.className === className && c.filePath === filePath)) continue;
5609
+ out.push({
5610
+ className,
5611
+ decorator: "Module",
5612
+ filePath,
5613
+ relativePath: relPath,
5614
+ isDefault: Boolean(defaultMarker)
5615
+ });
5616
+ }
5548
5617
  return out;
5549
5618
  }
5550
5619
  /** Extract `createToken('name')` definitions from a single source file */
@@ -5604,16 +5673,25 @@ function extractRoutesFromSource(source, filePath, cwd, classesInFile) {
5604
5673
  const { cls, start } = positions[i];
5605
5674
  const end = i + 1 < positions.length ? positions[i + 1].start : source.length;
5606
5675
  const block = source.slice(start, end);
5607
- ROUTE_METHOD_REGEX.lastIndex = 0;
5608
- let match;
5609
- while ((match = ROUTE_METHOD_REGEX.exec(block)) !== null) {
5610
- const [matchedText, verb, pathLiteral, methodName] = match;
5611
- const path = pathLiteral && pathLiteral.length > 0 ? pathLiteral : "/";
5612
- const apiQp = extractApiQueryParams(matchedText, source);
5613
- const routeArgs = extractRouteOptionsArg(matchedText);
5614
- const bodyId = routeArgs ? extractObjectFieldIdentifier(routeArgs, "body") : null;
5615
- const queryId = routeArgs ? extractObjectFieldIdentifier(routeArgs, "query") : null;
5616
- const paramsId = routeArgs ? extractObjectFieldIdentifier(routeArgs, "params") : null;
5676
+ ROUTE_DECORATOR_START.lastIndex = 0;
5677
+ let startMatch;
5678
+ while ((startMatch = ROUTE_DECORATOR_START.exec(block)) !== null) {
5679
+ const verb = startMatch[1];
5680
+ const decoratorStart = startMatch.index;
5681
+ const openParen = ROUTE_DECORATOR_START.lastIndex - 1;
5682
+ const closeParen = findBalancedClose(block, openParen);
5683
+ if (closeParen < 0) continue;
5684
+ const routeArgs = block.slice(openParen + 1, closeParen);
5685
+ const pathLiteralMatch = routeArgs.match(/^\s*['"`]([^'"`]*)['"`]/);
5686
+ const path = pathLiteralMatch && pathLiteralMatch[1].length > 0 ? pathLiteralMatch[1] : "/";
5687
+ const methodInfo = readMethodAfterDecorators(block, closeParen + 1);
5688
+ if (!methodInfo) continue;
5689
+ const { methodName, endPos } = methodInfo;
5690
+ ROUTE_DECORATOR_START.lastIndex = endPos;
5691
+ const apiQp = extractApiQueryParams(block.slice(decoratorStart, endPos), source);
5692
+ const bodyId = extractObjectFieldIdentifier(routeArgs, "body");
5693
+ const queryId = extractObjectFieldIdentifier(routeArgs, "query");
5694
+ const paramsId = extractObjectFieldIdentifier(routeArgs, "params");
5617
5695
  out.push({
5618
5696
  controller: cls.className,
5619
5697
  method: methodName,
@@ -7092,8 +7170,36 @@ const PACKAGE_REGISTRY = {
7092
7170
  function detectPackageManager() {
7093
7171
  if (existsSync(resolve("pnpm-lock.yaml"))) return "pnpm";
7094
7172
  if (existsSync(resolve("yarn.lock"))) return "yarn";
7173
+ if (existsSync(resolve("bun.lockb")) || existsSync(resolve("bun.lock"))) return "bun";
7095
7174
  return "npm";
7096
7175
  }
7176
+ /** Read `packageManager` from package.json (corepack convention: "pnpm@10.0.0") */
7177
+ function packageManagerFromPackageJson() {
7178
+ try {
7179
+ const field = JSON.parse(readFileSync(resolve("package.json"), "utf-8")).packageManager;
7180
+ if (typeof field !== "string") return null;
7181
+ const name = field.split("@")[0];
7182
+ return PACKAGE_MANAGERS.includes(name) ? name : null;
7183
+ } catch {
7184
+ return null;
7185
+ }
7186
+ }
7187
+ /**
7188
+ * Resolve which package manager to use, in priority order:
7189
+ * 1. `--pm` CLI flag
7190
+ * 2. `packageManager` in kick.config
7191
+ * 3. `packageManager` in package.json (corepack)
7192
+ * 4. Lockfile detection
7193
+ * 5. `'npm'`
7194
+ */
7195
+ async function resolvePackageManager(flagPm) {
7196
+ if (flagPm && PACKAGE_MANAGERS.includes(flagPm)) return flagPm;
7197
+ const config = await loadKickConfig(process.cwd());
7198
+ if (config?.packageManager && PACKAGE_MANAGERS.includes(config.packageManager)) return config.packageManager;
7199
+ const fromPkg = packageManagerFromPackageJson();
7200
+ if (fromPkg) return fromPkg;
7201
+ return detectPackageManager();
7202
+ }
7097
7203
  function printPackageList() {
7098
7204
  console.log("\n Available KickJS packages:\n");
7099
7205
  const maxName = Math.max(...Object.keys(PACKAGE_REGISTRY).map((k) => k.length));
@@ -7117,7 +7223,7 @@ function registerAddCommand(program) {
7117
7223
  printPackageList();
7118
7224
  return;
7119
7225
  }
7120
- const pm = opts.pm ?? detectPackageManager();
7226
+ const pm = await resolvePackageManager(opts.pm);
7121
7227
  const forceDevFlag = opts.dev;
7122
7228
  const prodDeps = /* @__PURE__ */ new Set();
7123
7229
  const devDeps = /* @__PURE__ */ new Set();
package/dist/index.d.mts CHANGED
@@ -20,6 +20,8 @@ interface KickCommandDefinition {
20
20
  }
21
21
  /** Project pattern — controls what generators produce and which deps are installed */
22
22
  type ProjectPattern = 'rest' | 'graphql' | 'ddd' | 'cqrs' | 'minimal';
23
+ /** Package manager used for `kick add` and other dep-installing commands */
24
+ type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';
23
25
  /** Built-in repository types with first-class code generation support */
24
26
  type BuiltinRepoType$1 = 'drizzle' | 'inmemory' | 'prisma';
25
27
  /** Custom repository type — generates a stub with TODO markers */
@@ -132,6 +134,22 @@ interface KickConfig {
132
134
  * }
133
135
  */
134
136
  modules?: ModuleConfig;
137
+ /**
138
+ * Package manager used by `kick add` (and any future dep-installing command)
139
+ * to install dependencies. When set, overrides lockfile auto-detection so
140
+ * commands always use the project's intended package manager.
141
+ *
142
+ * Priority (highest first):
143
+ * 1. `--pm` flag on the CLI
144
+ * 2. `packageManager` in kick.config
145
+ * 3. `packageManager` field in package.json (corepack convention)
146
+ * 4. Lockfile detection (pnpm-lock.yaml → pnpm, yarn.lock → yarn)
147
+ * 5. `'npm'`
148
+ *
149
+ * @example
150
+ * packageManager: 'pnpm'
151
+ */
152
+ packageManager?: PackageManager;
135
153
  /** @deprecated Use `modules.dir` instead */
136
154
  modulesDir?: string;
137
155
  /** @deprecated Use `modules.repo` instead */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/generators/module.ts","../src/generators/adapter.ts","../src/generators/middleware.ts","../src/generators/guard.ts","../src/generators/service.ts","../src/generators/controller.ts","../src/generators/dto.ts","../src/generators/project.ts","../src/utils/naming.ts"],"mappings":";;;UAIiB,qBAAA;EAAqB;EAEpC,IAAA;EAFoC;EAIpC,WAAA;EAAA;;;;;AAeF;;;EANE,KAAA;EAMwB;EAJxB,OAAA;AAAA;;KAIU,cAAA;;KAGA,iBAAA;;UAKK,cAAA;EACf,IAAA;AAAA;;KAIU,cAAA,GAAiB,iBAAA,GAAkB,cAAA;;;AAS/C;;;;;KAAY,eAAA;;UAGK,aAAA;EAuBkB;;;;EAlBjC,MAAA;EA4BA;;;AAIF;EA3BE,MAAA;;;;;;;;;;;AAiEF;;EApDE,eAAA,GAAkB,eAAA;EA6DR;;;;;;;;;EAnDV,OAAA;AAAA;;UAIe,YAAA;EAiEf;EA/DA,GAAA;EAiEA;;;;;;;;;;;;;EAnDA,IAAA,GAAO,cAAA;EAuFL;EArFF,SAAA;EAqFQ;AAKV;;;;EApFE,SAAA;EAoF2B;;;;AA6B7B;;;;;EAvGE,gBAAA;AAAA;;UAIe,UAAA;;;;AC5GjB;;;;;EDqHE,OAAA,GAAU,cAAA;ECpHQ;;;;AAOnB;;;;;;;EDyHC,OAAA,GAAU,YAAA;EClHV;EDsHA,UAAA;ECrHA;EDuHA,WAAA,GAAc,cAAA;ECrHd;EDuHA,SAAA;ECtHA;EDwHA,SAAA;ECpHA;;;AAaF;;;;;;;;;;EDqHE,QAAA,GAAW,KAAA;IAAiB,GAAA;IAAa,IAAA;EAAA;;;;AE/J3C;;;;;;;;EF2KE,OAAA,GAAU,aAAA;;EAEV,QAAA,GAAW,qBAAA;;EAEX,KAAA;IACE,UAAA;IACA,MAAA;IACA,aAAA;IACA,MAAA;EAAA;AAAA;;iBAKY,YAAA,CAAa,MAAA,EAAQ,UAAA,GAAa,UAAA;;iBA6B5B,cAAA,CAAe,GAAA,WAAc,OAAA,CAAQ,UAAA;;;KC/M/C,eAAA;AAAA,KACA,QAAA,GAAW,eAAA;AAAA,UASb,qBAAA;EACR,IAAA;EACA,UAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA,GAAO,QAAA;EACP,OAAA;EACA,KAAA;EACA,OAAA,GAAU,cAAA;EACV,MAAA;EDXwB;ECaxB,SAAA;EDVyB;ECYzB,gBAAA;AAAA;;ADPF;;;;;AAKA;;;;iBCesB,cAAA,CAAe,OAAA,EAAS,qBAAA,GAAwB,OAAA;;;UC/C5D,sBAAA;EACR,IAAA;EACA,MAAA;AAAA;AAAA,iBAGoB,eAAA,CAAgB,OAAA,EAAS,sBAAA,GAAyB,OAAA;;;UCH9D,yBAAA;EACR,IAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;EACA,OAAA,GAAU,cAAA;EACV,SAAA;AAAA;AAAA,iBAGoB,kBAAA,CAAmB,OAAA,EAAS,yBAAA,GAA4B,OAAA;;;UCTpE,oBAAA;EACR,IAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;EACA,OAAA,GAAU,cAAA;EACV,SAAA;AAAA;AAAA,iBAGoB,aAAA,CAAc,OAAA,EAAS,oBAAA,GAAuB,OAAA;;;UCT1D,sBAAA;EACR,IAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;EACA,OAAA,GAAU,cAAA;EACV,SAAA;AAAA;AAAA,iBAGoB,eAAA,CAAgB,OAAA,EAAS,sBAAA,GAAyB,OAAA;;;UCT9D,yBAAA;EACR,IAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;EACA,OAAA,GAAU,cAAA;EACV,SAAA;AAAA;AAAA,iBAGoB,kBAAA,CAAmB,OAAA,EAAS,yBAAA,GAA4B,OAAA;;;UCTpE,kBAAA;EACR,IAAA;EACA,MAAA;EACA,UAAA;EACA,UAAA;EACA,OAAA,GAAU,cAAA;EACV,SAAA;AAAA;AAAA,iBAGoB,WAAA,CAAY,OAAA,EAAS,kBAAA,GAAqB,OAAA;;;KCiB3D,eAAA;AAAA,UAEK,kBAAA;EACR,IAAA;EACA,SAAA;EACA,cAAA;EACA,OAAA;EACA,WAAA;EACA,QAAA,GAAW,eAAA;EACX,WAAA;EACA,QAAA;AAAA;ARnBF;AAAA,iBQuBsB,WAAA,CAAY,OAAA,EAAS,kBAAA,GAAqB,OAAA;;;;iBC3ChD,YAAA,CAAa,IAAA;;iBAOb,WAAA,CAAY,IAAA;;iBAMZ,WAAA,CAAY,IAAA;;;;;;iBAYZ,SAAA,CAAU,IAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/generators/module.ts","../src/generators/adapter.ts","../src/generators/middleware.ts","../src/generators/guard.ts","../src/generators/service.ts","../src/generators/controller.ts","../src/generators/dto.ts","../src/generators/project.ts","../src/utils/naming.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v3.0.7
2
+ * @forinda/kickjs-cli v3.1.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1824,11 +1824,14 @@ export class HelloModule implements AppModule {
1824
1824
  `;
1825
1825
  }
1826
1826
  /** Generate kick.config.ts CLI configuration */
1827
- function generateKickConfig(template, defaultRepo = "inmemory") {
1827
+ function generateKickConfig(template, defaultRepo = "inmemory", packageManager = "pnpm") {
1828
1828
  return `import { defineConfig } from '@forinda/kickjs-cli'
1829
1829
 
1830
1830
  export default defineConfig({
1831
1831
  pattern: '${template}',
1832
+ // Pinned so \`kick add\` and other dep-installing commands always use the
1833
+ // project's intended package manager, regardless of which lockfile exists.
1834
+ packageManager: '${packageManager}',
1832
1835
  modules: {
1833
1836
  dir: 'src/modules',
1834
1837
  repo: ${[
@@ -3749,7 +3752,7 @@ async function initProject(options) {
3749
3752
  await writeFileSafe(join(dir, "src/modules/hello/hello.controller.ts"), generateHelloController());
3750
3753
  await writeFileSafe(join(dir, "src/modules/hello/hello.module.ts"), generateHelloModule());
3751
3754
  if (template === "graphql") await writeFileSafe(join(dir, "src/resolvers/.gitkeep"), "");
3752
- await writeFileSafe(join(dir, "kick.config.ts"), generateKickConfig(template, defaultRepo));
3755
+ await writeFileSafe(join(dir, "kick.config.ts"), generateKickConfig(template, defaultRepo, packageManager));
3753
3756
  await writeFileSafe(join(dir, "vitest.config.ts"), generateVitestConfig());
3754
3757
  await writeFileSafe(join(dir, "README.md"), generateReadme(name, template, packageManager));
3755
3758
  await writeFileSafe(join(dir, "CLAUDE.md"), generateClaude(name, template, packageManager));
@@ -3767,7 +3770,7 @@ async function initProject(options) {
3767
3770
  }
3768
3771
  }
3769
3772
  try {
3770
- const { runTypegen } = await import("./typegen-ClVX3qTL.mjs");
3773
+ const { runTypegen } = await import("./typegen-C3Nf74nD.mjs");
3771
3774
  await runTypegen({
3772
3775
  cwd: dir,
3773
3776
  allowDuplicates: true,