@forinda/kickjs-cli 7.1.1 → 8.0.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 (51) hide show
  1. package/README.md +4 -3
  2. package/dist/agent-docs-B7yE3lQx.mjs +11 -0
  3. package/dist/agent-docs-BsDrREYZ.mjs +12 -0
  4. package/dist/agent-docs-BsDrREYZ.mjs.map +1 -0
  5. package/dist/{build-1OHeIhGr.mjs → build-D6d8OEIP.mjs} +2 -2
  6. package/dist/{build-BJd10HpG.mjs → build-Dzh4toKg.mjs} +3 -3
  7. package/dist/{build-BJd10HpG.mjs.map → build-Dzh4toKg.mjs.map} +1 -1
  8. package/dist/{builtins-BJ1fZBKi.mjs → builtins-BZ-nFDRJ.mjs} +2 -2
  9. package/dist/{builtins-CK8nnKx3.mjs → builtins-DAE1P8v_.mjs} +334 -317
  10. package/dist/cli.mjs +2 -2
  11. package/dist/{config-B26M-H3G.mjs → config-1AktuESd.mjs} +4 -4
  12. package/dist/config-1AktuESd.mjs.map +1 -0
  13. package/dist/{config-CcRRKBhg.mjs → config-DVJ-0xov.mjs} +3 -3
  14. package/dist/{doctor-bVCuDQuM.mjs → doctor-DKu4x3uO.mjs} +250 -233
  15. package/dist/doctor-DKu4x3uO.mjs.map +1 -0
  16. package/dist/{fullstack-BfgB5r1W.mjs → fullstack-7cYgMEf1.mjs} +3 -3
  17. package/dist/{fullstack-Bhe_l1v6.mjs → fullstack-DEgxqh6m.mjs} +4 -4
  18. package/dist/{fullstack-Bhe_l1v6.mjs.map → fullstack-DEgxqh6m.mjs.map} +1 -1
  19. package/dist/index.d.mts +30 -12
  20. package/dist/index.d.mts.map +1 -1
  21. package/dist/index.mjs +2 -2
  22. package/dist/{plugin-_eznyEJd.mjs → plugin-C5HNkLuq.mjs} +3 -3
  23. package/dist/{plugin-_eznyEJd.mjs.map → plugin-C5HNkLuq.mjs.map} +1 -1
  24. package/dist/{plugin-LY_08MMA.mjs → plugin-DhUZGZ1v.mjs} +2 -2
  25. package/dist/{project-C7RF1-Gb.mjs → project-Bb1LRDKF.mjs} +11 -7
  26. package/dist/{project-BRcVX0aF.mjs → project-D8Bjdxtm.mjs} +12 -8
  27. package/dist/project-D8Bjdxtm.mjs.map +1 -0
  28. package/dist/{project-docs-YvI9sWW2.mjs → project-docs-DWPzkZ5p.mjs} +71 -15
  29. package/dist/{project-docs-BJSgVODJ.mjs → project-docs-pIpQ-4Os.mjs} +72 -16
  30. package/dist/project-docs-pIpQ-4Os.mjs.map +1 -0
  31. package/dist/{project-root-DpJw0zEd.mjs → project-root-CJm3KGjG.mjs} +3 -3
  32. package/dist/{project-root-DpJw0zEd.mjs.map → project-root-CJm3KGjG.mjs.map} +1 -1
  33. package/dist/{project-root-Cd1GKxvd.mjs → project-root-CTbG-IYo.mjs} +2 -2
  34. package/dist/{prompts-CE8oxMS2.mjs → prompts-xizRYRHy.mjs} +2 -2
  35. package/dist/{prompts-CE8oxMS2.mjs.map → prompts-xizRYRHy.mjs.map} +1 -1
  36. package/dist/{rolldown-runtime-D-Y-59yJ.mjs → rolldown-runtime-CSIJ2o5J.mjs} +1 -1
  37. package/dist/{run-plugins-CHv-_CI_.mjs → run-plugins-BKGgSL6L.mjs} +57 -57
  38. package/dist/run-plugins-BKGgSL6L.mjs.map +1 -0
  39. package/dist/{typegen-DiD6n0_q.mjs → typegen-BA-9aIp0.mjs} +4 -4
  40. package/dist/{typegen-BDYmZKFF.mjs → typegen-D85l90Te.mjs} +5 -5
  41. package/dist/{typegen-BDYmZKFF.mjs.map → typegen-D85l90Te.mjs.map} +1 -1
  42. package/dist/{types-BvRcbnr7.mjs → types-DlARm-HF.mjs} +1 -1
  43. package/package.json +3 -3
  44. package/dist/agent-docs-Bxp34Ss6.mjs +0 -11
  45. package/dist/agent-docs-CMj7Zyj4.mjs +0 -12
  46. package/dist/agent-docs-CMj7Zyj4.mjs.map +0 -1
  47. package/dist/config-B26M-H3G.mjs.map +0 -1
  48. package/dist/doctor-bVCuDQuM.mjs.map +0 -1
  49. package/dist/project-BRcVX0aF.mjs.map +0 -1
  50. package/dist/project-docs-BJSgVODJ.mjs.map +0 -1
  51. package/dist/run-plugins-CHv-_CI_.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v7.1.1
