@forinda/kickjs-cli 6.1.1 → 6.2.0-alpha.1

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.
Files changed (31) hide show
  1. package/README.md +15 -2
  2. package/dist/{agent-docs-GpRHHdWC.mjs → agent-docs-DKEQiq25.mjs} +3 -3
  3. package/dist/{agent-docs-GpRHHdWC.mjs.map → agent-docs-DKEQiq25.mjs.map} +1 -1
  4. package/dist/{build-D9X9QBkC.mjs → build-I8Yhoqj-.mjs} +3 -3
  5. package/dist/{build-D9X9QBkC.mjs.map → build-I8Yhoqj-.mjs.map} +1 -1
  6. package/dist/{builtins-DHcybuaw.mjs → builtins-7IQexhj7.mjs} +2 -2
  7. package/dist/cli.mjs +198 -157
  8. package/dist/{config-DLy6JCCy.mjs → config-DXJWJLD4.mjs} +3 -3
  9. package/dist/config-DXJWJLD4.mjs.map +1 -0
  10. package/dist/{doctor-CcVNNzGj.mjs → doctor-414bnUd8.mjs} +72 -64
  11. package/dist/doctor-414bnUd8.mjs.map +1 -0
  12. package/dist/index.d.mts +28 -0
  13. package/dist/index.d.mts.map +1 -1
  14. package/dist/index.mjs +2 -2
  15. package/dist/{plugin-C6jhcq0N.mjs → plugin-C03BaYpV.mjs} +3 -3
  16. package/dist/{plugin-C6jhcq0N.mjs.map → plugin-C03BaYpV.mjs.map} +1 -1
  17. package/dist/{project-docs-CqOymvmb.mjs → project-docs-gnsQyilx.mjs} +44 -5
  18. package/dist/project-docs-gnsQyilx.mjs.map +1 -0
  19. package/dist/{project-root-yLxS5CqO.mjs → project-root-gmupeTuu.mjs} +3 -3
  20. package/dist/{project-root-yLxS5CqO.mjs.map → project-root-gmupeTuu.mjs.map} +1 -1
  21. package/dist/{rolldown-runtime-BnMWUWuC.mjs → rolldown-runtime-BKjf5NYQ.mjs} +1 -1
  22. package/dist/{run-plugins-CubT9x_A.mjs → run-plugins-A7mE5YjC.mjs} +70 -76
  23. package/dist/run-plugins-A7mE5YjC.mjs.map +1 -0
  24. package/dist/{typegen-BJwy65-p.mjs → typegen-C4nEHdxn.mjs} +5 -5
  25. package/dist/{typegen-BJwy65-p.mjs.map → typegen-C4nEHdxn.mjs.map} +1 -1
  26. package/dist/{types-D7d_Y66D.mjs → types-3XZpaE0p.mjs} +1 -1
  27. package/package.json +4 -4
  28. package/dist/config-DLy6JCCy.mjs.map +0 -1
  29. package/dist/doctor-CcVNNzGj.mjs.map +0 -1
  30. package/dist/project-docs-CqOymvmb.mjs.map +0 -1
  31. package/dist/run-plugins-CubT9x_A.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v6.1.1
