@forinda/kickjs-cli 8.9.0 → 8.10.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.
Files changed (49) hide show
  1. package/dist/{agent-docs-DUB-1Z6Q.mjs → agent-docs-CmPrfpaP.mjs} +8 -3
  2. package/dist/agent-docs-CmPrfpaP.mjs.map +1 -0
  3. package/dist/{agent-docs-bVMPt2m5.mjs → agent-docs-CvBsLoE4.mjs} +7 -2
  4. package/dist/{build-C30mBgw6.mjs → build-Dr7_JT3S.mjs} +3 -3
  5. package/dist/{build-C30mBgw6.mjs.map → build-Dr7_JT3S.mjs.map} +1 -1
  6. package/dist/{build-xQXbdDpw.mjs → build-Snjzr08O.mjs} +2 -2
  7. package/dist/{builtins-DiWfXc-D.mjs → builtins-BTPvizzK.mjs} +126 -117
  8. package/dist/{builtins-CtpLZ4FY.mjs → builtins-MG6t5uS3.mjs} +2 -2
  9. package/dist/cli.mjs +2 -2
  10. package/dist/{config-ZHuFjsKI.mjs → config-B7ZUrOl6.mjs} +3 -3
  11. package/dist/{config-ZHuFjsKI.mjs.map → config-B7ZUrOl6.mjs.map} +1 -1
  12. package/dist/{config-YvIngROH.mjs → config-DO4J2xgV.mjs} +2 -2
  13. package/dist/{doctor-CnsnRW7T.mjs → doctor-C-VSGhJ6.mjs} +4 -4
  14. package/dist/{doctor-CnsnRW7T.mjs.map → doctor-C-VSGhJ6.mjs.map} +1 -1
  15. package/dist/{fs-Bm2St4gk.mjs → fs-CT9PRuSw.mjs} +1 -1
  16. package/dist/{fs-BvGbbHY0.mjs → fs-gRPNbfZO.mjs} +2 -2
  17. package/dist/{fs-BvGbbHY0.mjs.map → fs-gRPNbfZO.mjs.map} +1 -1
  18. package/dist/{fullstack-CZ9XQYk-.mjs → fullstack-CTB1yuCK.mjs} +3 -3
  19. package/dist/{fullstack-B0g06sSQ.mjs → fullstack-bVcLaFbj.mjs} +4 -4
  20. package/dist/{fullstack-B0g06sSQ.mjs.map → fullstack-bVcLaFbj.mjs.map} +1 -1
  21. package/dist/index.d.mts.map +1 -1
  22. package/dist/index.mjs +2 -2
  23. package/dist/{plugin-BfdvW6_r.mjs → plugin-BpfANLIW.mjs} +2 -2
  24. package/dist/{plugin-Bs0soxrU.mjs → plugin-E910l1_e.mjs} +2 -2
  25. package/dist/project-BAmOMd-l.mjs +113 -0
  26. package/dist/project-D7x753R7.mjs +114 -0
  27. package/dist/project-D7x753R7.mjs.map +1 -0
  28. package/dist/{project-root-LYOxQHXp.mjs → project-root-D74lbi2U.mjs} +2 -2
  29. package/dist/{project-root-B9BrO1na.mjs → project-root-DO7MsZOq.mjs} +3 -3
  30. package/dist/{project-root-B9BrO1na.mjs.map → project-root-DO7MsZOq.mjs.map} +1 -1
  31. package/dist/{prompts-BEAqcbPT.mjs → prompts-DKR7UZkc.mjs} +2 -2
  32. package/dist/{prompts-BEAqcbPT.mjs.map → prompts-DKR7UZkc.mjs.map} +1 -1
  33. package/dist/{rolldown-runtime-Da-NDvKz.mjs → rolldown-runtime-vT0bVE76.mjs} +1 -1
  34. package/dist/{run-plugins-0AfIgIsZ.mjs → run-plugins-BXNfws9R.mjs} +43 -34
  35. package/dist/run-plugins-BXNfws9R.mjs.map +1 -0
  36. package/dist/{typegen-BzgWveE_.mjs → typegen-B90QMhV8.mjs} +5 -5
  37. package/dist/{typegen-BzgWveE_.mjs.map → typegen-B90QMhV8.mjs.map} +1 -1
  38. package/dist/{typegen-up-UkaNc.mjs → typegen-BmyEoY3Z.mjs} +4 -4
  39. package/dist/{types-ChFFRT8E.mjs → types-C2QNIHnD.mjs} +1 -1
  40. package/package.json +6 -6
  41. package/templates/feature-storage/feature.json +13 -0
  42. package/templates/feature-storage/files/_dot_env.example.append +6 -0
  43. package/templates/feature-storage/files/_dot_gitignore.append +2 -0
  44. package/templates/feature-storage/files/src/storage.ts +16 -0
  45. package/dist/agent-docs-DUB-1Z6Q.mjs.map +0 -1
  46. package/dist/project-B_qDdkYQ.mjs +0 -113
  47. package/dist/project-B_qDdkYQ.mjs.map +0 -1
  48. package/dist/project-Bp-KfBNb.mjs +0 -112
  49. package/dist/run-plugins-0AfIgIsZ.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"project-root-B9BrO1na.mjs","names":["__exportAll","project_root_exports","findProjectRoot","CONFIG_FILENAMES","start","resolve","startDir","fsRoot","parse","firstPackageJson","cursor","name","existsSync","parent","dirname"],"sources":["../src/utils/project-root.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { dirname, parse, resolve } from 'node:path'\n\nconst CONFIG_FILENAMES = ['kick.config.ts', 'kick.config.js', 'kick.config.mjs', 'kick.config.json']\n\n/**\n * Walk up from `startDir` looking for the project root. A directory\n * counts as the root when it contains any of:\n * - `kick.config.{ts,js,mjs,json}` (strongest signal)\n * - `package.json` (fallback when no config file exists yet)\n *\n * Returns the absolute path of the first matching directory, or\n * `startDir` itself when nothing was found (no surprises — callers\n * that didn't find a config still get a reasonable cwd).\n *\n * `kick.config.*` wins over `package.json` when both appear at\n * different levels, so adopters running `kick typegen` from `src/`\n * land on the project root that owns the config, not on the nearest\n * workspace package boundary in a monorepo.\n */\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n const start = resolve(startDir)\n const { root: fsRoot } = parse(start)\n\n let firstPackageJson: string | null = null\n let cursor = start\n while (true) {\n for (const name of CONFIG_FILENAMES) {\n if (existsSync(resolve(cursor, name))) return cursor\n }\n if (firstPackageJson === null && existsSync(resolve(cursor, 'package.json'))) {\n firstPackageJson = cursor\n }\n if (cursor === fsRoot) break\n const parent = dirname(cursor)\n if (parent === cursor) break\n cursor = parent\n }\n\n return firstPackageJson ?? start\n}\n"],"mappings":";;;;;;;;;;sMAGA,MAAMG,EAAmB,CAAC,iBAAkB,iBAAkB,kBAAmB,kBAAkB,EAiBnG,SAAgBD,EAAgB,EAAmB,QAAQ,IAAI,EAAW,CACxE,IAAME,EAAQC,EAAQC,CAAQ,EACxB,CAAE,KAAMC,GAAWC,EAAMJ,CAAK,EAEhCK,EAAkC,KAClCC,EAASN,EACb,OAAa,CACX,IAAK,IAAMO,KAAQR,EACjB,GAAIS,EAAWP,EAAQK,EAAQC,CAAI,CAAC,EAAG,OAAOD,EAKhD,GAHID,IAAqB,MAAQG,EAAWP,EAAQK,EAAQ,cAAc,CAAC,IACzE,EAAmBA,GAEjBA,IAAWH,EAAQ,MACvB,IAAMM,EAASC,EAAQJ,CAAM,EAC7B,GAAIG,IAAWH,EAAQ,MACvB,EAASG,CACX,CAEA,OAAOJ,GAAoBL,CAC7B"}
1
+ {"version":3,"file":"project-root-DO7MsZOq.mjs","names":["__exportAll","project_root_exports","findProjectRoot","CONFIG_FILENAMES","start","resolve","startDir","fsRoot","parse","firstPackageJson","cursor","name","existsSync","parent","dirname"],"sources":["../src/utils/project-root.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { dirname, parse, resolve } from 'node:path'\n\nconst CONFIG_FILENAMES = ['kick.config.ts', 'kick.config.js', 'kick.config.mjs', 'kick.config.json']\n\n/**\n * Walk up from `startDir` looking for the project root. A directory\n * counts as the root when it contains any of:\n * - `kick.config.{ts,js,mjs,json}` (strongest signal)\n * - `package.json` (fallback when no config file exists yet)\n *\n * Returns the absolute path of the first matching directory, or\n * `startDir` itself when nothing was found (no surprises — callers\n * that didn't find a config still get a reasonable cwd).\n *\n * `kick.config.*` wins over `package.json` when both appear at\n * different levels, so adopters running `kick typegen` from `src/`\n * land on the project root that owns the config, not on the nearest\n * workspace package boundary in a monorepo.\n */\nexport function findProjectRoot(startDir: string = process.cwd()): string {\n const start = resolve(startDir)\n const { root: fsRoot } = parse(start)\n\n let firstPackageJson: string | null = null\n let cursor = start\n while (true) {\n for (const name of CONFIG_FILENAMES) {\n if (existsSync(resolve(cursor, name))) return cursor\n }\n if (firstPackageJson === null && existsSync(resolve(cursor, 'package.json'))) {\n firstPackageJson = cursor\n }\n if (cursor === fsRoot) break\n const parent = dirname(cursor)\n if (parent === cursor) break\n cursor = parent\n }\n\n return firstPackageJson ?? start\n}\n"],"mappings":";;;;;;;;;;sMAGA,MAAMG,EAAmB,CAAC,iBAAkB,iBAAkB,kBAAmB,kBAAkB,EAiBnG,SAAgBD,EAAgB,EAAmB,QAAQ,IAAI,EAAW,CACxE,IAAME,EAAQC,EAAQC,CAAQ,EACxB,CAAE,KAAMC,GAAWC,EAAMJ,CAAK,EAEhCK,EAAkC,KAClCC,EAASN,EACb,OAAa,CACX,IAAK,IAAMO,KAAQR,EACjB,GAAIS,EAAWP,EAAQK,EAAQC,CAAI,CAAC,EAAG,OAAOD,EAKhD,GAHID,IAAqB,MAAQG,EAAWP,EAAQK,EAAQ,cAAc,CAAC,IACzE,EAAmBA,GAEjBA,IAAWH,EAAQ,MACvB,IAAMM,EAASC,EAAQJ,CAAM,EAC7B,GAAIG,IAAWH,EAAQ,MACvB,EAASG,CACX,CAEA,OAAOJ,GAAoBL,CAC7B"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v8.9.0
2
+ * @forinda/kickjs-cli v8.10.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -9,4 +9,4 @@
9
9
  * @license MIT
10
10
  */
11
11
  import*as e from"@clack/prompts";import t from"picocolors";const n={GET:t.green,POST:t.cyan,PUT:t.yellow,PATCH:t.magenta,DELETE:t.red};function r(e){return(n[e]??t.dim)(e.padEnd(7))}function i(e){let n=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return t.red(n);case`WARNING`:return t.yellow(n);case`INFO`:return t.blue(t.dim(n));default:return n}}t.green(`✓`),t.red(`✖`),t.yellow(`⚠`),t.blue(`ℹ`);function a(n){e.intro(t.bgCyan(t.black(` ${n} `)))}function o(t){e.outro(t)}function s(t){e.isCancel(t)&&(e.cancel(`Operation cancelled.`),process.exit(0))}async function c(t){let n=await e.text(t);return s(n),n}async function l(t){let n=await e.select(t);return s(n),n}async function u(t){let n=await e.multiselect(t);return s(n),n}async function d(t){let n=await e.confirm(t);return s(n),n}function f(){return e.spinner()}const p=e.log;export{o as a,c,i as d,u as i,r as l,a as n,l as o,p as r,f as s,d as t,t as u};
