@forinda/kickjs-cli 8.5.0 → 8.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/{project-docs-Y6vOc-Uj.mjs → agent-docs-BO_QMIkN.mjs} +9 -71
  2. package/dist/agent-docs-BO_QMIkN.mjs.map +1 -0
  3. package/dist/{project-docs-BE8DKCWP.mjs → agent-docs-DTg4y5mT.mjs} +3 -65
  4. package/dist/{build-D3rNfcxu.mjs → build-DSQ6SPr4.mjs} +3 -3
  5. package/dist/{build-D3rNfcxu.mjs.map → build-DSQ6SPr4.mjs.map} +1 -1
  6. package/dist/{build-DwfrMHgx.mjs → build-DfrjvGMx.mjs} +2 -2
  7. package/dist/{builtins-DtTYiDg0.mjs → builtins-A-wfYHI9.mjs} +36 -31
  8. package/dist/{builtins-D4pwODzu.mjs → builtins-KQmcywFY.mjs} +2 -2
  9. package/dist/cli.mjs +2 -2
  10. package/dist/config-BoXFaObA.mjs +13 -0
  11. package/dist/config-BoXFaObA.mjs.map +1 -0
  12. package/dist/config-Bz1suLYz.mjs +12 -0
  13. package/dist/{doctor-Df6zCPr5.mjs → doctor-p4bjILiU.mjs} +6 -6
  14. package/dist/{doctor-Df6zCPr5.mjs.map → doctor-p4bjILiU.mjs.map} +1 -1
  15. package/dist/fs-DH9oxW0t.mjs +11 -0
  16. package/dist/fs-Dz7zBXL4.mjs +12 -0
  17. package/dist/fs-Dz7zBXL4.mjs.map +1 -0
  18. package/dist/fullstack-BKD9McZF.mjs +96 -0
  19. package/dist/fullstack-BKD9McZF.mjs.map +1 -0
  20. package/dist/fullstack-DQbVCW5U.mjs +95 -0
  21. package/dist/index.d.mts +15 -24
  22. package/dist/index.d.mts.map +1 -1
  23. package/dist/index.mjs +2 -2
  24. package/dist/{plugin-B8fmVbk8.mjs → plugin-Aof9UWs7.mjs} +2 -2
  25. package/dist/{plugin-B-mP0jvi.mjs → plugin-B-kr8WAU.mjs} +2 -2
  26. package/dist/project-BAGDIkJa.mjs +45 -0
  27. package/dist/project-BjxeGJBn.mjs +46 -0
  28. package/dist/project-BjxeGJBn.mjs.map +1 -0
  29. package/dist/{project-root-CSHMf3L7.mjs → project-root-4oQKPMOs.mjs} +2 -2
  30. package/dist/{project-root-BzyIWFlH.mjs → project-root-D8VclnwB.mjs} +3 -3
  31. package/dist/{project-root-BzyIWFlH.mjs.map → project-root-D8VclnwB.mjs.map} +1 -1
  32. package/dist/{prompts-wFEGsPZt.mjs → prompts-BIl0rZ4C.mjs} +2 -2
  33. package/dist/{prompts-wFEGsPZt.mjs.map → prompts-BIl0rZ4C.mjs.map} +1 -1
  34. package/dist/{rolldown-runtime-DzFISCwE.mjs → rolldown-runtime-DElgkk48.mjs} +1 -1
  35. package/dist/{run-plugins-ByRyAAZe.mjs → run-plugins-DCVSqa5a.mjs} +34 -29
  36. package/dist/run-plugins-DCVSqa5a.mjs.map +1 -0
  37. package/dist/typegen-BOxA_1DU.mjs +132 -0
  38. package/dist/{typegen-Bx2IQ-w5.mjs.map → typegen-BOxA_1DU.mjs.map} +1 -1
  39. package/dist/{typegen-BfOYvlWo.mjs → typegen-Dss5L5p7.mjs} +4 -4
  40. package/dist/{types-dUiZnaWm.mjs → types-Dudqvbd1.mjs} +1 -1
  41. package/package.json +9 -8
  42. package/templates/base/feature.json +18 -0
  43. package/templates/base/files/README.md +61 -0
  44. package/templates/base/files/_dot_editorconfig +13 -0
  45. package/templates/base/files/_dot_env +2 -0
  46. package/templates/base/files/_dot_env.example +2 -0
  47. package/templates/base/files/_dot_env.test +9 -0
  48. package/templates/base/files/_dot_env.test.example +11 -0
  49. package/templates/base/files/_dot_gitattributes +18 -0
  50. package/templates/base/files/_dot_gitignore +14 -0
  51. package/templates/base/files/_dot_oxfmtrc.json +9 -0
  52. package/templates/base/files/kick.config.ts +58 -0
  53. package/templates/base/files/src/modules/hello/hello.controller.ts +26 -0
  54. package/templates/base/files/src/modules/hello/hello.module.ts +21 -0
  55. package/templates/base/files/src/modules/hello/hello.service.ts +12 -0
  56. package/templates/base/files/src/modules/index.ts +7 -0
  57. package/templates/base/files/tsconfig.json +21 -0
  58. package/templates/base/files/vite.config.ts +31 -0
  59. package/templates/base/files/vitest.config.ts +18 -0
  60. package/templates/feature-devtools/feature.json +13 -0
  61. package/templates/feature-queue/feature.json +16 -0
  62. package/templates/feature-queue/files/_dot_env.append +2 -0
  63. package/templates/feature-queue/files/_dot_env.example.append +2 -0
  64. package/templates/feature-swagger/feature.json +16 -0
  65. package/templates/feature-ws/feature.json +13 -0
  66. package/templates/fullstack-root/files/_dot_gitignore +8 -0
  67. package/templates/fullstack-root/files/netlify.toml +13 -0
  68. package/templates/fullstack-root/files/vercel.json +5 -0
  69. package/templates/host-config/files/netlify.toml +6 -0
  70. package/templates/host-config/files/vercel.json +5 -0
  71. package/templates/runtime-express/feature.json +22 -0
  72. package/templates/runtime-fastify/feature.json +13 -0
  73. package/templates/runtime-h3/feature.json +13 -0
  74. package/templates/schema-valibot/feature.json +3 -0
  75. package/templates/schema-valibot/files/src/config/index.ts +41 -0
  76. package/templates/schema-yup/feature.json +3 -0
  77. package/templates/schema-yup/files/src/config/index.ts +43 -0
  78. package/templates/schema-zod/feature.json +3 -0
  79. package/templates/schema-zod/files/src/config/index.ts +41 -0
  80. package/templates/server-fullstack/feature.json +13 -0
  81. package/templates/template-minimal/feature.json +10 -0
  82. package/templates/template-minimal/files/src/index.ts +17 -0
  83. package/templates/template-rest/feature.json +10 -0
  84. package/templates/template-rest/files/src/index.ts +28 -0
  85. package/templates/web-kick/files/web/index.html +12 -0
  86. package/templates/web-kick/files/web/src/App.tsx +45 -0
  87. package/templates/web-kick/files/web/src/api.ts +14 -0
  88. package/templates/web-kick/files/web/src/main.tsx +9 -0
  89. package/templates/web-kick/files/web/tsconfig.json +15 -0
  90. package/templates/web-kick/files/web/vite.config.ts +13 -0
  91. package/dist/agent-docs-CXX06wib.mjs +0 -11
  92. package/dist/agent-docs-CXs5UDAM.mjs +0 -12
  93. package/dist/agent-docs-CXs5UDAM.mjs.map +0 -1
  94. package/dist/config-BUYf44lU.mjs +0 -13
  95. package/dist/config-BUYf44lU.mjs.map +0 -1
  96. package/dist/config-F1NW28_P.mjs +0 -12
  97. package/dist/fullstack-BcJ5lOwt.mjs +0 -194
  98. package/dist/fullstack-D3W7RS2W.mjs +0 -195
  99. package/dist/fullstack-D3W7RS2W.mjs.map +0 -1
  100. package/dist/project-5aAVIQV5.mjs +0 -450
  101. package/dist/project-DdYD7xPw.mjs +0 -451
  102. package/dist/project-DdYD7xPw.mjs.map +0 -1
  103. package/dist/project-docs-Y6vOc-Uj.mjs.map +0 -1
  104. package/dist/run-plugins-ByRyAAZe.mjs.map +0 -1
  105. package/dist/typegen-Bx2IQ-w5.mjs +0 -132
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v8.5.0
2
+ * @forinda/kickjs-cli v8.6.1
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{t as e}from"./rolldown-runtime-DzFISCwE.mjs";import{statSync as t}from"node:fs";import{basename as n,dirname as r,join as i,relative as a,resolve as o,sep as s}from"node:path";import{mkdir as c,readFile as l,readdir as u,stat as d,unlink as f,writeFile as p}from"node:fs/promises";import{parseSync as m}from"oxc-parser";import{globSync as h}from"glob";import{groupAssetKeys as g}from"@forinda/kickjs";const _=[`classes`,`tokens`,`injects`,`pluginsAndAdapters`,`augmentations`,`contextKeys`,`routeFlags`,`routes`,`moduleMounts`,`globPatterns`];function v(e){if(!e||typeof e!=`object`)return!1;let t=e;return _.every(e=>Array.isArray(t[e]))}var y=class e{path;prev;next=new Map;nextSig=new Map;constructor(e,t){this.path=e,this.prev=t}static async load(t){let n=i(t,`scan.json`),r=new Map;try{let e=await l(n,`utf-8`),t=JSON.parse(e);if(t.version===3&&t.files)for(let[e,n]of Object.entries(t.files))n&&typeof n.sig==`string`&&v(n.extract)&&r.set(e,n)}catch{}return new e(n,r)}static async signature(e){try{let t=await d(e);return`${t.mtimeMs}:${t.size}`}catch{return null}}get(e,t){let n=this.prev.get(e);return n&&n.sig===t?n.extract:null}set(e,t,n){this.next.set(e,n),this.nextSig.set(e,t)}cachedFiles(){return[...this.prev.keys()]}peek(e){return this.prev.get(e)?.extract??null}carry(e){let t=this.prev.get(e);return t?(this.next.set(e,t.extract),this.nextSig.set(e,t.sig),!0):!1}async save(){let e={};for(let[t,n]of this.next){let r=this.nextSig.get(t);r&&(e[t]={sig:r,extract:n})}let t={version:3,files:e};try{await c(r(this.path),{recursive:!0}),await p(this.path,JSON.stringify(t),`utf-8`)}catch{}}};let b=null;function x(){return b??=new Set(L),b}const S=new Set([`Get`,`Post`,`Put`,`Delete`,`Patch`]);function C(e){return typeof e==`object`&&!!e&&typeof e.type==`string`}function w(e,t){if(Array.isArray(e)){for(let n of e)w(n,t);return}if(C(e)){t(e);for(let n of Object.keys(e)){if(n===`type`)continue;let r=e[n];typeof r==`object`&&r&&w(r,t)}}}function T(e){if(!C(e))return null;if(e.type===`Literal`&&typeof e.value==`string`)return e.value;if(e.type===`TemplateLiteral`){let t=e.quasis,n=e.expressions;if(t?.length===1&&(n?.length??0)===0){let e=t[0].value?.cooked;return typeof e==`string`?e:null}}return null}function E(e){return C(e)&&e.type===`Identifier`?e.name:null}function D(e){return E(e.callee)}function O(e,t){if(!e||e.type!==`ObjectExpression`)return null;for(let n of e.properties??[]){if(n.type!==`Property`)continue;let e=n.key;if((E(e)??(e.type===`Literal`?String(e.value):T(e)))===t)return n.value}return null}function k(e){let t=e.arguments?.[0];return C(t)&&t.type===`ObjectExpression`?t:null}function A(e,t){let n=O(e,t);if(!C(n)||n.type!==`ArrayExpression`)return[];let r=[];for(let e of n.elements??[]){let t=T(e);t!==null&&r.push(t)}return r}function ee(e,t){return a(t,e).split(s).join(`/`)}function te(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function ne(e,t){for(let n of e.implements??[]){let e=n.expression??n;if(E(e)===t)return!0;if(e.type===`TSQualifiedName`||e.type===`MemberExpression`){let n=e.right??e.property;if(n&&E(n)===t)return!0}}return!1}function j(e){return e.decorators??[]}function M(e){let t=e.expression;if(!C(t)||t.type!==`CallExpression`)return null;let n=D(t);return n?{name:n,call:t}:null}function re(e){let t=new Map,n=new Set;for(let r of e.body??[]){if(r.type===`ImportDeclaration`){let e=T(r.source)??``;for(let n of r.specifiers??[]){let r=E(n.local);r&&t.set(r,{source:e})}continue}let e=r.type===`VariableDeclaration`?r:r.type===`ExportNamedDeclaration`&&C(r.declaration)?r.declaration:null;if(C(e)&&e.type===`VariableDeclaration`)for(let t of e.declarations??[]){let e=E(t.id);e&&n.add(e)}}return{imports:t,topLevelConsts:n}}function N(e,t){let n=t.imports.get(e);return n?{identifier:e,source:n.source}:t.topLevelConsts.has(e)?{identifier:e,source:``}:{identifier:e,source:null}}function ie(e,t){let n=[];for(let r of e){let e=M(r),i=e?e.name:E(r.expression);if(!i||S.has(i))continue;let a=t.imports.get(i);n.push({identifier:i,source:a?a.source:t.topLevelConsts.has(i)?``:null})}return n}const P=new Set([`bootstrap`,`createWebApp`,`Application`]);function ae(e,t){if(!P.has(e))return!1;let n=t.imports.get(e)?.source;return n===`@forinda/kickjs`||(n?.startsWith(`@forinda/kickjs/`)??!1)}function oe(e,t){let n={refs:[],resolved:!1},r=se(e);if(!r||r.type!==`ArrayExpression`)return n;let i=[];for(let e of r.elements??[]){if(!C(e)||e.type!==`MemberExpression`||E(e.property)!==`registration`)return n;let r=e.object,a=E(r);if(!a&&C(r)&&r.type===`CallExpression`){let e=r.callee;C(e)&&e.type===`MemberExpression`&&E(e.property)===`with`&&(a=E(e.object))}if(!a)return n;let o=t.imports.get(a);i.push({identifier:a,source:o?o.source:t.topLevelConsts.has(a)?``:null})}return{refs:i,resolved:!0}}function se(e){let t=e.value??e;if(!C(t))return null;if(t.type===`ArrayExpression`)return t;let n=t.body;if(!C(n))return null;if(n.type!==`BlockStatement`)return n;let r=(n.body??[]).filter(e=>e.type===`ReturnStatement`);if(r.length!==1)return null;let i=r[0].argument;return C(i)?i:null}function F(e,t,n){let r=E(O(e,t));return r?N(r,n):null}function ce(e,t){for(let n of e){let e=M(n);if(!e||e.name!==`ApiQueryParams`)continue;let r=e.call.arguments?.[0],i=null;if(C(r)&&r.type===`ObjectExpression`)i=r;else{let e=E(r);if(e){let n=t.get(e);n&&n.type===`ObjectExpression`&&(i=n)}}return{filterable:A(i,`filterable`),sortable:A(i,`sortable`),searchable:A(i,`searchable`)}}return null}function I(e,t,n){let r;try{let n=m(t,e);if(n.errors.length>0)return null;r=n.program}catch{return null}let i=ee(t,n),a=re(r),o=[],s=[],c=[],l=[],u=[],d=[],f=[],p=new Set,h=[],g=[],_=[],v=new Set,y=new Set,b=new Map;w(r,e=>{if(e.type!==`VariableDeclarator`)return;let t=E(e.id),n=e.init;t&&C(n)&&b.set(n,t)});let A=new Set,N=new Map;for(let e of r.body??[]){let t=e.type===`VariableDeclaration`?e:e.type===`ExportNamedDeclaration`&&C(e.declaration)?e.declaration:null;if(C(t)&&t.type===`VariableDeclaration`)for(let e of t.declarations??[]){let t=E(e.id);t&&C(e.init)&&N.set(t,e.init)}}let P=[];for(let e of r.body??[])if(e.type===`ExportNamedDeclaration`&&C(e.declaration)){let t=e.declaration;t.type===`ClassDeclaration`&&P.push({cls:t,isDefault:!1})}else if(e.type===`ExportDefaultDeclaration`&&C(e.declaration)){let t=e.declaration;t.type===`ClassDeclaration`&&P.push({cls:t,isDefault:!0})}for(let{cls:e,isDefault:n}of P){let r=E(e.id);if(!r)continue;let a=null;for(let t of j(e)){let e=M(t);if(e&&x().has(e.name)){a=e.name;break}}a?o.push({className:r,decorator:a,filePath:t,relativePath:i,isDefault:n}):ne(e,`AppModule`)&&o.push({className:r,decorator:`Module`,filePath:t,relativePath:i,isDefault:n})}for(let e of r.body??[]){if(e.type!==`ExportNamedDeclaration`||!C(e.declaration))continue;let n=e.declaration;if(n.type===`VariableDeclaration`)for(let e of n.declarations??[]){let n=E(e.id),r=e.init;n&&C(r)&&r.type===`CallExpression`&&D(r)===`defineModule`&&(o.some(e=>e.className===n)||o.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!1}))}}w(r,n=>{if(n.type===`VariableDeclarator`){let e=n.init;if(C(e)&&e.type===`CallExpression`&&D(e)===`createToken`){let r=T(e.arguments?.[0]);r!==null&&(A.add(e),s.push({name:r,variable:E(n.id),filePath:t,relativePath:i}))}return}if(n.type!==`CallExpression`){if(n.type===`Decorator`){let e=M(n);if(e?.name===`Inject`){let n=T(e.call.arguments?.[0]);n!==null&&c.push({name:n,filePath:t,relativePath:i})}}return}let r=n.callee,a=D(n);if(a===`createToken`&&!A.has(n)){let e=T(n.arguments?.[0]);e!==null&&s.push({name:e,variable:null,filePath:t,relativePath:i});return}if(a===`defineAdapter`||a===`definePlugin`){let e=T(O(k(n),`name`));if(e!==null){let n=a===`definePlugin`?`plugin`:`adapter`,r=`${a}::${e}::${t}`;v.has(r)||(v.add(r),l.push({kind:n,name:e,filePath:t,relativePath:i}))}return}if(a===`defineAugmentation`){let e=n.arguments??[],r=T(e[0]);if(r!==null){let n=C(e[1])&&e[1].type===`ObjectExpression`?e[1]:null;u.push({name:r,description:T(O(n,`description`)),example:T(O(n,`example`)),filePath:t,relativePath:i})}return}if(a===`defineRouteFlag`){let r=T(n.arguments?.[0]);if(r!==null&&!p.has(r)){p.add(r);let a=n.typeArguments,o=a?e.slice(a.start,a.end):null;f.push({name:r,valueType:o?o.slice(1,-1).trim():null,filePath:t,relativePath:i})}return}if(a===`defineContextDecorator`||a===`defineHttpContextDecorator`){let e=T(O(k(n),`key`));e!==null&&!y.has(e)&&(y.add(e),d.push({key:e,exportName:b.get(n)??null,filePath:t,relativePath:i}));return}if(C(r)&&r.type===`CallExpression`){let e=r.callee;if(C(e)&&e.type===`MemberExpression`&&E(e.property)===`withParams`){let r=E(e.object);if(r===`defineContextDecorator`||r===`defineHttpContextDecorator`){let e=T(O(k(n),`key`));e!==null&&!y.has(e)&&(y.add(e),d.push({key:e,exportName:b.get(n)??null,filePath:t,relativePath:i}))}}return}if(C(r)&&r.type===`MemberExpression`&&E(r.property)===`glob`){let e=r.object;C(e)&&e.type===`MetaProperty`&&w(n.arguments,e=>{let t=T(e);t!==null&&_.push(t)})}});let se=[];w(r,e=>{if(e.type===`ClassDeclaration`||e.type===`ClassExpression`){let t=E(e.id);t&&se.push({cls:e,className:t})}});for(let{cls:e,className:n}of se){let r=o.find(e=>e.className===n),s=e.body?.body;if(ne(e,`AppAdapter`))for(let e of s??[]){if(e.type!==`PropertyDefinition`||E(e.key)!==`name`)continue;let n=T(e.value);if(n===null)continue;let r=`class::${n}::${t}`;v.has(r)||(v.add(r),l.push({kind:`adapter`,name:n,filePath:t,relativePath:i}));break}for(let o of s??[]){if(o.type!==`MethodDefinition`)continue;let s=E(o.key);if(!s)continue;if(s===`routes`){le(o.value,g);continue}if(!r)continue;let c=j(o),l=ce(c,N),u=[...ie(j(e),a),...ie(c,a)];for(let e of c){let o=M(e);if(!o||!S.has(o.name))continue;let c=o.call.arguments??[],d=T(c[0]),f=d&&d.length>0?d:`/`,p=C(c[1])&&c[1].type===`ObjectExpression`?c[1]:null;h.push({controller:n,method:s,httpMethod:o.name.toUpperCase(),path:f,pathParams:te(f),queryFilterable:l?.filterable??null,querySortable:l?.sortable??null,querySearchable:l?.searchable??null,bodySchema:F(p,`body`,a),querySchema:F(p,`query`,a),paramsSchema:F(p,`params`,a),responseSchema:F(p,`response`,a),filePath:t,relativePath:i,controllerIsDefaultExport:r.isDefault,appliedDecorators:u,mountedPath:f})}}}w(r,e=>{if(e.type!==`Property`||E(e.key)!==`routes`)return;let t=e.value;C(t)&&(t.type===`FunctionExpression`||t.type===`ArrowFunctionExpression`)&&le(t,g)});let I=new Set,L=new Set;w(r,e=>{let t=e.type===`Property`&&E(e.key)===`contributors`,n=e.type===`MethodDefinition`&&E(e.key)===`contributors`;(t||n)&&L.add(e)});let R=e=>e.properties??e.body?.body??[];w(r,e=>{if(e.type!==`ObjectExpression`&&e.type!==`ClassDeclaration`)return;let t=R(e);if(t.map(e=>E(e.key)).includes(`routes`))for(let e of t)E(e.key)===`contributors`&&I.add(e)});let z=new Set;w(r,e=>{let t=e.type===`CallExpression`?D(e):e.type===`NewExpression`?E(e.callee):null;if(t===null||!ae(t,a))return;let n=k(e);if(n)for(let e of n.properties??[])e.type===`Property`&&E(e.key)===`contributors`&&z.add(e)});let B=e=>{if(e.size===0)return null;let n=[],r=!0;for(let t of e){let e=oe(t,a);e.resolved||(r=!1),n.push(...e.refs)}return{refs:n,resolved:r,filePath:t}},V=B(I),H=B(z);return{classes:o,tokens:s,injects:c,pluginsAndAdapters:l,augmentations:u,contextKeys:d,routeFlags:f,routes:h,moduleMounts:g,globPatterns:/\.module\.[mc]?[tj]sx?$/.test(t)?_:[],moduleContributors:V,appContributors:H,hasNonDecoratorContributors:L.size>I.size+z.size}}function le(e,t){let n=[],r=[];w(e.body,e=>{if(e.type!==`Property`)return;let t=E(e.key);if(t===`path`){let t=T(e.value);t!==null&&n.push(t)}else if(t===`controller`){let t=E(e.value);t&&/^[A-Z]/.test(t)&&r.push(t)}});let i=Math.min(n.length,r.length);for(let e=0;e<i;e++)t.push({controller:r[e],mountPath:n[e]})}const L=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],R=[`.ts`,`.tsx`,`.mts`,`.cts`],z=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],B=new RegExp(String.raw`@(${L.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),V=new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppModule\b`,`g`),H=/export\s+const\s+(\w+)\s*(?::\s*[^=]+)?=\s*defineModule\s*(?:<[^>]*>)?\s*\(/g,ue=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,de=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,fe=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,U=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,W=/(?:(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*(?::[^=]+)?=\s*)?\b(?:defineContextDecorator|defineHttpContextDecorator)\s*(?:\.withParams\s*<(?:[^<>]|<[^<>]*>)*>\s*\(\s*\))?\s*(?:<(?:[^<>]|<[^<>]*>)*>)?\s*\(/g,pe=new RegExp(String.raw`export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppAdapter\b`,`g`),me=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,he=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,G=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function K(e,t){let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`(`)n++;else if(t===`)`&&(n--,n===0))return r}return-1}function ge(e,t){let n=t;for(;n<e.length;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`@`)break;let t=e.slice(n).match(/^@([A-Z]\w*)/);if(!t)break;for(n+=t[0].length;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]===`(`){let t=K(e,n);if(t<0)return null;n=t+1}}for(;n<e.length&&/\s/.test(e[n]);)n++;for(let t of[`public`,`private`,`protected`])if(e.slice(n,n+t.length)===t&&/\s/.test(e.charAt(n+t.length))){for(n+=t.length;n<e.length&&/\s/.test(e[n]);)n++;break}if(e.slice(n,n+5)===`async`&&/\s/.test(e.charAt(n+5)))for(n+=5;n<e.length&&/\s/.test(e[n]);)n++;let r=e.slice(n).match(/^([a-zA-Z_]\w*)\s*\(/);return r?{methodName:r[1],endPos:n+r[0].length}:null}function _e(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function ve(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const ye=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,be=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,xe=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,Se=/\bimport\.meta\.glob\s*\(/g;function Ce(e){let t=[];for(Se.lastIndex=0;Se.exec(e)!==null;){let n=Se.lastIndex-1,r=K(e,n);if(r<0)continue;let i=e.slice(n+1,r),a=/['"`]([^'"`]+)['"`]/g,o;for(;(o=a.exec(i))!==null;)t.push(o[1])}return t}function we(e){let t=e.replace(/[.+^$()|[\]\\]/g,`\\$&`).replace(/\?/g,`.`).replace(/\*\*\//g,`___DOUBLESTAR_SLASH___`).replace(/\*\*/g,`___DOUBLESTAR___`).replace(/\*/g,`[^/]*`).replace(/___DOUBLESTAR_SLASH___/g,`(?:.+/)?`).replace(/___DOUBLESTAR___/g,`.*`);return RegExp(`^`+t+`$`)}function Te(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);we(t?e.slice(1):e).test(n)&&(r=!t)}return r}function Ee(e){let t=[];ye.lastIndex=0;let n;for(;(n=ye.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Ie(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];be.lastIndex=0;let s;for(;(s=be.exec(a))!==null;)o.push(s[1]??``);let c=[];xe.lastIndex=0;let l;for(;(l=xe.exec(a))!==null;)c.push(l[1]);let u=Math.min(o.length,c.length);for(let e=0;e<u;e++)t.push({controller:c[e],mountPath:o[e]})}return t}function q(e,t){let n=new RegExp(String.raw`\b${t}\s*:\s*([A-Za-z_$][\w$]*)`,`g`).exec(e);return n?n[1]:null}function J(e,t){let n=new RegExp(String.raw`import\s*(?:type\s+)?\{[^}]*\b${t}\b[^}]*\}\s*from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(n)return n[1];let r=new RegExp(String.raw`import\s+(?:type\s+)?${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(r)return r[1];let i=new RegExp(String.raw`import\s*\*\s*as\s+${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);return i?i[1]:new RegExp(String.raw`(?:^|\n)\s*(?:export\s+)?const\s+${t}\b`).test(e)?``:null}function De(e,t){let n=/@ApiQueryParams\s*\(\s*([\s\S]*?)\s*\)\s*$/.exec(e);if(!n){let n=/@ApiQueryParams\s*\(([\s\S]*?)\)/.exec(e);return n?Oe(n[1].trim(),t):null}return Oe(n[1].trim(),t)}function Oe(e,t){if(e.startsWith(`{`))return Ae(e);let n=/^([A-Za-z_]\w*)/.exec(e);if(n){let e=n[1],r=new RegExp(String.raw`const\s+${e}\s*(?::\s*[^=]+)?=\s*(\{[\s\S]*?\n\})`,`m`).exec(t);if(r)return Ae(r[1])}return{filterable:[],sortable:[],searchable:[]}}function ke(e,t){let n=new RegExp(String.raw`${t}\s*:\s*\[([\s\S]*?)\]`).exec(e);return n?Array.from(n[1].matchAll(/['"`]([^'"`]+)['"`]/g)).map(e=>e[1]):[]}function Ae(e){return{filterable:ke(e,`filterable`),sortable:ke(e,`sortable`),searchable:ke(e,`searchable`)}}async function je(e,t){let n=t.extensions??R,r=t.exclude??z,o=[],s;try{s=await u(e,{withFileTypes:!0,encoding:`utf-8`})}catch{return o}for(let c of s){let s=i(e,c.name),l=a(t.cwd,s);r.some(e=>l.includes(e))||(c.isDirectory()?o.push(...await je(s,t)):c.isFile()&&n.some(e=>c.name.endsWith(e))&&o.push(s))}return o}function Y(e,t){return a(t,e).split(s).join(`/`)}function Me(e,t,n){let r=[],i=Y(t,n);B.lastIndex=0;let a;for(;(a=B.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}V.lastIndex=0;let o;for(;(o=V.exec(e))!==null;){let[,e,n]=o;r.some(e=>e.className===n&&e.filePath===t)||r.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!!e})}H.lastIndex=0;let s;for(;(s=H.exec(e))!==null;){let[,e]=s;r.some(n=>n.className===e&&n.filePath===t)||r.push({className:e,decorator:`Module`,filePath:t,relativePath:i,isDefault:!1})}return r}function Ne(e,t,n){let r=[],i=Y(t,n),a=new Set;ue.lastIndex=0;let o;for(;(o=ue.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(de.lastIndex=0;(o=de.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Pe(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=Y(t,n),s=[];for(let t of r){let n=new RegExp(String.raw`class\s+${t.className}\b`).exec(e);n?.index!==void 0&&s.push({cls:t,start:n.index})}s.sort((e,t)=>e.start-t.start);for(let n=0;n<s.length;n++){let{cls:r,start:c}=s[n],l=n+1<s.length?s[n+1].start:e.length,u=e.slice(c,l);G.lastIndex=0;let d;for(;(d=G.exec(u))!==null;){let n=d[1],s=d.index,c=G.lastIndex-1,l=K(u,c);if(l<0)continue;let f=u.slice(c+1,l),p=f.match(/^\s*['"`]([^'"`]*)['"`]/),m=p&&p[1].length>0?p[1]:`/`,h=ge(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;G.lastIndex=_;let v=De(u.slice(s,_),e),y=q(f,`body`),b=q(f,`query`),x=q(f,`params`),S=q(f,`response`),C=i.get(r.className)??``,w=C?ve(C,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:_e(w),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:J(e,y)}:null,querySchema:b?{identifier:b,source:J(e,b)}:null,paramsSchema:x?{identifier:x,source:J(e,x)}:null,responseSchema:S?{identifier:S,source:J(e,S)}:null,filePath:t,relativePath:o,controllerIsDefaultExport:r.isDefault,mountedPath:w})}}return a}function Fe(e,t,n){let r=[],i=Y(t,n);fe.lastIndex=0;let a;for(;(a=fe.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Ie(e,t){let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return r}return-1}function Le(e,t,n){let r=[],i=Y(t,n),a=new Set;U.lastIndex=0;let o;for(;(o=U.exec(e))!==null;){let n=o[1],s=U.lastIndex-1,c=K(e,s);if(c<0)continue;let l=e.slice(s+1,c),u=/\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(l);if(!u)continue;let d=u[1],f=`${n}::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:n===`definePlugin`?`plugin`:`adapter`,name:d,filePath:t,relativePath:i}))}pe.lastIndex=0;let s;for(;(s=pe.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Ie(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=me.exec(l);if(!u)continue;let d=u[1],f=`class::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:`adapter`,name:d,filePath:t,relativePath:i}))}return r}function Re(e,t,n){let r=[],i=Y(t,n),a=new Set;W.lastIndex=0;let o;for(;(o=W.exec(e))!==null;){let n=W.lastIndex-1,s=K(e,n);if(s<0)continue;let c=e.slice(n+1,s),l=/\bkey\s*:\s*['"`]([^'"`]+)['"`]/.exec(c);if(!l)continue;let u=l[1];a.has(u)||(a.add(u),r.push({key:u,exportName:o[1]??null,filePath:t,relativePath:i}))}return r}function ze(e,t,n){let r=[],i=Y(t,n);he.lastIndex=0;let a;for(;(a=he.exec(e))!==null;){let n=a[1],o=null,s=null;if(a[2]){let t=e.indexOf(`{`,a.index+a[0].length-1);if(t>=0){let n=Ie(e,t);if(n>=0){let r=e.slice(t+1,n);o=Be(r,`description`),s=Be(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function Be(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(['"\`])`,`g`).exec(e);if(!n)return null;let r=n[1],i=n.index+n[0].length,a=i,o=null;for(;a<e.length;){let t=e[a];if(t===`\\`){a+=2;continue}if(t===r){o=e.slice(i,a);break}a++}return o===null?null:o.replace(/\\(.)/g,(e,t)=>t===`n`?`
11
+ import{t as e}from"./rolldown-runtime-DElgkk48.mjs";import{statSync as t}from"node:fs";import{basename as n,dirname as r,join as i,relative as a,resolve as o,sep as s}from"node:path";import{mkdir as c,readFile as l,readdir as u,stat as d,unlink as f,writeFile as p}from"node:fs/promises";import{parseSync as m}from"oxc-parser";import{globSync as h}from"glob";import{groupAssetKeys as g}from"@forinda/kickjs";const _=[`classes`,`tokens`,`injects`,`pluginsAndAdapters`,`augmentations`,`contextKeys`,`routeFlags`,`routes`,`moduleMounts`,`globPatterns`];function v(e){if(!e||typeof e!=`object`)return!1;let t=e;return _.every(e=>Array.isArray(t[e]))}var y=class e{path;prev;next=new Map;nextSig=new Map;constructor(e,t){this.path=e,this.prev=t}static async load(t){let n=i(t,`scan.json`),r=new Map;try{let e=await l(n,`utf-8`),t=JSON.parse(e);if(t.version===3&&t.files)for(let[e,n]of Object.entries(t.files))n&&typeof n.sig==`string`&&v(n.extract)&&r.set(e,n)}catch{}return new e(n,r)}static async signature(e){try{let t=await d(e);return`${t.mtimeMs}:${t.size}`}catch{return null}}get(e,t){let n=this.prev.get(e);return n&&n.sig===t?n.extract:null}set(e,t,n){this.next.set(e,n),this.nextSig.set(e,t)}cachedFiles(){return[...this.prev.keys()]}peek(e){return this.prev.get(e)?.extract??null}carry(e){let t=this.prev.get(e);return t?(this.next.set(e,t.extract),this.nextSig.set(e,t.sig),!0):!1}async save(){let e={};for(let[t,n]of this.next){let r=this.nextSig.get(t);r&&(e[t]={sig:r,extract:n})}let t={version:3,files:e};try{await c(r(this.path),{recursive:!0}),await p(this.path,JSON.stringify(t),`utf-8`)}catch{}}};let b=null;function x(){return b??=new Set(L),b}const S=new Set([`Get`,`Post`,`Put`,`Delete`,`Patch`]);function C(e){return typeof e==`object`&&!!e&&typeof e.type==`string`}function w(e,t){if(Array.isArray(e)){for(let n of e)w(n,t);return}if(C(e)){t(e);for(let n of Object.keys(e)){if(n===`type`)continue;let r=e[n];typeof r==`object`&&r&&w(r,t)}}}function T(e){if(!C(e))return null;if(e.type===`Literal`&&typeof e.value==`string`)return e.value;if(e.type===`TemplateLiteral`){let t=e.quasis,n=e.expressions;if(t?.length===1&&(n?.length??0)===0){let e=t[0].value?.cooked;return typeof e==`string`?e:null}}return null}function E(e){return C(e)&&e.type===`Identifier`?e.name:null}function D(e){return E(e.callee)}function O(e,t){if(!e||e.type!==`ObjectExpression`)return null;for(let n of e.properties??[]){if(n.type!==`Property`)continue;let e=n.key;if((E(e)??(e.type===`Literal`?String(e.value):T(e)))===t)return n.value}return null}function k(e){let t=e.arguments?.[0];return C(t)&&t.type===`ObjectExpression`?t:null}function A(e,t){let n=O(e,t);if(!C(n)||n.type!==`ArrayExpression`)return[];let r=[];for(let e of n.elements??[]){let t=T(e);t!==null&&r.push(t)}return r}function ee(e,t){return a(t,e).split(s).join(`/`)}function te(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function ne(e,t){for(let n of e.implements??[]){let e=n.expression??n;if(E(e)===t)return!0;if(e.type===`TSQualifiedName`||e.type===`MemberExpression`){let n=e.right??e.property;if(n&&E(n)===t)return!0}}return!1}function j(e){return e.decorators??[]}function M(e){let t=e.expression;if(!C(t)||t.type!==`CallExpression`)return null;let n=D(t);return n?{name:n,call:t}:null}function re(e){let t=new Map,n=new Set;for(let r of e.body??[]){if(r.type===`ImportDeclaration`){let e=T(r.source)??``;for(let n of r.specifiers??[]){let r=E(n.local);r&&t.set(r,{source:e})}continue}let e=r.type===`VariableDeclaration`?r:r.type===`ExportNamedDeclaration`&&C(r.declaration)?r.declaration:null;if(C(e)&&e.type===`VariableDeclaration`)for(let t of e.declarations??[]){let e=E(t.id);e&&n.add(e)}}return{imports:t,topLevelConsts:n}}function N(e,t){let n=t.imports.get(e);return n?{identifier:e,source:n.source}:t.topLevelConsts.has(e)?{identifier:e,source:``}:{identifier:e,source:null}}function ie(e,t){let n=[];for(let r of e){let e=M(r),i=e?e.name:E(r.expression);if(!i||S.has(i))continue;let a=t.imports.get(i);n.push({identifier:i,source:a?a.source:t.topLevelConsts.has(i)?``:null})}return n}const P=new Set([`bootstrap`,`createWebApp`,`Application`]);function ae(e,t){if(!P.has(e))return!1;let n=t.imports.get(e)?.source;return n===`@forinda/kickjs`||(n?.startsWith(`@forinda/kickjs/`)??!1)}function oe(e,t){let n={refs:[],resolved:!1},r=se(e);if(!r||r.type!==`ArrayExpression`)return n;let i=[];for(let e of r.elements??[]){if(!C(e)||e.type!==`MemberExpression`||E(e.property)!==`registration`)return n;let r=e.object,a=E(r);if(!a&&C(r)&&r.type===`CallExpression`){let e=r.callee;C(e)&&e.type===`MemberExpression`&&E(e.property)===`with`&&(a=E(e.object))}if(!a)return n;let o=t.imports.get(a);i.push({identifier:a,source:o?o.source:t.topLevelConsts.has(a)?``:null})}return{refs:i,resolved:!0}}function se(e){let t=e.value??e;if(!C(t))return null;if(t.type===`ArrayExpression`)return t;let n=t.body;if(!C(n))return null;if(n.type!==`BlockStatement`)return n;let r=(n.body??[]).filter(e=>e.type===`ReturnStatement`);if(r.length!==1)return null;let i=r[0].argument;return C(i)?i:null}function F(e,t,n){let r=E(O(e,t));return r?N(r,n):null}function ce(e,t){for(let n of e){let e=M(n);if(!e||e.name!==`ApiQueryParams`)continue;let r=e.call.arguments?.[0],i=null;if(C(r)&&r.type===`ObjectExpression`)i=r;else{let e=E(r);if(e){let n=t.get(e);n&&n.type===`ObjectExpression`&&(i=n)}}return{filterable:A(i,`filterable`),sortable:A(i,`sortable`),searchable:A(i,`searchable`)}}return null}function I(e,t,n){let r;try{let n=m(t,e);if(n.errors.length>0)return null;r=n.program}catch{return null}let i=ee(t,n),a=re(r),o=[],s=[],c=[],l=[],u=[],d=[],f=[],p=new Set,h=[],g=[],_=[],v=new Set,y=new Set,b=new Map;w(r,e=>{if(e.type!==`VariableDeclarator`)return;let t=E(e.id),n=e.init;t&&C(n)&&b.set(n,t)});let A=new Set,N=new Map;for(let e of r.body??[]){let t=e.type===`VariableDeclaration`?e:e.type===`ExportNamedDeclaration`&&C(e.declaration)?e.declaration:null;if(C(t)&&t.type===`VariableDeclaration`)for(let e of t.declarations??[]){let t=E(e.id);t&&C(e.init)&&N.set(t,e.init)}}let P=[];for(let e of r.body??[])if(e.type===`ExportNamedDeclaration`&&C(e.declaration)){let t=e.declaration;t.type===`ClassDeclaration`&&P.push({cls:t,isDefault:!1})}else if(e.type===`ExportDefaultDeclaration`&&C(e.declaration)){let t=e.declaration;t.type===`ClassDeclaration`&&P.push({cls:t,isDefault:!0})}for(let{cls:e,isDefault:n}of P){let r=E(e.id);if(!r)continue;let a=null;for(let t of j(e)){let e=M(t);if(e&&x().has(e.name)){a=e.name;break}}a?o.push({className:r,decorator:a,filePath:t,relativePath:i,isDefault:n}):ne(e,`AppModule`)&&o.push({className:r,decorator:`Module`,filePath:t,relativePath:i,isDefault:n})}for(let e of r.body??[]){if(e.type!==`ExportNamedDeclaration`||!C(e.declaration))continue;let n=e.declaration;if(n.type===`VariableDeclaration`)for(let e of n.declarations??[]){let n=E(e.id),r=e.init;n&&C(r)&&r.type===`CallExpression`&&D(r)===`defineModule`&&(o.some(e=>e.className===n)||o.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!1}))}}w(r,n=>{if(n.type===`VariableDeclarator`){let e=n.init;if(C(e)&&e.type===`CallExpression`&&D(e)===`createToken`){let r=T(e.arguments?.[0]);r!==null&&(A.add(e),s.push({name:r,variable:E(n.id),filePath:t,relativePath:i}))}return}if(n.type!==`CallExpression`){if(n.type===`Decorator`){let e=M(n);if(e?.name===`Inject`){let n=T(e.call.arguments?.[0]);n!==null&&c.push({name:n,filePath:t,relativePath:i})}}return}let r=n.callee,a=D(n);if(a===`createToken`&&!A.has(n)){let e=T(n.arguments?.[0]);e!==null&&s.push({name:e,variable:null,filePath:t,relativePath:i});return}if(a===`defineAdapter`||a===`definePlugin`){let e=T(O(k(n),`name`));if(e!==null){let n=a===`definePlugin`?`plugin`:`adapter`,r=`${a}::${e}::${t}`;v.has(r)||(v.add(r),l.push({kind:n,name:e,filePath:t,relativePath:i}))}return}if(a===`defineAugmentation`){let e=n.arguments??[],r=T(e[0]);if(r!==null){let n=C(e[1])&&e[1].type===`ObjectExpression`?e[1]:null;u.push({name:r,description:T(O(n,`description`)),example:T(O(n,`example`)),filePath:t,relativePath:i})}return}if(a===`defineRouteFlag`){let r=T(n.arguments?.[0]);if(r!==null&&!p.has(r)){p.add(r);let a=n.typeArguments,o=a?e.slice(a.start,a.end):null;f.push({name:r,valueType:o?o.slice(1,-1).trim():null,filePath:t,relativePath:i})}return}if(a===`defineContextDecorator`||a===`defineHttpContextDecorator`){let e=T(O(k(n),`key`));e!==null&&!y.has(e)&&(y.add(e),d.push({key:e,exportName:b.get(n)??null,filePath:t,relativePath:i}));return}if(C(r)&&r.type===`CallExpression`){let e=r.callee;if(C(e)&&e.type===`MemberExpression`&&E(e.property)===`withParams`){let r=E(e.object);if(r===`defineContextDecorator`||r===`defineHttpContextDecorator`){let e=T(O(k(n),`key`));e!==null&&!y.has(e)&&(y.add(e),d.push({key:e,exportName:b.get(n)??null,filePath:t,relativePath:i}))}}return}if(C(r)&&r.type===`MemberExpression`&&E(r.property)===`glob`){let e=r.object;C(e)&&e.type===`MetaProperty`&&w(n.arguments,e=>{let t=T(e);t!==null&&_.push(t)})}});let se=[];w(r,e=>{if(e.type===`ClassDeclaration`||e.type===`ClassExpression`){let t=E(e.id);t&&se.push({cls:e,className:t})}});for(let{cls:e,className:n}of se){let r=o.find(e=>e.className===n),s=e.body?.body;if(ne(e,`AppAdapter`))for(let e of s??[]){if(e.type!==`PropertyDefinition`||E(e.key)!==`name`)continue;let n=T(e.value);if(n===null)continue;let r=`class::${n}::${t}`;v.has(r)||(v.add(r),l.push({kind:`adapter`,name:n,filePath:t,relativePath:i}));break}for(let o of s??[]){if(o.type!==`MethodDefinition`)continue;let s=E(o.key);if(!s)continue;if(s===`routes`){le(o.value,g);continue}if(!r)continue;let c=j(o),l=ce(c,N),u=[...ie(j(e),a),...ie(c,a)];for(let e of c){let o=M(e);if(!o||!S.has(o.name))continue;let c=o.call.arguments??[],d=T(c[0]),f=d&&d.length>0?d:`/`,p=C(c[1])&&c[1].type===`ObjectExpression`?c[1]:null;h.push({controller:n,method:s,httpMethod:o.name.toUpperCase(),path:f,pathParams:te(f),queryFilterable:l?.filterable??null,querySortable:l?.sortable??null,querySearchable:l?.searchable??null,bodySchema:F(p,`body`,a),querySchema:F(p,`query`,a),paramsSchema:F(p,`params`,a),responseSchema:F(p,`response`,a),filePath:t,relativePath:i,controllerIsDefaultExport:r.isDefault,appliedDecorators:u,mountedPath:f})}}}w(r,e=>{if(e.type!==`Property`||E(e.key)!==`routes`)return;let t=e.value;C(t)&&(t.type===`FunctionExpression`||t.type===`ArrowFunctionExpression`)&&le(t,g)});let I=new Set,L=new Set;w(r,e=>{let t=e.type===`Property`&&E(e.key)===`contributors`,n=e.type===`MethodDefinition`&&E(e.key)===`contributors`;(t||n)&&L.add(e)});let R=e=>e.properties??e.body?.body??[];w(r,e=>{if(e.type!==`ObjectExpression`&&e.type!==`ClassDeclaration`)return;let t=R(e);if(t.map(e=>E(e.key)).includes(`routes`))for(let e of t)E(e.key)===`contributors`&&I.add(e)});let z=new Set;w(r,e=>{let t=e.type===`CallExpression`?D(e):e.type===`NewExpression`?E(e.callee):null;if(t===null||!ae(t,a))return;let n=k(e);if(n)for(let e of n.properties??[])e.type===`Property`&&E(e.key)===`contributors`&&z.add(e)});let B=e=>{if(e.size===0)return null;let n=[],r=!0;for(let t of e){let e=oe(t,a);e.resolved||(r=!1),n.push(...e.refs)}return{refs:n,resolved:r,filePath:t}},V=B(I),H=B(z);return{classes:o,tokens:s,injects:c,pluginsAndAdapters:l,augmentations:u,contextKeys:d,routeFlags:f,routes:h,moduleMounts:g,globPatterns:/\.module\.[mc]?[tj]sx?$/.test(t)?_:[],moduleContributors:V,appContributors:H,hasNonDecoratorContributors:L.size>I.size+z.size}}function le(e,t){let n=[],r=[];w(e.body,e=>{if(e.type!==`Property`)return;let t=E(e.key);if(t===`path`){let t=T(e.value);t!==null&&n.push(t)}else if(t===`controller`){let t=E(e.value);t&&/^[A-Z]/.test(t)&&r.push(t)}});let i=Math.min(n.length,r.length);for(let e=0;e<i;e++)t.push({controller:r[e],mountPath:n[e]})}const L=[`Service`,`Controller`,`Repository`,`Injectable`,`Component`,`Module`],R=[`.ts`,`.tsx`,`.mts`,`.cts`],z=[`node_modules`,`.kickjs`,`dist`,`build`,`.test.`,`.spec.`,`.d.ts`],B=new RegExp(String.raw`@(${L.join(`|`)})\s*\([^)]*\)`+String.raw`(?:\s*@[A-Z]\w*(?:\s*\([^)]*\))?)*`+String.raw`\s*export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`,`g`),V=new RegExp(String.raw`export\s+(default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppModule\b`,`g`),H=/export\s+const\s+(\w+)\s*(?::\s*[^=]+)?=\s*defineModule\s*(?:<[^>]*>)?\s*\(/g,ue=/(?:export\s+)?const\s+(\w+)\s*(?::\s*[^=]+)?=\s*createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,de=/createToken\s*(?:<[^>]*>)?\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,fe=/@Inject\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g,U=/\b(defineAdapter|definePlugin)\s*(?:<[^>]*>)?\s*\(/g,W=/(?:(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*(?::[^=]+)?=\s*)?\b(?:defineContextDecorator|defineHttpContextDecorator)\s*(?:\.withParams\s*<(?:[^<>]|<[^<>]*>)*>\s*\(\s*\))?\s*(?:<(?:[^<>]|<[^<>]*>)*>)?\s*\(/g,pe=new RegExp(String.raw`export\s+(?:default\s+)?(?:abstract\s+)?class\s+(\w+)`+String.raw`(?:\s+extends\s+\w+(?:<[^>]*>)?)?`+String.raw`\s+implements\s+[^{]*\bAppAdapter\b`,`g`),me=/\bname\s*(?::\s*[^=]+)?=\s*['"`]([^'"`]+)['"`]/,he=/\bdefineAugmentation\s*\(\s*['"`]([^'"`]+)['"`]\s*(,\s*\{)?/g,G=new RegExp(String.raw`@(${[`Get`,`Post`,`Put`,`Delete`,`Patch`].join(`|`)})\s*\(`,`g`);function K(e,t){let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`(`)n++;else if(t===`)`&&(n--,n===0))return r}return-1}function ge(e,t){let n=t;for(;n<e.length;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`@`)break;let t=e.slice(n).match(/^@([A-Z]\w*)/);if(!t)break;for(n+=t[0].length;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]===`(`){let t=K(e,n);if(t<0)return null;n=t+1}}for(;n<e.length&&/\s/.test(e[n]);)n++;for(let t of[`public`,`private`,`protected`])if(e.slice(n,n+t.length)===t&&/\s/.test(e.charAt(n+t.length))){for(n+=t.length;n<e.length&&/\s/.test(e[n]);)n++;break}if(e.slice(n,n+5)===`async`&&/\s/.test(e.charAt(n+5)))for(n+=5;n<e.length&&/\s/.test(e[n]);)n++;let r=e.slice(n).match(/^([a-zA-Z_]\w*)\s*\(/);return r?{methodName:r[1],endPos:n+r[0].length}:null}function _e(e){return(e.match(/:([a-zA-Z_]\w*)/g)??[]).map(e=>e.slice(1))}function ve(e,t){let n=e.endsWith(`/`)?e.slice(0,-1):e;return!t||t===`/`?n||`/`:n+(t.startsWith(`/`)?t:`/`+t)||`/`}const ye=/\b(?:public\s+|private\s+|protected\s+)?routes\s*\([^)]*\)\s*(?::\s*[A-Za-z_][\w<>[\]\s,|]*\s*)?\{/g,be=/\bpath\s*:\s*['"`]([^'"`]*)['"`]/g,xe=/\bcontroller\s*:\s*([A-Z]\w*)\b/g,Se=/\bimport\.meta\.glob\s*\(/g;function Ce(e){let t=[];for(Se.lastIndex=0;Se.exec(e)!==null;){let n=Se.lastIndex-1,r=K(e,n);if(r<0)continue;let i=e.slice(n+1,r),a=/['"`]([^'"`]+)['"`]/g,o;for(;(o=a.exec(i))!==null;)t.push(o[1])}return t}function we(e){let t=e.replace(/[.+^$()|[\]\\]/g,`\\$&`).replace(/\?/g,`.`).replace(/\*\*\//g,`___DOUBLESTAR_SLASH___`).replace(/\*\*/g,`___DOUBLESTAR___`).replace(/\*/g,`[^/]*`).replace(/___DOUBLESTAR_SLASH___/g,`(?:.+/)?`).replace(/___DOUBLESTAR___/g,`.*`);return RegExp(`^`+t+`$`)}function Te(e,t){let n=e.startsWith(`./`)?e:`./`+e,r=!1;for(let e of t){let t=e.startsWith(`!`);we(t?e.slice(1):e).test(n)&&(r=!t)}return r}function Ee(e){let t=[];ye.lastIndex=0;let n;for(;(n=ye.exec(e))!==null;){let r=e.indexOf(`{`,n.index+n[0].length-1);if(r<0)continue;let i=Ie(e,r);if(i<0)continue;let a=e.slice(r+1,i),o=[];be.lastIndex=0;let s;for(;(s=be.exec(a))!==null;)o.push(s[1]??``);let c=[];xe.lastIndex=0;let l;for(;(l=xe.exec(a))!==null;)c.push(l[1]);let u=Math.min(o.length,c.length);for(let e=0;e<u;e++)t.push({controller:c[e],mountPath:o[e]})}return t}function q(e,t){let n=new RegExp(String.raw`\b${t}\s*:\s*([A-Za-z_$][\w$]*)`,`g`).exec(e);return n?n[1]:null}function J(e,t){let n=new RegExp(String.raw`import\s*(?:type\s+)?\{[^}]*\b${t}\b[^}]*\}\s*from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(n)return n[1];let r=new RegExp(String.raw`import\s+(?:type\s+)?${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);if(r)return r[1];let i=new RegExp(String.raw`import\s*\*\s*as\s+${t}\s+from\s*['"\`]([^'"\`]+)['"\`]`).exec(e);return i?i[1]:new RegExp(String.raw`(?:^|\n)\s*(?:export\s+)?const\s+${t}\b`).test(e)?``:null}function De(e,t){let n=/@ApiQueryParams\s*\(\s*([\s\S]*?)\s*\)\s*$/.exec(e);if(!n){let n=/@ApiQueryParams\s*\(([\s\S]*?)\)/.exec(e);return n?Oe(n[1].trim(),t):null}return Oe(n[1].trim(),t)}function Oe(e,t){if(e.startsWith(`{`))return Ae(e);let n=/^([A-Za-z_]\w*)/.exec(e);if(n){let e=n[1],r=new RegExp(String.raw`const\s+${e}\s*(?::\s*[^=]+)?=\s*(\{[\s\S]*?\n\})`,`m`).exec(t);if(r)return Ae(r[1])}return{filterable:[],sortable:[],searchable:[]}}function ke(e,t){let n=new RegExp(String.raw`${t}\s*:\s*\[([\s\S]*?)\]`).exec(e);return n?Array.from(n[1].matchAll(/['"`]([^'"`]+)['"`]/g)).map(e=>e[1]):[]}function Ae(e){return{filterable:ke(e,`filterable`),sortable:ke(e,`sortable`),searchable:ke(e,`searchable`)}}async function je(e,t){let n=t.extensions??R,r=t.exclude??z,o=[],s;try{s=await u(e,{withFileTypes:!0,encoding:`utf-8`})}catch{return o}for(let c of s){let s=i(e,c.name),l=a(t.cwd,s);r.some(e=>l.includes(e))||(c.isDirectory()?o.push(...await je(s,t)):c.isFile()&&n.some(e=>c.name.endsWith(e))&&o.push(s))}return o}function Y(e,t){return a(t,e).split(s).join(`/`)}function Me(e,t,n){let r=[],i=Y(t,n);B.lastIndex=0;let a;for(;(a=B.exec(e))!==null;){let[,e,n,o]=a;r.push({className:o,decorator:e,filePath:t,relativePath:i,isDefault:!!n})}V.lastIndex=0;let o;for(;(o=V.exec(e))!==null;){let[,e,n]=o;r.some(e=>e.className===n&&e.filePath===t)||r.push({className:n,decorator:`Module`,filePath:t,relativePath:i,isDefault:!!e})}H.lastIndex=0;let s;for(;(s=H.exec(e))!==null;){let[,e]=s;r.some(n=>n.className===e&&n.filePath===t)||r.push({className:e,decorator:`Module`,filePath:t,relativePath:i,isDefault:!1})}return r}function Ne(e,t,n){let r=[],i=Y(t,n),a=new Set;ue.lastIndex=0;let o;for(;(o=ue.exec(e))!==null;){let[e,n,s]=o;a.add(e),r.push({name:s,variable:n,filePath:t,relativePath:i})}for(de.lastIndex=0;(o=de.exec(e))!==null;)a.has(o[0])||r.push({name:o[1],variable:null,filePath:t,relativePath:i});return r}function Pe(e,t,n,r,i=new Map){let a=[];if(r.length===0)return a;let o=Y(t,n),s=[];for(let t of r){let n=new RegExp(String.raw`class\s+${t.className}\b`).exec(e);n?.index!==void 0&&s.push({cls:t,start:n.index})}s.sort((e,t)=>e.start-t.start);for(let n=0;n<s.length;n++){let{cls:r,start:c}=s[n],l=n+1<s.length?s[n+1].start:e.length,u=e.slice(c,l);G.lastIndex=0;let d;for(;(d=G.exec(u))!==null;){let n=d[1],s=d.index,c=G.lastIndex-1,l=K(u,c);if(l<0)continue;let f=u.slice(c+1,l),p=f.match(/^\s*['"`]([^'"`]*)['"`]/),m=p&&p[1].length>0?p[1]:`/`,h=ge(u,l+1);if(!h)continue;let{methodName:g,endPos:_}=h;G.lastIndex=_;let v=De(u.slice(s,_),e),y=q(f,`body`),b=q(f,`query`),x=q(f,`params`),S=q(f,`response`),C=i.get(r.className)??``,w=C?ve(C,m):m;a.push({controller:r.className,method:g,httpMethod:n.toUpperCase(),path:m,pathParams:_e(w),queryFilterable:v?.filterable??null,querySortable:v?.sortable??null,querySearchable:v?.searchable??null,bodySchema:y?{identifier:y,source:J(e,y)}:null,querySchema:b?{identifier:b,source:J(e,b)}:null,paramsSchema:x?{identifier:x,source:J(e,x)}:null,responseSchema:S?{identifier:S,source:J(e,S)}:null,filePath:t,relativePath:o,controllerIsDefaultExport:r.isDefault,mountedPath:w})}}return a}function Fe(e,t,n){let r=[],i=Y(t,n);fe.lastIndex=0;let a;for(;(a=fe.exec(e))!==null;)r.push({name:a[1],filePath:t,relativePath:i});return r}function Ie(e,t){let n=1;for(let r=t+1;r<e.length;r++){let t=e[r];if(t===`{`)n++;else if(t===`}`&&(n--,n===0))return r}return-1}function Le(e,t,n){let r=[],i=Y(t,n),a=new Set;U.lastIndex=0;let o;for(;(o=U.exec(e))!==null;){let n=o[1],s=U.lastIndex-1,c=K(e,s);if(c<0)continue;let l=e.slice(s+1,c),u=/\bname\s*:\s*['"`]([^'"`]+)['"`]/.exec(l);if(!u)continue;let d=u[1],f=`${n}::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:n===`definePlugin`?`plugin`:`adapter`,name:d,filePath:t,relativePath:i}))}pe.lastIndex=0;let s;for(;(s=pe.exec(e))!==null;){let n=s.index,o=e.indexOf(`{`,n);if(o<0)continue;let c=Ie(e,o);if(c<0)continue;let l=e.slice(o+1,c),u=me.exec(l);if(!u)continue;let d=u[1],f=`class::${d}::${t}`;a.has(f)||(a.add(f),r.push({kind:`adapter`,name:d,filePath:t,relativePath:i}))}return r}function Re(e,t,n){let r=[],i=Y(t,n),a=new Set;W.lastIndex=0;let o;for(;(o=W.exec(e))!==null;){let n=W.lastIndex-1,s=K(e,n);if(s<0)continue;let c=e.slice(n+1,s),l=/\bkey\s*:\s*['"`]([^'"`]+)['"`]/.exec(c);if(!l)continue;let u=l[1];a.has(u)||(a.add(u),r.push({key:u,exportName:o[1]??null,filePath:t,relativePath:i}))}return r}function ze(e,t,n){let r=[],i=Y(t,n);he.lastIndex=0;let a;for(;(a=he.exec(e))!==null;){let n=a[1],o=null,s=null;if(a[2]){let t=e.indexOf(`{`,a.index+a[0].length-1);if(t>=0){let n=Ie(e,t);if(n>=0){let r=e.slice(t+1,n);o=Be(r,`description`),s=Be(r,`example`)}}}r.push({name:n,description:o,example:s,filePath:t,relativePath:i})}return r}function Be(e,t){let n=RegExp(`\\b${t}\\s*:\\s*(['"\`])`,`g`).exec(e);if(!n)return null;let r=n[1],i=n.index+n[0].length,a=i,o=null;for(;a<e.length;){let t=e[a];if(t===`\\`){a+=2;continue}if(t===r){o=e.slice(i,a);break}a++}return o===null?null:o.replace(/\\(.)/g,(e,t)=>t===`n`?`
12
12
  `:t===`t`?` `:t===`r`?`\r`:t)}const Ve=[`src/config/index.ts`,`src/config/env.ts`,`src/config.ts`,`src/env.ts`];async function He(e,t){let n=t===`src/env.ts`?Ve:[t];for(let t of n){let n=o(e,t),r;try{r=await l(n,`utf-8`)}catch{continue}if((/\bdefineEnv\s*\(/.test(r)||/\bfrom(Zod|Valibot|Yup)\s*\(/.test(r))&&/export\s+default\b/.test(r)&&!/export\s+default\s+loadEnvFromSchema\s*\(/.test(r))return{filePath:n,relativePath:Y(n,e)}}return null}function Ue(e){let t=new Map;for(let n of e){let e=t.get(n.className)??[];e.push(n),t.set(n.className,e)}let n=[];for(let[e,r]of t)new Set(r.map(e=>e.filePath)).size>1&&n.push({className:e,classes:r});return n.sort((e,t)=>e.className.localeCompare(t.className)),n}const We=new Set([`Controller`,`Service`,`Repository`,`Injectable`,`Component`,`Module`,`Middleware`,`ApiQueryParams`,`Public`,`Roles`,`Cron`,`Cacheable`,`CacheEvict`,`FileUpload`,`Asset`,`Builder`,`PostConstruct`,`PreDestroy`,`Value`,`Inject`,`Autowired`]);function X(e){return e.split(s).join(`/`).replace(/\.[mc]?[tj]sx?$/,``)}function Ge(e,t,n){let i=X(n);if(t===``)return i===X(e);if(t.startsWith(`.`)){let n=X(o(r(e),t));return i===n||i===`${n}/index`}let a=t.replace(/^[@~#]\//,``);if(a===t&&t.startsWith(`@`))return!1;let s=X(a);return i===s||i.endsWith(`/${s}`)}function Ke(e){let t=new Map,n=new Map;for(let t of e)if(t)for(let{controller:e}of t.moduleMounts)n.set(e,(n.get(e)??0)+1);for(let r of e)if(r?.moduleContributors)for(let{controller:e}of r.moduleMounts){if((n.get(e)??0)>1){t.set(e,`ambiguous`);continue}let i=t.get(e);t.set(e,i===void 0?r.moduleContributors:`ambiguous`)}return t}function qe(e,t,n,r=new Map,i=[]){if(n){for(let t of e)t.contextKeys=null;return}let a=new Map;for(let e of t){if(!e.exportName)continue;let t=a.get(e.exportName);t?t.push(e):a.set(e.exportName,[e])}for(let t of e){let e=t.appliedDecorators;if(!e){t.contextKeys=null;continue}let n=new Set,o=!0,s=(e,t)=>{if(t.source===null)return null;let n=(a.get(t.identifier)??[]).filter(n=>Ge(e,t.source,n.filePath));return n.length===1?n[0].key:null};for(let r of e){if(We.has(r.identifier))continue;let e=s(t.filePath,r);if(e===null){o=!1;break}n.add(e)}if(o)for(let e of i){if(!e.resolved){o=!1;break}for(let t of e.refs){let r=s(e.filePath,t);if(r===null){o=!1;break}n.add(r)}if(!o)break}if(o){let e=r.get(t.controller);if(e===`ambiguous`)o=!1;else if(e){if(!e.resolved)o=!1;else for(let t of e.refs){let r=s(e.filePath,t);if(r===null){o=!1;break}n.add(r)}}}t.contextKeys=o?[...n].toSorted():null}}const Je=/\bcontributors\s*(?::|\()/;function Ye(e,t,n){return I(e,t,n)||{...Xe(e,t,n),hasNonDecoratorContributors:Je.test(e)}}function Xe(e,t,n){let r=Me(e,t,n);return{classes:r,tokens:Ne(e,t,n),injects:Fe(e,t,n),pluginsAndAdapters:Le(e,t,n),routeFlags:[],augmentations:ze(e,t,n),contextKeys:Re(e,t,n),routes:Pe(e,t,n,r,new Map),moduleMounts:Ee(e),globPatterns:/\.module\.[mc]?[tj]sx?$/.test(t)?Ce(e):[],hasNonDecoratorContributors:!1}}async function Ze(e,t,n){let r=n?await y.signature(e):null;if(n&&r){let t=n.get(e,r);if(t)return n.set(e,r,t),t}let i;try{i=await l(e,`utf-8`)}catch{return null}let a=Ye(i,e,t);return n&&r&&n.set(e,r,a),a}async function Qe(e,t,n){let r=[],i=0,a=Array.from({length:Math.min(t,e.length)},async()=>{for(;;){let t=i++;if(t>=e.length)return;r[t]=await n(e[t],t)}});return await Promise.all(a),r}async function Z(e){let t=(await je(o(e.root),e)).toSorted(),n=e.cacheDir?await y.load(e.cacheDir):null,r=tt(t,await Qe(t,16,t=>Ze(t,e.cwd,n))),i=await He(e.cwd,e.envFile??`src/env.ts`);return n&&await n.save(),{...r,env:i}}function $e(e,t,n){let r=n.extensions??R,i=n.exclude??z;if(!e.startsWith(t+s)&&e!==t||!r.some(t=>e.endsWith(t)))return!1;let o=a(n.cwd,e);return!i.some(e=>o.includes(e))}async function et(e,t){if(!e.cacheDir)return Z(e);let n=o(e.root),r=await y.load(e.cacheDir),i=r.cachedFiles();if(i.length===0)return Z(e);let a=new Set(t.removed.map(t=>o(e.cwd,t))),s=t.changed.map(t=>o(e.cwd,t)).filter(t=>!a.has(t)&&$e(t,n,e)),c=new Set(s),u=new Set(i);for(let e of c)u.add(e);for(let e of a)u.delete(e);let d=new Map;await Qe(s,16,async t=>{if(!u.has(t))return;let n=await y.signature(t),i;try{i=await l(t,`utf-8`)}catch{u.delete(t);return}let a=Ye(i,t,e.cwd);d.set(t,a),n&&r.set(t,n,a)});let f=[...u].toSorted(),p=tt(f,f.map(e=>d.get(e)||(r.carry(e),r.peek(e)))),m=await He(e.cwd,e.envFile??`src/env.ts`);return await r.save(),{...p,env:m}}function tt(e,t){let n=[],r=[],i=[],a=[],o=[],c=[],l=[],u=[],d=new Map;for(let e of t)if(e)for(let{controller:t,mountPath:n}of e.moduleMounts)d.has(t)||d.set(t,n);let f=new Map;for(let s=0;s<e.length;s++){let p=t[s];if(p){n.push(...p.classes),i.push(...p.tokens),a.push(...p.injects),o.push(...p.pluginsAndAdapters),c.push(...p.augmentations),l.push(...p.contextKeys),u.push(...p.routeFlags),p.globPatterns.length>0&&f.set(e[s],p.globPatterns);for(let e of p.routes){let t=d.get(e.controller);if(t){let n=ve(t,e.path);r.push({...e,pathParams:_e(n),mountedPath:n})}else r.push({...e,mountedPath:e.mountedPath??e.path})}}}qe(r,l,t.some(e=>e?.hasNonDecoratorContributors===!0),Ke(t),t.flatMap(e=>e?.appContributors?[e.appContributors]:[]));let p=[];for(let[e,t]of f){if(!/\.module\.[mc]?[tj]sx?$/.test(e)||t.length===0)continue;let r=e.replaceAll(s,`/`),i=r.slice(0,r.lastIndexOf(`/`));for(let a of n){if(a.decorator===`Module`)continue;let n=a.filePath.replaceAll(s,`/`);n.startsWith(i+`/`)&&n!==r&&(Te(n.slice(i.length+1),t)||p.push({className:a.className,filePath:a.filePath,relativePath:a.relativePath,moduleFilePath:e,decorator:a.decorator}))}}n.sort((e,t)=>e.className===t.className?e.relativePath.localeCompare(t.relativePath):e.className.localeCompare(t.className)),i.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),a.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),r.sort((e,t)=>e.controller.localeCompare(t.controller)||e.method.localeCompare(t.method)),o.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),c.sort((e,t)=>e.name.localeCompare(t.name)||e.relativePath.localeCompare(t.relativePath)),l.sort((e,t)=>e.key.localeCompare(t.key)||e.relativePath.localeCompare(t.relativePath));let m=Ue(n);return p.sort((e,t)=>e.relativePath.localeCompare(t.relativePath)||e.className.localeCompare(t.className)),{classes:n,routes:r,tokens:i,injects:a,collisions:m,pluginsAndAdapters:o,augmentations:c,contextKeys:l,routeFlags:u,orphanedClasses:p}}function nt(e){let t=e.lastIndexOf(`.`);return t<=0?{stem:e,ext:``}:{stem:e.slice(0,t),ext:e.slice(t+1)}}function rt(e){let t=e.replaceAll(`\\`,`/`),{stem:n,ext:r}=nt(t.slice(t.lastIndexOf(`/`)+1)),i=r||`ts`,a=n.lastIndexOf(`.`);return a>0?`./**/*.${n.slice(a+1)}.${i}`:`./**/*.${i}`}function it(e){let t=new Set;for(let n of e)t.add(rt(n.relativePath));return[...t].toSorted()}function at(e,t){let n=0,r=null;for(let i=t;i<e.length;i++){let t=e[i];if(r){if(t===`\\`){i++;continue}t===r&&(r=null);continue}if(t===`'`||t===`"`||t==="`")r=t;else if(t===`(`)n++;else if(t===`)`&&(n--,n===0))return i}return-1}function ot(e,t,n,r){let i=null;for(let a=n;a<r;a++){let n=e[a];if(i){if(n===`\\`){a++;continue}n===i&&(i=null);continue}if(n===`'`||n===`"`||n==="`")i=n;else if(n===t)return a}return-1}function st(e,t){let n=0,r=null;for(let i=t;i<e.length;i++){let t=e[i];if(r){if(t===`\\`){i++;continue}t===r&&(r=null);continue}if(t===`'`||t===`"`||t==="`")r=t;else if(t===`[`)n++;else if(t===`]`&&(n--,n===0))return i}return-1}function ct(e){let t=/\bimport\.meta\.glob\s*\(/g,n=[],r;for(;(r=t.exec(e))!==null;){let t=e.indexOf(`(`,r.index);if(t<0)continue;let i=at(e,t);i<0||n.push({start:r.index,open:t,close:i})}return n}function lt(e,t){let n=ct(e);if(n.length===0)return null;let r=n.find(t=>/\beager\s*:\s*true\b/.test(e.slice(t.open,t.close+1)))??n[0],i=e.slice(r.start,r.close+1),a=new Set(Ce(i).map(e=>e.startsWith(`!`)?e.slice(1):e)),o=t.filter(e=>!a.has(e));if(o.length===0)return null;let s=o.map(e=>`'${e}'`).join(`, `),c=ot(e,`[`,r.open,r.close);if(c>=0){let t=st(e,c);if(t<0||t>r.close)return null;let n=e.slice(0,t);return n+(/[[,]\s*$/.test(n)?``:`, `)+s+e.slice(t)}let l=/(['"`])((?:\\.|(?!\1).)*)\1/,u=e.slice(r.open+1,r.close),d=l.exec(u);if(!d)return null;let f=r.open+1+d.index,p=f+d[0].length;return e.slice(0,f)+`[${d[0]}, ${s}]`+e.slice(p)}const Q="/* 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",ut=new Set([`Service`,`Repository`,`Injectable`,`Component`]);var dt=class extends Error{collisions;constructor(e){super(ft(e)),this.name=`TokenCollisionError`,this.collisions=e}};function ft(e){let t=[`kick typegen: token collision detected`];for(let n of e){t.push(``),t.push(` ${n.classes.length} classes named '${n.className}':`);for(let e of n.classes)t.push(` - ${e.relativePath}`)}return t.push(``),t.push(`Resolutions:`),t.push(` (a) Rename one of the classes`),t.push(` (b) Use createToken<T>('namespaced/Name') and import the token explicitly — see @forinda/kickjs`),t.push(` (c) Pass --allow-duplicates to namespace the registry keys automatically`),t.push(` (e.g. 'modules/users/UserService' instead of 'UserService')`),t.join(`
13
13
  `)}function pt(e,t){let n=r(t),i=a(n,e).split(s).join(`/`);return i=i.replace(/\.(ts|tsx|mts|cts)$/i,``),i.startsWith(`.`)||(i=`./`+i),i}function mt(e){let t=e.relativePath.replace(/^src\//,``).replace(/\.(ts|tsx|mts|cts)$/i,``).split(`/`);t.pop();let n=t.join(`/`);return n?`${n}/${e.className}`:e.className}function ht(e,t,n){let r=new Set,i=[];for(let a of e){if(!ut.has(a.decorator))continue;let e=n.has(a.className)?mt(a):a.className;if(r.has(e))continue;r.add(e);let o=pt(a.filePath,t),s=a.isDefault?`import('${o}').default`:`import('${o}').${a.className}`;i.push(` '${e}': ${s}`)}let a=i.length?i.join(`
14
14
  `):" // (no services discovered yet — run `kick g service <name>` to add one)";return`${Q}
@@ -124,8 +124,8 @@ ${Nt(n,` `)}
124
124
 
125
125
  export {}
126
126
  `}const Mt=Symbol(`asset-leaf`);function Nt(e,t){let n=Object.keys(e).toSorted(),r=[];for(let i of n){let n=e[i],a=Pt(i)?i:JSON.stringify(i);n===Mt?r.push(`${t}${a}: () => string`):(r.push(`${t}${a}: {`),r.push(Nt(n,`${t} `)),r.push(`${t}}`))}return r.join(`
127
- `)}function Pt(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function Ft(e){try{return t(e).isDirectory()}catch{return!1}}var It=e({runTypegen:()=>Rt,sweepStaleTypegen:()=>Ht,watchTypegen:()=>Vt,writeTypegenArtifacts:()=>$});function Lt(e){let t=e.cwd??process.cwd();return{cwd:t,srcDir:o(t,e.srcDir??`src`),outDir:o(t,e.outDir??`.kickjs/types`),silent:e.silent??!1,allowDuplicates:e.allowDuplicates??!1,schemaValidator:e.schemaValidator??!1,envFile:e.envFile??`src/env.ts`}}async function Rt(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,envFile:s}=Lt(e),c=Date.now(),l={root:n,cwd:t,cacheDir:e.noCache?void 0:o(t,`.kickjs`,`cache`),envFile:s===!1?void 0:s},u=e.changedFiles?await et(l,e.changedFiles):await Z(l);if(u.collisions.length>0&&!a)throw new dt(u.collisions);let d=At(e.assetMap,t),f=[],p=[];if(e.runPlugins!==!1){try{let{runAllPluginTypegens:n}=await import(`./builtins-DtTYiDg0.mjs`).then(e=>e.n),{loadKickConfig:r}=await import(`./config-F1NW28_P.mjs`).then(e=>e.n);f=await n({cwd:t,config:await r(t),silent:!0,changedFiles:e.changedFiles})}catch(e){if(!i){let t=e instanceof Error?e.message:String(e);console.warn(` kick typegen: plugin pipeline failed (${t}) — continuing`)}}p.push(...await $(r,f,i))}let m=Ot(u.tokens),h=Bt(u,d.count,p),g=Date.now()-c;if(!i){let e=r.replace(t+`/`,``),n=h.resolvedCollisions>0?`, ${h.resolvedCollisions} collisions namespaced`:``,i=h.envWritten?`, env typed`:``,a=h.pluginEntries>0?`, ${h.pluginEntries} plugins/adapters`:``,o=h.augmentationEntries>0?`, ${h.augmentationEntries} augmentations`:``,s=h.assetEntries>0?`, ${h.assetEntries} assets`:``;if(console.log(` kick typegen → ${h.serviceTokens} services, ${h.routeEntries} routes, ${h.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${g}ms)`),m.length>0){console.warn(` kick typegen: ${m.length} token(s) don't match the §22.2 convention:`);for(let e of m){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}}return u.orphanedClasses.length>0&&await zt(u.orphanedClasses,{fix:e.fix??!1,silent:i}),{scan:u,result:h,tokenWarnings:m}}async function zt(e,{fix:t,silent:n}){let r=new Map;for(let t of e){let e=r.get(t.moduleFilePath)??[];e.push(t),r.set(t.moduleFilePath,e)}if(t){let e=0,t=[];for(let[i,a]of r){let r=it(a);try{let a=await l(i,`utf-8`),o=lt(a,r);o&&o!==a?(await p(i,o),e++,n||console.log(` kick typegen --fix: patched ${i}\n + ${r.join(`, `)}`)):t.push(i)}catch{t.push(i)}}if(!n&&(e>0&&console.log(` kick typegen --fix: updated ${e} module glob(s) — re-run typegen to pick up the now-loaded classes.`),t.length>0)){console.warn(` kick typegen --fix: could not auto-patch ${t.length} module(s) (no import.meta.glob() call found) — add the patterns by hand:`);for(let e of t){let t=r.get(e)??[];console.warn(` ${e}: ${it(t).join(`, `)}`)}}return}if(!n){console.warn(` kick typegen: ${e.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let[e,t]of r){for(let e of t)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`);let n=it(t);console.warn(` → add to import.meta.glob([...]) in ${e}:`),console.warn(` ${n.map(e=>`'${e}'`).join(`, `)}`)}console.warn(" → or run `kick typegen --fix` to apply these automatically.")}}function Bt(e,t,n){let r=new Set(e.collisions.map(e=>e.className)),i=e.classes.filter(e=>ut.has(e.decorator)),a=yt(e.classes,e.tokens,e.injects,r);return{registryEntries:i.length,serviceTokens:new Set(a).size,moduleTokens:bt(e.classes).length,routeEntries:e.routes.length,pluginEntries:new Set(e.pluginsAndAdapters.map(e=>e.name)).size,augmentationEntries:new Set(e.augmentations.map(e=>e.name)).size,assetEntries:t,envWritten:e.env!==null,written:n,resolvedCollisions:e.collisions.length}}async function $(e,t,n){await c(e,{recursive:!0}),await p(i(r(e),`.gitignore`),`# Auto-generated by kick typegen
127
+ `)}function Pt(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function Ft(e){try{return t(e).isDirectory()}catch{return!1}}var It=e({runTypegen:()=>Rt,sweepStaleTypegen:()=>Ht,watchTypegen:()=>Vt,writeTypegenArtifacts:()=>$});function Lt(e){let t=e.cwd??process.cwd();return{cwd:t,srcDir:o(t,e.srcDir??`src`),outDir:o(t,e.outDir??`.kickjs/types`),silent:e.silent??!1,allowDuplicates:e.allowDuplicates??!1,schemaValidator:e.schemaValidator??!1,envFile:e.envFile??`src/env.ts`}}async function Rt(e={}){let{cwd:t,srcDir:n,outDir:r,silent:i,allowDuplicates:a,envFile:s}=Lt(e),c=Date.now(),l={root:n,cwd:t,cacheDir:e.noCache?void 0:o(t,`.kickjs`,`cache`),envFile:s===!1?void 0:s},u=e.changedFiles?await et(l,e.changedFiles):await Z(l);if(u.collisions.length>0&&!a)throw new dt(u.collisions);let d=At(e.assetMap,t),f=[],p=[];if(e.runPlugins!==!1){try{let{runAllPluginTypegens:n}=await import(`./builtins-A-wfYHI9.mjs`).then(e=>e.n),{loadKickConfig:r}=await import(`./config-Bz1suLYz.mjs`).then(e=>e.n);f=await n({cwd:t,config:await r(t),silent:!0,changedFiles:e.changedFiles})}catch(e){if(!i){let t=e instanceof Error?e.message:String(e);console.warn(` kick typegen: plugin pipeline failed (${t}) — continuing`)}}p.push(...await $(r,f,i))}let m=Ot(u.tokens),h=Bt(u,d.count,p),g=Date.now()-c;if(!i){let e=r.replace(t+`/`,``),n=h.resolvedCollisions>0?`, ${h.resolvedCollisions} collisions namespaced`:``,i=h.envWritten?`, env typed`:``,a=h.pluginEntries>0?`, ${h.pluginEntries} plugins/adapters`:``,o=h.augmentationEntries>0?`, ${h.augmentationEntries} augmentations`:``,s=h.assetEntries>0?`, ${h.assetEntries} assets`:``;if(console.log(` kick typegen → ${h.serviceTokens} services, ${h.routeEntries} routes, ${h.moduleTokens} modules${a}${o}${s}${i}${n} → ${e} (${g}ms)`),m.length>0){console.warn(` kick typegen: ${m.length} token(s) don't match the §22.2 convention:`);for(let e of m){let t=e.variable?` [${e.variable}]`:``;console.warn(` '${e.token}' (${e.filePath})${t} — ${e.reason}`),e.suggestion&&console.warn(` → suggestion: ${e.suggestion}`)}}}return u.orphanedClasses.length>0&&await zt(u.orphanedClasses,{fix:e.fix??!1,silent:i}),{scan:u,result:h,tokenWarnings:m}}async function zt(e,{fix:t,silent:n}){let r=new Map;for(let t of e){let e=r.get(t.moduleFilePath)??[];e.push(t),r.set(t.moduleFilePath,e)}if(t){let e=0,t=[];for(let[i,a]of r){let r=it(a);try{let a=await l(i,`utf-8`),o=lt(a,r);o&&o!==a?(await p(i,o),e++,n||console.log(` kick typegen --fix: patched ${i}\n + ${r.join(`, `)}`)):t.push(i)}catch{t.push(i)}}if(!n&&(e>0&&console.log(` kick typegen --fix: updated ${e} module glob(s) — re-run typegen to pick up the now-loaded classes.`),t.length>0)){console.warn(` kick typegen --fix: could not auto-patch ${t.length} module(s) (no import.meta.glob() call found) — add the patterns by hand:`);for(let e of t){let t=r.get(e)??[];console.warn(` ${e}: ${it(t).join(`, `)}`)}}return}if(!n){console.warn(` kick typegen: ${e.length} decorated class(es) not matched by any module's import.meta.glob():`);for(let[e,t]of r){for(let e of t)console.warn(` @${e.decorator} ${e.className} (${e.relativePath})`);let n=it(t);console.warn(` → add to import.meta.glob([...]) in ${e}:`),console.warn(` ${n.map(e=>`'${e}'`).join(`, `)}`)}console.warn(" → or run `kick typegen --fix` to apply these automatically.")}}function Bt(e,t,n){let r=new Set(e.collisions.map(e=>e.className)),i=e.classes.filter(e=>ut.has(e.decorator)),a=yt(e.classes,e.tokens,e.injects,r);return{registryEntries:i.length,serviceTokens:new Set(a).size,moduleTokens:bt(e.classes).length,routeEntries:e.routes.length,pluginEntries:new Set(e.pluginsAndAdapters.map(e=>e.name)).size,augmentationEntries:new Set(e.augmentations.map(e=>e.name)).size,assetEntries:t,envWritten:e.env!==null,written:n,resolvedCollisions:e.collisions.length}}async function $(e,t,n){await c(e,{recursive:!0}),await p(i(r(e),`.gitignore`),`# Auto-generated by kick typegen
128
128
  *
129
- `,`utf-8`);let a=t.filter(e=>e.outFile).map(e=>e.outFile);return await Ht(e,a,t,n),a}async function Vt(e={}){let t=Lt(e),{srcDir:n,silent:r,cwd:i}=t,a={...t,allowDuplicates:!0,runPlugins:!1,noCache:e.noCache},o=process.env.KICKJS_WATCH_POLLING===`1`||process.env.KICKJS_WATCH_POLLING===`true`,[{runAllPluginTypegens:s},{loadKickConfig:c}]=await Promise.all([import(`./builtins-DtTYiDg0.mjs`).then(e=>e.n),import(`./config-F1NW28_P.mjs`).then(e=>e.n)]),l=await c(i),u=async()=>{try{await Rt({...a})}catch(e){if(r)return;if(e instanceof dt)console.error(`
129
+ `,`utf-8`);let a=t.filter(e=>e.outFile).map(e=>e.outFile);return await Ht(e,a,t,n),a}async function Vt(e={}){let t=Lt(e),{srcDir:n,silent:r,cwd:i}=t,a={...t,allowDuplicates:!0,runPlugins:!1,noCache:e.noCache},o=process.env.KICKJS_WATCH_POLLING===`1`||process.env.KICKJS_WATCH_POLLING===`true`,[{runAllPluginTypegens:s},{loadKickConfig:c}]=await Promise.all([import(`./builtins-A-wfYHI9.mjs`).then(e=>e.n),import(`./config-Bz1suLYz.mjs`).then(e=>e.n)]),l=await c(i),u=async()=>{try{await Rt({...a})}catch(e){if(r)return;if(e instanceof dt)console.error(`
130
130
  `+e.message+`
131
131
  `);else{let t=e instanceof Error?e.message:String(e);console.error(` kick typegen failed: ${t}`)}}},d=async()=>{try{let e=await s({cwd:i,config:l,silent:!0,watch:!0});await $(t.outDir,e,!0)}catch{}};await u(),await d();let{watch:f}=await import(`node:fs`),p=null,m=e=>{e&&/\.(ts|tsx|mts|cts)$/.test(e)&&(e.includes(`.kickjs`)||e.endsWith(`.d.ts`)||(p&&clearTimeout(p),p=setTimeout(()=>{u().then(d)},100)))};if(o){r||console.log(` kick typegen: polling mode (KICKJS_WATCH_POLLING)`);let e=setInterval(()=>{u().then(d)},2e3);return()=>clearInterval(e)}let h;try{h=f(n,{recursive:!0},(e,t)=>{m(t)})}catch(e){r||console.warn(` kick typegen: watch mode unavailable (${e?.message??e}). Falling back to polling.`);let t=setInterval(()=>{u().then(d)},2e3);return()=>clearInterval(t)}return()=>{p&&clearTimeout(p),h.close()}}async function Ht(e,t,r,i){let a=new Set;for(let e of t)a.add(n(e));for(let e of r)e.outFile&&a.add(n(e.outFile));let s;try{s=await u(e)}catch{return[]}let c=[];for(let t of s){if(!Ut.has(t)||a.has(t))continue;let n=o(e,t);try{if(!(await d(n)).isFile())continue;await f(n),c.push(t)}catch{}}return c.length>0&&!i&&console.log(` kick typegen: swept ${c.length} stale file(s): ${c.join(`, `)}`),c}const Ut=new Set([`assets.d.ts`,`env.ts`,`routes.ts`,`registry.d.ts`,`services.d.ts`,`modules.d.ts`,`plugins.d.ts`,`augmentations.d.ts`,`index.d.ts`]);export{C,E as S,w as T,et as _,At as a,k as b,bt as c,_t as d,Tt as f,Z as g,vt as h,$ as i,yt as l,wt as m,It as n,jt as o,ht as p,Vt as r,dt as s,Rt as t,Et as u,M as v,T as w,O as x,j as y};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v8.5.0
2
+ * @forinda/kickjs-cli v8.6.1
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forinda/kickjs-cli",
3
- "version": "8.5.0",
3
+ "version": "8.6.1",
4
4
  "description": "CLI for KickJS — project scaffolding, DDD module generation, dev/build/start",
5
5
  "keywords": [
6
6
  "kickjs",
@@ -29,30 +29,31 @@
29
29
  },
30
30
  "files": [
31
31
  "bin.js",
32
- "dist"
32
+ "dist",
33
+ "templates"
33
34
  ],
34
35
  "dependencies": {
35
36
  "@clack/prompts": "^1.8.0",
36
37
  "commander": "^15.0.0",
37
38
  "glob": "^13.0.6",
38
39
  "jiti": "^2.7.0",
39
- "oxc-parser": "^0.150.0",
40
- "oxfmt": "^0.68.0",
40
+ "oxc-parser": "^0.151.0",
41
+ "oxfmt": "^0.70.0",
41
42
  "picocolors": "^1.1.1",
42
43
  "pluralize": "^8.0.0",
43
- "@forinda/kickjs": "8.6.0",
44
44
  "@forinda/kickjs-cli-kit": "0.1.2",
45
- "@forinda/kickjs-db": "7.3.0"
45
+ "@forinda/kickjs": "8.7.0",
46
+ "@forinda/kickjs-db": "8.0.0"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@swc/core": "^1.16.2",
49
- "@types/node": "^26.6.1",
50
+ "@types/node": "^26.6.2",
50
51
  "@types/pg": "^8.23.1",
51
52
  "@types/pluralize": "^0.0.33",
52
53
  "@typescript/typescript6": "^6.0.2",
53
54
  "pg": "^8.23.0",
54
55
  "typescript": "^7.0.2",
55
- "vite": "^8.3.0",
56
+ "vite": "^8.3.1",
56
57
  "vitest": "^5.0.1",
57
58
  "@forinda/kickjs-ai": "8.0.0"
58
59
  },
@@ -0,0 +1,18 @@
1
+ {
2
+ "dependencies": ["@forinda/kickjs", "@forinda/kickjs-schema", "dotenv", "reflect-metadata"],
3
+ "devDependencies": [
4
+ "@forinda/kickjs-cli",
5
+ "@forinda/kickjs-testing",
6
+ "@forinda/kickjs-vite",
7
+ "@types/supertest",
8
+ "@swc/core",
9
+ "@types/node",
10
+ "unplugin-swc",
11
+ "vite",
12
+ "supertest",
13
+ "vitest",
14
+ "typescript",
15
+ "oxfmt",
16
+ "oxlint"
17
+ ]
18
+ }
@@ -0,0 +1,61 @@
1
+ # {{name}}
2
+
3
+ A **{{templateLabel}}** built with [KickJS](https://kickjs.app/) — a decorator-driven Node.js framework for TypeScript that runs on Express, Fastify, or h3 (swap the engine in one line).
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ {{packageManager}} install
9
+ kick dev
10
+ ```
11
+
12
+ ## Scripts
13
+
14
+ | Command | Description |
15
+ | ------------------------------------ | ------------------------------------ |
16
+ | `kick dev` | Start dev server with Vite HMR |
17
+ | `kick build` | Production build |
18
+ | `kick start` | Run production build |
19
+ | `{{packageManager}} run test` | Run tests with Vitest |
20
+ | `kick g module <name>` | Generate a DDD module |
21
+ | `kick g scaffold <name> <fields...>` | Generate CRUD from field definitions |
22
+ | `kick add <package>` | Add a KickJS package |
23
+
24
+ ## Project Structure
25
+
26
+ ```
27
+ src/
28
+ ├── index.ts # Application entry point
29
+ ├── modules/ # Feature modules (controllers, services, repos)
30
+ │ └── index.ts # Module registry
31
+ └── ...
32
+ ```
33
+
34
+ ## Packages
35
+
36
+ {{packages}}
37
+
38
+ ## Adding Features
39
+
40
+ ```bash
41
+ kick add swagger # OpenAPI documentation
42
+ kick add ws # WebSocket support
43
+ kick add queue # Background job processing
44
+ kick add --list # Show all available packages
45
+ ```
46
+
47
+ For email, scheduled tasks, multi-tenancy, OpenTelemetry, GraphQL, and notifications use the BYO recipes in the [KickJS guides](https://kickjs.app/guide/) — they wire the upstream library through `defineAdapter()` / `definePlugin()` directly, so you keep control of the integration.
48
+
49
+ ## Environment Variables
50
+
51
+ Copy `.env.example` to `.env` and configure:
52
+
53
+ | Variable | Default | Description |
54
+ | ---------- | ------------- | ----------- |
55
+ | `PORT` | `3000` | Server port |
56
+ | `NODE_ENV` | `development` | Environment |
57
+
58
+ ## Learn More
59
+
60
+ - [KickJS Documentation](https://kickjs.app/)
61
+ - [CLI Reference](https://kickjs.app/api/cli.html)
@@ -0,0 +1,13 @@
1
+ # https://editorconfig.org
2
+ root = true
3
+
4
+ [*]
5
+ indent_style = space
6
+ indent_size = 2
7
+ end_of_line = lf
8
+ charset = utf-8
9
+ trim_trailing_whitespace = true
10
+ insert_final_newline = true
11
+
12
+ [*.md]
13
+ trim_trailing_whitespace = false
@@ -0,0 +1,2 @@
1
+ PORT=3000
2
+ NODE_ENV=development
@@ -0,0 +1,2 @@
1
+ PORT=3000
2
+ NODE_ENV=development
@@ -0,0 +1,9 @@
1
+ # Read INSTEAD of .env when NODE_ENV=test (or under vitest).
2
+ # No fallback to .env — declare here everything the suite needs, so a
3
+ # missing var fails the run instead of silently resolving to your dev value.
4
+ #
5
+ # Not committed. Add new keys to .env.test.example too, with placeholder
6
+ # values — never real endpoints or credentials.
7
+ NODE_ENV=test
8
+ PORT=0
9
+ LOG_LEVEL=silent
@@ -0,0 +1,11 @@
1
+ # Template for .env.test. Copy it and fill in your machine's values:
2
+ # cp .env.test.example .env.test
3
+ # Read INSTEAD of .env when NODE_ENV=test (or under vitest).
4
+ # No fallback to .env — declare here everything the suite needs, so a
5
+ # missing var fails the run instead of silently resolving to your dev value.
6
+ #
7
+ # This file is committed; .env.test is not. Keep the two in step, with
8
+ # placeholder values here — never real endpoints or credentials.
9
+ NODE_ENV=test
10
+ PORT=0
11
+ LOG_LEVEL=silent
@@ -0,0 +1,18 @@
1
+ # Auto-detect text files and normalise line endings to LF
2
+ * text=auto eol=lf
3
+
4
+ # Explicitly mark generated / binary files
5
+ *.png binary
6
+ *.jpg binary
7
+ *.jpeg binary
8
+ *.gif binary
9
+ *.ico binary
10
+ *.woff binary
11
+ *.woff2 binary
12
+ *.ttf binary
13
+ *.eot binary
14
+
15
+ # Lock files — treat as generated
16
+ pnpm-lock.yaml -diff linguist-generated
17
+ yarn.lock -diff linguist-generated
18
+ package-lock.json -diff linguist-generated
@@ -0,0 +1,14 @@
1
+ node_modules/
2
+ dist/
3
+ .env
4
+ # Machine-specific: each developer's test env differs (database names, ports).
5
+ # The shared template is the committed `.env.test.example`.
6
+ .env.test
7
+ *.local
8
+ coverage/
9
+ .DS_Store
10
+ *.tsbuildinfo
11
+ .kickjs/
12
+ # Platform build output — written by `kick build:netlify` / `kick build:vercel`.
13
+ .netlify/
14
+ .vercel/
@@ -0,0 +1,9 @@
1
+ {
2
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
3
+ "semi": false,
4
+ "singleQuote": true,
5
+ "trailingComma": "all",
6
+ "printWidth": 100,
7
+ "tabWidth": 2,
8
+ "ignorePatterns": ["**/dist/", "**/.kickjs/", "**/node_modules/"]
9
+ }
@@ -0,0 +1,58 @@
1
+ import { defineConfig } from '@forinda/kickjs-cli'
2
+
3
+ export default defineConfig({
4
+ pattern: '{{template}}',
5
+ // The HTTP engine this app boots on (matches `bootstrap({ runtime })` in
6
+ // src/index.ts). Dep-aware commands read it: `kick add upload` installs the
7
+ // engine's multipart driver, `kick doctor` checks the engine peers, and
8
+ // `kick typegen` flips the runtime escape-hatch types to this engine.
9
+ runtime: '{{runtime}}',
10
+ // Pinned so `kick add` and other dep-installing commands always use the
11
+ // project's intended package manager, regardless of which lockfile exists.
12
+ packageManager: '{{packageManager}}',
13
+ modules: {
14
+ dir: 'src/modules',
15
+ // @kick:repo
16
+ pluralize: true,
17
+ },
18
+
19
+ // `kick typegen` populates `.kickjs/types/` so `Ctx<KickRoutes.X['method']>`
20
+ // resolves to fully-typed params/body/query. Auto-runs on `kick dev`.
21
+ // `'kickjs-schema'` routes inference through `InferSchemaOutput` so the
22
+ // typegen works for any wrapped schema (Zod / Valibot / Yup). Switch
23
+ // to `'zod'` if you ship Zod schemas without `fromZod()` wrapping, or
24
+ // set `schemaValidator: false` to skip schema-driven body typing.
25
+ typegen: {
26
+ schemaValidator: 'kickjs-schema',
27
+ // @kick:typegen-option
28
+ },
29
+
30
+ commands: [
31
+ {
32
+ name: 'test',
33
+ description: 'Run tests with Vitest',
34
+ steps: 'vitest run',
35
+ },
36
+ {
37
+ name: 'lint',
38
+ description: 'Lint with oxlint',
39
+ steps: 'oxlint src/',
40
+ },
41
+ {
42
+ name: 'format',
43
+ description: 'Format code with oxfmt',
44
+ steps: 'oxfmt src/',
45
+ },
46
+ {
47
+ name: 'format:check',
48
+ description: 'Check formatting without writing',
49
+ steps: 'oxfmt --check src/',
50
+ },
51
+ {
52
+ name: 'ci:check',
53
+ description: 'Run typecheck + lint + format check',
54
+ steps: ['kick typecheck', 'oxlint src/', 'oxfmt --check src/'],
55
+ aliases: ['verify'],
56
+ },
57
+ ],
58
+ })
@@ -0,0 +1,26 @@
1
+ import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
2
+ import { HelloService } from './hello.service'
3
+
4
+ // `Ctx<KickRoutes.HelloController['<method>']>` is generated by
5
+ // `kick typegen` (auto-run on `kick dev`). The first run after a fresh
6
+ // scaffold creates `.kickjs/types/routes.ts` so this file typechecks.
7
+ // See https://kickjs.app/guide/typegen.
8
+
9
+ @Controller()
10
+ export class HelloController {
11
+ @Autowired() private readonly helloService!: HelloService
12
+
13
+ // Return-value handlers: the runtime sends the returned payload as
14
+ // 200 json, and `kick typegen` infers the response type into
15
+ // `KickRoutes.Api` — which is what makes the typed client
16
+ // (@forinda/kickjs-client) end-to-end type-safe.
17
+ @Get('/')
18
+ index(_ctx: Ctx<KickRoutes.HelloController['index']>) {
19
+ return this.helloService.greet('World')
20
+ }
21
+
22
+ @Get('/health')
23
+ health(_ctx: Ctx<KickRoutes.HelloController['health']>) {
24
+ return this.helloService.healthCheck()
25
+ }
26
+ }
@@ -0,0 +1,21 @@
1
+ import { defineModule } from '@forinda/kickjs'
2
+ import { HelloController } from './hello.controller'
3
+
4
+ export const HelloModule = defineModule({
5
+ name: 'HelloModule',
6
+ build: () => ({
7
+ // `register(container)` is optional — only implement it when you need
8
+ // to bind a token to a concrete implementation, e.g.
9
+ // register(container) {
10
+ // container.registerFactory(USER_REPOSITORY, () => container.resolve(InMemoryUserRepository))
11
+ // }
12
+ // The HelloService uses @Service() so the decorator handles registration.
13
+
14
+ routes() {
15
+ return {
16
+ path: '/hello',
17
+ controller: HelloController,
18
+ }
19
+ },
20
+ }),
21
+ })
@@ -0,0 +1,12 @@
1
+ import { Service } from '@forinda/kickjs'
2
+
3
+ @Service()
4
+ export class HelloService {
5
+ greet(name: string) {
6
+ return { message: `Hello ${name} from KickJS!`, timestamp: new Date().toISOString() }
7
+ }
8
+
9
+ healthCheck() {
10
+ return { status: 'ok', uptime: process.uptime() }
11
+ }
12
+ }
@@ -0,0 +1,7 @@
1
+ import { defineModules } from '@forinda/kickjs'
2
+ import { HelloModule } from './hello/hello.module'
3
+
4
+ // Remove HelloModule and run: kick g module <name>
5
+ // `defineModules()` returns a chainable list — `kick g module` appends
6
+ // `.mount(NewModule())` to the chain on every generation.
7
+ export const modules = defineModules().mount(HelloModule())
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "types": ["node", "vite/client"],
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "sourceMap": true,
12
+ "declaration": true,
13
+ "experimentalDecorators": true,
14
+ "emitDecoratorMetadata": true,
15
+ "outDir": "dist",
16
+ "paths": {
17
+ "@/*": ["./src/*"]
18
+ }
19
+ },
20
+ "include": ["src", ".kickjs/types/**/*.d.ts", ".kickjs/types/**/*.ts"]
21
+ }
@@ -0,0 +1,31 @@
1
+ import { defineConfig } from 'vite'
2
+ import { fileURLToPath } from 'node:url'
3
+ import swc from 'unplugin-swc'
4
+ import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
5
+
6
+ export default defineConfig({
7
+ oxc: false,
8
+ plugins: [
9
+ swc.vite(),
10
+ kickjsVitePlugin({ entry: 'src/index.ts' }),
11
+ // Watches .env files and triggers a full reload on change so the
12
+ // dev server picks up env tweaks without a manual restart.
13
+ envWatchPlugin(),
14
+ ],
15
+ // @kick:vite-option
16
+ resolve: {
17
+ alias: {
18
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
19
+ },
20
+ },
21
+ build: {
22
+ target: 'node20',
23
+ ssr: true,
24
+ outDir: 'dist',
25
+ sourcemap: true,
26
+ rollupOptions: {
27
+ input: fileURLToPath(new URL('./src/index.ts', import.meta.url)),
28
+ output: { format: 'esm' },
29
+ },
30
+ },
31
+ })
@@ -0,0 +1,18 @@
1
+ import { defineConfig, mergeConfig } from 'vitest/config'
2
+ import viteConfig from './vite.config.ts'
3
+
4
+ // A `vitest.config.ts` OVERRIDES `vite.config.ts` outright — vitest does not
5
+ // merge the two, and it never reads tsconfig `paths`. Restating settings here
6
+ // would mean the `@` alias lives in three files and drifts in two of them, so
7
+ // merge the real config instead: the alias, plugins, and ssr externals all come
8
+ // from one place.
9
+ export default mergeConfig(
10
+ viteConfig,
11
+ defineConfig({
12
+ test: {
13
+ globals: true,
14
+ environment: 'node',
15
+ include: ['src/**/*.test.ts'],
16
+ },
17
+ }),
18
+ )
@@ -0,0 +1,13 @@
1
+ {
2
+ "dependencies": ["@forinda/kickjs-devtools"],
3
+ "integrations": [
4
+ {
5
+ "import": {
6
+ "from": "@forinda/kickjs-devtools",
7
+ "names": ["DevToolsAdapter"]
8
+ },
9
+ "slot": "adapter",
10
+ "code": "DevToolsAdapter()"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "dependencies": ["@forinda/kickjs-queue", "bullmq", "ioredis"],
3
+ "builds": {
4
+ "msgpackr-extract": false
5
+ },
6
+ "integrations": [
7
+ {
8
+ "import": {
9
+ "from": "@forinda/kickjs-queue",
10
+ "names": ["QueueAdapter"]
11
+ },
12
+ "slot": "adapter",
13
+ "code": "// BullMQ over Redis. Nothing connects until a @Job class or a queue\n// is used, so the app boots without Redis running.\nQueueAdapter({\n redis: {\n host: process.env.REDIS_HOST ?? '127.0.0.1',\n port: Number(process.env.REDIS_PORT ?? 6379),\n },\n})"
14
+ }
15
+ ]
16
+ }