2
+ * @forinda/kickjs-cli v6.2.0-alpha.1
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{b as e,c as t,d as n,g as r,l as i,o as a,s as o,v as s}from"./project-docs-CqOymvmb.mjs";import{i as c}from"./config-DLy6JCCy.mjs";import{t as l}from"./project-root-yLxS5CqO.mjs";import{createRequire as u}from"node:module";import d,{dirname as f,join as p,relative as m,resolve as h}from"node:path";import{existsSync as g,readFileSync as _,readdirSync as v,statSync as y}from"node:fs";import{readFile as b,writeFile as x}from"node:fs/promises";import S from"pluralize";import{execFileSync as C,execSync as w}from"node:child_process";import{fileURLToPath as ee,pathToFileURL as te}from"node:url";import{defineGenerator as ne}from"@forinda/kickjs-cli-kit";function T(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function E(e){let t=T(e);return t.charAt(0).toLowerCase()+t.slice(1)}function D(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function O(e){return S.plural(e)}function k(e){return S.plural(e)}function A(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function re(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function ie(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function ae(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${re(n)}${e}Repository`,repoFile:i[n]??`${ie(n)}-${t}`}}function j(e){return e??`define`}function M(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=ae(t,n,i),c=j(a),l=`/**
11
+ import{b as e,c as t,d as n,g as r,l as i,o as a,s as o,v as s}from"./project-docs-gnsQyilx.mjs";import{i as c,t as l}from"./config-DXJWJLD4.mjs";import{t as u}from"./project-root-gmupeTuu.mjs";import{createRequire as d}from"node:module";import f,{dirname as p,join as m,relative as h,resolve as g}from"node:path";import{existsSync as _,readFileSync as v,readdirSync as y,statSync as b}from"node:fs";import{readFile as x,writeFile as S}from"node:fs/promises";import C from"pluralize";import{execFileSync as w,execSync as T}from"node:child_process";import{fileURLToPath as ee,pathToFileURL as te}from"node:url";import{defineGenerator as ne}from"@forinda/kickjs-cli-kit";function E(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function D(e){let t=E(e);return t.charAt(0).toLowerCase()+t.slice(1)}function O(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function k(e){return C.plural(e)}function re(e){return C.plural(e)}function A(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function ie(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function ae(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function oe(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${ie(n)}${e}Repository`,repoFile:i[n]??`${ae(n)}-${t}`}}function j(e){return e??`define`}function M(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=oe(t,n,i),c=j(a),l=`/**
12
12
  * ${t} Module
13
13
  *
14
14
  * REST module with a flat folder structure.
@@ -80,7 +80,7 @@ ${d}
80
80
  },
81
81
  }),
82
82
  })
83
- `}function oe(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=j(i),o=` /**
83
+ `}function se(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=j(i),o=` /**
84
84
  * Declare HTTP routes. Return value shape:
85
85
  *
86
86
  * - \`path\` — URL prefix for this route set.
@@ -175,7 +175,7 @@ export class ${t}Controller {
175
175
  ctx.noContent()
176
176
  }
177
177
  }
178
- `}function se(e){let{pascal:t}=e;return`import { z } from 'zod'
178
+ `}function ce(e){let{pascal:t}=e;return`import { z } from 'zod'
179
179
 
180
180
  /**
181
181
  * Create ${t} DTO — Zod schema for validating POST request bodies.
@@ -191,14 +191,14 @@ export const create${t}Schema = z.object({
191
191
  })
192
192
 
193
193
  export type Create${t}DTO = z.infer<typeof create${t}Schema>
194
- `}function ce(e){let{pascal:t}=e;return`import { z } from 'zod'
194
+ `}function le(e){let{pascal:t}=e;return`import { z } from 'zod'
195
195
 
196
196
  export const update${t}Schema = z.object({
197
197
  name: z.string().min(1).max(200).optional(),
198
198
  })
199
199
 
200
200
  export type Update${t}DTO = z.infer<typeof update${t}Schema>
201
- `}function le(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
201
+ `}function ue(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
202
202
  id: string
203
203
  name: string
204
204
  createdAt: string
@@ -368,7 +368,7 @@ export class ${o}${t}Repository implements I${t}Repository {
368
368
  this.store.delete(id)
369
369
  }
370
370
  }
371
- `}function ue(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
371
+ `}function de(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
372
372
  import { Container } from '@forinda/kickjs'
373
373
 
374
374
  describe('${t}Controller', () => {
@@ -420,7 +420,7 @@ describe('${t}Controller', () => {
420
420
  })
421
421
  })
422
422
  })
423
- `}function de(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
423
+ `}function fe(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
424
424
  import { InMemory${t}Repository } from '${i}'
425
425
 
426
426
  describe('InMemory${t}Repository', () => {
@@ -526,58 +526,54 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
526
526
  sortable: ['name', 'createdAt'],
527
527
  searchable: ['name'],
528
528
  }
529
- `}function fe(e,t,n,r=[]){switch(t){case`minimal`:{let t=[],i=[];return r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({ info: { title: '${e}', version: '${n}' } }),`)),r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`)),`import 'reflect-metadata'
529
+ `}const pe={express:{from:`@forinda/kickjs`,name:`expressRuntime`},fastify:{from:`@forinda/kickjs/fastify`,name:`fastifyRuntime`},h3:{from:`@forinda/kickjs/h3`,name:`h3Runtime`}};function me(e,t,n,r=[],i=`express`){let a=pe[i],o=i===`express`;switch(t){case`minimal`:{let t=[],i=[],s=o?`import { bootstrap, ${a.name} } from '@forinda/kickjs'`:`import { bootstrap } from '@forinda/kickjs'\nimport { ${a.name} } from '${a.from}'`;r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({ info: { title: '${e}', version: '${n}' } }),`)),r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`));let c=t.length?t.join(`
530
+ `)+`
531
+ `:``,l=i.length?`,\n adapters: [\n${i.join(`
532
+ `)}\n ]`:``;return`import 'reflect-metadata'
530
533
  // Side-effect import — registers the extended env schema with kickjs
531
534
  // **before** any controller / service / @Value gets resolved. Without
532
535
  // this line ConfigService.get('YOUR_KEY') returns undefined because the
533
536
  // cached schema would still be the base shape. See guide/configuration.
534
537
  import './config'
535
- import { bootstrap } from '@forinda/kickjs'
536
- ${t.length?t.join(`
537
- `)+`
538
- `:``}import { modules } from './modules'
538
+ ${s}
539
+ ${c}import { modules } from './modules'
539
540
 
540
541
  // Export the app for the Vite plugin (dev mode)
541
- export const app = await bootstrap({ modules${i.length?`,\n adapters: [\n${i.join(`
542
- `)}\n ]`:``} })
543
- `}default:{let t=[],i=[];return r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`)),r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({\n info: { title: '${e}', version: '${n}' },\n }),`)),`import 'reflect-metadata'
542
+ export const app = await bootstrap({ modules, runtime: ${a.name}()${l} })
543
+ `}default:{let t=[],i=[];r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`)),r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({\n info: { title: '${e}', version: '${n}' },\n }),`));let s=t.length?t.join(`
544
+ `)+`
545
+ `:``,c=i.length?`\n adapters: [\n${i.join(`
546
+ `)}\n ],`:``,l=[`bootstrap`,`requestId`,`requestLogger`,`helmet`,`cors`];o&&l.push(a.name);let u=o?`import express from 'express'\nimport {\n ${l.join(`,
547
+ `)},\n} from '@forinda/kickjs'`:`import {\n ${l.join(`,
548
+ `)},\n} from '@forinda/kickjs'\nimport { ${a.name} } from '${a.from}'`,d=o?`
549
+ express.json(),`:``;return`import 'reflect-metadata'
544
550
  // Side-effect import — registers the extended env schema with kickjs
545
551
  // **before** any controller / service / @Value gets resolved. Without
546
552
  // this line ConfigService.get('YOUR_KEY') returns undefined because the
547
553
  // cached schema would still be the base shape. See guide/configuration.
548
554
  import './config'
549
- import express from 'express'
550
- import {
551
- bootstrap,
552
- requestId,
553
- requestLogger,
554
- helmet,
555
- cors,
556
- } from '@forinda/kickjs'
557
- ${t.length?t.join(`
558
- `)+`
559
- `:``}import { modules } from './modules'
555
+ ${u}
556
+ ${s}import { modules } from './modules'
560
557
 
561
558
  // Export the app for the Vite plugin (dev mode)
562
559
  export const app = await bootstrap({
563
- modules,${i.length?`\n adapters: [\n${i.join(`
564
- `)}\n ],`:``}
560
+ modules,
561
+ runtime: ${a.name}(),${c}
565
562
  middleware: [
566
563
  helmet(),
567
564
  cors({ origin: '*' }),
568
565
  requestId(),
569
- requestLogger(),
570
- express.json(),
566
+ requestLogger(),${d}
571
567
  ],
572
568
  })
573
- `}}}function pe(){return`import { defineModules } from '@forinda/kickjs'
569
+ `}}}function he(){return`import { defineModules } from '@forinda/kickjs'
574
570
  import { HelloModule } from './hello/hello.module'
575
571
 
576
572
  // Remove HelloModule and run: kick g module <name>
577
573
  // \`defineModules()\` returns a chainable list — \`kick g module\` appends
578
574
  // \`.mount(NewModule())\` to the chain on every generation.
579
575
  export const modules = defineModules().mount(HelloModule())
580
- `}function me(e=`zod`){return e===`valibot`?`import { loadEnvFromSchema } from '@forinda/kickjs/config'
576
+ `}function ge(e=`zod`){return e===`valibot`?`import { loadEnvFromSchema } from '@forinda/kickjs/config'
581
577
  import { fromValibot } from '@forinda/kickjs-schema/valibot'
582
578
  import * as v from 'valibot'
583
579
 
@@ -705,7 +701,7 @@ const envSchema = fromZod(
705
701
  export const env = loadEnvFromSchema(envSchema)
706
702
 
707
703
  export default envSchema
708
- `}function he(){return`import { Service } from '@forinda/kickjs'
704
+ `}function _e(){return`import { Service } from '@forinda/kickjs'
709
705
 
710
706
  @Service()
711
707
  export class HelloService {
@@ -717,7 +713,7 @@ export class HelloService {
717
713
  return { status: 'ok', uptime: process.uptime() }
718
714
  }
719
715
  }
720
- `}function ge(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
716
+ `}function ve(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
721
717
  import { HelloService } from './hello.service'
722
718
 
723
719
  // \`Ctx<KickRoutes.HelloController['<method>']>\` is generated by
@@ -739,7 +735,7 @@ export class HelloController {
739
735
  ctx.json(this.helloService.healthCheck())
740
736
  }
741
737
  }
742
- `}function _e(){return`import { defineModule } from '@forinda/kickjs'
738
+ `}function ye(){return`import { defineModule } from '@forinda/kickjs'
743
739
  import { HelloController } from './hello.controller'
744
740
 
745
741
  export const HelloModule = defineModule({
@@ -760,10 +756,15 @@ export const HelloModule = defineModule({
760
756
  },
761
757
  }),
762
758
  })
763
- `}function ve(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
759
+ `}function be(e,t=`inmemory`,n=`pnpm`,r=`express`){return`import { defineConfig } from '@forinda/kickjs-cli'
764
760
 
765
761
  export default defineConfig({
766
762
  pattern: '${e}',
763
+ // The HTTP engine this app boots on (matches \`bootstrap({ runtime })\` in
764
+ // src/index.ts). Dep-aware commands read it: \`kick add upload\` installs the
765
+ // engine's multipart driver, \`kick doctor\` checks the engine peers, and
766
+ // \`kick typegen\` flips the runtime escape-hatch types to this engine.
767
+ runtime: '${r}',
767
768
  // Pinned so \`kick add\` and other dep-installing commands always use the
768
769
  // project's intended package manager, regardless of which lockfile exists.
769
770
  packageManager: '${n}',
@@ -807,7 +808,7 @@ export default defineConfig({
807
808
  },
808
809
  ],
809
810
  })
810
- `}async function ye(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,oe({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
811
+ `}async function xe(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,se({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
811
812
 
812
813
  // \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
813
814
  // \`kick typegen\` (auto-run on \`kick dev\`).
@@ -819,7 +820,7 @@ export class ${t}Controller {
819
820
  ctx.json({ message: '${t} list' })
820
821
  }
821
822
  }
822
- `)}async function be(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,tokenScope:s,style:c,write:l}=e;await l(`${n}.module.ts`,M({pascal:t,kebab:n,plural:r,repo:a,style:c})),await l(`${n}.constants.ts`,R({pascal:t,kebab:n})),await l(`${n}.controller.ts`,N({pascal:t,kebab:n,plural:r,pluralPascal:i})),await l(`${n}.service.ts`,L({pascal:t,kebab:n})),await l(`dtos/create-${n}.dto.ts`,se({pascal:t,kebab:n})),await l(`dtos/update-${n}.dto.ts`,ce({pascal:t,kebab:n})),await l(`dtos/${n}-response.dto.ts`,le({pascal:t,kebab:n})),await l(`${n}.repository.ts`,P({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:s}));let u=a===`inmemory`,d=u?`in-memory-${n}`:`${D(a)}-${n}`,f=u?F({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}):I({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`});await l(`${d}.repository.ts`,f),o||(a!==`inmemory`&&await l(`in-memory-${n}.repository.ts`,F({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await l(`__tests__/${n}.controller.test.ts`,ue({pascal:t,kebab:n,plural:r})),await l(`__tests__/${n}.repository.test.ts`,de({pascal:t,kebab:n,plural:r,repoPrefix:`../in-memory-${n}.repository`})))}function xe(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Se(t){let{name:n,modulesDir:a,noEntity:c,noTests:l,repo:u=`inmemory`,force:d,dryRun:f}=t,m=t.pluralize!==!1,h=t.pattern??`rest`;t.minimal&&(h=`minimal`);let g=D(n),_=T(n),v=m?O(g):g,y=m?k(_):_,b=p(a,v),x=[],S=d??!1,C={kebab:g,pascal:_,plural:v,pluralPascal:y,moduleDir:b,repo:u,noEntity:c??!1,noTests:l??!1,prismaClientPath:t.prismaClientPath??`@prisma/client`,tokenScope:t.tokenScope??`app`,style:t.style??`define`,write:async(t,n)=>{let a=p(b,t);if(f){x.push(a);return}if(!S&&await s(a)&&!await o({message:`File exists: ${r.dim(t)}. Overwrite?`,initialValue:!1})){i.warn(`Skipped: ${t}`);return}await e(a,n),x.push(a)},files:x};switch(h){case`minimal`:await ye(C);break;default:await be(C);break}return f||await z(a,_,v,g,C.style),x}async function z(t,n,r,i,a=`define`){let o=p(t,`index.ts`),c=await s(o),l=`./${r}/${i}.module`,u=a===`class`?`${n}Module`:`${n}Module()`;if(!c){await e(o,a===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
823
+ `)}async function Se(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,tokenScope:s,style:c,write:l}=e;await l(`${n}.module.ts`,M({pascal:t,kebab:n,plural:r,repo:a,style:c})),await l(`${n}.constants.ts`,R({pascal:t,kebab:n})),await l(`${n}.controller.ts`,N({pascal:t,kebab:n,plural:r,pluralPascal:i})),await l(`${n}.service.ts`,L({pascal:t,kebab:n})),await l(`dtos/create-${n}.dto.ts`,ce({pascal:t,kebab:n})),await l(`dtos/update-${n}.dto.ts`,le({pascal:t,kebab:n})),await l(`dtos/${n}-response.dto.ts`,ue({pascal:t,kebab:n})),await l(`${n}.repository.ts`,P({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:s}));let u=a===`inmemory`,d=u?`in-memory-${n}`:`${O(a)}-${n}`,f=u?F({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}):I({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`});await l(`${d}.repository.ts`,f),o||(a!==`inmemory`&&await l(`in-memory-${n}.repository.ts`,F({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await l(`__tests__/${n}.controller.test.ts`,de({pascal:t,kebab:n,plural:r})),await l(`__tests__/${n}.repository.test.ts`,fe({pascal:t,kebab:n,plural:r,repoPrefix:`../in-memory-${n}.repository`})))}function Ce(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function we(t){let{name:n,modulesDir:a,noEntity:c,noTests:l,repo:u=`inmemory`,force:d,dryRun:f}=t,p=t.pluralize!==!1,h=t.pattern??`rest`;t.minimal&&(h=`minimal`);let g=O(n),_=E(n),v=p?k(g):g,y=p?re(_):_,b=m(a,v),x=[],S=d??!1,C={kebab:g,pascal:_,plural:v,pluralPascal:y,moduleDir:b,repo:u,noEntity:c??!1,noTests:l??!1,prismaClientPath:t.prismaClientPath??`@prisma/client`,tokenScope:t.tokenScope??`app`,style:t.style??`define`,write:async(t,n)=>{let a=m(b,t);if(f){x.push(a);return}if(!S&&await s(a)&&!await o({message:`File exists: ${r.dim(t)}. Overwrite?`,initialValue:!1})){i.warn(`Skipped: ${t}`);return}await e(a,n),x.push(a)},files:x};switch(h){case`minimal`:await xe(C);break;default:await Se(C);break}return f||await z(a,_,v,g,C.style),x}async function z(t,n,r,i,a=`define`){let o=m(t,`index.ts`),c=await s(o),l=`./${r}/${i}.module`,u=a===`class`?`${n}Module`:`${n}Module()`;if(!c){await e(o,a===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
823
824
  import { ${n}Module } from '${l}'
824
825
 
825
826
  export const modules: AppModuleEntry[] = [${u}]
@@ -827,11 +828,11 @@ export const modules: AppModuleEntry[] = [${u}]
827
828
  import { ${n}Module } from '${l}'
828
829
 
829
830
  export const modules = defineModules().mount(${u})
830
- `);return}let d=await b(o,`utf-8`),f=`import { ${n}Module } from '${l}'`,m=A(l);if(!RegExp(`^import\\s*\\{[^}]*\\b${A(n)}Module\\b[^}]*\\}\\s*from\\s*['"]${m}['"]`,`m`).test(d)){let e=d.lastIndexOf(`import `);if(e!==-1){let t=d.indexOf(`
831
+ `);return}let d=await x(o,`utf-8`),f=`import { ${n}Module } from '${l}'`,p=A(l);if(!RegExp(`^import\\s*\\{[^}]*\\b${A(n)}Module\\b[^}]*\\}\\s*from\\s*['"]${p}['"]`,`m`).test(d)){let e=d.lastIndexOf(`import `);if(e!==-1){let t=d.indexOf(`
831
832
  `,e);d=d.slice(0,t+1)+f+`
832
833
  `+d.slice(t+1)}else d=f+`
833
- `+d}let h=V(d);if(h){let e=d.slice(h.rhsStart,h.rhsEnd+1);RegExp(`\\b${A(n)}Module\\b`).test(e)||(d=B(d,u))}else d=B(d,u);await x(o,d,`utf-8`)}function B(e,t){let n=V(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function V(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=we(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=Ce(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function Ce(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=U(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=U(e,t);if(n===-1)break;i=n+1}return i}function H(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
834
- `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function we(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=H(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function U(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=H(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function Te(t){let{name:n,outDir:r}=t,i=D(n),a=T(n),o=[],s=p(r,`${i}.adapter.ts`);return await e(s,`import {
834
+ `+d}let h=V(d);if(h){let e=d.slice(h.rhsStart,h.rhsEnd+1);RegExp(`\\b${A(n)}Module\\b`).test(e)||(d=B(d,u))}else d=B(d,u);await S(o,d,`utf-8`)}function B(e,t){let n=V(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function V(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=Ee(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=Te(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function Te(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=U(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=U(e,t);if(n===-1)break;i=n+1}return i}function H(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
835
+ `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function Ee(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=H(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function U(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=H(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function De(t){let{name:n,outDir:r}=t,i=O(n),a=E(n),o=[],s=m(r,`${i}.adapter.ts`);return await e(s,`import {
835
836
  defineAdapter,
836
837
  type AdapterContext,
837
838
  type AdapterMiddleware,
@@ -1000,9 +1001,9 @@ export const ${a}Adapter = defineAdapter<${a}AdapterConfig>({
1000
1001
  }
1001
1002
  },
1002
1003
  })
1003
- `),o.push(s),o}const Ee={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,contributor:`contributors`};function W(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,shouldPluralize:o=!0}=e;if(n)return h(n);if(r){let e=Ee,n=D(r),a=o?O(n):n,s=e[t]??``,c=p(i,a);return h(s?p(c,s):c)}return h(a)}async function De(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`middleware`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/middleware`,pattern:a,shouldPluralize:t.pluralize??!0}),s=D(n),c=E(n),l=[],u=p(o,`${s}.middleware.ts`);return await e(u,`import type { Request, Response, NextFunction } from 'express'
1004
+ `),o.push(s),o}const Oe={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,contributor:`contributors`};function W(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,shouldPluralize:o=!0}=e;if(n)return g(n);if(r){let e=Oe,n=O(r),a=o?k(n):n,s=e[t]??``,c=m(i,a);return g(s?m(c,s):c)}return g(a)}async function ke(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`middleware`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/middleware`,pattern:a,shouldPluralize:t.pluralize??!0}),s=O(n),c=D(n),l=[],u=m(o,`${s}.middleware.ts`);return await e(u,`import type { Request, Response, NextFunction } from 'express'
1004
1005
 
1005
- export interface ${T(n)}Options {
1006
+ export interface ${E(n)}Options {
1006
1007
  // Add configuration options here. The factory below closes over the
1007
1008
  // resolved options object; pass them at the call site —
1008
1009
  // \`${c}({ foo: 'bar' })\` — and the closure preserves them across
@@ -1010,7 +1011,7 @@ export interface ${T(n)}Options {
1010
1011
  }
1011
1012
 
1012
1013
  /**
1013
- * ${T(n)} middleware.
1014
+ * ${E(n)} middleware.
1014
1015
  *
1015
1016
  * Usage in bootstrap (fires on every request):
1016
1017
  * middleware: [${c}()]
@@ -1042,7 +1043,7 @@ export interface ${T(n)}Options {
1042
1043
  * Usage with @Middleware decorator:
1043
1044
  * @Middleware(${c}())
1044
1045
  */
1045
- export function ${c}(options: ${T(n)}Options = {}) {
1046
+ export function ${c}(options: ${E(n)}Options = {}) {
1046
1047
  return (req: Request, res: Response, next: NextFunction) => {
1047
1048
  // Implement your middleware logic here. \`options\` is captured by
1048
1049
  // closure — log or read it anywhere in this handler body.
@@ -1050,7 +1051,7 @@ export function ${c}(options: ${T(n)}Options = {}) {
1050
1051
  next()
1051
1052
  }
1052
1053
  }
1053
- `),l.push(u),l}async function Oe(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`guard`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/guards`,pattern:a,shouldPluralize:t.pluralize??!0}),s=D(n),c=E(n),l=T(n),u=[],d=p(o,`${s}.guard.ts`);return await e(d,`import { Container, HttpException } from '@forinda/kickjs'
1054
+ `),l.push(u),l}async function Ae(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`guard`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/guards`,pattern:a,shouldPluralize:t.pluralize??!0}),s=O(n),c=D(n),l=E(n),u=[],d=m(o,`${s}.guard.ts`);return await e(d,`import { Container, HttpException } from '@forinda/kickjs'
1054
1055
  import type { RequestContext } from '@forinda/kickjs'
1055
1056
 
1056
1057
  /**
@@ -1086,7 +1087,7 @@ export async function ${c}Guard(ctx: RequestContext, next: () => void): Promise<
1086
1087
  ctx.res.status(401).json({ message: 'Invalid or expired token' })
1087
1088
  }
1088
1089
  }
1089
- `),u.push(d),u}async function ke(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`service`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/services`,pattern:a,shouldPluralize:t.pluralize??!0}),s=D(n),c=T(n),l=[],u=p(o,`${s}.service.ts`);return await e(u,`import { Service } from '@forinda/kickjs'
1090
+ `),u.push(d),u}async function je(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`service`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/services`,pattern:a,shouldPluralize:t.pluralize??!0}),s=O(n),c=E(n),l=[],u=m(o,`${s}.service.ts`);return await e(u,`import { Service } from '@forinda/kickjs'
1090
1091
 
1091
1092
  @Service()
1092
1093
  export class ${c}Service {
@@ -1095,7 +1096,7 @@ export class ${c}Service {
1095
1096
  // @Inject(MY_REPO) private readonly repo: IMyRepository,
1096
1097
  // ) {}
1097
1098
  }
1098
- `),l.push(u),l}async function Ae(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`controller`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/controllers`,pattern:a,shouldPluralize:t.pluralize??!0}),s=D(n),c=T(n),l=[],u=p(o,`${s}.controller.ts`);return await e(u,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
1099
+ `),l.push(u),l}async function Me(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`controller`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/controllers`,pattern:a,shouldPluralize:t.pluralize??!0}),s=O(n),c=E(n),l=[],u=m(o,`${s}.controller.ts`);return await e(u,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
1099
1100
 
1100
1101
  // \`Ctx<KickRoutes.${c}Controller['<method>']>\` is generated by
1101
1102
  // \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
@@ -1116,7 +1117,7 @@ export class ${c}Controller {
1116
1117
  ctx.created({ message: '${c} created', data: ctx.body })
1117
1118
  }
1118
1119
  }
1119
- `),l.push(u),l}async function je(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`dto`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/dtos`,pattern:a,shouldPluralize:t.pluralize??!0}),s=D(n),c=T(n),l=E(n),u=[],d=p(o,`${s}.dto.ts`);return await e(d,`import { z } from 'zod'
1120
+ `),l.push(u),l}async function Ne(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=W({type:`dto`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/dtos`,pattern:a,shouldPluralize:t.pluralize??!0}),s=O(n),c=E(n),l=D(n),u=[],d=m(o,`${s}.dto.ts`);return await e(d,`import { z } from 'zod'
1120
1121
 
1121
1122
  export const ${l}Schema = z.object({
1122
1123
  // Define your schema fields here
@@ -1124,7 +1125,7 @@ export const ${l}Schema = z.object({
1124
1125
  })
1125
1126
 
1126
1127
  export type ${c}DTO = z.infer<typeof ${l}Schema>
1127
- `),u.push(d),u}const Me={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`},Ne={zod:{name:`zod`,range:`^4.3.6`},valibot:{name:`valibot`,range:`^1.4.1`},yup:{name:`yup`,range:`^1.7.1`}};function G(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function Pe(e,t,n,r=[],i=`zod`){let a=Ne[i],o={"@forinda/kickjs":G(n,`@forinda/kickjs`),"@forinda/kickjs-schema":G(n,`@forinda/kickjs-schema`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,[a.name]:a.range};for(let e of r){let t=Me[e];t&&!o[t]&&(o[t]=G(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`kick dev`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:o,devDependencies:{"@forinda/kickjs-cli":G(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":G(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function Fe(){return`import { defineConfig } from 'vite'
1128
+ `),u.push(d),u}const Pe={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`},Fe={zod:{name:`zod`,range:`^4.3.6`},valibot:{name:`valibot`,range:`^1.4.1`},yup:{name:`yup`,range:`^1.7.1`}};function G(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function Ie(e,t,n,r=[],i=`zod`,a=`express`){let o=Fe[i],s={"@forinda/kickjs":G(n,`@forinda/kickjs`),"@forinda/kickjs-schema":G(n,`@forinda/kickjs-schema`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,[o.name]:o.range};a===`fastify`?(s.fastify=`^5.0.0`,s[`@fastify/middie`]=`^9.0.0`):a===`h3`&&(s.h3=`^1.0.0`);for(let e of r){let t=Pe[e];t&&!s[t]&&(s[t]=G(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`kick dev`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:s,devDependencies:{"@forinda/kickjs-cli":G(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":G(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function Le(){return`import { defineConfig } from 'vite'
1128
1129
  import { resolve } from 'node:path'
1129
1130
  import swc from 'unplugin-swc'
1130
1131
  import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
@@ -1154,7 +1155,7 @@ export default defineConfig({
1154
1155
  },
1155
1156
  },
1156
1157
  })
1157
- `}function Ie(){return JSON.stringify({compilerOptions:{target:`ES2022`,module:`ESNext`,moduleResolution:`bundler`,lib:[`ES2022`],types:[`node`,`vite/client`],strict:!0,esModuleInterop:!0,skipLibCheck:!0,sourceMap:!0,declaration:!0,experimentalDecorators:!0,emitDecoratorMetadata:!0,outDir:`dist`,paths:{"@/*":[`./src/*`]}},include:[`src`,`.kickjs/types/**/*.d.ts`,`.kickjs/types/**/*.ts`]},null,2)}function Le(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function Re(){return`# https://editorconfig.org
1158
+ `}function Re(){return JSON.stringify({compilerOptions:{target:`ES2022`,module:`ESNext`,moduleResolution:`bundler`,lib:[`ES2022`],types:[`node`,`vite/client`],strict:!0,esModuleInterop:!0,skipLibCheck:!0,sourceMap:!0,declaration:!0,experimentalDecorators:!0,emitDecoratorMetadata:!0,outDir:`dist`,paths:{"@/*":[`./src/*`]}},include:[`src`,`.kickjs/types/**/*.d.ts`,`.kickjs/types/**/*.ts`]},null,2)}function ze(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function Be(){return`# https://editorconfig.org
1158
1159
  root = true
1159
1160
 
1160
1161
  [*]
@@ -1167,14 +1168,14 @@ insert_final_newline = true
1167
1168
 
1168
1169
  [*.md]
1169
1170
  trim_trailing_whitespace = false
1170
- `}function ze(){return`node_modules/
1171
+ `}function Ve(){return`node_modules/
1171
1172
  dist/
1172
1173
  .env
1173
1174
  coverage/
1174
1175
  .DS_Store
1175
1176
  *.tsbuildinfo
1176
1177
  .kickjs/
1177
- `}function Be(){return`# Auto-detect text files and normalise line endings to LF
1178
+ `}function He(){return`# Auto-detect text files and normalise line endings to LF
1178
1179
  * text=auto eol=lf
1179
1180
 
1180
1181
  # Explicitly mark generated / binary files
@@ -1192,11 +1193,11 @@ coverage/
1192
1193
  pnpm-lock.yaml -diff linguist-generated
1193
1194
  yarn.lock -diff linguist-generated
1194
1195
  package-lock.json -diff linguist-generated
1195
- `}function Ve(){return`PORT=3000
1196
+ `}function Ue(){return`PORT=3000
1196
1197
  NODE_ENV=development
1197
- `}function He(){return`PORT=3000
1198
+ `}function We(){return`PORT=3000
1198
1199
  NODE_ENV=development
1199
- `}function Ue(){return`import { defineConfig } from 'vitest/config'
1200
+ `}function Ge(){return`import { defineConfig } from 'vitest/config'
1200
1201
  import swc from 'unplugin-swc'
1201
1202
 
1202
1203
  export default defineConfig({
@@ -1207,15 +1208,22 @@ export default defineConfig({
1207
1208
  include: ['src/**/*.test.ts'],
1208
1209
  },
1209
1210
  })
1210
- `}const We=f(ee(import.meta.url)),K=JSON.parse(_(p(We,`..`,`package.json`),`utf-8`)),Ge=`^${K.version}`,Ke=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-schema`,`@forinda/kickjs-vite`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function qe(){let e=await Promise.all(Ke.map(async e=>{try{let t=C(`npm`,[`view`,e,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(t&&/^\d+\.\d+\.\d+/.test(t))return[e,`^${t}`]}catch{}return[e,Ge]}));return Object.fromEntries(e)}async function Je(t){let{name:n,directory:r,packageManager:i=`pnpm`,template:o=`rest`,defaultRepo:s=`inmemory`,packages:c=[],schemaLib:l=`zod`}=t,u=r,d=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${n}\n`),d(`Resolving package versions...`);let f=await qe();await e(p(u,`package.json`),Pe(n,o,f,c,l)),await e(p(u,`vite.config.ts`),Fe()),await e(p(u,`tsconfig.json`),Ie()),await e(p(u,`.prettierrc`),Le()),await e(p(u,`.editorconfig`),Re()),await e(p(u,`.gitignore`),ze()),await e(p(u,`.gitattributes`),Be()),await e(p(u,`.env`),Ve()),await e(p(u,`.env.example`),He()),await e(p(u,`src/config/index.ts`),me(l)),await e(p(u,`src/index.ts`),fe(n,o,K.version,c)),await e(p(u,`src/modules/index.ts`),pe()),await e(p(u,`src/modules/hello/hello.service.ts`),he()),await e(p(u,`src/modules/hello/hello.controller.ts`),ge()),await e(p(u,`src/modules/hello/hello.module.ts`),_e()),await e(p(u,`kick.config.ts`),ve(o,s,i)),await e(p(u,`vitest.config.ts`),Ue()),await e(p(u,`README.md`),a(n,o,i));let{generateAgentDocs:m}=await import(`./agent-docs-GpRHHdWC.mjs`).then(e=>e.t);if(await m({outDir:u,name:n,pm:i,template:o,only:`all`,force:!0}),t.installDeps){console.log(`\n Installing dependencies with ${i}...\n`);try{w(`${i} install`,{cwd:u,stdio:`inherit`}),console.log(`
1211
- Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${i} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-BJwy65-p.mjs`).then(e=>e.n);await e({cwd:u,allowDuplicates:!0,silent:!0})}catch{}if(t.initGit)try{w(`git init`,{cwd:u,stdio:`pipe`}),w(`git branch -M main`,{cwd:u,stdio:`pipe`}),w(`git add -A`,{cwd:u,stdio:`pipe`}),w(`git commit -m "chore: initial commit from kick new"`,{cwd:u,stdio:`pipe`}),d(`Git repository initialized`)}catch{d(`Warning: git init failed (git may not be installed)`)}console.log(`
1212
- Project scaffolded successfully!`),console.log();let h=u!==process.cwd();d(`Next steps:`),h&&d(` cd ${n}`),t.installDeps||d(` ${i} install`);let g={rest:`kick g module user`,ddd:`kick g module user --repo drizzle`,cqrs:`kick g module user --pattern cqrs`,minimal:`# add your routes to src/index.ts`};d(` ${g[o]??g.rest}`),d(` kick dev`),d(``),d(`Commands:`),d(` kick dev Start dev server with Vite HMR`),d(` kick build Production build via Vite`),d(` kick start Run production build`),d(``),d(`Generators:`),d(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),d(` kick g scaffold <n> <f..> CRUD module from field definitions`),d(` kick g controller <name> Standalone controller`),d(` kick g service <name> @Service() class`),d(` kick g middleware <name> Express middleware`),d(` kick g guard <name> Route guard (auth, roles, etc.)`),d(` kick g adapter <name> AppAdapter with lifecycle hooks`),d(` kick g dto <name> Zod DTO schema`),d(` kick g config Generate kick.config.ts`),d(``),d(`Add packages:`),d(` kick add <pkg> Install a KickJS package + peers`),d(` kick add --list Show all available packages`),d(``),d(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),d(``)}function Ye(e){let t=new Map;return{report(n,r){let i=r instanceof Error?r.message:String(r);t.get(n)!==i&&(t.set(n,i),e(` kick typegen: ${n} pass failed (${i}) — types in .kickjs/types may be stale`))},clear(e){t.delete(e)}}}const Xe=`__kickjs_typegen_owner`;function Ze(e){let{cwd:t,config:n}=e,r=e.debounceMs??100,i=e.pipeline??{runTypegen:async e=>(await import(`./typegen-BJwy65-p.mjs`).then(e=>e.n)).runTypegen(e),runAllPluginTypegens:async e=>(await import(`./run-plugins-CubT9x_A.mjs`)).runAllPluginTypegens(e),writeTypegenArtifacts:async(e,t,n)=>(await import(`./typegen-BJwy65-p.mjs`).then(e=>e.n)).writeTypegenArtifacts(e,t,n),buildAssets:async(e,t)=>(await import(`./build-D9X9QBkC.mjs`).then(e=>e.n)).buildAssets(e,t)},a=n?.typegen?.schemaValidator??`zod`,o=n?.typegen?.envFile,s=d.resolve(t,n?.typegen?.outDir??`.kickjs/types`),c=n?.assetMap?Object.values(n.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>d.resolve(t,e)):[],l=!!n?.assetMap&&Object.keys(n.assetMap).length>0,u=e=>e.replaceAll(`\\`,`/`),f=c.map(u),p=e=>{let t=u(e);return f.some(e=>t===e||t.startsWith(`${e}/`))},m=Ye(e.emitWarning),h=null,g=!1,_=new Set,v=new Set,y=!1,b=!1;function x(r,c){i.runTypegen({cwd:t,silent:!0,allowDuplicates:!0,schemaValidator:a,envFile:o,srcDir:n?.typegen?.srcDir,outDir:n?.typegen?.outDir,assetMap:n?.assetMap,changedFiles:r,runPlugins:!1}).then(()=>m.clear(`scan`)).catch(e=>m.report(`scan`,e)),i.runAllPluginTypegens({cwd:t,config:n,silent:!0,changedFiles:r}).then(e=>i.writeTypegenArtifacts(s,e,!0)).then(()=>m.clear(`plugins`)).catch(e=>m.report(`plugins`,e)).finally(()=>e.onPassComplete?.()),c&&n&&i.buildAssets(n,{cwd:t,silent:!0}).catch(()=>{})}function S(){let e=y?void 0:{changed:[..._],removed:[...v]},t=b;_.clear(),v.clear(),y=!1,b=!1,x(e,t)}return{assetSrcRoots:c,handleWatchEvent(e,t){if(!g&&!u(t).includes(`/.kickjs/`)){if(e===`unlinkDir`)y=!0,l&&(b=!0);else{if(t.endsWith(`.d.ts`))return;let n=/\.(ts|tsx|mts|cts)$/.test(t),r=p(t);if(!n&&!r)return;r&&l&&(b=!0),n&&(e===`unlink`?(v.add(t),_.delete(t)):(_.add(t),v.delete(t)))}h&&clearTimeout(h),h=setTimeout(S,r)}},runOnce(){g||x(void 0,l)},dispose(){g=!0,h&&clearTimeout(h),h=null}}}function Qe(e){return D(e).replace(/-/g,`_`)}function q(e){let t=e.cwd??process.cwd(),n=e.projectRoot??l(t),r=e.pluralize??!0,i=T(e.name),a=E(e.name),o=D(e.name),s=Qe(e.name),c={name:e.name,pascal:i,camel:a,kebab:o,snake:s,modulesDir:e.modulesDir??`src/modules`,cwd:t,projectRoot:n,args:e.args??[],flags:e.flags??{}};if(r){let e=O(o);c.pluralKebab=e,c.pluralPascal=T(e),c.pluralCamel=E(e)}return c}function $e(e,t){return h(e.cwd,t)}async function et(e){return import(te(e).href)}const J=new Map;async function Y(e){let t=J.get(e);if(t)return t;let n=tt(e);return J.set(e,n),n}async function tt(e){let t=h(e,`package.json`);if(!g(t))return{generators:[],loaded:[],failed:[]};let n=nt(JSON.parse(await b(t,`utf-8`))),r=u(h(e,`package.json`)),i=[],a=[],o=[];for(let e of n){let t;try{t=r.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await b(t,`utf-8`))}catch(t){o.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let s=n.kickjs.generators,c=h(f(t),s);if(!g(c)){o.push({source:e,reason:`kickjs.generators points to missing file: ${s}`});continue}let l;try{l=await et(c)}catch(t){o.push({source:e,reason:`failed to import manifest: ${t}`});continue}let u=l.default;if(!Array.isArray(u)){o.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of u){if(!rt(t)){o.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}i.push({source:e,spec:t})}a.push(e)}return{generators:i,loaded:a,failed:o}}function nt(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function rt(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function it(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return X(r.spec,r.source,e,n);let i=ot(await Y(n),e.generatorName);return i?X(i.spec,i.source,e,n):null}async function at(e,t=[]){let n=await Y(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function ot(e,t){return e.generators.find(e=>e.spec.name===t)}async function X(t,n,r,i){let a=q({name:r.itemName,args:r.args,flags:r.flags,modulesDir:r.modulesDir,pluralize:r.pluralize,cwd:i,projectRoot:r.projectRoot}),o=await t.files(a),s=[];for(let t of o){let n=$e(a,t.path);await e(n,t.content),s.push(n)}return{files:s,source:n}}function st(e){return e}function ct(e){return e}function Z(e){try{return JSON.parse(_(e,`utf-8`))}catch{return null}}function Q(e){try{return _(e,`utf-8`)}catch{return null}}function lt(e){let t=Q(p(e,`tsconfig.json`));if(!t)return null;let n=t.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\/\/.*$/gm,``),r;try{r=JSON.parse(n)}catch{return null}if(typeof r?.extends==`string`){let t=ut(e,r.extends);if(t){let e=Z(t)??{};r.compilerOptions={...e.compilerOptions,...r.compilerOptions}}}return r}function ut(e,t){if(t.startsWith(`.`)){let n=h(e,t);return g(n)?n:null}let n=p(e,`node_modules`,t);return g(n)?n:null}function dt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function ft(){let e=process.version,t=Number.parseInt(e.replace(/^v/,``).split(`.`)[0],10);return Number.isNaN(t)||t<20?{name:`Node version`,status:`fail`,message:e,fix:`KickJS requires Node 20 or newer.
1213
- Install a supported version via nvm / fnm / volta.`}:{name:`Node version`,status:`pass`,message:e}}function $(e){if(!e.pkg)return{name:`@forinda/kickjs installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]?{name:`@forinda/kickjs installed`,status:`pass`,message:t[`@forinda/kickjs`]}:{name:`@forinda/kickjs installed`,status:`fail`,fix:"This directory does not look like a KickJS project — `@forinda/kickjs` is not in your package.json. Run `kick doctor` from the project root, or scaffold a fresh project with `kick new <name>`."}}function pt(e){if(!e.pkg)return null;let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]&&!t.express?{name:`express installed`,status:`fail`,fix:"`@forinda/kickjs` declares `express` as a required peer dependency, but your package.json does not include it. Install: pnpm add express"}:t.express?{name:`express installed`,status:`pass`,message:t.express}:null}function mt(e){if(!e.pkg)return{name:`reflect-metadata installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies};return t[`reflect-metadata`]?{name:`reflect-metadata installed`,status:`pass`,message:t[`reflect-metadata`]}:{name:`reflect-metadata installed`,status:`fail`,fix:`KickJS decorators require the reflect-metadata polyfill.
1211
+ `}const Ke=p(ee(import.meta.url)),K=JSON.parse(v(m(Ke,`..`,`package.json`),`utf-8`)),qe=`^${K.version}`,Je=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-schema`,`@forinda/kickjs-vite`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function Ye(){let e=await Promise.all(Je.map(async e=>{try{let t=w(`npm`,[`view`,e,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(t&&/^\d+\.\d+\.\d+/.test(t))return[e,`^${t}`]}catch{}return[e,qe]}));return Object.fromEntries(e)}function Xe(e,t){try{let n=w(`npm`,[`view`,`${e}@${t}`,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();return n&&/^\d+\.\d+\.\d+/.test(n)?n:null}catch{return null}}function q(e){return(e??``).replace(/^[\^~>=<\s]+/,``)}function Ze(e,t){let n=e=>q(e).split(`-`)[0].split(`.`).map(e=>Number.parseInt(e,10)||0),[r=0,i=0,a=0]=n(e),[o=0,s=0,c=0]=n(t);return r===o?i===s?a>=c:i>s:r>o}function Qe(e,t,n){try{let r=w(`npm`,[`view`,`${e}@${t}`,`exports`,`--json`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(!r)return!1;let i=JSON.parse(r);return Object.prototype.hasOwnProperty.call(i,n)}catch{return!1}}async function $e(t){let{name:n,directory:r,packageManager:i=`pnpm`,template:o=`rest`,defaultRepo:s=`inmemory`,packages:c=[],schemaLib:l=`zod`,runtime:u=`express`}=t,d=r,f=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${n}\n`),f(`Resolving package versions...`);let p=await Ye();if(u!==`express`)if(Qe(`@forinda/kickjs`,`latest`,`./${u}`))f(`Using @forinda/kickjs@latest (stable ships the ${u} runtime)`);else{let e=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`],t=[],n=!1;for(let r of e){let e=Xe(r,`alpha`);e&&Ze(e,q(p[r]))&&(p[r]=e,t.push(`${r}@${e}`),r===`@forinda/kickjs`&&(n=!0))}f(n?`Using the alpha channel for the ${u} runtime: ${t.join(`, `)}`:`WARNING: could not resolve @forinda/kickjs@alpha — the ${u} runtime subpath may be missing. After install, run: ${i} add @forinda/kickjs@alpha`)}await e(m(d,`package.json`),Ie(n,o,p,c,l,u)),await e(m(d,`vite.config.ts`),Le()),await e(m(d,`tsconfig.json`),Re()),await e(m(d,`.prettierrc`),ze()),await e(m(d,`.editorconfig`),Be()),await e(m(d,`.gitignore`),Ve()),await e(m(d,`.gitattributes`),He()),await e(m(d,`.env`),Ue()),await e(m(d,`.env.example`),We()),await e(m(d,`src/config/index.ts`),ge(l)),await e(m(d,`src/index.ts`),me(n,o,K.version,c,u)),await e(m(d,`src/modules/index.ts`),he()),await e(m(d,`src/modules/hello/hello.service.ts`),_e()),await e(m(d,`src/modules/hello/hello.controller.ts`),ve()),await e(m(d,`src/modules/hello/hello.module.ts`),ye()),await e(m(d,`kick.config.ts`),be(o,s,i,u)),await e(m(d,`vitest.config.ts`),Ge()),await e(m(d,`README.md`),a(n,o,i));let{generateAgentDocs:h}=await import(`./agent-docs-DKEQiq25.mjs`).then(e=>e.t);if(await h({outDir:d,name:n,pm:i,template:o,only:`all`,force:!0}),t.installDeps){console.log(`\n Installing dependencies with ${i}...\n`);try{T(`${i} install`,{cwd:d,stdio:`inherit`}),console.log(`
1212
+ Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${i} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-C4nEHdxn.mjs`).then(e=>e.n);await e({cwd:d,allowDuplicates:!0,silent:!0})}catch{}if(t.initGit)try{T(`git init`,{cwd:d,stdio:`pipe`}),T(`git branch -M main`,{cwd:d,stdio:`pipe`}),T(`git add -A`,{cwd:d,stdio:`pipe`}),T(`git commit -m "chore: initial commit from kick new"`,{cwd:d,stdio:`pipe`}),f(`Git repository initialized`)}catch{f(`Warning: git init failed (git may not be installed)`)}console.log(`
1213
+ Project scaffolded successfully!`),console.log();let g=d!==process.cwd();f(`Next steps:`),g&&f(` cd ${n}`),t.installDeps||f(` ${i} install`);let _={rest:`kick g module user`,ddd:`kick g module user --repo drizzle`,cqrs:`kick g module user --pattern cqrs`,minimal:`# add your routes to src/index.ts`};f(` ${_[o]??_.rest}`),f(` kick dev`),f(``),f(`Commands:`),f(` kick dev Start dev server with Vite HMR`),f(` kick build Production build via Vite`),f(` kick start Run production build`),f(``),f(`Generators:`),f(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),f(` kick g scaffold <n> <f..> CRUD module from field definitions`),f(` kick g controller <name> Standalone controller`),f(` kick g service <name> @Service() class`),f(` kick g middleware <name> Express middleware`),f(` kick g guard <name> Route guard (auth, roles, etc.)`),f(` kick g adapter <name> AppAdapter with lifecycle hooks`),f(` kick g dto <name> Zod DTO schema`),f(` kick g config Generate kick.config.ts`),f(``),f(`Add packages:`),f(` kick add <pkg> Install a KickJS package + peers`),f(` kick add --list Show all available packages`),f(``),f(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),f(``)}function et(e){let t=new Map;return{report(n,r){let i=r instanceof Error?r.message:String(r);t.get(n)!==i&&(t.set(n,i),e(` kick typegen: ${n} pass failed (${i}) — types in .kickjs/types may be stale`))},clear(e){t.delete(e)}}}const tt=`__kickjs_typegen_owner`;function nt(e){let{cwd:t,config:n}=e,r=e.debounceMs??100,i=e.pipeline??{runTypegen:async e=>(await import(`./typegen-C4nEHdxn.mjs`).then(e=>e.n)).runTypegen(e),runAllPluginTypegens:async e=>(await import(`./run-plugins-A7mE5YjC.mjs`)).runAllPluginTypegens(e),writeTypegenArtifacts:async(e,t,n)=>(await import(`./typegen-C4nEHdxn.mjs`).then(e=>e.n)).writeTypegenArtifacts(e,t,n),buildAssets:async(e,t)=>(await import(`./build-I8Yhoqj-.mjs`).then(e=>e.n)).buildAssets(e,t)},a=n?.typegen?.schemaValidator??`zod`,o=n?.typegen?.envFile,s=f.resolve(t,n?.typegen?.outDir??`.kickjs/types`),c=n?.assetMap?Object.values(n.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>f.resolve(t,e)):[],l=!!n?.assetMap&&Object.keys(n.assetMap).length>0,u=e=>e.replaceAll(`\\`,`/`),d=c.map(u),p=e=>{let t=u(e);return d.some(e=>t===e||t.startsWith(`${e}/`))},m=et(e.emitWarning),h=null,g=!1,_=new Set,v=new Set,y=!1,b=!1;function x(r,c){i.runTypegen({cwd:t,silent:!0,allowDuplicates:!0,schemaValidator:a,envFile:o,srcDir:n?.typegen?.srcDir,outDir:n?.typegen?.outDir,assetMap:n?.assetMap,changedFiles:r,runPlugins:!1}).then(()=>m.clear(`scan`)).catch(e=>m.report(`scan`,e)),i.runAllPluginTypegens({cwd:t,config:n,silent:!0,changedFiles:r}).then(e=>i.writeTypegenArtifacts(s,e,!0)).then(()=>m.clear(`plugins`)).catch(e=>m.report(`plugins`,e)).finally(()=>e.onPassComplete?.()),c&&n&&i.buildAssets(n,{cwd:t,silent:!0}).catch(()=>{})}function S(){let e=y?void 0:{changed:[..._],removed:[...v]},t=b;_.clear(),v.clear(),y=!1,b=!1,x(e,t)}return{assetSrcRoots:c,handleWatchEvent(e,t){if(!g&&!u(t).includes(`/.kickjs/`)){if(e===`unlinkDir`)y=!0,l&&(b=!0);else{if(t.endsWith(`.d.ts`))return;let n=/\.(ts|tsx|mts|cts)$/.test(t),r=p(t);if(!n&&!r)return;r&&l&&(b=!0),n&&(e===`unlink`?(v.add(t),_.delete(t)):(_.add(t),v.delete(t)))}h&&clearTimeout(h),h=setTimeout(S,r)}},runOnce(){g||x(void 0,l)},dispose(){g=!0,h&&clearTimeout(h),h=null}}}function rt(e){return O(e).replace(/-/g,`_`)}function J(e){let t=e.cwd??process.cwd(),n=e.projectRoot??u(t),r=e.pluralize??!0,i=E(e.name),a=D(e.name),o=O(e.name),s=rt(e.name),c={name:e.name,pascal:i,camel:a,kebab:o,snake:s,modulesDir:e.modulesDir??`src/modules`,cwd:t,projectRoot:n,args:e.args??[],flags:e.flags??{}};if(r){let e=k(o);c.pluralKebab=e,c.pluralPascal=E(e),c.pluralCamel=D(e)}return c}function it(e,t){return g(e.cwd,t)}async function at(e){return import(te(e).href)}const Y=new Map;async function X(e){let t=Y.get(e);if(t)return t;let n=ot(e);return Y.set(e,n),n}async function ot(e){let t=g(e,`package.json`);if(!_(t))return{generators:[],loaded:[],failed:[]};let n=st(JSON.parse(await x(t,`utf-8`))),r=d(g(e,`package.json`)),i=[],a=[],o=[];for(let e of n){let t;try{t=r.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await x(t,`utf-8`))}catch(t){o.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let s=n.kickjs.generators,c=g(p(t),s);if(!_(c)){o.push({source:e,reason:`kickjs.generators points to missing file: ${s}`});continue}let l;try{l=await at(c)}catch(t){o.push({source:e,reason:`failed to import manifest: ${t}`});continue}let u=l.default;if(!Array.isArray(u)){o.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of u){if(!ct(t)){o.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}i.push({source:e,spec:t})}a.push(e)}return{generators:i,loaded:a,failed:o}}function st(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function ct(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function lt(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return ft(r.spec,r.source,e,n);let i=dt(await X(n),e.generatorName);return i?ft(i.spec,i.source,e,n):null}async function ut(e,t=[]){let n=await X(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function dt(e,t){return e.generators.find(e=>e.spec.name===t)}async function ft(t,n,r,i){let a=J({name:r.itemName,args:r.args,flags:r.flags,modulesDir:r.modulesDir,pluralize:r.pluralize,cwd:i,projectRoot:r.projectRoot}),o=await t.files(a),s=[];for(let t of o){let n=it(a,t.path);await e(n,t.content),s.push(n)}return{files:s,source:n}}const Z={kickjs:{pkg:`@forinda/kickjs`,peers:[`express`],description:`Unified framework: DI, decorators, routing, middleware`,core:!0},vite:{pkg:`@forinda/kickjs-vite`,peers:[`vite`],description:`Vite plugin: dev server, HMR, module discovery`,dev:!0,core:!0},cli:{pkg:`@forinda/kickjs-cli`,peers:[],description:`CLI tool and code generators`,dev:!0,core:!0},zod:{pkg:`zod`,peers:[],description:`Zod schema validation (env, DTOs, OpenAPI) — wrap with fromZod()`},valibot:{pkg:`valibot`,peers:[],description:`Valibot schema validation — wrap with fromValibot()`},yup:{pkg:`yup`,peers:[],description:`Yup schema validation — wrap with fromYup()`},auth:{pkg:`@forinda/kickjs-auth`,peers:[`jsonwebtoken`],description:`JWT, API key, OAuth strategies, @Public, @Roles (+ optional argon2/bcryptjs)`,deprecated:`auth is moving to BYO — compose @LoadAuthUser/@RequireRole/@Public from defineContextDecorator (see the BYO Auth recipe in the docs)`},ai:{pkg:`@forinda/kickjs-ai`,peers:[`zod`],description:`AI toolkit — LLM providers, tool definitions from controllers`},swagger:{pkg:`@forinda/kickjs-swagger`,peers:[],description:`OpenAPI spec + Swagger UI + ReDoc`},db:{pkg:`@forinda/kickjs-db`,peers:[],description:`kick/db core — schema DSL, migrations, KickDbClient, customType`},pg:{pkg:`@forinda/kickjs-db`,peers:[`pg`],description:`kick/db + PostgreSQL driver (use @forinda/kickjs-db/pg)`},sqlite:{pkg:`@forinda/kickjs-db`,peers:[`better-sqlite3`],description:`kick/db + SQLite driver (use @forinda/kickjs-db/sqlite)`},mysql:{pkg:`@forinda/kickjs-db`,peers:[`mysql2`],description:`kick/db + MySQL driver (use @forinda/kickjs-db/mysql)`},drizzle:{pkg:`@forinda/kickjs-drizzle`,peers:[`drizzle-orm`],description:`Drizzle ORM adapter + query builder`,deprecated:"early-adoption adapter, no longer maintained — wire Drizzle directly (BYO), or use @forinda/kickjs-db, the built-in Kick ORM (`kick add db` / pg / sqlite / mysql)"},prisma:{pkg:`@forinda/kickjs-prisma`,peers:[`@prisma/client`],description:`Prisma adapter + query builder`,deprecated:"early-adoption adapter, no longer maintained — wire Prisma directly (BYO), or use @forinda/kickjs-db, the built-in Kick ORM (`kick add db` / pg / sqlite / mysql)"},ws:{pkg:`@forinda/kickjs-ws`,peers:[`ws`],description:`WebSocket with @WsController decorators`},devtools:{pkg:`@forinda/kickjs-devtools`,peers:[],description:`Development dashboard — routes, DI, metrics, health`,dev:!0},queue:{pkg:`@forinda/kickjs-queue`,peers:[],description:`Queue adapter (BullMQ/RabbitMQ/Kafka)`},"queue:bullmq":{pkg:`@forinda/kickjs-queue`,peers:[`bullmq`,`ioredis`],description:`Queue with BullMQ + Redis`},"queue:rabbitmq":{pkg:`@forinda/kickjs-queue`,peers:[`amqplib`],description:`Queue with RabbitMQ`},"queue:kafka":{pkg:`@forinda/kickjs-queue`,peers:[`kafkajs`],description:`Queue with Kafka`},"queue:redis-pubsub":{pkg:`@forinda/kickjs-queue`,peers:[`ioredis`],description:`Lightweight pub/sub via Redis (no persistence)`},mcp:{pkg:`@forinda/kickjs-mcp`,peers:[`@modelcontextprotocol/sdk`],description:`Model Context Protocol server — expose @Controller endpoints as AI tools`},testing:{pkg:`@forinda/kickjs-testing`,peers:[],description:`Test utilities and TestModule builder`,dev:!0}},pt={express:{prod:`multer`,dev:`@types/multer`,note:`Express uploads use multer (memory/disk storage, ctx.file / ctx.files).`},fastify:{prod:`@fastify/multipart`,note:`Fastify uploads use @fastify/multipart (buffered into ctx.file / ctx.files).`},h3:{note:`h3 parses multipart natively (readMultipartFormData) — no driver to install.`}};async function mt(e=process.cwd()){let t=(await c(e))?.runtime;return t===`express`||t===`fastify`||t===`h3`?t:ht(e)}function ht(e=process.cwd()){let t=Q(`package.json`,e);if(t)try{let e=JSON.parse(v(g(t,`package.json`),`utf-8`)),n={...e.dependencies,...e.devDependencies};if(`fastify`in n)return`fastify`;if(`h3`in n)return`h3`}catch{}return`express`}function Q(e,t=process.cwd()){let n=t;for(;;){if(_(g(n,e)))return n;let t=p(n);if(t===n)return null;n=t}}function gt(){return Q(`pnpm-lock.yaml`)?`pnpm`:Q(`yarn.lock`)?`yarn`:Q(`bun.lockb`)||Q(`bun.lock`)?`bun`:Q(`package-lock.json`)?`npm`:null}function _t(){let e=process.cwd();for(;e;){let t=g(e,`package.json`);if(_(t))try{let e=JSON.parse(v(t,`utf-8`)).packageManager;if(typeof e==`string`){let t=e.split(`@`)[0];if(l.includes(t))return t}}catch{}let n=p(e);if(n===e)return null;e=n}return null}async function vt(e){if(e&&l.includes(e))return{pm:e,source:`flag`};let t=await c(process.cwd());if(t?.packageManager&&l.includes(t.packageManager))return{pm:t.packageManager,source:`config`};let n=_t();if(n)return{pm:n,source:`package.json`};let r=gt();return r?{pm:r,source:`lockfile`}:{pm:`npm`,source:`default`}}async function yt(e){let{pm:t}=await vt(e);return t}function bt(e=!1){let t=Object.entries(Z),n=Math.max(...t.map(([e])=>e.length)),r=t.filter(([,e])=>e.core),i=t.filter(([,e])=>!e.core),a=([e,t])=>{let r=e.padEnd(n+2),i=t.peers.length?` (+ ${t.peers.join(`, `)})`:``,a=t.deprecated?` [DEPRECATED — ${t.deprecated}]`:``;return` ${r} ${t.description}${i}${a}`};console.log(`
1214
+ Core packages (always installed by \`kick new\`):
1215
+ `);for(let e of r)console.log(a(e));if(e){console.log(`
1216
+ Optional packages (add as needed):
1217
+ `);for(let e of i)console.log(a(e))}else console.log(`\n Plus ${i.length} optional packages (auth, swagger, db, queue, …).`),console.log(" Run `kick add --list --all` for the full catalog.");console.log(`
1218
+ Usage: kick add ai db swagger`),console.log(` kick add queue:bullmq`),console.log(` kick add upload # installs the multipart driver for your runtime`),console.log()}function xt(e,t,n=`express`){let r=new Set,i=new Set,a=[],o=[],s=[];for(let c of e){if(c===`upload`){let e=pt[n];s.push(`upload (${n}): ${e.note}`),e.prod&&(t?i:r).add(e.prod),e.dev&&i.add(e.dev);continue}let e=Z[c];if(!e){a.push(c);continue}e.deprecated&&o.push(`'${c}' (${e.pkg}) is deprecated — ${e.deprecated}`);let l=t||e.dev?i:r;l.add(e.pkg);for(let t of e.peers)l.add(t)}return{prodDeps:[...r],devDeps:[...i],unknown:a,warnings:o,notices:s}}function St(e){e.command(`list`).alias(`ls`).description(`List KickJS packages (core only; pair with --all for the full catalog)`).option(`--all`,`Include the full optional catalog`).action(e=>{bt(!!e.all)})}function Ct(e){e.command(`add [packages...]`).description(`Add KickJS packages with their required dependencies`).option(`--pm <manager>`,`Package manager override`).option(`-D, --dev`,`Install as dev dependency`).option(`--list`,`List packages (core only by default; pair with --all)`).option(`--all`,`When listing, include the full optional catalog`).action(async(e,t)=>{if(t.list||e.length===0){bt(!!t.all);return}let{pm:n,source:r}=await vt(t.pm);console.log(`\n Using ${n} (resolved from ${r})`);let i=await mt(process.cwd()),{prodDeps:a,devDeps:o,unknown:s,warnings:c,notices:l}=xt(e,!!t.dev,i);for(let e of c)console.warn(`\n WARNING: ${e}`);for(let e of l)console.log(`\n ${e}`);if(!(s.length>0&&(console.log(`\n Unknown packages: ${s.join(`, `)}`),console.log(` Run "kick add --list" to see available packages.
1219
+ `),a.length===0&&o.length===0))){if(a.length>0){let e=a,t=`${n} add ${e.join(` `)}`;console.log(`\n Installing ${e.length} dependency(ies):`);for(let t of e)console.log(` + ${t}`);console.log();try{T(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}if(o.length>0){let e=o,t=`${n} add -D ${e.join(` `)}`;console.log(`\n Installing ${e.length} dev dependency(ies):`);for(let t of e)console.log(` + ${t} (dev)`);console.log();try{T(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}console.log(` Done!
1220
+ `)}})}function wt(e){return e}function Tt(e){return e}function Et(e){try{return JSON.parse(v(e,`utf-8`))}catch{return null}}function $(e){try{return v(e,`utf-8`)}catch{return null}}function Dt(e){let t=$(m(e,`tsconfig.json`));if(!t)return null;let n=t.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\/\/.*$/gm,``),r;try{r=JSON.parse(n)}catch{return null}if(typeof r?.extends==`string`){let t=Ot(e,r.extends);if(t){let e=Et(t)??{};r.compilerOptions={...e.compilerOptions,...r.compilerOptions}}}return r}function Ot(e,t){if(t.startsWith(`.`)){let n=g(e,t);return _(n)?n:null}let n=m(e,`node_modules`,t);return _(n)?n:null}function kt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function At(){let e=process.version,t=Number.parseInt(e.replace(/^v/,``).split(`.`)[0],10);return Number.isNaN(t)||t<20?{name:`Node version`,status:`fail`,message:e,fix:`KickJS requires Node 20 or newer.
1221
+ Install a supported version via nvm / fnm / volta.`}:{name:`Node version`,status:`pass`,message:e}}function jt(e){if(!e.pkg)return{name:`@forinda/kickjs installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]?{name:`@forinda/kickjs installed`,status:`pass`,message:t[`@forinda/kickjs`]}:{name:`@forinda/kickjs installed`,status:`fail`,fix:"This directory does not look like a KickJS project — `@forinda/kickjs` is not in your package.json. Run `kick doctor` from the project root, or scaffold a fresh project with `kick new <name>`."}}function Mt(e){if(!e.pkg)return null;let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]&&!t.express?{name:`express installed`,status:`fail`,fix:"`@forinda/kickjs` declares `express` as a required peer dependency, but your package.json does not include it. Install: pnpm add express"}:t.express?{name:`express installed`,status:`pass`,message:t.express}:null}const Nt={express:[],fastify:[`fastify`,`@fastify/middie`],h3:[`h3`]};function Pt(e){if(!e.pkg||e.runtime===`express`)return null;let t={...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies},n=Nt[e.runtime].filter(e=>!t[e]),r=`runtime engine (${e.runtime})`;return n.length>0?{name:r,status:`fail`,fix:`Resolved runtime '${e.runtime}' is missing engine peer(s): ${n.join(`, `)}.\nInstall: pnpm add ${n.join(` `)}`}:{name:r,status:`pass`}}function Ft(e){if(!e.pkg||!Lt(e.cwd))return null;let t=pt[e.runtime],n=`upload driver (${e.runtime})`;return t.prod?{...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies}[t.prod]?{name:n,status:`pass`,message:t.prod}:{name:n,status:`fail`,fix:`This project uses file uploads on the '${e.runtime}' runtime, which needs '${t.prod}'.\nInstall it: kick add upload (or pnpm add ${t.prod})`}:{name:n,status:`pass`,message:`native multipart`}}const It=2e3;function Lt(e){let t=m(e,`src`);if(!_(t))return!1;let n=/@FileUpload\b|\bupload\.(single|array|none)\s*\(/,r=[t],i=0;for(;r.length>0&&i<It;){let e=r.pop(),t;try{t=y(e,{withFileTypes:!0})}catch{continue}for(let a of t){if(i>=It)break;let t=m(e,a.name);if(a.isDirectory()){a.name!==`node_modules`&&r.push(t);continue}if(/\.(ts|tsx|mts|cts)$/.test(a.name)&&(i++,n.test($(t)??``)))return!0}}return!1}function Rt(e){if(!e.pkg)return{name:`reflect-metadata installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies};return t[`reflect-metadata`]?{name:`reflect-metadata installed`,status:`pass`,message:t[`reflect-metadata`]}:{name:`reflect-metadata installed`,status:`fail`,fix:`KickJS decorators require the reflect-metadata polyfill.
1214
1222
  Install it: pnpm add reflect-metadata
1215
1223
  Then import it at the top of src/index.ts:
1216
1224
 
1217
1225
  import 'reflect-metadata'
1218
- // ... rest of bootstrap`}}function ht(e){if(!e.tsconfig)return[{name:`tsconfig.json present`,status:`fail`,fix:"Create a tsconfig.json with `experimentalDecorators: true` and `emitDecoratorMetadata: true`. `kick new` scaffolds one automatically."}];let t=e.tsconfig.compilerOptions??{},n=[];return n.push(t.experimentalDecorators===!0?{name:`tsconfig: experimentalDecorators`,status:`pass`}:{name:`tsconfig: experimentalDecorators`,status:`fail`,fix:'Add `"experimentalDecorators": true` to compilerOptions in tsconfig.json. Without it, @Service / @Controller / @Get etc. don\'t register any metadata at compile time.'}),n.push(t.emitDecoratorMetadata===!0?{name:`tsconfig: emitDecoratorMetadata`,status:`pass`}:{name:`tsconfig: emitDecoratorMetadata`,status:`fail`,fix:'Add `"emitDecoratorMetadata": true` to compilerOptions in tsconfig.json. The DI container uses this metadata for constructor-parameter injection.'}),n}function gt(e){let t=[`src/env.ts`,`src/env/index.ts`,`src/config/env.ts`,`src/config/index.ts`].map(t=>p(e.cwd,t)).filter(e=>g(e)).filter(e=>/\bloadEnv\s*\(/.test(Q(e)??``));if(t.length===0)return null;let n=[`src/index.ts`,`src/main.ts`].map(t=>p(e.cwd,t)).find(e=>g(e));if(!n)return{name:`env wiring`,status:`warn`,message:`env-init file exists but no src/index.ts or src/main.ts found`};let r=Q(n)??``,i=f(n),a=[];for(let e of t){let t=m(i,e).replace(/\\/g,`/`).replace(/\.ts$/,``),n=t.startsWith(`.`)?t:`./`+t,r=n.replace(/\/index$/,``);a.push(n,r);let o=e.replace(/\\/g,`/`).match(/\/src\/(.+?)(?:\.ts)?$/);if(o){let e=`@/`+o[1],t=e.replace(/\/index$/,``);a.push(e,t)}}let o=-1;for(let e of new Set(a)){let t=RegExp(`^import\\s+(?:.*?from\\s+)?['"]${dt(e)}['"]`,`m`),n=r.match(t);n&&n.index!==void 0&&(o===-1||n.index<o)&&(o=n.index)}let s=r.search(/\bbootstrap\s*\(/),c=t.map(t=>m(e.cwd,t).replace(/\\/g,`/`)).join(`, `);return o===-1?{name:`env wiring`,status:`fail`,message:c,fix:`An env-init file (${c}) calls \`loadEnv(...)\` but \`${m(e.cwd,n).replace(/\\/g,`/`)}\` doesn't import it.\nWithout this, ConfigService.get('X') returns undefined while @Value('X') works via process.env fallback — a half-broken config you won't notice until something is missing.\n\nFix: add a side-effect import at the top of ${m(e.cwd,n).replace(/\\/g,`/`)} (above bootstrap()), pointing at one of the detected files. For example:\n\n import './env'\n // or\n import './config'\n // or, with the @/ alias:\n import '@/config/env'`}:s!==-1&&o>s?{name:`env wiring`,status:`warn`,message:`env-init imported AFTER bootstrap() — should be before`,fix:`Move the env import above the bootstrap() call so the schema runs before any service reads from ConfigService.`}:{name:`env wiring`,status:`pass`}}function _t(e,t=vt){let n=0,r=0,i=[e];for(;i.length>0&&r<t;){let e=i.pop(),a;try{a=v(e,{withFileTypes:!0})}catch{continue}for(let o of a){if(r>=t)break;r++;let a=p(e,o.name);if(o.isDirectory()){i.push(a);continue}try{let e=y(a).mtimeMs;e>n&&(n=e)}catch{}}}return n}const vt=2e3;function yt(e){let t=p(e.cwd,`.kickjs`,`types`);if(!g(t))return null;let n=_t(t);if(n===0)return null;let r=Date.now()-n,i=Math.floor(r/6e4);return i>60?{name:`typegen freshness`,status:`warn`,message:`last updated ${i} minutes ago`,fix:"Re-run `kick typegen` (or `kick dev`, which runs it on every reload) so generated types match the current code."}:{name:`typegen freshness`,status:`pass`,message:i===0?`just now`:`${i}m ago`}}const bt=[()=>ft(),$,pt,mt,ht,gt,yt];async function xt(e,t={}){let n={cwd:e,pkg:Z(p(e,`package.json`)),tsconfig:lt(e)},r=[...bt,...t.extraChecks??[]],i=[];for(let e of r){let t;try{t=await e(n)}catch(t){i.push({name:e.name||`doctor check`,status:`fail`,message:t instanceof Error?t.message:String(t)});continue}t!=null&&(Array.isArray(t)?i.push(...t):i.push(t))}return i}function St(e){switch(e){case`pass`:return r.green(`✔`);case`warn`:return r.yellow(`⚠`);case`fail`:return r.red(`✖`)}}function Ct(e){let t=St(e.status),n=e.message?` ${r.dim(`(${e.message})`)}`:``;return`${t} ${e.name}${n}`}function wt(e){return e.split(`
1226
+ // ... rest of bootstrap`}}function zt(e){if(!e.tsconfig)return[{name:`tsconfig.json present`,status:`fail`,fix:"Create a tsconfig.json with `experimentalDecorators: true` and `emitDecoratorMetadata: true`. `kick new` scaffolds one automatically."}];let t=e.tsconfig.compilerOptions??{},n=[];return n.push(t.experimentalDecorators===!0?{name:`tsconfig: experimentalDecorators`,status:`pass`}:{name:`tsconfig: experimentalDecorators`,status:`fail`,fix:'Add `"experimentalDecorators": true` to compilerOptions in tsconfig.json. Without it, @Service / @Controller / @Get etc. don\'t register any metadata at compile time.'}),n.push(t.emitDecoratorMetadata===!0?{name:`tsconfig: emitDecoratorMetadata`,status:`pass`}:{name:`tsconfig: emitDecoratorMetadata`,status:`fail`,fix:'Add `"emitDecoratorMetadata": true` to compilerOptions in tsconfig.json. The DI container uses this metadata for constructor-parameter injection.'}),n}function Bt(e){let t=[`src/env.ts`,`src/env/index.ts`,`src/config/env.ts`,`src/config/index.ts`].map(t=>m(e.cwd,t)).filter(e=>_(e)).filter(e=>/\bloadEnv\s*\(/.test($(e)??``));if(t.length===0)return null;let n=[`src/index.ts`,`src/main.ts`].map(t=>m(e.cwd,t)).find(e=>_(e));if(!n)return{name:`env wiring`,status:`warn`,message:`env-init file exists but no src/index.ts or src/main.ts found`};let r=$(n)??``,i=p(n),a=[];for(let e of t){let t=h(i,e).replace(/\\/g,`/`).replace(/\.ts$/,``),n=t.startsWith(`.`)?t:`./`+t,r=n.replace(/\/index$/,``);a.push(n,r);let o=e.replace(/\\/g,`/`).match(/\/src\/(.+?)(?:\.ts)?$/);if(o){let e=`@/`+o[1],t=e.replace(/\/index$/,``);a.push(e,t)}}let o=-1;for(let e of new Set(a)){let t=RegExp(`^import\\s+(?:.*?from\\s+)?['"]${kt(e)}['"]`,`m`),n=r.match(t);n&&n.index!==void 0&&(o===-1||n.index<o)&&(o=n.index)}let s=r.search(/\bbootstrap\s*\(/),c=t.map(t=>h(e.cwd,t).replace(/\\/g,`/`)).join(`, `);return o===-1?{name:`env wiring`,status:`fail`,message:c,fix:`An env-init file (${c}) calls \`loadEnv(...)\` but \`${h(e.cwd,n).replace(/\\/g,`/`)}\` doesn't import it.\nWithout this, ConfigService.get('X') returns undefined while @Value('X') works via process.env fallback — a half-broken config you won't notice until something is missing.\n\nFix: add a side-effect import at the top of ${h(e.cwd,n).replace(/\\/g,`/`)} (above bootstrap()), pointing at one of the detected files. For example:\n\n import './env'\n // or\n import './config'\n // or, with the @/ alias:\n import '@/config/env'`}:s!==-1&&o>s?{name:`env wiring`,status:`warn`,message:`env-init imported AFTER bootstrap() — should be before`,fix:`Move the env import above the bootstrap() call so the schema runs before any service reads from ConfigService.`}:{name:`env wiring`,status:`pass`}}function Vt(e,t=Ht){let n=0,r=0,i=[e];for(;i.length>0&&r<t;){let e=i.pop(),a;try{a=y(e,{withFileTypes:!0})}catch{continue}for(let o of a){if(r>=t)break;r++;let a=m(e,o.name);if(o.isDirectory()){i.push(a);continue}try{let e=b(a).mtimeMs;e>n&&(n=e)}catch{}}}return n}const Ht=2e3;function Ut(e){let t=m(e.cwd,`.kickjs`,`types`);if(!_(t))return null;let n=Vt(t);if(n===0)return null;let r=Date.now()-n,i=Math.floor(r/6e4);return i>60?{name:`typegen freshness`,status:`warn`,message:`last updated ${i} minutes ago`,fix:"Re-run `kick typegen` (or `kick dev`, which runs it on every reload) so generated types match the current code."}:{name:`typegen freshness`,status:`pass`,message:i===0?`just now`:`${i}m ago`}}const Wt=[()=>At(),jt,Mt,Pt,Ft,Rt,zt,Bt,Ut];async function Gt(e,t={}){let n={cwd:e,pkg:Et(m(e,`package.json`)),tsconfig:Dt(e),runtime:t.runtime??`express`},r=[...Wt,...t.extraChecks??[]],i=[];for(let e of r){let t;try{t=await e(n)}catch(t){i.push({name:e.name||`doctor check`,status:`fail`,message:t instanceof Error?t.message:String(t)});continue}t!=null&&(Array.isArray(t)?i.push(...t):i.push(t))}return i}function Kt(e){switch(e){case`pass`:return r.green(`✔`);case`warn`:return r.yellow(`⚠`);case`fail`:return r.red(`✖`)}}function qt(e){let t=Kt(e.status),n=e.message?` ${r.dim(`(${e.message})`)}`:``;return`${t} ${e.name}${n}`}function Jt(e){return e.split(`
1219
1227
  `).map(e=>` ${r.dim(`→`)} ${e}`).join(`
1220
- `)}function Tt(e){return e?.doctor?.checks??[]}function Et(e){e.command(`doctor`).description(`Pre-flight checks for your KickJS project (dev environment health)`).action(async()=>{let e=process.cwd(),a=Tt(await c(e));t(`KickJS Doctor`);let o=await xt(e,{extraChecks:a});for(let e of o)i.message(Ct(e)),e.fix&&e.status!==`pass`&&i.message(wt(e.fix));let s=o.filter(e=>e.status===`pass`).length,l=o.filter(e=>e.status===`warn`).length,u=o.filter(e=>e.status===`fail`).length,d=[r.green(`${s} passed`),l>0?r.yellow(`${l} warning${l===1?``:`s`}`):`${l} warnings`,u>0?r.red(`${u} error${u===1?``:`s`}`):`${u} errors`].join(`, `);u>0?(n(`${d} — fix the errors above before running the app`),process.exit(1)):n(l>0?`${d} — review the warnings`:r.green(`${d} — your environment looks good`))})}export{O as A,L as C,N as D,P as E,E as M,D as N,M as O,T as P,R as S,F as T,Te as _,it as a,Se as b,Xe as c,je as d,Ae as f,W as g,De as h,at as i,k as j,A as k,Ze as l,Oe as m,st as n,q as o,ke as p,Et as r,ne as s,ct as t,Je as u,z as v,I as w,xe as x,V as y};
1221
- //# sourceMappingURL=doctor-CcVNNzGj.mjs.map
1228
+ `)}function Yt(e){return e?.doctor?.checks??[]}function Xt(e){e.command(`doctor`).description(`Pre-flight checks for your KickJS project (dev environment health)`).action(async()=>{let e=process.cwd(),a=Yt(await c(e)),o=await mt(e);t(`KickJS Doctor`);let s=await Gt(e,{extraChecks:a,runtime:o});for(let e of s)i.message(qt(e)),e.fix&&e.status!==`pass`&&i.message(Jt(e.fix));let l=s.filter(e=>e.status===`pass`).length,u=s.filter(e=>e.status===`warn`).length,d=s.filter(e=>e.status===`fail`).length,f=[r.green(`${l} passed`),u>0?r.yellow(`${u} warning${u===1?``:`s`}`):`${u} warnings`,d>0?r.red(`${d} error${d===1?``:`s`}`):`${d} errors`].join(`, `);d>0?(n(`${f} — fix the errors above before running the app`),process.exit(1)):n(u>0?`${f} — review the warnings`:r.green(`${f} — your environment looks good`))})}export{P as A,V as C,L as D,R as E,re as F,D as I,O as L,M,A as N,I as O,k as P,E as R,z as S,Ce as T,je as _,Ct as a,W as b,ut as c,ne as d,tt as f,Me as g,Ne as h,Z as i,N as j,F as k,lt as l,$e as m,wt as n,St as o,nt as p,Xt as r,yt as s,Tt as t,J as u,Ae as v,we as w,De as x,ke as y};
1229
+ //# sourceMappingURL=doctor-414bnUd8.mjs.map