2
+ * @forinda/kickjs-cli v8.0.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{c as e,l as t,s as n}from"./project-docs-BJSgVODJ.mjs";import{a as r,c as i,d as a,i as o,l as s,n as c,o as l,r as u,s as d,t as f,u as p}from"./prompts-CE8oxMS2.mjs";import{A as m,C as h,D as g,E as _,F as v,I as y,M as b,N as x,O as ee,P as S,S as C,T as te,_ as ne,a as re,b as ie,c as ae,f as oe,g as se,h as ce,i as le,j as w,k as ue,l as de,m as fe,p as pe,r as me,u as he,v as ge,w as _e,x as ve,y as ye}from"./doctor-bVCuDQuM.mjs";import{a as be,c as xe,o as Se,r as Ce,t as we,u as Te}from"./project-BRcVX0aF.mjs";import{a as T,c as Ee,i as De,o as E,s as Oe}from"./config-B26M-H3G.mjs";import{t as D}from"./project-root-DpJw0zEd.mjs";import{n as O}from"./types-BvRcbnr7.mjs";import{t as ke}from"./build-BJd10HpG.mjs";import{n as Ae}from"./agent-docs-CMj7Zyj4.mjs";import{n as je}from"./plugin-_eznyEJd.mjs";import{a as Me,c as Ne,d as Pe,f as Fe,g as Ie,h as Le,i as Re,l as ze,m as Be,o as Ve,p as He,r as Ue,s as We,t as Ge,u as Ke}from"./typegen-BDYmZKFF.mjs";import{createRequire as qe}from"node:module";import k,{basename as Je,dirname as A,join as j,relative as Ye,resolve as M,sep as Xe}from"node:path";import{cpSync as Ze,existsSync as N,mkdirSync as Qe,readFileSync as P,readdirSync as $e,rmSync as et,writeFileSync as tt}from"node:fs";import{copyFile as nt,mkdir as F,readFile as I,readdir as rt,rm as it,stat as at,writeFile as L}from"node:fs/promises";import{fork as ot,spawn as st,spawnSync as ct}from"node:child_process";import{fileURLToPath as lt,pathToFileURL as R}from"node:url";import{arch as ut,platform as dt,release as ft}from"node:os";import{createHash as pt}from"node:crypto";const mt=[{value:`swagger`,label:`Swagger`,hint:`OpenAPI docs`},{value:`ws`,label:`WebSocket`,hint:`rooms, heartbeat`},{value:`queue`,label:`Queue`,hint:`BullMQ/RabbitMQ/Kafka`},{value:`devtools`,label:`DevTools`,hint:`debug dashboard`}];function ht(e){e.command(`new [name]`).alias(`init`).description(`Create a new KickJS project (use "." for current directory)`).option(`-d, --directory <dir>`,`Target directory (defaults to project name)`).option(`--pm <manager>`,`Package manager: pnpm | npm | yarn | bun`).option(`--git`,`Initialize git repository`).option(`--no-git`,`Skip git initialization`).option(`--install`,`Install dependencies after scaffolding`).option(`--no-install`,`Skip dependency installation`).option(`-f, --force`,`Remove existing files without prompting`).option(`-t, --template <type>`,`Project template: rest | minimal | fullstack`).option(`--runtime <engine>`,`HTTP runtime: express | fastify | h3`).option(`-r, --repo <type>`,`Repository name (inmemory, or any DB name e.g. postgres)`).option(`-s, --schema <lib>`,`Schema library for env / DTOs: zod | valibot | yup (default: zod)`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. auth,swagger,ws,queue)`).option(`-y, --yes`,`Pick safe defaults for every prompt (template=minimal, repo=inmemory, no extras, git+install on)`).option(`--non-interactive`,`alias for --yes`).action(async(e,t)=>{c(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await i({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let a;if(e===`.`?(a=M(`.`),e=Je(a)):a=M(t.directory||e),N(a)){let i=$e(a);if(i.length>0){if(t.force)u.warn(`Clearing existing files in ${a}`);else if(n){u.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),r(`Aborted.`);return}else{u.warn(`Directory "${e}" is not empty:`);let t=i.slice(0,5);for(let e of t)u.message(` - ${e}`);if(i.length>5&&u.message(` ... and ${i.length-5} more`),!await f({message:p.red(`Remove all existing files and proceed?`),initialValue:!1})){r(`Aborted.`);return}}for(let e of i)et(M(a,e),{recursive:!0,force:!0})}}let s=t.template;s||=n?`minimal`:await l({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`minimal`,label:`Minimal`,hint:`bare Express`},{value:`fullstack`,label:`Fullstack`,hint:`server + Vite React web, typed client`}]});let d=t.runtime;d||=n?`express`:await l({message:`HTTP runtime`,options:[{value:`express`,label:`Express`,hint:`default, zero-config`},{value:`fastify`,label:`Fastify`,hint:`fastify + @fastify/middie`},{value:`h3`,label:`h3`,hint:`Nitro / Nuxt engine`}]});let m=t.pm;m||=n?await xe(void 0):await l({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let h=t.repo;h||=n?`inmemory`:await i({message:`Repository name`,placeholder:`inmemory (or a DB name, e.g. postgres)`,defaultValue:`inmemory`}),Ee(h);let g=t.schema;g||=n?`zod`:await l({message:`Schema library (env + DTO validation)`,options:[{value:`zod`,label:`Zod`,hint:`default — broad ecosystem`},{value:`valibot`,label:`Valibot`,hint:`smaller bundle`},{value:`yup`,label:`Yup`,hint:`classic API`}]}),[`zod`,`valibot`,`yup`].includes(g)||(u.warn(`Unknown --schema "${g}", falling back to zod.`),g=`zod`);let _;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();_=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else _=n?[]:await o({message:`Select packages to include`,options:[...mt],required:!1});let v;v=t.git===void 0?n?!0:await f({message:`Initialize git repository?`,initialValue:!0}):t.git;let y;if(y=t.install===void 0?n?!0:await f({message:`Install dependencies?`,initialValue:!0}):t.install,s===`fullstack`){let{initFullstackProject:t}=await import(`./fullstack-Bhe_l1v6.mjs`);await t({name:e,directory:a,packageManager:m,initGit:v,installDeps:y,schemaLib:g,runtime:d}),r(`Done! Next steps: ${p.cyan(`cd ${e} && ${m}${m===`pnpm`?` dev`:` run dev:server`}`)}`);return}await we({name:e,directory:a,packageManager:m,initGit:v,installDeps:y,template:s,defaultRepo:h,packages:_,schemaLib:g,runtime:d}),r(`Done! Next steps: ${p.cyan(`cd ${e} && ${m} dev`)}`)})}async function gt(e){let{name:n,outDir:r}=e,i=v(n),a=y(n),o=[],s=j(r,`${i}.plugin.ts`);return await t(s,`import {
11
+ import{c as e,l as t,s as n}from"./project-docs-pIpQ-4Os.mjs";import{a as r,c as i,d as a,i as o,l as s,n as c,o as l,r as u,s as d,t as f,u as p}from"./prompts-xizRYRHy.mjs";import{A as m,C as h,D as g,E as _,M as v,N as y,O as ee,P as b,S as te,T as ne,_ as re,a as ie,b as ae,c as oe,f as x,g as se,h as ce,i as le,j as ue,k as S,l as de,m as fe,p as pe,r as me,u as he,v as ge,w as _e,x as ve,y as ye}from"./doctor-DKu4x3uO.mjs";import{a as be,c as xe,o as Se,r as Ce,t as we,u as Te}from"./project-D8Bjdxtm.mjs";import{a as Ee,c as De,i as Oe,l as ke,o as C,s as w}from"./config-1AktuESd.mjs";import{t as T}from"./project-root-CJm3KGjG.mjs";import{n as E}from"./types-DlARm-HF.mjs";import{t as Ae}from"./build-Dzh4toKg.mjs";import{n as je}from"./agent-docs-BsDrREYZ.mjs";import{n as Me}from"./plugin-C5HNkLuq.mjs";import{a as Ne,c as Pe,d as Fe,f as Ie,g as Le,h as Re,i as ze,l as Be,m as Ve,o as He,p as Ue,r as We,s as Ge,t as D,u as Ke}from"./typegen-D85l90Te.mjs";import{createRequire as qe}from"node:module";import O,{basename as k,dirname as A,join as j,relative as Je,resolve as M,sep as Ye}from"node:path";import{cpSync as Xe,existsSync as N,mkdirSync as Ze,readFileSync as P,readdirSync as Qe,rmSync as $e,writeFileSync as et}from"node:fs";import{copyFile as tt,mkdir as nt,readFile as F,readdir as rt,rm as it,stat as at,writeFile as I}from"node:fs/promises";import{fork as ot,spawn as st,spawnSync as ct}from"node:child_process";import{fileURLToPath as lt,pathToFileURL as L}from"node:url";import{arch as ut,platform as dt,release as ft}from"node:os";import{createHash as pt}from"node:crypto";const mt=[{value:`swagger`,label:`Swagger`,hint:`OpenAPI docs`},{value:`ws`,label:`WebSocket`,hint:`rooms, heartbeat`},{value:`queue`,label:`Queue`,hint:`BullMQ/RabbitMQ/Kafka`},{value:`devtools`,label:`DevTools`,hint:`debug dashboard`}];function ht(e){e.command(`new [name]`).alias(`init`).description(`Create a new KickJS project (use "." for current directory)`).option(`-d, --directory <dir>`,`Target directory (defaults to project name)`).option(`--pm <manager>`,`Package manager: pnpm | npm | yarn | bun`).option(`--git`,`Initialize git repository`).option(`--no-git`,`Skip git initialization`).option(`--install`,`Install dependencies after scaffolding`).option(`--no-install`,`Skip dependency installation`).option(`-f, --force`,`Remove existing files without prompting`).option(`-t, --template <type>`,`Project template: rest | minimal | fullstack`).option(`--runtime <engine>`,`HTTP runtime: express | fastify | h3`).option(`-r, --repo <type>`,`Repository name (inmemory, or any DB name e.g. postgres)`).option(`-s, --schema <lib>`,`Schema library for env / DTOs: zod | valibot | yup (default: zod)`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. swagger,ws,queue,devtools)`).option(`-y, --yes`,`Pick safe defaults for every prompt (template=minimal, repo=inmemory, no extras, git+install on)`).option(`--non-interactive`,`alias for --yes`).action(async(e,t)=>{c(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await i({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let a;if(e===`.`?(a=M(`.`),e=k(a)):a=M(t.directory||e),N(a)){let i=Qe(a);if(i.length>0){if(t.force)u.warn(`Clearing existing files in ${a}`);else if(n){u.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),r(`Aborted.`);return}else{u.warn(`Directory "${e}" is not empty:`);let t=i.slice(0,5);for(let e of t)u.message(` - ${e}`);if(i.length>5&&u.message(` ... and ${i.length-5} more`),!await f({message:p.red(`Remove all existing files and proceed?`),initialValue:!1})){r(`Aborted.`);return}}for(let e of i)$e(M(a,e),{recursive:!0,force:!0})}}let s=t.template;s||=n?`minimal`:await l({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`minimal`,label:`Minimal`,hint:`bare Express`},{value:`fullstack`,label:`Fullstack`,hint:`server + Vite React web, typed client`}]});let d=t.runtime;d||=n?`express`:await l({message:`HTTP runtime`,options:[{value:`express`,label:`Express`,hint:`default, zero-config`},{value:`fastify`,label:`Fastify`,hint:`fastify + @fastify/middie`},{value:`h3`,label:`h3`,hint:`Nitro / Nuxt engine`}]});let m=t.pm;m||=n?await xe(void 0):await l({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let h=t.repo;h||=n?`inmemory`:await i({message:`Repository name`,placeholder:`inmemory (or a DB name, e.g. postgres)`,defaultValue:`inmemory`}),ke(h);let g=t.schema;g||=n?`zod`:await l({message:`Schema library (env + DTO validation)`,options:[{value:`zod`,label:`Zod`,hint:`default — broad ecosystem`},{value:`valibot`,label:`Valibot`,hint:`smaller bundle`},{value:`yup`,label:`Yup`,hint:`classic API`}]}),[`zod`,`valibot`,`yup`].includes(g)||(u.warn(`Unknown --schema "${g}", falling back to zod.`),g=`zod`);let _;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();_=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else _=n?[]:await o({message:`Select packages to include`,options:[...mt],required:!1});let v;v=t.git===void 0?n?!0:await f({message:`Initialize git repository?`,initialValue:!0}):t.git;let y;if(y=t.install===void 0?n?!0:await f({message:`Install dependencies?`,initialValue:!0}):t.install,s===`fullstack`){let{initFullstackProject:t}=await import(`./fullstack-DEgxqh6m.mjs`);await t({name:e,directory:a,packageManager:m,initGit:v,installDeps:y,schemaLib:g,runtime:d}),r(`Done! Next steps: ${p.cyan(`cd ${e} && ${m}${m===`pnpm`?` dev`:` run dev:server`}`)}`);return}await we({name:e,directory:a,packageManager:m,initGit:v,installDeps:y,template:s,defaultRepo:h,packages:_,schemaLib:g,runtime:d}),r(`Done! Next steps: ${p.cyan(`cd ${e} && ${m} dev`)}`)})}async function gt(e){let{name:n,outDir:r}=e,i=y(n),a=b(n),o=[],s=j(r,`${i}.plugin.ts`);return await t(s,`import {
12
12
  definePlugin,
13
13
  type AppAdapter,
14
14
  type AppModuleEntry,
@@ -154,11 +154,11 @@ export const ${a}Plugin = definePlugin<${a}PluginConfig>({
154
154
  },
155
155
  }),
156
156
  })
157
- `),o.push(s),o}function _t(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,n]=e.split(`:`).map(e=>e.trim());return{name:t,type:n||`string`}}).filter(e=>e.name.length>0):[]}async function vt(e){let{name:n,moduleName:r,modulesDir:i,pattern:a}=e,o=e.type??`http`,s=v(n),c=y(n),l=e.key??S(n),u=Array.isArray(e.params)?e.params:_t(e.params),d=ge({type:`contributor`,outDir:e.outDir,moduleName:r,modulesDir:i,defaultDir:`src/contributors`,pattern:a,shouldPluralize:e.pluralize??!0}),f=o===`http`?`defineHttpContextDecorator`:`defineContextDecorator`,p=o===`http`?`RequestContext`:`ExecutionContext`,m=u.length>0?`\nexport type ${c}Params = {\n${u.map(e=>` ${e.name}: ${e.type}`).join(`
157
+ `),o.push(s),o}function _t(e){return e?e.split(`,`).map(e=>e.trim()).filter(Boolean).map(e=>{let[t,n]=e.split(`:`).map(e=>e.trim());return{name:t,type:n||`string`}}).filter(e=>e.name.length>0):[]}async function vt(e){let{name:n,moduleName:r,modulesDir:i,pattern:a}=e,o=e.type??`http`,s=y(n),c=b(n),l=e.key??v(n),u=Array.isArray(e.params)?e.params:_t(e.params),d=ge({type:`contributor`,outDir:e.outDir,moduleName:r,modulesDir:i,defaultDir:`src/contributors`,pattern:a,shouldPluralize:e.pluralize??!0}),f=o===`http`?`defineHttpContextDecorator`:`defineContextDecorator`,p=o===`http`?`RequestContext`:`ExecutionContext`,m=u.length>0?`\nexport type ${c}Params = {\n${u.map(e=>` ${e.name}: ${e.type}`).join(`
158
158
  `)}\n}\n`:``,h=u.length>0?`${f}.withParams<${c}Params>()({`:`${f}({`,g=u.length>0?` // Every call site must supply these — no placeholder defaults.
159
159
  // Add \`paramDefaults: { … }\` for any field whose default is
160
160
  // genuinely correct for an undecorated route, and drop it from here.
161
- requiredParams: [${u.map(e=>`'${e.name}'`).join(`, `)}],\n`:``,_=u.length>0?`(ctx, _deps, params)`:`(ctx)`,b=u.length>0?` // \`params\` is typed as ${c}Params (call-site params merged onto any paramDefaults).`:` // \`ctx\` is a ${p} — read ctx.req / ctx.headers / ctx.params (http) or ctx.get (bare).`,x=`import { ${f} } from '@forinda/kickjs'
161
+ requiredParams: [${u.map(e=>`'${e.name}'`).join(`, `)}],\n`:``,_=u.length>0?`(ctx, _deps, params)`:`(ctx)`,ee=u.length>0?` // \`params\` is typed as ${c}Params (call-site params merged onto any paramDefaults).`:` // \`ctx\` is a ${p} — read ctx.req / ctx.headers / ctx.params (http) or ctx.get (bare).`,te=`import { ${f} } from '@forinda/kickjs'
162
162
  import type { ${p} } from '@forinda/kickjs'
163
163
 
164
164
  /**
@@ -200,12 +200,12 @@ ${m}
200
200
  export const ${c} = ${h}
201
201
  key: '${l}',
202
202
  ${g} resolve: ${_} => {
203
- ${b}
203
+ ${ee}
204
204
  // TODO: compute and return the value written to ctx.set('${l}', …)
205
205
  throw new Error("${c} contributor: resolve() not implemented")
206
206
  },
207
207
  })
208
- `,ee=j(d,`${s}.contributor.ts`);return await t(ee,x),[ee]}async function yt(e){let n=j(e.outDir,`kick.config.ts`),r=e.modulesDir??`src/modules`,i=e.defaultRepo??`inmemory`;return N(n)&&!e.force&&!await f({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
208
+ `,ne=j(d,`${s}.contributor.ts`);return await t(ne,te),[ne]}async function yt(e){let n=j(e.outDir,`kick.config.ts`),r=e.modulesDir??`src/modules`,i=e.defaultRepo??`inmemory`;return N(n)&&!e.force&&!await f({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
209
209
  Skipped — existing kick.config.ts preserved.`),[]):(await t(n,`import { defineConfig } from '@forinda/kickjs-cli'
210
210
 
211
211
  export default defineConfig({
@@ -248,18 +248,18 @@ export default defineConfig({
248
248
  },
249
249
  ],
250
250
  })
251
- `),[n])}function z(e,t){if(e[t]!==`{`)return-1;let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return r}return-1}function B(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=z(e,r);return i===-1?null:e.slice(r+1,i)}function V(e,t,n){let r=` `.repeat(n);return e.split(`
251
+ `),[n])}function R(e,t){if(e[t]!==`{`)return-1;let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return r}return-1}function z(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=R(e,r);return i===-1?null:e.slice(r+1,i)}function B(e,t,n){let r=` `.repeat(n);return e.split(`
252
252
  `).map(e=>{if(e.trim()===``)return e;let n=RegExp(`^ {0,${t}}`),i=e.replace(n,``);return r+i}).join(`
253
- `)}function bt(e){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`Container`&&e!==`type Container`&&e!==`type AppModule`&&e!==`AppModule`&&e!==`type ModuleRoutes`&&e!==`ModuleRoutes`);return n.includes(`defineModule`)||n.push(`defineModule`),`import { ${n.join(`, `)} } from '@forinda/kickjs'`})}function xt(e,t){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,n)=>{let r=n.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`defineModule`);return t.container&&!r.includes(`Container`)&&r.push(`Container`),t.appModule&&!r.some(e=>e===`AppModule`||e===`type AppModule`)&&r.push(`type AppModule`),t.moduleRoutes&&!r.some(e=>e===`ModuleRoutes`||e===`type ModuleRoutes`)&&r.push(`type ModuleRoutes`),t.contributorRegistrations&&!r.some(e=>e===`ContributorRegistrations`||e===`type ContributorRegistrations`)&&r.push(`type ContributorRegistrations`),`import { ${r.join(`, `)} } from '@forinda/kickjs'`})}function St(e){if(/\bdefineModule\s*\(/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+class\s+(\w+Module)\s+implements\s+AppModule\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no class form detected`};if(t.length>1)return{migrated:null,reason:`multiple module classes in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=z(e,i);if(a===-1)return{migrated:null,reason:`unbalanced class braces`};let o=e.slice(i+1,a),s=e.slice(0,n.index),c=e.slice(a+1),l=B(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=B(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=B(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=bt(s),p=``;return l&&(p+=` register(container) {${V(l,4,6)} },\n\n`),u&&(p+=` contributors() {${V(u,4,6)} },\n\n`),p+=` routes() {${V(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
253
+ `)}function bt(e){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,t)=>{let n=t.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`Container`&&e!==`type Container`&&e!==`type AppModule`&&e!==`AppModule`&&e!==`type ModuleRoutes`&&e!==`ModuleRoutes`);return n.includes(`defineModule`)||n.push(`defineModule`),`import { ${n.join(`, `)} } from '@forinda/kickjs'`})}function xt(e,t){return e.replaceAll(/import\s*\{\s*([^}]+)\s*\}\s*from\s*'@forinda\/kickjs'/g,(e,n)=>{let r=n.split(`,`).map(e=>e.trim()).filter(e=>e&&e!==`defineModule`);return t.container&&!r.includes(`Container`)&&r.push(`Container`),t.appModule&&!r.some(e=>e===`AppModule`||e===`type AppModule`)&&r.push(`type AppModule`),t.moduleRoutes&&!r.some(e=>e===`ModuleRoutes`||e===`type ModuleRoutes`)&&r.push(`type ModuleRoutes`),t.contributorRegistrations&&!r.some(e=>e===`ContributorRegistrations`||e===`type ContributorRegistrations`)&&r.push(`type ContributorRegistrations`),`import { ${r.join(`, `)} } from '@forinda/kickjs'`})}function St(e){if(/\bdefineModule\s*\(/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+class\s+(\w+Module)\s+implements\s+AppModule\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no class form detected`};if(t.length>1)return{migrated:null,reason:`multiple module classes in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=R(e,i);if(a===-1)return{migrated:null,reason:`unbalanced class braces`};let o=e.slice(i+1,a),s=e.slice(0,n.index),c=e.slice(a+1),l=z(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=z(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=z(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=bt(s),p=``;return l&&(p+=` register(container) {${B(l,4,6)} },\n\n`),u&&(p+=` contributors() {${B(u,4,6)} },\n\n`),p+=` routes() {${B(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
254
254
  name: '${r}',
255
255
  build: () => ({
256
256
  ${p}
257
257
  }),
258
- })`}${c}`}}function Ct(e){if(/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+const\s+(\w+Module)\s*=\s*defineModule\s*\(\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no defineModule form detected`};if(t.length>1)return{migrated:null,reason:`multiple defineModule blocks in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=z(e,i);if(a===-1)return{migrated:null,reason:`unbalanced defineModule braces`};let o=e.indexOf(`)`,a);if(o===-1)return{migrated:null,reason:`unbalanced defineModule call parens`};let s=e.slice(i+1,a),c=e.slice(0,n.index),l=o+1;for(;l<e.length&&(e[l]===`
259
- `||e[l]===`\r`);)l++;let u=e.slice(l),d=/build\s*:\s*\([^)]*\)\s*=>\s*\(\s*\{/g.exec(s);if(!d)return{migrated:null,reason:`build: () => ({...}) not found in defineModule`};let f=d.index+d[0].length-1,p=z(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=B(m,/register\s*\(([^)]*)\)\s*\{/),g=B(m,/contributors\s*\(\s*\)\s*\{/),_=B(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=xt(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${V(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${V(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${V(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
258
+ })`}${c}`}}function Ct(e){if(/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/.test(e))return{migrated:null,reason:`already in target form`};let t=[...e.matchAll(/export\s+const\s+(\w+Module)\s*=\s*defineModule\s*\(\s*\{/g)];if(t.length===0)return{migrated:null,reason:`no defineModule form detected`};if(t.length>1)return{migrated:null,reason:`multiple defineModule blocks in one file — migrate manually`};let n=t[0],r=n[1],i=n.index+n[0].length-1,a=R(e,i);if(a===-1)return{migrated:null,reason:`unbalanced defineModule braces`};let o=e.indexOf(`)`,a);if(o===-1)return{migrated:null,reason:`unbalanced defineModule call parens`};let s=e.slice(i+1,a),c=e.slice(0,n.index),l=o+1;for(;l<e.length&&(e[l]===`
259
+ `||e[l]===`\r`);)l++;let u=e.slice(l),d=/build\s*:\s*\([^)]*\)\s*=>\s*\(\s*\{/g.exec(s);if(!d)return{migrated:null,reason:`build: () => ({...}) not found in defineModule`};let f=d.index+d[0].length-1,p=R(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=z(m,/register\s*\(([^)]*)\)\s*\{/),g=z(m,/contributors\s*\(\s*\)\s*\{/),_=z(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=xt(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${B(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${B(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${B(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
260
260
  ${y}
261
261
  }
262
- `}${u}`}}function wt(e,t){return t===`class`?Ct(e):St(e)}function Tt(e,t){let n=e,r=!1;if(t===`define`){/\bAppModuleClass\b/.test(n)&&(n=n.replaceAll(/\bAppModuleClass\b/g,`AppModuleEntry`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)(?![(.])/g,`$1()`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}else{/\bAppModuleEntry\b/.test(n)&&(n=n.replaceAll(/\bAppModuleEntry\b/g,`AppModuleClass`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)\s*\(\s*\)/g,`$1`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}return r?{migrated:n}:{migrated:null,reason:`no changes needed`}}async function Et(e){let t=[];return await n(M(e),0),t;async function n(e,r){let i;try{i=await rt(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=j(e,a),o;try{o=await at(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function Dt(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await rt(e)}catch{return}await F(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=j(e,a),o=j(t,a),s;try{s=await at(i)}catch{continue}s.isDirectory()?await r(i,o):(await nt(i,o),n++)}}}function Ot(e){return j(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function kt(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await Et(e),s=await I(j(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Ot(r),await Dt(e,c));let l=[];for(let e of o){let t=wt(await I(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await L(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=j(e,`index.ts`),d=null;try{d=await I(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=Tt(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await L(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function At(e,t){let n=await Et(e),r=[],i=t===`define`?/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/:/export\s+const\s+\w+Module\s*=\s*defineModule\s*\(/;for(let e of n){let t=await I(e,`utf-8`);i.test(t)&&r.push(e)}return r}const jt={string:{ts:`string`,zod:`z.string()`},text:{ts:`string`,zod:`z.string()`},number:{ts:`number`,zod:`z.number()`},int:{ts:`number`,zod:`z.number().int()`},float:{ts:`number`,zod:`z.number()`},boolean:{ts:`boolean`,zod:`z.boolean()`},date:{ts:`string`,zod:`z.string().datetime()`},email:{ts:`string`,zod:`z.string().email()`},url:{ts:`string`,zod:`z.string().url()`},uuid:{ts:`string`,zod:`z.string().uuid()`},json:{ts:`any`,zod:`z.any()`}};function Mt(e){return e.map(e=>{let t=e.indexOf(`:`);if(t===-1)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let n=e.slice(0,t),r=e.slice(t+1);if(!n||!r)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let i=!1;r.endsWith(`:optional`)&&(r=r.slice(0,-9),i=!0),n.endsWith(`?`)&&(n=n.slice(0,-1),i=!0),r.endsWith(`?`)&&(r=r.slice(0,-1),i=!0);let a=r;if(a.startsWith(`enum:`)){let e=a.slice(5).split(`,`);return{name:n,type:`enum`,tsType:e.map(e=>`'${e}'`).join(` | `),zodType:`z.enum([${e.map(e=>`'${e}'`).join(`, `)}])`,optional:i}}let o=jt[a];if(!o){let e=[...Object.keys(jt),`enum:a,b,c`].join(`, `);throw Error(`Unknown field type: "${a}". Valid types: ${e}`)}return{name:n,type:a,tsType:o.ts,zodType:o.zod,optional:i}})}async function Nt(e){let{name:n,fields:r,modulesDir:i,repo:a=`inmemory`,tokenScope:o=`app`,style:s=`define`}=e,c=e.pluralize!==!1,l=v(n),u=y(n),d=c?b(l):l,f=c?x(u):u,p=j(i,d),h=[],S=async(e,n)=>{let r=j(p,e);await t(r,n),h.push(r)};await S(`${l}.module.ts`,m({pascal:u,kebab:l,plural:d,repo:a,style:s})),await S(`${l}.constants.ts`,_e({pascal:u,kebab:l})),await S(`${l}.controller.ts`,ue({pascal:u,kebab:l,plural:d,pluralPascal:f,swagger:e.swagger??!1})),await S(`${l}.service.ts`,te({pascal:u,kebab:l})),await S(`dtos/create-${l}.dto.ts`,Pt(u,r)),await S(`dtos/update-${l}.dto.ts`,Ft(u,r)),await S(`dtos/${l}-response.dto.ts`,It(u,r)),await S(`${l}.repository.ts`,ee({pascal:u,kebab:l,dtoPrefix:`./dtos`,tokenScope:o}));let C=a===`inmemory`,ne=C?`in-memory-${l}`:`${v(a)}-${l}`,re=C?g({pascal:u,kebab:l,repoPrefix:`.`,dtoPrefix:`./dtos`}):_({pascal:u,kebab:l,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`});return await S(`${ne}.repository.ts`,re),await ie(i,u,d,l,s),h}function Pt(e,t){return`import { z } from 'zod'
262
+ `}${u}`}}function wt(e,t){return t===`class`?Ct(e):St(e)}function Tt(e,t){let n=e,r=!1;if(t===`define`){/\bAppModuleClass\b/.test(n)&&(n=n.replaceAll(/\bAppModuleClass\b/g,`AppModuleEntry`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)(?![(.])/g,`$1()`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}else{/\bAppModuleEntry\b/.test(n)&&(n=n.replaceAll(/\bAppModuleEntry\b/g,`AppModuleClass`),r=!0);let e=/(=\s*\[)([\s\S]*?)(])/,t=e.exec(n);if(t){let i=t[1],a=t[3],o=t[2],s=o.replaceAll(/(\b\w+Module)\s*\(\s*\)/g,`$1`);s!==o&&(n=n.replace(e,`${i}${s}${a}`),r=!0)}}return r?{migrated:n}:{migrated:null,reason:`no changes needed`}}async function Et(e){let t=[];return await n(M(e),0),t;async function n(e,r){let i;try{i=await rt(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=j(e,a),o;try{o=await at(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function Dt(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await rt(e)}catch{return}await nt(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=j(e,a),o=j(t,a),s;try{s=await at(i)}catch{continue}s.isDirectory()?await r(i,o):(await tt(i,o),n++)}}}function Ot(e){return j(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function kt(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await Et(e),s=await F(j(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Ot(r),await Dt(e,c));let l=[];for(let e of o){let t=wt(await F(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await I(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=j(e,`index.ts`),d=null;try{d=await F(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=Tt(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await I(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function At(e,t){let n=await Et(e),r=[],i=t===`define`?/export\s+class\s+\w+Module\s+implements\s+AppModule\s*\{/:/export\s+const\s+\w+Module\s*=\s*defineModule\s*\(/;for(let e of n){let t=await F(e,`utf-8`);i.test(t)&&r.push(e)}return r}const jt={string:{ts:`string`,zod:`z.string()`},text:{ts:`string`,zod:`z.string()`},number:{ts:`number`,zod:`z.number()`},int:{ts:`number`,zod:`z.number().int()`},float:{ts:`number`,zod:`z.number()`},boolean:{ts:`boolean`,zod:`z.boolean()`},date:{ts:`string`,zod:`z.string().datetime()`},email:{ts:`string`,zod:`z.string().email()`},url:{ts:`string`,zod:`z.string().url()`},uuid:{ts:`string`,zod:`z.string().uuid()`},json:{ts:`any`,zod:`z.any()`}};function Mt(e){return e.map(e=>{let t=e.indexOf(`:`);if(t===-1)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let n=e.slice(0,t),r=e.slice(t+1);if(!n||!r)throw Error(`Invalid field: "${e}". Use format: name:type (e.g. title:string)`);let i=!1;r.endsWith(`:optional`)&&(r=r.slice(0,-9),i=!0),n.endsWith(`?`)&&(n=n.slice(0,-1),i=!0),r.endsWith(`?`)&&(r=r.slice(0,-1),i=!0);let a=r;if(a.startsWith(`enum:`)){let e=a.slice(5).split(`,`);return{name:n,type:`enum`,tsType:e.map(e=>`'${e}'`).join(` | `),zodType:`z.enum([${e.map(e=>`'${e}'`).join(`, `)}])`,optional:i}}let o=jt[a];if(!o){let e=[...Object.keys(jt),`enum:a,b,c`].join(`, `);throw Error(`Unknown field type: "${a}". Valid types: ${e}`)}return{name:n,type:a,tsType:o.ts,zodType:o.zod,optional:i}})}async function Nt(e){let{name:n,fields:r,modulesDir:i,repo:a=`inmemory`,tokenScope:o=`app`,style:s=`define`}=e,c=e.pluralize!==!1,l=y(n),u=b(n),d=c?m(l):l,f=c?ue(u):u,p=j(i,d),h=[],v=async(e,n)=>{let r=j(p,e);await t(r,n),h.push(r)};return await v(`${l}.module.ts`,ee({pascal:u,kebab:l,plural:d,repo:a,style:s})),await v(`${l}.constants.ts`,_e({pascal:u,kebab:l})),await v(`${l}.controller.ts`,g({pascal:u,kebab:l,plural:d,pluralPascal:f,swagger:e.swagger??!1})),await v(`${l}.service.ts`,ne({pascal:u,kebab:l})),await v(`dtos/create-${l}.dto.ts`,Pt(u,r)),await v(`dtos/update-${l}.dto.ts`,Ft(u,r)),await v(`dtos/${l}-response.dto.ts`,It(u,r)),await v(`${l}.repository.ts`,_({pascal:u,kebab:l,repoType:a,dtoPrefix:`./dtos`,tokenScope:o})),await ae(i,u,d,l,s),h}function Pt(e,t){return`import { z } from 'zod'
263
263
 
