@forinda/kickjs-cli 5.7.0 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v5.7.0
2
+ * @forinda/kickjs-cli v5.8.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{createRequire as e}from"node:module";import{Command as t}from"commander";import{cpSync as n,existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,rmSync as s,statSync as c,writeFileSync as l}from"node:fs";import u,{basename as d,dirname as f,extname as p,isAbsolute as m,join as h,parse as g,relative as _,resolve as v,sep as y}from"node:path";import{fileURLToPath as b,pathToFileURL as x}from"node:url";import{execFileSync as ee,execSync as S,fork as te,spawn as ne,spawnSync as re}from"node:child_process";import{access as ie,copyFile as ae,mkdir as oe,readFile as C,readdir as se,rm as ce,stat as le,unlink as ue,writeFile as w}from"node:fs/promises";import*as T from"@clack/prompts";import E from"picocolors";import de from"pluralize";import{glob as fe,globSync as pe}from"glob";import{groupAssetKeys as me}from"@forinda/kickjs";import{arch as he,platform as ge,release as _e}from"node:os";import{detectCompositeReferences as ve,generate as ye,migrateDown as be,migrateLatest as xe,migrateRollback as Se,migrateStatus as Ce,migrateUp as we,renderSchemaSource as Te,resolveDbConfig as Ee}from"@forinda/kickjs-db";var De=Object.defineProperty,D=(e,t)=>{let n={};for(var r in e)De(n,r,{get:e[r],enumerable:!0});return t||De(n,Symbol.toStringTag,{value:`Module`}),n};function Oe(e,t,n){S(e,{cwd:t,stdio:`inherit`,env:n?{...process.env,...n}:process.env})}function ke(e,t,n){let r=re(process.execPath,[e],{cwd:n,stdio:`inherit`,env:{...process.env,...t}});r.status!==0&&process.exit(r.status??1)}function Ae(e,t){if(!t?.commands?.length)return;let n=new Set(e.commands.map(e=>e.name()));for(let r of t.commands){if(n.has(r.name)){console.warn(` Warning: custom command '${r.name}' skipped — conflicts with a built-in command`);continue}je(e,r)}}function je(e,t){let n=e.command(t.name).description(t.description);if(t.aliases)for(let e of t.aliases)n.alias(e);n.allowUnknownOption(!0),n.argument(`[args...]`,`Additional arguments passed to the command`),n.action(e=>{let n=e.join(` `),r=Array.isArray(t.steps)?t.steps:[t.steps];for(let e of r){let r=n?`${e} ${n}`:e;console.log(` $ ${r}`);try{Oe(r)}catch{console.error(` Command failed: ${t.name}`),process.exitCode=1;return}}})}var Me=D({BUILTIN_REPO_TYPES:()=>Pe,PACKAGE_MANAGERS:()=>Ne,defineConfig:()=>Fe,loadKickConfig:()=>k,resolveModuleConfig:()=>O,resolveTokenScope:()=>Ie,validateAssetMap:()=>ze});const Ne=[`pnpm`,`npm`,`yarn`,`bun`],Pe=[`drizzle`,`inmemory`,`prisma`];function Fe(e){return e}function Ie(e,t){if(e?.tokenScope&&typeof e.tokenScope==`string`&&e.tokenScope.length>0){let t=Le(e.tokenScope);if(t.length>0)return t}try{let e=h(t,`package.json`);if(r(e)){let t=JSON.parse(a(e,`utf-8`));if(typeof t.name==`string`&&t.name.length>0){let e=t.name.match(/^@([^/]+)\//),n=Le(e?e[1]:t.name);if(n.length>0)return n}}}catch{}return`app`}function Le(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,`-`).replace(/^-+|-+$/g,``).replace(/-{2,}/g,`-`)}function O(e){if(!e)return{};let t={dir:e.modules?.dir,repo:e.modules?.repo,schemaDir:e.modules?.schemaDir,pluralize:e.modules?.pluralize,prismaClientPath:e.modules?.prismaClientPath,style:e.modules?.style};return t.style!==void 0&&t.style!==`define`&&t.style!==`class`&&(console.warn(` Warning: modules.style '${t.style}' is not a valid value (expected 'define' or 'class'). Falling back to 'define'.`),t.style=`define`),t.repo&&typeof t.repo==`string`&&!Pe.includes(t.repo)&&console.warn(` Warning: modules.repo '${t.repo}' is not a built-in type (${Pe.join(`, `)}). It will generate a stub repository. Use { name: '${t.repo}' } to silence this warning.`),t}const Re=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];async function k(e){let{findProjectRoot:t}=await Promise.resolve().then(()=>bo),n=t(e);for(let e of Re){let t=h(n,e);try{await ie(t)}catch{continue}if(e.endsWith(`.json`)){let e=await C(t,`utf-8`);return JSON.parse(e)}if(e.endsWith(`.ts`)){let r;try{r=await import(`jiti`)}catch(t){let n=t instanceof Error?t.message:String(t);n.includes(`Cannot find package 'jiti'`)||n.includes(`ERR_MODULE_NOT_FOUND`)?console.warn(`Warning: Failed to load ${e} — 'jiti' is required for TypeScript configs. Run \`pnpm add -D jiti\` (or your package manager's equivalent), or rename the file to kick.config.js / kick.config.mjs / kick.config.json.`):console.warn(`Warning: Failed to initialize jiti for ${e}: ${n}`);continue}try{let e=await r.createJiti(n,{interopDefault:!0,fsCache:!1}).import(t,{default:!0}),i=ze(e,n);for(let e of i)console.warn(` Warning: ${e}`);return e}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}try{let{pathToFileURL:e}=await import(`node:url`),r=await import(e(t).href),i=r.default??r,a=ze(i,n);for(let e of a)console.warn(` Warning: ${e}`);return i}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}return null}function ze(e,t){let n=[];if(!e?.assetMap)return n;let i=v(t);for(let[a,o]of Object.entries(e.assetMap)){if(!a||a.includes(`/`)){n.push(`assetMap key '${a}' is invalid — must be a non-empty string without '/'`);continue}if(typeof o?.src!=`string`||o.src.length===0){n.push(`assetMap.${a} is missing a non-empty 'src' field`);continue}r(v(t,o.src))||n.push(`assetMap.${a}.src ('${o.src}') does not exist — typegen + build will fail`),o.dest&&Be(v(t,o.dest),i)&&n.push(`assetMap.${a}.dest ('${o.dest}') resolves outside the project root — refusing to copy`)}return n}function Be(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function A(e){return e}var Ve=class extends Error{constructor(e,t,n){super(`Two plugins registered the same ${e} '${t}': ${n.join(`, `)}. Plugins must use unique ${e} names.`),this.name=`KickPluginConflictError`}};function He(e,t=[]){let n=new Map;for(let t of e){let e=(n.get(t.name)??0)+1;if(n.set(t.name,e),e===2)throw new Ve(`plugin`,t.name,[t.name,t.name])}let r=new Map,i=[];for(let t of e)for(let e of t.commands??[]){let n=r.get(e.name);if(n)throw new Ve(`command`,e.name,[n,t.name]);r.set(e.name,t.name),i.push(e)}let a=new Set(t.map(e=>e.name)),o=[...i.filter(e=>!a.has(e.name)),...t],s=new Map,c=[];for(let t of e)for(let e of t.typegens??[]){let n=s.get(e.id);if(n)throw new Ve(`typegen`,e.id,[n,t.name]);s.set(e.id,t.name),c.push(e)}let l=new Map,u=[];for(let t of e)for(let e of t.generators??[]){let n=l.get(e.name);if(n)throw new Ve(`generator`,e.name,[n,t.name]);l.set(e.name,t.name),u.push({source:t.name,spec:e})}return{commands:o,typegens:c,generators:u,register:async(t,n)=>{let r=n?{generators:u,...n}:{cwd:process.cwd(),config:null,log:()=>{},generators:u};for(let n of e)n.register&&await n.register(t,r)}}}var Ue=D({mergeCliPlugins:()=>He});let We=!1;function j(e){We=e}const Ge=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){We||(await oe(f(e),{recursive:!0}),await w(e,t,`utf-8`),Ge.has(p(e))&&await qe(e,t).catch(()=>{}))}let N;async function Ke(t){if(N!==void 0)return N;try{N=await import(e(h(t,`package.json`)).resolve(`oxfmt`))}catch{N=null}return N}async function qe(e,t){let n=await Ke(process.cwd());if(!n)return;let r=await Ye(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await w(e,i.code,`utf-8`)}const Je=new Map;async function Ye(e){let t=f(e),n=t;if(Je.has(n))return Je.get(n);for(;;){let e=h(t,`.oxfmtrc.json`);if(r(e))try{let t=await C(e,`utf-8`),r=JSON.parse(t);return delete r.$schema,delete r.ignorePatterns,Je.set(n,r),r}catch{return Je.set(n,null),null}let i=f(t);if(i===t)return Je.set(n,null),null;t=i}}async function Xe(e){try{return await ie(e),!0}catch{return!1}}const Ze={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function Qe(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function $e(e,t,n,r=[]){let i={"@forinda/kickjs":Qe(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`,pino:`^10.3.1`,"pino-pretty":`^13.1.3`};for(let e of r){let t=Ze[e];t&&!i[t]&&(i[t]=Qe(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`vite`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:i,devDependencies:{"@forinda/kickjs-cli":Qe(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":Qe(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function et(){return`import { defineConfig } from 'vite'
11
+ import{createRequire as e}from"node:module";import{Command as t}from"commander";import{cpSync as n,existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,rmSync as s,statSync as c,writeFileSync as l}from"node:fs";import u,{basename as d,dirname as f,extname as p,isAbsolute as m,join as h,parse as g,relative as _,resolve as v,sep as y}from"node:path";import{fileURLToPath as b,pathToFileURL as x}from"node:url";import{execFileSync as ee,execSync as S,fork as te,spawn as ne,spawnSync as re}from"node:child_process";import{access as ie,copyFile as ae,mkdir as oe,readFile as C,readdir as se,rm as ce,stat as le,unlink as ue,writeFile as w}from"node:fs/promises";import*as T from"@clack/prompts";import E from"picocolors";import de from"pluralize";import{glob as fe,globSync as pe}from"glob";import{groupAssetKeys as me}from"@forinda/kickjs";import{arch as he,platform as ge,release as _e}from"node:os";import{detectCompositeReferences as ve,generate as ye,migrateDown as be,migrateLatest as xe,migrateRollback as Se,migrateStatus as Ce,migrateUp as we,renderSchemaSource as Te,resolveDbConfig as Ee}from"@forinda/kickjs-db";var De=Object.defineProperty,D=(e,t)=>{let n={};for(var r in e)De(n,r,{get:e[r],enumerable:!0});return t||De(n,Symbol.toStringTag,{value:`Module`}),n};function Oe(e,t,n){S(e,{cwd:t,stdio:`inherit`,env:n?{...process.env,...n}:process.env})}function ke(e,t,n){let r=re(process.execPath,[e],{cwd:n,stdio:`inherit`,env:{...process.env,...t}});r.status!==0&&process.exit(r.status??1)}function Ae(e,t){if(!t?.commands?.length)return;let n=new Set(e.commands.map(e=>e.name()));for(let r of t.commands){if(n.has(r.name)){console.warn(` Warning: custom command '${r.name}' skipped — conflicts with a built-in command`);continue}je(e,r)}}function je(e,t){let n=e.command(t.name).description(t.description);if(t.aliases)for(let e of t.aliases)n.alias(e);n.allowUnknownOption(!0),n.argument(`[args...]`,`Additional arguments passed to the command`),n.action(e=>{let n=e.join(` `),r=Array.isArray(t.steps)?t.steps:[t.steps];for(let e of r){let r=n?`${e} ${n}`:e;console.log(` $ ${r}`);try{Oe(r)}catch{console.error(` Command failed: ${t.name}`),process.exitCode=1;return}}})}var Me=D({BUILTIN_REPO_TYPES:()=>Pe,PACKAGE_MANAGERS:()=>Ne,defineConfig:()=>Fe,loadKickConfig:()=>k,resolveModuleConfig:()=>O,resolveTokenScope:()=>Ie,validateAssetMap:()=>ze});const Ne=[`pnpm`,`npm`,`yarn`,`bun`],Pe=[`drizzle`,`inmemory`,`prisma`];function Fe(e){return e}function Ie(e,t){if(e?.tokenScope&&typeof e.tokenScope==`string`&&e.tokenScope.length>0){let t=Le(e.tokenScope);if(t.length>0)return t}try{let e=h(t,`package.json`);if(r(e)){let t=JSON.parse(a(e,`utf-8`));if(typeof t.name==`string`&&t.name.length>0){let e=t.name.match(/^@([^/]+)\//),n=Le(e?e[1]:t.name);if(n.length>0)return n}}}catch{}return`app`}function Le(e){return e.toLowerCase().replace(/[^a-z0-9-]/g,`-`).replace(/^-+|-+$/g,``).replace(/-{2,}/g,`-`)}function O(e){if(!e)return{};let t={dir:e.modules?.dir,repo:e.modules?.repo,schemaDir:e.modules?.schemaDir,pluralize:e.modules?.pluralize,prismaClientPath:e.modules?.prismaClientPath,style:e.modules?.style};return t.style!==void 0&&t.style!==`define`&&t.style!==`class`&&(console.warn(` Warning: modules.style '${t.style}' is not a valid value (expected 'define' or 'class'). Falling back to 'define'.`),t.style=`define`),t.repo&&typeof t.repo==`string`&&!Pe.includes(t.repo)&&console.warn(` Warning: modules.repo '${t.repo}' is not a built-in type (${Pe.join(`, `)}). It will generate a stub repository. Use { name: '${t.repo}' } to silence this warning.`),t}const Re=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];async function k(e){let{findProjectRoot:t}=await Promise.resolve().then(()=>Zt),n=t(e);for(let e of Re){let t=h(n,e);try{await ie(t)}catch{continue}if(e.endsWith(`.json`)){let e=await C(t,`utf-8`);return JSON.parse(e)}if(e.endsWith(`.ts`)){let r;try{r=await import(`jiti`)}catch(t){let n=t instanceof Error?t.message:String(t);n.includes(`Cannot find package 'jiti'`)||n.includes(`ERR_MODULE_NOT_FOUND`)?console.warn(`Warning: Failed to load ${e} — 'jiti' is required for TypeScript configs. Run \`pnpm add -D jiti\` (or your package manager's equivalent), or rename the file to kick.config.js / kick.config.mjs / kick.config.json.`):console.warn(`Warning: Failed to initialize jiti for ${e}: ${n}`);continue}try{let e=await r.createJiti(n,{interopDefault:!0,fsCache:!1}).import(t,{default:!0}),i=ze(e,n);for(let e of i)console.warn(` Warning: ${e}`);return e}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}try{let{pathToFileURL:e}=await import(`node:url`),r=await import(e(t).href),i=r.default??r,a=ze(i,n);for(let e of a)console.warn(` Warning: ${e}`);return i}catch(t){let n=t instanceof Error?t.message:String(t);console.warn(`Warning: Failed to load ${e}: ${n}`);continue}}return null}function ze(e,t){let n=[];if(!e?.assetMap)return n;let i=v(t);for(let[a,o]of Object.entries(e.assetMap)){if(!a||a.includes(`/`)){n.push(`assetMap key '${a}' is invalid — must be a non-empty string without '/'`);continue}if(typeof o?.src!=`string`||o.src.length===0){n.push(`assetMap.${a} is missing a non-empty 'src' field`);continue}r(v(t,o.src))||n.push(`assetMap.${a}.src ('${o.src}') does not exist — typegen + build will fail`),o.dest&&Be(v(t,o.dest),i)&&n.push(`assetMap.${a}.dest ('${o.dest}') resolves outside the project root — refusing to copy`)}return n}function Be(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function A(e){return e}var Ve=class extends Error{constructor(e,t,n){super(`Two plugins registered the same ${e} '${t}': ${n.join(`, `)}. Plugins must use unique ${e} names.`),this.name=`KickPluginConflictError`}};function He(e,t=[]){let n=new Map;for(let t of e){let e=(n.get(t.name)??0)+1;if(n.set(t.name,e),e===2)throw new Ve(`plugin`,t.name,[t.name,t.name])}let r=new Map,i=[];for(let t of e)for(let e of t.commands??[]){let n=r.get(e.name);if(n)throw new Ve(`command`,e.name,[n,t.name]);r.set(e.name,t.name),i.push(e)}let a=new Set(t.map(e=>e.name)),o=[...i.filter(e=>!a.has(e.name)),...t],s=new Map,c=[];for(let t of e)for(let e of t.typegens??[]){let n=s.get(e.id);if(n)throw new Ve(`typegen`,e.id,[n,t.name]);s.set(e.id,t.name),c.push(e)}let l=new Map,u=[];for(let t of e)for(let e of t.generators??[]){let n=l.get(e.name);if(n)throw new Ve(`generator`,e.name,[n,t.name]);l.set(e.name,t.name),u.push({source:t.name,spec:e})}return{commands:o,typegens:c,generators:u,register:async(t,n)=>{let r;if(n)r={generators:u,...n};else{let{findProjectRoot:e}=await Promise.resolve().then(()=>Zt),t=process.cwd();r={cwd:t,projectRoot:e(t),config:null,log:()=>{},generators:u}}for(let n of e)n.register&&await n.register(t,r)}}}var Ue=D({mergeCliPlugins:()=>He});let We=!1;function j(e){We=e}const Ge=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function M(e,t){We||(await oe(f(e),{recursive:!0}),await w(e,t,`utf-8`),Ge.has(p(e))&&await Je(e,t).catch(()=>{}))}let Ke;async function qe(t){if(Ke!==void 0)return Ke;try{Ke=await import(e(h(t,`package.json`)).resolve(`oxfmt`))}catch{Ke=null}return Ke}async function Je(e,t){let n=await qe(process.cwd());if(!n)return;let r=await Ye(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await w(e,i.code,`utf-8`)}const N=new Map;async function Ye(e){let t=f(e),n=t;if(N.has(n))return N.get(n);for(;;){let e=h(t,`.oxfmtrc.json`);if(r(e))try{let t=await C(e,`utf-8`),r=JSON.parse(t);return delete r.$schema,delete r.ignorePatterns,N.set(n,r),r}catch{return N.set(n,null),null}let i=f(t);if(i===t)return N.set(n,null),null;t=i}}async function Xe(e){try{return await ie(e),!0}catch{return!1}}const Ze={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function Qe(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function $e(e,t,n,r=[]){let i={"@forinda/kickjs":Qe(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`,pino:`^10.3.1`,"pino-pretty":`^13.1.3`};for(let e of r){let t=Ze[e];t&&!i[t]&&(i[t]=Qe(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`vite`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:i,devDependencies:{"@forinda/kickjs-cli":Qe(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":Qe(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function et(){return`import { defineConfig } from 'vite'
12
12
  import { resolve } from 'node:path'
13
13
  import swc from 'unplugin-swc'
14
14
  import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
@@ -1403,7 +1403,7 @@ Codex / Cursor / Gemini / Claude Code without copy-pasting.
1403
1403
  CLI template. Hand-edited content is overwritten — keep customisation
1404
1404
  in \`.agents/COPILOT.local.md\`.
1405
1405
  `}const Ct=f(b(import.meta.url)),wt=JSON.parse(a(h(Ct,`..`,`package.json`),`utf-8`)),Tt=`^${wt.version}`,Et=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function Dt(){let e=await Promise.all(Et.map(async e=>{try{let t=ee(`npm`,[`view`,e,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(t&&/^\d+\.\d+\.\d+/.test(t))return[e,`^${t}`]}catch{}return[e,Tt]}));return Object.fromEntries(e)}async function Ot(e){let{name:t,directory:n,packageManager:r=`pnpm`,template:i=`rest`,defaultRepo:a=`inmemory`,packages:o=[]}=e,s=n,c=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${t}\n`),c(`Resolving package versions...`);let l=await Dt();if(await M(h(s,`package.json`),$e(t,i,l,o)),await M(h(s,`vite.config.ts`),et()),await M(h(s,`tsconfig.json`),tt()),await M(h(s,`.prettierrc`),nt()),await M(h(s,`.editorconfig`),rt()),await M(h(s,`.gitignore`),it()),await M(h(s,`.gitattributes`),at()),await M(h(s,`.env`),ot()),await M(h(s,`.env.example`),st()),await M(h(s,`src/config/index.ts`),dt()),await M(h(s,`src/index.ts`),lt(t,i,wt.version,o)),await M(h(s,`src/modules/index.ts`),ut()),await M(h(s,`src/modules/hello/hello.service.ts`),ft()),await M(h(s,`src/modules/hello/hello.controller.ts`),pt()),await M(h(s,`src/modules/hello/hello.module.ts`),mt()),await M(h(s,`kick.config.ts`),ht(i,a,r)),await M(h(s,`vitest.config.ts`),ct()),await M(h(s,`README.md`),gt(t,i,r)),await M(h(s,`CLAUDE.md`),_t(t,i,r)),await M(h(s,`AGENTS.md`),vt(t,i,r)),await M(h(s,`kickjs-skills.md`),bt(t,i,r)),e.installDeps){console.log(`\n Installing dependencies with ${r}...\n`);try{S(`${r} install`,{cwd:s,stdio:`inherit`}),console.log(`
1406
- Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await Promise.resolve().then(()=>oa);await e({cwd:s,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{S(`git init`,{cwd:s,stdio:`pipe`}),S(`git branch -M main`,{cwd:s,stdio:`pipe`}),S(`git add -A`,{cwd:s,stdio:`pipe`}),S(`git commit -m "chore: initial commit from kick new"`,{cwd:s,stdio:`pipe`}),c(`Git repository initialized`)}catch{c(`Warning: git init failed (git may not be installed)`)}console.log(`
1406
+ Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${r} install failed. Run it manually.`)}}try{let{runTypegen:e}=await Promise.resolve().then(()=>la);await e({cwd:s,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{S(`git init`,{cwd:s,stdio:`pipe`}),S(`git branch -M main`,{cwd:s,stdio:`pipe`}),S(`git add -A`,{cwd:s,stdio:`pipe`}),S(`git commit -m "chore: initial commit from kick new"`,{cwd:s,stdio:`pipe`}),c(`Git repository initialized`)}catch{c(`Warning: git init failed (git may not be installed)`)}console.log(`
1407
1407
  Project scaffolded successfully!`),console.log();let u=s!==process.cwd();c(`Next steps:`),u&&c(` cd ${t}`),e.installDeps||c(` ${r} install`);let d={rest:`kick g module user`,ddd:`kick g module user --repo drizzle`,cqrs:`kick g module user --pattern cqrs`,minimal:`# add your routes to src/index.ts`};c(` ${d[i]??d.rest}`),c(` kick dev`),c(``),c(`Commands:`),c(` kick dev Start dev server with Vite HMR`),c(` kick build Production build via Vite`),c(` kick start Run production build`),c(``),c(`Generators:`),c(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),c(` kick g scaffold <n> <f..> CRUD module from field definitions`),c(` kick g controller <name> Standalone controller`),c(` kick g service <name> @Service() class`),c(` kick g middleware <name> Express middleware`),c(` kick g guard <name> Route guard (auth, roles, etc.)`),c(` kick g adapter <name> AppAdapter with lifecycle hooks`),c(` kick g dto <name> Zod DTO schema`),i===`cqrs`&&c(` kick g job <name> Queue job processor`),c(` kick g config Generate kick.config.ts`),c(``),c(`Add packages:`),c(` kick add <pkg> Install a KickJS package + peers`),c(` kick add --list Show all available packages`),c(``),c(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),c(``)}const kt={GET:E.green,POST:E.cyan,PUT:E.yellow,PATCH:E.magenta,DELETE:E.red};function At(e){return(kt[e]??E.dim)(e.padEnd(7))}function jt(e){let t=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return E.red(t);case`WARNING`:return E.yellow(t);case`INFO`:return E.blue(E.dim(t));default:return t}}E.green(`✓`),E.red(`✖`),E.yellow(`⚠`),E.blue(`ℹ`);function Mt(e){T.intro(E.bgCyan(E.black(` ${e} `)))}function Nt(e){T.outro(e)}function Pt(e){T.isCancel(e)&&(T.cancel(`Operation cancelled.`),process.exit(0))}async function Ft(e){let t=await T.text(e);return Pt(t),t}async function It(e){let t=await T.select(e);return Pt(t),t}async function Lt(e){let t=await T.multiselect(e);return Pt(t),t}async function P(e){let t=await T.confirm(e);return Pt(t),t}function Rt(){return T.spinner()}const F=T.log,zt={kickjs:{pkg:`@forinda/kickjs`,peers:[`express`],description:`Unified framework: DI, decorators, routing, middleware`,core:!0},vite:{pkg:`@forinda/kickjs-vite`,peers:[`vite`],description:`Vite plugin: dev server, HMR, module discovery`,dev:!0,core:!0},cli:{pkg:`@forinda/kickjs-cli`,peers:[],description:`CLI tool and code generators`,dev:!0,core:!0},swagger:{pkg:`@forinda/kickjs-swagger`,peers:[],description:`OpenAPI spec + Swagger UI + ReDoc`},db:{pkg:`@forinda/kickjs-db`,peers:[],description:`kick/db core — schema DSL, migrations, KickDbClient, customType`},"db-pg":{pkg:`@forinda/kickjs-db-pg`,peers:[`pg`],description:`kick/db PostgreSQL dialect + adapter (pgDialect, pgAdapter)`},drizzle:{pkg:`@forinda/kickjs-drizzle`,peers:[`drizzle-orm`],description:`Drizzle ORM adapter + query builder`},prisma:{pkg:`@forinda/kickjs-prisma`,peers:[`@prisma/client`],description:`Prisma adapter + query builder`},ws:{pkg:`@forinda/kickjs-ws`,peers:[`socket.io`],description:`WebSocket with @WsController decorators`},devtools:{pkg:`@forinda/kickjs-devtools`,peers:[],description:`Development dashboard — routes, DI, metrics, health`,dev:!0},queue:{pkg:`@forinda/kickjs-queue`,peers:[],description:`Queue adapter (BullMQ/RabbitMQ/Kafka)`},"queue:bullmq":{pkg:`@forinda/kickjs-queue`,peers:[`bullmq`,`ioredis`],description:`Queue with BullMQ + Redis`},"queue:rabbitmq":{pkg:`@forinda/kickjs-queue`,peers:[`amqplib`],description:`Queue with RabbitMQ`},"queue:kafka":{pkg:`@forinda/kickjs-queue`,peers:[`kafkajs`],description:`Queue with Kafka`},mcp:{pkg:`@forinda/kickjs-mcp`,peers:[`@modelcontextprotocol/sdk`],description:`Model Context Protocol server — expose @Controller endpoints as AI tools`},testing:{pkg:`@forinda/kickjs-testing`,peers:[],description:`Test utilities and TestModule builder`,dev:!0}};function Bt(e,t=process.cwd()){let n=t;for(;;){if(r(v(n,e)))return n;let t=f(n);if(t===n)return null;n=t}}function Vt(){return Bt(`pnpm-lock.yaml`)?`pnpm`:Bt(`yarn.lock`)?`yarn`:Bt(`bun.lockb`)||Bt(`bun.lock`)?`bun`:Bt(`package-lock.json`)?`npm`:null}function Ht(){let e=process.cwd();for(;e;){let t=v(e,`package.json`);if(r(t))try{let e=JSON.parse(a(t,`utf-8`)).packageManager;if(typeof e==`string`){let t=e.split(`@`)[0];if(Ne.includes(t))return t}}catch{}let n=f(e);if(n===e)return null;e=n}return null}async function Ut(e){if(e&&Ne.includes(e))return{pm:e,source:`flag`};let t=await k(process.cwd());if(t?.packageManager&&Ne.includes(t.packageManager))return{pm:t.packageManager,source:`config`};let n=Ht();if(n)return{pm:n,source:`package.json`};let r=Vt();return r?{pm:r,source:`lockfile`}:{pm:`npm`,source:`default`}}async function Wt(e){let{pm:t}=await Ut(e);return t}function Gt(e=!1){let t=Object.entries(zt),n=Math.max(...t.map(([e])=>e.length)),r=t.filter(([,e])=>e.core),i=t.filter(([,e])=>!e.core),a=([e,t])=>{let r=e.padEnd(n+2),i=t.peers.length?` (+ ${t.peers.join(`, `)})`:``;return` ${r} ${t.description}${i}`};console.log(`
1408
1408
  Core packages (always installed by \`kick new\`):
1409
1409
  `);for(let e of r)console.log(a(e));if(e){console.log(`
@@ -1411,7 +1411,7 @@ in \`.agents/COPILOT.local.md\`.
1411
1411
  `);for(let e of i)console.log(a(e))}else console.log(`\n Plus ${i.length} optional packages (auth, swagger, db, queue, …).`),console.log(" Run `kick add --list --all` for the full catalog.");console.log(`
1412
1412
  Usage: kick add auth drizzle swagger`),console.log(` kick add queue:bullmq`),console.log()}function Kt(e){e.command(`list`).alias(`ls`).description(`List KickJS packages (core only; pair with --all for the full catalog)`).option(`--all`,`Include the full optional catalog`).action(e=>{Gt(!!e.all)})}function qt(e){e.command(`add [packages...]`).description(`Add KickJS packages with their required dependencies`).option(`--pm <manager>`,`Package manager override`).option(`-D, --dev`,`Install as dev dependency`).option(`--list`,`List packages (core only by default; pair with --all)`).option(`--all`,`When listing, include the full optional catalog`).action(async(e,t)=>{if(t.list||e.length===0){Gt(!!t.all);return}let{pm:n,source:r}=await Ut(t.pm);console.log(`\n Using ${n} (resolved from ${r})`);let i=t.dev,a=new Set,o=new Set,s=[];for(let t of e){let e=zt[t];if(!e){s.push(t);continue}let n=i||e.dev?o:a;n.add(e.pkg);for(let t of e.peers)n.add(t)}if(!(s.length>0&&(console.log(`\n Unknown packages: ${s.join(`, `)}`),console.log(` Run "kick add --list" to see available packages.
1413
1413
  `),a.size===0&&o.size===0))){if(a.size>0){let e=Array.from(a),t=`${n} add ${e.join(` `)}`;console.log(`\n Installing ${e.length} dependency(ies):`);for(let t of e)console.log(` + ${t}`);console.log();try{S(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}if(o.size>0){let e=Array.from(o),t=`${n} add -D ${e.join(` `)}`;console.log(`\n Installing ${e.length} dev dependency(ies):`);for(let t of e)console.log(` + ${t} (dev)`);console.log();try{S(t,{stdio:`inherit`})}catch{console.log(`\n Installation failed. Run manually:\n ${t}\n`)}}console.log(` Done!
1414
- `)}})}const Jt=[{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 Yt(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 | ddd | cqrs | minimal`).option(`-r, --repo <type>`,`Default repository: prisma | drizzle | inmemory | custom`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. auth,swagger,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)=>{Mt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await Ft({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let i;if(e===`.`?(i=v(`.`),e=d(i)):i=v(t.directory||e),r(i)){let r=o(i);if(r.length>0){if(t.force)F.warn(`Clearing existing files in ${i}`);else if(n){F.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),Nt(`Aborted.`);return}else{F.warn(`Directory "${e}" is not empty:`);let t=r.slice(0,5);for(let e of t)F.message(` - ${e}`);if(r.length>5&&F.message(` ... and ${r.length-5} more`),!await P({message:E.red(`Remove all existing files and proceed?`),initialValue:!1})){Nt(`Aborted.`);return}}for(let e of r)s(v(i,e),{recursive:!0,force:!0})}}let a=t.template;a||=n?`minimal`:await It({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`ddd`,label:`DDD`,hint:`Domain-Driven Design modules`},{value:`cqrs`,label:`CQRS`,hint:`Commands, Queries, Events + WS/Queue`},{value:`minimal`,label:`Minimal`,hint:`bare Express`}]});let c=t.pm;c||=n?await Wt(void 0):await It({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let l=t.repo;l||(n?l=`inmemory`:(l=await It({message:`Default repository/ORM`,options:[{value:`prisma`,label:`Prisma`},{value:`drizzle`,label:`Drizzle`},{value:`inmemory`,label:`In-Memory`},{value:`custom`,label:`Custom`,hint:`specify later`}]}),l===`custom`&&(l=await Ft({message:`Custom repository name`,defaultValue:`custom`}))));let u;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();u=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else u=n?[]:await Lt({message:`Select packages to include`,options:[...Jt],required:!1});let f;f=t.git===void 0?n?!0:await P({message:`Initialize git repository?`,initialValue:!0}):t.git;let p;p=t.install===void 0?n?!0:await P({message:`Install dependencies?`,initialValue:!0}):t.install,await Ot({name:e,directory:i,packageManager:c,initGit:f,installDeps:p,template:a,defaultRepo:l,packages:u}),Nt(`Done! Next steps: ${E.cyan(`cd ${e} && ${c} dev`)}`)})}function I(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function L(e){let t=I(e);return t.charAt(0).toLowerCase()+t.slice(1)}function R(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function z(e){return de.plural(e)}function Xt(e){return de.plural(e)}function Zt(e){return R(e).replace(/-/g,`_`)}function Qt(e){let t=e.cwd??process.cwd(),n=e.pluralize??!0,r=I(e.name),i=L(e.name),a=R(e.name),o=Zt(e.name),s={name:e.name,pascal:r,camel:i,kebab:a,snake:o,modulesDir:e.modulesDir??`src/modules`,cwd:t,args:e.args??[],flags:e.flags??{}};if(n){let e=z(a);s.pluralKebab=e,s.pluralPascal=I(e),s.pluralCamel=L(e)}return s}function $t(e,t){return v(e.cwd,t)}async function en(e){return import(x(e).href)}const tn=new Map;async function nn(e){let t=tn.get(e);if(t)return t;let n=rn(e);return tn.set(e,n),n}async function rn(t){let n=v(t,`package.json`);if(!r(n))return{generators:[],loaded:[],failed:[]};let i=an(JSON.parse(await C(n,`utf-8`))),a=e(v(t,`package.json`)),o=[],s=[],c=[];for(let e of i){let t;try{t=a.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await C(t,`utf-8`))}catch(t){c.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let i=n.kickjs.generators,l=v(f(t),i);if(!r(l)){c.push({source:e,reason:`kickjs.generators points to missing file: ${i}`});continue}let u;try{u=await en(l)}catch(t){c.push({source:e,reason:`failed to import manifest: ${t}`});continue}let d=u.default;if(!Array.isArray(d)){c.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of d){if(!on(t)){c.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}o.push({source:e,spec:t})}s.push(e)}return{generators:o,loaded:s,failed:c}}function an(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function on(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function sn(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return un(r.spec,r.source,e,n);let i=ln(await nn(n),e.generatorName);return i?un(i.spec,i.source,e,n):null}async function cn(e,t=[]){let n=await nn(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function ln(e,t){return e.generators.find(e=>e.spec.name===t)}async function un(e,t,n,r){let i=Qt({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r}),a=await e.files(i),o=[];for(let e of a){let t=$t(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function B(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const dn={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function fn(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function pn(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function mn(e){return dn[e]??fn(e)}function hn(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${fn(n)}${e}Repository`,repoFile:i[n]??`${pn(n)}-${t}`}}function gn(e){return e??`define`}function _n(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=hn(t,n,i),c=gn(a),l=`/**
1414
+ `)}})}const Jt=[{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 Yt(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 | ddd | cqrs | minimal`).option(`-r, --repo <type>`,`Default repository: prisma | drizzle | inmemory | custom`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. auth,swagger,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)=>{Mt(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await Ft({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let i;if(e===`.`?(i=v(`.`),e=d(i)):i=v(t.directory||e),r(i)){let r=o(i);if(r.length>0){if(t.force)F.warn(`Clearing existing files in ${i}`);else if(n){F.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),Nt(`Aborted.`);return}else{F.warn(`Directory "${e}" is not empty:`);let t=r.slice(0,5);for(let e of t)F.message(` - ${e}`);if(r.length>5&&F.message(` ... and ${r.length-5} more`),!await P({message:E.red(`Remove all existing files and proceed?`),initialValue:!1})){Nt(`Aborted.`);return}}for(let e of r)s(v(i,e),{recursive:!0,force:!0})}}let a=t.template;a||=n?`minimal`:await It({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`ddd`,label:`DDD`,hint:`Domain-Driven Design modules`},{value:`cqrs`,label:`CQRS`,hint:`Commands, Queries, Events + WS/Queue`},{value:`minimal`,label:`Minimal`,hint:`bare Express`}]});let c=t.pm;c||=n?await Wt(void 0):await It({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let l=t.repo;l||(n?l=`inmemory`:(l=await It({message:`Default repository/ORM`,options:[{value:`prisma`,label:`Prisma`},{value:`drizzle`,label:`Drizzle`},{value:`inmemory`,label:`In-Memory`},{value:`custom`,label:`Custom`,hint:`specify later`}]}),l===`custom`&&(l=await Ft({message:`Custom repository name`,defaultValue:`custom`}))));let u;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();u=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else u=n?[]:await Lt({message:`Select packages to include`,options:[...Jt],required:!1});let f;f=t.git===void 0?n?!0:await P({message:`Initialize git repository?`,initialValue:!0}):t.git;let p;p=t.install===void 0?n?!0:await P({message:`Install dependencies?`,initialValue:!0}):t.install,await Ot({name:e,directory:i,packageManager:c,initGit:f,installDeps:p,template:a,defaultRepo:l,packages:u}),Nt(`Done! Next steps: ${E.cyan(`cd ${e} && ${c} dev`)}`)})}function I(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function L(e){let t=I(e);return t.charAt(0).toLowerCase()+t.slice(1)}function R(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function z(e){return de.plural(e)}function Xt(e){return de.plural(e)}var Zt=D({findProjectRoot:()=>$t});const Qt=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];function $t(e=process.cwd()){let t=v(e),{root:n}=g(t),i=null,a=t;for(;;){for(let e of Qt)if(r(v(a,e)))return a;if(i===null&&r(v(a,`package.json`))&&(i=a),a===n)break;let e=f(a);if(e===a)break;a=e}return i??t}function en(e){return R(e).replace(/-/g,`_`)}function tn(e){let t=e.cwd??process.cwd(),n=e.projectRoot??$t(t),r=e.pluralize??!0,i=I(e.name),a=L(e.name),o=R(e.name),s=en(e.name),c={name:e.name,pascal:i,camel:a,kebab:o,snake:s,modulesDir:e.modulesDir??`src/modules`,cwd:t,projectRoot:n,args:e.args??[],flags:e.flags??{}};if(r){let e=z(o);c.pluralKebab=e,c.pluralPascal=I(e),c.pluralCamel=L(e)}return c}function nn(e,t){return v(e.cwd,t)}async function rn(e){return import(x(e).href)}const an=new Map;async function on(e){let t=an.get(e);if(t)return t;let n=sn(e);return an.set(e,n),n}async function sn(t){let n=v(t,`package.json`);if(!r(n))return{generators:[],loaded:[],failed:[]};let i=cn(JSON.parse(await C(n,`utf-8`))),a=e(v(t,`package.json`)),o=[],s=[],c=[];for(let e of i){let t;try{t=a.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await C(t,`utf-8`))}catch(t){c.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let i=n.kickjs.generators,l=v(f(t),i);if(!r(l)){c.push({source:e,reason:`kickjs.generators points to missing file: ${i}`});continue}let u;try{u=await rn(l)}catch(t){c.push({source:e,reason:`failed to import manifest: ${t}`});continue}let d=u.default;if(!Array.isArray(d)){c.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of d){if(!ln(t)){c.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}o.push({source:e,spec:t})}s.push(e)}return{generators:o,loaded:s,failed:c}}function cn(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function ln(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function un(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return pn(r.spec,r.source,e,n);let i=fn(await on(n),e.generatorName);return i?pn(i.spec,i.source,e,n):null}async function dn(e,t=[]){let n=await on(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function fn(e,t){return e.generators.find(e=>e.spec.name===t)}async function pn(e,t,n,r){let i=tn({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r,projectRoot:n.projectRoot}),a=await e.files(i),o=[];for(let e of a){let t=nn(i,e.path);await M(t,e.content),o.push(t)}return{files:o,source:t}}function B(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const mn={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function hn(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function gn(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function _n(e){return mn[e]??hn(e)}function vn(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${hn(n)}${e}Repository`,repoFile:i[n]??`${gn(n)}-${t}`}}function yn(e){return e??`define`}function bn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=vn(t,n,i),c=yn(a),l=`/**
1415
1415
  * ${t} Module
1416
1416
  *
1417
1417
  * Self-contained feature module following Domain-Driven Design (DDD).
@@ -1421,7 +1421,7 @@ in \`.agents/COPILOT.local.md\`.
1421
1421
  * presentation/ — HTTP controllers (entry points)
1422
1422
  * application/ — Use cases (orchestration) and DTOs (validation)
1423
1423
  * domain/ — Entities, value objects, repository interfaces, domain services
1424
- * infrastructure/ — Repository implementations (currently ${mn(i)})
1424
+ * infrastructure/ — Repository implementations (currently ${_n(i)})
1425
1425
  */`,u=`import { ${t.toUpperCase()}_REPOSITORY } from './domain/repositories/${n}.repository'
1426
1426
  import { ${o} } from './infrastructure/repositories/${s}.repository'
1427
1427
  import { ${t}Controller } from './presentation/${n}.controller'
@@ -1455,7 +1455,7 @@ export class ${t}Module implements AppModule {
1455
1455
  /**
1456
1456
  * Register module dependencies in the DI container.
1457
1457
  * Bind repository interface tokens to their implementations here.
1458
- * Currently wired to ${mn(i)}. To swap implementations, change the factory target.
1458
+ * Currently wired to ${_n(i)}. To swap implementations, change the factory target.
1459
1459
  */
1460
1460
  register(container: Container): void {
1461
1461
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1481,7 +1481,7 @@ export const ${t}Module = defineModule({
1481
1481
  /**
1482
1482
  * Register module dependencies in the DI container.
1483
1483
  * Bind repository interface tokens to their implementations here.
1484
- * Currently wired to ${mn(i)}. To swap implementations, change the factory target.
1484
+ * Currently wired to ${_n(i)}. To swap implementations, change the factory target.
1485
1485
  */
1486
1486
  register(container) {
1487
1487
  container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
@@ -1498,7 +1498,7 @@ ${d}
1498
1498
  },
1499
1499
  }),
1500
1500
  })
1501
- `}function vn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=hn(t,n,i),c=gn(a),l=`/**
1501
+ `}function xn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=vn(t,n,i),c=yn(a),l=`/**
1502
1502
  * ${t} Module
1503
1503
  *
1504
1504
  * REST module with a flat folder structure.
@@ -1570,7 +1570,7 @@ ${d}
1570
1570
  },
1571
1571
  }),
1572
1572
  })
1573
- `}function yn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=gn(i),o=` /**
1573
+ `}function Sn(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=yn(i),o=` /**
1574
1574
  * Declare HTTP routes. Return value shape:
1575
1575
  *
1576
1576
  * - \`path\` — URL prefix for this route set.
@@ -1610,7 +1610,7 @@ ${o}
1610
1610
  },
1611
1611
  }),
1612
1612
  })
1613
- `}function bn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1613
+ `}function Cn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1614
1614
  import { ApiTags } from '@forinda/kickjs-swagger'
1615
1615
  import { Create${t}UseCase } from '../application/use-cases/create-${n}.use-case'
1616
1616
  import { Get${t}UseCase } from '../application/use-cases/get-${n}.use-case'
@@ -1673,7 +1673,7 @@ export class ${t}Controller {
1673
1673
  ctx.noContent()
1674
1674
  }
1675
1675
  }
1676
- `}function xn(e){let{pascal:t,kebab:n}=e,r=t.charAt(0).toLowerCase()+t.slice(1);return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1676
+ `}function wn(e){let{pascal:t,kebab:n}=e,r=t.charAt(0).toLowerCase()+t.slice(1);return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
1677
1677
  import { ApiTags } from '@forinda/kickjs-swagger'
1678
1678
  import { ${t}Service } from './${n}.service'
1679
1679
  import { create${t}Schema } from './dtos/create-${n}.dto'
@@ -1728,14 +1728,14 @@ export class ${t}Controller {
1728
1728
  ctx.noContent()
1729
1729
  }
1730
1730
  }
1731
- `}function Sn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1731
+ `}function Tn(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
1732
1732
 
1733
1733
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryParamsConfig = {
1734
1734
  filterable: ['name'],
1735
1735
  sortable: ['name', 'createdAt'],
1736
1736
  searchable: ['name'],
1737
1737
  }
1738
- `}function Cn(e){let{pascal:t}=e;return`import { z } from 'zod'
1738
+ `}function En(e){let{pascal:t}=e;return`import { z } from 'zod'
1739
1739
 
1740
1740
  /**
1741
1741
  * Create ${t} DTO — Zod schema for validating POST request bodies.
@@ -1751,20 +1751,20 @@ export const create${t}Schema = z.object({
1751
1751
  })
1752
1752
 
1753
1753
  export type Create${t}DTO = z.infer<typeof create${t}Schema>
1754
- `}function wn(e){let{pascal:t}=e;return`import { z } from 'zod'
1754
+ `}function Dn(e){let{pascal:t}=e;return`import { z } from 'zod'
1755
1755
 
1756
1756
  export const update${t}Schema = z.object({
1757
1757
  name: z.string().min(1).max(200).optional(),
1758
1758
  })
1759
1759
 
1760
1760
  export type Update${t}DTO = z.infer<typeof update${t}Schema>
1761
- `}function Tn(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1761
+ `}function On(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
1762
1762
  id: string
1763
1763
  name: string
1764
1764
  createdAt: string
1765
1765
  updatedAt: string
1766
1766
  }
1767
- `}function En(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1767
+ `}function kn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
1768
1768
  * Create ${t} Use Case
1769
1769
  *
1770
1770
  * Application layer — orchestrates a single business operation.
@@ -1842,7 +1842,7 @@ export class Delete${t}UseCase {
1842
1842
  await this.repo.delete(id)
1843
1843
  }
1844
1844
  }
1845
- `}]}function Dn(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1845
+ `}]}function An(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
1846
1846
  * ${t} Repository Interface
1847
1847
  *
1848
1848
  * Defines the contract for data access.
@@ -1937,7 +1937,7 @@ export class InMemory${t}Repository implements I${t}Repository {
1937
1937
  this.store.delete(id)
1938
1938
  }
1939
1939
  }
1940
- `}function On(e){let{pascal:t,kebab:n,repoType:r=``,repoPrefix:i=`../../domain/repositories`,dtoPrefix:a=`../../application/dtos`}=e,o=r.charAt(0).toUpperCase()+r.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
1940
+ `}function jn(e){let{pascal:t,kebab:n,repoType:r=``,repoPrefix:i=`../../domain/repositories`,dtoPrefix:a=`../../application/dtos`}=e,o=r.charAt(0).toUpperCase()+r.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
1941
1941
  * ${o} ${t} Repository
1942
1942
  *
1943
1943
  * Stub implementation for a custom '${r}' repository.
@@ -2006,7 +2006,7 @@ export class ${o}${t}Repository implements I${t}Repository {
2006
2006
  this.store.delete(id)
2007
2007
  }
2008
2008
  }
2009
- `}function kn(e){let{pascal:t,kebab:n}=e;return`/**
2009
+ `}function Mn(e){let{pascal:t,kebab:n}=e;return`/**
2010
2010
  * ${t} Domain Service
2011
2011
  *
2012
2012
  * Domain layer — contains business rules that don't belong to a single entity.
@@ -2029,7 +2029,7 @@ export class ${t}DomainService {
2029
2029
  }
2030
2030
  }
2031
2031
  }
2032
- `}function An(e){let{pascal:t,kebab:n}=e;return`/**
2032
+ `}function Nn(e){let{pascal:t,kebab:n}=e;return`/**
2033
2033
  * ${t} Entity
2034
2034
  *
2035
2035
  * Domain layer — the core business object.
@@ -2098,7 +2098,7 @@ export class ${t} {
2098
2098
  }
2099
2099
  }
2100
2100
  }
2101
- `}function jn(e){let{pascal:t}=e;return`/**
2101
+ `}function Pn(e){let{pascal:t}=e;return`/**
2102
2102
  * ${t} ID Value Object
2103
2103
  *
2104
2104
  * Domain layer — wraps a primitive ID with type safety and validation.
@@ -2132,7 +2132,7 @@ export class ${t}Id {
2132
2132
  return this.value === other.value
2133
2133
  }
2134
2134
  }
2135
- `}function Mn(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
2135
+ `}function Fn(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
2136
2136
  import { Container } from '@forinda/kickjs'
2137
2137
 
2138
2138
  describe('${t}Controller', () => {
@@ -2184,7 +2184,7 @@ describe('${t}Controller', () => {
2184
2184
  })
2185
2185
  })
2186
2186
  })
2187
- `}function Nn(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
2187
+ `}function In(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
2188
2188
  import { InMemory${t}Repository } from '${i}'
2189
2189
 
2190
2190
  describe('InMemory${t}Repository', () => {
@@ -2246,7 +2246,7 @@ describe('InMemory${t}Repository', () => {
2246
2246
  expect(found).toBeNull()
2247
2247
  })
2248
2248
  })
2249
- `}function Pn(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2249
+ `}function Ln(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
2250
2250
  import type { ParsedQuery } from '@forinda/kickjs'
2251
2251
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from './${n}.repository'
2252
2252
  import type { ${t}ResponseDTO } from './dtos/${n}-response.dto'
@@ -2283,14 +2283,14 @@ export class ${t}Service {
2283
2283
  await this.repo.delete(id)
2284
2284
  }
2285
2285
  }
2286
- `}function Fn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2286
+ `}function Rn(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
2287
2287
 
2288
2288
  export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
2289
2289
  filterable: ['name'],
2290
2290
  sortable: ['name', 'createdAt'],
2291
2291
  searchable: ['name'],
2292
2292
  }
2293
- `}function In(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,o={inmemory:`InMemory${t}Repository`,drizzle:`Drizzle${t}Repository`,prisma:`Prisma${t}Repository`},s={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},c=o[i]??o.inmemory,l=s[i]??s.inmemory,u=a??`define`,d=`/**
2293
+ `}function zn(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,o={inmemory:`InMemory${t}Repository`,drizzle:`Drizzle${t}Repository`,prisma:`Prisma${t}Repository`},s={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},c=o[i]??o.inmemory,l=s[i]??s.inmemory,u=a??`define`,d=`/**
2294
2294
  * ${t} Module — CQRS Pattern
2295
2295
  *
2296
2296
  * Separates read (queries) and write (commands) operations.
@@ -2369,7 +2369,7 @@ ${p}
2369
2369
  },
2370
2370
  }),
2371
2371
  })
2372
- `}function Ln(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
2372
+ `}function Bn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
2373
2373
  import { ApiTags } from '@forinda/kickjs-swagger'
2374
2374
  import { Create${t}Command } from './commands/create-${n}.command'
2375
2375
  import { Update${t}Command } from './commands/update-${n}.command'
@@ -2432,7 +2432,7 @@ export class ${t}Controller {
2432
2432
  ctx.noContent()
2433
2433
  }
2434
2434
  }
2435
- `}function Rn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2435
+ `}function Vn(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2436
2436
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2437
2437
  import type { Create${t}DTO } from '../dtos/create-${n}.dto'
2438
2438
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
@@ -2486,7 +2486,7 @@ export class Delete${t}Command {
2486
2486
  this.events.emit('${n}.deleted', { id })
2487
2487
  }
2488
2488
  }
2489
- `}]}function zn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2489
+ `}]}function Hn(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
2490
2490
  import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
2491
2491
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2492
2492
 
@@ -2514,7 +2514,7 @@ export class List${i}Query {
2514
2514
  return this.repo.findPaginated(parsed)
2515
2515
  }
2516
2516
  }
2517
- `}]}function Bn(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2517
+ `}]}function Un(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
2518
2518
  import { EventEmitter } from 'node:events'
2519
2519
  import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
2520
2520
 
@@ -2600,7 +2600,7 @@ export class On${t}ChangeHandler {
2600
2600
  })
2601
2601
  }
2602
2602
  }
2603
- `}]}function Vn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2603
+ `}]}function Wn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
2604
2604
  * Drizzle ${t} Repository
2605
2605
  *
2606
2606
  * Implements the repository interface using Drizzle ORM.
@@ -2682,7 +2682,7 @@ export class Drizzle${t}Repository implements I${t}Repository {
2682
2682
  throw new Error('Drizzle ${t} repository not yet implemented')
2683
2683
  }
2684
2684
  }
2685
- `}function Hn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2685
+ `}function Gn(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
2686
2686
  // TODO: Import your schema table and reference actual columns for type safety
2687
2687
  // import { ${n}s } from '@/db/schema'
2688
2688
 
@@ -2700,7 +2700,7 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: DrizzleQueryParamsConfig = {
2700
2700
  // ${n}s.name,
2701
2701
  ],
2702
2702
  }
2703
- `}function Un(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e,a=n.replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
2703
+ `}function Kn(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e,a=n.replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
2704
2704
  * Prisma ${t} Repository
2705
2705
  *
2706
2706
  * Implements the repository interface using Prisma Client.
@@ -2758,7 +2758,7 @@ export class Prisma${t}Repository implements I${t}Repository {
2758
2758
  await this.prisma.${a}.deleteMany({ where: { id } })
2759
2759
  }
2760
2760
  }
2761
- `}async function Wn(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,yn({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2761
+ `}async function qn(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,Sn({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
2762
2762
 
2763
2763
  // \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
2764
2764
  // \`kick typegen\` (auto-run on \`kick dev\`).
@@ -2770,7 +2770,7 @@ export class ${t}Controller {
2770
2770
  ctx.json({ message: '${t} list' })
2771
2771
  }
2772
2772
  }
2773
- `)}async function Gn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,vn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Fn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,xn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,Pn({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,Cn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,wn({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,Tn({pascal:t,kebab:n})),await u(`${n}.repository.ts`,Dn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Vn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Un({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${R(a)}-${n}`,m=f[a]??(()=>On({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${p}.repository.ts`,m()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Mn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,Nn({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function Kn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,In({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Fn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Ln({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,Cn({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,wn({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,Tn({pascal:t,kebab:n}));let d=Rn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=zn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=Bn({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,Dn({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Vn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Un({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${R(a)}-${n}`,_=h[a]??(()=>On({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Mn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,Nn({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function qn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noEntity:o,noTests:s,prismaClientPath:c,tokenScope:l,style:u,write:d}=e;await d(`${n}.module.ts`,_n({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Hn({pascal:t,kebab:n}):Sn({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,bn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,Cn({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,wn({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,Tn({pascal:t,kebab:n}));let f=En({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await d(`application/use-cases/${e.file}`,e.content);await d(`domain/repositories/${n}.repository.ts`,Dn({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,kn({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>V({pascal:t,kebab:n}),drizzle:()=>Vn({pascal:t,kebab:n}),prisma:()=>Un({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${R(a)}-${n}`,g=m[a]??(()=>On({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,An({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,jn({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,V({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,Mn({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,Nn({pascal:t,kebab:n,plural:r})))}function Jn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Yn(e){let{name:t,modulesDir:n,noEntity:r,noTests:i,repo:a=`inmemory`,force:o,dryRun:s}=e,c=e.pluralize!==!1,l=e.pattern??`ddd`;e.minimal&&(l=`minimal`);let u=R(t),d=I(t),f=c?z(u):u,p=c?Xt(d):d,m=h(n,f),g=[],_=o??!1,v={kebab:u,pascal:d,plural:f,pluralPascal:p,moduleDir:m,repo:a,noEntity:r??!1,noTests:i??!1,prismaClientPath:e.prismaClientPath??`@prisma/client`,tokenScope:e.tokenScope??`app`,style:e.style??`define`,write:async(e,t)=>{let n=h(m,e);if(s){g.push(n);return}if(!_&&await Xe(n)&&!await P({message:`File exists: ${E.dim(e)}. Overwrite?`,initialValue:!1})){F.warn(`Skipped: ${e}`);return}await M(n,t),g.push(n)},files:g};switch(l){case`minimal`:await Wn(v);break;case`rest`:await Gn(v);break;case`cqrs`:await Kn(v);break;default:await qn(v);break}return s||await Xn(n,d,f,u,v.style),g}async function Xn(e,t,n,r,i=`define`){let a=h(e,`index.ts`),o=await Xe(a),s=`./${n}/${r}.module`,c=i===`class`?`${t}Module`:`${t}Module()`;if(!o){await M(a,i===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
2773
+ `)}async function Jn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,xn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Rn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,wn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,Ln({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,En({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,On({pascal:t,kebab:n})),await u(`${n}.repository.ts`,An({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Wn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Kn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${R(a)}-${n}`,m=f[a]??(()=>jn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${p}.repository.ts`,m()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Fn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,In({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function Yn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,zn({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,Rn({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Bn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,En({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,On({pascal:t,kebab:n}));let d=Vn({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=Hn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=Un({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,An({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>Wn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>Kn({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${R(a)}-${n}`,_=h[a]??(()=>jn({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,V({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,Fn({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,In({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Xn(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noEntity:o,noTests:s,prismaClientPath:c,tokenScope:l,style:u,write:d}=e;await d(`${n}.module.ts`,bn({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Gn({pascal:t,kebab:n}):Tn({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,Cn({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,En({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,Dn({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,On({pascal:t,kebab:n}));let f=kn({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await d(`application/use-cases/${e.file}`,e.content);await d(`domain/repositories/${n}.repository.ts`,An({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,Mn({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>V({pascal:t,kebab:n}),drizzle:()=>Wn({pascal:t,kebab:n}),prisma:()=>Kn({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${R(a)}-${n}`,g=m[a]??(()=>jn({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,Nn({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,Pn({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,V({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,Fn({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,In({pascal:t,kebab:n,plural:r})))}function Zn(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Qn(e){let{name:t,modulesDir:n,noEntity:r,noTests:i,repo:a=`inmemory`,force:o,dryRun:s}=e,c=e.pluralize!==!1,l=e.pattern??`ddd`;e.minimal&&(l=`minimal`);let u=R(t),d=I(t),f=c?z(u):u,p=c?Xt(d):d,m=h(n,f),g=[],_=o??!1,v={kebab:u,pascal:d,plural:f,pluralPascal:p,moduleDir:m,repo:a,noEntity:r??!1,noTests:i??!1,prismaClientPath:e.prismaClientPath??`@prisma/client`,tokenScope:e.tokenScope??`app`,style:e.style??`define`,write:async(e,t)=>{let n=h(m,e);if(s){g.push(n);return}if(!_&&await Xe(n)&&!await P({message:`File exists: ${E.dim(e)}. Overwrite?`,initialValue:!1})){F.warn(`Skipped: ${e}`);return}await M(n,t),g.push(n)},files:g};switch(l){case`minimal`:await qn(v);break;case`rest`:await Jn(v);break;case`cqrs`:await Yn(v);break;default:await Xn(v);break}return s||await $n(n,d,f,u,v.style),g}async function $n(e,t,n,r,i=`define`){let a=h(e,`index.ts`),o=await Xe(a),s=`./${n}/${r}.module`,c=i===`class`?`${t}Module`:`${t}Module()`;if(!o){await M(a,i===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
2774
2774
  import { ${t}Module } from '${s}'
2775
2775
 
2776
2776
  export const modules: AppModuleEntry[] = [${c}]
@@ -2781,8 +2781,8 @@ export const modules = defineModules().mount(${c})
2781
2781
  `);return}let l=await C(a,`utf-8`),u=`import { ${t}Module } from '${s}'`,d=B(s);if(!RegExp(`^import\\s*\\{[^}]*\\b${B(t)}Module\\b[^}]*\\}\\s*from\\s*['"]${d}['"]`,`m`).test(l)){let e=l.lastIndexOf(`import `);if(e!==-1){let t=l.indexOf(`
2782
2782
  `,e);l=l.slice(0,t+1)+u+`
2783
2783
  `+l.slice(t+1)}else l=u+`
2784
- `+l}let f=Qn(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${B(t)}Module\\b`).test(e)||(l=Zn(l,c))}else l=Zn(l,c);await w(a,l,`utf-8`)}function Zn(e,t){let n=Qn(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function Qn(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=tr(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=$n(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function $n(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=nr(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=nr(e,t);if(n===-1)break;i=n+1}return i}function er(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2785
- `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function tr(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=er(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function nr(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=er(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function rr(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.adapter.ts`);return await M(o,`import {
2784
+ `+l}let f=tr(l);if(f){let e=l.slice(f.rhsStart,f.rhsEnd+1);RegExp(`\\b${B(t)}Module\\b`).test(e)||(l=er(l,c))}else l=er(l,c);await w(a,l,`utf-8`)}function er(e,t){let n=tr(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function tr(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=ir(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=nr(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function nr(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=ar(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=ar(e,t);if(n===-1)break;i=n+1}return i}function rr(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
2785
+ `;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function ir(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=rr(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function ar(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=rr(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function or(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.adapter.ts`);return await M(o,`import {
2786
2786
  defineAdapter,
2787
2787
  type AdapterContext,
2788
2788
  type AdapterMiddleware,
@@ -2951,7 +2951,7 @@ export const ${i}Adapter = defineAdapter<${i}AdapterConfig>({
2951
2951
  }
2952
2952
  },
2953
2953
  })
2954
- `),a.push(o),a}async function ir(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.plugin.ts`);return await M(o,`import {
2954
+ `),a.push(o),a}async function sr(e){let{name:t,outDir:n}=e,r=R(t),i=I(t),a=[],o=h(n,`${r}.plugin.ts`);return await M(o,`import {
2955
2955
  definePlugin,
2956
2956
  type AppAdapter,
2957
2957
  type AppModuleEntry,
@@ -3095,7 +3095,7 @@ export const ${i}Plugin = definePlugin<${i}PluginConfig>({
3095
3095
  },
3096
3096
  }),
3097
3097
  })
3098
- `),a.push(o),a}const ar={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},or={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},sr={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function cr(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return v(n);if(r){let e=o===`ddd`?ar:o===`cqrs`?sr:or,n=R(r),a=s?z(n):n,c=e[t]??``,l=h(i,a);return v(c?h(l,c):l)}return v(a)}async function lr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=cr({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/middleware`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=[],l=h(a,`${o}.middleware.ts`);return await M(l,`import type { Request, Response, NextFunction } from 'express'
3098
+ `),a.push(o),a}const cr={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},lr={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},ur={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function dr(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return v(n);if(r){let e=o===`ddd`?cr:o===`cqrs`?ur:lr,n=R(r),a=s?z(n):n,c=e[t]??``,l=h(i,a);return v(c?h(l,c):l)}return v(a)}async function fr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/middleware`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=[],l=h(a,`${o}.middleware.ts`);return await M(l,`import type { Request, Response, NextFunction } from 'express'
3099
3099
 
3100
3100
  export interface ${I(t)}Options {
3101
3101
  // Add configuration options here. The factory below closes over the
@@ -3145,7 +3145,7 @@ export function ${s}(options: ${I(t)}Options = {}) {
3145
3145
  next()
3146
3146
  }
3147
3147
  }
3148
- `),c.push(l),c}async function ur(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=cr({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/guards`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=I(t),l=[],u=h(a,`${o}.guard.ts`);return await M(u,`import { Container, HttpException } from '@forinda/kickjs'
3148
+ `),c.push(l),c}async function pr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/guards`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=L(t),c=I(t),l=[],u=h(a,`${o}.guard.ts`);return await M(u,`import { Container, HttpException } from '@forinda/kickjs'
3149
3149
  import type { RequestContext } from '@forinda/kickjs'
3150
3150
 
3151
3151
  /**
@@ -3181,7 +3181,7 @@ export async function ${s}Guard(ctx: RequestContext, next: () => void): Promise<
3181
3181
  ctx.res.status(401).json({ message: 'Invalid or expired token' })
3182
3182
  }
3183
3183
  }
3184
- `),l.push(u),l}async function dr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=cr({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/services`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.service.ts`);return await M(l,`import { Service } from '@forinda/kickjs'
3184
+ `),l.push(u),l}async function mr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/services`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.service.ts`);return await M(l,`import { Service } from '@forinda/kickjs'
3185
3185
 
3186
3186
  @Service()
3187
3187
  export class ${s}Service {
@@ -3190,7 +3190,7 @@ export class ${s}Service {
3190
3190
  // @Inject(MY_REPO) private readonly repo: IMyRepository,
3191
3191
  // ) {}
3192
3192
  }
3193
- `),c.push(l),c}async function fr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=cr({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/controllers`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.controller.ts`);return await M(l,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
3193
+ `),c.push(l),c}async function hr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/controllers`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=[],l=h(a,`${o}.controller.ts`);return await M(l,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
3194
3194
 
3195
3195
  // \`Ctx<KickRoutes.${s}Controller['<method>']>\` is generated by
3196
3196
  // \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
@@ -3211,7 +3211,7 @@ export class ${s}Controller {
3211
3211
  ctx.created({ message: '${s} created', data: ctx.body })
3212
3212
  }
3213
3213
  }
3214
- `),c.push(l),c}async function pr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=cr({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/dtos`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=L(t),l=[],u=h(a,`${o}.dto.ts`);return await M(u,`import { z } from 'zod'
3214
+ `),c.push(l),c}async function gr(e){let{name:t,moduleName:n,modulesDir:r,pattern:i}=e,a=dr({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:r,defaultDir:`src/dtos`,pattern:i,shouldPluralize:e.pluralize??!0}),o=R(t),s=I(t),c=L(t),l=[],u=h(a,`${o}.dto.ts`);return await M(u,`import { z } from 'zod'
3215
3215
 
3216
3216
  export const ${c}Schema = z.object({
3217
3217
  // Define your schema fields here
@@ -3219,7 +3219,7 @@ export const ${c}Schema = z.object({
3219
3219
  })
3220
3220
 
3221
3221
  export type ${s}DTO = z.infer<typeof ${c}Schema>
3222
- `),l.push(u),l}async function mr(e){let t=h(e.outDir,`kick.config.ts`),n=e.modulesDir??`src/modules`,i=e.defaultRepo??`inmemory`;return r(t)&&!e.force&&!await P({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
3222
+ `),l.push(u),l}async function _r(e){let t=h(e.outDir,`kick.config.ts`),n=e.modulesDir??`src/modules`,i=e.defaultRepo??`inmemory`;return r(t)&&!e.force&&!await P({message:`kick.config.ts already exists. Overwrite?`,initialValue:!1})?(console.log(`
3223
3223
  Skipped — existing kick.config.ts preserved.`),[]):(await M(t,`import { defineConfig } from '@forinda/kickjs-cli'
3224
3224
 
3225
3225
  export default defineConfig({
@@ -3257,18 +3257,18 @@ export default defineConfig({
3257
3257
  },
3258
3258
  ],
3259
3259
  })
3260
- `),[t])}const hr=`.agents`,gr=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function _r(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function vr(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function yr(e,t){if(t)return t;try{let t=(await k(e))?.pattern;if(t&&gr.has(t))return t}catch{}return`ddd`}async function br(e){let t=e.only??`all`,n=_r(e.outDir,e.name),i=vr(e.outDir,e.pm),a=await yr(e.outDir,e.template),o=t===`agents`||t===`both`||t===`all`,s=t===`claude`||t===`both`||t===`all`,c=t===`skills`||t===`all`,l=t===`gemini`||t===`all`,u=t===`copilot`||t===`all`,d=[];if(o&&d.push({file:h(e.outDir,hr,`AGENTS.md`),render:()=>vt(n,a,i)}),s&&d.push({file:h(e.outDir,`CLAUDE.md`),render:()=>_t(n,a,i)}),c)for(let t of yt(n,a,i))d.push({file:h(e.outDir,hr,`skills`,t.slug,`SKILL.md`),render:()=>t.content});l&&d.push({file:h(e.outDir,hr,`GEMINI.md`),render:()=>xt(n,a,i)}),u&&d.push({file:h(e.outDir,hr,`COPILOT.md`),render:()=>St(n,a,i)});let f=[];for(let{file:t,render:n}of d){if(r(t)&&!e.force&&!await P({message:`${t.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})){console.log(` Skipped — existing ${t.replace(e.outDir+`/`,``)} preserved.`);continue}await M(t,n()),f.push(t)}return f}function xr(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 H(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=xr(e,r);return i===-1?null:e.slice(r+1,i)}function U(e,t,n){let r=` `.repeat(n);return e.split(`
3260
+ `),[t])}const vr=`.agents`,yr=new Set([`rest`,`ddd`,`cqrs`,`minimal`]);function br(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.name)return t.name.replace(/^@[^/]+\//,``)}catch{}return e.split(`/`).findLast(Boolean)??`app`}function xr(e,t){if(t)return t;try{let t=JSON.parse(a(h(e,`package.json`),`utf-8`));if(t.packageManager)return t.packageManager.split(`@`)[0]}catch{}return`pnpm`}async function Sr(e,t){if(t)return t;try{let t=(await k(e))?.pattern;if(t&&yr.has(t))return t}catch{}return`ddd`}async function Cr(e){let t=e.only??`all`,n=br(e.outDir,e.name),i=xr(e.outDir,e.pm),a=await Sr(e.outDir,e.template),o=t===`agents`||t===`both`||t===`all`,s=t===`claude`||t===`both`||t===`all`,c=t===`skills`||t===`all`,l=t===`gemini`||t===`all`,u=t===`copilot`||t===`all`,d=[];if(o&&d.push({file:h(e.outDir,vr,`AGENTS.md`),render:()=>vt(n,a,i)}),s&&d.push({file:h(e.outDir,`CLAUDE.md`),render:()=>_t(n,a,i)}),c)for(let t of yt(n,a,i))d.push({file:h(e.outDir,vr,`skills`,t.slug,`SKILL.md`),render:()=>t.content});l&&d.push({file:h(e.outDir,vr,`GEMINI.md`),render:()=>xt(n,a,i)}),u&&d.push({file:h(e.outDir,vr,`COPILOT.md`),render:()=>St(n,a,i)});let f=[];for(let{file:t,render:n}of d){if(r(t)&&!e.force&&!await P({message:`${t.replace(e.outDir+`/`,``)} already exists. Overwrite?`,initialValue:!1})){console.log(` Skipped — existing ${t.replace(e.outDir+`/`,``)} preserved.`);continue}await M(t,n()),f.push(t)}return f}function wr(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 H(e,t){let n=t.exec(e);if(!n)return null;let r=n.index+n[0].length-1,i=wr(e,r);return i===-1?null:e.slice(r+1,i)}function U(e,t,n){let r=` `.repeat(n);return e.split(`
3261
3261
  `).map(e=>{if(e.trim()===``)return e;let n=RegExp(`^ {0,${t}}`);return r+e.replace(n,``)}).join(`
3262
- `)}function Sr(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 Cr(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 wr(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=xr(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=H(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=H(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=H(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=Sr(s),p=``;return l&&(p+=` register(container) {${U(l,4,6)} },\n\n`),u&&(p+=` contributors() {${U(u,4,6)} },\n\n`),p+=` routes() {${U(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3262
+ `)}function Tr(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 Er(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 Dr(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=wr(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=H(o,/register\s*\(([^)]*)\)\s*:\s*void\s*\{/),u=H(o,/contributors\s*\(\s*\)\s*:\s*ContributorRegistrations\s*\{/),d=H(o,/routes\s*\(\s*\)\s*:\s*[A-Za-z|[\]\s]+\{/);if(!d)return{migrated:null,reason:`routes() method missing or signature unrecognized`};let f=Tr(s),p=``;return l&&(p+=` register(container) {${U(l,4,6)} },\n\n`),u&&(p+=` contributors() {${U(u,4,6)} },\n\n`),p+=` routes() {${U(d,4,6)} },`,{migrated:`${f}${`export const ${r} = defineModule({
3263
3263
  name: '${r}',
3264
3264
  build: () => ({
3265
3265
  ${p}
3266
3266
  }),
3267
- })`}${c}`}}function Tr(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=xr(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]===`
3268
- `||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=xr(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=H(m,/register\s*\(([^)]*)\)\s*\{/),g=H(m,/contributors\s*\(\s*\)\s*\{/),_=H(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=Cr(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${U(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${U(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${U(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3267
+ })`}${c}`}}function Or(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=wr(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]===`
3268
+ `||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=wr(s,f);if(p===-1)return{migrated:null,reason:`unbalanced build() braces`};let m=s.slice(f+1,p),h=H(m,/register\s*\(([^)]*)\)\s*\{/),g=H(m,/contributors\s*\(\s*\)\s*\{/),_=H(m,/routes\s*\(\s*\)\s*\{/);if(!_)return{migrated:null,reason:`routes() method missing inside build()`};let v=Er(c,{container:h!==null,appModule:!0,moduleRoutes:!0,contributorRegistrations:g!==null}),y=``;return h!==null&&(y+=` register(container: Container): void {${U(h,6,4)} }\n\n`),g!==null&&(y+=` contributors(): ContributorRegistrations {${U(g,6,4)} }\n\n`),y+=` routes(): ModuleRoutes {${U(_,6,4)} }`,{migrated:`${v}${`export class ${r} implements AppModule {
3269
3269
  ${y}
3270
3270
  }
3271
- `}${u}`}}function Er(e,t){return t===`class`?Tr(e):wr(e)}function Dr(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 Or(e){let t=[];return await n(v(e),0),t;async function n(e,r){let i;try{i=await se(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o;try{o=await le(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function kr(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await se(e)}catch{return}await oe(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o=h(t,a),s;try{s=await le(i)}catch{continue}s.isDirectory()?await r(i,o):(await ae(i,o),n++)}}}function Ar(e){return h(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function jr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await Or(e),s=await C(h(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Ar(r),await kr(e,c));let l=[];for(let e of o){let t=Er(await C(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await w(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=h(e,`index.ts`),d=null;try{d=await C(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=Dr(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await w(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function Mr(e,t){let n=await Or(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 C(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function Nr(e){let{name:t,outDir:n}=e,r=I(t),i=R(t),a=L(t),o=e.queue??`${i}-queue`,s=[];return await(async(e,t)=>{let r=h(n,e);await M(r,t),s.push(r)})(`${i}.job.ts`,`import { Inject } from '@forinda/kickjs'
3271
+ `}${u}`}}function kr(e,t){return t===`class`?Or(e):Dr(e)}function Ar(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 jr(e){let t=[];return await n(v(e),0),t;async function n(e,r){let i;try{i=await se(e)}catch{return}for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o;try{o=await le(i)}catch{continue}o.isDirectory()?await n(i,r+1):(a.endsWith(`.module.ts`)||a===`index.ts`&&r===1)&&t.push(i)}}}async function Mr(e,t){let n=0;return await r(e,t),n;async function r(e,t){let i;try{i=await se(e)}catch{return}await oe(t,{recursive:!0});for(let a of i){if(a===`node_modules`||a===`dist`||a===`.kickjs`)continue;let i=h(e,a),o=h(t,a),s;try{s=await le(i)}catch{continue}s.isDirectory()?await r(i,o):(await ae(i,o),n++)}}}function Nr(e){return h(e,`.kickjs`,`codemod-backups`,`${new Date().toISOString().replaceAll(/[:.]/g,`-`)}-modules`)}async function Pr(e,t){let{dryRun:n=!1,cwd:r=process.cwd(),target:i}=t,a=t.backup??!n,o=await jr(e),s=await C(h(e,`index.ts`),`utf-8`).then(()=>!0,()=>!1),c=null;a&&(o.length>0||s)&&(c=Nr(r),await Mr(e,c));let l=[];for(let e of o){let t=kr(await C(e,`utf-8`),i);if(t.migrated==null){l.push({path:e,status:`skipped`,reason:t.reason});continue}n||await w(e,t.migrated,`utf-8`),l.push({path:e,status:`migrated`})}let u=h(e,`index.ts`),d=null;try{d=await C(u,`utf-8`)}catch{return{target:i,files:l,indexStatus:`not-found`,indexPath:u,backupDir:c}}let f=Ar(d,i);return f.migrated==null?{target:i,files:l,indexStatus:`skipped`,indexPath:u,indexReason:f.reason,backupDir:c}:(n||await w(u,f.migrated,`utf-8`),{target:i,files:l,indexStatus:`migrated`,indexPath:u,backupDir:c})}async function Fr(e,t){let n=await jr(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 C(e,`utf-8`);i.test(t)&&r.push(e)}return r}async function Ir(e){let{name:t,outDir:n}=e,r=I(t),i=R(t),a=L(t),o=e.queue??`${i}-queue`,s=[];return await(async(e,t)=>{let r=h(n,e);await M(r,t),s.push(r)})(`${i}.job.ts`,`import { Inject } from '@forinda/kickjs'
3272
3272
  import { Job, Process, QUEUE_MANAGER, type QueueService } from '@forinda/kickjs-queue'
3273
3273
 
3274
3274
  /**
@@ -3301,7 +3301,7 @@ export class ${r}Job {
3301
3301
  // Handle high-priority variant of this job
3302
3302
  }
3303
3303
  }
3304
- `),s}const Pr={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 Fr(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=Pr[a];if(!o){let e=[...Object.keys(Pr),`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 Ir(e){let{name:t,fields:n,modulesDir:r,noEntity:i,noTests:a,repo:o=`inmemory`,tokenScope:s=`app`,style:c=`define`}=e,l=e.pluralize!==!1,u=R(t),d=I(t);L(t);let f=l?z(u):u,p=l?Xt(d):d,m=h(r,f),g=[],_=async(e,t)=>{let n=h(m,e);await M(n,t),g.push(n)};await _(`${u}.module.ts`,Wr(d,u,f,c)),await _(`constants.ts`,Br(d,n)),await _(`presentation/${u}.controller.ts`,Gr(d,u,f,p)),await _(`application/dtos/create-${u}.dto.ts`,Lr(d,n)),await _(`application/dtos/update-${u}.dto.ts`,Rr(d,n)),await _(`application/dtos/${u}-response.dto.ts`,zr(d,n));let v=Jr(d,u,f,p);for(let e of v)await _(`application/use-cases/${e.file}`,e.content);return await _(`domain/repositories/${u}.repository.ts`,Kr(d,u,s)),await _(`domain/services/${u}-domain.service.ts`,qr(d,u)),o===`inmemory`&&await _(`infrastructure/repositories/in-memory-${u}.repository.ts`,Vr(d,u,n)),i||(await _(`domain/entities/${u}.entity.ts`,Hr(d,u,n)),await _(`domain/value-objects/${u}-id.vo.ts`,Ur(d))),await Xn(r,d,f,u,c),g}function Lr(e,t){return`import { z } from 'zod'
3304
+ `),s}const Lr={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 Rr(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=Lr[a];if(!o){let e=[...Object.keys(Lr),`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 zr(e){let{name:t,fields:n,modulesDir:r,noEntity:i,noTests:a,repo:o=`inmemory`,tokenScope:s=`app`,style:c=`define`}=e,l=e.pluralize!==!1,u=R(t),d=I(t);L(t);let f=l?z(u):u,p=l?Xt(d):d,m=h(r,f),g=[],_=async(e,t)=>{let n=h(m,e);await M(n,t),g.push(n)};await _(`${u}.module.ts`,qr(d,u,f,c)),await _(`constants.ts`,Ur(d,n)),await _(`presentation/${u}.controller.ts`,Jr(d,u,f,p)),await _(`application/dtos/create-${u}.dto.ts`,Br(d,n)),await _(`application/dtos/update-${u}.dto.ts`,Vr(d,n)),await _(`application/dtos/${u}-response.dto.ts`,Hr(d,n));let v=Zr(d,u,f,p);for(let e of v)await _(`application/use-cases/${e.file}`,e.content);return await _(`domain/repositories/${u}.repository.ts`,Yr(d,u,s)),await _(`domain/services/${u}-domain.service.ts`,Xr(d,u)),o===`inmemory`&&await _(`infrastructure/repositories/in-memory-${u}.repository.ts`,Wr(d,u,n)),i||(await _(`domain/entities/${u}.entity.ts`,Gr(d,u,n)),await _(`domain/value-objects/${u}-id.vo.ts`,Kr(d))),await $n(r,d,f,u,c),g}function Br(e,t){return`import { z } from 'zod'
3305
3305
 
3306
3306
  export const create${e}Schema = z.object({
3307
3307
  ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:``},`}).join(`
@@ -3309,7 +3309,7 @@ ${t.map(e=>{let t=e.zodType;return` ${e.name}: ${t}${e.optional?`.optional()`:`
3309
3309
  })
3310
3310
 
3311
3311
  export type Create${e}DTO = z.infer<typeof create${e}Schema>
3312
- `}function Rr(e,t){return`import { z } from 'zod'
3312
+ `}function Vr(e,t){return`import { z } from 'zod'
3313
3313
 
3314
3314
  export const update${e}Schema = z.object({
3315
3315
  ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
@@ -3317,21 +3317,21 @@ ${t.map(e=>` ${e.name}: ${e.zodType}.optional(),`).join(`
3317
3317
  })
3318
3318
 
3319
3319
  export type Update${e}DTO = z.infer<typeof update${e}Schema>
3320
- `}function zr(e,t){return`export interface ${e}ResponseDTO {
3320
+ `}function Hr(e,t){return`export interface ${e}ResponseDTO {
3321
3321
  id: string
3322
3322
  ${t.map(e=>` ${e.name}${e.optional?`?`:``}: ${e.tsType}`).join(`
3323
3323
  `)}
3324
3324
  createdAt: string
3325
3325
  updatedAt: string
3326
3326
  }
3327
- `}function Br(e,t){let n=t.filter(e=>e.tsType===`string`).map(e=>`'${e.name}'`);t.filter(e=>e.tsType===`number`).map(e=>`'${e.name}'`);let r=t.map(e=>`'${e.name}'`),i=[...r].join(`, `),a=[...r,`'createdAt'`,`'updatedAt'`].join(`, `),o=n.length>0?n.join(`, `):`'name'`;return`import type { ApiQueryParamsConfig } from '@forinda/kickjs'
3327
+ `}function Ur(e,t){let n=t.filter(e=>e.tsType===`string`).map(e=>`'${e.name}'`);t.filter(e=>e.tsType===`number`).map(e=>`'${e.name}'`);let r=t.map(e=>`'${e.name}'`),i=[...r].join(`, `),a=[...r,`'createdAt'`,`'updatedAt'`].join(`, `),o=n.length>0?n.join(`, `):`'name'`;return`import type { ApiQueryParamsConfig } from '@forinda/kickjs'
3328
3328
 
3329
3329
  export const ${e.toUpperCase()}_QUERY_CONFIG: ApiQueryParamsConfig = {
3330
3330
  filterable: [${i}],
3331
3331
  sortable: [${a}],
3332
3332
  searchable: [${o}],
3333
3333
  }
3334
- `}function Vr(e,t,n){return`import { randomUUID } from 'node:crypto'
3334
+ `}function Wr(e,t,n){return`import { randomUUID } from 'node:crypto'
3335
3335
  import { Repository, HttpException } from '@forinda/kickjs'
3336
3336
  import type { ParsedQuery } from '@forinda/kickjs'
3337
3337
  import type { I${e}Repository } from '../../domain/repositories/${t}.repository'
@@ -3383,7 +3383,7 @@ ${n.map(e=>` ${e.name}: dto.${e.name},`).join(`
3383
3383
  this.store.delete(id)
3384
3384
  }
3385
3385
  }
3386
- `}function Hr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3386
+ `}function Gr(e,t,n){return`import { ${e}Id } from '../value-objects/${t}-id.vo'
3387
3387
 
3388
3388
  interface ${e}Props {
3389
3389
  id: ${e}Id
@@ -3429,7 +3429,7 @@ ${n.map(e=>` ${e.name}: this.props.${e.name},`).join(`
3429
3429
  }
3430
3430
  }
3431
3431
  }
3432
- `}function Ur(e){return`import { randomUUID } from 'node:crypto'
3432
+ `}function Kr(e){return`import { randomUUID } from 'node:crypto'
3433
3433
 
3434
3434
  export class ${e}Id {
3435
3435
  private constructor(private readonly value: string) {}
@@ -3444,7 +3444,7 @@ export class ${e}Id {
3444
3444
  toString(): string { return this.value }
3445
3445
  equals(other: ${e}Id): boolean { return this.value === other.value }
3446
3446
  }
3447
- `}function Wr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3447
+ `}function qr(e,t,n,r=`define`){let i=`import { ${e}Controller } from './presentation/${t}.controller'
3448
3448
  import { ${e.toUpperCase()}_REPOSITORY } from './domain/repositories/${t}.repository'
3449
3449
  import { InMemory${e}Repository } from './infrastructure/repositories/in-memory-${t}.repository'
3450
3450
 
@@ -3517,7 +3517,7 @@ ${a}
3517
3517
  },
3518
3518
  }),
3519
3519
  })
3520
- `}function Gr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3520
+ `}function Jr(e,t,n,r){return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
3521
3521
  import { ApiTags } from '@forinda/kickjs-swagger'
3522
3522
  import { Create${e}UseCase } from '../application/use-cases/create-${t}.use-case'
3523
3523
  import { Get${e}UseCase } from '../application/use-cases/get-${t}.use-case'
@@ -3580,7 +3580,7 @@ export class ${e}Controller {
3580
3580
  ctx.noContent()
3581
3581
  }
3582
3582
  }
3583
- `}function Kr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3583
+ `}function Yr(e,t,n){return`import { createToken } from '@forinda/kickjs'
3584
3584
  import type { ${e}ResponseDTO } from '../../application/dtos/${t}-response.dto'
3585
3585
  import type { Create${e}DTO } from '../../application/dtos/create-${t}.dto'
3586
3586
  import type { Update${e}DTO } from '../../application/dtos/update-${t}.dto'
@@ -3606,7 +3606,7 @@ export interface I${e}Repository {
3606
3606
  * adopters must NOT use the reserved \`'kick/'\` namespace.
3607
3607
  */
3608
3608
  export const ${e.toUpperCase()}_REPOSITORY = createToken<I${e}Repository>('${n}/${e}/repository')
3609
- `}function qr(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3609
+ `}function Xr(e,t){return`import { Service, Inject, HttpException } from '@forinda/kickjs'
3610
3610
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../repositories/${t}.repository'
3611
3611
 
3612
3612
  @Service()
@@ -3620,7 +3620,7 @@ export class ${e}DomainService {
3620
3620
  if (!entity) throw HttpException.notFound('${e} not found')
3621
3621
  }
3622
3622
  }
3623
- `}function Jr(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3623
+ `}function Zr(e,t,n,r){return[{file:`create-${t}.use-case.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
3624
3624
  import { ${e.toUpperCase()}_REPOSITORY, type I${e}Repository } from '../../domain/repositories/${t}.repository'
3625
3625
  import type { Create${e}DTO } from '../dtos/create-${t}.dto'
3626
3626
 
@@ -3663,7 +3663,7 @@ export class Delete${e}UseCase {
3663
3663
  constructor(@Inject(${e.toUpperCase()}_REPOSITORY) private repo: I${e}Repository) {}
3664
3664
  async execute(id: string) { return this.repo.delete(id) }
3665
3665
  }
3666
- `}]}async function Yr(e){let{name:t,moduleName:n,modulesDir:r}=e,i=e.pluralize??!0,a=R(t),o=I(t),s=[],c;if(e.outDir)c=v(e.outDir);else if(n){let e=R(n),t=i?z(e):e;c=v(h(r??`src/modules`,t,`__tests__`))}else c=v(`src/__tests__`);let l=h(c,`${a}.test.ts`);return await M(l,`import { describe, it, expect, beforeEach } from 'vitest'
3666
+ `}]}async function Qr(e){let{name:t,moduleName:n,modulesDir:r}=e,i=e.pluralize??!0,a=R(t),o=I(t),s=[],c;if(e.outDir)c=v(e.outDir);else if(n){let e=R(n),t=i?z(e):e;c=v(h(r??`src/modules`,t,`__tests__`))}else c=v(`src/__tests__`);let l=h(c,`${a}.test.ts`);return await M(l,`import { describe, it, expect, beforeEach } from 'vitest'
3667
3667
  import { Container } from '@forinda/kickjs'
3668
3668
 
3669
3669
  describe('${o}', () => {
@@ -3686,9 +3686,9 @@ describe('${o}', () => {
3686
3686
  expect(true).toBe(true)
3687
3687
  })
3688
3688
  })
3689
- `),s.push(l),s}const Xr=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],Zr=[`.ts`,`.tsx`,`.mts`,`.cts`],Qr=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],$r=new RegExp(String.raw`@(${Xr.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),ei=new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppModule\b`,`g`),ti=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ni=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ri=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ii=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,ai=new RegExp(String.raw`export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppAdapter\b`,`g`),oi=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,si=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,ci=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function li(e,t){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 ui(e,t){let n=t;for(;n<e.length;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`@`)break;let t=e.slice(n).match(/^@([A-Z]\w*)/);if(!t)break;for(n+=t[0].length;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]===`(`){let t=li(e,n);if(t<0)return null;n=t+1}}for(;n<e.length&&/\s/.test(e[n]);)n++;for(let t of[`public`,`private`,`protected`])if(e.slice(n,n+t.length)===t&&/\s/.test(e.charAt(n+t.length))){for(n+=t.length;n<e.length&&/\s/.test(e[n]);)n++;break}if(e.slice(n,n+5)===`async`&&/\s/.test(e.charAt(n+5)))for(n+=5;n<e.length&&/\s/.test(e[n]);)n++;let r=e.slice(n).match(/^([a-zA-Z_]\w*)\s*\(/);return r?{methodName:r[1],endPos:n+r[0].length}:null}function di(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function fi(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const pi=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,mi=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,hi=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,gi=/\bimport\.meta\.glob\s*\(/g;function _i(e){let t=[];for(gi.lastIndex=0;gi.exec(e)!==null;){let n=gi.lastIndex-1,r=li(e,n);if(r<0)continue;let i=e.slice(n+1,r),a=/['"`]([^'"`]+)['"`]/g,o;for(;(o=a.exec(i))!==null;)t.push(o[1])}return t}function vi(e){let t=e.replace(/[.+^$()|[\]\\]/g,`\\$&`).replace(/\?/g,`.`).replace(/\*\*\//g,`___DOUBLESTAR_SLASH___`).replace(/\*\*/g,`___DOUBLESTAR___`).replace(/\*/g,`[^/]*`).replace(/___DOUBLESTAR_SLASH___/g,`(?:.+/)?`).replace(/___DOUBLESTAR___/g,`.*`);return RegExp(`^`+t+`$`)}function yi(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);vi(t?e.slice(1):e).test(n)&&(r=!t)}return r}function bi(e){let t=[];pi.lastIndex=0;let n;for(;(n=pi.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Mi(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];mi.lastIndex=0;let s;for(;(s=mi.exec(a))!==null;)o.push(s[1]??``);let c=[];hi.lastIndex=0;let l;for(;(l=hi.exec(a))!==null;)c.push(l[1]);let u=Math.min(o.length,c.length);for(let e=0;e<u;e++)t.push({controller:c[e],mountPath:o[e]})}return t}function xi(e,t){let n=new RegExp(String.raw`\b${t}\s*:\s*([A-Za-z_$][\w$]*)`,`g`).exec(e);return n?n[1]:null}function Si(e,t){let n=new RegExp(String.raw`import\s*(?:type\s+)?\{[^}]*\b${t}\b[^}]*\}\s*from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(n)return n[1];let r=new RegExp(String.raw`import\s+(?:type\s+)?${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(r)return r[1];let i=new RegExp(String.raw`import\s*\*\s*as\s+${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);return i?i[1]:new RegExp(String.raw`(?:^|\n)\s*(?:export\s+)?const\s+${t}\b`).test(e)?``:null}function Ci(e,t){let n=/@ApiQueryParams\s*\(\s*([\s\S]*?)\s*\)\s*$/.exec(e);if(!n){let n=/@ApiQueryParams\s*\(([\s\S]*?)\)/.exec(e);return n?wi(n[1].trim(),t):null}return wi(n[1].trim(),t)}function wi(e,t){if(e.startsWith(`{`))return Ei(e);let n=/^([A-Za-z_]\w*)/.exec(e);if(n){let e=n[1],r=new RegExp(String.raw`const\s+${e}\s*(?::\s*[^=]+)?=\s*(\{[\s\S]*?\n\})`,`m`).exec(t);if(r)return Ei(r[1])}return{filterable:[],sortable:[],searchable:[]}}function Ti(e,t){let n=new RegExp(String.raw`${t}\s*:\s*\[([\s\S]*?)\]`).exec(e);return n?Array.from(n[1].matchAll(/['"`]([^'"`]+)['"`]/g)).map(e=>e[1]):[]}function Ei(e){return{filterable:Ti(e,`filterable`),sortable:Ti(e,`sortable`),searchable:Ti(e,`searchable`)}}async function Di(e,t){let n=t.extensions??Zr,r=t.exclude??Qr,i=[],a;try{a=await se(e,{withFileTypes:!0,encoding:`utf-8`})}catch{return i}for(let o of a){let a=h(e,o.name),s=_(t.cwd,a);r.some(e=>s.includes(e))||(o.isDirectory()?i.push(...await Di(a,t)):o.isFile()&&n.some(e=>o.name.endsWith(e))&&i.push(a))}return i}function W(e,t){return _(t,e).split(y).join(`/`)}function Oi(e,t,n){let r=[],i=W(t,n);$r.lastIndex=0;let a;for(;(a=$r.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}ei.lastIndex=0;let o;for(;(o=ei.exec(e))!==null;){let[,e,n]=o;r.some(e=>e.className===n&&e.filePath===t)||r.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!!e})}return r}function ki(e,t,n){let r=[],i=W(t,n),a=new Set;ti.lastIndex=0;let o;for(;(o=ti.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(ni.lastIndex=0;(o=ni.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Ai(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=W(t,n),s=[];for(let t of r){let n=new RegExp(String.raw`class\s+${t.className}\b`).exec(e);n?.index!==void 0&&s.push({cls:t,start:n.index})}s.sort((e,t)=>e.start-t.start);for(let n=0;n<s.length;n++){let{cls:r,start:c}=s[n],l=n+1<s.length?s[n+1].start:e.length,u=e.slice(c,l);ci.lastIndex=0;let d;for(;(d=ci.exec(u))!==null;){let n=d[1],s=d.index,c=ci.lastIndex-1,l=li(u,c);if(l<0)continue;let f=u.slice(c+1,l),p=f.match(/^\s*['"`]([^'"`]*)['"`]/),m=p&&p[1].length>0?p[1]:`/`,h=ui(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;ci.lastIndex=_;let v=Ci(u.slice(s,_),e),y=xi(f,`body`),b=xi(f,`query`),x=xi(f,`params`),ee=i.get(r.className)??``,S=ee?fi(ee,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:di(S),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:Si(e,y)}:null,querySchema:b?{identifier:b,source:Si(e,b)}:null,paramsSchema:x?{identifier:x,source:Si(e,x)}:null,filePath:t,relativePath:o})}}return a}function ji(e,t,n){let r=[],i=W(t,n);ri.lastIndex=0;let a;for(;(a=ri.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Mi(e,t){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 Ni(e,t,n){let r=[],i=W(t,n),a=new Set;ii.lastIndex=0;let o;for(;(o=ii.exec(e))!==null;){let n=o[1],s=ii.lastIndex-1,c=li(e,s);if(c<0)continue;let l=e.slice(s+1,c),u=/\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(l);if(!u)continue;let d=u[1],f=`${n}::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:n===`definePlugin`?`plugin`:`adapter`,name:d,filePath:t,relativePath:i}))}ai.lastIndex=0;let s;for(;(s=ai.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Mi(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=oi.exec(l);if(!u)continue;let d=u[1],f=`class::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:`adapter`,name:d,filePath:t,relativePath:i}))}return r}function Pi(e,t,n){let r=[],i=W(t,n);si.lastIndex=0;let a;for(;(a=si.exec(e))!==null;){let n=a[1],o=null,s=null;if(a[2]){let t=e.indexOf(`{`,a.index+a[0].length-1);if(t>=0){let n=Mi(e,t);if(n>=0){let r=e.slice(t+1,n);o=Fi(r,`description`),s=Fi(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function Fi(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(['"\`])`,`g`).exec(e);if(!n)return null;let r=n[1],i=n.index+n[0].length,a=i,o=null;for(;a<e.length;){let t=e[a];if(t===`\\`){a+=2;continue}if(t===r){o=e.slice(i,a);break}a++}return o===null?null:o.replace(/\\(.)/g,(e,t)=>t===`n`?`
3690
- `:t===`t`?` `:t===`r`?`\r`:t)}const Ii=[`src/config/index.ts`,`src/config/env.ts`,`src/config.ts`,`src/env.ts`];async function Li(e,t){let n=t===`src/env.ts`?Ii:[t];for(let t of n){let n=v(e,t),r;try{r=await C(n,`utf-8`)}catch{continue}if(/\bdefineEnv\s*\(/.test(r)&&/export\s+default\b/.test(r))return{filePath:n,relativePath:W(n,e)}}return null}function Ri(e){let t=new Map;for(let n of e){let e=t.get(n.className)??[];e.push(n),t.set(n.className,e)}let n=[];for(let[e,r]of t)new Set(r.map(e=>e.filePath)).size>1&&n.push({className:e,classes:r});return n.sort((e,t)=>e.className.localeCompare(t.className)),n}async function zi(e){let t=await Di(v(e.root),e),n=[],r=[],i=[],a=[],o=[],s=[],c=new Map;for(let r of t){let t;try{t=await C(r,`utf-8`)}catch{continue}c.set(r,t),n.push(...Oi(t,r,e.cwd)),i.push(...ki(t,r,e.cwd)),a.push(...ji(t,r,e.cwd)),o.push(...Ni(t,r,e.cwd)),s.push(...Pi(t,r,e.cwd))}let l=new Map;for(let[,e]of c)for(let{controller:t,mountPath:n}of bi(e))l.has(t)||l.set(t,n);for(let[t,i]of c){let a=n.filter(e=>e.filePath===t);r.push(...Ai(i,t,e.cwd,a,l))}let u=[];for(let[e,t]of c){if(!/\.module\.[mc]?[tj]sx?$/.test(e))continue;let r=_i(t);if(r.length===0)continue;let i=e.replaceAll(y,`/`),a=i.slice(0,i.lastIndexOf(`/`));for(let t of n){if(t.decorator===`Module`)continue;let n=t.filePath.replaceAll(y,`/`);n.startsWith(a+`/`)&&n!==i&&(yi(n.slice(a.length+1),r)||u.push({className:t.className,filePath:t.filePath,relativePath:t.relativePath,moduleFilePath:e,decorator:t.decorator}))}}n.sort((e,t)=>e.className===t.className?e.relativePath.localeCompare(t.relativePath):e.className.localeCompare(t.className)),i.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),a.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),r.sort((e,t)=>e.controller.localeCompare(t.controller)||e.method.localeCompare(t.method)),o.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),s.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath));let d=Ri(n),f=await Li(e.cwd,e.envFile??`src/env.ts`);return u.sort((e,t)=>e.relativePath.localeCompare(t.relativePath)||e.className.localeCompare(t.className)),{classes:n,routes:r,tokens:i,injects:a,collisions:d,env:f,pluginsAndAdapters:o,augmentations:s,orphanedClasses:u}}const G="/* 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",Bi=new Set([`Service`,`Repository`,`Injectable`,`Component`]);var Vi=class extends Error{collisions;constructor(e){super(Hi(e)),this.name=`TokenCollisionError`,this.collisions=e}};function Hi(e){let t=[`kick typegen: token collision detected`];for(let n of e){t.push(``),t.push(` ${n.classes.length} classes named '${n.className}':`);for(let e of n.classes)t.push(` - ${e.relativePath}`)}return t.push(``),t.push(`Resolutions:`),t.push(` (a) Rename one of the classes`),t.push(` (b) Use createToken<T>('namespaced/Name') and import the token explicitly — see @forinda/kickjs`),t.push(` (c) Pass --allow-duplicates to namespace the registry keys automatically`),t.push(` (e.g. 'modules/users/UserService' instead of 'UserService')`),t.join(`
3691
- `)}function Ui(e,t){let n=_(f(t),e).split(y).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),n}function Wi(e){let t=e.relativePath.replace(/^src\//,``).replace(/\.(ts|tsx|mts|cts)$/i,``).split(`/`);t.pop();let n=t.join(`/`);return n?`${n}/${e.className}`:e.className}function Gi(e,t,n){let r=new Set,i=[];for(let a of e){if(!Bi.has(a.decorator))continue;let e=n.has(a.className)?Wi(a):a.className;if(r.has(e))continue;r.add(e);let o=Ui(a.filePath,t),s=a.isDefault?`import('${o}').default`:`import('${o}').${a.className}`;i.push(` '${e}': ${s}`)}return`${G}
3689
+ `),s.push(l),s}const $r=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],ei=[`.ts`,`.tsx`,`.mts`,`.cts`],ti=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],ni=new RegExp(String.raw`@(${$r.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),ri=new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppModule\b`,`g`),ii=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,ai=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,oi=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,si=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,ci=new RegExp(String.raw`export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppAdapter\b`,`g`),li=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,ui=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,di=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function fi(e,t){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 pi(e,t){let n=t;for(;n<e.length;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`@`)break;let t=e.slice(n).match(/^@([A-Z]\w*)/);if(!t)break;for(n+=t[0].length;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]===`(`){let t=fi(e,n);if(t<0)return null;n=t+1}}for(;n<e.length&&/\s/.test(e[n]);)n++;for(let t of[`public`,`private`,`protected`])if(e.slice(n,n+t.length)===t&&/\s/.test(e.charAt(n+t.length))){for(n+=t.length;n<e.length&&/\s/.test(e[n]);)n++;break}if(e.slice(n,n+5)===`async`&&/\s/.test(e.charAt(n+5)))for(n+=5;n<e.length&&/\s/.test(e[n]);)n++;let r=e.slice(n).match(/^([a-zA-Z_]\w*)\s*\(/);return r?{methodName:r[1],endPos:n+r[0].length}:null}function mi(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function hi(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const gi=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,_i=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,vi=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,yi=/\bimport\.meta\.glob\s*\(/g;function bi(e){let t=[];for(yi.lastIndex=0;yi.exec(e)!==null;){let n=yi.lastIndex-1,r=fi(e,n);if(r<0)continue;let i=e.slice(n+1,r),a=/['"`]([^'"`]+)['"`]/g,o;for(;(o=a.exec(i))!==null;)t.push(o[1])}return t}function xi(e){let t=e.replace(/[.+^$()|[\]\\]/g,`\\$&`).replace(/\?/g,`.`).replace(/\*\*\//g,`___DOUBLESTAR_SLASH___`).replace(/\*\*/g,`___DOUBLESTAR___`).replace(/\*/g,`[^/]*`).replace(/___DOUBLESTAR_SLASH___/g,`(?:.+/)?`).replace(/___DOUBLESTAR___/g,`.*`);return RegExp(`^`+t+`$`)}function Si(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);xi(t?e.slice(1):e).test(n)&&(r=!t)}return r}function Ci(e){let t=[];gi.lastIndex=0;let n;for(;(n=gi.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Fi(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];_i.lastIndex=0;let s;for(;(s=_i.exec(a))!==null;)o.push(s[1]??``);let c=[];vi.lastIndex=0;let l;for(;(l=vi.exec(a))!==null;)c.push(l[1]);let u=Math.min(o.length,c.length);for(let e=0;e<u;e++)t.push({controller:c[e],mountPath:o[e]})}return t}function wi(e,t){let n=new RegExp(String.raw`\b${t}\s*:\s*([A-Za-z_$][\w$]*)`,`g`).exec(e);return n?n[1]:null}function Ti(e,t){let n=new RegExp(String.raw`import\s*(?:type\s+)?\{[^}]*\b${t}\b[^}]*\}\s*from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(n)return n[1];let r=new RegExp(String.raw`import\s+(?:type\s+)?${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(r)return r[1];let i=new RegExp(String.raw`import\s*\*\s*as\s+${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);return i?i[1]:new RegExp(String.raw`(?:^|\n)\s*(?:export\s+)?const\s+${t}\b`).test(e)?``:null}function Ei(e,t){let n=/@ApiQueryParams\s*\(\s*([\s\S]*?)\s*\)\s*$/.exec(e);if(!n){let n=/@ApiQueryParams\s*\(([\s\S]*?)\)/.exec(e);return n?Di(n[1].trim(),t):null}return Di(n[1].trim(),t)}function Di(e,t){if(e.startsWith(`{`))return ki(e);let n=/^([A-Za-z_]\w*)/.exec(e);if(n){let e=n[1],r=new RegExp(String.raw`const\s+${e}\s*(?::\s*[^=]+)?=\s*(\{[\s\S]*?\n\})`,`m`).exec(t);if(r)return ki(r[1])}return{filterable:[],sortable:[],searchable:[]}}function Oi(e,t){let n=new RegExp(String.raw`${t}\s*:\s*\[([\s\S]*?)\]`).exec(e);return n?Array.from(n[1].matchAll(/['"`]([^'"`]+)['"`]/g)).map(e=>e[1]):[]}function ki(e){return{filterable:Oi(e,`filterable`),sortable:Oi(e,`sortable`),searchable:Oi(e,`searchable`)}}async function Ai(e,t){let n=t.extensions??ei,r=t.exclude??ti,i=[],a;try{a=await se(e,{withFileTypes:!0,encoding:`utf-8`})}catch{return i}for(let o of a){let a=h(e,o.name),s=_(t.cwd,a);r.some(e=>s.includes(e))||(o.isDirectory()?i.push(...await Ai(a,t)):o.isFile()&&n.some(e=>o.name.endsWith(e))&&i.push(a))}return i}function W(e,t){return _(t,e).split(y).join(`/`)}function ji(e,t,n){let r=[],i=W(t,n);ni.lastIndex=0;let a;for(;(a=ni.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}ri.lastIndex=0;let o;for(;(o=ri.exec(e))!==null;){let[,e,n]=o;r.some(e=>e.className===n&&e.filePath===t)||r.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!!e})}return r}function Mi(e,t,n){let r=[],i=W(t,n),a=new Set;ii.lastIndex=0;let o;for(;(o=ii.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(ai.lastIndex=0;(o=ai.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Ni(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=W(t,n),s=[];for(let t of r){let n=new RegExp(String.raw`class\s+${t.className}\b`).exec(e);n?.index!==void 0&&s.push({cls:t,start:n.index})}s.sort((e,t)=>e.start-t.start);for(let n=0;n<s.length;n++){let{cls:r,start:c}=s[n],l=n+1<s.length?s[n+1].start:e.length,u=e.slice(c,l);di.lastIndex=0;let d;for(;(d=di.exec(u))!==null;){let n=d[1],s=d.index,c=di.lastIndex-1,l=fi(u,c);if(l<0)continue;let f=u.slice(c+1,l),p=f.match(/^\s*['"`]([^'"`]*)['"`]/),m=p&&p[1].length>0?p[1]:`/`,h=pi(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;di.lastIndex=_;let v=Ei(u.slice(s,_),e),y=wi(f,`body`),b=wi(f,`query`),x=wi(f,`params`),ee=i.get(r.className)??``,S=ee?hi(ee,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:mi(S),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:Ti(e,y)}:null,querySchema:b?{identifier:b,source:Ti(e,b)}:null,paramsSchema:x?{identifier:x,source:Ti(e,x)}:null,filePath:t,relativePath:o})}}return a}function Pi(e,t,n){let r=[],i=W(t,n);oi.lastIndex=0;let a;for(;(a=oi.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Fi(e,t){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 Ii(e,t,n){let r=[],i=W(t,n),a=new Set;si.lastIndex=0;let o;for(;(o=si.exec(e))!==null;){let n=o[1],s=si.lastIndex-1,c=fi(e,s);if(c<0)continue;let l=e.slice(s+1,c),u=/\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(l);if(!u)continue;let d=u[1],f=`${n}::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:n===`definePlugin`?`plugin`:`adapter`,name:d,filePath:t,relativePath:i}))}ci.lastIndex=0;let s;for(;(s=ci.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Fi(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=li.exec(l);if(!u)continue;let d=u[1],f=`class::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:`adapter`,name:d,filePath:t,relativePath:i}))}return r}function Li(e,t,n){let r=[],i=W(t,n);ui.lastIndex=0;let a;for(;(a=ui.exec(e))!==null;){let n=a[1],o=null,s=null;if(a[2]){let t=e.indexOf(`{`,a.index+a[0].length-1);if(t>=0){let n=Fi(e,t);if(n>=0){let r=e.slice(t+1,n);o=Ri(r,`description`),s=Ri(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function Ri(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(['"\`])`,`g`).exec(e);if(!n)return null;let r=n[1],i=n.index+n[0].length,a=i,o=null;for(;a<e.length;){let t=e[a];if(t===`\\`){a+=2;continue}if(t===r){o=e.slice(i,a);break}a++}return o===null?null:o.replace(/\\(.)/g,(e,t)=>t===`n`?`
3690
+ `:t===`t`?` `:t===`r`?`\r`:t)}const zi=[`src/config/index.ts`,`src/config/env.ts`,`src/config.ts`,`src/env.ts`];async function Bi(e,t){let n=t===`src/env.ts`?zi:[t];for(let t of n){let n=v(e,t),r;try{r=await C(n,`utf-8`)}catch{continue}if(/\bdefineEnv\s*\(/.test(r)&&/export\s+default\b/.test(r))return{filePath:n,relativePath:W(n,e)}}return null}function Vi(e){let t=new Map;for(let n of e){let e=t.get(n.className)??[];e.push(n),t.set(n.className,e)}let n=[];for(let[e,r]of t)new Set(r.map(e=>e.filePath)).size>1&&n.push({className:e,classes:r});return n.sort((e,t)=>e.className.localeCompare(t.className)),n}async function Hi(e){let t=await Ai(v(e.root),e),n=[],r=[],i=[],a=[],o=[],s=[],c=new Map;for(let r of t){let t;try{t=await C(r,`utf-8`)}catch{continue}c.set(r,t),n.push(...ji(t,r,e.cwd)),i.push(...Mi(t,r,e.cwd)),a.push(...Pi(t,r,e.cwd)),o.push(...Ii(t,r,e.cwd)),s.push(...Li(t,r,e.cwd))}let l=new Map;for(let[,e]of c)for(let{controller:t,mountPath:n}of Ci(e))l.has(t)||l.set(t,n);for(let[t,i]of c){let a=n.filter(e=>e.filePath===t);r.push(...Ni(i,t,e.cwd,a,l))}let u=[];for(let[e,t]of c){if(!/\.module\.[mc]?[tj]sx?$/.test(e))continue;let r=bi(t);if(r.length===0)continue;let i=e.replaceAll(y,`/`),a=i.slice(0,i.lastIndexOf(`/`));for(let t of n){if(t.decorator===`Module`)continue;let n=t.filePath.replaceAll(y,`/`);n.startsWith(a+`/`)&&n!==i&&(Si(n.slice(a.length+1),r)||u.push({className:t.className,filePath:t.filePath,relativePath:t.relativePath,moduleFilePath:e,decorator:t.decorator}))}}n.sort((e,t)=>e.className===t.className?e.relativePath.localeCompare(t.relativePath):e.className.localeCompare(t.className)),i.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),a.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),r.sort((e,t)=>e.controller.localeCompare(t.controller)||e.method.localeCompare(t.method)),o.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),s.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath));let d=Vi(n),f=await Bi(e.cwd,e.envFile??`src/env.ts`);return u.sort((e,t)=>e.relativePath.localeCompare(t.relativePath)||e.className.localeCompare(t.className)),{classes:n,routes:r,tokens:i,injects:a,collisions:d,env:f,pluginsAndAdapters:o,augmentations:s,orphanedClasses:u}}const G="/* 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",Ui=new Set([`Service`,`Repository`,`Injectable`,`Component`]);var Wi=class extends Error{collisions;constructor(e){super(Gi(e)),this.name=`TokenCollisionError`,this.collisions=e}};function Gi(e){let t=[`kick typegen: token collision detected`];for(let n of e){t.push(``),t.push(` ${n.classes.length} classes named '${n.className}':`);for(let e of n.classes)t.push(` - ${e.relativePath}`)}return t.push(``),t.push(`Resolutions:`),t.push(` (a) Rename one of the classes`),t.push(` (b) Use createToken<T>('namespaced/Name') and import the token explicitly — see @forinda/kickjs`),t.push(` (c) Pass --allow-duplicates to namespace the registry keys automatically`),t.push(` (e.g. 'modules/users/UserService' instead of 'UserService')`),t.join(`
3691
+ `)}function Ki(e,t){let n=_(f(t),e).split(y).join(`/`);return n=n.replace(/\.(ts|tsx|mts|cts)$/i,``),n.startsWith(`.`)||(n=`./`+n),n}function qi(e){let t=e.relativePath.replace(/^src\//,``).replace(/\.(ts|tsx|mts|cts)$/i,``).split(`/`);t.pop();let n=t.join(`/`);return n?`${n}/${e.className}`:e.className}function Ji(e,t,n){let r=new Set,i=[];for(let a of e){if(!Ui.has(a.decorator))continue;let e=n.has(a.className)?qi(a):a.className;if(r.has(e))continue;r.add(e);let o=Ki(a.filePath,t),s=a.isDefault?`import('${o}').default`:`import('${o}').${a.className}`;i.push(` '${e}': ${s}`)}return`${G}
3692
3692
  declare module '@forinda/kickjs' {
3693
3693
  interface KickJsRegistry {
3694
3694
  ${i.length?i.join(`
@@ -3697,14 +3697,14 @@ ${i.length?i.join(`
3697
3697
  }
3698
3698
 
3699
3699
  export {}
3700
- `}function Ki(e,t,n){return t.length===0?`${G}
3700
+ `}function Yi(e,t,n){return t.length===0?`${G}
3701
3701
  // ${n}
3702
3702
  export type ${e} = never
3703
3703
  `:`${G}
3704
3704
  export type ${e} =
3705
3705
  ${[...new Set(t)].toSorted().map(e=>` | '${e}'`).join(`
3706
3706
  `)}
3707
- `}function qi(e,t){return`${G}
3707
+ `}function Xi(e,t){return`${G}
3708
3708
  export type { ServiceToken } from './services'
3709
3709
  export type { ModuleToken } from './modules'
3710
3710
 
@@ -3720,7 +3720,7 @@ import './plugins'
3720
3720
  import './augmentations'
3721
3721
  ${t?`import './kick__assets'
3722
3722
  `:``}${e?`import './kick__env'
3723
- `:``}`}function Ji(e){let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return`${G}
3723
+ `:``}`}function Zi(e){let t=new Map;for(let n of e)t.has(n.name)||t.set(n.name,n);return`${G}
3724
3724
  declare module '@forinda/kickjs' {
3725
3725
  /**
3726
3726
  * Map of every plugin/adapter \`name\` discovered in the project. The
@@ -3735,7 +3735,7 @@ ${[...t.values()].toSorted((e,t)=>e.name.localeCompare(t.name)).map(e=>` '${e
3735
3735
  }
3736
3736
 
3737
3737
  export {}
3738
- `}function Yi(e){if(e.length===0)return`${G}
3738
+ `}function Qi(e){if(e.length===0)return`${G}
3739
3739
  // No augmentations discovered.
3740
3740
  //
3741
3741
  // Plugins advertise augmentable interfaces via:
@@ -3759,9 +3759,9 @@ export {}
3759
3759
  ${n.join(`
3760
3760
 
3761
3761
  `)}
3762
- `}async function Xi(e){let{classes:t,routes:n=[],tokens:r=[],injects:i=[],collisions:a=[],env:o=null,pluginsAndAdapters:s=[],augmentations:c=[],assets:l={entries:[],count:0},outDir:u,allowDuplicates:d=!1,schemaValidator:p=!1}=e;if(a.length>0&&!d)throw new Vi(a);await oe(u,{recursive:!0});let m=h(u,`registry.d.ts`),g=h(u,`services.d.ts`),_=h(u,`modules.d.ts`),v=h(u,`plugins.d.ts`),y=h(u,`augmentations.d.ts`),b=h(u,`index.d.ts`),x=new Set(a.map(e=>e.className)),ee=Gi(t,m,x),S=t.filter(e=>Bi.has(e.decorator)).map(e=>x.has(e.className)?Wi(e):e.className),te=r.map(e=>e.name),ne=i.map(e=>e.name),re=[...S,...te,...ne],ie=t.filter(e=>e.decorator===`Module`).map(e=>e.className),ae=Ki(`ServiceToken`,re,"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)"),C=Ki(`ModuleToken`,ie,"(no @Module classes discovered — `kick g module <name>` to add one)"),se=Ji(s),ce=Yi(c),le=qi(o!==null,l.count>0);await w(m,ee,`utf-8`),await w(g,ae,`utf-8`),await w(_,C,`utf-8`),await w(v,se,`utf-8`),await w(y,ce,`utf-8`),await w(b,le,`utf-8`);let ue=[m,g,_,v,y,b];await w(h(f(u),`.gitignore`),`# Auto-generated by kick typegen
3762
+ `}async function $i(e){let{classes:t,routes:n=[],tokens:r=[],injects:i=[],collisions:a=[],env:o=null,pluginsAndAdapters:s=[],augmentations:c=[],assets:l={entries:[],count:0},outDir:u,allowDuplicates:d=!1,schemaValidator:p=!1}=e;if(a.length>0&&!d)throw new Wi(a);await oe(u,{recursive:!0});let m=h(u,`registry.d.ts`),g=h(u,`services.d.ts`),_=h(u,`modules.d.ts`),v=h(u,`plugins.d.ts`),y=h(u,`augmentations.d.ts`),b=h(u,`index.d.ts`),x=new Set(a.map(e=>e.className)),ee=Ji(t,m,x),S=t.filter(e=>Ui.has(e.decorator)).map(e=>x.has(e.className)?qi(e):e.className),te=r.map(e=>e.name),ne=i.map(e=>e.name),re=[...S,...te,...ne],ie=t.filter(e=>e.decorator===`Module`).map(e=>e.className),ae=Yi(`ServiceToken`,re,"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)"),C=Yi(`ModuleToken`,ie,"(no @Module classes discovered — `kick g module <name>` to add one)"),se=Zi(s),ce=Qi(c),le=Xi(o!==null,l.count>0);await w(m,ee,`utf-8`),await w(g,ae,`utf-8`),await w(_,C,`utf-8`),await w(v,se,`utf-8`),await w(y,ce,`utf-8`),await w(b,le,`utf-8`);let ue=[m,g,_,v,y,b];await w(h(f(u),`.gitignore`),`# Auto-generated by kick typegen
3763
3763
  *
3764
- `,`utf-8`);let T=new Set(s.map(e=>e.name)).size,E=new Set(c.map(e=>e.name)).size;return{registryEntries:S.length,serviceTokens:new Set(re).size,moduleTokens:ie.length,routeEntries:n.length,pluginEntries:T,augmentationEntries:E,assetEntries:l.count,envWritten:o!==null,written:ue,resolvedCollisions:a.length}}const Zi=/^(kick\/)?([a-z][\w-]*\/[A-Z]\w*)(\/.+)?(:[a-z][\w-]+(:[a-z][\w-]+)*)?$/;function Qi(e){let t=[];for(let n of e){let e=n.name;e.startsWith(`kickjs.`)||Zi.test(e)||t.push({token:e,variable:n.variable,filePath:n.relativePath,reason:"does not match `<scope>/<PascalKey>[/<suffix>][:<instance>]`",suggestion:$i(e)})}return t}function $i(e){if(/^[A-Z]\w*$/.test(e))return`'<scope>/${e}' (e.g. 'mycorp/${e}')`;if(e.includes(`.`))return`consider '<scope>/PascalKey' instead of dotted form`;let t=/^([a-z][\w-]*)\/([a-z]\w*)$/.exec(e);if(t){let[,e,n]=t;return`'${e}/${n.charAt(0).toUpperCase()}${n.slice(1)}'`}}function ea(e,t){if(!e)return{entries:[],count:0};let n=new Map;for(let[r,i]of Object.entries(e)){if(!i||typeof i.src!=`string`)continue;let e=v(t,i.src);if(!aa(e))continue;let a=pe(i.glob??`**/*`,{cwd:e,nodir:!0,dot:!1,posix:!0});a.sort();let{pairs:o}=me(r,a,{strategy:i.keys??`auto`});for(let{key:e}of o){let t=e.slice(r.length+1);n.set(e,{namespace:r,key:t})}}return{entries:[...n.values()],count:n.size}}function ta(e){let t="/* 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";if(e.entries.length===0)return`${t}
3764
+ `,`utf-8`);let T=new Set(s.map(e=>e.name)).size,E=new Set(c.map(e=>e.name)).size;return{registryEntries:S.length,serviceTokens:new Set(re).size,moduleTokens:ie.length,routeEntries:n.length,pluginEntries:T,augmentationEntries:E,assetEntries:l.count,envWritten:o!==null,written:ue,resolvedCollisions:a.length}}const ea=/^(kick\/)?([a-z][\w-]*\/[A-Z]\w*)(\/.+)?(:[a-z][\w-]+(:[a-z][\w-]+)*)?$/;function ta(e){let t=[];for(let n of e){let e=n.name;e.startsWith(`kickjs.`)||ea.test(e)||t.push({token:e,variable:n.variable,filePath:n.relativePath,reason:"does not match `<scope>/<PascalKey>[/<suffix>][:<instance>]`",suggestion:na(e)})}return t}function na(e){if(/^[A-Z]\w*$/.test(e))return`'<scope>/${e}' (e.g. 'mycorp/${e}')`;if(e.includes(`.`))return`consider '<scope>/PascalKey' instead of dotted form`;let t=/^([a-z][\w-]*)\/([a-z]\w*)$/.exec(e);if(t){let[,e,n]=t;return`'${e}/${n.charAt(0).toUpperCase()}${n.slice(1)}'`}}function ra(e,t){if(!e)return{entries:[],count:0};let n=new Map;for(let[r,i]of Object.entries(e)){if(!i||typeof i.src!=`string`)continue;let e=v(t,i.src);if(!ca(e))continue;let a=pe(i.glob??`**/*`,{cwd:e,nodir:!0,dot:!1,posix:!0});a.sort();let{pairs:o}=me(r,a,{strategy:i.keys??`auto`});for(let{key:e}of o){let t=e.slice(r.length+1);n.set(e,{namespace:r,key:t})}}return{entries:[...n.values()],count:n.size}}function ia(e){let t="/* 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";if(e.entries.length===0)return`${t}
3765
3765
  declare module '@forinda/kickjs' {
3766
3766
  /**
3767
3767
  * Map of every typed asset discovered in the project's assetMap.
@@ -3772,7 +3772,7 @@ declare module '@forinda/kickjs' {
3772
3772
  }
3773
3773
 
3774
3774
  export {}
3775
- `;let n={};for(let t of e.entries){let e=`${t.namespace}/${t.key}`.split(`/`),r=n;for(let t=0;t<e.length-1;t++){let n=e[t],i=r[n];if(i===na){let e={};r[n]=e,r=e}else i||(r[n]={}),r=r[n]}let i=e[e.length-1];typeof r[i]!=`object`&&(r[i]=na)}return`${t}
3775
+ `;let n={};for(let t of e.entries){let e=`${t.namespace}/${t.key}`.split(`/`),r=n;for(let t=0;t<e.length-1;t++){let n=e[t],i=r[n];if(i===aa){let e={};r[n]=e,r=e}else i||(r[n]={}),r=r[n]}let i=e[e.length-1];typeof r[i]!=`object`&&(r[i]=aa)}return`${t}
3776
3776
  declare module '@forinda/kickjs' {
3777
3777
  /**
3778
3778
  * Map of every typed asset discovered in the project's assetMap.
@@ -3781,30 +3781,30 @@ declare module '@forinda/kickjs' {
3781
3781
  * prod → dist).
3782
3782
  */
3783
3783
  interface KickAssets {
3784
- ${ra(n,` `)}
3784
+ ${oa(n,` `)}
3785
3785
  }
3786
3786
  }
3787
3787
 
3788
3788
  export {}
3789
- `}const na=Symbol(`asset-leaf`);function ra(e,t){let n=Object.keys(e).toSorted(),r=[];for(let i of n){let n=e[i],a=ia(i)?i:JSON.stringify(i);n===na?r.push(`${t}${a}: () => string`):(r.push(`${t}${a}: {`),r.push(ra(n,`${t} `)),r.push(`${t}}`))}return r.join(`
3790
- `)}function ia(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function aa(e){try{return c(e).isDirectory()}catch{return!1}}var oa=D({runTypegen:()=>K,sweepStaleTypegen:()=>ua,watchTypegen:()=>ca});function sa(e){let t=e.cwd??process.cwd();return{cwd:t,srcDir:v(t,e.srcDir??`src`),outDir:v(t,e.outDir??`.kickjs/types`),silent:e.silent??!1,allowDuplicates:e.allowDuplicates??!1,schemaValidator:e.schemaValidator??!1,envFile:e.envFile??`src/env.ts`}}async function K(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,schemaValidator:o,envFile:s}=sa(e),c=Date.now(),l=await zi({root:n,cwd:t,envFile:s===!1?void 0:s}),u=ea(e.assetMap,t),d=await Xi({classes:l.classes,routes:l.routes,tokens:l.tokens,injects:l.injects,collisions:l.collisions,env:s===!1?null:l.env,pluginsAndAdapters:l.pluginsAndAdapters,augmentations:l.augmentations,assets:u,outDir:r,allowDuplicates:a,schemaValidator:o}),f=[];if(e.runPlugins!==!1)try{let{runAllPluginTypegens:e}=await Promise.resolve().then(()=>xa),{loadKickConfig:n}=await Promise.resolve().then(()=>Me);f=await e({cwd:t,config:await n(t),silent:!0})}catch(e){if(!i){let t=e instanceof Error?e.message:String(e);console.warn(` kick typegen: plugin pipeline failed (${t}) — continuing`)}}e.runPlugins!==!1&&await ua(r,d.written,f,i);let p=Qi(l.tokens),m=Date.now()-c;if(!i){let e=r.replace(t+`/`,``),n=d.resolvedCollisions>0?`, ${d.resolvedCollisions} collisions namespaced`:``,i=d.envWritten?`, env typed`:``,a=d.pluginEntries>0?`, ${d.pluginEntries} plugins/adapters`:``,o=d.augmentationEntries>0?`, ${d.augmentationEntries} augmentations`:``,s=d.assetEntries>0?`, ${d.assetEntries} assets`:``;if(console.log(` kick typegen → ${d.serviceTokens} services, ${d.routeEntries} routes, ${d.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${m}ms)`),p.length>0){console.warn(` kick typegen: ${p.length} token(s) don't match the §22.2 convention:`);for(let e of p){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}if(l.orphanedClasses.length>0){console.warn(` kick typegen: ${l.orphanedClasses.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let e of l.orphanedClasses)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`),console.warn(` → not picked up by any glob in ${e.moduleFilePath}`)}}return{scan:l,result:d,tokenWarnings:p}}async function ca(e={}){let t=sa(e),{srcDir:n,silent:r,cwd:i}=t,a={...t,allowDuplicates:!0,runPlugins:!1},o=process.env.KICKJS_WATCH_POLLING===`1`||process.env.KICKJS_WATCH_POLLING===`true`,[{runAllPluginTypegens:s},{loadKickConfig:c}]=await Promise.all([Promise.resolve().then(()=>xa),Promise.resolve().then(()=>Me)]),l=await c(i),u=[],d=async()=>{try{u=(await K({...a})).result.written}catch(e){if(r)return;if(e instanceof Vi)console.error(`
3789
+ `}const aa=Symbol(`asset-leaf`);function oa(e,t){let n=Object.keys(e).toSorted(),r=[];for(let i of n){let n=e[i],a=sa(i)?i:JSON.stringify(i);n===aa?r.push(`${t}${a}: () => string`):(r.push(`${t}${a}: {`),r.push(oa(n,`${t} `)),r.push(`${t}}`))}return r.join(`
3790
+ `)}function sa(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function ca(e){try{return c(e).isDirectory()}catch{return!1}}var la=D({runTypegen:()=>K,sweepStaleTypegen:()=>pa,watchTypegen:()=>da});function ua(e){let t=e.cwd??process.cwd();return{cwd:t,srcDir:v(t,e.srcDir??`src`),outDir:v(t,e.outDir??`.kickjs/types`),silent:e.silent??!1,allowDuplicates:e.allowDuplicates??!1,schemaValidator:e.schemaValidator??!1,envFile:e.envFile??`src/env.ts`}}async function K(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,schemaValidator:o,envFile:s}=ua(e),c=Date.now(),l=await Hi({root:n,cwd:t,envFile:s===!1?void 0:s}),u=ra(e.assetMap,t),d=await $i({classes:l.classes,routes:l.routes,tokens:l.tokens,injects:l.injects,collisions:l.collisions,env:s===!1?null:l.env,pluginsAndAdapters:l.pluginsAndAdapters,augmentations:l.augmentations,assets:u,outDir:r,allowDuplicates:a,schemaValidator:o}),f=[];if(e.runPlugins!==!1)try{let{runAllPluginTypegens:e}=await Promise.resolve().then(()=>wa),{loadKickConfig:n}=await Promise.resolve().then(()=>Me);f=await e({cwd:t,config:await n(t),silent:!0})}catch(e){if(!i){let t=e instanceof Error?e.message:String(e);console.warn(` kick typegen: plugin pipeline failed (${t}) — continuing`)}}e.runPlugins!==!1&&await pa(r,d.written,f,i);let p=ta(l.tokens),m=Date.now()-c;if(!i){let e=r.replace(t+`/`,``),n=d.resolvedCollisions>0?`, ${d.resolvedCollisions} collisions namespaced`:``,i=d.envWritten?`, env typed`:``,a=d.pluginEntries>0?`, ${d.pluginEntries} plugins/adapters`:``,o=d.augmentationEntries>0?`, ${d.augmentationEntries} augmentations`:``,s=d.assetEntries>0?`, ${d.assetEntries} assets`:``;if(console.log(` kick typegen → ${d.serviceTokens} services, ${d.routeEntries} routes, ${d.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${m}ms)`),p.length>0){console.warn(` kick typegen: ${p.length} token(s) don't match the §22.2 convention:`);for(let e of p){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}if(l.orphanedClasses.length>0){console.warn(` kick typegen: ${l.orphanedClasses.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let e of l.orphanedClasses)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`),console.warn(` → not picked up by any glob in ${e.moduleFilePath}`)}}return{scan:l,result:d,tokenWarnings:p}}async function da(e={}){let t=ua(e),{srcDir:n,silent:r,cwd:i}=t,a={...t,allowDuplicates:!0,runPlugins:!1},o=process.env.KICKJS_WATCH_POLLING===`1`||process.env.KICKJS_WATCH_POLLING===`true`,[{runAllPluginTypegens:s},{loadKickConfig:c}]=await Promise.all([Promise.resolve().then(()=>wa),Promise.resolve().then(()=>Me)]),l=await c(i),u=[],d=async()=>{try{u=(await K({...a})).result.written}catch(e){if(r)return;if(e instanceof Wi)console.error(`
3791
3791
  `+e.message+`
3792
- `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}},f=async()=>{try{let e=await s({cwd:i,config:l,silent:!0});await ua(t.outDir,u,e,!0)}catch{}};await d(),await f();let{watch:p}=await import(`node:fs`),m=null,h=e=>{e&&/\.(ts|tsx|mts|cts)$/.test(e)&&(e.includes(`.kickjs`)||e.endsWith(`.d.ts`)||(m&&clearTimeout(m),m=setTimeout(()=>{d().then(f)},100)))};if(o){r||console.log(` kick typegen: polling mode (KICKJS_WATCH_POLLING)`);let e=setInterval(()=>{la({...a,silent:!0},!0)},2e3);return()=>clearInterval(e)}let g;try{g=p(n,{recursive:!0},(e,t)=>{h(t)})}catch(e){r||console.warn(` kick typegen: watch mode unavailable (${e?.message??e}). Falling back to polling.`);let t=setInterval(()=>{la({...a,silent:!0},!0)},2e3);return()=>clearInterval(t)}return()=>{m&&clearTimeout(m),g.close()}}async function la(e,t){try{await K(e)}catch(e){if(t)return;if(e instanceof Vi)console.error(`
3792
+ `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}},f=async()=>{try{let e=await s({cwd:i,config:l,silent:!0});await pa(t.outDir,u,e,!0)}catch{}};await d(),await f();let{watch:p}=await import(`node:fs`),m=null,h=e=>{e&&/\.(ts|tsx|mts|cts)$/.test(e)&&(e.includes(`.kickjs`)||e.endsWith(`.d.ts`)||(m&&clearTimeout(m),m=setTimeout(()=>{d().then(f)},100)))};if(o){r||console.log(` kick typegen: polling mode (KICKJS_WATCH_POLLING)`);let e=setInterval(()=>{fa({...a,silent:!0},!0)},2e3);return()=>clearInterval(e)}let g;try{g=p(n,{recursive:!0},(e,t)=>{h(t)})}catch(e){r||console.warn(` kick typegen: watch mode unavailable (${e?.message??e}). Falling back to polling.`);let t=setInterval(()=>{fa({...a,silent:!0},!0)},2e3);return()=>clearInterval(t)}return()=>{m&&clearTimeout(m),g.close()}}async function fa(e,t){try{await K(e)}catch(e){if(t)return;if(e instanceof Wi)console.error(`
3793
3793
  `+e.message+`
3794
- `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}}async function ua(e,t,n,r){let i=new Set;for(let e of t)i.add(d(e));for(let e of n)e.outFile&&i.add(d(e.outFile));let a;try{a=await se(e)}catch{return[]}let o=[];for(let t of a){if(i.has(t))continue;let n=v(e,t);try{if(!(await le(n)).isFile())continue;await ue(n),o.push(t)}catch{}}return o.length>0&&!r&&console.log(` kick typegen: swept ${o.length} stale file(s): ${o.join(`, `)}`),o}const da=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`both`,`all`];function q(e){return e.parent?.opts()?.dryRun??!1}function J(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(`
3795
- (dry run — no files were written)`),console.log()}async function fa(e){if(!e)try{let e=await k(process.cwd());await K({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 pa=[{name:`module <name>`,description:`Full DDD module (controller, DTOs, use-cases, 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:`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:`job <name>`,description:`Queue @Job processor`},{name:`config`,description:`Generate kick.config.ts`},{name:`agents`,description:`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md from upstream templates`}];async function ma(){console.log(`
3794
+ `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}}async function pa(e,t,n,r){let i=new Set;for(let e of t)i.add(d(e));for(let e of n)e.outFile&&i.add(d(e.outFile));let a;try{a=await se(e)}catch{return[]}let o=[];for(let t of a){if(i.has(t))continue;let n=v(e,t);try{if(!(await le(n)).isFile())continue;await ue(n),o.push(t)}catch{}}return o.length>0&&!r&&console.log(` kick typegen: swept ${o.length} stale file(s): ${o.join(`, `)}`),o}const ma=[`agents`,`claude`,`skills`,`gemini`,`copilot`,`both`,`all`];function q(e){return e.parent?.opts()?.dryRun??!1}function J(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(`
3795
+ (dry run — no files were written)`),console.log()}async function ha(e){if(!e)try{let e=await k(process.cwd());await K({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 ga=[{name:`module <name>`,description:`Full DDD module (controller, DTOs, use-cases, 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:`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:`job <name>`,description:`Queue @Job processor`},{name:`config`,description:`Generate kick.config.ts`},{name:`agents`,description:`Regenerate AGENTS.md + CLAUDE.md + kickjs-skills.md from upstream templates`}];async function _a(){console.log(`
3796
3796
  Built-in generators:
3797
- `);let e=Math.max(...pa.map(e=>e.name.length));for(let t of pa)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await k(process.cwd()),n=He(t?.plugins??[],t?.commands??[]),r=await cn(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
3797
+ `);let e=Math.max(...ga.map(e=>e.name.length));for(let t of ga)console.log(` kick g ${t.name.padEnd(e+2)} ${t.description}`);let t=await k(process.cwd()),n=He(t?.plugins??[],t?.commands??[]),r=await dn(process.cwd(),n.generators);if(r.generators.length>0){console.log(`
3798
3798
  Plugin generators:
3799
3799
  `);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(`
3800
3800
  Failed to load:
3801
- `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function ha(e,t,n){let r=await k(process.cwd()),i=O(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??Jn(i.repo),s=t.pattern??r?.pattern??`ddd`,c=t.pluralize===!1?!1:i.pluralize??!0,l=Ie(r,process.cwd()),u=i.style??`define`;if(!n&&u===`define`){let e=await Mr(v(a),`define`);if(e.length>0){console.error(`\n ${E.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${E.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${E.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 ${E.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${E.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${E.dim(`// kick.config.ts`)}\n ${E.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let d=[];for(let r of e){let e=await Yn({name:r,modulesDir:v(a),noEntity:t.entity===!1,noTests:t.tests===!1,repo:o,minimal:t.minimal,force:t.force,pattern:s,dryRun:n,pluralize:c,prismaClientPath:i.prismaClientPath,tokenScope:l,style:i.style});d.push(...e)}J(d,n),await fa(n)}function ga(e,t){let n=e.command(`generate [names...]`).alias(`g`).description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option(`--list`,`List all available generators`).option(`--dry-run`,`Preview files that would be generated without writing them`).option(`--no-entity`,`Skip entity and value object generation (module shortcut)`).option(`--no-tests`,`Skip test file generation (module shortcut)`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,r)=>{if(t.list){await ma();return}if(!e||e.length===0){n.help();return}let i=q(r);j(i);let[a,o,...s]=e;if(a){let e=await k(process.cwd()),n=He(e?.plugins??[],e?.commands??[]),r=await sn({generatorName:a,itemName:o??``,args:s,flags:t,cwd:process.cwd()},n.generators);if(r){J(r.files,i);return}}await ha(e,t,i)});n.command(`module <names...>`).description(`Generate one or more modules (e.g. kick g module user task project)`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,n)=>{let r=q(n);j(r),await ha(e,{...n.optsWithGlobals(),...t},r)}),n.command(`adapter <name>`).description(`Generate an AppAdapter with lifecycle hooks and middleware support`).option(`-o, --out <dir>`,`Output directory`,`src/adapters`).action(async(e,t,n)=>{let r=q(n);j(r),J(await rr({name:e,outDir:v(t.out)}),r)}),n.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(e,t,n)=>{let r=q(n);j(r),J(await ir({name:e,outDir:v(t.out)}),r)}),n.command(`middleware <name>`).description(`Generate an Express middleware function
3802
- 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await lr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
3803
- 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await ur({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`service <name>`).description(`Generate a @Service() class
3804
- 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await dr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
3805
- 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await fr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r),await fa(r)}),n.command(`dto <name>`).description(`Generate a Zod DTO schema
3806
- 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await pr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`test <name>`).description(`Generate a Vitest test scaffold
3807
- 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(e,t,n)=>{let r=q(n);j(r);let i=O(await k(process.cwd())),a=i.dir??`src/modules`;J(await Yr({name:e,outDir:t.out,moduleName:t.module,modulesDir:a,pluralize:i.pluralize??!0}),r)}),n.command(`job <name>`).description(`Generate a @Job queue processor with @Process handlers`).option(`-o, --out <dir>`,`Output directory`,`src/jobs`).option(`-q, --queue <name>`,`Queue name (default: <name>-queue)`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Nr({name:e,outDir:v(t.out),queue:t.queue}),r)}),n.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3801
+ `);for(let{source:e,reason:t}of r.failed)console.log(` ${e} — ${t}`)}console.log()}async function va(e,t,n){let r=await k(process.cwd()),i=O(r),a=t.modulesDir??i.dir??`src/modules`,o=t.repo??Zn(i.repo),s=t.pattern??r?.pattern??`ddd`,c=t.pluralize===!1?!1:i.pluralize??!0,l=Ie(r,process.cwd()),u=i.style??`define`;if(!n&&u===`define`){let e=await Fr(v(a),`define`);if(e.length>0){console.error(`\n ${E.red(`Error:`)} ${e.length} module file(s) still use the legacy \`class … implements AppModule\` shape.\n ${E.dim(`Project setting:`)} modules.style: 'define' (default)\n\n ${E.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 ${E.bold(`Pick one:`)}\n 1. Migrate everything to defineModule:\n ${E.dim(`$`)} kick codemod modules --experimental --apply\n 2. Keep the class form — pin it in kick.config.ts:\n ${E.dim(`// kick.config.ts`)}\n ${E.dim(`export default defineConfig({ modules: { style: 'class' } })`)}\n`),process.exit(1)}}let d=[];for(let r of e){let e=await Qn({name:r,modulesDir:v(a),noEntity:t.entity===!1,noTests:t.tests===!1,repo:o,minimal:t.minimal,force:t.force,pattern:s,dryRun:n,pluralize:c,prismaClientPath:i.prismaClientPath,tokenScope:l,style:i.style});d.push(...e)}J(d,n),await ha(n)}function ya(e,t){let n=e.command(`generate [names...]`).alias(`g`).description("Generate code scaffolds — bare form `kick g <name>` is shorthand for `kick g module <name>`").option(`--list`,`List all available generators`).option(`--dry-run`,`Preview files that would be generated without writing them`).option(`--no-entity`,`Skip entity and value object generation (module shortcut)`).option(`--no-tests`,`Skip test file generation (module shortcut)`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,r,i)=>{if(r.list){await _a();return}if(!e||e.length===0){n.help();return}let a=q(i);j(a);let[o,s,...c]=e;if(o){let e=await k(process.cwd()),n=He(e?.plugins??[],e?.commands??[]),i=await un({generatorName:o,itemName:s??``,args:c,flags:r,cwd:process.cwd(),projectRoot:t?.projectRoot},n.generators);if(i){J(i.files,a);return}}await va(e,r,a)});n.command(`module <names...>`).description(`Generate one or more modules (e.g. kick g module user task project)`).option(`--no-entity`,`Skip entity and value object generation`).option(`--no-tests`,`Skip test file generation`).option(`--repo <type>`,`Repository implementation: inmemory | drizzle | prisma`).option(`--pattern <pattern>`,`Override project pattern: rest | ddd | cqrs | minimal`).option(`--minimal`,`Shorthand for --pattern minimal`).option(`--modules-dir <dir>`,`Modules directory`).option(`--no-pluralize`,`Use singular names (skip auto-pluralization)`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t,n)=>{let r=q(n);j(r),await va(e,{...n.optsWithGlobals(),...t},r)}),n.command(`adapter <name>`).description(`Generate an AppAdapter with lifecycle hooks and middleware support`).option(`-o, --out <dir>`,`Output directory`,`src/adapters`).action(async(e,t,n)=>{let r=q(n);j(r),J(await or({name:e,outDir:v(t.out)}),r)}),n.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(e,t,n)=>{let r=q(n);j(r),J(await sr({name:e,outDir:v(t.out)}),r)}),n.command(`middleware <name>`).description(`Generate an Express middleware function
3802
+ 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await fr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`guard <name>`).description(`Generate a route guard (auth, roles, etc.)
3803
+ 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await pr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`service <name>`).description(`Generate a @Service() class
3804
+ 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await mr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`controller <name>`).description(`Generate a @Controller() class with basic routes
3805
+ 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await hr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r),await ha(r)}),n.command(`dto <name>`).description(`Generate a Zod DTO schema
3806
+ 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(e,t,n)=>{let r=q(n);j(r);let i=await k(process.cwd()),a=O(i),o=a.dir??`src/modules`;J(await gr({name:e,outDir:t.out,moduleName:t.module,modulesDir:o,pattern:i?.pattern,pluralize:a.pluralize??!0}),r)}),n.command(`test <name>`).description(`Generate a Vitest test scaffold
3807
+ 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(e,t,n)=>{let r=q(n);j(r);let i=O(await k(process.cwd())),a=i.dir??`src/modules`;J(await Qr({name:e,outDir:t.out,moduleName:t.module,modulesDir:a,pluralize:i.pluralize??!0}),r)}),n.command(`job <name>`).description(`Generate a @Job queue processor with @Process handlers`).option(`-o, --out <dir>`,`Output directory`,`src/jobs`).option(`-q, --queue <name>`,`Queue name (default: <name>-queue)`).action(async(e,t,n)=>{let r=q(n);j(r),J(await Ir({name:e,outDir:v(t.out),queue:t.queue}),r)}),n.command(`scaffold <name> [fields...]`).description(`Generate a full CRUD module from field definitions
3808
3808
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3809
3809
  Types: string, text, number, int, float, boolean, date, email, url, uuid, json, enum:a,b,c
3810
3810
  Optional: append :optional (shell-safe): description:text:optional
@@ -3813,11 +3813,11 @@ export {}
3813
3813
  Usage: kick g scaffold <name> <field:type> [field:type...]
3814
3814
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
3815
3815
  Optional: append :optional (shell-safe, no quoting needed)
3816
- `),process.exit(1));let a=await k(process.cwd()),o=O(a),s=n.modulesDir??o.dir??`src/modules`,c=Fr(t),l=Ie(a,process.cwd()),u=a?.pattern??`ddd`;u!==`ddd`&&(console.error(`\n Error: 'kick g scaffold' currently only supports the DDD pattern.\n Detected project pattern: '${u}'.\n Workarounds:\n - Run 'kick g module ${e}' for the ${u} layout (no fields), then add fields manually.\n - Override the pattern for this scaffold by setting kick.config.ts pattern: 'ddd'.\n`),process.exit(1));let d=await Ir({name:e,fields:c,modulesDir:v(s),noEntity:n.entity===!1,noTests:n.tests===!1,pluralize:n.pluralize===!1?!1:o.pluralize??!0,tokenScope:l,style:o.style});console.log(`\n Scaffolded ${e} with ${c.length} field(s):`);for(let e of c)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);J(d,i),await fa(i)}),n.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Default repository type: inmemory | drizzle | prisma`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(e,t)=>{let n=q(t);j(n),J(await mr({outDir:v(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),n)}),n.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 | ddd | cqrs | minimal`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t)=>{let n=q(t);j(n);let r=e.only??`all`;if(!da.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${da.join(` | `)}`),process.exitCode=1;return}J(await br({outDir:v(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)});for(let e of t?.generators??[])_a(n,e)}function _a(e,t){let{source:n,spec:r}=t,i=r.args?.[0],a=i?.name??`itemName`,o=i?.required?`<${a}>`:`[${a}]`,s=`${r.name} ${o} [extraArgs...]`,c=e.command(s).description(`${r.description} [${n}]`);for(let e of r.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;c.option(n,e.description??``)}c.action(async(e,n,i,a)=>{let o=q(a);j(o);let s=await sn({generatorName:r.name,itemName:e??``,args:n??[],flags:i,cwd:process.cwd()},[t]);s&&J(s.files,o)})}async function va(e){let t=u.resolve(e.cwd,`.kickjs/types`);await oe(t,{recursive:!0});let n=new Map,i=e.scan??zi,a={cwd:e.cwd,config:e.config,async importTs(e){return await import(x(e).href)},async writeFile(t,n){let r=u.resolve(e.cwd,t);await oe(u.dirname(r),{recursive:!0}),await w(r,n,`utf8`)},getScanResult:e=>{let t=ya(e),r=n.get(t);return r||(r=i(e),n.set(t,r)),r},log:console},o=[];for(let n of e.plugins){let i=await n.generate(a);if(i===null){o.push({id:n.id,status:`skipped`});continue}let s=n.outExtension??`.d.ts`,c=u.join(t,`${n.id.replace(/\//g,`__`)}${s}`),l=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+i+`
3817
- `,d=``;if(r(c)&&(d=await C(c,`utf8`)),d===l){o.push({id:n.id,status:`unchanged`,outFile:c});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${c})`);await w(c,l,`utf8`),o.push({id:n.id,status:`written`,outFile:c})}return o}function ya(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 ba(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))}}var xa=D({applyDisableFilter:()=>ba,runAllPluginTypegens:()=>Sa});async function Sa(e){let{enabled:t,skipped:n,unknown:r}=ba(He([...ls,...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 va({cwd:e.cwd,config:e.config??{},plugins:t,check:e.check});if(!e.silent)for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}async function Ca(e,t){let{cwd:n,silent:r=!1}=t,a=t.distDir??e?.build?.outDir??`dist`,o=e?.assetMap;if(!o||Object.keys(o).length===0)return null;let s=r?()=>{}:console.log,c=v(n,a);i(c,{recursive:!0});let u=[],d={};for(let[e,t]of Object.entries(o)){let r=await wa(e,t,n,c);u.push(r.entrySummary),Object.assign(d,r.manifestSlice),s(` ✓ ${e}: ${r.entrySummary.filesCopied} file(s) → ${r.entrySummary.dest}`)}let f={version:1,entries:d},p=h(c,`.kickjs-assets.json`);return l(p,JSON.stringify(f,null,2)+`
3818
- `,`utf-8`),s(` ✓ wrote manifest → ${_(n,p)} (${Object.keys(d).length} entries)`),{manifestPath:p,entries:u,manifest:f}}async function wa(e,t,a,o){let s=v(a,t.src),c=t.dest?v(a,t.dest):h(o,e);if(Ea(c,a))return console.warn(` ⚠ assetMap.${e}.dest ('${t.dest}') resolves outside the project root — skipping copy`),{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};if(!r(s)||!Da(s))return{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};let l=await fe(t.glob??`**/*`,{cwd:s,nodir:!0,dot:!1,posix:!0});i(c,{recursive:!0});let u={},{pairs:d,collisionGroupsResolved:p}=me(e,[...l].toSorted(),{strategy:t.keys??`auto`});for(let{rel:e,key:t}of d){let r=h(s,e),a=h(c,e);i(f(a),{recursive:!0}),n(r,a),u[t]=Ta(o,a)}return p>0&&console.log(` ℹ assetMap.${e}: auto-resolved ${p} basename collision(s) by keeping extensions (set 'keys: "strip"' to opt back into legacy last-write-wins behaviour, or 'keys: "with-extension"' to keep all keys verbose).`),{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:l.length},manifestSlice:u}}function Ta(e,t){return _(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function Ea(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function Da(e){try{return c(e).isDirectory()}catch{return!1}}function Oa(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function ka(e,t,n={}){t&&(process.env.PORT=t);let r=Oa(n.polling),i=process.cwd(),a=await k(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await K({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})`)}await Sa({cwd:i,config:a});let{createRequire:c}=await import(`node:module`),{createServer:l}=await import(x(c(v(`package.json`)).resolve(`vite`)).href),u=await l({configFile:v(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),d=a?.assetMap?Object.values(a.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>v(i,e)):[],f=e=>d.some(t=>e===t||e.startsWith(`${t}/`)),p=null,m=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=f(e);!t&&!n||(p&&clearTimeout(p),p=setTimeout(()=>{K({cwd:i,silent:!0,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1}).catch(()=>{}),Sa({cwd:i,config:a,silent:!0}).catch(()=>{})},100))};u.watcher.on(`add`,m),u.watcher.on(`unlink`,m),u.watcher.on(`change`,m),d.length>0&&u.watcher.add(d),await u.listen(),u.printUrls(),console.log(`
3816
+ `),process.exit(1));let a=await k(process.cwd()),o=O(a),s=n.modulesDir??o.dir??`src/modules`,c=Rr(t),l=Ie(a,process.cwd()),u=a?.pattern??`ddd`;u!==`ddd`&&(console.error(`\n Error: 'kick g scaffold' currently only supports the DDD pattern.\n Detected project pattern: '${u}'.\n Workarounds:\n - Run 'kick g module ${e}' for the ${u} layout (no fields), then add fields manually.\n - Override the pattern for this scaffold by setting kick.config.ts pattern: 'ddd'.\n`),process.exit(1));let d=await zr({name:e,fields:c,modulesDir:v(s),noEntity:n.entity===!1,noTests:n.tests===!1,pluralize:n.pluralize===!1?!1:o.pluralize??!0,tokenScope:l,style:o.style});console.log(`\n Scaffolded ${e} with ${c.length} field(s):`);for(let e of c)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);J(d,i),await ha(i)}),n.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Default repository type: inmemory | drizzle | prisma`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(e,t)=>{let n=q(t);j(n),J(await _r({outDir:v(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),n)}),n.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 | ddd | cqrs | minimal`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,t)=>{let n=q(t);j(n);let r=e.only??`all`;if(!ma.includes(r)){console.error(` Invalid --only value: ${r}. Expected: ${ma.join(` | `)}`),process.exitCode=1;return}J(await Cr({outDir:v(`.`),only:r,name:e.name,pm:e.pm,template:e.template,force:e.force}),n)});for(let e of t?.generators??[])ba(n,e,t?.projectRoot)}function ba(e,t,n){let{source:r,spec:i}=t,a=i.args?.[0],o=a?.name??`itemName`,s=a?.required?`<${o}>`:`[${o}]`,c=`${i.name} ${s} [extraArgs...]`,l=e.command(c).description(`${i.description} [${r}]`);for(let e of i.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;l.option(n,e.description??``)}l.action(async(e,r,a,o)=>{let s=q(o);j(s);let c=await un({generatorName:i.name,itemName:e??``,args:r??[],flags:a,cwd:process.cwd(),projectRoot:n},[t]);c&&J(c.files,s)})}async function xa(e){let t=u.resolve(e.cwd,`.kickjs/types`);await oe(t,{recursive:!0});let n=new Map,i=e.scan??Hi,a={cwd:e.cwd,config:e.config,async importTs(e){return await import(x(e).href)},async writeFile(t,n){let r=u.resolve(e.cwd,t);await oe(u.dirname(r),{recursive:!0}),await w(r,n,`utf8`)},getScanResult:e=>{let t=Sa(e),r=n.get(t);return r||(r=i(e),n.set(t,r)),r},log:console},o=[];for(let n of e.plugins){let i=await n.generate(a);if(i===null){o.push({id:n.id,status:`skipped`});continue}let s=n.outExtension??`.d.ts`,c=u.join(t,`${n.id.replace(/\//g,`__`)}${s}`),l=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: ${n.id} */\n\n`+i+`
3817
+ `,d=``;if(r(c)&&(d=await C(c,`utf8`)),d===l){o.push({id:n.id,status:`unchanged`,outFile:c});continue}if(e.check)throw Error(`kick typegen --check: drift detected for ${n.id} (${c})`);await w(c,l,`utf8`),o.push({id:n.id,status:`written`,outFile:c})}return o}function Sa(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 Ca(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))}}var wa=D({applyDisableFilter:()=>Ca,runAllPluginTypegens:()=>Ta});async function Ta(e){let{enabled:t,skipped:n,unknown:r}=Ca(He([...ls,...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 xa({cwd:e.cwd,config:e.config??{},plugins:t,check:e.check});if(!e.silent)for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}async function Ea(e,t){let{cwd:n,silent:r=!1}=t,a=t.distDir??e?.build?.outDir??`dist`,o=e?.assetMap;if(!o||Object.keys(o).length===0)return null;let s=r?()=>{}:console.log,c=v(n,a);i(c,{recursive:!0});let u=[],d={};for(let[e,t]of Object.entries(o)){let r=await Da(e,t,n,c);u.push(r.entrySummary),Object.assign(d,r.manifestSlice),s(` ✓ ${e}: ${r.entrySummary.filesCopied} file(s) → ${r.entrySummary.dest}`)}let f={version:1,entries:d},p=h(c,`.kickjs-assets.json`);return l(p,JSON.stringify(f,null,2)+`
3818
+ `,`utf-8`),s(` ✓ wrote manifest → ${_(n,p)} (${Object.keys(d).length} entries)`),{manifestPath:p,entries:u,manifest:f}}async function Da(e,t,a,o){let s=v(a,t.src),c=t.dest?v(a,t.dest):h(o,e);if(ka(c,a))return console.warn(` ⚠ assetMap.${e}.dest ('${t.dest}') resolves outside the project root — skipping copy`),{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};if(!r(s)||!Aa(s))return{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:0},manifestSlice:{}};let l=await fe(t.glob??`**/*`,{cwd:s,nodir:!0,dot:!1,posix:!0});i(c,{recursive:!0});let u={},{pairs:d,collisionGroupsResolved:p}=me(e,[...l].toSorted(),{strategy:t.keys??`auto`});for(let{rel:e,key:t}of d){let r=h(s,e),a=h(c,e);i(f(a),{recursive:!0}),n(r,a),u[t]=Oa(o,a)}return p>0&&console.log(` ℹ assetMap.${e}: auto-resolved ${p} basename collision(s) by keeping extensions (set 'keys: "strip"' to opt back into legacy last-write-wins behaviour, or 'keys: "with-extension"' to keep all keys verbose).`),{entrySummary:{namespace:e,src:t.src,dest:_(a,c),filesCopied:l.length},manifestSlice:u}}function Oa(e,t){return _(e,t).split(/[\\/]/).filter(Boolean).join(`/`)}function ka(e,t){let n=_(t,e);return n===``?!1:n.startsWith(`..`)||m(n)}function Aa(e){try{return c(e).isDirectory()}catch{return!1}}function ja(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function Ma(e,t,n={}){t&&(process.env.PORT=t);let r=ja(n.polling),i=process.cwd(),a=await k(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await K({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})`)}await Ta({cwd:i,config:a});let{createRequire:c}=await import(`node:module`),{createServer:l}=await import(x(c(v(`package.json`)).resolve(`vite`)).href),u=await l({configFile:v(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),d=a?.assetMap?Object.values(a.assetMap).map(e=>e?.src).filter(e=>typeof e==`string`&&e.length>0).map(e=>v(i,e)):[],f=e=>d.some(t=>e===t||e.startsWith(`${t}/`)),p=null,m=e=>{if(e.includes(`.kickjs`)||e.endsWith(`.d.ts`))return;let t=/\.(ts|tsx|mts|cts)$/.test(e),n=f(e);!t&&!n||(p&&clearTimeout(p),p=setTimeout(()=>{K({cwd:i,silent:!0,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1}).catch(()=>{}),Ta({cwd:i,config:a,silent:!0}).catch(()=>{})},100))};u.watcher.on(`add`,m),u.watcher.on(`unlink`,m),u.watcher.on(`change`,m),d.length>0&&u.watcher.add(d),await u.listen(),u.printUrls(),console.log(`
3819
3819
  KickJS dev server running (Vite + @forinda/kickjs-vite)
3820
- `);let h=async()=>{p&&clearTimeout(p),await u.close(),process.exit(0)};process.on(`SIGINT`,h),process.on(`SIGTERM`,h)}function Aa(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)`).action(async e=>{try{await ka(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3820
+ `);let h=async()=>{p&&clearTimeout(p),await u.close(),process.exit(0)};process.on(`SIGINT`,h),process.on(`SIGTERM`,h)}function Na(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)`).action(async e=>{try{await Ma(e.entry,e.port,{polling:e.polling})}catch(e){e.code===`ERR_MODULE_NOT_FOUND`&&e.message?.includes(`vite`)?console.error(`
3821
3821
  Error: vite is not installed.
3822
3822
  Run: pnpm add -D vite unplugin-swc
3823
3823
  `):console.error(`
@@ -3825,13 +3825,13 @@ export {}
3825
3825
  Building for production...
3826
3826
  `);let{createRequire:e}=await import(`node:module`),{build:t}=await import(x(e(v(`package.json`)).resolve(`vite`)).href);await t({configFile:v(`vite.config.ts`)});let a=await k(process.cwd()),o=a?.copyDirs??[];if(o.length>0){console.log(`
3827
3827
  Copying directories to dist...`);for(let e of o){let t=typeof e==`string`?e:e.src,a=typeof e==`string`?h(`dist`,e):e.dest??h(`dist`,t),o=v(t),s=v(a);if(!r(o)){console.log(` ⚠ Skipped ${t} (not found)`);continue}i(s,{recursive:!0}),n(o,s,{recursive:!0}),console.log(` ✓ ${t} → ${a}`)}}if(a?.assetMap&&Object.keys(a.assetMap).length>0){console.log(`
3828
- Building asset map...`);try{await Ca(a,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3828
+ Building asset map...`);try{await Ea(a,{cwd:process.cwd()})}catch(e){console.error(` ✗ asset build failed: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}console.log(`
3829
3829
  Build complete.
3830
3830
  `)}),e.command(`build:assets`).description(`Rebuild the .kickjs-assets.json manifest under the configured outDir (no JS rebuild)`).action(async()=>{let e=await k(process.cwd());if(!e?.assetMap||Object.keys(e.assetMap).length===0){console.log(` No assetMap entries — nothing to build.`);return}console.log(`
3831
- Building asset map...`);try{await Ca(e,{cwd:process.cwd()}),console.log(`
3831
+ Building asset map...`);try{await Ea(e,{cwd:process.cwd()}),console.log(`
3832
3832
  Asset build complete.
3833
- `)}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)),ke(e.entry,t)}),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`).action(async e=>{let t=e.inspectPort??`9229`;process.env.NODE_OPTIONS=`--inspect=0.0.0.0:${t}`,console.log(` Debugger: ws://0.0.0.0:${t}`);try{await ka(e.entry,e.port)}catch(e){console.error(`
3834
- Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function ja(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3833
+ `)}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)),ke(e.entry,t)}),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`).action(async e=>{let t=e.inspectPort??`9229`;process.env.NODE_OPTIONS=`--inspect=0.0.0.0:${t}`,console.log(` Debugger: ws://0.0.0.0:${t}`);try{await Ma(e.entry,e.port)}catch(e){console.error(`
3834
+ Dev server (debug) failed:`,e.message??e),process.exit(1)}})}function Pa(e){e.command(`info`).description(`Print system and framework info`).action(()=>{console.log(`
3835
3835
  KickJS CLI
3836
3836
 
3837
3837
  System:
@@ -3842,7 +3842,7 @@ export {}
3842
3842
  @forinda/kickjs workspace
3843
3843
  @forinda/kickjs-vite workspace
3844
3844
  @forinda/kickjs-cli workspace
3845
- `)})}const{bold:Y,dim:X,green:Ma,red:Na,yellow:Pa,blue:Fa}=E;function Ia(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 La(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function Ra(e,t){try{return await La(`${e}${t}`)}catch{return null}}async function za(e){let[t,n,r,i,a]=await Promise.all([Ra(e,`/health`),Ra(e,`/metrics`),Ra(e,`/routes`),Ra(e,`/container`),Ra(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function Ba(e,t){let{health:n,metrics:r,routes:i,container:a,ws:o}=t,s=X(`─`.repeat(60));if(console.log(),console.log(Y(` KickJS Inspector`)+X(` → ${e}`)),console.log(s),n){let e=n.status===`healthy`?Ma(`● healthy`):Na(`● `+n.status);console.log(` ${Y(`Health:`)} ${e}`)}else console.log(` ${Y(`Health:`)} ${Na(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?Na:r.errorRate>0?Pa:Ma;console.log(` ${Y(`Uptime:`)} ${Ia(r.uptimeSeconds)}`),console.log(` ${Y(`Requests:`)} ${r.requests}`),console.log(` ${Y(`Errors:`)} ${r.serverErrors} server, ${r.clientErrors??0} client ${X(`(`)}${t(e+`%`)}${X(`)`)}`)}if(a&&console.log(` ${Y(`DI:`)} ${a.count} bindings`),o&&o.enabled&&console.log(` ${Y(`WS:`)} ${o.connections??0} connections, ${o.namespaces??0} namespaces`),i?.routes?.length){console.log(),console.log(Y(` Routes`)),console.log(s),console.log(` ${X(`METHOD`)} ${X(`PATH`.padEnd(36))} ${X(`CONTROLLER`)}`);for(let e of i.routes){let t=e.path.length>36?e.path.slice(0,33)+`...`:e.path.padEnd(36);console.log(` ${At(e.method)} ${t} ${Fa(e.controller)}.${X(e.handler)}`)}}console.log(s),console.log()}function Va(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 za(r);t.json?console.log(JSON.stringify(e,null,2)):Ba(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(Na(` ✖ Could not connect to ${n}`)),console.error(X(` ${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 Ha(e,t){let n=e.toLowerCase();return t.every(e=>n.includes(e.toLowerCase()))}function Z(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}const Ua=[{match(e,t){let n=Ha(e,[`config`,`get`])&&Z(e,[`undefined`,`null`]),r=e.includes(`@Value`)&&Z(e,[`undefined`,`is not defined`]);return!n&&!r?null:{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
3845
+ `)})}const{bold:Y,dim:X,green:Fa,red:Ia,yellow:La,blue:Ra}=E;function za(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 Ba(e){let t=await fetch(e,{signal:AbortSignal.timeout(5e3)});if(!t.ok)throw Error(`${t.status} ${t.statusText}`);return t.json()}async function Va(e,t){try{return await Ba(`${e}${t}`)}catch{return null}}async function Ha(e){let[t,n,r,i,a]=await Promise.all([Va(e,`/health`),Va(e,`/metrics`),Va(e,`/routes`),Va(e,`/container`),Va(e,`/ws`)]);return{health:t,metrics:n,routes:r,container:i,ws:a}}function Ua(e,t){let{health:n,metrics:r,routes:i,container:a,ws:o}=t,s=X(`─`.repeat(60));if(console.log(),console.log(Y(` KickJS Inspector`)+X(` → ${e}`)),console.log(s),n){let e=n.status===`healthy`?Fa(`● healthy`):Ia(`● `+n.status);console.log(` ${Y(`Health:`)} ${e}`)}else console.log(` ${Y(`Health:`)} ${Ia(`● unreachable`)}`);if(r){let e=((r.errorRate??0)*100).toFixed(1),t=r.errorRate>.1?Ia:r.errorRate>0?La:Fa;console.log(` ${Y(`Uptime:`)} ${za(r.uptimeSeconds)}`),console.log(` ${Y(`Requests:`)} ${r.requests}`),console.log(` ${Y(`Errors:`)} ${r.serverErrors} server, ${r.clientErrors??0} client ${X(`(`)}${t(e+`%`)}${X(`)`)}`)}if(a&&console.log(` ${Y(`DI:`)} ${a.count} bindings`),o&&o.enabled&&console.log(` ${Y(`WS:`)} ${o.connections??0} connections, ${o.namespaces??0} namespaces`),i?.routes?.length){console.log(),console.log(Y(` Routes`)),console.log(s),console.log(` ${X(`METHOD`)} ${X(`PATH`.padEnd(36))} ${X(`CONTROLLER`)}`);for(let e of i.routes){let t=e.path.length>36?e.path.slice(0,33)+`...`:e.path.padEnd(36);console.log(` ${At(e.method)} ${t} ${Ra(e.controller)}.${X(e.handler)}`)}}console.log(s),console.log()}function Wa(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 Ha(r);t.json?console.log(JSON.stringify(e,null,2)):Ua(n,e)}catch(e){t.json?console.log(JSON.stringify({error:String(e)})):(console.error(Ia(` ✖ Could not connect to ${n}`)),console.error(X(` ${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 Ga(e,t){let n=e.toLowerCase();return t.every(e=>n.includes(e.toLowerCase()))}function Z(e,t){let n=e.toLowerCase();return t.some(e=>n.includes(e.toLowerCase()))}const Ka=[{match(e,t){let n=Ga(e,[`config`,`get`])&&Z(e,[`undefined`,`null`]),r=e.includes(`@Value`)&&Z(e,[`undefined`,`is not defined`]);return!n&&!r?null:{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
3846
3846
  registers the env schema with kickjs at module-load time. Without it,
3847
3847
  ConfigService falls back to the base schema (PORT/NODE_ENV/LOG_LEVEL only)
3848
3848
  and every user-defined key reads as undefined. @Value() may *appear* to
@@ -3864,7 +3864,7 @@ describe('UserController', () => {
3864
3864
  beforeEach(() => Container.reset())
3865
3865
 
3866
3866
  it('does the thing', async () => { /* ... */ })
3867
- })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||Ha(e,[`Module`,`is not a function`])||Ha(e,[`Module`,`no exported member`])?{confidence:80,diagnosis:{id:`module-decorator-not-found`,title:`KickJS does not have a @Module decorator (different pattern from NestJS)`,explanation:`NestJS uses @Module({ controllers, providers }). KickJS uses an interface
3867
+ })`,docs:`https://forinda.github.io/kick-js/guide/testing.html`}}:null}},{match(e,t){return e.includes(`@Module`)||Ga(e,[`Module`,`is not a function`])||Ga(e,[`Module`,`no exported member`])?{confidence:80,diagnosis:{id:`module-decorator-not-found`,title:`KickJS does not have a @Module decorator (different pattern from NestJS)`,explanation:`NestJS uses @Module({ controllers, providers }). KickJS uses an interface
3868
3868
  pattern instead: a class implements AppModule and exposes routes() that
3869
3869
  returns the controller wiring. This was a deliberate choice — modules
3870
3870
  become explicit values rather than metadata, which makes them easier to
@@ -3916,24 +3916,24 @@ drop the entry.`,fix:`Open src/modules/index.ts and verify the module is in the
3916
3916
  import { UserModule } from './users/user.module'
3917
3917
  import { TaskModule } from './tasks/task.module' // ← was this missing?
3918
3918
 
3919
- export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function Wa(e,t){let n=null;for(let r of Ua){let i=null;try{i=r.match(e,t)}catch{continue}!i||i.confidence<40||(!n||i.confidence>n.confidence)&&(n=i)}return n}async function Ga(e){let t=e.provider??`openai`,n=process.env.OPENAI_API_KEY;if(t===`openai`&&!n)return{kind:`unavailable`,reason:`OPENAI_API_KEY environment variable is not set`,suggestion:`Set OPENAI_API_KEY in your shell, e.g.
3919
+ export const modules: AppModuleEntry[] = [UserModule(), TaskModule()]`,docs:`https://forinda.github.io/kick-js/guide/project-structure.html`}}:null}}];function qa(e,t){let n=null;for(let r of Ka){let i=null;try{i=r.match(e,t)}catch{continue}!i||i.confidence<40||(!n||i.confidence>n.confidence)&&(n=i)}return n}async function Ja(e){let t=e.provider??`openai`,n=process.env.OPENAI_API_KEY;if(t===`openai`&&!n)return{kind:`unavailable`,reason:`OPENAI_API_KEY environment variable is not set`,suggestion:`Set OPENAI_API_KEY in your shell, e.g.
3920
3920
  export OPENAI_API_KEY="sk-..."
3921
3921
 
3922
3922
  Then re-run \`kick explain --ai "<your error>"\`.`};let r;try{r=await import(`@forinda/kickjs-ai`)}catch{return{kind:`unavailable`,reason:`@forinda/kickjs-ai is not installed`,suggestion:`Install the AI package to enable the LLM fallback:
3923
3923
  kick add ai
3924
3924
 
3925
3925
  Or manually:
3926
- pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=Ka(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=qa((await a.chat({messages:[{role:`system`,content:o},{role:`user`,content:s}]})).content);return e?{kind:`ok`,diagnosis:e}:{kind:`error`,message:`The LLM responded but the payload was not valid JSON in the expected shape. Try again, or file an issue with the error text.`}}catch(e){return{kind:`error`,message:`LLM request failed: ${e instanceof Error?e.message:String(e)}`}}}function Ka(e){return[`You are a diagnostic assistant for KickJS, a decorator-driven Node.js`,`framework built on Express 5 and TypeScript. KickJS projects use:`,` - @Controller, @Get, @Post, @Autowired, @Service, @Value decorators`,` - An AppModule interface with a routes() method (NOT a @Module decorator)`,` - Zod schemas as both runtime validators and OpenAPI sources`,` - Ctx<KickRoutes.ControllerName['method']> for typed request context`,` - src/config/index.ts with defineEnv/loadEnv for env schema`,' - A side-effect `import "./config"` in src/index.ts to register the schema',` - Container.reset() in beforeEach for DI test isolation`,``,`When the user gives you an error message or stack trace, produce a`,`structured diagnosis that helps them fix the bug. You MUST respond`,`with a single JSON object (no surrounding prose, no markdown fences)`,`matching this shape:`,``,`{`,` "id": "<kebab-case-identifier>",`,` "title": "<one-line problem summary>",`,` "explanation": "<multi-line explanation of what is wrong>",`,` "fix": "<multi-line instructions for fixing the problem>",`,` "codeBefore": "<optional: broken code snippet>",`,` "codeAfter": "<optional: corrected code snippet>",`,` "docs": "<optional: KickJS doc URL that discusses this topic>"`,`}`,``,`The KickJS docs live at https://forinda.github.io/kick-js/ — prefer`,`that domain for any doc links you suggest.`,e?`The project is located at ${e}.`:``].filter(e=>e.length>0).join(`
3927
- `)}function qa(e){let t=[e,Ja(e),Ya(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if(Xa(t))return t}catch{continue}return null}function Ja(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function Ya(e){let t=e.indexOf(`{`);if(t===-1)return null;let n=0,r=!1,i=!1;for(let a=t;a<e.length;a++){let o=e[a];if(i){i=!1;continue}if(o===`\\`&&r){i=!0;continue}if(o===`"`){r=!r;continue}if(!r&&(o===`{`&&n++,o===`}`&&(n--,n===0)))return e.slice(t,a+1)}return null}function Xa(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&typeof t.title==`string`&&typeof t.explanation==`string`&&typeof t.fix==`string`}function Za(e){e.command(`explain [message]`).description(`Explain a KickJS error and suggest a fix`).option(`-m, --message <text>`,`Error message to explain (alternative to positional arg)`).option(`--ai`,`Fall back to LLM if no known-issue matches (requires @forinda/kickjs-ai)`).option(`--model <name>`,`Model name for the --ai fallback`,`gpt-4o-mini`).option(`--json`,`Output the diagnosis as JSON for tooling integration`).action(async(e,t)=>{let n=await eo(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3926
+ pnpm add @forinda/kickjs-ai`}}let{OpenAIProvider:i}=r,a=new i({apiKey:n,defaultChatModel:e.model??`gpt-4o-mini`}),o=Ya(e.cwd),s=`Error or stack trace:\n\n${e.input.trim()}`;try{let e=Xa((await a.chat({messages:[{role:`system`,content:o},{role:`user`,content:s}]})).content);return e?{kind:`ok`,diagnosis:e}:{kind:`error`,message:`The LLM responded but the payload was not valid JSON in the expected shape. Try again, or file an issue with the error text.`}}catch(e){return{kind:`error`,message:`LLM request failed: ${e instanceof Error?e.message:String(e)}`}}}function Ya(e){return[`You are a diagnostic assistant for KickJS, a decorator-driven Node.js`,`framework built on Express 5 and TypeScript. KickJS projects use:`,` - @Controller, @Get, @Post, @Autowired, @Service, @Value decorators`,` - An AppModule interface with a routes() method (NOT a @Module decorator)`,` - Zod schemas as both runtime validators and OpenAPI sources`,` - Ctx<KickRoutes.ControllerName['method']> for typed request context`,` - src/config/index.ts with defineEnv/loadEnv for env schema`,' - A side-effect `import "./config"` in src/index.ts to register the schema',` - Container.reset() in beforeEach for DI test isolation`,``,`When the user gives you an error message or stack trace, produce a`,`structured diagnosis that helps them fix the bug. You MUST respond`,`with a single JSON object (no surrounding prose, no markdown fences)`,`matching this shape:`,``,`{`,` "id": "<kebab-case-identifier>",`,` "title": "<one-line problem summary>",`,` "explanation": "<multi-line explanation of what is wrong>",`,` "fix": "<multi-line instructions for fixing the problem>",`,` "codeBefore": "<optional: broken code snippet>",`,` "codeAfter": "<optional: corrected code snippet>",`,` "docs": "<optional: KickJS doc URL that discusses this topic>"`,`}`,``,`The KickJS docs live at https://forinda.github.io/kick-js/ — prefer`,`that domain for any doc links you suggest.`,e?`The project is located at ${e}.`:``].filter(e=>e.length>0).join(`
3927
+ `)}function Xa(e){let t=[e,Za(e),Qa(e)].filter(e=>e!==null);for(let e of t)try{let t=JSON.parse(e);if($a(t))return t}catch{continue}return null}function Za(e){let t=e.match(/```(?:json)?\s*\n([\s\S]*?)```/);return t?t[1]?.trim()??null:null}function Qa(e){let t=e.indexOf(`{`);if(t===-1)return null;let n=0,r=!1,i=!1;for(let a=t;a<e.length;a++){let o=e[a];if(i){i=!1;continue}if(o===`\\`&&r){i=!0;continue}if(o===`"`){r=!r;continue}if(!r&&(o===`{`&&n++,o===`}`&&(n--,n===0)))return e.slice(t,a+1)}return null}function $a(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&typeof t.title==`string`&&typeof t.explanation==`string`&&typeof t.fix==`string`}function eo(e){e.command(`explain [message]`).description(`Explain a KickJS error and suggest a fix`).option(`-m, --message <text>`,`Error message to explain (alternative to positional arg)`).option(`--ai`,`Fall back to LLM if no known-issue matches (requires @forinda/kickjs-ai)`).option(`--model <name>`,`Model name for the --ai fallback`,`gpt-4o-mini`).option(`--json`,`Output the diagnosis as JSON for tooling integration`).action(async(e,t)=>{let n=await ro(e,t.message);(!n||n.trim().length===0)&&(process.stderr.write(`Error: no input provided.
3928
3928
 
3929
3929
  Pass a message as a positional arg, --message flag, or pipe via stdin:
3930
3930
  kick explain "config.get returned undefined"
3931
3931
  pnpm test 2>&1 | kick explain
3932
- `),process.exit(1));let r=no(),i=Wa(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3933
- `);return}if(i){ro(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3934
- `),process.exit(2)),io(n,!1),process.exit(2));let a=await Ga({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(Qa(a),null,2)+`
3935
- `),process.exit(a.kind===`ok`?0:2)),$a(n,a),process.exit(a.kind===`ok`?0:2)})}function Qa(e){return e.kind===`ok`?{matched:!0,source:`ai`,diagnosis:e.diagnosis}:e.kind===`unavailable`?{matched:!1,aiUnavailable:!0,reason:e.reason}:{matched:!1,aiError:!0,error:e.message}}function $a(e,t){if(t.kind===`ok`){ro(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${oo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${ao(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${oo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function eo(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:to()}function to(){return new Promise((e,t)=>{let n=``;process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{n+=e}),process.stdin.on(`end`,()=>e(n)),process.stdin.on(`error`,t)})}function no(){let e=process.cwd();return{cwd:e,hasFile:t=>r(v(e,t))}}function ro(e,t,n,r=!1){let i=oo(e.trim(),200),a=r?`AI-generated — verify before applying`:so(n);process.stdout.write(`\n Explaining: ${i}\n`),process.stdout.write(`\n Match: ${t.id} (${a})\n`),process.stdout.write(` Title: ${t.title}\n`),process.stdout.write(`\n Diagnosis:\n${ao(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${ao(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${ao(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${ao(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3936
- `)}function io(e,t){let n=oo(e.trim(),200);process.stdout.write(`\n Explaining: ${n}\n\n`),t?process.stdout.write(` No known-issue matched, and --ai fallback is not yet wired.
3932
+ `),process.exit(1));let r=ao(),i=qa(n,r);if(t.json&&i){process.stdout.write(JSON.stringify({matched:!0,...i},null,2)+`
3933
+ `);return}if(i){oo(n,i.diagnosis,i.confidence);return}t.ai||(t.json&&(process.stdout.write(JSON.stringify({matched:!1},null,2)+`
3934
+ `),process.exit(2)),so(n,!1),process.exit(2));let a=await Ja({input:n,model:t.model,cwd:r.cwd});t.json&&(process.stdout.write(JSON.stringify(to(a),null,2)+`
3935
+ `),process.exit(a.kind===`ok`?0:2)),no(n,a),process.exit(a.kind===`ok`?0:2)})}function to(e){return e.kind===`ok`?{matched:!0,source:`ai`,diagnosis:e.diagnosis}:e.kind===`unavailable`?{matched:!1,aiUnavailable:!0,reason:e.reason}:{matched:!1,aiError:!0,error:e.message}}function no(e,t){if(t.kind===`ok`){oo(e,t.diagnosis,-1,!0);return}if(t.kind===`unavailable`){process.stdout.write(`\n Explaining: ${lo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback unavailable: ${t.reason}\n\n`),process.stdout.write(`${co(t.suggestion,` `)}\n\n`);return}process.stdout.write(`\n Explaining: ${lo(e.trim(),200)}\n\n`),process.stdout.write(` AI fallback error: ${t.message}\n\n`)}async function ro(e,t){return e&&e.trim().length>0?e:t&&t.trim().length>0?t:process.stdin.isTTY?``:io()}function io(){return new Promise((e,t)=>{let n=``;process.stdin.setEncoding(`utf8`),process.stdin.on(`data`,e=>{n+=e}),process.stdin.on(`end`,()=>e(n)),process.stdin.on(`error`,t)})}function ao(){let e=process.cwd();return{cwd:e,hasFile:t=>r(v(e,t))}}function oo(e,t,n,r=!1){let i=lo(e.trim(),200),a=r?`AI-generated — verify before applying`:uo(n);process.stdout.write(`\n Explaining: ${i}\n`),process.stdout.write(`\n Match: ${t.id} (${a})\n`),process.stdout.write(` Title: ${t.title}\n`),process.stdout.write(`\n Diagnosis:\n${co(t.explanation,` `)}\n`),process.stdout.write(`\n Fix:\n${co(t.fix,` `)}\n`),t.codeBefore&&process.stdout.write(`\n Before:\n${co(t.codeBefore,` `)}\n`),t.codeAfter&&process.stdout.write(`\n After:\n${co(t.codeAfter,` `)}\n`),t.docs&&process.stdout.write(`\n Docs: ${t.docs}\n`),process.stdout.write(`
3936
+ `)}function so(e,t){let n=lo(e.trim(),200);process.stdout.write(`\n Explaining: ${n}\n\n`),t?process.stdout.write(` No known-issue matched, and --ai fallback is not yet wired.
3937
3937
  When @forinda/kickjs-ai ships its provider implementations,
3938
3938
  this command will call the configured LLM with the error +
3939
3939
  project context and return a structured fix.
@@ -3950,12 +3950,12 @@ Pass a message as a positional arg, --message flag, or pipe via stdin:
3950
3950
  3. File an issue with the error text:
3951
3951
  https://github.com/forinda/kick-js/issues/new
3952
3952
 
3953
- `)}function ao(e,t){return e.split(`
3953
+ `)}function co(e,t){return e.split(`
3954
3954
  `).map(e=>`${t}${e}`).join(`
3955
- `)}function oo(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function so(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function co(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(lo),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(uo)}function lo(e){let t=v(e.entry);r(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],i=ne(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});i.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),i.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let a=e=>{i.killed||i.kill(e)};process.on(`SIGINT`,()=>a(`SIGINT`)),process.on(`SIGTERM`,()=>a(`SIGTERM`))}function uo(e){let t=process.cwd(),n=fo(t)??d(t),i=e.name??n,o=e.global?v(process.env.HOME??`.`,`.mcp.json`):v(t,e.out),s={command:`kick`,args:[`mcp`],cwd:t},c={mcpServers:{}};if(r(o))try{let e=a(o,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(c={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${o} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}c.mcpServers[i]&&!e.force&&(process.stderr.write(`Error: an entry for "${i}" already exists in ${o}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),c.mcpServers[i]=s,l(o,JSON.stringify(c,null,2)+`
3956
- `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${i}" to ${o}\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 fo(e){let t=v(e,`package.json`);if(!r(t))return null;try{let e=a(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function po(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=v(t,e.entry);r(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let i=ho(t,`tsx`);i||(console.error(`
3955
+ `)}function lo(e,t){return e.length<=t?e:e.slice(0,t-1)+`…`}function uo(e){return e>=90?`high confidence`:e>=70?`good match`:e>=50?`medium confidence`:`low confidence — verify manually`}function fo(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(po),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(mo)}function po(e){let t=v(e.entry);r(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],i=ne(process.execPath,n,{stdio:`inherit`,env:{...process.env,KICK_MCP_STDIO:`1`,NODE_ENV:process.env.NODE_ENV??`production`}});i.on(`error`,e=>{process.stderr.write(`Failed to start MCP server: ${e.message}\n`),process.exit(1)}),i.on(`exit`,(e,t)=>{if(t){process.kill(process.pid,t);return}process.exit(e??0)});let a=e=>{i.killed||i.kill(e)};process.on(`SIGINT`,()=>a(`SIGINT`)),process.on(`SIGTERM`,()=>a(`SIGTERM`))}function mo(e){let t=process.cwd(),n=ho(t)??d(t),i=e.name??n,o=e.global?v(process.env.HOME??`.`,`.mcp.json`):v(t,e.out),s={command:`kick`,args:[`mcp`],cwd:t},c={mcpServers:{}};if(r(o))try{let e=a(o,`utf8`),t=JSON.parse(e);t&&typeof t==`object`&&t.mcpServers&&(c={mcpServers:{...t.mcpServers}})}catch(e){let t=e instanceof Error?e.message:String(e);process.stderr.write(`Error: existing ${o} is not valid JSON (${t}).\nFix the file or pass --force to overwrite the entry.\n`),process.exit(1)}c.mcpServers[i]&&!e.force&&(process.stderr.write(`Error: an entry for "${i}" already exists in ${o}.\nPass --force to overwrite it, or use --name to pick a different key.\n`),process.exit(1)),c.mcpServers[i]=s,l(o,JSON.stringify(c,null,2)+`
3956
+ `,`utf8`),process.stdout.write(`\n ✓ Wrote MCP server entry "${i}" to ${o}\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 ho(e){let t=v(e,`package.json`);if(!r(t))return null;try{let e=a(t,`utf8`),n=JSON.parse(e);return typeof n.name==`string`?n.name:null}catch{return null}}function go(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=v(t,e.entry);r(n)||(console.error(`\n Error: ${e.entry} not found.\n`),process.exit(1));let i=vo(t,`tsx`);i||(console.error(`
3957
3957
  Error: tsx not found. Install it: pnpm add -D tsx
3958
- `),process.exit(1));let a=mo(n,e.entry),o=h(t,`.kick-tinker.mjs`),{writeFileSync:s,unlinkSync:c}=await import(`node:fs`);s(o,a,`utf-8`);try{let e=te(o,[],{cwd:t,execPath:i,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{c(o)}catch{}}})}function mo(e,t){return`
3958
+ `),process.exit(1));let a=_o(n,e.entry),o=h(t,`.kick-tinker.mjs`),{writeFileSync:s,unlinkSync:c}=await import(`node:fs`);s(o,a,`utf-8`);try{let e=te(o,[],{cwd:t,execPath:i,stdio:`inherit`});await new Promise(t=>{e.on(`exit`,()=>t())})}finally{try{c(o)}catch{}}})}function _o(e,t){return`
3959
3959
  import 'reflect-metadata'
3960
3960
 
3961
3961
  // Prevent bootstrap() from starting the HTTP server
@@ -4009,15 +4009,15 @@ server.on('exit', () => {
4009
4009
  console.log('\\n Goodbye!\\n')
4010
4010
  process.exit(0)
4011
4011
  })
4012
- `}function ho(e,t){let n=e;for(;;){let e=h(n,`node_modules`,`.bin`,t);if(r(e))return e;let i=v(n,`..`);if(i===n)break;n=i}return null}function go(e,t){let n=RegExp(`^\\s*${B(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]!==`
4012
+ `}function vo(e,t){let n=e;for(;;){let e=h(n,`node_modules`,`.bin`,t);if(r(e))return e;let i=v(n,`..`);if(i===n)break;n=i}return null}function yo(e,t){let n=RegExp(`^\\s*${B(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]!==`
4013
4013
  `;)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]===`
4014
- `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function _o(e,t){let n=Qn(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=go(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${B(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 vo(e){let{name:t,modulesDir:n,force:r}=e,i=e.pluralize!==!1,a=R(t),o=I(t),s=i?z(a):a,c=h(n,s);if(!await Xe(c)){console.log(`\n Module not found: ${c}\n`);return}if(!r&&!await P({message:E.red(`Delete module '${s}' at ${c}? This cannot be undone.`),initialValue:!1})){console.log(`
4014
+ `);)t--;a=a.slice(0,t)+a.slice(s+1),r=!0,i=t;continue}i=s+1}return{content:a,changed:r}}function bo(e,t){let n=tr(e);if(!n)return e;let r=n.rhsStart,i=n.rhsEnd+1,a=e.slice(r,i);return a=yo(a,t).content,a=a.replace(RegExp(`\\s*,?\\s*${B(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 xo(e){let{name:t,modulesDir:n,force:r}=e,i=e.pluralize!==!1,a=R(t),o=I(t),s=i?z(a):a,c=h(n,s);if(!await Xe(c)){console.log(`\n Module not found: ${c}\n`);return}if(!r&&!await P({message:E.red(`Delete module '${s}' at ${c}? This cannot be undone.`),initialValue:!1})){console.log(`
4015
4015
  Cancelled.
4016
- `);return}await ce(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=h(n,`index.ts`);if(await Xe(l)){let e=await C(l,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${B(o)}Module\\s*\\}\\s*from\\s*['"][^'"]*${B(s)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=_o(e,o),e=e.replace(/\n{3,}/g,`
4016
+ `);return}await ce(c,{recursive:!0,force:!0}),console.log(` Deleted: ${c}`);let l=h(n,`index.ts`);if(await Xe(l)){let e=await C(l,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${B(o)}Module\\s*\\}\\s*from\\s*['"][^'"]*${B(s)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=bo(e,o),e=e.replace(/\n{3,}/g,`
4017
4017
 
4018
- `),e!==t&&(await w(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function yo(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=O(await k(process.cwd())),r=t.modulesDir??n.dir??`src/modules`,i=t.pluralize===!1?!1:n.pluralize??!0;for(let n of e)await vo({name:n,modulesDir:v(r),force:t.force,pluralize:i})})}var bo=D({findProjectRoot:()=>So});const xo=[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`];function So(e=process.cwd()){let t=v(e),{root:n}=g(t),i=null,a=t;for(;;){for(let e of xo)if(r(v(a,e)))return a;if(i===null&&r(v(a,`package.json`))&&(i=a),a===n)break;let e=f(a);if(e===a)break;a=e}return i??t}function Co(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;console.warn(` kick typegen: unknown --schema-validator '${e}' (only 'zod' and 'false' are supported). Falling back to project config.`)}}function wo(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function To(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: fail on plugin-typegen drift instead of writing`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").action(async e=>{let t=So(process.cwd()),n=await k(t);if(e.list){let{mergeCliPlugins:e}=await Promise.resolve().then(()=>Ue),{builtinCliPlugins:t}=await Promise.resolve().then(()=>cs),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(`
4018
+ `),e!==t&&(await w(l,e,`utf-8`),console.log(` Unregistered: ${o}Module from ${l}`))}console.log(`\n Module '${s}' removed.\n`)}function So(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=O(await k(process.cwd())),r=t.modulesDir??n.dir??`src/modules`,i=t.pluralize===!1?!1:n.pluralize??!0;for(let n of e)await xo({name:n,modulesDir:v(r),force:t.force,pluralize:i})})}function Co(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;console.warn(` kick typegen: unknown --schema-validator '${e}' (only 'zod' and 'false' are supported). Falling back to project config.`)}}function wo(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function To(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: fail on plugin-typegen drift instead of writing`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").action(async e=>{let t=$t(process.cwd()),n=await k(t);if(e.list){let{mergeCliPlugins:e}=await Promise.resolve().then(()=>Ue),{builtinCliPlugins:t}=await Promise.resolve().then(()=>cs),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(`
4019
4019
  Registered typegen plugins:
4020
- `);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=Co(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=wo(e.envFile)??n?.typegen?.envFile,a={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,allowDuplicates:e.allowDuplicates,schemaValidator:r,envFile:i,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await ca(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{let{result:r}=await K(a),i=await Sa({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&i.some(e=>e.status===`written`)&&process.exit(1),e.check||await ua(v(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r.written,i,e.silent??!1)}}catch(e){e instanceof Vi?console.error(`
4020
+ `);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=Co(e.schemaValidator)??n?.typegen?.schemaValidator??`zod`,i=wo(e.envFile)??n?.typegen?.envFile,a={cwd:t,srcDir:e.src??n?.typegen?.srcDir,outDir:e.out??n?.typegen?.outDir,silent:e.silent,allowDuplicates:e.allowDuplicates,schemaValidator:r,envFile:i,assetMap:n?.assetMap,runPlugins:!1};try{if(e.watch){let t=await da(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{let{result:r}=await K(a),i=await Ta({cwd:t,config:n??null,silent:e.silent,check:e.check});e.check&&i.some(e=>e.status===`written`)&&process.exit(1),e.check||await pa(v(t,e.out??n?.typegen?.outDir??`.kickjs/types`),r.written,i,e.silent??!1)}}catch(e){e instanceof Wi?console.error(`
4021
4021
  `+e.message+`
4022
4022
  `):e instanceof Error?console.error(`\n kick typegen failed: ${e.message}`):console.error(`\n kick typegen failed: ${JSON.stringify(e)}`),process.exit(1)}})}function Eo(e){let t=[];if(!r(e))return t;let n=o(e,{withFileTypes:!0});for(let r of n){let n=h(e,r.name);if(r.isDirectory()){if([`node_modules`,`dist`,`.kickjs`,`.git`].includes(r.name))continue;t.push(...Eo(n))}else r.isFile()&&/\.tsx?$/.test(r.name)&&!r.name.endsWith(`.d.ts`)&&t.push(n)}return t}function Do(e){try{return a(e,`utf-8`)}catch{return``}}const Oo=new Set([`secret`,`changeme`,`password`,`test`,`default`,``]);function ko(e,t){let n=Do(h(e,`.env`));if(n){let e=n.match(/^JWT_SECRET\s*=\s*['"]?([^'"\n]*)['"]?/m);if(e){let t=e[1].trim();if(Oo.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 Ao(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 jo(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 Mo(){return process.env.NODE_ENV===`production`?null:{severity:`WARNING`,message:`NODE_ENV is '${process.env.NODE_ENV??`undefined`}', not 'production'`}}function No(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 Po(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 Fo(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 Io(e){let t=Eo(h(e,`src`)).map(e=>Do(e)),n=[],r=ko(e,t);r&&n.push(r);let i=Ao(t);i&&n.push(i);let a=jo(t);a&&n.push(a);let o=Mo();o&&n.push(o);let s=No(t);return s&&n.push(s),n.push(Po(t)),n.push(Fo(t)),n}function Lo(e){e.command(`check`).description(`Audit project for common issues`).option(`--deploy`,`Run production readiness checks`).action(e=>{if(!e.deploy){console.log(`
4023
4023
  Usage: kick check --deploy
@@ -4033,8 +4033,8 @@ server.on('exit', () => {
4033
4033
  The regex-based rewrite handles the shapes our templates produce.
4034
4034
  Hand-rolled modules with non-standard structures may be skipped.
4035
4035
  Always commit before running with --apply.
4036
- `),process.exit(1));let r=O(await k(process.cwd())),i=v(e.modulesDir??r.dir??`src/modules`),a;e.target===`define`||e.target===`class`?a=e.target:e.target===void 0?a=r.style??`define`:(console.error(`\n ${E.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let o=E.dim(`→ ${a}`),s=n?E.dim(`(dry-run)`):E.bold(`(applying)`);console.log(`\n ${E.bold(`kick codemod modules`)} ${o} ${s}`),console.log(` modulesDir: ${E.dim(i)}\n`);let c=e.backup!==!1&&!n,l=await jr(i,{dryRun:n,target:a,backup:c});if(l.backupDir){let e=l.backupDir;console.log(` ${E.green(`✓`)} backup: ${E.dim(e)}\n ${E.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else !n&&e.backup===!1&&console.log(` ${E.dim(`(--no-backup — skipping snapshot)`)}\n`);let u=0,d=0;for(let e of l.files)if(e.status===`migrated`)u++,console.log(` ${E.green(`✓`)} ${e.path}`);else{d++;let t=E.dim(`(${e.reason??`skipped`})`);console.log(` ${E.dim(`-`)} ${e.path} ${t}`)}if(console.log(),l.indexStatus===`migrated`)console.log(` ${E.green(`✓`)} ${l.indexPath}`);else if(l.indexStatus===`skipped`){let e=E.dim(`(${l.indexReason??`skipped`})`);console.log(` ${E.dim(`-`)} ${l.indexPath} ${e}`)}else console.log(` ${E.dim(`-`)} ${l.indexPath} ${E.dim(`(not found)`)}`);let f=n?E.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${E.bold(String(u))} migrated, ${E.bold(String(d))} skipped${f}\n`)})}const Uo=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],Wo=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=Go(e.cwd);if(!t)return null;let n=u.resolve(e.cwd,`.kickjs/types`);return[`import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,`import type * as appSchema from '${Ko(u.relative(n,t)).replace(/\.ts$/,``).replace(/\/index$/,``)}'`,``,`declare global {`,` interface KickDbSchema extends SchemaToTypes<typeof appSchema> {}`,`}`,``,`declare module '@forinda/kickjs-db' {`,` interface KickDbRegister {`,` db: KickDbClient<KickDbSchema>`,` }`,``,` interface KickDbRelationsRegister {`,` db: SchemaToRelationsRegister<typeof appSchema>`,` }`,`}`].join(`
4037
- `)}});function Go(e){for(let t of Uo){let n=u.resolve(e,t);if(t.endsWith(`.ts`)){if(r(n))return n}else{let e=u.join(n,`index.ts`);if(r(e))return e}}return null}function Ko(e){return e.replace(/\\/g,`/`)}const qo=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!r(u.resolve(e.cwd,`kick.config.ts`)))return null;let t=await k(e.cwd);if(!t?.assetMap)return null;let n=ea(t.assetMap,e.cwd);return n.count===0?null:ta(n)}}),Jo="/* 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 Yo(e,t,n){if(e.length===0)return`${Jo}
4036
+ `),process.exit(1));let r=O(await k(process.cwd())),i=v(e.modulesDir??r.dir??`src/modules`),a;e.target===`define`||e.target===`class`?a=e.target:e.target===void 0?a=r.style??`define`:(console.error(`\n ${E.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let o=E.dim(`→ ${a}`),s=n?E.dim(`(dry-run)`):E.bold(`(applying)`);console.log(`\n ${E.bold(`kick codemod modules`)} ${o} ${s}`),console.log(` modulesDir: ${E.dim(i)}\n`);let c=e.backup!==!1&&!n,l=await Pr(i,{dryRun:n,target:a,backup:c});if(l.backupDir){let e=l.backupDir;console.log(` ${E.green(`✓`)} backup: ${E.dim(e)}\n ${E.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else !n&&e.backup===!1&&console.log(` ${E.dim(`(--no-backup — skipping snapshot)`)}\n`);let u=0,d=0;for(let e of l.files)if(e.status===`migrated`)u++,console.log(` ${E.green(`✓`)} ${e.path}`);else{d++;let t=E.dim(`(${e.reason??`skipped`})`);console.log(` ${E.dim(`-`)} ${e.path} ${t}`)}if(console.log(),l.indexStatus===`migrated`)console.log(` ${E.green(`✓`)} ${l.indexPath}`);else if(l.indexStatus===`skipped`){let e=E.dim(`(${l.indexReason??`skipped`})`);console.log(` ${E.dim(`-`)} ${l.indexPath} ${e}`)}else console.log(` ${E.dim(`-`)} ${l.indexPath} ${E.dim(`(not found)`)}`);let f=n?E.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${E.bold(String(u))} migrated, ${E.bold(String(d))} skipped${f}\n`)})}const Uo=[`src/db/schema.ts`,`src/db/schema/index.ts`,`src/db/schema`],Wo=()=>({id:`kick/db`,inputs:[`src/db/schema.ts`,`src/db/schema/**/*.ts`],async generate(e){let t=Go(e.cwd);if(!t)return null;let n=u.resolve(e.cwd,`.kickjs/types`);return[`import type { SchemaToTypes, SchemaToRelationsRegister, KickDbClient } from '@forinda/kickjs-db'`,`import type * as appSchema from '${Ko(u.relative(n,t)).replace(/\.ts$/,``).replace(/\/index$/,``)}'`,``,`declare global {`,` interface KickDbSchema extends SchemaToTypes<typeof appSchema> {}`,`}`,``,`declare module '@forinda/kickjs-db' {`,` interface KickDbRegister {`,` db: KickDbClient<KickDbSchema>`,` }`,``,` interface KickDbRelationsRegister {`,` db: SchemaToRelationsRegister<typeof appSchema>`,` }`,`}`].join(`
4037
+ `)}});function Go(e){for(let t of Uo){let n=u.resolve(e,t);if(t.endsWith(`.ts`)){if(r(n))return n}else{let e=u.join(n,`index.ts`);if(r(e))return e}}return null}function Ko(e){return e.replace(/\\/g,`/`)}const qo=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){if(!r(u.resolve(e.cwd,`kick.config.ts`)))return null;let t=await k(e.cwd);if(!t?.assetMap)return null;let n=ra(t.assetMap,e.cwd);return n.count===0?null:ia(n)}}),Jo="/* 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 Yo(e,t,n){if(e.length===0)return`${Jo}
4038
4038
  // (no routes discovered yet — annotate a controller method with
4039
4039
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
4040
4040
  declare global {
@@ -4092,4 +4092,4 @@ declare global {
4092
4092
  }
4093
4093
 
4094
4094
  export {}
4095
- `}const as=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=ss(e);if(t===!1)return null;let n=await e.getScanResult({root:os(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=u.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return is(n.env,r)}});function os(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ss(e){return e.config?.typegen?.envFile}var cs=D({builtinCliPlugins:()=>ls});const ls=[A({name:`kick/init`,register:Yt}),A({name:`kick/generate`,register:ga}),A({name:`kick/run`,register:Aa}),A({name:`kick/info`,register:ja}),A({name:`kick/inspect`,register:Va}),A({name:`kick/add`,register:qt}),A({name:`kick/list`,register:Kt}),A({name:`kick/explain`,register:Za}),A({name:`kick/mcp`,register:co}),A({name:`kick/tinker`,register:po}),A({name:`kick/remove`,register:yo}),A({name:`kick/typegen`,register:To}),A({name:`kick/check`,register:Lo}),A({name:`kick/db`,register:Bo,typegens:[Wo()]}),A({name:`kick/codemod`,register:Ho}),A({name:`kick/assets`,typegens:[qo()]}),A({name:`kick/routes`,typegens:[ts()]}),A({name:`kick/env`,typegens:[as()]})],us=f(b(import.meta.url)),ds=JSON.parse(a(h(us,`..`,`package.json`),`utf-8`));async function fs(){let e=new t;e.name(`kick`).description(`KickJS — A production-grade, decorator-driven Node.js framework`).version(ds.version);let n=So(process.cwd()),r=await k(n)??{},i=He([...ls,...r.plugins??[]],r.commands??[]);await i.register(e,{cwd:n,config:r,log:e=>console.log(e)}),Ae(e,{...r,commands:i.commands}),e.showHelpAfterError(),await e.parseAsync(process.argv)}fs().catch(e=>{console.error(e instanceof Error?e.message:e),process.exitCode=1});export{};
4095
+ `}const as=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=ss(e);if(t===!1)return null;let n=await e.getScanResult({root:os(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=u.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return is(n.env,r)}});function os(e){return u.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ss(e){return e.config?.typegen?.envFile}var cs=D({builtinCliPlugins:()=>ls});const ls=[A({name:`kick/init`,register:Yt}),A({name:`kick/generate`,register:ya}),A({name:`kick/run`,register:Na}),A({name:`kick/info`,register:Pa}),A({name:`kick/inspect`,register:Wa}),A({name:`kick/add`,register:qt}),A({name:`kick/list`,register:Kt}),A({name:`kick/explain`,register:eo}),A({name:`kick/mcp`,register:fo}),A({name:`kick/tinker`,register:go}),A({name:`kick/remove`,register:So}),A({name:`kick/typegen`,register:To}),A({name:`kick/check`,register:Lo}),A({name:`kick/db`,register:Bo,typegens:[Wo()]}),A({name:`kick/codemod`,register:Ho}),A({name:`kick/assets`,typegens:[qo()]}),A({name:`kick/routes`,typegens:[ts()]}),A({name:`kick/env`,typegens:[as()]})],us=f(b(import.meta.url)),ds=JSON.parse(a(h(us,`..`,`package.json`),`utf-8`));async function fs(){let e=new t;e.name(`kick`).description(`KickJS — A production-grade, decorator-driven Node.js framework`).version(ds.version);let n=$t(process.cwd()),r=n,i=await k(r)??{},a=He([...ls,...i.plugins??[]],i.commands??[]);await a.register(e,{cwd:r,projectRoot:n,config:i,log:e=>console.log(e)}),Ae(e,{...i,commands:a.commands}),e.showHelpAfterError(),await e.parseAsync(process.argv)}fs().catch(e=>{console.error(e instanceof Error?e.message:e),process.exitCode=1});export{};