12
- //# sourceMappingURL=prompts-BEAqcbPT.mjs.map
12
+ //# sourceMappingURL=prompts-DKR7UZkc.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts-BEAqcbPT.mjs","names":["colors","clack","pc","METHOD_COLOR_MAP","httpMethodColor","method","severityColor","tag","severity","intro","title","outro","message","handleCancel","value","text","opts","select","multiSelect","confirm","spinner","log"],"sources":["../src/utils/colors.ts","../src/utils/prompts.ts"],"sourcesContent":["import pc from 'picocolors'\n\nexport { pc as colors }\n\nconst METHOD_COLOR_MAP: Record<string, (s: string) => string> = {\n GET: pc.green,\n POST: pc.cyan,\n PUT: pc.yellow,\n PATCH: pc.magenta,\n DELETE: pc.red,\n}\n\n/** Color an HTTP method string for terminal display */\nexport function httpMethodColor(method: string): string {\n const fn = METHOD_COLOR_MAP[method] ?? pc.dim\n return fn(method.padEnd(7))\n}\n\n/** Color a severity tag for terminal display (padded to 10 chars) */\nexport function severityColor(severity: string): string {\n const tag = `[${severity}]`.padEnd(10)\n switch (severity) {\n case 'CRITICAL':\n return pc.red(tag)\n case 'WARNING':\n return pc.yellow(tag)\n case 'INFO':\n return pc.blue(pc.dim(tag))\n default:\n return tag\n }\n}\n","import * as clack from '@clack/prompts'\nimport { colors } from './colors'\n\nexport const symbols = {\n success: colors.green('✓'),\n error: colors.red('✖'),\n warning: colors.yellow('⚠'),\n info: colors.blue('ℹ'),\n}\n\n/** Show branded intro banner */\nexport function intro(title: string): void {\n clack.intro(colors.bgCyan(colors.black(` ${title} `)))\n}\n\n/** Show closing message */\nexport function outro(message: string): void {\n clack.outro(message)\n}\n\n/** Handle cancellation — print message and exit */\nfunction handleCancel(value: unknown): void {\n if (clack.isCancel(value)) {\n clack.cancel('Operation cancelled.')\n process.exit(0)\n }\n}\n\n/** Text input prompt */\nexport async function text(opts: {\n message: string\n placeholder?: string\n defaultValue?: string\n validate?: (value: string) => string | void\n}): Promise<string> {\n const value = await clack.text(opts as any)\n handleCancel(value)\n return value as string\n}\n\n/** Single select prompt */\nexport async function select<T>(opts: {\n message: string\n options: { value: T; label: string; hint?: string }[]\n initialValue?: T\n}): Promise<T> {\n const value = await clack.select(opts as any)\n handleCancel(value)\n return value as T\n}\n\n/** Multi-select prompt with checkboxes */\nexport async function multiSelect<T>(opts: {\n message: string\n options: { value: T; label: string; hint?: string }[]\n required?: boolean\n initialValues?: T[]\n}): Promise<T[]> {\n const value = await clack.multiselect(opts as any)\n handleCancel(value)\n return value as T[]\n}\n\n/** Yes/no confirmation prompt */\nexport async function confirm(opts: {\n message: string\n active?: string\n inactive?: string\n initialValue?: boolean\n}): Promise<boolean> {\n const value = await clack.confirm(opts)\n handleCancel(value)\n return value as boolean\n}\n\n/** Create a spinner for progress indication */\nexport function spinner() {\n return clack.spinner()\n}\n\n/** Log utilities for styled messages inside clack flow */\nexport const log = clack.log\n"],"mappings":";;;;;;;;;;2DAIA,MAAMG,EAA0D,CAC9D,IAAKD,EAAG,MACR,KAAMA,EAAG,KACT,IAAKA,EAAG,OACR,MAAOA,EAAG,QACV,OAAQA,EAAG,GACb,EAGA,SAAgBE,EAAgB,EAAwB,CAEtD,OADWD,EAAiBE,IAAWH,EAAG,IAAA,CAChCG,EAAO,OAAO,CAAC,CAAC,CAC5B,CAGA,SAAgBC,EAAc,EAA0B,CACtD,IAAMC,EAAM,IAAIC,EAAS,GAAG,OAAO,EAAE,EACrC,OAAQA,EAAR,CACE,IAAK,WACH,OAAON,EAAG,IAAIK,CAAG,EACnB,IAAK,UACH,OAAOL,EAAG,OAAOK,CAAG,EACtB,IAAK,OACH,OAAOL,EAAG,KAAKA,EAAG,IAAIK,CAAG,CAAC,EAC5B,QACE,OAAOA,CACX,CACF,CC3BWP,EAAO,MAAM,GAAG,EAClBA,EAAO,IAAI,GAAG,EACZA,EAAO,OAAO,GAAG,EACpBA,EAAO,KAAK,GAAG,EAIvB,SAAgBS,EAAM,EAAqB,CACzCR,EAAM,MAAMD,EAAO,OAAOA,EAAO,MAAM,IAAIU,EAAM,EAAE,CAAC,CAAC,CACvD,CAGA,SAAgBC,EAAM,EAAuB,CAC3CV,EAAM,MAAMW,CAAO,CACrB,CAGA,SAASC,EAAa,EAAsB,CACtCZ,EAAM,SAASa,CAAK,IACtBb,EAAM,OAAO,sBAAsB,EACnC,QAAQ,KAAK,CAAC,EAElB,CAGA,eAAsBc,EAAK,EAKP,CAClB,IAAMD,EAAQ,MAAMb,EAAM,KAAKe,CAAW,EAE1C,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,eAAsBG,EAAU,EAIjB,CACb,IAAMH,EAAQ,MAAMb,EAAM,OAAOe,CAAW,EAE5C,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,eAAsBI,EAAe,EAKpB,CACf,IAAMJ,EAAQ,MAAMb,EAAM,YAAYe,CAAW,EAEjD,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,eAAsBK,EAAQ,EAKT,CACnB,IAAML,EAAQ,MAAMb,EAAM,QAAQe,CAAI,EAEtC,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,SAAgBM,GAAU,CACxB,OAAOnB,EAAM,QAAQ,CACvB,CAGA,MAAaoB,EAAMpB,EAAM"}
1
+ {"version":3,"file":"prompts-DKR7UZkc.mjs","names":["colors","clack","pc","METHOD_COLOR_MAP","httpMethodColor","method","severityColor","tag","severity","intro","title","outro","message","handleCancel","value","text","opts","select","multiSelect","confirm","spinner","log"],"sources":["../src/utils/colors.ts","../src/utils/prompts.ts"],"sourcesContent":["import pc from 'picocolors'\n\nexport { pc as colors }\n\nconst METHOD_COLOR_MAP: Record<string, (s: string) => string> = {\n GET: pc.green,\n POST: pc.cyan,\n PUT: pc.yellow,\n PATCH: pc.magenta,\n DELETE: pc.red,\n}\n\n/** Color an HTTP method string for terminal display */\nexport function httpMethodColor(method: string): string {\n const fn = METHOD_COLOR_MAP[method] ?? pc.dim\n return fn(method.padEnd(7))\n}\n\n/** Color a severity tag for terminal display (padded to 10 chars) */\nexport function severityColor(severity: string): string {\n const tag = `[${severity}]`.padEnd(10)\n switch (severity) {\n case 'CRITICAL':\n return pc.red(tag)\n case 'WARNING':\n return pc.yellow(tag)\n case 'INFO':\n return pc.blue(pc.dim(tag))\n default:\n return tag\n }\n}\n","import * as clack from '@clack/prompts'\nimport { colors } from './colors'\n\nexport const symbols = {\n success: colors.green('✓'),\n error: colors.red('✖'),\n warning: colors.yellow('⚠'),\n info: colors.blue('ℹ'),\n}\n\n/** Show branded intro banner */\nexport function intro(title: string): void {\n clack.intro(colors.bgCyan(colors.black(` ${title} `)))\n}\n\n/** Show closing message */\nexport function outro(message: string): void {\n clack.outro(message)\n}\n\n/** Handle cancellation — print message and exit */\nfunction handleCancel(value: unknown): void {\n if (clack.isCancel(value)) {\n clack.cancel('Operation cancelled.')\n process.exit(0)\n }\n}\n\n/** Text input prompt */\nexport async function text(opts: {\n message: string\n placeholder?: string\n defaultValue?: string\n validate?: (value: string) => string | void\n}): Promise<string> {\n const value = await clack.text(opts as any)\n handleCancel(value)\n return value as string\n}\n\n/** Single select prompt */\nexport async function select<T>(opts: {\n message: string\n options: { value: T; label: string; hint?: string }[]\n initialValue?: T\n}): Promise<T> {\n const value = await clack.select(opts as any)\n handleCancel(value)\n return value as T\n}\n\n/** Multi-select prompt with checkboxes */\nexport async function multiSelect<T>(opts: {\n message: string\n options: { value: T; label: string; hint?: string }[]\n required?: boolean\n initialValues?: T[]\n}): Promise<T[]> {\n const value = await clack.multiselect(opts as any)\n handleCancel(value)\n return value as T[]\n}\n\n/** Yes/no confirmation prompt */\nexport async function confirm(opts: {\n message: string\n active?: string\n inactive?: string\n initialValue?: boolean\n}): Promise<boolean> {\n const value = await clack.confirm(opts)\n handleCancel(value)\n return value as boolean\n}\n\n/** Create a spinner for progress indication */\nexport function spinner() {\n return clack.spinner()\n}\n\n/** Log utilities for styled messages inside clack flow */\nexport const log = clack.log\n"],"mappings":";;;;;;;;;;2DAIA,MAAMG,EAA0D,CAC9D,IAAKD,EAAG,MACR,KAAMA,EAAG,KACT,IAAKA,EAAG,OACR,MAAOA,EAAG,QACV,OAAQA,EAAG,GACb,EAGA,SAAgBE,EAAgB,EAAwB,CAEtD,OADWD,EAAiBE,IAAWH,EAAG,IAAA,CAChCG,EAAO,OAAO,CAAC,CAAC,CAC5B,CAGA,SAAgBC,EAAc,EAA0B,CACtD,IAAMC,EAAM,IAAIC,EAAS,GAAG,OAAO,EAAE,EACrC,OAAQA,EAAR,CACE,IAAK,WACH,OAAON,EAAG,IAAIK,CAAG,EACnB,IAAK,UACH,OAAOL,EAAG,OAAOK,CAAG,EACtB,IAAK,OACH,OAAOL,EAAG,KAAKA,EAAG,IAAIK,CAAG,CAAC,EAC5B,QACE,OAAOA,CACX,CACF,CC3BWP,EAAO,MAAM,GAAG,EAClBA,EAAO,IAAI,GAAG,EACZA,EAAO,OAAO,GAAG,EACpBA,EAAO,KAAK,GAAG,EAIvB,SAAgBS,EAAM,EAAqB,CACzCR,EAAM,MAAMD,EAAO,OAAOA,EAAO,MAAM,IAAIU,EAAM,EAAE,CAAC,CAAC,CACvD,CAGA,SAAgBC,EAAM,EAAuB,CAC3CV,EAAM,MAAMW,CAAO,CACrB,CAGA,SAASC,EAAa,EAAsB,CACtCZ,EAAM,SAASa,CAAK,IACtBb,EAAM,OAAO,sBAAsB,EACnC,QAAQ,KAAK,CAAC,EAElB,CAGA,eAAsBc,EAAK,EAKP,CAClB,IAAMD,EAAQ,MAAMb,EAAM,KAAKe,CAAW,EAE1C,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,eAAsBG,EAAU,EAIjB,CACb,IAAMH,EAAQ,MAAMb,EAAM,OAAOe,CAAW,EAE5C,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,eAAsBI,EAAe,EAKpB,CACf,IAAMJ,EAAQ,MAAMb,EAAM,YAAYe,CAAW,EAEjD,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,eAAsBK,EAAQ,EAKT,CACnB,IAAML,EAAQ,MAAMb,EAAM,QAAQe,CAAI,EAEtC,OADAH,EAAaC,CAAK,EACXA,CACT,CAGA,SAAgBM,GAAU,CACxB,OAAOnB,EAAM,QAAQ,CACvB,CAGA,MAAaoB,EAAMpB,EAAM"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v8.9.0
2
+ * @forinda/kickjs-cli v8.10.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v8.9.0
2
+ * @forinda/kickjs-cli v8.10.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{t as e}from"./rolldown-runtime-Da-NDvKz.mjs";import{n as t,r as n,t as r}from"./fs-BvGbbHY0.mjs";import{a as i,c as a,d as o,i as s,l as c,n as l,o as u,r as d,s as f,t as p,u as m}from"./prompts-BEAqcbPT.mjs";import{A as h,C as g,D as _,E as v,F as y,M as b,N as ee,O as x,P as S,S as te,T as ne,_ as re,a as ie,b as ae,c as oe,f as se,g as ce,h as le,i as ue,j as de,k as fe,l as pe,m as me,p as he,r as ge,u as _e,v as ve,w as ye,x as be,y as xe}from"./doctor-CnsnRW7T.mjs";import{f as Se,l as Ce,o as we,r as Te,s as Ee,t as De}from"./project-B_qDdkYQ.mjs";import{a as Oe,c as ke,i as Ae,l as je,o as C,s as w,u as Me}from"./config-ZHuFjsKI.mjs";import{t as T}from"./project-root-B9BrO1na.mjs";import{n as E,t as Ne}from"./types-ChFFRT8E.mjs";import{t as Pe}from"./build-C30mBgw6.mjs";import{n as Fe}from"./agent-docs-DUB-1Z6Q.mjs";import{C as Ie,S as Le,_ as Re,a as ze,b as Be,c as Ve,d as He,f as Ue,g as We,h as Ge,i as Ke,l as qe,m as Je,o as Ye,p as Xe,r as Ze,s as Qe,t as $e,u as et,v as tt,w as nt,x as D,y as rt}from"./typegen-BzgWveE_.mjs";import{createRequire as it}from"node:module";import O,{basename as at,dirname as k,join as A,relative as j,resolve as M,sep as N}from"node:path";import{cpSync as ot,existsSync as P,mkdirSync as st,readFileSync as F,readdirSync as I,rmSync as ct,statSync as lt,writeFileSync as L}from"node:fs";import{copyFile as ut,mkdir as dt,readFile as R,readdir as ft,rm as pt,stat as mt,writeFile as z}from"node:fs/promises";import{fork as ht,spawn as gt,spawnSync as _t}from"node:child_process";import{createHash as vt}from"node:crypto";import{fileURLToPath as yt,pathToFileURL as B}from"node:url";import{parseSync as bt}from"oxc-parser";import{arch as xt,platform as St,release as Ct}from"node:os";const wt=[{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 Tt(e){e.command(`new [name]`).alias(`init`).description(`Create a new KickJS project (use "." for current directory)`).option(`-d, --directory <dir>`,`Target directory (defaults to project name)`).option(`--pm <manager>`,`Package manager: pnpm | npm | yarn | bun`).option(`--git`,`Initialize git repository`).option(`--no-git`,`Skip git initialization`).option(`--install`,`Install dependencies after scaffolding`).option(`--no-install`,`Skip dependency installation`).option(`-f, --force`,`Remove existing files without prompting`).option(`-t, --template <type>`,`Project template: rest | minimal | fullstack | inertia`).option(`--runtime <engine>`,`HTTP runtime: express | fastify | h3`).option(`-r, --repo <type>`,`Repository name (inmemory, or any DB name e.g. postgres)`).option(`-s, --schema <lib>`,`Schema library for env / DTOs: zod | valibot | yup (default: zod)`).option(`--frontend <kind>`,`Fullstack web/ scaffold: 'kick' (wired React app) or 'vite' (create-vite, unwired)`).option(`--vite-template <name>`,`create-vite TypeScript template for --frontend vite (default 'react-ts')`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. swagger,ws,queue,devtools)`).option(`-y, --yes`,`Pick safe defaults for every prompt (template=minimal, repo=inmemory, no extras, git+install on)`).option(`--non-interactive`,`alias for --yes`).action(async(e,t)=>{l(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await a({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let r;if(e===`.`?(r=M(`.`),e=at(r)):r=M(t.directory||e),P(r)){let a=I(r);if(a.length>0){if(t.force)d.warn(`Clearing existing files in ${r}`);else if(n){d.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),i(`Aborted.`);return}else{d.warn(`Directory "${e}" is not empty:`);let t=a.slice(0,5);for(let e of t)d.message(` - ${e}`);if(a.length>5&&d.message(` ... and ${a.length-5} more`),!await p({message:m.red(`Remove all existing files and proceed?`),initialValue:!1})){i(`Aborted.`);return}}for(let e of a)ct(M(r,e),{recursive:!0,force:!0})}}let o=t.template;o||=n?`minimal`:await u({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`minimal`,label:`Minimal`,hint:`bare Express`},{value:`fullstack`,label:`Fullstack`,hint:`server + Vite React web, typed client`},{value:`inertia`,label:`Inertia`,hint:`server-driven React pages, one app, SSR`}]});let c=t.runtime;c||=n?`express`:await u({message:`HTTP runtime`,options:[{value:`express`,label:`Express`,hint:`default, zero-config`},{value:`fastify`,label:`Fastify`,hint:`fastify + @fastify/middie`},{value:`h3`,label:`h3`,hint:`Nitro / Nuxt engine`}]});let f=t.pm;f||=n?await Ce(void 0):await u({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let h=t.repo;h||=n?`inmemory`:await a({message:`Repository name`,placeholder:`inmemory (or a DB name, e.g. postgres)`,defaultValue:`inmemory`}),Me(h);let g=t.schema;o===`inertia`&&(g&&g!==`zod`&&d.warn(`The inertia template uses zod — ignoring --schema ${g}.`),g=`zod`),g||=n?`zod`:await u({message:`Schema library (env + DTO validation)`,options:[{value:`zod`,label:`Zod`,hint:`default — broad ecosystem`},{value:`valibot`,label:`Valibot`,hint:`smaller bundle`},{value:`yup`,label:`Yup`,hint:`classic API`}]}),[`zod`,`valibot`,`yup`].includes(g)||(d.warn(`Unknown --schema "${g}", falling back to zod.`),g=`zod`);let _;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();_=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else _=n?[]:await s({message:`Select packages to include`,options:[...wt],required:!1});let v;v=t.git===void 0?n?!0:await p({message:`Initialize git repository?`,initialValue:!0}):t.git;let y;if(y=t.install===void 0?n?!0:await p({message:`Install dependencies?`,initialValue:!0}):t.install,t.frontend!==void 0&&t.frontend!==`kick`&&t.frontend!==`vite`){d.error(`Unknown --frontend '${String(t.frontend)}'. Use 'kick' (wired React app) or 'vite' (create-vite).`),i(`Aborted.`);return}let{VITE_TEMPLATES:b,DEFAULT_VITE_TEMPLATE:ee}=await import(`./fullstack-B0g06sSQ.mjs`);if(t.viteTemplate!==void 0&&!b.some(e=>e.value===t.viteTemplate)){d.error(`Unknown --vite-template '${String(t.viteTemplate)}'. TypeScript templates only: ${b.map(e=>e.value).join(`, `)}.`),i(`Aborted.`);return}let x=t.frontend===`vite`?`vite`:`kick`,S=t.viteTemplate??ee;if(o===`fullstack`&&!t.frontend&&!n&&(x=await u({message:`Frontend for web/`,options:[{value:`kick`,label:`KickJS React app`,hint:`typed client, /api proxy, route types — wired`},{value:`vite`,label:`Delegate to create-vite`,hint:`pick any framework; wiring is manual (guide printed after)`}]})),x===`vite`&&!t.viteTemplate&&!n&&(S=await u({message:`create-vite template`,options:b.map(e=>({value:e.value,label:e.label})),initialValue:ee})),o===`fullstack`){let{initFullstackProject:t}=await import(`./fullstack-B0g06sSQ.mjs`);await t({name:e,directory:r,packageManager:f,initGit:v,installDeps:y,schemaLib:g,runtime:c,packages:_,frontend:x,viteTemplate:S}),i(`Done! Next steps: ${m.cyan(`cd ${e} && ${f}${f===`pnpm`?` dev`:` run dev:server`}`)}`)}else await De({name:e,directory:r,packageManager:f,initGit:v,installDeps:y,template:o,defaultRepo:h,packages:_,schemaLib:g,runtime:c}),i(`Done! Next steps: ${m.cyan(`cd ${e} && ${f} dev`)}`)})}function Et(e,t=[]){let n=/* @__PURE__ */ 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 Ne(`plugin`,t.name,[t.name,t.name])}let r=/* @__PURE__ */ new Map,i=[];for(let t of e)for(let e of t.commands??[]){let n=r.get(e.name);if(n)throw new Ne(`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=/* @__PURE__ */ new Map,c=[];for(let t of e)for(let e of t.typegens??[]){let n=s.get(e.id);if(n)throw new Ne(`typegen`,e.id,[n,t.name]);s.set(e.id,t.name),c.push(e)}let l=/* @__PURE__ */ new Map,u=[];for(let t of e)for(let e of t.generators??[]){let n=l.get(e.name);if(n)throw new Ne(`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 import(`./project-root-B9BrO1na.mjs`).then(e=>e.n),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)}}}async function Dt(e){let{name:t,outDir:r}=e,i=S(t),a=y(t),o=[],s=A(r,`${i}.plugin.ts`);return await n(s,`import {
11
+ import{t as e}from"./rolldown-runtime-vT0bVE76.mjs";import{n as t,r as n,t as r}from"./fs-gRPNbfZO.mjs";import{a as i,c as a,d as o,i as s,l as c,n as l,o as u,r as d,s as f,t as p,u as m}from"./prompts-DKR7UZkc.mjs";import{A as h,C as g,D as _,E as v,F as y,M as b,N as ee,O as x,P as S,S as te,T as ne,_ as re,a as ie,b as ae,c as oe,f as se,g as ce,h as le,i as ue,j as de,k as fe,l as pe,m as me,p as he,r as ge,u as _e,v as ve,w as ye,x as be,y as xe}from"./doctor-C-VSGhJ6.mjs";import{f as Se,l as Ce,o as we,r as Te,s as Ee,t as De}from"./project-D7x753R7.mjs";import{a as Oe,c as ke,i as Ae,l as je,o as C,s as w,u as Me}from"./config-B7ZUrOl6.mjs";import{t as T}from"./project-root-DO7MsZOq.mjs";import{n as E,t as Ne}from"./types-C2QNIHnD.mjs";import{t as Pe}from"./build-Dr7_JT3S.mjs";import{n as Fe}from"./agent-docs-CmPrfpaP.mjs";import{C as Ie,S as Le,_ as Re,a as ze,b as Be,c as Ve,d as He,f as Ue,g as We,h as Ge,i as Ke,l as qe,m as Je,o as Ye,p as Xe,r as Ze,s as Qe,t as $e,u as et,v as tt,w as nt,x as D,y as rt}from"./typegen-B90QMhV8.mjs";import{createRequire as it}from"node:module";import O,{basename as at,dirname as k,join as A,relative as j,resolve as M,sep as N}from"node:path";import{cpSync as ot,existsSync as P,mkdirSync as st,readFileSync as F,readdirSync as I,rmSync as ct,statSync as lt,writeFileSync as L}from"node:fs";import{copyFile as ut,mkdir as dt,readFile as R,readdir as ft,rm as pt,stat as mt,writeFile as z}from"node:fs/promises";import{fork as ht,spawn as gt,spawnSync as _t}from"node:child_process";import{createHash as vt}from"node:crypto";import{fileURLToPath as yt,pathToFileURL as B}from"node:url";import{parseSync as bt}from"oxc-parser";import{arch as xt,platform as St,release as Ct}from"node:os";const wt=[{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`},{value:`storage`,label:`Storage`,hint:`disk, S3 / R2 / MinIO`}];function Tt(e){e.command(`new [name]`).alias(`init`).description(`Create a new KickJS project (use "." for current directory)`).option(`-d, --directory <dir>`,`Target directory (defaults to project name)`).option(`--pm <manager>`,`Package manager: pnpm | npm | yarn | bun`).option(`--git`,`Initialize git repository`).option(`--no-git`,`Skip git initialization`).option(`--install`,`Install dependencies after scaffolding`).option(`--no-install`,`Skip dependency installation`).option(`-f, --force`,`Remove existing files without prompting`).option(`-t, --template <type>`,`Project template: rest | minimal | fullstack | inertia`).option(`--runtime <engine>`,`HTTP runtime: express | fastify | h3`).option(`-r, --repo <type>`,`Repository name (inmemory, or any DB name e.g. postgres)`).option(`-s, --schema <lib>`,`Schema library for env / DTOs: zod | valibot | yup (default: zod)`).option(`--frontend <kind>`,`Fullstack web/ scaffold: 'kick' (wired React app) or 'vite' (create-vite, unwired)`).option(`--vite-template <name>`,`create-vite TypeScript template for --frontend vite (default 'react-ts')`).option(`--packages <packages>`,`Comma-separated packages to include (e.g. swagger,ws,queue,devtools)`).option(`-y, --yes`,`Pick safe defaults for every prompt (template=minimal, repo=inmemory, no extras, git+install on)`).option(`--non-interactive`,`alias for --yes`).action(async(e,t)=>{l(`KickJS — Create a new project`);let n=!!(t.yes||t.nonInteractive);e||=n?`my-api`:await a({message:`Project name`,placeholder:`my-api`,defaultValue:`my-api`});let r;if(e===`.`?(r=M(`.`),e=at(r)):r=M(t.directory||e),P(r)){let a=I(r);if(a.length>0){if(t.force)d.warn(`Clearing existing files in ${r}`);else if(n){d.warn(`Directory "${e}" is not empty. Pass --force to clear it.`),i(`Aborted.`);return}else{d.warn(`Directory "${e}" is not empty:`);let t=a.slice(0,5);for(let e of t)d.message(` - ${e}`);if(a.length>5&&d.message(` ... and ${a.length-5} more`),!await p({message:m.red(`Remove all existing files and proceed?`),initialValue:!1})){i(`Aborted.`);return}}for(let e of a)ct(M(r,e),{recursive:!0,force:!0})}}let o=t.template;o||=n?`minimal`:await u({message:`Project template`,options:[{value:`rest`,label:`REST API`,hint:`Express + Swagger`},{value:`minimal`,label:`Minimal`,hint:`bare Express`},{value:`fullstack`,label:`Fullstack`,hint:`server + Vite React web, typed client`},{value:`inertia`,label:`Inertia`,hint:`server-driven React pages, one app, SSR`}]});let c=t.runtime;c||=n?`express`:await u({message:`HTTP runtime`,options:[{value:`express`,label:`Express`,hint:`default, zero-config`},{value:`fastify`,label:`Fastify`,hint:`fastify + @fastify/middie`},{value:`h3`,label:`h3`,hint:`Nitro / Nuxt engine`}]});let f=t.pm;f||=n?await Ce(void 0):await u({message:`Package manager`,options:[{value:`pnpm`,label:`pnpm`},{value:`npm`,label:`npm`},{value:`yarn`,label:`yarn`},{value:`bun`,label:`bun`}]});let h=t.repo;h||=n?`inmemory`:await a({message:`Repository name`,placeholder:`inmemory (or a DB name, e.g. postgres)`,defaultValue:`inmemory`}),Me(h);let g=t.schema;o===`inertia`&&(g&&g!==`zod`&&d.warn(`The inertia template uses zod — ignoring --schema ${g}.`),g=`zod`),g||=n?`zod`:await u({message:`Schema library (env + DTO validation)`,options:[{value:`zod`,label:`Zod`,hint:`default — broad ecosystem`},{value:`valibot`,label:`Valibot`,hint:`smaller bundle`},{value:`yup`,label:`Yup`,hint:`classic API`}]}),[`zod`,`valibot`,`yup`].includes(g)||(d.warn(`Unknown --schema "${g}", falling back to zod.`),g=`zod`);let _;if(t.packages!==void 0){let e=t.packages.trim().toLowerCase();_=e===``||e===`none`||e===`false`?[]:t.packages.split(`,`).map(e=>e.trim()).filter(Boolean)}else _=n?[]:await s({message:`Select packages to include`,options:[...wt],required:!1});let v;v=t.git===void 0?n?!0:await p({message:`Initialize git repository?`,initialValue:!0}):t.git;let y;if(y=t.install===void 0?n?!0:await p({message:`Install dependencies?`,initialValue:!0}):t.install,t.frontend!==void 0&&t.frontend!==`kick`&&t.frontend!==`vite`){d.error(`Unknown --frontend '${String(t.frontend)}'. Use 'kick' (wired React app) or 'vite' (create-vite).`),i(`Aborted.`);return}let{VITE_TEMPLATES:b,DEFAULT_VITE_TEMPLATE:ee}=await import(`./fullstack-bVcLaFbj.mjs`);if(t.viteTemplate!==void 0&&!b.some(e=>e.value===t.viteTemplate)){d.error(`Unknown --vite-template '${String(t.viteTemplate)}'. TypeScript templates only: ${b.map(e=>e.value).join(`, `)}.`),i(`Aborted.`);return}let x=t.frontend===`vite`?`vite`:`kick`,S=t.viteTemplate??ee;if(o===`fullstack`&&!t.frontend&&!n&&(x=await u({message:`Frontend for web/`,options:[{value:`kick`,label:`KickJS React app`,hint:`typed client, /api proxy, route types — wired`},{value:`vite`,label:`Delegate to create-vite`,hint:`pick any framework; wiring is manual (guide printed after)`}]})),x===`vite`&&!t.viteTemplate&&!n&&(S=await u({message:`create-vite template`,options:b.map(e=>({value:e.value,label:e.label})),initialValue:ee})),o===`fullstack`){let{initFullstackProject:t}=await import(`./fullstack-bVcLaFbj.mjs`);await t({name:e,directory:r,packageManager:f,initGit:v,installDeps:y,schemaLib:g,runtime:c,packages:_,frontend:x,viteTemplate:S}),i(`Done! Next steps: ${m.cyan(`cd ${e} && ${f}${f===`pnpm`?` dev`:` run dev:server`}`)}`)}else await De({name:e,directory:r,packageManager:f,initGit:v,installDeps:y,template:o,defaultRepo:h,packages:_,schemaLib:g,runtime:c}),i(`Done! Next steps: ${m.cyan(`cd ${e} && ${f} dev`)}`)})}function Et(e,t=[]){let n=/* @__PURE__ */ 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 Ne(`plugin`,t.name,[t.name,t.name])}let r=/* @__PURE__ */ new Map,i=[];for(let t of e)for(let e of t.commands??[]){let n=r.get(e.name);if(n)throw new Ne(`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=/* @__PURE__ */ new Map,c=[];for(let t of e)for(let e of t.typegens??[]){let n=s.get(e.id);if(n)throw new Ne(`typegen`,e.id,[n,t.name]);s.set(e.id,t.name),c.push(e)}let l=/* @__PURE__ */ new Map,u=[];for(let t of e)for(let e of t.generators??[]){let n=l.get(e.name);if(n)throw new Ne(`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 import(`./project-root-DO7MsZOq.mjs`).then(e=>e.n),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)}}}async function Dt(e){let{name:t,outDir:r}=e,i=S(t),a=y(t),o=[],s=A(r,`${i}.plugin.ts`);return await n(s,`import {
12
12
  definePlugin,
13
13
  type AppAdapter,
14
14
  type AppModuleEntry,
@@ -347,7 +347,7 @@ describe('${s}', () => {
347
347
  Example: kick g scaffold Post title:string body:text:optional published:boolean:optional
348
348
  Optional: append :optional (shell-safe, no quoting needed)
349
349
  `),process.exit(1));let s=await C(process.cwd()),c=w(s),l=a.modulesDir??c.dir??`src/modules`,u=Wt(n),d=je(s,process.cwd()),f=Oe(T()),p=await Gt({name:e,fields:u,modulesDir:M(l),noEntity:a.entity===!1,noTests:a.tests===!1,pluralize:a.pluralize===!1?!1:c.pluralize??!0,tokenScope:d,swagger:f,style:c.style});console.log(`\n Scaffolded ${e} with ${u.length} field(s):`);for(let e of u)console.log(` ${e.name}: ${e.type}${e.optional?` (optional)`:``}`);W(p,o),await Zt(o)}),r.command(`config`).description(`Generate a kick.config.ts at the project root`).option(`--modules-dir <dir>`,`Modules directory path`,`src/modules`).option(`--repo <type>`,`Repository name: inmemory (default) or any DB name`,`inmemory`).option(`-f, --force`,`Overwrite existing kick.config.ts without prompting`).action(async(e,n)=>{let r=U(n);t(r),W(await At({outDir:M(`.`),modulesDir:e.modulesDir,defaultRepo:e.repo,force:e.force}),r)}),r.command(`agents`).alias(`agent-docs`).alias(`ai-docs`).description(`Regenerate .agents/* + root CLAUDE.md (sync after framework upgrades)`).option(`--only <which>`,`Limit scope: agents | claude | skills | gemini | copilot | both (agents+claude) | all (default: all)`,`all`).option(`--name <name>`,`Project name (defaults to package.json name)`).option(`--pm <pm>`,`Package manager (defaults to package.json packageManager)`).option(`--template <template>`,`Template: rest | minimal | fullstack | inertia`).option(`-f, --force`,`Overwrite existing files without prompting`).action(async(e,n)=>{let r=U(n);t(r);let i=e.only??`all`;Xt.includes(i)?W(await Fe({outDir:M(`.`),only:i,name:e.name,pm:e.pm,template:e.template,force:e.force}),r):(console.error(` Invalid --only value: ${i}. Expected: ${Xt.join(` | `)}`),process.exitCode=1)});for(let e of n?.generators??[])on(r,e,n?.projectRoot)}function on(e,n,r){let{source:i,spec:a}=n,o=a.args?.[0],s=o?.name??`itemName`,c=o?.required?`<${s}>`:`[${s}]`,l=`${a.name} ${c} [extraArgs...]`,u=e.command(l).description(`${a.description} [${i}]`);for(let e of a.flags??[]){let t=e.takesValue?`--${e.name} <value>`:`--${e.name}`,n=e.alias?`-${e.alias}, ${t}`:t;u.option(n,e.description??``)}u.action(async(e,i,o,s)=>{let c=U(s);t(c);let l=await ie({generatorName:a.name,itemName:e??``,args:i??[],flags:o,cwd:process.cwd(),projectRoot:r},[n]);l&&W(l.files,c)})}const sn=`/* AUTO-GENERATED by kick typegen — do not edit. Plugin: `;async function cn(e){let t=O.resolve(e.cwd,`.kickjs/types`);e.check||await dt(t,{recursive:!0});let n=/* @__PURE__ */ new Map,r=e.scan??Ge,i=O.resolve(e.cwd,`.kickjs`,`cache`),a=e.scan?void 0:e.changedFiles,o={cwd:e.cwd,config:e.config,async importTs(e){return await import(B(e).href)},async writeFile(t,n){let r=O.resolve(e.cwd,t);await dt(O.dirname(r),{recursive:!0}),await z(r,n,`utf8`)},getScanResult:e=>{let t=ln(e),o=n.get(t);if(!o){let s={cacheDir:i,...e};o=a?We(s,a):r(s),n.set(t,o)}return o},log:console,watch:e.watch,check:e.check},s=[],c=[];for(let n of e.plugins){let r=n.outExtension??`.d.ts`,i=O.join(t,`${n.id.replace(/\//g,`__`)}${r}`),a;try{a=await n.generate(o)}catch(t){let r=t instanceof Error?t.message:String(t);if(e.check)throw Error(`kick typegen --check: ${n.id} failed to generate (${r})`,{cause:t});o.log.error(` ${n.id}: typegen failed (${r}) — keeping previous output`),s.push({id:n.id,status:`error`,outFile:i});continue}if(a===null){s.push({id:n.id,status:`skipped`});continue}let l=`${sn}${n.id} */\n\n`+a+`
350
- `,u=``;P(i)&&(u=await R(i,`utf8`)),u===l?s.push({id:n.id,status:`unchanged`,outFile:i}):e.check?(c.push({id:n.id,outFile:i}),s.push({id:n.id,status:`drifted`,outFile:i})):(await z(i,l,`utf8`),s.push({id:n.id,status:`written`,outFile:i}))}if(c.length>0)throw new _e(c);return s}function ln(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 un(e,t){let n=new Set(t),r=[],i=[],a=/* @__PURE__ */ 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 dn=/* @__PURE__ */ e({applyDisableFilter:()=>un,runAllPluginTypegens:()=>G});async function G(e){let{enabled:t,skipped:n,unknown:r}=un(Et([...ra,...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 cn({cwd:e.cwd,config:e.config??{},plugins:t,watch:e.watch,check:e.check,changedFiles:e.changedFiles});if(!e.silent&&se())for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(t instanceof _e||e.check)throw t;if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}function fn(e){let t=A(e,`node_modules`,`.bin`),n=process.platform===`win32`;for(let e of[`vue-tsc`,`tsgo`,`tsc`]){let r=n?[`${e}.CMD`,`${e}.cmd`,`${e}.exe`]:[e];for(let i of r){let r=A(t,i);if(P(r))return{cmd:r,args:[`--noEmit`],shell:n,kind:e}}}return null}function pn(e){let t=e.spawnFn??gt,n=null,r=0,i=!1;return{schedule(){if(i)return;let a=++r;n&&=(n.kill(),null);let o=Date.now(),s=t(e.bin.cmd,e.bin.args,{cwd:e.cwd,shell:e.bin.shell,stdio:[`ignore`,`pipe`,`pipe`]});n=s;let c=``;s.stdout?.on(`data`,e=>{c+=e.toString()}),s.stderr?.on(`data`,e=>{c+=e.toString()}),s.on(`error`,()=>{a===r&&(n=null)}),s.on(`close`,t=>{i||a!==r||(n=null,e.onResult({ok:t===0,output:c,durationMs:Date.now()-o,kind:e.bin.kind}))})},dispose(){i=!0,n&&=(n.kill(),null)}}}function mn(e,t=12){let n=e.trim().split(/\r?\n/);return n.length<=t?n.join(`
350
+ `,u=``;P(i)&&(u=await R(i,`utf8`)),u===l?s.push({id:n.id,status:`unchanged`,outFile:i}):e.check?(c.push({id:n.id,outFile:i}),s.push({id:n.id,status:`drifted`,outFile:i})):(await z(i,l,`utf8`),s.push({id:n.id,status:`written`,outFile:i}))}if(c.length>0)throw new _e(c);return s}function ln(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 un(e,t){let n=new Set(t),r=[],i=[],a=/* @__PURE__ */ 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 dn=/* @__PURE__ */ e({applyDisableFilter:()=>un,runAllPluginTypegens:()=>G});async function G(e){let{enabled:t,skipped:n,unknown:r}=un(Et([...ua,...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 cn({cwd:e.cwd,config:e.config??{},plugins:t,watch:e.watch,check:e.check,changedFiles:e.changedFiles});if(!e.silent&&se())for(let e of n)console.log(` ${e.id}: ${e.status}`);return n}catch(t){if(t instanceof _e||e.check)throw t;if(!e.silent){let e=t instanceof Error?t.message:String(t);console.warn(` kick typegen plugins: skipped (${e})`)}return[]}}function fn(e){let t=A(e,`node_modules`,`.bin`),n=process.platform===`win32`;for(let e of[`vue-tsc`,`tsgo`,`tsc`]){let r=n?[`${e}.CMD`,`${e}.cmd`,`${e}.exe`]:[e];for(let i of r){let r=A(t,i);if(P(r))return{cmd:r,args:[`--noEmit`],shell:n,kind:e}}}return null}function pn(e){let t=e.spawnFn??gt,n=null,r=0,i=!1;return{schedule(){if(i)return;let a=++r;n&&=(n.kill(),null);let o=Date.now(),s=t(e.bin.cmd,e.bin.args,{cwd:e.cwd,shell:e.bin.shell,stdio:[`ignore`,`pipe`,`pipe`]});n=s;let c=``;s.stdout?.on(`data`,e=>{c+=e.toString()}),s.stderr?.on(`data`,e=>{c+=e.toString()}),s.on(`error`,()=>{a===r&&(n=null)}),s.on(`close`,t=>{i||a!==r||(n=null,e.onResult({ok:t===0,output:c,durationMs:Date.now()-o,kind:e.bin.kind}))})},dispose(){i=!0,n&&=(n.kill(),null)}}}function mn(e,t=12){let n=e.trim().split(/\r?\n/);return n.length<=t?n.join(`
351
351
  `):`${n.slice(0,t).join(`
352
352
  `)}\n… ${n.length-t} more line(s)`}function hn(e){if(typeof e==`boolean`)return e;let t=process.env.KICKJS_WATCH_POLLING;return t===`1`||t===`true`}async function gn(e,t=`127.0.0.1`){let n=await import(`node:inspector`);n.open(e,t,!1);let r=n.url();if(!r)throw Error(`inspector.open() reported no URL`);return r}async function _n(e,t,n={}){t&&(process.env.PORT=t);let r=hn(n.polling),i=process.cwd(),a=await C(i),o=a?.typegen?.schemaValidator??`zod`,s=a?.typegen?.envFile;try{await $e({cwd:i,allowDuplicates:!0,schemaValidator:o,envFile:s,srcDir:a?.typegen?.srcDir,outDir:a?.typegen?.outDir,assetMap:a?.assetMap,runPlugins:!1})}catch(e){console.warn(` kick typegen: skipped (${e?.message??e})`)}let c=M(i,a?.typegen?.outDir??`.kickjs/types`);try{let e=await G({cwd:i,config:a});await Ke(c,e,!1)}catch(e){console.warn(` kick typegen: plugin pass skipped (${e?.message??e})`)}let{createRequire:l}=await import(`node:module`),u=l(M(`package.json`)).resolve(`vite`),{createServer:d}=await import(B(u).href);globalThis[oe]=`kick-dev`;let f=await d({configFile:M(`vite.config.ts`),server:{port:t?parseInt(t,10):void 0,...r?{watch:{usePolling:!0,interval:100}}:{}}}),p=n.typecheck??a?.dev?.typecheck??!1,m=null,h=!0;if(p){let e=fn(i);e?m=pn({cwd:i,bin:e,onResult:e=>{f.hot.send({type:`custom`,event:`kickjs:typecheck`,data:{ok:e.ok,output:e.output,durationMs:e.durationMs}}),e.ok?h||(h=!0,console.log(` kick typecheck: clean again (${e.kind}, ${e.durationMs}ms)`)):(h=!1,console.warn(`\n kick typecheck (${e.kind}, ${e.durationMs}ms):`),console.warn(mn(e.output).replace(/^/gm,` `)))}}):console.warn(` kick dev: --typecheck requested but neither tsgo (@typescript/native-preview) nor typescript is installed in this project — skipping type checks.`)}let g=pe({cwd:i,config:a,emitWarning:e=>{console.warn(e),f.hot.send({type:`custom`,event:`kickjs:typegen-error`,data:{message:e,timestamp:Date.now()}})},onPassComplete:()=>m?.schedule()});f.watcher.on(`add`,e=>g.handleWatchEvent(`add`,e)),f.watcher.on(`unlink`,e=>g.handleWatchEvent(`unlink`,e)),f.watcher.on(`change`,e=>g.handleWatchEvent(`change`,e)),f.watcher.on(`unlinkDir`,e=>g.handleWatchEvent(`unlinkDir`,e)),g.assetSrcRoots.length>0&&f.watcher.add([...g.assetSrcRoots]),await f.listen(),f.printUrls(),console.log(`
353
353
  KickJS dev server running (Vite + @forinda/kickjs-vite)
@@ -679,7 +679,7 @@ server.on('exit', () => {
679
679
  Cancelled.
680
680
  `);return}await pt(l,{recursive:!0,force:!0}),console.log(` Deleted: ${l}`);let u=A(n,`index.ts`);if(await r(u)){let e=await R(u,`utf-8`),t=e,n=RegExp(`^import\\s*\\{\\s*${h(s)}Module\\s*\\}\\s*from\\s*['"][^'"]*${h(c)}(?:/[^'"]*)?['"].*\\n?`,`gm`);e=e.replace(n,``),e=or(e,s),e=e.replace(/\n{3,}/g,`
681
681
 
682
- `),e!==t&&(await z(u,e,`utf-8`),console.log(` Unregistered: ${s}Module from ${u}`))}console.log(`\n Module '${c}' removed.\n`)}function cr(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=await C(process.cwd()),r=w(n),i=t.modulesDir??r.dir??`src/modules`,a=t.pluralize===!1?!1:r.pluralize??!0;for(let n of e)await sr({name:n,modulesDir:M(i),force:t.force,pluralize:a})})}function lr(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;if(e===`kickjs-schema`||e===`schema`)return`kickjs-schema`;console.warn(` kick typegen: unknown --schema-validator '${e}' (supported: 'zod', 'kickjs-schema', 'false'). Falling back to project config.`)}}function ur(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function dr(e){e.command(`typegen`).description(`Generate type-safe DI registry and module types into .kickjs/types/`).option(`-w, --watch`,`Watch source files and regenerate on change`).option(`-s, --src <dir>`,`Source directory to scan`,`src`).option(`-o, --out <dir>`,`Output directory`,`.kickjs/types`).option(`--silent`,`Suppress output`).option(`--allow-duplicates`,`Auto-namespace duplicate class names instead of failing (use with caution)`).option(`--schema-validator <name>`,`Schema validator for body/query/params typing (currently 'zod' or 'false')`).option(`--env-file <path>`,`Path to env schema file for KickEnv typing (default 'src/env.ts'; pass 'false' to disable)`).option(`--check`,`CI gate: exit non-zero if any generated file in .kickjs/types/ is out of date (routes, env, db, assets, adopter plugins) instead of writing it`).option(`--fix`,`Patch module import.meta.glob() calls to cover decorated classes that aren't loaded by any glob (orphans)`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").option(`--no-cache`,`Disable the persistent scan cache; re-read + re-extract every file from cold`).action(async e=>{let t=T(process.cwd()),n=await C(t);if(e.list){let{mergeCliPlugins:e}=await import(`./plugin-Bs0soxrU.mjs`),{builtinCliPlugins:t}=await import(`./builtins-CtpLZ4FY.mjs`),r=e([...t,...n?.plugins??[]],n?.commands??[]),i=new Set(n?.typegen?.disable??[]);if(r.typegens.length===0){console.log(` No typegen plugins registered.`);return}let a=Math.max(...r.typegens.map(e=>e.id.length));console.log(`
682
+ `),e!==t&&(await z(u,e,`utf-8`),console.log(` Unregistered: ${s}Module from ${u}`))}console.log(`\n Module '${c}' removed.\n`)}function cr(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=await C(process.cwd()),r=w(n),i=t.modulesDir??r.dir??`src/modules`,a=t.pluralize===!1?!1:r.pluralize??!0;for(let n of e)await sr({name:n,modulesDir:M(i),force:t.force,pluralize:a})})}function lr(e){if(e!==void 0){if(e===`false`||e===`off`||e===`none`)return!1;if(e===`zod`)return`zod`;if(e===`kickjs-schema`||e===`schema`)return`kickjs-schema`;console.warn(` kick typegen: unknown --schema-validator '${e}' (supported: 'zod', 'kickjs-schema', 'false'). Falling back to project config.`)}}function ur(e){if(e!==void 0)return e===`false`||e===`off`||e===`none`?!1:e}function dr(e){e.command(`typegen`).description(`Generate type-safe DI registry and module types into .kickjs/types/`).option(`-w, --watch`,`Watch source files and regenerate on change`).option(`-s, --src <dir>`,`Source directory to scan`,`src`).option(`-o, --out <dir>`,`Output directory`,`.kickjs/types`).option(`--silent`,`Suppress output`).option(`--allow-duplicates`,`Auto-namespace duplicate class names instead of failing (use with caution)`).option(`--schema-validator <name>`,`Schema validator for body/query/params typing (currently 'zod' or 'false')`).option(`--env-file <path>`,`Path to env schema file for KickEnv typing (default 'src/env.ts'; pass 'false' to disable)`).option(`--check`,`CI gate: exit non-zero if any generated file in .kickjs/types/ is out of date (routes, env, db, assets, adopter plugins) instead of writing it`).option(`--fix`,`Patch module import.meta.glob() calls to cover decorated classes that aren't loaded by any glob (orphans)`).option(`--list`,"List every registered typegen plugin id (use to populate `typegen.disable`)").option(`--no-cache`,`Disable the persistent scan cache; re-read + re-extract every file from cold`).action(async e=>{let t=T(process.cwd()),n=await C(t);if(e.list){let{mergeCliPlugins:e}=await import(`./plugin-E910l1_e.mjs`),{builtinCliPlugins:t}=await import(`./builtins-MG6t5uS3.mjs`),r=e([...t,...n?.plugins??[]],n?.commands??[]),i=new Set(n?.typegen?.disable??[]);if(r.typegens.length===0){console.log(` No typegen plugins registered.`);return}let a=Math.max(...r.typegens.map(e=>e.id.length));console.log(`
683
683
  Registered typegen plugins:
684
684
  `);for(let e of r.typegens){let t=i.has(e.id)?` (disabled)`:``,n=`${e.id.replace(/\//g,`__`)}${e.outExtension??`.d.ts`}`;console.log(` ${e.id.padEnd(a+2)}→ .kickjs/types/${n}${t}`),console.log(` ${` `.repeat(a+2)} watches: ${e.inputs.join(`, `)||`(none)`}`)}console.log(`
685
685
  Disable one in kick.config.ts:
@@ -695,16 +695,24 @@ server.on('exit', () => {
695
695
  Available checks:
696
696
  --deploy Audit for production readiness (security, config, best practices)
697
697
  --di Find REQUEST-scoped dependencies injected into singleton constructors
698
- `);return}let t=process.cwd();l(e.deploy?`KickJS Deploy Check`:`KickJS DI Check`);let n=f();n.start(`Scanning project...`);let r=[...e.deploy?Or(t):[],...e.di?kr(t):[]];n.stop(`Scan complete`);let a={CRITICAL:0,WARNING:1,INFO:2};r.sort((e,t)=>a[e.severity]-a[t.severity]);for(let e of r)d.message(`${o(e.severity)} ${e.message}`);let s=r.filter(e=>e.severity===`CRITICAL`).length,c=r.filter(e=>e.severity===`WARNING`).length,u=r.filter(e=>e.severity===`INFO`).length,p=c===1?`warning`:`warnings`,h=[s>0?m.red(`${s} critical`):`${s} critical`,c>0?m.yellow(`${c} ${p}`):`${c} ${p}`,`${u} info`].join(`, `);s>0?(i(m.red(`${h} — fix critical issues before deploying`)),process.exit(1)):i(m.green(`${h} — looking good!`))})}function jr(e){return e.optsWithGlobals().dryRun??!1}function Mr(e){e.command(`codemod`).description(`Codebase migration commands (AST-style rewrites — distinct from db migrate)`).command(`modules`).description(`Rewrite module declarations between class form and the defineModule factory.
698
+ `);return}let t=process.cwd();l(e.deploy?`KickJS Deploy Check`:`KickJS DI Check`);let n=f();n.start(`Scanning project...`);let r=[...e.deploy?Or(t):[],...e.di?kr(t):[]];n.stop(`Scan complete`);let a={CRITICAL:0,WARNING:1,INFO:2};r.sort((e,t)=>a[e.severity]-a[t.severity]);for(let e of r)d.message(`${o(e.severity)} ${e.message}`);let s=r.filter(e=>e.severity===`CRITICAL`).length,c=r.filter(e=>e.severity===`WARNING`).length,u=r.filter(e=>e.severity===`INFO`).length,p=c===1?`warning`:`warnings`,h=[s>0?m.red(`${s} critical`):`${s} critical`,c>0?m.yellow(`${c} ${p}`):`${c} ${p}`,`${u} info`].join(`, `);s>0?(i(m.red(`${h} — fix critical issues before deploying`)),process.exit(1)):i(m.green(`${h} — looking good!`))})}const jr=Symbol.for(`kickjs.handler.entryCapture`),Mr=Symbol.for(`kickjs.config.describe`);function Nr(e){return Array.isArray(e)?e.join(`,`):typeof e==`object`&&e||typeof e==`string`&&/[\r\n]/.test(e)?JSON.stringify(e):String(e)}function Pr(e){let t=[];for(let n of e){let e=[n.description,n.list?`comma-separated list`:void 0].filter(Boolean);for(let n of e.length>0?e.join(` — `).split(/\r?\n/):[])t.push(`# ${n}`);n.required?t.push(`${n.name}=`):t.push(`# ${n.name}=${n.default===void 0?``:Nr(n.default)}`)}return t}function Fr(e){let t=[`# Generated by \`kick env example\` from the env schema and the declared settings
699
+ # sections. Re-run it after changing them; \`kick env example --check\` fails when stale.
700
+ #
701
+ # Uncommented variables are required. Commented ones are optional; the value shown
702
+ # is the default. Any variable can come from a file instead: NAME_FILE=/run/secrets/name`];e.env.length>0&&t.push([`# ── App env schema ──`,...Pr(e.env)].join(`
703
+ `));for(let n of e.sections)t.push([`# ── ${n.prefix} settings (declared by ${n.declaredBy}) ──`,...Pr(n.vars)].join(`
704
+ `));return`${t.join(`
705
+
706
+ `)}\n`}async function Ir(e,t){let n=M(e,t);if(!P(n))throw Error(`${t} not found`);let r=M(e,`vite.config.ts`);if(!P(r))throw Error(`vite.config.ts not found — kick env example loads the app through it`);let{createRequire:i}=await import(`node:module`),a=i(M(e,`package.json`)),{createServer:o}=await import(B(a.resolve(`vite`)).href),s=globalThis,c;s[jr]=e=>{c??=e},s[Mr]=!0,s[oe]=`kick-env`;let l=await o({configFile:r,root:e,logLevel:`error`,appType:`custom`,server:{middlewareMode:!0,hmr:!1,watch:null}});try{await l.ssrLoadModule(n)}finally{delete s[jr],delete s[Mr],delete s[oe],await l.close()}if(!c)throw Error(`${t} finished loading without calling bootstrap()`);return c.describeConfig()}function Lr(e){e.command(`env`).description(`Work with the environment the app reads`).command(`example`).description(`Write .env.example from the env schema and declared settings sections`).option(`-e, --entry <file>`,`App entry that calls bootstrap()`,`src/index.ts`).option(`-o, --out <file>`,`File to write`,`.env.example`).option(`--check`,`Exit 1 if the file is missing or out of date, instead of writing it`).action(async e=>{let t=process.cwd(),n=M(t,e.out),r;try{r=Fr(await Ir(t,e.entry))}catch(e){console.error(`\n kick env example: ${e.message}\n`),process.exit(1)}e.check?((P(n)?F(n,`utf8`):void 0)!==r&&(console.error(`\n ${e.out} is out of date — run \`kick env example\`.\n`),process.exit(1)),console.log(` ${e.out} is up to date.`)):(L(n,r),console.log(` Wrote ${e.out}`))})}function Rr(e){return e.optsWithGlobals().dryRun??!1}function zr(e){e.command(`codemod`).description(`Codebase migration commands (AST-style rewrites — distinct from db migrate)`).command(`modules`).description(`Rewrite module declarations between class form and the defineModule factory.
699
707
  Direction defaults to \`modules.style\` from kick.config (or "define").
700
708
  --target define|class Override the migration direction.
701
709
  --apply Apply the changes (default: dry-run preview).
702
- --experimental Acknowledge that AST migration is experimental.`).option(`--modules-dir <dir>`,`Modules directory (default: src/modules from kick.config)`).option(`--apply`,`Apply the migration to disk (default: dry-run)`).option(`--experimental`,`Acknowledge that this command is experimental`).option(`--target <style>`,`Migration direction — 'define' or 'class'`).option(`--no-backup`,`Skip the .kickjs/codemod-backups/ snapshot (default: backup on)`).action(async(e,n)=>{let r=jr(n)||!e.apply;t(r),e.experimental||(console.error(`
710
+ --experimental Acknowledge that AST migration is experimental.`).option(`--modules-dir <dir>`,`Modules directory (default: src/modules from kick.config)`).option(`--apply`,`Apply the migration to disk (default: dry-run)`).option(`--experimental`,`Acknowledge that this command is experimental`).option(`--target <style>`,`Migration direction — 'define' or 'class'`).option(`--no-backup`,`Skip the .kickjs/codemod-backups/ snapshot (default: backup on)`).action(async(e,n)=>{let r=Rr(n)||!e.apply;t(r),e.experimental||(console.error(`
703
711
  `+m.red(`Error:`)+` kick codemod modules is experimental — pass --experimental to acknowledge.
704
712
  The regex-based rewrite handles the shapes our templates produce.
705
713
  Hand-rolled modules with non-standard structures may be skipped.
706
714
  Always commit before running with --apply.
707
- `),process.exit(1));let i=await C(process.cwd()),a=w(i),o=M(e.modulesDir??a.dir??`src/modules`),s;e.target===`define`||e.target===`class`?s=e.target:e.target===void 0?s=a.style??`define`:(console.error(`\n ${m.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let c=m.dim(`→ ${s}`),l=r?m.dim(`(dry-run)`):m.bold(`(applying)`);console.log(`\n ${m.bold(`kick codemod modules`)} ${c} ${l}`),console.log(` modulesDir: ${m.dim(o)}\n`);let u=e.backup!==!1&&!r,d=await Vt(o,{dryRun:r,target:s,backup:u});if(d.backupDir){let e=d.backupDir;console.log(` ${m.green(`✓`)} backup: ${m.dim(e)}\n ${m.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else!r&&e.backup===!1&&console.log(` ${m.dim(`(--no-backup — skipping snapshot)`)}\n`);let f=0,p=0;for(let e of d.files)if(e.status===`migrated`)f++,console.log(` ${m.green(`✓`)} ${e.path}`);else{p++;let t=m.dim(`(${e.reason??`skipped`})`);console.log(` ${m.dim(`-`)} ${e.path} ${t}`)}if(console.log(),d.indexStatus===`migrated`)console.log(` ${m.green(`✓`)} ${d.indexPath}`);else if(d.indexStatus===`skipped`){let e=m.dim(`(${d.indexReason??`skipped`})`);console.log(` ${m.dim(`-`)} ${d.indexPath} ${e}`)}else console.log(` ${m.dim(`-`)} ${d.indexPath} ${m.dim(`(not found)`)}`);let h=r?m.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${m.bold(String(f))} migrated, ${m.bold(String(p))} skipped${h}\n`)})}function Nr(e){try{let t=JSON.parse(F(M(e,`package.json`),`utf-8`));return{...t.dependencies,...t.devDependencies}}catch{return{}}}function Pr(e,t=P,n=Nr(e)){if(n[`@forinda/kickjs-inertia`])return{staticDir:`dist/client`,siteRoot:`.`,apiPath:``,include:[`dist/client/.vite/manifest.json`,`dist/ssr`]};let r=k(e);return(t(M(r,`pnpm-workspace.yaml`))||t(M(r,`package.json`)))&&t(M(r,`web`,`package.json`))?{staticDir:`../web/dist`,siteRoot:`..`,apiPath:`/api`}:{siteRoot:`.`,apiPath:``}}function Fr(e,t,n,r){let i=Pr(t,n,r),a=e?.staticDir===!1?void 0:e?.staticDir??i.staticDir;return{entry:e?.entry??`src/serverless.ts`,outDir:e?.outDir??`dist/serverless`,staticDir:a,siteRoot:e?.siteRoot??i.siteRoot,publishDir:e?.publishDir??`dist/public`,apiPath:e?.apiPath??i.apiPath,external:e?.external??[`valibot`,`yup`],vercelRuntime:e?.vercelRuntime??`nodejs22.x`,include:e?.include??i.include??[]}}function Ir(e,t,n={projectDir:`.`}){let r=[` path: '${t}/*',`,...n.preferStatic?[` preferStatic: true,`]:[],...n.includedFiles?.length?[` includedFiles: ${JSON.stringify(n.includedFiles)},`]:[]];return`import { fileURLToPath } from 'node:url'
715
+ `),process.exit(1));let i=await C(process.cwd()),a=w(i),o=M(e.modulesDir??a.dir??`src/modules`),s;e.target===`define`||e.target===`class`?s=e.target:e.target===void 0?s=a.style??`define`:(console.error(`\n ${m.red(`Error:`)} --target must be 'define' or 'class' (got '${e.target}').\n`),process.exit(1));let c=m.dim(`→ ${s}`),l=r?m.dim(`(dry-run)`):m.bold(`(applying)`);console.log(`\n ${m.bold(`kick codemod modules`)} ${c} ${l}`),console.log(` modulesDir: ${m.dim(o)}\n`);let u=e.backup!==!1&&!r,d=await Vt(o,{dryRun:r,target:s,backup:u});if(d.backupDir){let e=d.backupDir;console.log(` ${m.green(`✓`)} backup: ${m.dim(e)}\n ${m.dim(`(restore: rm -rf <modulesDir> && mv "<backup>" <modulesDir>)`)}\n`)}else!r&&e.backup===!1&&console.log(` ${m.dim(`(--no-backup — skipping snapshot)`)}\n`);let f=0,p=0;for(let e of d.files)if(e.status===`migrated`)f++,console.log(` ${m.green(`✓`)} ${e.path}`);else{p++;let t=m.dim(`(${e.reason??`skipped`})`);console.log(` ${m.dim(`-`)} ${e.path} ${t}`)}if(console.log(),d.indexStatus===`migrated`)console.log(` ${m.green(`✓`)} ${d.indexPath}`);else if(d.indexStatus===`skipped`){let e=m.dim(`(${d.indexReason??`skipped`})`);console.log(` ${m.dim(`-`)} ${d.indexPath} ${e}`)}else console.log(` ${m.dim(`-`)} ${d.indexPath} ${m.dim(`(not found)`)}`);let h=r?m.dim(` (dry-run — pass --apply to write)`):``;console.log(`\n ${m.bold(String(f))} migrated, ${m.bold(String(p))} skipped${h}\n`)})}function Br(e){try{let t=JSON.parse(F(M(e,`package.json`),`utf-8`));return{...t.dependencies,...t.devDependencies}}catch{return{}}}function Vr(e,t=P,n=Br(e)){if(n[`@forinda/kickjs-inertia`])return{staticDir:`dist/client`,siteRoot:`.`,apiPath:``,include:[`dist/client/.vite/manifest.json`,`dist/ssr`]};let r=k(e);return(t(M(r,`pnpm-workspace.yaml`))||t(M(r,`package.json`)))&&t(M(r,`web`,`package.json`))?{staticDir:`../web/dist`,siteRoot:`..`,apiPath:`/api`}:{siteRoot:`.`,apiPath:``}}function Hr(e,t,n,r){let i=Vr(t,n,r),a=e?.staticDir===!1?void 0:e?.staticDir??i.staticDir;return{entry:e?.entry??`src/serverless.ts`,outDir:e?.outDir??`dist/serverless`,staticDir:a,siteRoot:e?.siteRoot??i.siteRoot,publishDir:e?.publishDir??`dist/public`,apiPath:e?.apiPath??i.apiPath,external:e?.external??[`valibot`,`yup`],vercelRuntime:e?.vercelRuntime??`nodejs22.x`,include:e?.include??i.include??[]}}function Ur(e,t,n={projectDir:`.`}){let r=[` path: '${t}/*',`,...n.preferStatic?[` preferStatic: true,`]:[],...n.includedFiles?.length?[` includedFiles: ${JSON.stringify(n.includedFiles)},`]:[]];return`import { fileURLToPath } from 'node:url'
708
716
  import { handler } from '${e}'
709
717
 
710
718
  // Where the app's build files were packaged; the platform starts this
@@ -718,7 +726,7 @@ export const config = {
718
726
  ${r.join(`
719
727
  `)}
720
728
  }
721
- `}function Lr(){return`import { fileURLToPath } from 'node:url'
729
+ `}function Wr(){return`import { fileURLToPath } from 'node:url'
722
730
  import { handler } from './server.mjs'
723
731
 
724
732
  // The app's build files are copied into this function at their project
@@ -728,11 +736,11 @@ process.env.KICK_APP_ROOT ??= fileURLToPath(new URL('./', import.meta.url))
728
736
  const requestContext = () => globalThis[Symbol.for('@vercel/request-context')]?.get?.()
729
737
 
730
738
  export default (req, res) => handler.node(req, res, requestContext())
731
- `}function Rr(e){return/^\s*publish\s*=\s*["']([^"']+)["']/m.exec(e)?.[1]?.replace(/^\.\//,``).replace(/\/+$/,``)}function zr(e,t,n=!1){let r=[{handle:`filesystem`},{src:`^${e}/(.*)$`,dest:`/api`}];return n&&e!==``&&r.push({src:`^/_kick/(.*)$`,dest:`/api`}),t&&e!==``&&r.push({src:`^/(.*)$`,dest:`/index.html`}),r}function Br(e,t){let n;try{n=bt(t,e).program}catch{return[]}let r=[],i=t=>e.slice(0,t).split(`
732
- `).length,a=e=>{if(!e||typeof e!=`object`)return;if(Array.isArray(e))return e.forEach(a);let n=e,o=n.expression;if(n.type===`Decorator`&&o?.type===`CallExpression`&&o.callee?.type===`Identifier`&&o.callee.name===`Cron`){let[e,a]=o.arguments??[],s=e?.type===`Literal`&&typeof e.value==`string`?e.value:e?.type===`TemplateLiteral`&&e.expressions.length===0?e.quasis[0]?.value?.cooked:void 0;r.push({file:t,line:i(n.start??0),expression:s,timezone:a?.type===`ObjectExpression`&&a.properties.some(e=>(e.key?.name??e.key?.value)===`timezone`)})}for(let e in n)e!==`parent`&&a(n[e])};return a(n),r}function Vr(e){let t=M(e,`src`);return P(t)?I(t,{recursive:!0,encoding:`utf-8`}).filter(e=>/\.m?ts$/.test(e)&&!/\.(test|spec|d)\.m?ts$/.test(e)).flatMap(e=>{let n=F(M(t,e),`utf-8`);return n.includes(`@Cron`)?Br(n,`src/${e}`):[]}):[]}function Hr(e){let t=2166136261;for(let n of e.trim().replace(/\s+/g,` `))t^=n.codePointAt(0),t=Math.imul(t,16777619)>>>0;return t.toString(36)}function Ur(e){let t=[],n=/* @__PURE__ */ new Map;for(let r of e){let e=`${r.file}:${r.line}`;if(r.expression===void 0){t.push(`${e}: @Cron expression is not a string literal, so it has no Vercel cron entry`);continue}r.timezone&&t.push(`${e}: Vercel crons run in UTC — the timezone option is ignored there`);let i=r.expression.trim().replace(/\s+/g,` `);i.split(` `).length===5?n.set(Hr(i),i):t.push(`${e}: Vercel crons need a five-field expression, so it has no Vercel cron entry`)}return{crons:[...n].map(([e,t])=>({path:`/_kick/cron/${e}`,schedule:t})),warnings:t}}function Wr(e){let t=e=>{if(typeof e==`string`)return e;if(!e||typeof e!=`object`)return;let n=e;for(let e of[`import`,`module`,`node`,`default`]){let r=t(n[e]);if(r)return r}},n=e.exports;return t(typeof n==`string`||Array.isArray(n)?n:n?.[`.`]??n)??e.module??e.main}async function Gr(e,t){let{createRequire:n}=await import(`node:module`),r=n(M(e,`package.json`)),i;try{i=r.resolve(`${t}/package.json`)}catch{i=M(e,`node_modules`,t,`package.json`)}if(!P(i))throw Error(`${t} is not installed in this project. Run: pnpm add -D vite unplugin-swc @forinda/kickjs-vite`);let a=Wr(JSON.parse(F(i,`utf-8`)));if(!a)throw Error(`${t} has no importable entry point`);return import(B(M(k(i),a)).href)}async function Kr(e,t,n){let r=M(e,t.entry);if(!P(r))throw Error(`${t.entry} not found. The serverless entry exports \`handler = createHandler({ modules })\` — see the Serverless guide.`);let{build:i}=await Gr(e,`vite`),{default:a}=await Gr(e,`unplugin-swc`),{devtoolsFlagPlugin:o,devtoolsStripPlugin:s}=await Gr(e,`@forinda/kickjs-vite`);await i({configFile:!1,root:e,logLevel:`warn`,oxc:!1,plugins:[a.vite(),o(),s()],resolve:{alias:{"@":M(e,`src`)}},ssr:{noExternal:!0,target:`node`},build:{ssr:!0,target:`node20`,outDir:M(e,t.outDir),emptyOutDir:!0,minify:!1,rollupOptions:{input:r,external:(n,r)=>Jr(n,r?k(r):e)||t.external.includes(n)&&!P(M(e,`node_modules`,n)),output:{format:`esm`,entryFileNames:`server.mjs`,codeSplitting:!1}}}});let c=M(e,t.outDir,`server.mjs`);return n(`bundled ${j(process.cwd(),c)}`),c}function qr(e){return/^((?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*)(?:\/|$)/i.exec(e)?.[1]}function Jr(e,t,n=P){let r=qr(e);if(!r)return!1;for(let e=t;;e=k(e)){if(n(M(e,`node_modules`,r,`package.json`)))return!1;if(k(e)===e)return!0}}function Yr(e,t){let n=j(e,t).split(N)[0];return n!==void 0&&n.startsWith(`.`)}function Xr(e){return e.flatMap(e=>[`/${e} /404 404!`,`/${e}/* /404 404!`])}function Zr(e){try{return lt(e)}catch{return}}function Qr(e,t){let n=t.filter(t=>!P(M(e,t)));if(n.length>0)throw Error(`${n.join(`, `)} not found — the function reads ${n.length===1?`it`:`them`} at runtime. Run the full build first (\`pnpm build\`), or fix \`deploy.include\`.`)}function $r(e,t){let n=t.projectRoot,r=()=>Fr(t.config?.deploy,n);e.command(`build:netlify`).description(`Bundle the serverless entry and write the Netlify function`).action(async()=>{let e=r();Qr(n,e.include);let i=await Kr(n,e,t.log),a=M(n,e.siteRoot),o=Vr(n);o.length>0&&t.log(`warning: ${o.length} @Cron job(s) found — Netlify has no cron trigger for them, so they will not run. Use Netlify scheduled functions, or deploy to Vercel or Workers.`);let s=M(a,`.netlify/v1/functions`);st(s,{recursive:!0});let c=j(s,i).split(N).join(`/`),l=e=>e.split(N).join(`/`);L(M(s,`api.mjs`),Ir(c,e.apiPath,{projectDir:l(j(s,n)),preferStatic:e.apiPath===``&&!!e.staticDir,includedFiles:e.include.flatMap(e=>{let t=l(j(s,M(n,e)));return Zr(M(n,e))?.isDirectory()?[`${t}/**`]:[t]})})),t.log(`wrote ${j(process.cwd(),M(s,`api.mjs`))}`);let u=e.staticDir??e.publishDir;if(!e.staticDir)st(M(n,u),{recursive:!0}),t.log(`publish directory ready at ${j(process.cwd(),M(n,u))}`);else if(P(M(n,u))){let e=I(M(n,u)).filter(e=>e.startsWith(`.`));if(e.length>0){let t=M(n,u,`_redirects`),r=P(t)?F(t,`utf-8`):``,i=Xr(e).filter(e=>!r.includes(e));i.length>0&&L(t,`${r}${r&&!r.endsWith(`
739
+ `}function Gr(e){return/^\s*publish\s*=\s*["']([^"']+)["']/m.exec(e)?.[1]?.replace(/^\.\//,``).replace(/\/+$/,``)}function Kr(e,t,n=!1){let r=[{handle:`filesystem`},{src:`^${e}/(.*)$`,dest:`/api`}];return n&&e!==``&&r.push({src:`^/_kick/(.*)$`,dest:`/api`}),t&&e!==``&&r.push({src:`^/(.*)$`,dest:`/index.html`}),r}function qr(e,t){let n;try{n=bt(t,e).program}catch{return[]}let r=[],i=t=>e.slice(0,t).split(`
740
+ `).length,a=e=>{if(!e||typeof e!=`object`)return;if(Array.isArray(e))return e.forEach(a);let n=e,o=n.expression;if(n.type===`Decorator`&&o?.type===`CallExpression`&&o.callee?.type===`Identifier`&&o.callee.name===`Cron`){let[e,a]=o.arguments??[],s=e?.type===`Literal`&&typeof e.value==`string`?e.value:e?.type===`TemplateLiteral`&&e.expressions.length===0?e.quasis[0]?.value?.cooked:void 0;r.push({file:t,line:i(n.start??0),expression:s,timezone:a?.type===`ObjectExpression`&&a.properties.some(e=>(e.key?.name??e.key?.value)===`timezone`)})}for(let e in n)e!==`parent`&&a(n[e])};return a(n),r}function Jr(e){let t=M(e,`src`);return P(t)?I(t,{recursive:!0,encoding:`utf-8`}).filter(e=>/\.m?ts$/.test(e)&&!/\.(test|spec|d)\.m?ts$/.test(e)).flatMap(e=>{let n=F(M(t,e),`utf-8`);return n.includes(`@Cron`)?qr(n,`src/${e}`):[]}):[]}function Yr(e){let t=2166136261;for(let n of e.trim().replace(/\s+/g,` `))t^=n.codePointAt(0),t=Math.imul(t,16777619)>>>0;return t.toString(36)}function Xr(e){let t=[],n=/* @__PURE__ */ new Map;for(let r of e){let e=`${r.file}:${r.line}`;if(r.expression===void 0){t.push(`${e}: @Cron expression is not a string literal, so it has no Vercel cron entry`);continue}r.timezone&&t.push(`${e}: Vercel crons run in UTC — the timezone option is ignored there`);let i=r.expression.trim().replace(/\s+/g,` `);i.split(` `).length===5?n.set(Yr(i),i):t.push(`${e}: Vercel crons need a five-field expression, so it has no Vercel cron entry`)}return{crons:[...n].map(([e,t])=>({path:`/_kick/cron/${e}`,schedule:t})),warnings:t}}function Zr(e){let t=e=>{if(typeof e==`string`)return e;if(!e||typeof e!=`object`)return;let n=e;for(let e of[`import`,`module`,`node`,`default`]){let r=t(n[e]);if(r)return r}},n=e.exports;return t(typeof n==`string`||Array.isArray(n)?n:n?.[`.`]??n)??e.module??e.main}async function Qr(e,t){let{createRequire:n}=await import(`node:module`),r=n(M(e,`package.json`)),i;try{i=r.resolve(`${t}/package.json`)}catch{i=M(e,`node_modules`,t,`package.json`)}if(!P(i))throw Error(`${t} is not installed in this project. Run: pnpm add -D vite unplugin-swc @forinda/kickjs-vite`);let a=Zr(JSON.parse(F(i,`utf-8`)));if(!a)throw Error(`${t} has no importable entry point`);return import(B(M(k(i),a)).href)}async function $r(e,t,n){let r=M(e,t.entry);if(!P(r))throw Error(`${t.entry} not found. The serverless entry exports \`handler = createHandler({ modules })\` — see the Serverless guide.`);let{build:i}=await Qr(e,`vite`),{default:a}=await Qr(e,`unplugin-swc`),{devtoolsFlagPlugin:o,devtoolsStripPlugin:s}=await Qr(e,`@forinda/kickjs-vite`);await i({configFile:!1,root:e,logLevel:`warn`,oxc:!1,plugins:[a.vite(),o(),s()],resolve:{alias:{"@":M(e,`src`)}},ssr:{noExternal:!0,target:`node`},build:{ssr:!0,target:`node20`,outDir:M(e,t.outDir),emptyOutDir:!0,minify:!1,rollupOptions:{input:r,external:(n,r)=>ti(n,r?k(r):e)||t.external.includes(n)&&!P(M(e,`node_modules`,n)),output:{format:`esm`,entryFileNames:`server.mjs`,codeSplitting:!1}}}});let c=M(e,t.outDir,`server.mjs`);return n(`bundled ${j(process.cwd(),c)}`),c}function ei(e){return/^((?:@[a-z0-9][\w.-]*\/)?[a-z0-9][\w.-]*)(?:\/|$)/i.exec(e)?.[1]}function ti(e,t,n=P){let r=ei(e);if(!r)return!1;for(let e=t;;e=k(e)){if(n(M(e,`node_modules`,r,`package.json`)))return!1;if(k(e)===e)return!0}}function ni(e,t){let n=j(e,t).split(N)[0];return n!==void 0&&n.startsWith(`.`)}function ri(e){return e.flatMap(e=>[`/${e} /404 404!`,`/${e}/* /404 404!`])}function ii(e){try{return lt(e)}catch{return}}function ai(e,t){let n=t.filter(t=>!P(M(e,t)));if(n.length>0)throw Error(`${n.join(`, `)} not found — the function reads ${n.length===1?`it`:`them`} at runtime. Run the full build first (\`pnpm build\`), or fix \`deploy.include\`.`)}function oi(e,t){let n=t.projectRoot,r=()=>Hr(t.config?.deploy,n);e.command(`build:netlify`).description(`Bundle the serverless entry and write the Netlify function`).action(async()=>{let e=r();ai(n,e.include);let i=await $r(n,e,t.log),a=M(n,e.siteRoot),o=Jr(n);o.length>0&&t.log(`warning: ${o.length} @Cron job(s) found — Netlify has no cron trigger for them, so they will not run. Use Netlify scheduled functions, or deploy to Vercel or Workers.`);let s=M(a,`.netlify/v1/functions`);st(s,{recursive:!0});let c=j(s,i).split(N).join(`/`),l=e=>e.split(N).join(`/`);L(M(s,`api.mjs`),Ur(c,e.apiPath,{projectDir:l(j(s,n)),preferStatic:e.apiPath===``&&!!e.staticDir,includedFiles:e.include.flatMap(e=>{let t=l(j(s,M(n,e)));return ii(M(n,e))?.isDirectory()?[`${t}/**`]:[t]})})),t.log(`wrote ${j(process.cwd(),M(s,`api.mjs`))}`);let u=e.staticDir??e.publishDir;if(!e.staticDir)st(M(n,u),{recursive:!0}),t.log(`publish directory ready at ${j(process.cwd(),M(n,u))}`);else if(P(M(n,u))){let e=I(M(n,u)).filter(e=>e.startsWith(`.`));if(e.length>0){let t=M(n,u,`_redirects`),r=P(t)?F(t,`utf-8`):``,i=ri(e).filter(e=>!r.includes(e));i.length>0&&L(t,`${r}${r&&!r.endsWith(`
733
741
  `)?`
734
742
  `:``}${i.join(`
735
- `)}\n`)}}let d=M(a,`netlify.toml`);if(P(d)){let e=Rr(F(d,`utf-8`)),r=j(a,M(n,u)).split(N).join(`/`);e!==void 0&&e!==r&&t.log(`warning: netlify.toml publishes "${e}", but this build fills "${r}". Update netlify.toml, or set \`deploy.publishDir\` / \`deploy.staticDir\` to match.`)}}),e.command(`build:vercel`).description(`Bundle the serverless entry and write .vercel/output (Build Output API v3)`).action(async()=>{let e=r();Qr(n,e.include);let i=await Kr(n,e,t.log),a=M(n,e.siteRoot),o=e.staticDir?M(n,e.staticDir):void 0,s=M(a,`.vercel/output`),c=M(s,`functions/api.func`);ct(s,{recursive:!0,force:!0}),st(c,{recursive:!0}),ot(i,M(c,`server.mjs`)),L(M(c,`index.mjs`),Lr());for(let t of e.include)ot(M(n,t),M(c,t),{recursive:!0});if(L(M(c,`.vc-config.json`),`${JSON.stringify({runtime:e.vercelRuntime,handler:`index.mjs`,launcherType:`Nodejs`,supportsResponseStreaming:!0},null,2)}\n`),o){if(!P(o))throw Error(`build:vercel: ${e.staticDir} does not exist — build the frontend first`);ot(o,M(s,`static`),{recursive:!0,filter:e=>!Yr(o,e)})}let{crons:l,warnings:u}=Ur(Vr(n));for(let e of u)t.log(`warning: ${e}`);let d={version:3,routes:zr(e.apiPath,!!o,l.length>0),...l.length>0?{crons:l}:{}};L(M(s,`config.json`),`${JSON.stringify(d,null,2)}\n`),t.log(`wrote ${j(process.cwd(),s)}`),l.length>0&&t.log(`${l.length} cron schedule(s) written. Set CRON_SECRET in the Vercel project — the trigger is not mounted without it.`)})}const ei=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){let t=O.resolve(e.cwd,`kick.config.ts`);if(!P(t))return null;let n=await C(e.cwd);if(!n?.assetMap)return null;let r=ze(n.assetMap,e.cwd);return r.count===0?null:Ye(r)}}),ti="/* 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 ni(e,t,n,r={}){if(e.length===0)return`${ti}
743
+ `)}\n`)}}let d=M(a,`netlify.toml`);if(P(d)){let e=Gr(F(d,`utf-8`)),r=j(a,M(n,u)).split(N).join(`/`);e!==void 0&&e!==r&&t.log(`warning: netlify.toml publishes "${e}", but this build fills "${r}". Update netlify.toml, or set \`deploy.publishDir\` / \`deploy.staticDir\` to match.`)}}),e.command(`build:vercel`).description(`Bundle the serverless entry and write .vercel/output (Build Output API v3)`).action(async()=>{let e=r();ai(n,e.include);let i=await $r(n,e,t.log),a=M(n,e.siteRoot),o=e.staticDir?M(n,e.staticDir):void 0,s=M(a,`.vercel/output`),c=M(s,`functions/api.func`);ct(s,{recursive:!0,force:!0}),st(c,{recursive:!0}),ot(i,M(c,`server.mjs`)),L(M(c,`index.mjs`),Wr());for(let t of e.include)ot(M(n,t),M(c,t),{recursive:!0});if(L(M(c,`.vc-config.json`),`${JSON.stringify({runtime:e.vercelRuntime,handler:`index.mjs`,launcherType:`Nodejs`,supportsResponseStreaming:!0},null,2)}\n`),o){if(!P(o))throw Error(`build:vercel: ${e.staticDir} does not exist — build the frontend first`);ot(o,M(s,`static`),{recursive:!0,filter:e=>!ni(o,e)})}let{crons:l,warnings:u}=Xr(Jr(n));for(let e of u)t.log(`warning: ${e}`);let d={version:3,routes:Kr(e.apiPath,!!o,l.length>0),...l.length>0?{crons:l}:{}};L(M(s,`config.json`),`${JSON.stringify(d,null,2)}\n`),t.log(`wrote ${j(process.cwd(),s)}`),l.length>0&&t.log(`${l.length} cron schedule(s) written. Set CRON_SECRET in the Vercel project — the trigger is not mounted without it.`)})}const si=()=>({id:`kick/assets`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`],async generate(e){let t=O.resolve(e.cwd,`kick.config.ts`);if(!P(t))return null;let n=await C(e.cwd);if(!n?.assetMap)return null;let r=ze(n.assetMap,e.cwd);return r.count===0?null:Ye(r)}}),ci="/* 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 li(e,t,n,r={}){if(e.length===0)return`${ci}
736
744
  // (no routes discovered yet — annotate a controller method with
737
745
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
738
746
  declare global {
@@ -749,37 +757,38 @@ declare global {
749
757
 
750
758
  /** Empty until the first route exists — see kick typegen. */
751
759
  export const kickRpc = {} as const
752
- `;let i=/* @__PURE__ */ new Map;for(let t of e){let e=i.get(t.controller)??[];e.push(t),i.set(t.controller,e)}let a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Map,s=e=>{let t=`${e.filePath}::${e.controller}`,n=o.get(t);return n||(n=`_C${o.size}`,o.set(t,n)),n},c=(e,i,o)=>{let s=oi(e,i.filePath,t,n,a);if(!s){if(e&&n!==!1){let t=o===`params`?`URL-pattern params`:o===`query`&&i.queryFilterable!==null?`the @ApiQueryParams-derived query shape`:`'unknown'`;r.onWarn?.(`route ${i.controller}.${i.method} (${i.httpMethod} ${i.path}): ${o} schema '${e.identifier}' could not be statically resolved — falling back to ${t}. Export the schema from the controller file or import it with a static specifier.`)}return null}return n===`kickjs-schema`?`import('@forinda/kickjs-schema').InferSchemaOutput<typeof ${s}>`:`import('zod').infer<typeof ${s}>`},l=[];for(let[e,t]of i){let n=[` interface ${e} {`];for(let e of t){let t=e.pathParams.length>0?`{ ${e.pathParams.map(e=>`${e}: string`).join(`; `)} }`:`{}`,r=c(e.bodySchema,e,`body`),i=c(e.querySchema,e,`query`),a=c(e.paramsSchema,e,`params`)??t,o=r??`unknown`,l=i??ii(e),u=c(e.responseSchema??null,e,`response`),d=s(e),f=u??`import('@forinda/kickjs').InferHandlerResponse<${d}['${e.method}']>`,p=ai(e);n.push(` /**`,` * ${e.httpMethod} ${e.path}`,...p.map(e=>` * ${e}`),` */`,` ${e.method}: {`,` params: ${a}`,` body: ${o}`,` query: ${l}`,` response: ${f}`,` contextKeys: ${ri(e)}`,` }`)}n.push(` }`),l.push(n.join(`
753
- `))}let u=[],d=/* @__PURE__ */ new Set,f=/* @__PURE__ */ new Set;i.has(`Api`)&&r.onWarn?.(`controller class 'Api' collides with the reserved KickRoutes.Api client map — its interface declaration-merges into the flat route map. Rename the controller.`);for(let[e,t]of i)for(let n of t){let t=`${n.httpMethod} ${n.mountedPath??n.path}`;d.has(t)?r.onWarn?.(`duplicate route '${t}' (${e}.${n.method}) — two handlers claim the same verb+path at runtime. KickRoutes.Api keeps the first (scan order, which may not match runtime dispatch); resolve the conflict in the modules.`):(d.add(t),f.add(`${e}.${n.method}`),u.push(` '${t}': ${e}['${n.method}']`))}let p=[` interface Api {`,...u,` }`].join(`
754
- `);l.push(p);let m=[],h=/* @__PURE__ */ new Set;for(let[e,t]of i){let n=li(e);if(h.has(n)){r.onWarn?.(`RPC manifest: controller key '${n}' (from ${e}) collides with another controller — keeping the first; rename one class for distinct RPC namespaces.`);continue}h.add(n);let i=[];for(let n of t){if(!f.has(`${e}.${n.method}`))continue;let t=`${n.httpMethod} ${n.mountedPath??n.path}`;i.push(` ${n.method}: '${t}',`)}i.length>0&&m.push(` ${n}: {\n${i.join(`
755
- `)}\n },`)}let g=[`/**`,` * Runtime route manifest for the tRPC-style sugar:`," * `createRpc(api, kickRpc)` from @forinda/kickjs-client.",` */`,`export const kickRpc = {`,...m,`} as const`].join(`
756
- `),_=[],v=/* @__PURE__ */ new Map;for(let t of e)v.set(`${t.filePath}::${t.controller}`,t);for(let[e,n]of o){let r=v.get(e),i=ci(``,r.filePath,t),a=r.controllerIsDefaultExport?`default as ${n}`:`${r.controller} as ${n}`;_.push(`import type { ${a} } from '${i}'`)}let y=_.length>0?_.join(`
760
+ `;let i=/* @__PURE__ */ new Map;for(let t of e){let e=i.get(t.controller)??[];e.push(t),i.set(t.controller,e)}let a=/* @__PURE__ */ new Map,o=/* @__PURE__ */ new Map,s=e=>{let t=`${e.filePath}::${e.controller}`,n=o.get(t);return n||(n=`_C${o.size}`,o.set(t,n)),n},c=(e,i,o)=>{let s=pi(e,i.filePath,t,n,a);if(!s){if(e&&n!==!1){let t=o===`params`?`URL-pattern params`:o===`query`&&i.queryFilterable!==null?`the @ApiQueryParams-derived query shape`:`'unknown'`;r.onWarn?.(`route ${i.controller}.${i.method} (${i.httpMethod} ${i.path}): ${o} schema '${e.identifier}' could not be statically resolved — falling back to ${t}. Export the schema from the controller file or import it with a static specifier.`)}return null}return n===`kickjs-schema`?`import('@forinda/kickjs-schema').InferSchemaOutput<typeof ${s}>`:`import('zod').infer<typeof ${s}>`},l=[];for(let[e,t]of i){let n=[` interface ${e} {`];for(let e of t){let t=e.pathParams.length>0?`{ ${e.pathParams.map(e=>`${e}: string`).join(`; `)} }`:`{}`,r=c(e.bodySchema,e,`body`),i=c(e.querySchema,e,`query`),a=c(e.paramsSchema,e,`params`)??t,o=r??`unknown`,l=i??di(e),u=c(e.responseSchema??null,e,`response`),d=s(e),f=u??`import('@forinda/kickjs').InferHandlerResponse<${d}['${e.method}']>`,p=fi(e);n.push(` /**`,` * ${e.httpMethod} ${e.path}`,...p.map(e=>` * ${e}`),` */`,` ${e.method}: {`,` params: ${a}`,` body: ${o}`,` query: ${l}`,` response: ${f}`,` contextKeys: ${ui(e)}`,` }`)}n.push(` }`),l.push(n.join(`
761
+ `))}let u=[],d=/* @__PURE__ */ new Set,f=/* @__PURE__ */ new Set;i.has(`Named`)&&r.onWarn?.(`controller class 'Named' collides with the reserved KickRoutes.Named route-name map — its interface declaration-merges into it. Rename the controller.`),i.has(`Api`)&&r.onWarn?.(`controller class 'Api' collides with the reserved KickRoutes.Api client map — its interface declaration-merges into the flat route map. Rename the controller.`);for(let[e,t]of i)for(let n of t){let t=`${n.httpMethod} ${n.mountedPath??n.path}`;d.has(t)?r.onWarn?.(`duplicate route '${t}' (${e}.${n.method}) — two handlers claim the same verb+path at runtime. KickRoutes.Api keeps the first (scan order, which may not match runtime dispatch); resolve the conflict in the modules.`):(d.add(t),f.add(`${e}.${n.method}`),u.push(` '${t}': ${e}['${n.method}']`))}let p=[` interface Api {`,...u,` }`].join(`
762
+ `);l.push(p);let m=[];for(let[e,t]of i)for(let n of t)f.has(`${e}.${n.method}`)&&m.push(` '${e}.${n.method}': ${e}['${n.method}']`);l.push([` interface Named {`,...m,` }`].join(`
763
+ `));let h=[],g=/* @__PURE__ */ new Set;for(let[e,t]of i){let n=gi(e);if(g.has(n)){r.onWarn?.(`RPC manifest: controller key '${n}' (from ${e}) collides with another controller — keeping the first; rename one class for distinct RPC namespaces.`);continue}g.add(n);let i=[];for(let n of t){if(!f.has(`${e}.${n.method}`))continue;let t=`${n.httpMethod} ${n.mountedPath??n.path}`;i.push(` ${n.method}: '${t}',`)}i.length>0&&h.push(` ${n}: {\n${i.join(`
764
+ `)}\n },`)}let _=[`/**`,` * Runtime route manifest for the tRPC-style sugar:`," * `createRpc(api, kickRpc)` from @forinda/kickjs-client.",` */`,`export const kickRpc = {`,...h,`} as const`].join(`
765
+ `),v=[],y=/* @__PURE__ */ new Map;for(let t of e)y.set(`${t.filePath}::${t.controller}`,t);for(let[e,n]of o){let r=y.get(e),i=hi(``,r.filePath,t),a=r.controllerIsDefaultExport?`default as ${n}`:`${r.controller} as ${n}`;v.push(`import type { ${a} } from '${i}'`)}let b=v.length>0?v.join(`
757
766
  `)+`
758
- `:``,b=si(a)+y,ee=l.join(`
759
- `);return`${ti}${b}
767
+ `:``,ee=mi(a)+b,x=l.join(`
768
+ `);return`${ci}${ee}
760
769
  declare global {
761
770
  // eslint-disable-next-line @typescript-eslint/no-namespace
762
771
  namespace KickRoutes {
763
- ${ee}
772
+ ${x}
764
773
  }
765
774
 
766
775
  /** Short alias for \`KickRoutes.Api\` — \`createClient<KickApi>(...)\`. */
767
776
  type KickApi = KickRoutes.Api
768
777
  }
769
778
 
770
- ${g}
771
- `}function ri(e){let t=e.contextKeys;return t==null?`string`:t.length===0?`never`:t.map(e=>JSON.stringify(e)).join(` | `)}function ii(e){if(e.queryFilterable===null)return`unknown`;let t=e.querySortable??[];return`{ filter?: string | string[]; sort?: ${t.length>0?t.flatMap(e=>[`'${e}'`,`'-${e}'`]).join(` | `):`string`}; q?: string; page?: string; limit?: string }`}function ai(e){let t=[];return e.queryFilterable&&e.queryFilterable.length>0&&t.push(`Filterable: ${e.queryFilterable.join(`, `)}`),e.querySortable&&e.querySortable.length>0&&t.push(`Sortable: ${e.querySortable.join(`, `)}`),e.querySearchable&&e.querySearchable.length>0&&t.push(`Searchable: ${e.querySearchable.join(`, `)}`),t}function oi(e,t,n,r,i){if(!e||r===!1||e.source===null)return null;let a=ci(e.source,t,n);if(a===`unknown`)return null;let o=`${a}::${e.identifier}`,s=i.get(o)?.specifier;return s?s=i.get(o).specifier:(s=`_S${i.size}`,i.set(o,{identifier:e.identifier,specifier:s})),s}function si(e){if(e.size===0)return``;let t=[];for(let[n,r]of e){let[e]=n.split(`::`);t.push(`import type { ${r.identifier} as ${r.specifier} } from '${e}'`)}return t.join(`
779
+ ${_}
780
+ `}function ui(e){let t=e.contextKeys;return t==null?`string`:t.length===0?`never`:t.map(e=>JSON.stringify(e)).join(` | `)}function di(e){if(e.queryFilterable===null)return`unknown`;let t=e.querySortable??[];return`{ filter?: string | string[]; sort?: ${t.length>0?t.flatMap(e=>[`'${e}'`,`'-${e}'`]).join(` | `):`string`}; q?: string; page?: string; limit?: string }`}function fi(e){let t=[];return e.queryFilterable&&e.queryFilterable.length>0&&t.push(`Filterable: ${e.queryFilterable.join(`, `)}`),e.querySortable&&e.querySortable.length>0&&t.push(`Sortable: ${e.querySortable.join(`, `)}`),e.querySearchable&&e.querySearchable.length>0&&t.push(`Searchable: ${e.querySearchable.join(`, `)}`),t}function pi(e,t,n,r,i){if(!e||r===!1||e.source===null)return null;let a=hi(e.source,t,n);if(a===`unknown`)return null;let o=`${a}::${e.identifier}`,s=i.get(o)?.specifier;return s?s=i.get(o).specifier:(s=`_S${i.size}`,i.set(o,{identifier:e.identifier,specifier:s})),s}function mi(e){if(e.size===0)return``;let t=[];for(let[n,r]of e){let[e]=n.split(`::`);t.push(`import type { ${r.identifier} as ${r.specifier} } from '${e}'`)}return t.join(`
772
781
  `)+`
773
- `}function ci(e,t,n){if(e===null)return`unknown`;let r=k(n);if(e===``){let e=j(r,t).split(N).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=k(t),a=M(i,e),o=j(r,a).split(N).join(`/`);return o=o.replace(/\.(ts|tsx|mts|cts)$/i,``),o.startsWith(`.`)||(o=`./`+o),o}function li(e){let t=e.endsWith(`Controller`)?e.slice(0,-10):e,n=t.length>0?t:e;return n.charAt(0).toLowerCase()+n.slice(1)}const ui=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:di(e),cwd:e.cwd,envFile:fi(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=O.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return ni(t.routes,r,n,{onWarn:t=>e.log.warn(t)})}});function di(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function fi(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}const pi=`@typescript/typescript6`;function mi(e){return typeof e?.createProgram==`function`}function hi(e){if(mi(e.typescript))return{api:e.typescript,source:`typescript`};if(mi(e.ts6))return{api:e.ts6,source:pi};let t=`Install it in the project:\n pnpm add -D ${pi}`;throw e.typescript?Error(`kick typegen: the client route map needs a TypeScript compiler API.
774
- TypeScript 7 does not ship a compiler API, so the compatibility package is required.\n ${t}`):Error(`kick typegen: the client route map needs a TypeScript compiler API, and neither 'typescript' nor '${pi}' resolved from this project.\n ${t}`)}async function gi(e){let t=it(A(e,`package.json`)),n=async e=>{try{return await import(B(t.resolve(e)).href)}catch{return null}},[r,i]=await Promise.all([n(`typescript`),n(pi)]);return hi({typescript:_i(r),ts6:_i(i)}).api}function _i(e){let t=e;return t?.default&&typeof t.default==`object`?t.default:e}const vi=Symbol(`kick/client: expansion budget exhausted`);var yi=class{ts;checker;program;opts;get printFlags(){return this.ts.TypeFormatFlags.NoTruncation}hoistedByType=/* @__PURE__ */ new Map;inProgress=/* @__PURE__ */ new Map;jsonInProgress=/* @__PURE__ */ new Set;nextName=0;blocks=[];maxDepth;truncations=0;budget;constructor(e,t,n,r={}){this.ts=e,this.checker=t,this.program=n,this.opts=r,this.maxDepth=r.maxDepth??12,this.budget=r.truncationBudget??1e3}hoisted(){return this.blocks}expand(e){this.truncations=0;let t=this.blocks.length,n=this.nextName,r=new Set(this.hoistedByType.keys());try{return this.render(e,0)}catch(e){if(e!==vi)throw e;this.blocks.length=t,this.nextName=n;for(let e of this.hoistedByType.keys())r.has(e)||this.hoistedByType.delete(e);return this.opts.onWarn?.(`expansion abandoned after ${this.budget} depth hoists — emitting 'unknown'. Either the response type never repeats (a generic that grows at every level) or it nests more distinct types than the budget allows; raising maxDepth hoists fewer of them. Declare a response schema on the route for an exact type.`),`unknown`}}render(e,t,n=!0){let r=this.ts.TypeFlags;if(n){let t=this.hoistedByType.get(e);if(t)return t}if(t>this.maxDepth&&!this.isLeaf(e))return this.hoistDeep(e);if(e.flags&(r.String|r.Number|r.Boolean|r.BigInt|r.ESSymbol)||e.flags&(r.Any|r.Unknown|r.Never|r.Void|r.Undefined|r.Null)||e.isLiteral()||e.flags&r.BooleanLiteral)return this.checker.typeToString(e,void 0,this.printFlags);if(e.isUnion()){let n=e.types.filter(e=>!this.isCallable(e));return(n.length>0?n:e.types).map(e=>this.render(e,t+1)).join(` | `)}if(e.isIntersection())return e.types.map(e=>this.render(e,t+1)).join(` & `);if(this.isTuple(e))return this.renderTuple(e,t);let i=this.arrayElement(e);if(i){let e=this.render(i.element,t+1),n=/[|&]/.test(e)?`(${e})[]`:`${e}[]`;return i.readonly?`readonly ${n}`:n}let a=this.toJsonType(e);if(a){if(this.jsonInProgress.has(e))return this.opts.onWarn?.(`'${this.checker.typeToString(e,void 0,this.printFlags)}' has a cyclic toJSON() — emitting 'unknown', since it has no serializable form.`),`unknown`;this.jsonInProgress.add(e);try{return this.render(a,t)}finally{this.jsonInProgress.delete(e)}}return this.isLibType(e)?this.renderLibType(e,t):e.flags&r.Object?this.renderObject(e,t):(this.opts.onWarn?.(`could not expand type '${this.checker.typeToString(e)}' — emitting 'unknown'`),`unknown`)}isLeaf(e){let t=this.ts.TypeFlags;return(e.flags&(t.String|t.Number|t.Boolean|t.BigInt|t.ESSymbol|t.Any|t.Unknown|t.Never|t.Void|t.Undefined|t.Null|t.BooleanLiteral))!==0||e.isLiteral()}hoistDeep(e){if(++this.truncations>this.budget)throw vi;let t=this.allocName();this.hoistedByType.set(e,t);let n=this.blocks.length;return this.blocks.push(``),this.blocks[n]=this.isPlainObject(e)?`interface ${t} {\n${this.members(e,0,` `)}\n}`:`type ${t} = ${this.render(e,0,!1)}`,t}isPlainObject(e){return(e.flags&this.ts.TypeFlags.Object)!==0&&!e.isUnionOrIntersection()&&!this.isTuple(e)&&!this.arrayElement(e)&&!this.toJsonType(e)&&!this.isLibType(e)}renderObject(e,t){let n=this.hoistedByType.get(e);if(n)return n;if(this.isNamed(e)){let t=this.allocName();this.hoistedByType.set(e,t);let n=this.blocks.length;return this.blocks.push(``),this.blocks[n]=`interface ${t} {\n${this.members(e,0,` `)}\n}`,t}let r=this.inProgress.get(e);if(r)return r.name??=this.allocName();let i={name:null};this.inProgress.set(e,i);let a;try{a=this.members(e,t,``,`; `)}finally{this.inProgress.delete(e)}if(i.name){this.hoistedByType.set(e,i.name);let t=this.blocks.length;return this.blocks.push(``),this.blocks[t]=`interface ${i.name} {\n${this.members(e,0,` `)}\n}`,i.name}return a.length>0?`{ ${a} }`:`{}`}allocName(){return`__T${this.nextName++}`}members(e,t,n,r=`
782
+ `}function hi(e,t,n){if(e===null)return`unknown`;let r=k(n);if(e===``){let e=j(r,t).split(N).join(`/`);return e=e.replace(/\.(ts|tsx|mts|cts)$/i,``),e.startsWith(`.`)||(e=`./`+e),e}if(!e.startsWith(`.`)&&!e.startsWith(`/`))return e;let i=k(t),a=M(i,e),o=j(r,a).split(N).join(`/`);return o=o.replace(/\.(ts|tsx|mts|cts)$/i,``),o.startsWith(`.`)||(o=`./`+o),o}function gi(e){let t=e.endsWith(`Controller`)?e.slice(0,-10):e,n=t.length>0?t:e;return n.charAt(0).toLowerCase()+n.slice(1)}const _i=()=>({id:`kick/routes`,outExtension:`.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){let t=await e.getScanResult({root:vi(e),cwd:e.cwd,envFile:yi(e)}),n=e.config?.typegen?.schemaValidator??`zod`,r=O.resolve(e.cwd,`.kickjs/types/kick__routes.ts`);return li(t.routes,r,n,{onWarn:t=>e.log.warn(t)})}});function vi(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function yi(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}const bi=`@typescript/typescript6`;function xi(e){return typeof e?.createProgram==`function`}function Si(e){if(xi(e.typescript))return{api:e.typescript,source:`typescript`};if(xi(e.ts6))return{api:e.ts6,source:bi};let t=`Install it in the project:\n pnpm add -D ${bi}`;throw e.typescript?Error(`kick typegen: the client route map needs a TypeScript compiler API.
783
+ TypeScript 7 does not ship a compiler API, so the compatibility package is required.\n ${t}`):Error(`kick typegen: the client route map needs a TypeScript compiler API, and neither 'typescript' nor '${bi}' resolved from this project.\n ${t}`)}async function Ci(e){let t=it(A(e,`package.json`)),n=async e=>{try{return await import(B(t.resolve(e)).href)}catch{return null}},[r,i]=await Promise.all([n(`typescript`),n(bi)]);return Si({typescript:wi(r),ts6:wi(i)}).api}function wi(e){let t=e;return t?.default&&typeof t.default==`object`?t.default:e}const Ti=Symbol(`kick/client: expansion budget exhausted`);var Ei=class{ts;checker;program;opts;get printFlags(){return this.ts.TypeFormatFlags.NoTruncation}hoistedByType=/* @__PURE__ */ new Map;inProgress=/* @__PURE__ */ new Map;jsonInProgress=/* @__PURE__ */ new Set;nextName=0;blocks=[];maxDepth;truncations=0;budget;constructor(e,t,n,r={}){this.ts=e,this.checker=t,this.program=n,this.opts=r,this.maxDepth=r.maxDepth??12,this.budget=r.truncationBudget??1e3}hoisted(){return this.blocks}expand(e){this.truncations=0;let t=this.blocks.length,n=this.nextName,r=new Set(this.hoistedByType.keys());try{return this.render(e,0)}catch(e){if(e!==Ti)throw e;this.blocks.length=t,this.nextName=n;for(let e of this.hoistedByType.keys())r.has(e)||this.hoistedByType.delete(e);return this.opts.onWarn?.(`expansion abandoned after ${this.budget} depth hoists — emitting 'unknown'. Either the response type never repeats (a generic that grows at every level) or it nests more distinct types than the budget allows; raising maxDepth hoists fewer of them. Declare a response schema on the route for an exact type.`),`unknown`}}render(e,t,n=!0){let r=this.ts.TypeFlags;if(n){let t=this.hoistedByType.get(e);if(t)return t}if(t>this.maxDepth&&!this.isLeaf(e))return this.hoistDeep(e);if(e.flags&(r.String|r.Number|r.Boolean|r.BigInt|r.ESSymbol)||e.flags&(r.Any|r.Unknown|r.Never|r.Void|r.Undefined|r.Null)||e.isLiteral()||e.flags&r.BooleanLiteral)return this.checker.typeToString(e,void 0,this.printFlags);if(e.isUnion()){let n=e.types.filter(e=>!this.isCallable(e));return(n.length>0?n:e.types).map(e=>this.render(e,t+1)).join(` | `)}if(e.isIntersection())return e.types.map(e=>this.render(e,t+1)).join(` & `);if(this.isTuple(e))return this.renderTuple(e,t);let i=this.arrayElement(e);if(i){let e=this.render(i.element,t+1),n=/[|&]/.test(e)?`(${e})[]`:`${e}[]`;return i.readonly?`readonly ${n}`:n}let a=this.toJsonType(e);if(a){if(this.jsonInProgress.has(e))return this.opts.onWarn?.(`'${this.checker.typeToString(e,void 0,this.printFlags)}' has a cyclic toJSON() — emitting 'unknown', since it has no serializable form.`),`unknown`;this.jsonInProgress.add(e);try{return this.render(a,t)}finally{this.jsonInProgress.delete(e)}}return this.isLibType(e)?this.renderLibType(e,t):e.flags&r.Object?this.renderObject(e,t):(this.opts.onWarn?.(`could not expand type '${this.checker.typeToString(e)}' — emitting 'unknown'`),`unknown`)}isLeaf(e){let t=this.ts.TypeFlags;return(e.flags&(t.String|t.Number|t.Boolean|t.BigInt|t.ESSymbol|t.Any|t.Unknown|t.Never|t.Void|t.Undefined|t.Null|t.BooleanLiteral))!==0||e.isLiteral()}hoistDeep(e){if(++this.truncations>this.budget)throw Ti;let t=this.allocName();this.hoistedByType.set(e,t);let n=this.blocks.length;return this.blocks.push(``),this.blocks[n]=this.isPlainObject(e)?`interface ${t} {\n${this.members(e,0,` `)}\n}`:`type ${t} = ${this.render(e,0,!1)}`,t}isPlainObject(e){return(e.flags&this.ts.TypeFlags.Object)!==0&&!e.isUnionOrIntersection()&&!this.isTuple(e)&&!this.arrayElement(e)&&!this.toJsonType(e)&&!this.isLibType(e)}renderObject(e,t){let n=this.hoistedByType.get(e);if(n)return n;if(this.isNamed(e)){let t=this.allocName();this.hoistedByType.set(e,t);let n=this.blocks.length;return this.blocks.push(``),this.blocks[n]=`interface ${t} {\n${this.members(e,0,` `)}\n}`,t}let r=this.inProgress.get(e);if(r)return r.name??=this.allocName();let i={name:null};this.inProgress.set(e,i);let a;try{a=this.members(e,t,``,`; `)}finally{this.inProgress.delete(e)}if(i.name){this.hoistedByType.set(e,i.name);let t=this.blocks.length;return this.blocks.push(``),this.blocks[t]=`interface ${i.name} {\n${this.members(e,0,` `)}\n}`,i.name}return a.length>0?`{ ${a} }`:`{}`}allocName(){return`__T${this.nextName++}`}members(e,t,n,r=`
775
784
  `){let i=[];for(let r of this.checker.getIndexInfosOfType(e)){let e=this.checker.typeToString(r.keyType,void 0,this.printFlags);i.push(`${n}[key: ${e}]: ${this.render(r.type,t+1)}`)}for(let r of this.checker.getPropertiesOfType(e)){let e=this.typeOfProperty(r);if(this.isCallable(e)||r.getName().startsWith(`__@`))continue;let a=(r.flags&this.ts.SymbolFlags.Optional)!==0,o=this.renderPropertyType(e,a,r,t+1),s=this.isReadonlyProp(r)?`readonly `:``;i.push(`${n}${s}${this.propName(r.getName())}${a?`?`:``}: ${o}`)}return i.join(r===`
776
785
  `?`
777
- `:r)}typeOfProperty(e){let t=this.checker;if(typeof t.getTypeOfSymbol==`function`)return t.getTypeOfSymbol(e);let n=e.valueDeclaration??e.declarations?.[0];return n?this.checker.getTypeOfSymbolAtLocation(e,n):this.checker.getDeclaredTypeOfSymbol(e)}renderPropertyType(e,t,n,r){if(!t||!e.isUnion()||this.declaresUndefined(n))return this.render(e,r);let i=e.types.filter(e=>!(e.flags&this.ts.TypeFlags.Undefined));return i.length===0?`undefined`:i.map(e=>this.render(e,r)).join(` | `)}isReadonlyProp(e){let t=e.valueDeclaration??e.declarations?.[0];return t?(this.ts.getCombinedModifierFlags(t)&this.ts.ModifierFlags.Readonly)!==0:!1}declaresUndefined(e){let t=e.valueDeclaration??e.declarations?.[0];if(!t||!(this.ts.isPropertySignature(t)||this.ts.isPropertyDeclaration(t))||!t.type)return!1;let n=this.checker.getTypeFromTypeNode(t.type);return(n.isUnion()?n.types:[n]).some(e=>(e.flags&this.ts.TypeFlags.Undefined)!==0)}renderTuple(e,t){let n=this.ts.ElementFlags,r=this.checker.getTypeArguments(e),i=e.target,a=i.elementFlags??[],o=r.map((e,r)=>{let i=a[r]??n.Required;return i&n.Optional?`${(e.isUnion()?e.types.filter(e=>!(e.flags&this.ts.TypeFlags.Undefined)):[e]).map(e=>this.render(e,t+1)).join(` | `)}?`:i&n.Rest?`...${this.render(e,t+1)}[]`:i&n.Variadic?`...${this.render(e,t+1)}`:this.render(e,t+1)});return`${i.readonly?`readonly `:``}[${o.join(`, `)}]`}propName(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}isLibType(e){let t=e.aliasSymbol?.declarations??e.getSymbol()?.declarations;return!t||t.length===0?!1:t.every(e=>this.program.isSourceFileDefaultLibrary(e.getSourceFile()))}renderLibType(e,t){let n=(e.aliasSymbol??e.getSymbol())?.getName(),r=e.aliasTypeArguments??this.typeArguments(e);return!n||r.length===0?this.checker.typeToString(e,void 0,this.printFlags):`${n}<${r.map(e=>this.render(e,t+1)).join(`, `)}>`}typeArguments(e){return!(e.flags&this.ts.TypeFlags.Object)||!(e.objectFlags&this.ts.ObjectFlags.Reference)?[]:this.checker.getTypeArguments(e)}toJsonType(e){if(!(e.flags&this.ts.TypeFlags.Object))return null;let t=this.checker.getPropertyOfType(e,`toJSON`);if(!t)return null;let[n]=this.checker.getSignaturesOfType(this.typeOfProperty(t),this.ts.SignatureKind.Call);if(!n)return null;let r=this.checker.getReturnTypeOfSignature(n);return r===e?null:r}isCallable(e){if(e.isUnion()){let t=e.types.filter(e=>!(e.flags&(this.ts.TypeFlags.Undefined|this.ts.TypeFlags.Null)));return t.length>0&&t.every(e=>this.isCallable(e))}return this.checker.getSignaturesOfType(e,this.ts.SignatureKind.Call).length>0||this.checker.getSignaturesOfType(e,this.ts.SignatureKind.Construct).length>0}isNamed(e){let t=e.getSymbol();if(!t)return!1;let n=t.getName();return n!==`__type`&&n!==`__object`&&n.length>0}isTuple(e){let t=this.ts.ObjectFlags;if(!(e.flags&this.ts.TypeFlags.Object)||!(e.objectFlags&t.Reference))return!1;let n=e.target;return!!(n&&n.objectFlags&t.Tuple)}arrayElement(e){let t=e.getSymbol()?.getName();if(t!==`Array`&&t!==`ReadonlyArray`)return null;let n=this.checker.getTypeArguments(e);return n.length===1?{element:n[0],readonly:t===`ReadonlyArray`}:null}};const bi=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`,`bun.lockb`],xi=/(?:^|[\\/])(?:node_modules|\.kickjs)(?:[\\/]|$)/;function Si(e){return vt(`sha1`).update(e).digest(`hex`)}function Ci(e){let t=vt(`sha1`);t.update(e.cliVersion),t.update(JSON.stringify(e.options??{})),t.update(e.keys.join(`
778
- `));for(let n of bi){let r=A(e.projectDir,n);if(P(r))try{t.update(F(r))}catch(e){throw Error(`kick/client: cannot read lockfile ${r}`,{cause:e})}}for(let n of e.fileNames.toSorted())if(!xi.test(n)){t.update(n);try{t.update(F(n))}catch(e){throw Error(`kick/client: cannot read project file ${n}`,{cause:e})}}return t.digest(`hex`)}async function wi(e){try{let t=await gi(e.compilerFrom??e.projectDir),n={...t.sys,onUnRecoverableConfigFileDiagnostic:()=>{}},r=t.getParsedCommandLineOfConfigFile(A(e.projectDir,`tsconfig.json`),{},n);return r?Ci({projectDir:e.projectDir,fileNames:r.fileNames,keys:e.keys,options:{...r.options,__kickMaxDepth:e.maxDepth??null},cliVersion:e.cliVersion}):null}catch{return null}}async function Ti(e){let t=await gi(e.compilerFrom??e.projectDir),n=A(k(e.routesFile),`__kick_client_probe__.ts`),r=Oi(e.routesFile,e.keys),i=ji(t,e.projectDir,n,r),a=i.getTypeChecker(),o=i.getSourceFile(n);if(!o)throw Error(`kick/client: could not add the resolution probe to the program. Check that ${e.routesFile} exists — run \`kick typegen\` first.`);Ei(t,i,e.routesFile);let s=ki(t,i,o,e.keys),c=null,l=new yi(t,a,i,{maxDepth:e.maxDepth,onWarn:t=>e.onWarn?.(c?`route '${c}': ${t}`:t)}),u=/* @__PURE__ */ new Map;for(let[n,r]of e.keys.entries()){if(s.has(r)){e.onWarn?.(`route '${r}' is not present in KickRoutes.Api — skipped. Re-run \`kick typegen\` so the two maps agree.`);continue}let i=o.statements.find(e=>t.isTypeAliasDeclaration(e)&&e.name.text===Di(n));if(!i){e.onWarn?.(`route '${r}' could not be resolved — skipped.`);continue}let d=a.getTypeAtLocation(i.type);d.flags&t.TypeFlags.Any?e.onWarn?.(`route '${r}' resolved to 'any' — skipped rather than emitted, since an 'any' entry silently accepts every call. Check that the server type-checks.`):(c=r,u.set(r,l.expand(d)),c=null)}return{entries:u,hoisted:l.hoisted()}}function Ei(e,t,n){let r=t.getSourceFile(n);if(!r)throw Error(`kick/client: ${n} is not in the TypeScript program. Run \`kick typegen\` first, and check that tsconfig.json includes .kickjs.`);let i=t.getSemanticDiagnostics(r);if(i.length===0)return;let a=i.slice(0,3).map(t=>` ${e.flattenDiagnosticMessageText(t.messageText,` `)}`).join(`
779
- `);throw Error(`${n} has ${i.length} type error(s), so its route types cannot be resolved — every entry would come out as 'any'.\n${a}\n Usually this means dependencies are not installed or the server does not type-check.`)}function Di(e){return`_K${e}`}function Oi(e,t){let n=`./`+at(e).replace(/\.tsx?$/,``),r=t.map((e,t)=>`type ${Di(t)} = KickRoutes.Api[${JSON.stringify(e)}]`);return[`import ${JSON.stringify(n)}`,...r].join(`
786
+ `:r)}typeOfProperty(e){let t=this.checker;if(typeof t.getTypeOfSymbol==`function`)return t.getTypeOfSymbol(e);let n=e.valueDeclaration??e.declarations?.[0];return n?this.checker.getTypeOfSymbolAtLocation(e,n):this.checker.getDeclaredTypeOfSymbol(e)}renderPropertyType(e,t,n,r){if(!t||!e.isUnion()||this.declaresUndefined(n))return this.render(e,r);let i=e.types.filter(e=>!(e.flags&this.ts.TypeFlags.Undefined));return i.length===0?`undefined`:i.map(e=>this.render(e,r)).join(` | `)}isReadonlyProp(e){let t=e.valueDeclaration??e.declarations?.[0];return t?(this.ts.getCombinedModifierFlags(t)&this.ts.ModifierFlags.Readonly)!==0:!1}declaresUndefined(e){let t=e.valueDeclaration??e.declarations?.[0];if(!t||!(this.ts.isPropertySignature(t)||this.ts.isPropertyDeclaration(t))||!t.type)return!1;let n=this.checker.getTypeFromTypeNode(t.type);return(n.isUnion()?n.types:[n]).some(e=>(e.flags&this.ts.TypeFlags.Undefined)!==0)}renderTuple(e,t){let n=this.ts.ElementFlags,r=this.checker.getTypeArguments(e),i=e.target,a=i.elementFlags??[],o=r.map((e,r)=>{let i=a[r]??n.Required;return i&n.Optional?`${(e.isUnion()?e.types.filter(e=>!(e.flags&this.ts.TypeFlags.Undefined)):[e]).map(e=>this.render(e,t+1)).join(` | `)}?`:i&n.Rest?`...${this.render(e,t+1)}[]`:i&n.Variadic?`...${this.render(e,t+1)}`:this.render(e,t+1)});return`${i.readonly?`readonly `:``}[${o.join(`, `)}]`}propName(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)?e:JSON.stringify(e)}isLibType(e){let t=e.aliasSymbol?.declarations??e.getSymbol()?.declarations;return!t||t.length===0?!1:t.every(e=>this.program.isSourceFileDefaultLibrary(e.getSourceFile()))}renderLibType(e,t){let n=(e.aliasSymbol??e.getSymbol())?.getName(),r=e.aliasTypeArguments??this.typeArguments(e);return!n||r.length===0?this.checker.typeToString(e,void 0,this.printFlags):`${n}<${r.map(e=>this.render(e,t+1)).join(`, `)}>`}typeArguments(e){return!(e.flags&this.ts.TypeFlags.Object)||!(e.objectFlags&this.ts.ObjectFlags.Reference)?[]:this.checker.getTypeArguments(e)}toJsonType(e){if(!(e.flags&this.ts.TypeFlags.Object))return null;let t=this.checker.getPropertyOfType(e,`toJSON`);if(!t)return null;let[n]=this.checker.getSignaturesOfType(this.typeOfProperty(t),this.ts.SignatureKind.Call);if(!n)return null;let r=this.checker.getReturnTypeOfSignature(n);return r===e?null:r}isCallable(e){if(e.isUnion()){let t=e.types.filter(e=>!(e.flags&(this.ts.TypeFlags.Undefined|this.ts.TypeFlags.Null)));return t.length>0&&t.every(e=>this.isCallable(e))}return this.checker.getSignaturesOfType(e,this.ts.SignatureKind.Call).length>0||this.checker.getSignaturesOfType(e,this.ts.SignatureKind.Construct).length>0}isNamed(e){let t=e.getSymbol();if(!t)return!1;let n=t.getName();return n!==`__type`&&n!==`__object`&&n.length>0}isTuple(e){let t=this.ts.ObjectFlags;if(!(e.flags&this.ts.TypeFlags.Object)||!(e.objectFlags&t.Reference))return!1;let n=e.target;return!!(n&&n.objectFlags&t.Tuple)}arrayElement(e){let t=e.getSymbol()?.getName();if(t!==`Array`&&t!==`ReadonlyArray`)return null;let n=this.checker.getTypeArguments(e);return n.length===1?{element:n[0],readonly:t===`ReadonlyArray`}:null}};const Di=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`,`bun.lockb`],Oi=/(?:^|[\\/])(?:node_modules|\.kickjs)(?:[\\/]|$)/;function ki(e){return vt(`sha1`).update(e).digest(`hex`)}function Ai(e){let t=vt(`sha1`);t.update(e.cliVersion),t.update(JSON.stringify(e.options??{})),t.update(e.keys.join(`
787
+ `));for(let n of Di){let r=A(e.projectDir,n);if(P(r))try{t.update(F(r))}catch(e){throw Error(`kick/client: cannot read lockfile ${r}`,{cause:e})}}for(let n of e.fileNames.toSorted())if(!Oi.test(n)){t.update(n);try{t.update(F(n))}catch(e){throw Error(`kick/client: cannot read project file ${n}`,{cause:e})}}return t.digest(`hex`)}async function ji(e){try{let t=await Ci(e.compilerFrom??e.projectDir),n={...t.sys,onUnRecoverableConfigFileDiagnostic:()=>{}},r=t.getParsedCommandLineOfConfigFile(A(e.projectDir,`tsconfig.json`),{},n);return r?Ai({projectDir:e.projectDir,fileNames:r.fileNames,keys:e.keys,options:{...r.options,__kickMaxDepth:e.maxDepth??null},cliVersion:e.cliVersion}):null}catch{return null}}async function Mi(e){let t=await Ci(e.compilerFrom??e.projectDir),n=A(k(e.routesFile),`__kick_client_probe__.ts`),r=Fi(e.routesFile,e.keys),i=Ri(t,e.projectDir,n,r),a=i.getTypeChecker(),o=i.getSourceFile(n);if(!o)throw Error(`kick/client: could not add the resolution probe to the program. Check that ${e.routesFile} exists — run \`kick typegen\` first.`);Ni(t,i,e.routesFile);let s=Ii(t,i,o,e.keys),c=null,l=new Ei(t,a,i,{maxDepth:e.maxDepth,onWarn:t=>e.onWarn?.(c?`route '${c}': ${t}`:t)}),u=/* @__PURE__ */ new Map;for(let[n,r]of e.keys.entries()){if(s.has(r)){e.onWarn?.(`route '${r}' is not present in KickRoutes.Api — skipped. Re-run \`kick typegen\` so the two maps agree.`);continue}let i=o.statements.find(e=>t.isTypeAliasDeclaration(e)&&e.name.text===Pi(n));if(!i){e.onWarn?.(`route '${r}' could not be resolved — skipped.`);continue}let d=a.getTypeAtLocation(i.type);d.flags&t.TypeFlags.Any?e.onWarn?.(`route '${r}' resolved to 'any' — skipped rather than emitted, since an 'any' entry silently accepts every call. Check that the server type-checks.`):(c=r,u.set(r,l.expand(d)),c=null)}return{entries:u,hoisted:l.hoisted()}}function Ni(e,t,n){let r=t.getSourceFile(n);if(!r)throw Error(`kick/client: ${n} is not in the TypeScript program. Run \`kick typegen\` first, and check that tsconfig.json includes .kickjs.`);let i=t.getSemanticDiagnostics(r);if(i.length===0)return;let a=i.slice(0,3).map(t=>` ${e.flattenDiagnosticMessageText(t.messageText,` `)}`).join(`
788
+ `);throw Error(`${n} has ${i.length} type error(s), so its route types cannot be resolved — every entry would come out as 'any'.\n${a}\n Usually this means dependencies are not installed or the server does not type-check.`)}function Pi(e){return`_K${e}`}function Fi(e,t){let n=`./`+at(e).replace(/\.tsx?$/,``),r=t.map((e,t)=>`type ${Pi(t)} = KickRoutes.Api[${JSON.stringify(e)}]`);return[`import ${JSON.stringify(n)}`,...r].join(`
780
789
  `)+`
781
- `}function ki(e,t,n,r){let i=/* @__PURE__ */ new Set,a=/* @__PURE__ */ new Map;for(let t of n.statements)e.isTypeAliasDeclaration(t)&&a.set(t.name.text,t);for(let e of t.getSemanticDiagnostics(n))if(e.start!==void 0)for(let[t,o]of r.entries()){let r=a.get(Di(t));r&&e.start>=r.getStart(n)&&e.start<r.getEnd()&&i.add(o)}return i}function Ai(e,t){let n=e.filter(e=>/\.d\.(ts|mts|cts)$/.test(e)),r=[];try{r=I(t).filter(e=>e.endsWith(`.ts`)).map(e=>A(t,e))}catch{}return[.../* @__PURE__ */ new Set([...n,...r])]}function ji(e,t,n,r){let i=A(t,`tsconfig.json`),a={...e.sys,onUnRecoverableConfigFileDiagnostic:t=>{throw Error(e.flattenDiagnosticMessageText(t.messageText,`
782
- `))}},o=e.getParsedCommandLineOfConfigFile(i,{},a);if(!o)throw Error(`kick/client: could not read ${i}`);let s=e.createCompilerHost(o.options,!0),c=s.readFile.bind(s),l=s.getSourceFile.bind(s),u=s.fileExists.bind(s);return s.readFile=e=>e===n?r:c(e),s.fileExists=e=>e===n||u(e),s.getSourceFile=(t,i,a,o)=>t===n?e.createSourceFile(t,r,i,!0):l(t,i,a,o),e.createProgram({rootNames:[...Ai(o.fileNames,k(n)),n],options:o.options,host:s})}const Mi=`/* eslint-disable */
790
+ `}function Ii(e,t,n,r){let i=/* @__PURE__ */ new Set,a=/* @__PURE__ */ new Map;for(let t of n.statements)e.isTypeAliasDeclaration(t)&&a.set(t.name.text,t);for(let e of t.getSemanticDiagnostics(n))if(e.start!==void 0)for(let[t,o]of r.entries()){let r=a.get(Pi(t));r&&e.start>=r.getStart(n)&&e.start<r.getEnd()&&i.add(o)}return i}function Li(e,t){let n=e.filter(e=>/\.d\.(ts|mts|cts)$/.test(e)),r=[];try{r=I(t).filter(e=>e.endsWith(`.ts`)).map(e=>A(t,e))}catch{}return[.../* @__PURE__ */ new Set([...n,...r])]}function Ri(e,t,n,r){let i=A(t,`tsconfig.json`),a={...e.sys,onUnRecoverableConfigFileDiagnostic:t=>{throw Error(e.flattenDiagnosticMessageText(t.messageText,`
791
+ `))}},o=e.getParsedCommandLineOfConfigFile(i,{},a);if(!o)throw Error(`kick/client: could not read ${i}`);let s=e.createCompilerHost(o.options,!0),c=s.readFile.bind(s),l=s.getSourceFile.bind(s),u=s.fileExists.bind(s);return s.readFile=e=>e===n?r:c(e),s.fileExists=e=>e===n||u(e),s.getSourceFile=(t,i,a,o)=>t===n?e.createSourceFile(t,r,i,!0):l(t,i,a,o),e.createProgram({rootNames:[...Li(o.fileNames,k(n)),n],options:o.options,host:s})}const zi=`/* eslint-disable */
783
792
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
784
793
  //
785
794
  // Self-contained: this file has no imports, so a frontend consumes it without
@@ -793,7 +802,7 @@ ${g}
793
802
  //
794
803
  // Written when \`kick dev\` starts, not on save — resolving these types builds a
795
804
  // full TypeScript program over the server. Re-run \`kick typegen\`.
796
- `;function Ni(e,t){let n=t.filter(t=>e.entries.has(t));if(n.length===0)return`${Mi}
805
+ `;function Bi(e,t){let n=t.filter(t=>e.entries.has(t));if(n.length===0)return`${zi}
797
806
  // (no routes discovered yet — annotate a controller method with
798
807
  // @Get/@Post/@Put/@Delete/@Patch and re-run \`kick typegen\`)
799
808
  interface Api {}
@@ -810,7 +819,7 @@ export type { Api }
810
819
 
811
820
  `)+`
812
821
 
813
- `:``,i=n.map(t=>` ${JSON.stringify(t)}: ${e.entries.get(t)}`);return`${Mi}
822
+ `:``,i=n.map(t=>` ${JSON.stringify(t)}: ${e.entries.get(t)}`);return`${zi}
814
823
  ${r}interface Api {
815
824
  ${i.join(`
816
825
  `)}
@@ -824,7 +833,7 @@ declare global {
824
833
  }
825
834
 
826
835
  export type { Api }
827
- `}const Pi=`kick/client`,Q=`.kickjs/types/kick__client.d.ts`,Fi=`.kickjs/cache/client-map.sha1`,Ii=(()=>{try{return it(import.meta.url)(`../../../package.json`).version??`0.0.0`}catch{return`0.0.0`}})();function Li(e){try{if(!P(e))return null;let[t,n]=F(e,`utf-8`).trim().split(/\s+/);return t&&n?{inputs:t,output:n}:null}catch{return null}}function Ri(e){return`${sn}${Pi} */\n\n${e}\n`}function zi(e){try{return P(e)?F(e,`utf-8`):null}catch{return null}}async function Bi(e){let t=O.resolve(e.cwd,Q);if(!P(t))return!1;try{await pt(t,{force:!0})}catch(t){return e.log.warn(` kick/client: could not remove the stale ${Q} — treat it as out of date (${t instanceof Error?t.message:String(t)})`),!0}return e.log.warn(` kick/client: removed the previously generated ${Q} rather than leave a stale one — re-run \`kick typegen\` once the cause above is fixed.`),!0}function Vi(e){let t=e?.typegen?.client;return typeof t==`object`?t.maxDepth:void 0}function Hi(e){let t=e.config?.typegen?.client;return typeof t==`boolean`?t:t&&typeof t==`object`?t.enabled!==!1:(P(O.resolve(e.cwd,Q))&&e.log.warn(` kick/client: ${Q} exists but typegen.client is not set, so it is NOT being refreshed.\n Add \`typegen: { client: true }\` to kick.config.ts to keep it current, or delete the file if nothing reads it.`),!1)}const Ui=()=>({id:Pi,outExtension:`.d.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){if(!Hi(e))return null;if(e.watch)return e.log.info?.(" kick/client: skipped under watch (builds a full TypeScript program). Run `kick typegen` to refresh the client route map."),null;let t=await e.getScanResult({root:O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`),cwd:e.cwd}),n=[],r=/* @__PURE__ */ new Set;for(let e of t.routes){let t=`${e.httpMethod} ${e.mountedPath??e.path}`;r.has(t)||(r.add(t),n.push(t))}let i=Vi(e.config),a=await wi({projectDir:e.cwd,keys:n,maxDepth:i,cliVersion:Ii}),o=Li(O.resolve(e.cwd,Fi)),s=zi(O.resolve(e.cwd,Q));if(a&&o&&s!==null&&o.inputs===a&&o.output===Si(s))return se()&&e.log.info?.(` kick/client: unchanged, keeping ${Q}`),null;try{let t=Ni(await Ti({projectDir:e.cwd,routesFile:O.resolve(e.cwd,`.kickjs/types/kick__routes.ts`),keys:n,maxDepth:i,onWarn:t=>e.log.warn(t)}),n);return a&&!e.check&&await e.writeFile(Fi,`${a} ${Si(Ri(t))}`),t}catch(t){let n=P(O.resolve(e.cwd,Q)),r=` kick/client: skipped — ${t instanceof Error?t.message:String(t)}`;return n?e.log.warn(r):se()&&e.log.info?.(r),n&&await Bi(e),null}}});function Wi(e,t,n=`zod`){if(!e)return null;let r=k(t),i=j(r,e.filePath).split(N).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),`/* eslint-disable */
836
+ `}const Vi=`kick/client`,Q=`.kickjs/types/kick__client.d.ts`,Hi=`.kickjs/cache/client-map.sha1`,Ui=(()=>{try{return it(import.meta.url)(`../../../package.json`).version??`0.0.0`}catch{return`0.0.0`}})();function Wi(e){try{if(!P(e))return null;let[t,n]=F(e,`utf-8`).trim().split(/\s+/);return t&&n?{inputs:t,output:n}:null}catch{return null}}function Gi(e){return`${sn}${Vi} */\n\n${e}\n`}function Ki(e){try{return P(e)?F(e,`utf-8`):null}catch{return null}}async function qi(e){let t=O.resolve(e.cwd,Q);if(!P(t))return!1;try{await pt(t,{force:!0})}catch(t){return e.log.warn(` kick/client: could not remove the stale ${Q} — treat it as out of date (${t instanceof Error?t.message:String(t)})`),!0}return e.log.warn(` kick/client: removed the previously generated ${Q} rather than leave a stale one — re-run \`kick typegen\` once the cause above is fixed.`),!0}function Ji(e){let t=e?.typegen?.client;return typeof t==`object`?t.maxDepth:void 0}function Yi(e){let t=e.config?.typegen?.client;return typeof t==`boolean`?t:t&&typeof t==`object`?t.enabled!==!1:(P(O.resolve(e.cwd,Q))&&e.log.warn(` kick/client: ${Q} exists but typegen.client is not set, so it is NOT being refreshed.\n Add \`typegen: { client: true }\` to kick.config.ts to keep it current, or delete the file if nothing reads it.`),!1)}const Xi=()=>({id:Vi,outExtension:`.d.ts`,inputs:[`src/**/*.controller.ts`,`src/**/*.module.ts`],async generate(e){if(!Yi(e))return null;if(e.watch)return e.log.info?.(" kick/client: skipped under watch (builds a full TypeScript program). Run `kick typegen` to refresh the client route map."),null;let t=await e.getScanResult({root:O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`),cwd:e.cwd}),n=[],r=/* @__PURE__ */ new Set;for(let e of t.routes){let t=`${e.httpMethod} ${e.mountedPath??e.path}`;r.has(t)||(r.add(t),n.push(t))}let i=Ji(e.config),a=await ji({projectDir:e.cwd,keys:n,maxDepth:i,cliVersion:Ui}),o=Wi(O.resolve(e.cwd,Hi)),s=Ki(O.resolve(e.cwd,Q));if(a&&o&&s!==null&&o.inputs===a&&o.output===ki(s))return se()&&e.log.info?.(` kick/client: unchanged, keeping ${Q}`),null;try{let t=Bi(await Mi({projectDir:e.cwd,routesFile:O.resolve(e.cwd,`.kickjs/types/kick__routes.ts`),keys:n,maxDepth:i,onWarn:t=>e.log.warn(t)}),n);return a&&!e.check&&await e.writeFile(Hi,`${a} ${ki(Gi(t))}`),t}catch(t){let n=P(O.resolve(e.cwd,Q)),r=` kick/client: skipped — ${t instanceof Error?t.message:String(t)}`;return n?e.log.warn(r):se()&&e.log.info?.(r),n&&await qi(e),null}}});function Zi(e,t,n=`zod`){if(!e)return null;let r=k(t),i=j(r,e.filePath).split(N).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),`/* eslint-disable */
828
837
  // AUTO-GENERATED by \`kick typegen\`. DO NOT EDIT.
829
838
  // Re-run with \`kick typegen\` or rely on \`kick dev\` to refresh.
830
839
 
@@ -862,6 +871,6 @@ declare global {
862
871
  }
863
872
 
864
873
  export {}
865
- `}const Gi=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=qi(e);if(t===!1)return null;let n=await e.getScanResult({root:Ki(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=e.config?.typegen?.schemaValidator??`zod`,i=O.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return Wi(n.env,i,r)}});function Ki(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function qi(e){return e.config?.typegen?.envFile}function Ji(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function Yi(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function $(e){return{root:Ji(e),cwd:e.cwd,envFile:Yi(e)}}const Xi=()=>({id:`kick/registry`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=O.resolve(e.cwd,`.kickjs/types/kick__registry.d.ts`),r=new Set(t.collisions.map(e=>e.className));return Ue(t.classes,n,r)}}),Zi=()=>({id:`kick/services`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=new Set(t.collisions.map(e=>e.className)),r=qe(t.classes,t.tokens,t.injects,n);return Je(`ServiceToken`,r,"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)")}}),Qi=()=>({id:`kick/modules`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return Je(`ModuleToken`,Ve(t.classes),"(no @Module classes discovered — `kick g module <name>` to add one)")}}),$i=()=>({id:`kick/plugins`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return He(t.pluginsAndAdapters)}}),ea=()=>({id:`kick/context`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return t.contextKeys.length===0?null:et(t.contextKeys)}}),ta=()=>({id:`kick/route-flags`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return Xe(t.routeFlags)}}),na={fastify:{subpath:`@forinda/kickjs/fastify`,typeName:`FastifyRuntimeTypes`},h3:{subpath:`@forinda/kickjs/h3`,typeName:`H3RuntimeTypes`}},ra=[E({name:`kick/init`,register:Tt}),E({name:`kick/generate`,register:an}),E({name:`kick/run`,register:yn}),E({name:`kick/info`,register:wn}),E({name:`kick/inspect`,register:Nn}),E({name:`kick/add`,register:we}),E({name:`kick/list`,register:Ee}),E({name:`kick/explain`,register:Hn}),E({name:`kick/mcp`,register:Qn}),E({name:`kick/tinker`,register:nr}),E({name:`kick/remove`,register:cr}),E({name:`kick/typegen`,register:dr}),E({name:`kick/check`,register:Ar}),E({name:`kick/doctor`,register:ge}),E({name:`kick/codemod`,register:Mr}),E({name:`kick/deploy`,register:$r}),E({name:`kick/registry`,typegens:[Xi()]}),E({name:`kick/services`,typegens:[Zi()]}),E({name:`kick/modules`,typegens:[Qi()]}),E({name:`kick/plugins`,typegens:[$i()]}),E({name:`kick/context`,typegens:[ea()]}),E({name:`kick/route-flags`,typegens:[ta()]}),E({name:`kick/assets`,typegens:[ei()]}),E({name:`kick/routes`,typegens:[ui()]}),E({name:`kick/client`,typegens:[Ui()]}),E({name:`kick/env`,typegens:[Gi()]}),E({name:`kick/runtime`,typegens:[{id:`kick/runtime`,outExtension:`.ts`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`],async generate(e){let t=e.config?.runtime;if(t!==`fastify`&&t!==`h3`)return null;let{subpath:n,typeName:r}=na[t];return[`// Runtime escape-hatch types for the '${t}' engine (kick.config runtime).`,`declare module '@forinda/kickjs' {`,` interface KickRuntimeRegister {`,` runtime: import('${n}').${r}`,` }`,`}`,``,`export {}`,``].join(`
866
- `)}}]})];export{un as applyDisableFilter,dn as n,Et as r,G as runAllPluginTypegens,ra as t};
867
- //# sourceMappingURL=run-plugins-0AfIgIsZ.mjs.map
874
+ `}const Qi=()=>({id:`kick/env`,outExtension:`.ts`,inputs:[`src/env.ts`,`src/**/env.ts`,`src/**/*.env.ts`],async generate(e){let t=ea(e);if(t===!1)return null;let n=await e.getScanResult({root:$i(e),cwd:e.cwd,envFile:t});if(!n.env)return null;let r=e.config?.typegen?.schemaValidator??`zod`,i=O.resolve(e.cwd,`.kickjs/types/kick__env.ts`);return Zi(n.env,i,r)}});function $i(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function ea(e){return e.config?.typegen?.envFile}function ta(e){return O.resolve(e.cwd,e.config?.typegen?.srcDir??`src`)}function na(e){let t=e.config?.typegen?.envFile;if(t!==!1)return t}function $(e){return{root:ta(e),cwd:e.cwd,envFile:na(e)}}const ra=()=>({id:`kick/registry`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=O.resolve(e.cwd,`.kickjs/types/kick__registry.d.ts`),r=new Set(t.collisions.map(e=>e.className));return Ue(t.classes,n,r)}}),ia=()=>({id:`kick/services`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e)),n=new Set(t.collisions.map(e=>e.className)),r=qe(t.classes,t.tokens,t.injects,n);return Je(`ServiceToken`,r,"(no tokens discovered — declare with createToken<T>() or `kick g service <name>`)")}}),aa=()=>({id:`kick/modules`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return Je(`ModuleToken`,Ve(t.classes),"(no @Module classes discovered — `kick g module <name>` to add one)")}}),oa=()=>({id:`kick/plugins`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return He(t.pluginsAndAdapters)}}),sa=()=>({id:`kick/context`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return t.contextKeys.length===0?null:et(t.contextKeys)}}),ca=()=>({id:`kick/route-flags`,inputs:[`src/**/*.ts`],async generate(e){let t=await e.getScanResult($(e));return Xe(t.routeFlags)}}),la={fastify:{subpath:`@forinda/kickjs/fastify`,typeName:`FastifyRuntimeTypes`},h3:{subpath:`@forinda/kickjs/h3`,typeName:`H3RuntimeTypes`}},ua=[E({name:`kick/init`,register:Tt}),E({name:`kick/generate`,register:an}),E({name:`kick/run`,register:yn}),E({name:`kick/info`,register:wn}),E({name:`kick/inspect`,register:Nn}),E({name:`kick/add`,register:we}),E({name:`kick/list`,register:Ee}),E({name:`kick/explain`,register:Hn}),E({name:`kick/mcp`,register:Qn}),E({name:`kick/tinker`,register:nr}),E({name:`kick/remove`,register:cr}),E({name:`kick/typegen`,register:dr}),E({name:`kick/check`,register:Ar}),E({name:`kick/doctor`,register:ge}),E({name:`kick/env-command`,register:Lr}),E({name:`kick/codemod`,register:zr}),E({name:`kick/deploy`,register:oi}),E({name:`kick/registry`,typegens:[ra()]}),E({name:`kick/services`,typegens:[ia()]}),E({name:`kick/modules`,typegens:[aa()]}),E({name:`kick/plugins`,typegens:[oa()]}),E({name:`kick/context`,typegens:[sa()]}),E({name:`kick/route-flags`,typegens:[ca()]}),E({name:`kick/assets`,typegens:[si()]}),E({name:`kick/routes`,typegens:[_i()]}),E({name:`kick/client`,typegens:[Xi()]}),E({name:`kick/env`,typegens:[Qi()]}),E({name:`kick/runtime`,typegens:[{id:`kick/runtime`,outExtension:`.ts`,inputs:[`kick.config.ts`,`kick.config.js`,`kick.config.mjs`,`kick.config.json`],async generate(e){let t=e.config?.runtime;if(t!==`fastify`&&t!==`h3`)return null;let{subpath:n,typeName:r}=la[t];return[`// Runtime escape-hatch types for the '${t}' engine (kick.config runtime).`,`declare module '@forinda/kickjs' {`,` interface KickRuntimeRegister {`,` runtime: import('${n}').${r}`,` }`,`}`,``,`export {}`,``].join(`
875
+ `)}}]})];export{un as applyDisableFilter,dn as n,Et as r,G as runAllPluginTypegens,ua as t};
876
+ //# sourceMappingURL=run-plugins-BXNfws9R.mjs.map