264
264
  export const create${e}Schema = z.object({
265
265
  ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:``},`}).join(`
@@ -282,7 +282,7 @@ ${t.map(e=>` ${e.name}${e.optional?`?`:``}: ${e.tsType}`).join(`
282
282
  createdAt: string
283
283
  updatedAt: string
284
284
  }
285
- `}async function Lt(e){let{name:n,moduleName:r,modulesDir:i}=e,a=e.pluralize??!0,o=v(n),s=y(n),c=[],l;if(e.outDir)l=M(e.outDir);else if(r){let e=v(r),t=a?b(e):e;l=M(j(i??`src/modules`,t,`__tests__`))}else l=M(`src/__tests__`);let u=j(l,`${o}.test.ts`);return await t(u,`import { describe, it, expect, beforeEach } from 'vitest'
285
+ `}async function Lt(e){let{name:n,moduleName:r,modulesDir:i}=e,a=e.pluralize??!0,o=y(n),s=b(n),c=[],l;if(e.outDir)l=M(e.outDir);else if(r){let e=y(r),t=a?m(e):e;l=M(j(i??`src/modules`,t,`__tests__`))}else l=M(`src/__tests__`);let u=j(l,`${o}.test.ts`);return await t(u,`import { describe, it, expect, beforeEach } from 'vitest'
286
286
  import { Container } from '@forinda/kickjs'
287
287
 
288
288
  describe('${s}', () => {
@@ -305,55 +305,55 @@ describe('${s}', () => {
305
305
  expect(true).toBe(true)
306
306
  })
307
307
  })
308
- `),c.push(u),c}const Rt=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`both`,`all`];function H(e){return e.parent?.opts()?.dryRun??!1}function U(e,t=!1){let n=process.cwd();console.log(`\n ${t?`Would generate`:`Generated`} ${e.length} file${e.length===1?``:`s`}:`);for(let t of e)console.log(` ${t.replace(n+`/`,``)}`);t&&console.log(`
309
- (dry run — no files were written)`),console.log()}async function zt(e){if(!e)try{let e=await T(process.cwd());await Ge({cwd:process.cwd(),allowDuplicates:!0,silent:!0,schemaValidator:e?.typegen?.schemaValidator??`zod`,envFile:e?.typegen?.envFile,srcDir:e?.typegen?.srcDir,outDir:e?.typegen?.outDir})}catch{}}const Bt=[{name:`module <name>`,description:`REST module (controller, service, DTOs, repo)`},{name:`scaffold <name> <fields...>`,description:`CRUD module from field definitions`},{name:`controller <name>`,description:`@Controller() class [-m module]`},{name:`service <name>`,description:`@Service() singleton [-m module]`},{name:`middleware <name>`,description:`Express middleware function [-m module]`},{name:`guard <name>`,description:`Route guard (auth, roles, etc.) [-m module]`},{name:`contributor <name>`,description:`Context contributor [--type http|bare] [--params a:string] [-m]`},{name:`dto <name>`,description:`Zod DTO schema [-m module]`},{name:`adapter <name>`,description:`AppAdapter with lifecycle hooks (app-level only)`},{name:`test <name>`,description:`Vitest test scaffold [-m module]`},{name:`config`,description:`Generate kick.config.ts`},{name:`agents`,description:`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md from upstream templates`}],Vt=new Map([[`job`,`Queue processors are no longer built in — their shape belongs to whichever queue you run.
308
+ `),c.push(u),c}const Rt=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`both`,`all`];function V(e){return e.parent?.opts()?.dryRun??!1}function H(e,t=!1){let n=process.cwd();console.log(`\n ${t?`Would generate`:`Generated`} ${e.length} file${e.length===1?``:`s`}:`);for(let t of e)console.log(` ${t.replace(n+`/`,``)}`);t&&console.log(`
309
+ (dry run — no files were written)`),console.log()}async function zt(e){if(!e)try{let e=await C(process.cwd());await D({cwd:process.cwd(),allowDuplicates:!0,silent:!0,schemaValidator:e?.typegen?.schemaValidator??`zod`,envFile:e?.typegen?.envFile,srcDir:e?.typegen?.srcDir,outDir:e?.typegen?.outDir})}catch{}}const Bt=[{name:`module <name>`,description:`REST module (controller, service, DTOs, repo)`},{name:`scaffold <name> <fields...>`,description:`CRUD module from field definitions`},{name:`controller <name>`,description:`@Controller() class [-m module]`},{name:`service <name>`,description:`@Service() singleton [-m module]`},{name:`middleware <name>`,description:`Express middleware function [-m module]`},{name:`guard <name>`,description:`Route guard (auth, roles, etc.) [-m module]`},{name:`contributor <name>`,description:`Context contributor [--type http|bare] [--params a:string] [-m]`},{name:`dto <name>`,description:`Zod DTO schema [-m module]`},{name:`adapter <name>`,description:`AppAdapter with lifecycle hooks (app-level only)`},{name:`test <name>`,description:`Vitest test scaffold [-m module]`},{name:`config`,description:`Generate kick.config.ts`},{name:`agents`,description:`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md from upstream templates`}],Vt=new Map([[`job`,`Queue processors are no longer built in — their shape belongs to whichever queue you run.
310
310
  Add your own in kick.config.ts: https://kickjs.app/guide/plugin-generators.html`]]),Ht=new Set([...Bt.map(e=>e.name.split(` `)[0]),...Vt.keys()]);async function Ut(){console.log(`
311
311
  Built-in generators:
312
- `);let e=Math.max(...Bt.map(e=>e.name.length));for(let t of Bt)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await T(process.cwd()),n=je(t?.plugins??[],t?.commands??[]),r=await le(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
312
+ `);let e=Math.max(...Bt.map(e=>e.name.length));for(let t of Bt)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await C(process.cwd()),n=Me(t?.plugins??[],t?.commands??[]),r=await le(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
313
313
  Plugin generators:
314
314
  `);let e=Math.max(...r.generators.map(e=>`${e.spec.name} <name>`.length));for(let{source:t,spec:n}of r.generators){let r=`${n.name} <name>`;console.log(` kick g ${r.padEnd(e+2)} ${n.description} [${t}]`)}}if(r.failed.length>0){console.log(`
315
315
  Failed to load:
316
- `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function Wt(e,t,n){let r=await T(process.cwd()),i=E(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??h(i.repo);t.repo&&Ee(t.repo);let s=t.pattern??r?.pattern??`rest`,c=t.pluralize===!1?!1:i.pluralize??!0,l=Oe(r,process.cwd()),u=De(D()),d=i.style??`define`;if(!n&&d===`define`){let e=await At(M(a),`define`);if(e.length>0){console.error(`\n ${p.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${p.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${p.bold(`Files needing migration:`)}`);for(let t of e.slice(0,5))console.error(` - ${t}`);e.length>5&&console.error(` … and ${e.length-5} more`),console.error(`\n ${p.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${p.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${p.dim(`// kick.config.ts`)}\n ${p.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let f=[];for(let r of e){let e=await C({name:r,modulesDir:M(a),noEntity:t.entity===!1,noTests:t.tests===!1,repo:o,minimal:t.minimal,force:t.force,pattern:s,dryRun:n,pluralize:c,tokenScope:l,swagger:u,style:i.style});f.push(...e)}U(f,n),await zt(n)}function Gt(t,n){let r=t.command(`generate [names...]`).alias(`g`).description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option(`--list`,`List all available generators`).option(`--dry-run`,`Preview files that would be generated without writing them`).option(`--no-entity`,`Skip entity and value object generation (module shortcut)`).option(`--no-tests`,`Skip test file generation (module shortcut)`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name (e.g. postgres)`).option(`--pattern <pattern>`,`Override project pattern: rest | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(t,i,a)=>{if(i.list){await Ut();return}if(!t||t.length===0){r.help();return}let o=H(a);e(o);let[s,c,...l]=t;if(s){let e=await T(process.cwd()),t=je(e?.plugins??[],e?.commands??[]),r=await re({generatorName:s,itemName:c??``,args:l,flags:i,cwd:process.cwd(),projectRoot:n?.projectRoot},t.generators);if(r){U(r.files,o);return}if(s!==`module`&&Ht.has(s)){let e=Vt.get(s);e?(console.error(`\n 'kick g ${s}' has been removed.`),console.error(` ${e}\n`)):(console.error(`\n '${s}' is a generator, not a module name.`),console.error(` Did you mean: kick g ${s} ${c??`<name>`}`),console.error(` If that errors, your @forinda/kickjs-cli is older than the '${s}' generator — upgrade it.\n`)),process.exitCode=1;return}}await Wt(t,i,o)});r.command(`module <names...>`).description(`Generate one or more modules (e.g. kick g module user task project)`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name (e.g. postgres)`).option(`--pattern <pattern>`,`Override project pattern: rest | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(t,n,r)=>{let i=H(r);e(i),await Wt(t,{...r.optsWithGlobals(),...n},i)}),r.command(`adapter <name>`).description(`Generate an AppAdapter with lifecycle hooks and middleware support`).option(`-o, --out <dir>`,`Output directory`,`src/adapters`).action(async(t,n,r)=>{let i=H(r);e(i),U(await ye({name:t,outDir:M(n.out)}),i)}),r.command(`plugin <name>`).description(`Generate a KickPlugin with DI, modules, adapters, middleware, and lifecycle hooks`).option(`-o, --out <dir>`,`Output directory`,`src/plugins`).action(async(t,n,r)=>{let i=H(r);e(i),U(await gt({name:t,outDir:M(n.out)}),i)}),r.command(`middleware <name>`).description(`Generate a global middleware function, typed for the configured runtime
317
- Use -m to scope it to a module: kick g middleware auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=H(r);e(i);let a=await T(process.cwd()),o=E(a),s=o.dir??`src/modules`;U(await ne({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0,runtime:a?.runtime}),i)}),r.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
318
- Use -m to scope it to a module: kick g guard admin -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=H(r);e(i);let a=await T(process.cwd()),o=E(a),s=o.dir??`src/modules`;U(await se({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i)}),r.command(`contributor <name>`).description(`Generate a Context Contributor (typed alternative to @Middleware for ctx.set)
316
+ `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function Wt(e,t,n){let r=await C(process.cwd()),i=w(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??h(i.repo);t.repo&&ke(t.repo);let s=t.pattern??r?.pattern??`rest`,c=t.pluralize===!1?!1:i.pluralize??!0,l=De(r,process.cwd()),u=Ee(T()),d=T(),f=Oe(d,`@forinda/kickjs-testing`,`any`)&&Oe(d,`supertest`,`any`),m=i.style??`define`;if(!n&&m===`define`){let e=await At(M(a),`define`);if(e.length>0){console.error(`\n ${p.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${p.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${p.bold(`Files needing migration:`)}`);for(let t of e.slice(0,5))console.error(` - ${t}`);e.length>5&&console.error(` … and ${e.length-5} more`),console.error(`\n ${p.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${p.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${p.dim(`// kick.config.ts`)}\n ${p.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let g=[];for(let r of e){let e=await te({name:r,modulesDir:M(a),noEntity:t.entity===!1,noTests:t.tests===!1,repo:o,minimal:t.minimal,force:t.force,pattern:s,testHarness:f,dryRun:n,pluralize:c,tokenScope:l,swagger:u,style:i.style});g.push(...e)}H(g,n),await zt(n)}function Gt(t,n){let r=t.command(`generate [names...]`).alias(`g`).description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option(`--list`,`List all available generators`).option(`--dry-run`,`Preview files that would be generated without writing them`).option(`--no-entity`,`Skip entity and value object generation (module shortcut)`).option(`--no-tests`,`Skip test file generation (module shortcut)`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name (e.g. postgres)`).option(`--pattern <pattern>`,`Override project pattern: rest | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(t,i,a)=>{if(i.list){await Ut();return}if(!t||t.length===0){r.help();return}let o=V(a);e(o);let[s,c,...l]=t;if(s){let e=await C(process.cwd()),t=Me(e?.plugins??[],e?.commands??[]),r=await ie({generatorName:s,itemName:c??``,args:l,flags:i,cwd:process.cwd(),projectRoot:n?.projectRoot},t.generators);if(r){H(r.files,o);return}if(s!==`module`&&Ht.has(s)){let e=Vt.get(s);e?(console.error(`\n 'kick g ${s}' has been removed.`),console.error(` ${e}\n`)):(console.error(`\n '${s}' is a generator, not a module name.`),console.error(` Did you mean: kick g ${s} ${c??`<name>`}`),console.error(` If that errors, your @forinda/kickjs-cli is older than the '${s}' generator — upgrade it.\n`)),process.exitCode=1;return}}await Wt(t,i,o)});r.command(`module <names...>`).description(`Generate one or more modules (e.g. kick g module user task project)`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name (e.g. postgres)`).option(`--pattern <pattern>`,`Override project pattern: rest | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(t,n,r)=>{let i=V(r);e(i),await Wt(t,{...r.optsWithGlobals(),...n},i)}),r.command(`adapter <name>`).description(`Generate an AppAdapter with lifecycle hooks and middleware support`).option(`-o, --out <dir>`,`Output directory`,`src/adapters`).action(async(t,n,r)=>{let i=V(r);e(i),H(await ye({name:t,outDir:M(n.out)}),i)}),r.command(`plugin <name>`).description(`Generate a KickPlugin with DI, modules, adapters, middleware, and lifecycle hooks`).option(`-o, --out <dir>`,`Output directory`,`src/plugins`).action(async(t,n,r)=>{let i=V(r);e(i),H(await gt({name:t,outDir:M(n.out)}),i)}),r.command(`middleware <name>`).description(`Generate a global middleware function, typed for the configured runtime
317
+ Use -m to scope it to a module: kick g middleware auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=V(r);e(i);let a=await C(process.cwd()),o=w(a),s=o.dir??`src/modules`;H(await re({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0,runtime:a?.runtime}),i)}),r.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
318
+ Use -m to scope it to a module: kick g guard admin -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=V(r);e(i);let a=await C(process.cwd()),o=w(a),s=o.dir??`src/modules`;H(await se({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i)}),r.command(`contributor <name>`).description(`Generate a Context Contributor (typed alternative to @Middleware for ctx.set)
319
319
  --type http (default, RequestContext) | bare (ExecutionContext)
320
320
  --params "source:string,region:number" → emits the withParams<T>() form
321
- Use -m to scope it to a module: kick g contributor tenant -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).option(`-t, --type <type>`,`Contributor flavour: http | bare`,`http`).option(`-k, --key <key>`,`Context key it writes (defaults to camelCase of name)`).option(`--params <fields>`,`Per-call params, e.g. "source:string,region:number"`).action(async(t,n,r)=>{let i=H(r);e(i);let a=(n.type??`http`).toLowerCase();a!==`http`&&a!==`bare`&&(console.warn(` kick g contributor: unknown --type '${n.type}', using 'http'.`),a=`http`);let o=await T(process.cwd()),s=E(o),c=s.dir??`src/modules`;U(await vt({name:t,type:a,key:n.key,params:n.params,outDir:n.out,moduleName:n.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),i)}),r.command(`service <name>`).description(`Generate a @Service() class
322
- Use -m to scope it to a module: kick g service payment -m orders`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=H(r);e(i);let a=await T(process.cwd()),o=E(a),s=o.dir??`src/modules`;U(await ce({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i)}),r.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
323
- Use -m to scope it to a module: kick g controller auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=H(r);e(i);let a=await T(process.cwd()),o=E(a),s=o.dir??`src/modules`;U(await fe({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i),await zt(i)}),r.command(`dto <name>`).description(`Generate a Zod DTO schema
324
- Use -m to scope it to a module: kick g dto create-user -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=H(r);e(i);let a=await T(process.cwd()),o=E(a),s=o.dir??`src/modules`;U(await pe({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i)}),r.command(`test <name>`).description(`Generate a Vitest test scaffold
325
- Use -m to scope it to a module: kick g test user-service -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module's __tests__/ folder`).action(async(t,n,r)=>{let i=H(r);e(i);let a=E(await T(process.cwd())),o=a.dir??`src/modules`;U(await Lt({name:t,outDir:n.out,moduleName:n.module,modulesDir:o,pluralize:a.pluralize??!0}),i)}),r.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
321
+ Use -m to scope it to a module: kick g contributor tenant -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).option(`-t, --type <type>`,`Contributor flavour: http | bare`,`http`).option(`-k, --key <key>`,`Context key it writes (defaults to camelCase of name)`).option(`--params <fields>`,`Per-call params, e.g. "source:string,region:number"`).action(async(t,n,r)=>{let i=V(r);e(i);let a=(n.type??`http`).toLowerCase();a!==`http`&&a!==`bare`&&(console.warn(` kick g contributor: unknown --type '${n.type}', using 'http'.`),a=`http`);let o=await C(process.cwd()),s=w(o),c=s.dir??`src/modules`;H(await vt({name:t,type:a,key:n.key,params:n.params,outDir:n.out,moduleName:n.module,modulesDir:c,pattern:o?.pattern,pluralize:s.pluralize??!0}),i)}),r.command(`service <name>`).description(`Generate a @Service() class
322
+ Use -m to scope it to a module: kick g service payment -m orders`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=V(r);e(i);let a=await C(process.cwd()),o=w(a),s=o.dir??`src/modules`;H(await ce({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i)}),r.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
323
+ Use -m to scope it to a module: kick g controller auth -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=V(r);e(i);let a=await C(process.cwd()),o=w(a),s=o.dir??`src/modules`;H(await fe({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i),await zt(i)}),r.command(`dto <name>`).description(`Generate a Zod DTO schema
324
+ Use -m to scope it to a module: kick g dto create-user -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module folder`).action(async(t,n,r)=>{let i=V(r);e(i);let a=await C(process.cwd()),o=w(a),s=o.dir??`src/modules`;H(await pe({name:t,outDir:n.out,moduleName:n.module,modulesDir:s,pattern:a?.pattern,pluralize:o.pluralize??!0}),i)}),r.command(`test <name>`).description(`Generate a Vitest test scaffold
325
+ Use -m to scope it to a module: kick g test user-service -m users`).option(`-o, --out <dir>`,`Output directory (overrides --module)`).option(`-m, --module <module>`,`Place inside a module's __tests__/ folder`).action(async(t,n,r)=>{let i=V(r);e(i);let a=w(await C(process.cwd())),o=a.dir??`src/modules`;H(await Lt({name:t,outDir:n.out,moduleName:n.module,modulesDir:o,pluralize:a.pluralize??!0}),i)}),r.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
326
326
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
327
327
  Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c
328
328
  Optional: append :optional (shell-safe): description:text:optional
329
- or use ? with quoting: "description:text?" or "description?:text"`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`--modules-dir <dir>`,`Modules directory`).action(async(t,n,r,i)=>{let a=H(i);e(a),n.length===0&&(console.error(`
329
+ or use ? with quoting: "description:text?" or "description?:text"`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`--modules-dir <dir>`,`Modules directory`).action(async(t,n,r,i)=>{let a=V(i);e(a),n.length===0&&(console.error(`
330
330
  Error: At least one field is required.
331
331
  Usage: kick g scaffold <name> <field:type> [field:type...]
332
332
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
333
333
  Optional: append :optional (shell-safe, no quoting needed)
334
- `),process.exit(1));let o=await T(process.cwd()),s=E(o),c=r.modulesDir??s.dir??`src/modules`,l=Mt(n),u=Oe(o,process.cwd()),d=De(D()),f=await Nt({name:t,fields:l,modulesDir:M(c),noEntity:r.entity===!1,noTests:r.tests===!1,pluralize:r.pluralize===!1?!1:s.pluralize??!0,tokenScope:u,swagger:d,style:s.style});console.log(`\n Scaffolded ${t} with ${l.length} field(s):`);for(let e of l)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);U(f,a),await zt(a)}),r.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(t,n)=>{let r=H(n);e(r),U(await yt({outDir:M(`.`),modulesDir:t.modulesDir,defaultRepo:t.repo,force:t.force}),r)}),r.command(`agents`).alias(`agent-docs`).alias(`ai-docs`).description(`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md (sync after framework upgrades)`).option(`--only <which>`,`Limit scope: agents | claude | skills | both (agents+claude) | all (default: all)`,`all`).option(`--name <name>`,`Project name (defaults to package.json name)`).option(`--pm <pm>`,`Package manager (defaults to package.json packageManager)`).option(`--template <template>`,`Template: rest | minimal`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(t,n)=>{let r=H(n);e(r);let i=t.only??`all`;if(!Rt.includes(i)){console.error(` Invalid --only value: ${i}. Expected: ${Rt.join(` | `)}`),process.exitCode=1;return}U(await Ae({outDir:M(`.`),only:i,name:t.name,pm:t.pm,template:t.template,force:t.force}),r)});for(let e of n?.generators??[])Kt(r,e,n?.projectRoot)}function Kt(t,n,r){let{source:i,spec:a}=n,o=a.args?.[0],s=o?.name??`itemName`,c=o?.required?`<${s}>`:`[${s}]`,l=`${a.name} ${c} [extraArgs...]`,u=t.command(l).description(`${a.description} [${i}]`);for(let e of a.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;u.option(n,e.description??``)}u.action(async(t,i,o,s)=>{let c=H(s);e(c);let l=await re({generatorName:a.name,itemName:t??``,args:i??[],flags:o,cwd:process.cwd(),projectRoot:r},[n]);l&&U(l.files,c)})}const qt=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: `;async function Jt(e){let t=k.resolve(e.cwd,`.kickjs/types`);e.check||await F(t,{recursive:!0});let n=new Map,r=e.scan??Le,i=k.resolve(e.cwd,`.kickjs`,`cache`),a=e.scan?void 0:e.changedFiles,o={cwd:e.cwd,config:e.config,async importTs(e){return await import(R(e).href)},async writeFile(t,n){let r=k.resolve(e.cwd,t);await F(k.dirname(r),{recursive:!0}),await L(r,n,`utf8`)},getScanResult:e=>{let t=Yt(e),o=n.get(t);if(!o){let s={cacheDir:i,...e};o=a?Ie(s,a):r(s),n.set(t,o)}return o},log:console,watch:e.watch,check:e.check},s=[],c=[];for(let n of e.plugins){let r=n.outExtension??`.d.ts`,i=k.join(t,`${n.id.replace(/\//g,`__`)}${r}`),a;try{a=await n.generate(o)}catch(t){let r=t instanceof Error?t.message:String(t);if(e.check)throw Error(`kick typegen --check: ${n.id} failed to generate (${r})`,{cause:t});o.log.error(` ${n.id}: typegen failed (${r}) — keeping previous output`),s.push({id:n.id,status:`error`,outFile:i});continue}if(a===null){s.push({id:n.id,status:`skipped`});continue}let l=`${qt}${n.id} */\n\n`+a+`
335
- `,u=``;if(N(i)&&(u=await I(i,`utf8`)),u===l){s.push({id:n.id,status:`unchanged`,outFile:i});continue}if(e.check){c.push({id:n.id,outFile:i}),s.push({id:n.id,status:`drifted`,outFile:i});continue}await L(i,l,`utf8`),s.push({id:n.id,status:`written`,outFile:i})}if(c.length>0)throw new he(c);return s}function Yt(e){let t=(e.extensions??[]).slice().toSorted().join(`,`),n=(e.exclude??[]).slice().toSorted().join(`,`);return[`root=${e.root}`,`cwd=${e.cwd}`,`extensions=${t}`,`exclude=${n}`,`envFile=${e.envFile??``}`].join(`|`)}function Xt(e,t){let n=new Set(t),r=[],i=[],a=new Set;for(let t of e)n.has(t.id)?(i.push(t),a.add(t.id)):r.push(t);return{enabled:r,skipped:i,unknown:[...n].filter(e=>!a.has(e))}}async function Zt(e){let{enabled:t,skipped:n,unknown:r}=Xt(je([...pi,...e.config?.plugins??[]],e.config?.commands??[]).typegens,e.config?.typegen?.disable??[]);if(!e.silent&&n.length>0)for(let e of n)console.log(` ${e.id}: disabled (typegen.disable)`);if(!e.silent&&r.length>0&&console.warn(` kick typegen: disable list references unknown id(s): ${r.map(e=>`'${e}'`).join(`, `)}. Run \`kick typegen --list\` to see registered ids.`),t.length===0)return[];try{let n=await Jt({cwd:e.cwd,config:e.config??{},plugins:t,watch:e.watch,check:e.check,changedFiles:e.changedFiles});if(!e.silent&&oe())for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(t instanceof he||e.check)throw t;if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}function Qt(e){let t=j(e,`node_modules`,`.bin`),n=process.platform===`win32`;for(let e of[`vue-tsc`,`tsgo`,`tsc`]){let r=n?[`${e}.CMD`,`${e}.cmd`,`${e}.exe`]:[e];for(let i of r){let r=j(t,i);if(N(r))return{cmd:r,args:[`--noEmit`],shell:n,kind:e}}}return null}function $t(e){let t=e.spawnFn??st,n=null,r=0,i=!1;return{schedule(){if(i)return;let a=++r;n&&=(n.kill(),null);let o=Date.now(),s=t(e.bin.cmd,e.bin.args,{cwd:e.cwd,shell:e.bin.shell,stdio:[`ignore`,`pipe`,`pipe`]});n=s;let c=``;s.stdout?.on(`data`,e=>{c+=e.toString()}),s.stderr?.on(`data`,e=>{c+=e.toString()}),s.on(`error`,()=>{a===r&&(n=null)}),s.on(`close`,t=>{i||a!==r||(n=null,e.onResult({ok:t===0,output:c,durationMs:Date.now()-o,kind:e.bin.kind}))})},dispose(){i=!0,n&&=(n.kill(),null)}}}function en(e,t=12){let n=e.trim().split(/\r?\n/);return n.length<=t?n.join(`
334
+ `),process.exit(1));let o=await C(process.cwd()),s=w(o),c=r.modulesDir??s.dir??`src/modules`,l=Mt(n),u=De(o,process.cwd()),d=Ee(T()),f=await Nt({name:t,fields:l,modulesDir:M(c),noEntity:r.entity===!1,noTests:r.tests===!1,pluralize:r.pluralize===!1?!1:s.pluralize??!0,tokenScope:u,swagger:d,style:s.style});console.log(`\n Scaffolded ${t} with ${l.length} field(s):`);for(let e of l)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);H(f,a),await zt(a)}),r.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(t,n)=>{let r=V(n);e(r),H(await yt({outDir:M(`.`),modulesDir:t.modulesDir,defaultRepo:t.repo,force:t.force}),r)}),r.command(`agents`).alias(`agent-docs`).alias(`ai-docs`).description(`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md (sync after framework upgrades)`).option(`--only <which>`,`Limit scope: agents | claude | skills | both (agents+claude) | all (default: all)`,`all`).option(`--name <name>`,`Project name (defaults to package.json name)`).option(`--pm <pm>`,`Package manager (defaults to package.json packageManager)`).option(`--template <template>`,`Template: rest | minimal`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(t,n)=>{let r=V(n);e(r);let i=t.only??`all`;if(!Rt.includes(i)){console.error(` Invalid --only value: ${i}. Expected: ${Rt.join(` | `)}`),process.exitCode=1;return}H(await je({outDir:M(`.`),only:i,name:t.name,pm:t.pm,template:t.template,force:t.force}),r)});for(let e of n?.generators??[])Kt(r,e,n?.projectRoot)}function Kt(t,n,r){let{source:i,spec:a}=n,o=a.args?.[0],s=o?.name??`itemName`,c=o?.required?`<${s}>`:`[${s}]`,l=`${a.name} ${c} [extraArgs...]`,u=t.command(l).description(`${a.description} [${i}]`);for(let e of a.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;u.option(n,e.description??``)}u.action(async(t,i,o,s)=>{let c=V(s);e(c);let l=await ie({generatorName:a.name,itemName:t??``,args:i??[],flags:o,cwd:process.cwd(),projectRoot:r},[n]);l&&H(l.files,c)})}const qt=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: `;async function Jt(e){let t=O.resolve(e.cwd,`.kickjs/types`);e.check||await nt(t,{recursive:!0});let n=new Map,r=e.scan??Re,i=O.resolve(e.cwd,`.kickjs`,`cache`),a=e.scan?void 0:e.changedFiles,o={cwd:e.cwd,config:e.config,async importTs(e){return await import(L(e).href)},async writeFile(t,n){let r=O.resolve(e.cwd,t);await nt(O.dirname(r),{recursive:!0}),await I(r,n,`utf8`)},getScanResult:e=>{let t=Yt(e),o=n.get(t);if(!o){let s={cacheDir:i,...e};o=a?Le(s,a):r(s),n.set(t,o)}return o},log:console,watch:e.watch,check:e.check},s=[],c=[];for(let n of e.plugins){let r=n.outExtension??`.d.ts`,i=O.join(t,`${n.id.replace(/\//g,`__`)}${r}`),a;try{a=await n.generate(o)}catch(t){let r=t instanceof Error?t.message:String(t);if(e.check)throw Error(`kick typegen --check: ${n.id} failed to generate (${r})`,{cause:t});o.log.error(` ${n.id}: typegen failed (${r}) — keeping previous output`),s.push({id:n.id,status:`error`,outFile:i});continue}if(a===null){s.push({id:n.id,status:`skipped`});continue}let l=`${qt}${n.id} */\n\n`+a+`
335
+ `,u=``;if(N(i)&&(u=await F(i,`utf8`)),u===l){s.push({id:n.id,status:`unchanged`,outFile:i});continue}if(e.check){c.push({id:n.id,outFile:i}),s.push({id:n.id,status:`drifted`,outFile:i});continue}await I(i,l,`utf8`),s.push({id:n.id,status:`written`,outFile:i})}if(c.length>0)throw new he(c);return s}function Yt(e){let t=(e.extensions??[]).slice().toSorted().join(`,`),n=(e.exclude??[]).slice().toSorted().join(`,`);return[`root=${e.root}`,`cwd=${e.cwd}`,`extensions=${t}`,`exclude=${n}`,`envFile=${e.envFile??``}`].join(`|`)}function Xt(e,t){let n=new Set(t),r=[],i=[],a=new Set;for(let t of e)n.has(t.id)?(i.push(t),a.add(t.id)):r.push(t);return{enabled:r,skipped:i,unknown:[...n].filter(e=>!a.has(e))}}async function U(e){let{enabled:t,skipped:n,unknown:r}=Xt(Me([...pi,...e.config?.plugins??[]],e.config?.commands??[]).typegens,e.config?.typegen?.disable??[]);if(!e.silent&&n.length>0)for(let e of n)console.log(` ${e.id}: disabled (typegen.disable)`);if(!e.silent&&r.length>0&&console.warn(` kick typegen: disable list references unknown id(s): ${r.map(e=>`'${e}'`).join(`, `)}. Run \`kick typegen --list\` to see registered ids.`),t.length===0)return[];try{let n=await Jt({cwd:e.cwd,config:e.config??{},plugins:t,watch:e.watch,check:e.check,changedFiles:e.changedFiles});if(!e.silent&&x())for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(t instanceof he||e.check)throw t;if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}function Zt(e){let t=j(e,`node_modules`,`.bin`),n=process.platform===`win32`;for(let e of[`vue-tsc`,`tsgo`,`tsc`]){let r=n?[`${e}.CMD`,`${e}.cmd`,`${e}.exe`]:[e];for(let i of r){let r=j(t,i);if(N(r))return{cmd:r,args:[`--noEmit`],shell:n,kind:e}}}return null}function Qt(e){let t=e.spawnFn??st,n=null,r=0,i=!1;return{schedule(){if(i)return;let a=++r;n&&=(n.kill(),null);let o=Date.now(),s=t(e.bin.cmd,e.bin.args,{cwd:e.cwd,shell:e.bin.shell,stdio:[`ignore`,`pipe`,`pipe`]});n=s;let c=``;s.stdout?.on(`data`,e=>{c+=e.toString()}),s.stderr?.on(`data`,e=>{c+=e.toString()}),s.on(`error`,()=>{a===r&&(n=null)}),s.on(`close`,t=>{i||a!==r||(n=null,e.onResult({ok:t===0,output:c,durationMs:Date.now()-o,kind:e.bin.kind}))})},dispose(){i=!0,n&&=(n.kill(),null)}}}function $t(e,t=12){let n=e.trim().split(/\r?\n/);return n.length<=t?n.join(`
336
336
  `):`${n.slice(0,t).join(`
337
- `)}\n… ${n.length-t} more line(s)`}function tn(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function nn(e,t=`127.0.0.1`){let n=await import(`node:inspector`);n.open(e,t,!1);let r=n.url();if(!r)throw Error(`inspector.open() reported no URL`);return r}async function rn(e,t,n={}){t&&(process.env.PORT=t);let r=tn(n.polling),i=process.cwd(),a=await T(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await Ge({cwd:i,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}let c=M(i,a?.typegen?.outDir??`.kickjs/types`);try{await Re(c,await Zt({cwd:i,config:a}),!1)}catch(e){console.warn(` kick typegen: plugin pass skipped (${e?.message??e})`)}let{createRequire:l}=await import(`node:module`),{createServer:u}=await import(R(l(M(`package.json`)).resolve(`vite`)).href);globalThis[ae]=`kick-dev`;let d=await u({configFile:M(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),f=n.typecheck??a?.dev?.typecheck??!1,p=null,m=!0;if(f){let e=Qt(i);e?p=$t({cwd:i,bin:e,onResult:e=>{d.hot.send({type:`custom`,event:`kickjs:typecheck`,data:{ok:e.ok,output:e.output,durationMs:e.durationMs}}),e.ok?m||(m=!0,console.log(` kick typecheck: clean again (${e.kind}, ${e.durationMs}ms)`)):(m=!1,console.warn(`\n kick typecheck (${e.kind}, ${e.durationMs}ms):`),console.warn(en(e.output).replace(/^/gm,` `)))}}):console.warn(` kick dev: --typecheck requested but neither tsgo (@typescript/native-preview) nor typescript is installed in this project — skipping type checks.`)}let h=de({cwd:i,config:a,emitWarning:e=>{console.warn(e),d.hot.send({type:`custom`,event:`kickjs:typegen-error`,data:{message:e,timestamp:Date.now()}})},onPassComplete:()=>p?.schedule()});d.watcher.on(`add`,e=>h.handleWatchEvent(`add`,e)),d.watcher.on(`unlink`,e=>h.handleWatchEvent(`unlink`,e)),d.watcher.on(`change`,e=>h.handleWatchEvent(`change`,e)),d.watcher.on(`unlinkDir`,e=>h.handleWatchEvent(`unlinkDir`,e)),h.assetSrcRoots.length>0&&d.watcher.add([...h.assetSrcRoots]),await d.listen(),d.printUrls(),console.log(`
337
+ `)}\n… ${n.length-t} more line(s)`}function en(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function tn(e,t=`127.0.0.1`){let n=await import(`node:inspector`);n.open(e,t,!1);let r=n.url();if(!r)throw Error(`inspector.open() reported no URL`);return r}async function nn(e,t,n={}){t&&(process.env.PORT=t);let r=en(n.polling),i=process.cwd(),a=await C(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await D({cwd:i,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}let c=M(i,a?.typegen?.outDir??`.kickjs/types`);try{await ze(c,await U({cwd:i,config:a}),!1)}catch(e){console.warn(` kick typegen: plugin pass skipped (${e?.message??e})`)}let{createRequire:l}=await import(`node:module`),{createServer:u}=await import(L(l(M(`package.json`)).resolve(`vite`)).href);globalThis[oe]=`kick-dev`;let d=await u({configFile:M(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),f=n.typecheck??a?.dev?.typecheck??!1,p=null,m=!0;if(f){let e=Zt(i);e?p=Qt({cwd:i,bin:e,onResult:e=>{d.hot.send({type:`custom`,event:`kickjs:typecheck`,data:{ok:e.ok,output:e.output,durationMs:e.durationMs}}),e.ok?m||(m=!0,console.log(` kick typecheck: clean again (${e.kind}, ${e.durationMs}ms)`)):(m=!1,console.warn(`\n kick typecheck (${e.kind}, ${e.durationMs}ms):`),console.warn($t(e.output).replace(/^/gm,` `)))}}):console.warn(` kick dev: --typecheck requested but neither tsgo (@typescript/native-preview) nor typescript is installed in this project — skipping type checks.`)}let h=de({cwd:i,config:a,emitWarning:e=>{console.warn(e),d.hot.send({type:`custom`,event:`kickjs:typegen-error`,data:{message:e,timestamp:Date.now()}})},onPassComplete:()=>p?.schedule()});d.watcher.on(`add`,e=>h.handleWatchEvent(`add`,e)),d.watcher.on(`unlink`,e=>h.handleWatchEvent(`unlink`,e)),d.watcher.on(`change`,e=>h.handleWatchEvent(`change`,e)),d.watcher.on(`unlinkDir`,e=>h.handleWatchEvent(`unlinkDir`,e)),h.assetSrcRoots.length>0&&d.watcher.add([...h.assetSrcRoots]),await d.listen(),d.printUrls(),console.log(`
338
338
  KickJS dev server running (Vite + @forinda/kickjs-vite)
339
- `),p?.schedule();let g=!1,_=async()=>{if(!g){g=!0,h.dispose(),p?.dispose();try{await globalThis.__kickjs_app_shutdown?.()}catch(e){console.error(` app shutdown hook failed: ${e?.message??e}`)}await d.close(),process.exit(0)}};process.on(`SIGINT`,_),process.on(`SIGTERM`,_),process.on(`SIGBREAK`,_)}function an(e){e.command(`dev`).description(`Start development server with Vite HMR (zero-downtime reload)`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--polling`,`Force chokidar to poll for file changes (Docker / WSL / NFS / older kernels)`).option(`--typecheck`,`Run the project TypeScript checker (tsgo/tsc --noEmit) after each change and report diagnostics`).action(async e=>{try{await rn(e.entry,e.port,{polling:e.polling,typecheck:e.typecheck})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
339
+ `),p?.schedule();let g=!1,_=async()=>{if(!g){g=!0,h.dispose(),p?.dispose();try{await globalThis.__kickjs_app_shutdown?.()}catch(e){console.error(` app shutdown hook failed: ${e?.message??e}`)}await d.close(),process.exit(0)}};process.on(`SIGINT`,_),process.on(`SIGTERM`,_),process.on(`SIGBREAK`,_)}async function rn(e){let t=await C(e);try{await D({cwd:e,allowDuplicates:!0,schemaValidator:t?.typegen?.schemaValidator??`zod`,envFile:t?.typegen?.envFile,srcDir:t?.typegen?.srcDir,outDir:t?.typegen?.outDir,assetMap:t?.assetMap,runPlugins:!1}),await ze(M(e,t?.typegen?.outDir??`.kickjs/types`),await U({cwd:e,config:t}),!1)}catch(e){console.warn(` kick typegen: skipped before typecheck (${e?.message??e}).\n Generated types may be stale — errors inside .kickjs/types are likely from that.`)}}function an(e){e.command(`dev`).description(`Start development server with Vite HMR (zero-downtime reload)`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--polling`,`Force chokidar to poll for file changes (Docker / WSL / NFS / older kernels)`).option(`--typecheck`,`Run the project TypeScript checker (tsgo/tsc --noEmit) after each change and report diagnostics`).action(async e=>{try{await nn(e.entry,e.port,{polling:e.polling,typecheck:e.typecheck})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
340
340
  Error: vite is not installed.
341
341
  Run: pnpm add -D vite unplugin-swc
342
342
  `):console.error(`
343
343
  Dev server failed:`,e.message??e),process.exit(1)}}),e.command(`build`).description(`Build for production via Vite`).action(async()=>{console.log(`
344
344
  Building for production...
345
- `);let{createRequire:e}=await import(`node:module`),{build:t}=await import(R(e(M(`package.json`)).resolve(`vite`)).href);await t({configFile:M(`vite.config.ts`)});let n=await T(process.cwd()),r=n?.copyDirs??[];if(r.length>0){console.log(`
346
- Copying directories to dist...`);for(let e of r){let t=typeof e==`string`?e:e.src,n=typeof e==`string`?j(`dist`,e):e.dest??j(`dist`,t),r=M(t),i=M(n);if(!N(r)){console.log(` ⚠ Skipped ${t} (not found)`);continue}Qe(i,{recursive:!0}),Ze(r,i,{recursive:!0}),console.log(` ✓ ${t} → ${n}`)}}if(n?.assetMap&&Object.keys(n.assetMap).length>0){console.log(`
347
- Building asset map...`);try{await ke(n,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
345
+ `);let{createRequire:e}=await import(`node:module`),{build:t}=await import(L(e(M(`package.json`)).resolve(`vite`)).href);await t({configFile:M(`vite.config.ts`)});let n=await C(process.cwd()),r=n?.copyDirs??[];if(r.length>0){console.log(`
346
+ Copying directories to dist...`);for(let e of r){let t=typeof e==`string`?e:e.src,n=typeof e==`string`?j(`dist`,e):e.dest??j(`dist`,t),r=M(t),i=M(n);if(!N(r)){console.log(` ⚠ Skipped ${t} (not found)`);continue}Ze(i,{recursive:!0}),Xe(r,i,{recursive:!0}),console.log(` ✓ ${t} → ${n}`)}}if(n?.assetMap&&Object.keys(n.assetMap).length>0){console.log(`
347
+ Building asset map...`);try{await Ae(n,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
348
348
  Build complete.
349
- `)}),e.command(`build:assets`).description(`Rebuild the .kickjs-assets.json manifest under the configured outDir (no JS rebuild)`).action(async()=>{let e=await T(process.cwd());if(!e?.assetMap||Object.keys(e.assetMap).length===0){console.log(` No assetMap entries — nothing to build.`);return}console.log(`
350
- Building asset map...`);try{await ke(e,{cwd:process.cwd()}),console.log(`
349
+ `)}),e.command(`build:assets`).description(`Rebuild the .kickjs-assets.json manifest under the configured outDir (no JS rebuild)`).action(async()=>{let e=await C(process.cwd());if(!e?.assetMap||Object.keys(e.assetMap).length===0){console.log(` No assetMap entries — nothing to build.`);return}console.log(`
350
+ Building asset map...`);try{await Ae(e,{cwd:process.cwd()}),console.log(`
351
351
  Asset build complete.
352
- `)}catch(e){console.error(` ✗ ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),e.command(`start`).description(`Start production server`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`-p, --port <port>`,`Port number`).action(e=>{let t={NODE_ENV:`production`};e.port&&(t.PORT=String(e.port)),Te(e.entry,t)}),e.command(`typecheck`).description(`Type-check the project with its own tsgo/tsc`).option(`--cwd <dir>`,`Directory to type-check`,`.`).action(e=>{let t=M(process.cwd(),e.cwd??`.`),n=Qt(t);if(!n){console.error(`
352
+ `)}catch(e){console.error(` ✗ ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),e.command(`start`).description(`Start production server`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`-p, --port <port>`,`Port number`).action(e=>{let t={NODE_ENV:`production`};e.port&&(t.PORT=String(e.port)),Te(e.entry,t)}),e.command(`typecheck`).description(`Type-check the project with its own tsgo/tsc`).option(`--cwd <dir>`,`Directory to type-check`,`.`).option(`--no-typegen`,`Skip refreshing .kickjs/types first`).action(async e=>{let t=M(process.cwd(),e.cwd??`.`);e.typegen!==!1&&await rn(t);let n=Zt(t);if(!n){console.error(`
353
353
  No type-checker found. Install one in this project:
354
354
  pnpm add -D typescript (tsc)
355
355
  pnpm add -D @typescript/native-preview (tsgo, faster)
356
- `),process.exit(1);return}let r=ct(n.cmd,n.args,{stdio:`inherit`,shell:n.shell,cwd:t});process.exit(r.status??1)}),e.command(`dev:debug`).description(`Start dev server with Node.js inspector attached`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--inspect-port <port>`,`Inspector port`,`9229`).option(`--inspect-host <host>`,`Inspector bind address (use 0.0.0.0 to reach it from outside a container)`,`127.0.0.1`).action(async e=>{let t=Number(e.inspectPort??`9229`),n=e.inspectHost??`127.0.0.1`;[`127.0.0.1`,`localhost`,`::1`].includes(n)||console.warn(` WARNING: the debugger is bound to ${n}, not loopback. Anyone who can\n reach port ${t} can run code in this process. Use it on a trusted\n network only, and prefer publishing the port from your container instead.`);let r;try{r=await nn(t,n)}catch(e){console.error(`\n Could not open the inspector on ${t}: ${e.message??e}\n Another process may already hold it — try --inspect-port <port>.`),process.exit(1);return}console.log(` Debugger: ${r}`);try{await rn(e.entry,e.port)}catch(e){console.error(`
356
+ `),process.exit(1);return}let r=ct(n.cmd,n.args,{stdio:`inherit`,shell:n.shell,cwd:t});process.exit(r.status??1)}),e.command(`dev:debug`).description(`Start dev server with Node.js inspector attached`).option(`-e, --entry <file>`,`Entry file`,`src/index.ts`).option(`-p, --port <port>`,`Port number`).option(`--inspect-port <port>`,`Inspector port`,`9229`).option(`--inspect-host <host>`,`Inspector bind address (use 0.0.0.0 to reach it from outside a container)`,`127.0.0.1`).action(async e=>{let t=Number(e.inspectPort??`9229`),n=e.inspectHost??`127.0.0.1`;[`127.0.0.1`,`localhost`,`::1`].includes(n)||console.warn(` WARNING: the debugger is bound to ${n}, not loopback. Anyone who can\n reach port ${t} can run code in this process. Use it on a trusted\n network only, and prefer publishing the port from your container instead.`);let r;try{r=await tn(t,n)}catch(e){console.error(`\n Could not open the inspector on ${t}: ${e.message??e}\n Another process may already hold it — try --inspect-port <port>.`),process.exit(1);return}console.log(` Debugger: ${r}`);try{await nn(e.entry,e.port)}catch(e){console.error(`
357
357
  Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function on(){try{let e=A(lt(import.meta.url));return JSON.parse(P(j(e,`..`,`package.json`),`utf-8`)).version??`unknown`}catch{return`unknown`}}const sn=new Set(Object.values(Ce).filter(e=>e.deprecated).map(e=>e.pkg));function cn(e){let t=j(e,`package.json`);if(!N(t))return[];let n;try{n=JSON.parse(P(t,`utf-8`))}catch{return[]}let r={...n.dependencies,...n.devDependencies};return Object.keys(r).filter(e=>e===`@forinda/kickjs`||e.startsWith(`@forinda/kickjs-`)).toSorted().map(t=>{let n=null,i=j(e,`node_modules`,...t.split(`/`),`package.json`);if(N(i))try{n=JSON.parse(P(i,`utf-8`)).version??null}catch{}return{name:t,installed:n,declared:r[t]??null,deprecated:sn.has(t)}})}function ln(e){let t=e;for(;;){if(N(j(t,`package.json`)))return t;let e=A(t);if(e===t)return null;t=e}}function un(e){e.command(`info`).description(`Print system and framework info`).action(()=>{let e=[``,` KickJS CLI v${on()}`,``,` System:`,` OS: ${dt()} ${ft()} (${ut()})`,` Node: ${process.version}`],t=ln(process.cwd()),n=t?cn(t):[];if(!t)e.push(``,` Packages: (not inside a project — no package.json found)`);else if(n.length===0)e.push(``,` Packages: (no @forinda/kickjs* dependencies in ${t})`);else{e.push(``,` Packages:`);let t=Math.max(...n.map(e=>e.name.length));for(let r of n){let n=r.installed??`${r.declared??`?`} (declared — not installed)`,i=r.deprecated?" [DEPRECATED — see `kick add --list --all`]":``;e.push(` ${r.name.padEnd(t+2)} ${n}${i}`)}}e.push(``),console.log(e.join(`
358
358
  `))})}const{bold:W,dim:G,green:dn,red:K,yellow:fn,blue:pn}=p;function mn(e){let t=Math.floor(e/86400),n=Math.floor(e%86400/3600),r=Math.floor(e%3600/60),i=e%60,a=[];return t&&a.push(`${t}d`),n&&a.push(`${n}h`),r&&a.push(`${r}m`),a.push(`${i}s`),a.join(` `)}async function hn(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function q(e,t){try{return await hn(`${e}${t}`)}catch{return null}}async function gn(e){let[t,n,r,i,a]=await Promise.all([q(e,`/health`),q(e,`/metrics`),q(e,`/routes`),q(e,`/container`),q(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function _n(e,t){let{health:n,metrics:r,routes:i,container:a,ws:o}=t,c=G(`─`.repeat(60));if(console.log(),console.log(W(` KickJS Inspector`)+G(` → ${e}`)),console.log(c),n){let e=n.status===`healthy`?dn(`● healthy`):K(`● `+n.status);console.log(` ${W(`Health:`)} ${e}`)}else console.log(` ${W(`Health:`)} ${K(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?K:r.errorRate>0?fn:dn;console.log(` ${W(`Uptime:`)} ${mn(r.uptimeSeconds)}`),console.log(` ${W(`Requests:`)} ${r.requests}`),console.log(` ${W(`Errors:`)} ${r.serverErrors} server, ${r.clientErrors??0} client ${G(`(`)}${t(e+`%`)}${G(`)`)}`)}if(a&&console.log(` ${W(`DI:`)} ${a.count} bindings`),o&&o.enabled&&console.log(` ${W(`WS:`)} ${o.connections??0} connections, ${o.namespaces??0} namespaces`),i?.routes?.length){console.log(),console.log(W(` Routes`)),console.log(c),console.log(` ${G(`METHOD`)} ${G(`PATH`.padEnd(36))} ${G(`CONTROLLER`)}`);for(let e of i.routes){let t=e.path.length>36?e.path.slice(0,33)+`...`:e.path.padEnd(36);console.log(` ${s(e.method)} ${t} ${pn(e.controller)}.${G(e.handler)}`)}}console.log(c),console.log()}function vn(e){e.command(`inspect [url]`).description(`Connect to a running KickJS app and display debug info`).option(`-p, --port <port>`,`Override port`).option(`-w, --watch`,`Poll every 5 seconds`).option(`-j, --json`,`Output raw JSON`).action(async(e,t)=>{let n=e??`http://localhost:3000`;if(t.port)try{let e=new URL(n);e.port=t.port,n=e.origin}catch{n=`http://localhost:${t.port}`}let r=`${n.replace(/\/$/,``)}/_debug`,i=async()=>{try{let e=await gn(r);t.json?console.log(JSON.stringify(e,null,2)):_n(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(K(` ✖ Could not connect to ${n}`)),console.error(G(` ${e instanceof Error?e.message:String(e)}`))),t.watch||(process.exitCode=1)}};if(t.watch){let e=async()=>{process.stdout.write(`\x1B[2J\x1B[H`),await i()};await e(),setInterval(e,5e3)}else await i()})}function yn(e,t){let n=e.toLowerCase();return t.every(e=>n.includes(e.toLowerCase()))}function J(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}const bn=[{match(e,t){let n=yn(e,[`config`,`get`])&&J(e,[`undefined`,`null`]),r=e.includes(`@Value`)&&J(e,[`undefined`,`is not defined`]);return!n&&!r?null:J(e,[`vitest`,`createTestApp`,`__tests__`,`.test.`,`.spec.`])?{confidence:85,diagnosis:{id:`env-schema-not-registered-in-test`,title:`ConfigService.get() returns undefined inside a test`,explanation:`The env schema is registered by a module-load side effect in
359
359
  src/config/index.ts, and src/index.ts imports it before bootstrap().
@@ -362,11 +362,11 @@ directly — so that import does not run and ConfigService falls back to
362
362
  the base schema. @Value() still reads through to process.env, so the
363
363
  app and its tests disagree and only the tests are wrong.`,fix:`Import the side-effect module in the test file itself:`,codeBefore:`import { createTestApp } from '@forinda/kickjs-testing'
364
364
 
365
- const { expressApp } = await createTestApp({ modules: [UserModule] })
365
+ const { app } = await createTestApp({ modules: [UserModule] })
366
366
  `,codeAfter:`import { createTestApp } from '@forinda/kickjs-testing'
367
367
  import '@/config' // ← registers the env schema, as src/index.ts does
368
368
 
369
- const { expressApp } = await createTestApp({ modules: [UserModule] })
369
+ const { app } = await createTestApp({ modules: [UserModule] })
370
370
  `,docs:`https://kickjs.app/guide/configuration.html#wiring-the-schema-at-startup`}}:{confidence:n&&r?90:75,diagnosis:{id:`env-schema-not-registered`,title:`ConfigService.get() returns undefined for user-defined keys`,explanation:`Your src/index.ts is missing \`import "./config"\`. That side-effect import
371
371
  registers the env schema with kickjs at module-load time. Without it,
372
372
  ConfigService falls back to the base schema (PORT/NODE_ENV/LOG_LEVEL only)
@@ -511,7 +511,7 @@ Pass a message as a positional arg, --message flag, or pipe via stdin:
511
511
 
512
512
  `)}function Y(e,t){return e.split(`
513
513
  `).map(e=>`${t}${e}`).join(`
514
- `)}function X(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function In(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function Ln(e){let t=e.command(`mcp`).description(`Model Context Protocol commands (start | init)`);t.command(`start`,{isDefault:!0}).description(`Run the built application as an MCP server over stdio`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`--node-arg <arg...>`,`Extra arguments to pass to node`).action(Rn),t.command(`init`).description(`Generate .mcp.json for Claude Code / Cursor / Zed`).option(`-n, --name <name>`,`Server name (defaults to package.json name)`).option(`-o, --out <file>`,`Output file`,`.mcp.json`).option(`-f, --force`,`Overwrite an existing entry without prompting`).option(`--global`,`Write to ~/.mcp.json instead of the project root`).action(zn)}function Rn(e){let t=M(e.entry);N(t)||(process.stderr.write(`Error: entry file not found: ${t}\n\nBuild the app first with \`kick build\`, or pass a custom entry:\n kick mcp -e dist/server.js\n`),process.exit(1));let n=[...e.nodeArg??[],t],r=st(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});r.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),r.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let i=e=>{r.killed||r.kill(e)};process.on(`SIGINT`,()=>i(`SIGINT`)),process.on(`SIGTERM`,()=>i(`SIGTERM`))}function zn(e){let t=process.cwd(),n=Bn(t)??Je(t),r=e.name??n,i=e.global?M(process.env.HOME??`.`,`.mcp.json`):M(t,e.out),a={command:`kick`,args:[`mcp`],cwd:t},o={mcpServers:{}};if(N(i))try{let e=P(i,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(o={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${i} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}o.mcpServers[r]&&!e.force&&(process.stderr.write(`Error: an entry for "${r}" already exists in ${i}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),o.mcpServers[r]=a,tt(i,JSON.stringify(o,null,2)+`
514
+ `)}function X(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function In(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function Ln(e){let t=e.command(`mcp`).description(`Model Context Protocol commands (start | init)`);t.command(`start`,{isDefault:!0}).description(`Run the built application as an MCP server over stdio`).option(`-e, --entry <file>`,`Entry file`,`dist/index.js`).option(`--node-arg <arg...>`,`Extra arguments to pass to node`).action(Rn),t.command(`init`).description(`Generate .mcp.json for Claude Code / Cursor / Zed`).option(`-n, --name <name>`,`Server name (defaults to package.json name)`).option(`-o, --out <file>`,`Output file`,`.mcp.json`).option(`-f, --force`,`Overwrite an existing entry without prompting`).option(`--global`,`Write to ~/.mcp.json instead of the project root`).action(zn)}function Rn(e){let t=M(e.entry);N(t)||(process.stderr.write(`Error: entry file not found: ${t}\n\nBuild the app first with \`kick build\`, or pass a custom entry:\n kick mcp -e dist/server.js\n`),process.exit(1));let n=[...e.nodeArg??[],t],r=st(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});r.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),r.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let i=e=>{r.killed||r.kill(e)};process.on(`SIGINT`,()=>i(`SIGINT`)),process.on(`SIGTERM`,()=>i(`SIGTERM`))}function zn(e){let t=process.cwd(),n=Bn(t)??k(t),r=e.name??n,i=e.global?M(process.env.HOME??`.`,`.mcp.json`):M(t,e.out),a={command:`kick`,args:[`mcp`],cwd:t},o={mcpServers:{}};if(N(i))try{let e=P(i,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(o={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${i} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}o.mcpServers[r]&&!e.force&&(process.stderr.write(`Error: an entry for "${r}" already exists in ${i}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),o.mcpServers[r]=a,et(i,JSON.stringify(o,null,2)+`
515
515
  `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${r}" to ${i}\n\n To activate it:\n 1. Build your app: kick build\n 2. Restart your MCP client (Claude Code, Cursor, Zed)\n 3. The server should appear in the client's tool picker\n\n`)}function Bn(e){let t=M(e,`package.json`);if(!N(t))return null;try{let e=P(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function Vn(e){e.command(`tinker`).description(`Interactive REPL with DI container and services loaded`).option(`-e, --entry <file>`,`Entry file to load`,`src/index.ts`).action(async e=>{let t=process.cwd(),n=M(t,e.entry);N(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let r=Un(t,`tsx`);r||(console.error(`
516
516
  Error: tsx not found. Install it: pnpm add -D tsx
517
517
  `),process.exit(1));let i=Hn(n,e.entry),a=j(t,`.kick-tinker.mjs`),{writeFileSync:o,unlinkSync:s}=await import(`node:fs`);o(a,i,`utf-8`);try{let e=ot(a,[],{cwd:t,execPath:r,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{s(a)}catch{}}})}function Hn(e,t){return`
@@ -539,7 +539,7 @@ try {
539
539
 
540
540
  // Load entry to trigger decorator registration
541
541
  try {
542
- await import('${R(e).href}')
542
+ await import('${L(e).href}')
543
543
  } catch (err) {
544
544
  console.warn(' Warning: ' + err.message)
545
545
  console.warn(' Container may be partially initialized.\\n')
@@ -568,19 +568,19 @@ server.on('exit', () => {
568
568
  console.log('\\n Goodbye!\\n')
569
569
  process.exit(0)
570
570
  })
571
- `}function Un(e,t){let n=e;for(;;){let e=j(n,`node_modules`,`.bin`,t);if(N(e))return e;let r=M(n,`..`);if(r===n)break;n=r}return null}function Wn(e,t){let n=RegExp(`^\\s*${w(t)}Module\\b`),r=!1,i=0,a=e;for(;;){let e=a.indexOf(`.mount(`,i);if(e===-1)break;let t=e+7,o=1,s=t;for(;s<a.length&&o>0;){let e=a.slice(s,s+2);if(e===`//`||e===`/*`){if(e===`//`)for(s+=2;s<a.length&&a[s]!==`
571
+ `}function Un(e,t){let n=e;for(;;){let e=j(n,`node_modules`,`.bin`,t);if(N(e))return e;let r=M(n,`..`);if(r===n)break;n=r}return null}function Wn(e,t){let n=RegExp(`^\\s*${S(t)}Module\\b`),r=!1,i=0,a=e;for(;;){let e=a.indexOf(`.mount(`,i);if(e===-1)break;let t=e+7,o=1,s=t;for(;s<a.length&&o>0;){let e=a.slice(s,s+2);if(e===`//`||e===`/*`){if(e===`//`)for(s+=2;s<a.length&&a[s]!==`
572
572
  `;)s++;else{for(s+=2;s+1<a.length&&(a[s]!==`*`||a[s+1]!==`/`);)s++;s+=2}continue}let t=a[s]??``;if(t===`'`||t===`"`||t==="`"){let e=t;for(s++;s<a.length&&a[s]!==e;)a[s]===`\\`&&s++,s++}else if(t===`(`)o++;else if(t===`)`&&(o--,o===0))break;s++}if(o!==0)break;let c=a.slice(t,s);if(n.test(c)){let t=e;for(;t>0&&(a[t-1]===` `||a[t-1]===` `||a[t-1]===`
573
- `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function Gn(e,t){let n=ve(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=Wn(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${w(t)}Module\\b(?:\\s*\\(\\s*\\))?\\s*,?`,`g`),e=>{let t=e.trimStart().startsWith(`,`),n=e.trimEnd().endsWith(`,`);return t&&n?`,`:``}),a=a.replace(/,(\s*])/,`$1`),e.slice(0,r)+a+e.slice(i)}async function Kn(e){let{name:t,modulesDir:r,force:i}=e,a=e.pluralize!==!1,o=v(t),s=y(t),c=a?b(o):o,l=j(r,c);if(!await n(l)){console.log(`\n Module not found: ${l}\n`);return}if(!i&&!await f({message:p.red(`Delete module '${c}' at ${l}? This cannot be undone.`),initialValue:!1})){console.log(`
573
+ `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function Gn(e,t){let n=ve(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=Wn(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${S(t)}Module\\b(?:\\s*\\(\\s*\\))?\\s*,?`,`g`),e=>{let t=e.trimStart().startsWith(`,`),n=e.trimEnd().endsWith(`,`);return t&&n?`,`:``}),a=a.replace(/,(\s*])/,`$1`),e.slice(0,r)+a+e.slice(i)}async function Kn(e){let{name:t,modulesDir:r,force:i}=e,a=e.pluralize!==!1,o=y(t),s=b(t),c=a?m(o):o,l=j(r,c);if(!await n(l)){console.log(`\n Module not found: ${l}\n`);return}if(!i&&!await f({message:p.red(`Delete module '${c}' at ${l}? This cannot be undone.`),initialValue:!1})){console.log(`
574
574
  Cancelled.
575
- `);return}await it(l,{recursive:!0,force:!0}),console.log(` Deleted: ${l}`);let u=j(r,`index.ts`);if(await n(u)){let e=await I(u,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${w(s)}Module\\s*\\}\\s*from\\s*['"][^'"]*${w(c)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=Gn(e,s),e=e.replace(/\n{3,}/g,`
575
+ `);return}await it(l,{recursive:!0,force:!0}),console.log(` Deleted: ${l}`);let u=j(r,`index.ts`);if(await n(u)){let e=await F(u,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${S(s)}Module\\s*\\}\\s*from\\s*['"][^'"]*${S(c)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=Gn(e,s),e=e.replace(/\n{3,}/g,`
576
576
 
577
- `),e!==t&&(await L(u,e,`utf-8`),console.log(` Unregistered: ${s}Module from ${u}`))}console.log(`\n Module '${c}' removed.\n`)}function qn(e){e.command(`remove`).alias(`rm`).description(`Remove generated code`).command(`module <names...>`).description(`Remove one or more modules (e.g. kick rm module user task)`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular module name`).option(`-f, --force`,`Skip confirmation prompt`).action(async(e,t)=>{let n=E(await T(process.cwd())),r=t.modulesDir??n.dir??`src/modules`,i=t.pluralize===!1?!1:n.pluralize??!0;for(let n of e)await Kn({name:n,modulesDir:M(r),force:t.force,pluralize:i})})}function Jn(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;if(e===`kickjs-schema`||e===`schema`)return`kickjs-schema`;console.warn(` kick typegen: unknown --schema-validator '${e}' (supported: 'zod', 'kickjs-schema', 'false'). Falling back to project config.`)}}function Yn(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function Xn(e){e.command(`typegen`).description(`Generate type-safe DI registry and module types into .kickjs/types/`).option(`-w, --watch`,`Watch source files and regenerate on change`).option(`-s, --src <dir>`,`Source directory to scan`,`src`).option(`-o, --out <dir>`,`Output directory`,`.kickjs/types`).option(`--silent`,`Suppress output`).option(`--allow-duplicates`,`Auto-namespace duplicate class names instead of failing (use with caution)`).option(`--schema-validator <name>`,`Schema validator for body/query/params typing (currently 'zod' or 'false')`).option(`--env-file <path>`,`Path to env schema file for KickEnv typing (default 'src/env.ts'; pass 'false' to disable)`).option(`--check`,`CI gate: exit non-zero if any generated file in .kickjs/types/ is out of date (routes, env, db, assets, adopter plugins) instead of writing it`).option(`--fix`,`Patch module import.meta.glob() calls to cover decorated classes that aren't loaded by any glob (orphans)`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").option(`--no-cache`,`Disable the persistent scan cache; re-read + re-extract every file from cold`).action(async e=>{let t=D(process.cwd()),n=await T(t);if(e.list){let{mergeCliPlugins:e}=await import(`./plugin-_eznyEJd.mjs`).then(e=>e.t),{builtinCliPlugins:t}=await import(`./builtins-BJ1fZBKi.mjs`),r=e([...t,...n?.plugins??[]],n?.commands??[]),i=new Set(n?.typegen?.disable??[]);if(r.typegens.length===0){console.log(` No typegen plugins registered.`);return}let a=Math.max(...r.typegens.map(e=>e.id.length));console.log(`
577
+ `),e!==t&&(await I(u,e,`utf-8`),console.log(` Unregistered: ${s}Module from ${u}`))}console.log(`\n Module '${c}' removed.\n`)}function qn(e){e.command(`remove`).alias(`rm`).description(`Remove generated code`).command(`module <names...>`).description(`Remove one or more modules (e.g. kick rm module user task)`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular module name`).option(`-f, --force`,`Skip confirmation prompt`).action(async(e,t)=>{let n=w(await C(process.cwd())),r=t.modulesDir??n.dir??`src/modules`,i=t.pluralize===!1?!1:n.pluralize??!0;for(let n of e)await Kn({name:n,modulesDir:M(r),force:t.force,pluralize:i})})}function Jn(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;if(e===`kickjs-schema`||e===`schema`)return`kickjs-schema`;console.warn(` kick typegen: unknown --schema-validator '${e}' (supported: 'zod', 'kickjs-schema', 'false'). Falling back to project config.`)}}function Yn(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function Xn(e){e.command(`typegen`).description(`Generate type-safe DI registry and module types into .kickjs/types/`).option(`-w, --watch`,`Watch source files and regenerate on change`).option(`-s, --src <dir>`,`Source directory to scan`,`src`).option(`-o, --out <dir>`,`Output directory`,`.kickjs/types`).option(`--silent`,`Suppress output`).option(`--allow-duplicates`,`Auto-namespace duplicate class names instead of failing (use with caution)`).option(`--schema-validator <name>`,`Schema validator for body/query/params typing (currently 'zod' or 'false')`).option(`--env-file <path>`,`Path to env schema file for KickEnv typing (default 'src/env.ts'; pass 'false' to disable)`).option(`--check`,`CI gate: exit non-zero if any generated file in .kickjs/types/ is out of date (routes, env, db, assets, adopter plugins) instead of writing it`).option(`--fix`,`Patch module import.meta.glob() calls to cover decorated classes that aren't loaded by any glob (orphans)`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").option(`--no-cache`,`Disable the persistent scan cache; re-read + re-extract every file from cold`).action(async e=>{let t=T(process.cwd()),n=await C(t);if(e.list){let{mergeCliPlugins:e}=await import(`./plugin-C5HNkLuq.mjs`).then(e=>e.t),{builtinCliPlugins:t}=await import(`./builtins-BZ-nFDRJ.mjs`),r=e([...t,...n?.plugins??[]],n?.commands??[]),i=new Set(n?.typegen?.disable??[]);if(r.typegens.length===0){console.log(` No typegen plugins registered.`);return}let a=Math.max(...r.typegens.map(e=>e.id.length));console.log(`
578
578
  Registered typegen plugins:
579
- `);for(let e of r.typegens){let t=i.has(e.id)?` (disabled)`:``;console.log(` ${e.id.padEnd(a+2)}inputs: ${e.inputs.join(`, `)||`(none)`}${t}`)}console.log();return}let r=Jn(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=Yn(e.envFile)??n?.typegen?.envFile,a={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,fix:e.fix,allowDuplicates:e.allowDuplicates,noCache:e.cache===!1,schemaValidator:r,envFile:i,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await Ue(a);e.silent||console.log(` kick typegen: watching for changes (Ctrl-C to exit)`);let n=()=>{t(),process.exit(0)};process.on(`SIGINT`,n),process.on(`SIGTERM`,n),await new Promise(()=>{})}else{await Ge(a);let r=await Zt({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&r.some(e=>e.status===`written`)&&process.exit(1),e.check||await Re(M(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r,e.silent??!1)}}catch(e){e instanceof We?console.error(`
579
+ `);for(let e of r.typegens){let t=i.has(e.id)?` (disabled)`:``;console.log(` ${e.id.padEnd(a+2)}inputs: ${e.inputs.join(`, `)||`(none)`}${t}`)}console.log();return}let r=Jn(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=Yn(e.envFile)??n?.typegen?.envFile,a={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,fix:e.fix,allowDuplicates:e.allowDuplicates,noCache:e.cache===!1,schemaValidator:r,envFile:i,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await We(a);e.silent||console.log(` kick typegen: watching for changes (Ctrl-C to exit)`);let n=()=>{t(),process.exit(0)};process.on(`SIGINT`,n),process.on(`SIGTERM`,n),await new Promise(()=>{})}else{await D(a);let r=await U({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&r.some(e=>e.status===`written`)&&process.exit(1),e.check||await ze(M(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r,e.silent??!1)}}catch(e){e instanceof Ge?console.error(`
580
580
  `+e.message+`
581
581
  `):e instanceof he?console.error(`
582
582
  `+e.message+`
583
- `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Zn(e){let t=[];if(!N(e))return t;let n=$e(e,{withFileTypes:!0});for(let r of n){let n=j(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Zn(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Qn(e){try{return P(e,`utf-8`)}catch{return``}}const $n=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function er(e,t){let n=Qn(j(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if($n.has(t.toLowerCase())||t.length<32)return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value or too short (< 32 chars) — change it`}}}for(let e of t)for(let t of[/JWT_SECRET['"]?\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i,/secret\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i])if(t.test(e))return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value in source code — use an environment variable`};return null}function tr(e){for(let t of e)if(/cors\s*\(/.test(t)&&/origin\s*:\s*['"]\*['"]/.test(t))return{severity:`CRITICAL`,message:`CORS origin is '*' — restrict to your domains`};return null}function nr(e){for(let t of e)if(/rateLimit/i.test(t)||/@RateLimit/i.test(t))return null;return{severity:`WARNING`,message:`No rate limiting detected — add rateLimit() middleware or @RateLimit decorator`}}function rr(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function ir(e){let t=!1,n=!1;for(let r of e)/tokenStore/i.test(r)&&(t=!0),/MemoryTokenStore/i.test(r)&&(n=!0);return n?{severity:`WARNING`,message:`MemoryTokenStore detected — use a persistent store (Redis, DB) for production deployments`}:t?null:{severity:`WARNING`,message:`No token revocation store detected — consider adding one for auth token management`}}function ar(e){for(let t of e)if(/helmet\s*\(/.test(t))return/security\s*\.\s*helmet\s*.*false/.test(t)?{severity:`WARNING`,message:`Helmet security headers are disabled — enable them for production`}:{severity:`INFO`,message:`Helmet security headers active`};return{severity:`WARNING`,message:`Helmet not detected — add helmet() middleware for security headers`}}function or(e){for(let t of e)if(/AuthAdapter/i.test(t))return{severity:`INFO`,message:`AuthAdapter configured`};return{severity:`INFO`,message:`No AuthAdapter detected — add one if your app requires authentication`}}function sr(e){let t=Zn(j(e,`src`)).map(e=>Qn(e)),n=[],r=er(e,t);r&&n.push(r);let i=tr(t);i&&n.push(i);let a=nr(t);a&&n.push(a);let o=rr();o&&n.push(o);let s=ir(t);return s&&n.push(s),n.push(ar(t)),n.push(or(t)),n}function cr(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
583
+ `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Zn(e){let t=[];if(!N(e))return t;let n=Qe(e,{withFileTypes:!0});for(let r of n){let n=j(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Zn(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Qn(e){try{return P(e,`utf-8`)}catch{return``}}const $n=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function er(e,t){let n=Qn(j(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if($n.has(t.toLowerCase())||t.length<32)return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value or too short (< 32 chars) — change it`}}}for(let e of t)for(let t of[/JWT_SECRET['"]?\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i,/secret\s*[:=]\s*['"]?(secret|changeme|password|test|default)['"]?/i])if(t.test(e))return{severity:`CRITICAL`,message:`JWT_SECRET appears to be a default value in source code — use an environment variable`};return null}function tr(e){for(let t of e)if(/cors\s*\(/.test(t)&&/origin\s*:\s*['"]\*['"]/.test(t))return{severity:`CRITICAL`,message:`CORS origin is '*' — restrict to your domains`};return null}function nr(e){for(let t of e)if(/rateLimit/i.test(t)||/@RateLimit/i.test(t))return null;return{severity:`WARNING`,message:`No rate limiting detected — add rateLimit() middleware or @RateLimit decorator`}}function rr(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function ir(e){let t=!1,n=!1;for(let r of e)/tokenStore/i.test(r)&&(t=!0),/MemoryTokenStore/i.test(r)&&(n=!0);return n?{severity:`WARNING`,message:`MemoryTokenStore detected — use a persistent store (Redis, DB) for production deployments`}:t?null:{severity:`WARNING`,message:`No token revocation store detected — consider adding one for auth token management`}}function ar(e){for(let t of e)if(/helmet\s*\(/.test(t))return/security\s*\.\s*helmet\s*.*false/.test(t)?{severity:`WARNING`,message:`Helmet security headers are disabled — enable them for production`}:{severity:`INFO`,message:`Helmet security headers active`};return{severity:`WARNING`,message:`Helmet not detected — add helmet() middleware for security headers`}}function or(e){for(let t of e)if(/AuthAdapter/i.test(t))return{severity:`INFO`,message:`AuthAdapter configured`};return{severity:`INFO`,message:`No AuthAdapter detected — add one if your app requires authentication`}}function sr(e){let t=Zn(j(e,`src`)).map(e=>Qn(e)),n=[],r=er(e,t);r&&n.push(r);let i=tr(t);i&&n.push(i);let a=nr(t);a&&n.push(a);let o=rr();o&&n.push(o);let s=ir(t);return s&&n.push(s),n.push(ar(t)),n.push(or(t)),n}function cr(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
584
584
  Usage: kick check --deploy
585
585
 
586
586
  Available checks:
@@ -594,7 +594,7 @@ server.on('exit', () => {
594
594
  The regex-based rewrite handles the shapes our templates produce.
595
595
  Hand-rolled modules with non-standard structures may be skipped.
596
596
  Always commit before running with --apply.
597
- `),process.exit(1));let i=E(await T(process.cwd())),a=M(t.modulesDir??i.dir??`src/modules`),o;t.target===`define`||t.target===`class`?o=t.target:t.target===void 0?o=i.style??`define`:(console.error(`\n ${p.red(`Error:`)} --target must be 'define' or 'class' (got '${t.target}').\n`),process.exit(1));let s=p.dim(`→ ${o}`),c=r?p.dim(`(dry-run)`):p.bold(`(applying)`);console.log(`\n ${p.bold(`kick codemod modules`)} ${s} ${c}`),console.log(` modulesDir: ${p.dim(a)}\n`);let l=t.backup!==!1&&!r,u=await kt(a,{dryRun:r,target:o,backup:l});if(u.backupDir){let e=u.backupDir;console.log(` ${p.green(`✓`)} backup: ${p.dim(e)}\n ${p.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else!r&&t.backup===!1&&console.log(` ${p.dim(`(--no-backup — skipping snapshot)`)}\n`);let d=0,f=0;for(let e of u.files)if(e.status===`migrated`)d++,console.log(` ${p.green(`✓`)} ${e.path}`);else{f++;let t=p.dim(`(${e.reason??`skipped`})`);console.log(` ${p.dim(`-`)} ${e.path} ${t}`)}if(console.log(),u.indexStatus===`migrated`)console.log(` ${p.green(`✓`)} ${u.indexPath}`);else if(u.indexStatus===`skipped`){let e=p.dim(`(${u.indexReason??`skipped`})`);console.log(` ${p.dim(`-`)} ${u.indexPath} ${e}`)}else console.log(` ${p.dim(`-`)} ${u.indexPath} ${p.dim(`(not found)`)}`);let m=r?p.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${p.bold(String(d))} migrated, ${p.bold(String(f))} skipped${m}\n`)})}const dr=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!N(k.resolve(e.cwd,`kick.config.ts`)))return null;let t=await T(e.cwd);if(!t?.assetMap)return null;let n=Me(t.assetMap,e.cwd);return n.count===0?null:Ve(n)}}),fr="/* eslint-disable */\n// AUTO-GENERATED by `kick typegen`. DO NOT EDIT.\n// Re-run with `kick typegen` or rely on `kick dev` to refresh.\n";function pr(e,t,n,r={}){if(e.length===0)return`${fr}
597
+ `),process.exit(1));let i=w(await C(process.cwd())),a=M(t.modulesDir??i.dir??`src/modules`),o;t.target===`define`||t.target===`class`?o=t.target:t.target===void 0?o=i.style??`define`:(console.error(`\n ${p.red(`Error:`)} --target must be 'define' or 'class' (got '${t.target}').\n`),process.exit(1));let s=p.dim(`→ ${o}`),c=r?p.dim(`(dry-run)`):p.bold(`(applying)`);console.log(`\n ${p.bold(`kick codemod modules`)} ${s} ${c}`),console.log(` modulesDir: ${p.dim(a)}\n`);let l=t.backup!==!1&&!r,u=await kt(a,{dryRun:r,target:o,backup:l});if(u.backupDir){let e=u.backupDir;console.log(` ${p.green(`✓`)} backup: ${p.dim(e)}\n ${p.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else!r&&t.backup===!1&&console.log(` ${p.dim(`(--no-backup — skipping snapshot)`)}\n`);let d=0,f=0;for(let e of u.files)if(e.status===`migrated`)d++,console.log(` ${p.green(`✓`)} ${e.path}`);else{f++;let t=p.dim(`(${e.reason??`skipped`})`);console.log(` ${p.dim(`-`)} ${e.path} ${t}`)}if(console.log(),u.indexStatus===`migrated`)console.log(` ${p.green(`✓`)} ${u.indexPath}`);else if(u.indexStatus===`skipped`){let e=p.dim(`(${u.indexReason??`skipped`})`);console.log(` ${p.dim(`-`)} ${u.indexPath} ${e}`)}else console.log(` ${p.dim(`-`)} ${u.indexPath} ${p.dim(`(not found)`)}`);let m=r?p.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${p.bold(String(d))} migrated, ${p.bold(String(f))} skipped${m}\n`)})}const dr=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!N(O.resolve(e.cwd,`kick.config.ts`)))return null;let t=await C(e.cwd);if(!t?.assetMap)return null;let n=Ne(t.assetMap,e.cwd);return n.count===0?null:He(n)}}),fr="/* eslint-disable */\n// AUTO-GENERATED by `kick typegen`. DO NOT EDIT.\n// Re-run with `kick typegen` or rely on `kick dev` to refresh.\n";function pr(e,t,n,r={}){if(e.length===0)return`${fr}
598
598
  // (no routes discovered yet — annotate a controller method with
599
599
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
600
600
  declare global {
@@ -617,12 +617,12 @@ export const kickRpc = {} as const
617
617
  `)}\n },`)}let g=[`/**`,` * Runtime route manifest for the tRPC-style sugar:`," * `createRpc(api, kickRpc)` from @forinda/kickjs-client.",` */`,`export const kickRpc = {`,...m,`} as const`].join(`
618
618
  `),_=[],v=new Map;for(let t of e)v.set(`${t.filePath}::${t.controller}`,t);for(let[e,n]of o){let r=v.get(e),i=yr(``,r.filePath,t),a=r.controllerIsDefaultExport?`default as ${n}`:`${r.controller} as ${n}`;_.push(`import type { ${a} } from '${i}'`)}let y=_.length>0?_.join(`
619
619
  `)+`
620
- `:``,b=vr(a)+y,x=l.join(`
621
- `);return`${fr}${b}
620
+ `:``,ee=vr(a)+y,b=l.join(`
621
+ `);return`${fr}${ee}
622
622
  declare global {
623
623
  // eslint-disable-next-line @typescript-eslint/no-namespace
624
624
  namespace KickRoutes {
625
- ${x}
625
+ ${b}
626
626
  }
627
627
 
628
628
  /** Short alias for \`KickRoutes.Api\` — \`createClient<KickApi>(...)\`. */
@@ -632,15 +632,15 @@ ${x}
632
632
  ${g}
633
633
  `}function mr(e){let t=e.contextKeys;return t==null?`string`:t.length===0?`never`:t.map(e=>JSON.stringify(e)).join(` | `)}function hr(e){if(e.queryFilterable===null)return`unknown`;let t=e.querySortable??[];return`{ filter?: string | string[]; sort?: ${t.length>0?t.flatMap(e=>[`'${e}'`,`'-${e}'`]).join(` | `):`string`}; q?: string; page?: string; limit?: string }`}function gr(e){let t=[];return e.queryFilterable&&e.queryFilterable.length>0&&t.push(`Filterable: ${e.queryFilterable.join(`, `)}`),e.querySortable&&e.querySortable.length>0&&t.push(`Sortable: ${e.querySortable.join(`, `)}`),e.querySearchable&&e.querySearchable.length>0&&t.push(`Searchable: ${e.querySearchable.join(`, `)}`),t}function _r(e,t,n,r,i){if(!e||r===!1||e.source===null)return null;let a=yr(e.source,t,n);if(a===`unknown`)return null;let o=`${a}::${e.identifier}`,s=i.get(o)?.specifier;return s?s=i.get(o).specifier:(s=`_S${i.size}`,i.set(o,{identifier:e.identifier,specifier:s})),s}function vr(e){if(e.size===0)return``;let t=[];for(let[n,r]of e){let[e]=n.split(`::`);t.push(`import type { ${r.identifier} as ${r.specifier} } from '${e}'`)}return t.join(`
634
634
  `)+`
635
- `}function yr(e,t,n){if(e===null)return`unknown`;let r=A(n);if(e===``){let e=Ye(r,t).split(Xe).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=Ye(r,M(A(t),e)).split(Xe).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}function br(e){let t=e.endsWith(`Controller`)?e.slice(0,-10):e,n=t.length>0?t:e;return n.charAt(0).toLowerCase()+n.slice(1)}const xr=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:Sr(e),cwd:e.cwd,envFile:Cr(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=k.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return pr(t.routes,r,n,{onWarn:t=>e.log.warn(t)})}});function Sr(e){return k.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Cr(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}const Z=`@typescript/typescript6`;function wr(e){return typeof e?.createProgram==`function`}function Tr(e){if(wr(e.typescript))return{api:e.typescript,source:`typescript`};if(wr(e.ts6))return{api:e.ts6,source:Z};let t=`Install it in the project:\n pnpm add -D ${Z}`;throw e.typescript?Error(`kick typegen: the client route map needs a TypeScript compiler API.
636
- TypeScript 7 does not ship a compiler API, so the compatibility package is required.\n ${t}`):Error(`kick typegen: the client route map needs a TypeScript compiler API, and neither 'typescript' nor '${Z}' resolved from this project.\n ${t}`)}async function Er(e){let t=qe(j(e,`package.json`)),n=async e=>{try{return await import(R(t.resolve(e)).href)}catch{return null}},[r,i]=await Promise.all([n(`typescript`),n(Z)]);return Tr({typescript:Dr(r),ts6:Dr(i)}).api}function Dr(e){let t=e;return t?.default&&typeof t.default==`object`?t.default:e}const Or=Symbol(`kick/client: expansion budget exhausted`);var kr=class{ts;checker;program;opts;get printFlags(){return this.ts.TypeFormatFlags.NoTruncation}hoistedByType=new Map;inProgress=new Map;jsonInProgress=new Set;nextName=0;blocks=[];maxDepth;truncations=0;budget;constructor(e,t,n,r={}){this.ts=e,this.checker=t,this.program=n,this.opts=r,this.maxDepth=r.maxDepth??12,this.budget=r.truncationBudget??1e3}hoisted(){return this.blocks}expand(e){this.truncations=0;try{return this.render(e,0)}catch(e){if(e!==Or)throw e;return this.opts.onWarn?.(`expansion abandoned after ${this.budget} truncations — emitting 'unknown'. This usually means a recursive type. Declare a response schema on the route for an exact type.`),`unknown`}}render(e,t){let n=this.ts.TypeFlags;if(t>this.maxDepth){if(++this.truncations>this.budget)throw Or;return this.opts.onWarn?.(`type nesting exceeded ${this.maxDepth} levels — emitting 'unknown'. Declare a response schema on the route for an exact type.`),`unknown`}if(e.flags&(n.String|n.Number|n.Boolean|n.BigInt|n.ESSymbol)||e.flags&(n.Any|n.Unknown|n.Never|n.Void|n.Undefined|n.Null)||e.isLiteral()||e.flags&n.BooleanLiteral)return this.checker.typeToString(e,void 0,this.printFlags);if(e.isUnion()){let n=e.types.filter(e=>!this.isCallable(e));return(n.length>0?n:e.types).map(e=>this.render(e,t+1)).join(` | `)}if(e.isIntersection())return e.types.map(e=>this.render(e,t+1)).join(` & `);if(this.isTuple(e))return this.renderTuple(e,t);let r=this.arrayElement(e);if(r){let e=this.render(r.element,t+1),n=/[|&]/.test(e)?`(${e})[]`:`${e}[]`;return r.readonly?`readonly ${n}`:n}let i=this.toJsonType(e);if(i){if(this.jsonInProgress.has(e))return this.opts.onWarn?.(`'${this.checker.typeToString(e,void 0,this.printFlags)}' has a cyclic toJSON() — emitting 'unknown', since it has no serializable form.`),`unknown`;this.jsonInProgress.add(e);try{return this.render(i,t)}finally{this.jsonInProgress.delete(e)}}return this.isLibType(e)?this.renderLibType(e,t):e.flags&n.Object?this.renderObject(e,t):(this.opts.onWarn?.(`could not expand type '${this.checker.typeToString(e)}' — emitting 'unknown'`),`unknown`)}renderObject(e,t){let n=this.hoistedByType.get(e);if(n)return n;if(this.isNamed(e)){let t=this.allocName();this.hoistedByType.set(e,t);let n=this.blocks.length;return this.blocks.push(``),this.blocks[n]=`interface ${t} {\n${this.members(e,0,` `)}\n}`,t}let r=this.inProgress.get(e);if(r)return r.name??=this.allocName();let i={name:null};this.inProgress.set(e,i);let a;try{a=this.members(e,t,``,`; `)}finally{this.inProgress.delete(e)}if(i.name){this.hoistedByType.set(e,i.name);let t=this.blocks.length;return this.blocks.push(``),this.blocks[t]=`interface ${i.name} {\n${this.members(e,0,` `)}\n}`,i.name}return a.length>0?`{ ${a} }`:`{}`}allocName(){return`__T${this.nextName++}`}members(e,t,n,r=`
635
+ `}function yr(e,t,n){if(e===null)return`unknown`;let r=A(n);if(e===``){let e=Je(r,t).split(Ye).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=Je(r,M(A(t),e)).split(Ye).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}function br(e){let t=e.endsWith(`Controller`)?e.slice(0,-10):e,n=t.length>0?t:e;return n.charAt(0).toLowerCase()+n.slice(1)}const xr=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:Sr(e),cwd:e.cwd,envFile:Cr(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=O.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return pr(t.routes,r,n,{onWarn:t=>e.log.warn(t)})}});function Sr(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Cr(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}const Z=`@typescript/typescript6`;function wr(e){return typeof e?.createProgram==`function`}function Tr(e){if(wr(e.typescript))return{api:e.typescript,source:`typescript`};if(wr(e.ts6))return{api:e.ts6,source:Z};let t=`Install it in the project:\n pnpm add -D ${Z}`;throw e.typescript?Error(`kick typegen: the client route map needs a TypeScript compiler API.
636
+ TypeScript 7 does not ship a compiler API, so the compatibility package is required.\n ${t}`):Error(`kick typegen: the client route map needs a TypeScript compiler API, and neither 'typescript' nor '${Z}' resolved from this project.\n ${t}`)}async function Er(e){let t=qe(j(e,`package.json`)),n=async e=>{try{return await import(L(t.resolve(e)).href)}catch{return null}},[r,i]=await Promise.all([n(`typescript`),n(Z)]);return Tr({typescript:Dr(r),ts6:Dr(i)}).api}function Dr(e){let t=e;return t?.default&&typeof t.default==`object`?t.default:e}const Or=Symbol(`kick/client: expansion budget exhausted`);var kr=class{ts;checker;program;opts;get printFlags(){return this.ts.TypeFormatFlags.NoTruncation}hoistedByType=new Map;inProgress=new Map;jsonInProgress=new Set;nextName=0;blocks=[];maxDepth;truncations=0;budget;constructor(e,t,n,r={}){this.ts=e,this.checker=t,this.program=n,this.opts=r,this.maxDepth=r.maxDepth??12,this.budget=r.truncationBudget??1e3}hoisted(){return this.blocks}expand(e){this.truncations=0;try{return this.render(e,0)}catch(e){if(e!==Or)throw e;return this.opts.onWarn?.(`expansion abandoned after ${this.budget} truncations — emitting 'unknown'. This usually means a recursive type. Declare a response schema on the route for an exact type.`),`unknown`}}render(e,t){let n=this.ts.TypeFlags;if(t>this.maxDepth){if(++this.truncations>this.budget)throw Or;return this.opts.onWarn?.(`type nesting exceeded ${this.maxDepth} levels — emitting 'unknown'. Declare a response schema on the route for an exact type.`),`unknown`}if(e.flags&(n.String|n.Number|n.Boolean|n.BigInt|n.ESSymbol)||e.flags&(n.Any|n.Unknown|n.Never|n.Void|n.Undefined|n.Null)||e.isLiteral()||e.flags&n.BooleanLiteral)return this.checker.typeToString(e,void 0,this.printFlags);if(e.isUnion()){let n=e.types.filter(e=>!this.isCallable(e));return(n.length>0?n:e.types).map(e=>this.render(e,t+1)).join(` | `)}if(e.isIntersection())return e.types.map(e=>this.render(e,t+1)).join(` & `);if(this.isTuple(e))return this.renderTuple(e,t);let r=this.arrayElement(e);if(r){let e=this.render(r.element,t+1),n=/[|&]/.test(e)?`(${e})[]`:`${e}[]`;return r.readonly?`readonly ${n}`:n}let i=this.toJsonType(e);if(i){if(this.jsonInProgress.has(e))return this.opts.onWarn?.(`'${this.checker.typeToString(e,void 0,this.printFlags)}' has a cyclic toJSON() — emitting 'unknown', since it has no serializable form.`),`unknown`;this.jsonInProgress.add(e);try{return this.render(i,t)}finally{this.jsonInProgress.delete(e)}}return this.isLibType(e)?this.renderLibType(e,t):e.flags&n.Object?this.renderObject(e,t):(this.opts.onWarn?.(`could not expand type '${this.checker.typeToString(e)}' — emitting 'unknown'`),`unknown`)}renderObject(e,t){let n=this.hoistedByType.get(e);if(n)return n;if(this.isNamed(e)){let t=this.allocName();this.hoistedByType.set(e,t);let n=this.blocks.length;return this.blocks.push(``),this.blocks[n]=`interface ${t} {\n${this.members(e,0,` `)}\n}`,t}let r=this.inProgress.get(e);if(r)return r.name??=this.allocName();let i={name:null};this.inProgress.set(e,i);let a;try{a=this.members(e,t,``,`; `)}finally{this.inProgress.delete(e)}if(i.name){this.hoistedByType.set(e,i.name);let t=this.blocks.length;return this.blocks.push(``),this.blocks[t]=`interface ${i.name} {\n${this.members(e,0,` `)}\n}`,i.name}return a.length>0?`{ ${a} }`:`{}`}allocName(){return`__T${this.nextName++}`}members(e,t,n,r=`
637
637
  `){let i=[];for(let r of this.checker.getIndexInfosOfType(e)){let e=this.checker.typeToString(r.keyType,void 0,this.printFlags);i.push(`${n}[key: ${e}]: ${this.render(r.type,t+1)}`)}for(let r of this.checker.getPropertiesOfType(e)){let e=this.typeOfProperty(r);if(this.isCallable(e)||r.getName().startsWith(`__@`))continue;let a=(r.flags&this.ts.SymbolFlags.Optional)!==0,o=this.renderPropertyType(e,a,r,t+1),s=this.isReadonlyProp(r)?`readonly `:``;i.push(`${n}${s}${this.propName(r.getName())}${a?`?`:``}: ${o}`)}return i.join(r===`
638
638
  `?`
639
639
  `:r)}typeOfProperty(e){let t=this.checker;if(typeof t.getTypeOfSymbol==`function`)return t.getTypeOfSymbol(e);let n=e.valueDeclaration??e.declarations?.[0];return n?this.checker.getTypeOfSymbolAtLocation(e,n):this.checker.getDeclaredTypeOfSymbol(e)}renderPropertyType(e,t,n,r){if(!t||!e.isUnion()||this.declaresUndefined(n))return this.render(e,r);let i=e.types.filter(e=>!(e.flags&this.ts.TypeFlags.Undefined));return i.length===0?`undefined`:i.map(e=>this.render(e,r)).join(` | `)}isReadonlyProp(e){let t=e.valueDeclaration??e.declarations?.[0];return t?(this.ts.getCombinedModifierFlags(t)&this.ts.ModifierFlags.Readonly)!==0:!1}declaresUndefined(e){let t=e.valueDeclaration??e.declarations?.[0];if(!t||!(this.ts.isPropertySignature(t)||this.ts.isPropertyDeclaration(t))||!t.type)return!1;let n=this.checker.getTypeFromTypeNode(t.type);return(n.isUnion()?n.types:[n]).some(e=>(e.flags&this.ts.TypeFlags.Undefined)!==0)}renderTuple(e,t){let n=this.ts.ElementFlags,r=this.checker.getTypeArguments(e),i=e.target,a=i.elementFlags??[],o=r.map((e,r)=>{let i=a[r]??n.Required;return i&n.Optional?`${(e.isUnion()?e.types.filter(e=>!(e.flags&this.ts.TypeFlags.Undefined)):[e]).map(e=>this.render(e,t+1)).join(` | `)}?`:i&n.Rest?`...${this.render(e,t+1)}[]`:i&n.Variadic?`...${this.render(e,t+1)}`:this.render(e,t+1)});return`${i.readonly?`readonly `:``}[${o.join(`, `)}]`}propName(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}isLibType(e){let t=e.aliasSymbol?.declarations??e.getSymbol()?.declarations;return!t||t.length===0?!1:t.every(e=>this.program.isSourceFileDefaultLibrary(e.getSourceFile()))}renderLibType(e,t){let n=(e.aliasSymbol??e.getSymbol())?.getName(),r=e.aliasTypeArguments??this.typeArguments(e);return!n||r.length===0?this.checker.typeToString(e,void 0,this.printFlags):`${n}<${r.map(e=>this.render(e,t+1)).join(`, `)}>`}typeArguments(e){return!(e.flags&this.ts.TypeFlags.Object)||!(e.objectFlags&this.ts.ObjectFlags.Reference)?[]:this.checker.getTypeArguments(e)}toJsonType(e){if(!(e.flags&this.ts.TypeFlags.Object))return null;let t=this.checker.getPropertyOfType(e,`toJSON`);if(!t)return null;let[n]=this.checker.getSignaturesOfType(this.typeOfProperty(t),this.ts.SignatureKind.Call);if(!n)return null;let r=this.checker.getReturnTypeOfSignature(n);return r===e?null:r}isCallable(e){if(e.isUnion()){let t=e.types.filter(e=>!(e.flags&(this.ts.TypeFlags.Undefined|this.ts.TypeFlags.Null)));return t.length>0&&t.every(e=>this.isCallable(e))}return this.checker.getSignaturesOfType(e,this.ts.SignatureKind.Call).length>0||this.checker.getSignaturesOfType(e,this.ts.SignatureKind.Construct).length>0}isNamed(e){let t=e.getSymbol();if(!t)return!1;let n=t.getName();return n!==`__type`&&n!==`__object`&&n.length>0}isTuple(e){let t=this.ts.ObjectFlags;if(!(e.flags&this.ts.TypeFlags.Object)||!(e.objectFlags&t.Reference))return!1;let n=e.target;return!!(n&&n.objectFlags&t.Tuple)}arrayElement(e){let t=e.getSymbol()?.getName();if(t!==`Array`&&t!==`ReadonlyArray`)return null;let n=this.checker.getTypeArguments(e);return n.length===1?{element:n[0],readonly:t===`ReadonlyArray`}:null}};const Ar=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`,`bun.lockb`],jr=/(?:^|[\\/])(?:node_modules|\.kickjs)(?:[\\/]|$)/;function Mr(e){return pt(`sha1`).update(e).digest(`hex`)}function Nr(e){let t=pt(`sha1`);t.update(e.cliVersion),t.update(JSON.stringify(e.options??{})),t.update(e.keys.join(`
640
640
  `));for(let n of Ar){let r=j(e.projectDir,n);if(N(r))try{t.update(P(r))}catch(e){throw Error(`kick/client: cannot read lockfile ${r}`,{cause:e})}}for(let n of e.fileNames.toSorted())if(!jr.test(n)){t.update(n);try{t.update(P(n))}catch(e){throw Error(`kick/client: cannot read project file ${n}`,{cause:e})}}return t.digest(`hex`)}async function Pr(e){try{let t=await Er(e.compilerFrom??e.projectDir),n={...t.sys,onUnRecoverableConfigFileDiagnostic:()=>{}},r=t.getParsedCommandLineOfConfigFile(j(e.projectDir,`tsconfig.json`),{},n);return r?Nr({projectDir:e.projectDir,fileNames:r.fileNames,keys:e.keys,options:{...r.options,__kickMaxDepth:e.maxDepth??null},cliVersion:e.cliVersion}):null}catch{return null}}async function Fr(e){let t=await Er(e.compilerFrom??e.projectDir),n=j(A(e.routesFile),`__kick_client_probe__.ts`),r=Rr(e.routesFile,e.keys),i=Vr(t,e.projectDir,n,r),a=i.getTypeChecker(),o=i.getSourceFile(n);if(!o)throw Error(`kick/client: could not add the resolution probe to the program. Check that ${e.routesFile} exists — run \`kick typegen\` first.`);Ir(t,i,e.routesFile);let s=zr(t,i,o,e.keys),c=null,l=new kr(t,a,i,{maxDepth:e.maxDepth,onWarn:t=>e.onWarn?.(c?`route '${c}': ${t}`:t)}),u=new Map;for(let[n,r]of e.keys.entries()){if(s.has(r)){e.onWarn?.(`route '${r}' is not present in KickRoutes.Api — skipped. Re-run \`kick typegen\` so the two maps agree.`);continue}let i=o.statements.find(e=>t.isTypeAliasDeclaration(e)&&e.name.text===Lr(n));if(!i){e.onWarn?.(`route '${r}' could not be resolved — skipped.`);continue}let d=a.getTypeAtLocation(i.type);if(d.flags&t.TypeFlags.Any){e.onWarn?.(`route '${r}' resolved to 'any' — skipped rather than emitted, since an 'any' entry silently accepts every call. Check that the server type-checks.`);continue}c=r,u.set(r,l.expand(d)),c=null}return{entries:u,hoisted:l.hoisted()}}function Ir(e,t,n){let r=t.getSourceFile(n);if(!r)throw Error(`kick/client: ${n} is not in the TypeScript program. Run \`kick typegen\` first, and check that tsconfig.json includes .kickjs.`);let i=t.getSemanticDiagnostics(r);if(i.length===0)return;let a=i.slice(0,3).map(t=>` ${e.flattenDiagnosticMessageText(t.messageText,` `)}`).join(`
641
- `);throw Error(`${n} has ${i.length} type error(s), so its route types cannot be resolved — every entry would come out as 'any'.\n${a}\n Usually this means dependencies are not installed or the server does not type-check.`)}function Lr(e){return`_K${e}`}function Rr(e,t){let n=`./`+Je(e).replace(/\.tsx?$/,``),r=t.map((e,t)=>`type ${Lr(t)} = KickRoutes.Api[${JSON.stringify(e)}]`);return[`import ${JSON.stringify(n)}`,...r].join(`
641
+ `);throw Error(`${n} has ${i.length} type error(s), so its route types cannot be resolved — every entry would come out as 'any'.\n${a}\n Usually this means dependencies are not installed or the server does not type-check.`)}function Lr(e){return`_K${e}`}function Rr(e,t){let n=`./`+k(e).replace(/\.tsx?$/,``),r=t.map((e,t)=>`type ${Lr(t)} = KickRoutes.Api[${JSON.stringify(e)}]`);return[`import ${JSON.stringify(n)}`,...r].join(`
642
642
  `)+`
643
- `}function zr(e,t,n,r){let i=new Set,a=new Map;for(let t of n.statements)e.isTypeAliasDeclaration(t)&&a.set(t.name.text,t);for(let e of t.getSemanticDiagnostics(n))if(e.start!==void 0)for(let[t,o]of r.entries()){let r=a.get(Lr(t));r&&e.start>=r.getStart(n)&&e.start<r.getEnd()&&i.add(o)}return i}function Br(e,t){let n=e.filter(e=>/\.d\.(ts|mts|cts)$/.test(e)),r=[];try{r=$e(t).filter(e=>e.endsWith(`.ts`)).map(e=>j(t,e))}catch{}return[...new Set([...n,...r])]}function Vr(e,t,n,r){let i=j(t,`tsconfig.json`),a={...e.sys,onUnRecoverableConfigFileDiagnostic:t=>{throw Error(e.flattenDiagnosticMessageText(t.messageText,`
643
+ `}function zr(e,t,n,r){let i=new Set,a=new Map;for(let t of n.statements)e.isTypeAliasDeclaration(t)&&a.set(t.name.text,t);for(let e of t.getSemanticDiagnostics(n))if(e.start!==void 0)for(let[t,o]of r.entries()){let r=a.get(Lr(t));r&&e.start>=r.getStart(n)&&e.start<r.getEnd()&&i.add(o)}return i}function Br(e,t){let n=e.filter(e=>/\.d\.(ts|mts|cts)$/.test(e)),r=[];try{r=Qe(t).filter(e=>e.endsWith(`.ts`)).map(e=>j(t,e))}catch{}return[...new Set([...n,...r])]}function Vr(e,t,n,r){let i=j(t,`tsconfig.json`),a={...e.sys,onUnRecoverableConfigFileDiagnostic:t=>{throw Error(e.flattenDiagnosticMessageText(t.messageText,`
644
644
  `))}},o=e.getParsedCommandLineOfConfigFile(i,{},a);if(!o)throw Error(`kick/client: could not read ${i}`);let s=e.createCompilerHost(o.options,!0),c=s.readFile.bind(s),l=s.getSourceFile.bind(s),u=s.fileExists.bind(s);return s.readFile=e=>e===n?r:c(e),s.fileExists=e=>e===n||u(e),s.getSourceFile=(t,i,a,o)=>t===n?e.createSourceFile(t,r,i,!0):l(t,i,a,o),e.createProgram({rootNames:[...Br(o.fileNames,A(n)),n],options:o.options,host:s})}const Hr=`/* eslint-disable */
645
645
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
646
646
  //
@@ -686,7 +686,7 @@ declare global {
686
686
  }
687
687
 
688
688
  export type { Api }
689
- `}const Wr=`kick/client`,Q=`.kickjs/types/kick__client.d.ts`,Gr=`.kickjs/cache/client-map.sha1`,Kr=(()=>{try{return qe(import.meta.url)(`../../../package.json`).version??`0.0.0`}catch{return`0.0.0`}})();function qr(e){try{if(!N(e))return null;let[t,n]=P(e,`utf-8`).trim().split(/\s+/);return t&&n?{inputs:t,output:n}:null}catch{return null}}function Jr(e){return`${qt}${Wr} */\n\n${e}\n`}function Yr(e){try{return N(e)?P(e,`utf-8`):null}catch{return null}}async function Xr(e){let t=k.resolve(e.cwd,Q);if(!N(t))return!1;try{await it(t,{force:!0})}catch(t){return e.log.warn(` kick/client: could not remove the stale ${Q} — treat it as out of date (${t instanceof Error?t.message:String(t)})`),!0}return e.log.warn(` kick/client: removed the previously generated ${Q} rather than leave a stale one — re-run \`kick typegen\` once the cause above is fixed.`),!0}function Zr(e){let t=e?.typegen?.client;return typeof t==`object`?t.maxDepth:void 0}function Qr(e){let t=e.config?.typegen?.client;return typeof t==`boolean`?t:t&&typeof t==`object`?t.enabled!==!1:(N(k.resolve(e.cwd,Q))&&e.log.warn(` kick/client: ${Q} exists but typegen.client is not set, so it is NOT being refreshed.\n Add \`typegen: { client: true }\` to kick.config.ts to keep it current, or delete the file if nothing reads it.`),!1)}const $r=()=>({id:Wr,outExtension:`.d.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){if(!Qr(e))return null;if(e.watch)return e.log.info?.(" kick/client: skipped under watch (builds a full TypeScript program). Run `kick typegen` to refresh the client route map."),null;let t=await e.getScanResult({root:k.resolve(e.cwd,e.config?.typegen?.srcDir??`src`),cwd:e.cwd}),n=[],r=new Set;for(let e of t.routes){let t=`${e.httpMethod} ${e.mountedPath??e.path}`;r.has(t)||(r.add(t),n.push(t))}let i=Zr(e.config),a=await Pr({projectDir:e.cwd,keys:n,maxDepth:i,cliVersion:Kr}),o=qr(k.resolve(e.cwd,Gr)),s=Yr(k.resolve(e.cwd,Q));if(a&&o&&s!==null&&o.inputs===a&&o.output===Mr(s))return oe()&&e.log.info?.(` kick/client: unchanged, keeping ${Q}`),null;try{let t=Ur(await Fr({projectDir:e.cwd,routesFile:k.resolve(e.cwd,`.kickjs/types/kick__routes.ts`),keys:n,maxDepth:i,onWarn:t=>e.log.warn(t)}),n);return a&&!e.check&&await e.writeFile(Gr,`${a} ${Mr(Jr(t))}`),t}catch(t){let n=N(k.resolve(e.cwd,Q)),r=` kick/client: skipped — ${t instanceof Error?t.message:String(t)}`;return n?e.log.warn(r):oe()&&e.log.info?.(r),n&&await Xr(e),null}}});function ei(e,t,n=`zod`){if(!e)return null;let r=Ye(A(t),e.filePath).split(Xe).join(`/`);return r=r.replace(/\.(ts|tsx|mts|cts)$/i,``),r.startsWith(`.`)||(r=`./`+r),`/* eslint-disable */
689
+ `}const Wr=`kick/client`,Q=`.kickjs/types/kick__client.d.ts`,Gr=`.kickjs/cache/client-map.sha1`,Kr=(()=>{try{return qe(import.meta.url)(`../../../package.json`).version??`0.0.0`}catch{return`0.0.0`}})();function qr(e){try{if(!N(e))return null;let[t,n]=P(e,`utf-8`).trim().split(/\s+/);return t&&n?{inputs:t,output:n}:null}catch{return null}}function Jr(e){return`${qt}${Wr} */\n\n${e}\n`}function Yr(e){try{return N(e)?P(e,`utf-8`):null}catch{return null}}async function Xr(e){let t=O.resolve(e.cwd,Q);if(!N(t))return!1;try{await it(t,{force:!0})}catch(t){return e.log.warn(` kick/client: could not remove the stale ${Q} — treat it as out of date (${t instanceof Error?t.message:String(t)})`),!0}return e.log.warn(` kick/client: removed the previously generated ${Q} rather than leave a stale one — re-run \`kick typegen\` once the cause above is fixed.`),!0}function Zr(e){let t=e?.typegen?.client;return typeof t==`object`?t.maxDepth:void 0}function Qr(e){let t=e.config?.typegen?.client;return typeof t==`boolean`?t:t&&typeof t==`object`?t.enabled!==!1:(N(O.resolve(e.cwd,Q))&&e.log.warn(` kick/client: ${Q} exists but typegen.client is not set, so it is NOT being refreshed.\n Add \`typegen: { client: true }\` to kick.config.ts to keep it current, or delete the file if nothing reads it.`),!1)}const $r=()=>({id:Wr,outExtension:`.d.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){if(!Qr(e))return null;if(e.watch)return e.log.info?.(" kick/client: skipped under watch (builds a full TypeScript program). Run `kick typegen` to refresh the client route map."),null;let t=await e.getScanResult({root:O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`),cwd:e.cwd}),n=[],r=new Set;for(let e of t.routes){let t=`${e.httpMethod} ${e.mountedPath??e.path}`;r.has(t)||(r.add(t),n.push(t))}let i=Zr(e.config),a=await Pr({projectDir:e.cwd,keys:n,maxDepth:i,cliVersion:Kr}),o=qr(O.resolve(e.cwd,Gr)),s=Yr(O.resolve(e.cwd,Q));if(a&&o&&s!==null&&o.inputs===a&&o.output===Mr(s))return x()&&e.log.info?.(` kick/client: unchanged, keeping ${Q}`),null;try{let t=Ur(await Fr({projectDir:e.cwd,routesFile:O.resolve(e.cwd,`.kickjs/types/kick__routes.ts`),keys:n,maxDepth:i,onWarn:t=>e.log.warn(t)}),n);return a&&!e.check&&await e.writeFile(Gr,`${a} ${Mr(Jr(t))}`),t}catch(t){let n=N(O.resolve(e.cwd,Q)),r=` kick/client: skipped — ${t instanceof Error?t.message:String(t)}`;return n?e.log.warn(r):x()&&e.log.info?.(r),n&&await Xr(e),null}}});function ei(e,t,n=`zod`){if(!e)return null;let r=Je(A(t),e.filePath).split(Ye).join(`/`);return r=r.replace(/\.(ts|tsx|mts|cts)$/i,``),r.startsWith(`.`)||(r=`./`+r),`/* eslint-disable */
690
690
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
691
691
  // Re-run with \`kick typegen\` or rely on \`kick dev\` to refresh.
692
692
 
@@ -724,6 +724,6 @@ declare global {
724
724
  }
725
725
 
726
726
  export {}
727
- `}const ti=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=ri(e);if(t===!1)return null;let n=await e.getScanResult({root:ni(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=e.config?.typegen?.schemaValidator??`zod`,i=k.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return ei(n.env,i,r)}});function ni(e){return k.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ri(e){return e.config?.typegen?.envFile}function ii(e){return k.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ai(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function $(e){return{root:ii(e),cwd:e.cwd,envFile:ai(e)}}const oi=()=>({id:`kick/registry`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=k.resolve(e.cwd,`.kickjs/types/kick__registry.d.ts`),r=new Set(t.collisions.map(e=>e.className));return He(t.classes,n,r)}}),si=()=>({id:`kick/services`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=new Set(t.collisions.map(e=>e.className));return Be(`ServiceToken`,ze(t.classes,t.tokens,t.injects,n),"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)")}}),ci=()=>({id:`kick/modules`,inputs:[`src/**/*.ts`],async generate(e){return Be(`ModuleToken`,Ne((await e.getScanResult($(e))).classes),"(no @Module classes discovered — `kick g module <name>` to add one)")}}),li=()=>({id:`kick/plugins`,inputs:[`src/**/*.ts`],async generate(e){return Fe((await e.getScanResult($(e))).pluginsAndAdapters)}}),ui=()=>({id:`kick/augmentations`,inputs:[`src/**/*.ts`],async generate(e){return Ke((await e.getScanResult($(e))).augmentations)}}),di=()=>({id:`kick/context`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return t.contextKeys.length===0?null:Pe(t.contextKeys)}}),fi={fastify:{subpath:`@forinda/kickjs/fastify`,typeName:`FastifyRuntimeTypes`},h3:{subpath:`@forinda/kickjs/h3`,typeName:`H3RuntimeTypes`}},pi=[O({name:`kick/init`,register:ht}),O({name:`kick/generate`,register:Gt}),O({name:`kick/run`,register:an}),O({name:`kick/info`,register:un}),O({name:`kick/inspect`,register:vn}),O({name:`kick/add`,register:be}),O({name:`kick/list`,register:Se}),O({name:`kick/explain`,register:On}),O({name:`kick/mcp`,register:Ln}),O({name:`kick/tinker`,register:Vn}),O({name:`kick/remove`,register:qn}),O({name:`kick/typegen`,register:Xn}),O({name:`kick/check`,register:cr}),O({name:`kick/doctor`,register:me}),O({name:`kick/codemod`,register:ur}),O({name:`kick/registry`,typegens:[oi()]}),O({name:`kick/services`,typegens:[si()]}),O({name:`kick/modules`,typegens:[ci()]}),O({name:`kick/plugins`,typegens:[li()]}),O({name:`kick/augmentations`,typegens:[ui()]}),O({name:`kick/context`,typegens:[di()]}),O({name:`kick/assets`,typegens:[dr()]}),O({name:`kick/routes`,typegens:[xr()]}),O({name:`kick/client`,typegens:[$r()]}),O({name:`kick/env`,typegens:[ti()]}),O({name:`kick/runtime`,typegens:[{id:`kick/runtime`,outExtension:`.ts`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`],async generate(e){let t=e.config?.runtime;if(t!==`fastify`&&t!==`h3`)return null;let{subpath:n,typeName:r}=fi[t];return[`// Runtime escape-hatch types for the '${t}' engine (kick.config runtime).`,`declare module '@forinda/kickjs' {`,` interface KickRuntimeRegister {`,` runtime: import('${n}').${r}`,` }`,`}`,``,`export {}`,``].join(`
728
- `)}}]})];export{Xt as applyDisableFilter,Zt as runAllPluginTypegens,pi as t};
729
- //# sourceMappingURL=run-plugins-CHv-_CI_.mjs.map
727
+ `}const ti=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=ri(e);if(t===!1)return null;let n=await e.getScanResult({root:ni(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=e.config?.typegen?.schemaValidator??`zod`,i=O.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return ei(n.env,i,r)}});function ni(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ri(e){return e.config?.typegen?.envFile}function ii(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ai(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function $(e){return{root:ii(e),cwd:e.cwd,envFile:ai(e)}}const oi=()=>({id:`kick/registry`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=O.resolve(e.cwd,`.kickjs/types/kick__registry.d.ts`),r=new Set(t.collisions.map(e=>e.className));return Ue(t.classes,n,r)}}),si=()=>({id:`kick/services`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=new Set(t.collisions.map(e=>e.className));return Ve(`ServiceToken`,Be(t.classes,t.tokens,t.injects,n),"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)")}}),ci=()=>({id:`kick/modules`,inputs:[`src/**/*.ts`],async generate(e){return Ve(`ModuleToken`,Pe((await e.getScanResult($(e))).classes),"(no @Module classes discovered — `kick g module <name>` to add one)")}}),li=()=>({id:`kick/plugins`,inputs:[`src/**/*.ts`],async generate(e){return Ie((await e.getScanResult($(e))).pluginsAndAdapters)}}),ui=()=>({id:`kick/augmentations`,inputs:[`src/**/*.ts`],async generate(e){return Ke((await e.getScanResult($(e))).augmentations)}}),di=()=>({id:`kick/context`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return t.contextKeys.length===0?null:Fe(t.contextKeys)}}),fi={fastify:{subpath:`@forinda/kickjs/fastify`,typeName:`FastifyRuntimeTypes`},h3:{subpath:`@forinda/kickjs/h3`,typeName:`H3RuntimeTypes`}},pi=[E({name:`kick/init`,register:ht}),E({name:`kick/generate`,register:Gt}),E({name:`kick/run`,register:an}),E({name:`kick/info`,register:un}),E({name:`kick/inspect`,register:vn}),E({name:`kick/add`,register:be}),E({name:`kick/list`,register:Se}),E({name:`kick/explain`,register:On}),E({name:`kick/mcp`,register:Ln}),E({name:`kick/tinker`,register:Vn}),E({name:`kick/remove`,register:qn}),E({name:`kick/typegen`,register:Xn}),E({name:`kick/check`,register:cr}),E({name:`kick/doctor`,register:me}),E({name:`kick/codemod`,register:ur}),E({name:`kick/registry`,typegens:[oi()]}),E({name:`kick/services`,typegens:[si()]}),E({name:`kick/modules`,typegens:[ci()]}),E({name:`kick/plugins`,typegens:[li()]}),E({name:`kick/augmentations`,typegens:[ui()]}),E({name:`kick/context`,typegens:[di()]}),E({name:`kick/assets`,typegens:[dr()]}),E({name:`kick/routes`,typegens:[xr()]}),E({name:`kick/client`,typegens:[$r()]}),E({name:`kick/env`,typegens:[ti()]}),E({name:`kick/runtime`,typegens:[{id:`kick/runtime`,outExtension:`.ts`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`],async generate(e){let t=e.config?.runtime;if(t!==`fastify`&&t!==`h3`)return null;let{subpath:n,typeName:r}=fi[t];return[`// Runtime escape-hatch types for the '${t}' engine (kick.config runtime).`,`declare module '@forinda/kickjs' {`,` interface KickRuntimeRegister {`,` runtime: import('${n}').${r}`,` }`,`}`,``,`export {}`,``].join(`
728
+ `)}}]})];export{Xt as applyDisableFilter,U as runAllPluginTypegens,pi as t};
729
+ //# sourceMappingURL=run-plugins-BKGgSL6L.mjs.map