@forinda/kickjs-cli 5.4.0 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{builtins-K-nRJcJG.mjs → builtins-CB0cpCRy.mjs} +207 -190
- package/dist/{builtins-DBzZkJey.mjs → builtins-DNnIUbGs.mjs} +101 -99
- package/dist/builtins-DNnIUbGs.mjs.map +1 -0
- package/dist/cli.mjs +2 -2
- package/dist/{config-CCNnXhar.mjs → config-CAjDTnMg.mjs} +2 -2
- package/dist/{config-CQZ6Hppr.mjs → config-f_GHcOYT.mjs} +3 -3
- package/dist/{config-CQZ6Hppr.mjs.map → config-f_GHcOYT.mjs.map} +1 -1
- package/dist/{generator-extension-Bn2aH7kY.mjs → generator-extension-Ds2fzYZS.mjs} +99 -84
- package/dist/generator-extension-Ds2fzYZS.mjs.map +1 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{plugin-DasN_2Zr.mjs → plugin-CiWyeMpX.mjs} +3 -3
- package/dist/{plugin-DasN_2Zr.mjs.map → plugin-CiWyeMpX.mjs.map} +1 -1
- package/dist/{plugin-D0C4ISZA.mjs → plugin-Dz0Yu4Ow.mjs} +2 -2
- package/dist/{rolldown-runtime-BTpMa50s.mjs → rolldown-runtime-iJll81ez.mjs} +1 -1
- package/dist/{run-plugins-Dk7KBKON.mjs → run-plugins-DBOc1G96.mjs} +2 -2
- package/dist/typegen-COBqEd4w.mjs +116 -0
- package/dist/typegen-DzmDwZvN.mjs +117 -0
- package/dist/typegen-DzmDwZvN.mjs.map +1 -0
- package/dist/{types-kAfWJgh0.mjs → types-DucsCMzP.mjs} +2 -2
- package/dist/{types-kAfWJgh0.mjs.map → types-DucsCMzP.mjs.map} +1 -1
- package/package.json +1 -1
- package/dist/builtins-DBzZkJey.mjs.map +0 -1
- package/dist/generator-extension-Bn2aH7kY.mjs.map +0 -1
- package/dist/typegen-Bl9kUVNL.mjs +0 -115
- package/dist/typegen-Bl9kUVNL.mjs.map +0 -1
- package/dist/typegen-DDQJNnUl.mjs +0 -114
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-cli v5.4.
|
|
2
|
+
* @forinda/kickjs-cli v5.4.2
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
import{createRequire as e}from"node:module";import{dirname as t,extname as n,join as r,resolve as i}from"node:path";import{existsSync as a,readFileSync as o}from"node:fs";import{access as s,mkdir as c,readFile as l,writeFile as u}from"node:fs/promises";import*as d from"@clack/prompts";import f from"picocolors";import p from"pluralize";import{execSync as
|
|
11
|
+
import{createRequire as e}from"node:module";import{dirname as t,extname as n,join as r,resolve as i}from"node:path";import{existsSync as a,readFileSync as o}from"node:fs";import{access as s,mkdir as c,readFile as l,writeFile as u}from"node:fs/promises";import*as d from"@clack/prompts";import f from"picocolors";import p from"pluralize";import{execFileSync as m,execSync as h}from"node:child_process";import{fileURLToPath as g,pathToFileURL as _}from"node:url";let v=!1;function y(e){v=e}const ee=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`,`.md`]);async function b(e,r){v||(await c(t(e),{recursive:!0}),await u(e,r,`utf-8`),ee.has(n(e))&&await ne(e,r).catch(()=>{}))}let x;async function te(t){if(x!==void 0)return x;try{x=await import(e(r(t,`package.json`)).resolve(`oxfmt`))}catch{x=null}return x}async function ne(e,t){let n=await te(process.cwd());if(!n)return;let r=await re(e);if(r===null)return;let i=await n.format(e,t,r);i.code!==t&&await u(e,i.code,`utf-8`)}const S=new Map;async function re(e){let n=t(e),i=n;if(S.has(i))return S.get(i);for(;;){let e=r(n,`.oxfmtrc.json`);if(a(e))try{let t=await l(e,`utf-8`),n=JSON.parse(t);return delete n.$schema,delete n.ignorePatterns,S.set(i,n),n}catch{return S.set(i,null),null}let o=t(n);if(o===n)return S.set(i,null),null;n=o}}async function C(e){try{return await s(e),!0}catch{return!1}}const ie={GET:f.green,POST:f.cyan,PUT:f.yellow,PATCH:f.magenta,DELETE:f.red};function ae(e){return(ie[e]??f.dim)(e.padEnd(7))}function oe(e){let t=`[${e}]`.padEnd(10);switch(e){case`CRITICAL`:return f.red(t);case`WARNING`:return f.yellow(t);case`INFO`:return f.blue(f.dim(t));default:return t}}f.green(`✓`),f.red(`✖`),f.yellow(`⚠`),f.blue(`ℹ`);function se(e){d.intro(f.bgCyan(f.black(` ${e} `)))}function ce(e){d.outro(e)}function w(e){d.isCancel(e)&&(d.cancel(`Operation cancelled.`),process.exit(0))}async function le(e){let t=await d.text(e);return w(t),t}async function ue(e){let t=await d.select(e);return w(t),t}async function de(e){let t=await d.multiselect(e);return w(t),t}async function T(e){let t=await d.confirm(e);return w(t),t}function fe(){return d.spinner()}const E=d.log;function D(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function O(e){let t=D(e);return t.charAt(0).toLowerCase()+t.slice(1)}function k(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function A(e){return p.plural(e)}function j(e){return p.plural(e)}function M(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const pe={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function me(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function he(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function N(e){return pe[e]??me(e)}function P(e,t,n){let r={inmemory:`InMemory${e}Repository`,drizzle:`Drizzle${e}Repository`,prisma:`Prisma${e}Repository`},i={inmemory:`in-memory-${t}`,drizzle:`drizzle-${t}`,prisma:`prisma-${t}`};return{repoClass:r[n]??`${me(n)}${e}Repository`,repoFile:i[n]??`${he(n)}-${t}`}}function F(e){return e??`define`}function ge(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=P(t,n,i),c=F(a),l=`/**
|
|
12
12
|
* ${t} Module
|
|
13
13
|
*
|
|
14
14
|
* Self-contained feature module following Domain-Driven Design (DDD).
|
|
@@ -28,17 +28,17 @@ import.meta.glob(
|
|
|
28
28
|
['./domain/services/**/*.ts', './application/use-cases/**/*.ts', '!./**/*.test.ts'],
|
|
29
29
|
{ eager: true },
|
|
30
30
|
)`,d=` /**
|
|
31
|
-
* Declare HTTP routes for this module.
|
|
31
|
+
* Declare HTTP routes for this module. Return value shape:
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
33
|
+
* - \`path\` — URL prefix for this route set, mounted under
|
|
34
|
+
* \`/{apiPrefix}/v{version}{path}\`.
|
|
35
|
+
* - \`controller\` — Controller class. Used both for the route
|
|
36
|
+
* handler bindings and OpenAPI spec generation.
|
|
37
|
+
* - \`version\` — Optional. Overrides the app-wide API version
|
|
38
|
+
* for this route set only.
|
|
37
39
|
*
|
|
38
40
|
* Return an **array** to mount multiple route sets under the
|
|
39
|
-
* same module (e.g. side-by-side v1 + v2 controllers)
|
|
40
|
-
* entry can override the API version with a \`version\` field —
|
|
41
|
-
* the mount path becomes \`/{apiPrefix}/v{version}{path}\`:
|
|
41
|
+
* same module (e.g. side-by-side v1 + v2 controllers):
|
|
42
42
|
*
|
|
43
43
|
* return [
|
|
44
44
|
* { path: '/${r}', version: 1, controller: ${t}V1Controller },
|
|
@@ -95,7 +95,7 @@ ${d}
|
|
|
95
95
|
},
|
|
96
96
|
}),
|
|
97
97
|
})
|
|
98
|
-
`}function
|
|
98
|
+
`}function _e(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=P(t,n,i),c=F(a),l=`/**
|
|
99
99
|
* ${t} Module
|
|
100
100
|
*
|
|
101
101
|
* REST module with a flat folder structure.
|
|
@@ -113,15 +113,14 @@ import { ${t}Controller } from './${n}.controller'
|
|
|
113
113
|
|
|
114
114
|
// Eagerly load decorated classes so @Service()/@Repository() decorators register in the DI container
|
|
115
115
|
import.meta.glob(['./**/*.service.ts', './**/*.repository.ts', '!./**/*.test.ts'], { eager: true })`,d=` /**
|
|
116
|
-
* Declare HTTP routes for this module.
|
|
116
|
+
* Declare HTTP routes for this module. Return value shape:
|
|
117
117
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
118
|
+
* - \`path\` — URL prefix for this route set.
|
|
119
|
+
* - \`controller\` — Controller class (also drives OpenAPI).
|
|
120
|
+
* - \`version\` — Optional. Overrides the app-wide API version.
|
|
121
121
|
*
|
|
122
|
-
* Return an **array** to mount multiple route sets
|
|
123
|
-
*
|
|
124
|
-
* Each entry can override the API version with a \`version\` field:
|
|
122
|
+
* Return an **array** to mount multiple route sets — admin
|
|
123
|
+
* surfaces, side-by-side v1 + v2 controllers, etc:
|
|
125
124
|
*
|
|
126
125
|
* return [
|
|
127
126
|
* { path: '/${r}', version: 1, controller: ${t}V1Controller },
|
|
@@ -168,11 +167,14 @@ ${d}
|
|
|
168
167
|
},
|
|
169
168
|
}),
|
|
170
169
|
})
|
|
171
|
-
`}function
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* \`
|
|
170
|
+
`}function ve(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=F(i),o=` /**
|
|
171
|
+
* Declare HTTP routes. Return value shape:
|
|
172
|
+
*
|
|
173
|
+
* - \`path\` — URL prefix for this route set.
|
|
174
|
+
* - \`controller\` — Controller class (also drives OpenAPI).
|
|
175
|
+
* - \`version\` — Optional. Overrides the app-wide API version.
|
|
176
|
+
*
|
|
177
|
+
* Return an array to mount multiple route sets:
|
|
176
178
|
*
|
|
177
179
|
* return [
|
|
178
180
|
* { path: '/${r}', version: 1, controller: ${t}V1Controller },
|
|
@@ -205,7 +207,7 @@ ${o}
|
|
|
205
207
|
},
|
|
206
208
|
}),
|
|
207
209
|
})
|
|
208
|
-
`}function
|
|
210
|
+
`}function ye(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
|
|
209
211
|
import { ApiTags } from '@forinda/kickjs-swagger'
|
|
210
212
|
import { Create${t}UseCase } from '../application/use-cases/create-${n}.use-case'
|
|
211
213
|
import { Get${t}UseCase } from '../application/use-cases/get-${n}.use-case'
|
|
@@ -268,7 +270,7 @@ export class ${t}Controller {
|
|
|
268
270
|
ctx.noContent()
|
|
269
271
|
}
|
|
270
272
|
}
|
|
271
|
-
`}function
|
|
273
|
+
`}function be(e){let{pascal:t,kebab:n}=e,r=t.charAt(0).toLowerCase()+t.slice(1);return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
|
|
272
274
|
import { ApiTags } from '@forinda/kickjs-swagger'
|
|
273
275
|
import { ${t}Service } from './${n}.service'
|
|
274
276
|
import { create${t}Schema } from './dtos/create-${n}.dto'
|
|
@@ -323,7 +325,7 @@ export class ${t}Controller {
|
|
|
323
325
|
ctx.noContent()
|
|
324
326
|
}
|
|
325
327
|
}
|
|
326
|
-
`}function
|
|
328
|
+
`}function xe(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
|
|
327
329
|
|
|
328
330
|
export const ${t.toUpperCase()}_QUERY_CONFIG: QueryParamsConfig = {
|
|
329
331
|
filterable: ['name'],
|
|
@@ -359,7 +361,7 @@ export type Update${t}DTO = z.infer<typeof update${t}Schema>
|
|
|
359
361
|
createdAt: string
|
|
360
362
|
updatedAt: string
|
|
361
363
|
}
|
|
362
|
-
`}function
|
|
364
|
+
`}function Se(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
|
|
363
365
|
* Create ${t} Use Case
|
|
364
366
|
*
|
|
365
367
|
* Application layer — orchestrates a single business operation.
|
|
@@ -601,7 +603,7 @@ export class ${o}${t}Repository implements I${t}Repository {
|
|
|
601
603
|
this.store.delete(id)
|
|
602
604
|
}
|
|
603
605
|
}
|
|
604
|
-
`}function
|
|
606
|
+
`}function Ce(e){let{pascal:t,kebab:n}=e;return`/**
|
|
605
607
|
* ${t} Domain Service
|
|
606
608
|
*
|
|
607
609
|
* Domain layer — contains business rules that don't belong to a single entity.
|
|
@@ -624,7 +626,7 @@ export class ${t}DomainService {
|
|
|
624
626
|
}
|
|
625
627
|
}
|
|
626
628
|
}
|
|
627
|
-
`}function
|
|
629
|
+
`}function we(e){let{pascal:t,kebab:n}=e;return`/**
|
|
628
630
|
* ${t} Entity
|
|
629
631
|
*
|
|
630
632
|
* Domain layer — the core business object.
|
|
@@ -693,7 +695,7 @@ export class ${t} {
|
|
|
693
695
|
}
|
|
694
696
|
}
|
|
695
697
|
}
|
|
696
|
-
`}function
|
|
698
|
+
`}function Te(e){let{pascal:t}=e;return`/**
|
|
697
699
|
* ${t} ID Value Object
|
|
698
700
|
*
|
|
699
701
|
* Domain layer — wraps a primitive ID with type safety and validation.
|
|
@@ -841,7 +843,7 @@ describe('InMemory${t}Repository', () => {
|
|
|
841
843
|
expect(found).toBeNull()
|
|
842
844
|
})
|
|
843
845
|
})
|
|
844
|
-
`}function
|
|
846
|
+
`}function Ee(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
|
|
845
847
|
import type { ParsedQuery } from '@forinda/kickjs'
|
|
846
848
|
import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from './${n}.repository'
|
|
847
849
|
import type { ${t}ResponseDTO } from './dtos/${n}-response.dto'
|
|
@@ -885,7 +887,7 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
|
|
|
885
887
|
sortable: ['name', 'createdAt'],
|
|
886
888
|
searchable: ['name'],
|
|
887
889
|
}
|
|
888
|
-
`}function
|
|
890
|
+
`}function De(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,o={inmemory:`InMemory${t}Repository`,drizzle:`Drizzle${t}Repository`,prisma:`Prisma${t}Repository`},s={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},c=o[i]??o.inmemory,l=s[i]??s.inmemory,u=a??`define`,d=`/**
|
|
889
891
|
* ${t} Module — CQRS Pattern
|
|
890
892
|
*
|
|
891
893
|
* Separates read (queries) and write (commands) operations.
|
|
@@ -911,11 +913,13 @@ import.meta.glob(
|
|
|
911
913
|
],
|
|
912
914
|
{ eager: true },
|
|
913
915
|
)`,p=` /**
|
|
914
|
-
* Declare HTTP routes
|
|
915
|
-
*
|
|
916
|
-
*
|
|
917
|
-
*
|
|
918
|
-
* version
|
|
916
|
+
* Declare HTTP routes for this CQRS module. Return value shape:
|
|
917
|
+
*
|
|
918
|
+
* - \`path\` — URL prefix for this route set.
|
|
919
|
+
* - \`controller\` — Controller class (also drives OpenAPI).
|
|
920
|
+
* - \`version\` — Optional. Overrides the app-wide API version.
|
|
921
|
+
*
|
|
922
|
+
* Return an array to mount multiple route sets:
|
|
919
923
|
*
|
|
920
924
|
* return [
|
|
921
925
|
* { path: '/${r}', version: 1, controller: ${t}V1Controller },
|
|
@@ -962,7 +966,7 @@ ${p}
|
|
|
962
966
|
},
|
|
963
967
|
}),
|
|
964
968
|
})
|
|
965
|
-
`}function
|
|
969
|
+
`}function Oe(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return`import { Controller, Get, Post, Put, Delete, Autowired, ApiQueryParams, type Ctx } from '@forinda/kickjs'
|
|
966
970
|
import { ApiTags } from '@forinda/kickjs-swagger'
|
|
967
971
|
import { Create${t}Command } from './commands/create-${n}.command'
|
|
968
972
|
import { Update${t}Command } from './commands/update-${n}.command'
|
|
@@ -1025,7 +1029,7 @@ export class ${t}Controller {
|
|
|
1025
1029
|
ctx.noContent()
|
|
1026
1030
|
}
|
|
1027
1031
|
}
|
|
1028
|
-
`}function
|
|
1032
|
+
`}function ke(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
|
|
1029
1033
|
import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
|
|
1030
1034
|
import type { Create${t}DTO } from '../dtos/create-${n}.dto'
|
|
1031
1035
|
import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
|
|
@@ -1079,7 +1083,7 @@ export class Delete${t}Command {
|
|
|
1079
1083
|
this.events.emit('${n}.deleted', { id })
|
|
1080
1084
|
}
|
|
1081
1085
|
}
|
|
1082
|
-
`}]}function
|
|
1086
|
+
`}]}function Ae(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
|
|
1083
1087
|
import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
|
|
1084
1088
|
import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
|
|
1085
1089
|
|
|
@@ -1107,7 +1111,7 @@ export class List${i}Query {
|
|
|
1107
1111
|
return this.repo.findPaginated(parsed)
|
|
1108
1112
|
}
|
|
1109
1113
|
}
|
|
1110
|
-
`}]}function
|
|
1114
|
+
`}]}function je(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
|
|
1111
1115
|
import { EventEmitter } from 'node:events'
|
|
1112
1116
|
import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
|
|
1113
1117
|
|
|
@@ -1275,7 +1279,7 @@ export class Drizzle${t}Repository implements I${t}Repository {
|
|
|
1275
1279
|
throw new Error('Drizzle ${t} repository not yet implemented')
|
|
1276
1280
|
}
|
|
1277
1281
|
}
|
|
1278
|
-
`}function
|
|
1282
|
+
`}function Me(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
|
|
1279
1283
|
// TODO: Import your schema table and reference actual columns for type safety
|
|
1280
1284
|
// import { ${n}s } from '@/db/schema'
|
|
1281
1285
|
|
|
@@ -1351,7 +1355,7 @@ export class Prisma${t}Repository implements I${t}Repository {
|
|
|
1351
1355
|
await this.prisma.${a}.deleteMany({ where: { id } })
|
|
1352
1356
|
}
|
|
1353
1357
|
}
|
|
1354
|
-
`}function
|
|
1358
|
+
`}function Ne(e,t,n,r=[]){switch(t){case`cqrs`:{let t=[],i=[];return r.includes(`devtools`)&&(t.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`),i.push(` DevToolsAdapter(),`)),r.includes(`swagger`)&&(t.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`),i.push(` SwaggerAdapter({\n info: { title: '${e}', version: '${n}' },\n }),`)),`import 'reflect-metadata'
|
|
1355
1359
|
// Side-effect import — registers the extended env schema with kickjs
|
|
1356
1360
|
// **before** any controller / service / @Value gets resolved. Without
|
|
1357
1361
|
// this line ConfigService.get('YOUR_KEY') returns undefined because the
|
|
@@ -1421,14 +1425,14 @@ export const app = await bootstrap({
|
|
|
1421
1425
|
express.json(),
|
|
1422
1426
|
],
|
|
1423
1427
|
})
|
|
1424
|
-
`}}}function
|
|
1428
|
+
`}}}function Pe(){return`import { defineModules } from '@forinda/kickjs'
|
|
1425
1429
|
import { HelloModule } from './hello/hello.module'
|
|
1426
1430
|
|
|
1427
1431
|
// Remove HelloModule and run: kick g module <name>
|
|
1428
|
-
//
|
|
1429
|
-
//
|
|
1430
|
-
export const modules
|
|
1431
|
-
`}function
|
|
1432
|
+
// \`defineModules()\` returns a chainable list — \`kick g module\` appends
|
|
1433
|
+
// \`.mount(NewModule())\` to the chain on every generation.
|
|
1434
|
+
export const modules = defineModules().mount(HelloModule())
|
|
1435
|
+
`}function Fe(){return`import { defineEnv, loadEnv } from '@forinda/kickjs/config'
|
|
1432
1436
|
import { z } from 'zod'
|
|
1433
1437
|
|
|
1434
1438
|
/**
|
|
@@ -1463,7 +1467,7 @@ const envSchema = defineEnv((base) =>
|
|
|
1463
1467
|
export const env = loadEnv(envSchema)
|
|
1464
1468
|
|
|
1465
1469
|
export default envSchema
|
|
1466
|
-
`}function
|
|
1470
|
+
`}function Ie(){return`import { Service } from '@forinda/kickjs'
|
|
1467
1471
|
|
|
1468
1472
|
@Service()
|
|
1469
1473
|
export class HelloService {
|
|
@@ -1475,7 +1479,7 @@ export class HelloService {
|
|
|
1475
1479
|
return { status: 'ok', uptime: process.uptime() }
|
|
1476
1480
|
}
|
|
1477
1481
|
}
|
|
1478
|
-
`}function
|
|
1482
|
+
`}function Le(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
|
|
1479
1483
|
import { HelloService } from './hello.service'
|
|
1480
1484
|
|
|
1481
1485
|
// \`Ctx<KickRoutes.HelloController['<method>']>\` is generated by
|
|
@@ -1497,7 +1501,7 @@ export class HelloController {
|
|
|
1497
1501
|
ctx.json(this.helloService.healthCheck())
|
|
1498
1502
|
}
|
|
1499
1503
|
}
|
|
1500
|
-
`}function
|
|
1504
|
+
`}function Re(){return`import { defineModule } from '@forinda/kickjs'
|
|
1501
1505
|
import { HelloController } from './hello.controller'
|
|
1502
1506
|
|
|
1503
1507
|
export const HelloModule = defineModule({
|
|
@@ -1518,7 +1522,7 @@ export const HelloModule = defineModule({
|
|
|
1518
1522
|
},
|
|
1519
1523
|
}),
|
|
1520
1524
|
})
|
|
1521
|
-
`}function
|
|
1525
|
+
`}function ze(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
|
|
1522
1526
|
|
|
1523
1527
|
export default defineConfig({
|
|
1524
1528
|
pattern: '${e}',
|
|
@@ -1562,7 +1566,7 @@ export default defineConfig({
|
|
|
1562
1566
|
},
|
|
1563
1567
|
],
|
|
1564
1568
|
})
|
|
1565
|
-
`}async function
|
|
1569
|
+
`}async function Be(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,ve({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
|
|
1566
1570
|
|
|
1567
1571
|
// \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
|
|
1568
1572
|
// \`kick typegen\` (auto-run on \`kick dev\`).
|
|
@@ -1574,14 +1578,19 @@ export class ${t}Controller {
|
|
|
1574
1578
|
ctx.json({ message: '${t} list' })
|
|
1575
1579
|
}
|
|
1576
1580
|
}
|
|
1577
|
-
`)}async function
|
|
1581
|
+
`)}async function Ve(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,_e({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,W({pascal:t,kebab:n})),await u(`${n}.controller.ts`,be({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,Ee({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,I({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,L({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,R({pascal:t,kebab:n})),await u(`${n}.repository.ts`,z({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>B({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>G({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>K({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${k(a)}-${n}`,m=f[a]??(()=>V({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${p}.repository.ts`,m()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,B({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,H({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,U({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function He(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noTests:o,prismaClientPath:s,tokenScope:c,style:l,write:u}=e;await u(`${n}.module.ts`,De({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,W({pascal:t,kebab:n})),await u(`${n}.controller.ts`,Oe({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,I({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,L({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,R({pascal:t,kebab:n}));let d=ke({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=Ae({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=je({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,z({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>B({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>G({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>K({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${k(a)}-${n}`,_=h[a]??(()=>V({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,B({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,H({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,U({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Ue(e){let{pascal:t,kebab:n,plural:r,pluralPascal:i,repo:a,noEntity:o,noTests:s,prismaClientPath:c,tokenScope:l,style:u,write:d}=e;await d(`${n}.module.ts`,ge({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?Me({pascal:t,kebab:n}):xe({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,ye({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,I({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,L({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,R({pascal:t,kebab:n}));let f=Se({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await d(`application/use-cases/${e.file}`,e.content);await d(`domain/repositories/${n}.repository.ts`,z({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,Ce({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>B({pascal:t,kebab:n}),drizzle:()=>G({pascal:t,kebab:n}),prisma:()=>K({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${k(a)}-${n}`,g=m[a]??(()=>V({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,we({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,Te({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,B({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,H({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,U({pascal:t,kebab:n,plural:r})))}function We(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Ge(e){let{name:t,modulesDir:n,noEntity:i,noTests:a,repo:o=`inmemory`,force:s,dryRun:c}=e,l=e.pluralize!==!1,u=e.pattern??`ddd`;e.minimal&&(u=`minimal`);let d=k(t),p=D(t),m=l?A(d):d,h=l?j(p):p,g=r(n,m),_=[],v=s??!1,y={kebab:d,pascal:p,plural:m,pluralPascal:h,moduleDir:g,repo:o,noEntity:i??!1,noTests:a??!1,prismaClientPath:e.prismaClientPath??`@prisma/client`,tokenScope:e.tokenScope??`app`,style:e.style??`define`,write:async(e,t)=>{let n=r(g,e);if(c){_.push(n);return}if(!v&&await C(n)&&!await T({message:`File exists: ${f.dim(e)}. Overwrite?`,initialValue:!1})){E.warn(`Skipped: ${e}`);return}await b(n,t),_.push(n)},files:_};switch(u){case`minimal`:await Be(y);break;case`rest`:await Ve(y);break;case`cqrs`:await He(y);break;default:await Ue(y);break}return c||await q(n,p,m,d,y.style),_}async function q(e,t,n,i,a=`define`){let o=r(e,`index.ts`),s=await C(o),c=`./${n}/${i}.module`,d=a===`class`?`${t}Module`:`${t}Module()`;if(!s){await b(o,a===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
|
|
1578
1582
|
import { ${t}Module } from '${c}'
|
|
1579
1583
|
|
|
1580
1584
|
export const modules: AppModuleEntry[] = [${d}]
|
|
1581
|
-
|
|
1585
|
+
`:`import { defineModules } from '@forinda/kickjs'
|
|
1586
|
+
import { ${t}Module } from '${c}'
|
|
1587
|
+
|
|
1588
|
+
export const modules = defineModules().mount(${d})
|
|
1589
|
+
`);return}let f=await l(o,`utf-8`),p=`import { ${t}Module } from '${c}'`,m=M(c);if(!RegExp(`^import\\s*\\{[^}]*\\b${M(t)}Module\\b[^}]*\\}\\s*from\\s*['"]${m}['"]`,`m`).test(f)){let e=f.lastIndexOf(`import `);if(e!==-1){let t=f.indexOf(`
|
|
1582
1590
|
`,e);f=f.slice(0,t+1)+p+`
|
|
1583
1591
|
`+f.slice(t+1)}else f=p+`
|
|
1584
|
-
`+f;
|
|
1592
|
+
`+f}let h=Y(f);if(h){let e=f.slice(h.rhsStart,h.rhsEnd+1);RegExp(`\\b${M(t)}Module\\b`).test(e)||(f=J(f,d))}else f=J(f,d);await u(o,f,`utf-8`)}function J(e,t){let n=Y(e);if(!n)return e;if(n.shape===`array`){let r=e.slice(n.rhsStart+1,n.rhsEnd),i=r.trim(),a;if(!i)a=`[${t}]`;else{let e=i.endsWith(`,`)?``:`,`;a=`[${r.trimEnd()}${e} ${t}]`}return e.slice(0,n.rhsStart)+a+e.slice(n.rhsEnd+1)}return`${e.slice(0,n.chainEnd)}\n .mount(${t})${e.slice(n.chainEnd)}`}function Y(e){let t=/export\s+const\s+modules\b[^=]*=/.exec(e);if(!t)return null;let n=t.index+t[0].length;for(;n<e.length&&/\s/.test(e[n]??``);)n++;if(e[n]===`[`){let t=qe(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=Ke(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function Ke(e,t=0){let n=/defineModules\s*\(/g;n.lastIndex=t;let r=n.exec(e);if(!r)return-1;let i=r.index+r[0].length-1;if(e[i]!==`(`||(i=Z(e,i),i===-1))return-1;for(i++;;){let t=i;for(;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`.`||e.slice(t,t+6)!==`.mount`)break;for(t+=6;t<e.length&&/\s/.test(e[t]??``);)t++;if(e[t]!==`(`)break;let n=Z(e,t);if(n===-1)break;i=n+1}return i}function X(e,t){let n=e.slice(t,t+2);if(n===`//`){for(t+=2;t<e.length&&e[t]!==`
|
|
1593
|
+
`;)t++;return t}if(n===`/*`){for(t+=2;t+1<e.length&&!(e[t]===`*`&&e[t+1]===`/`);)t++;return t+2}return t}function qe(e,t){if(e[t]!==`[`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=X(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`[`)n++;else if(i===`]`&&(n--,n===0))return r;r++}return-1}function Z(e,t){if(e[t]!==`(`)return-1;let n=1,r=t+1;for(;r<e.length;){let t=e.slice(r,r+2);if(t===`//`||t===`/*`){r=X(e,r);continue}let i=e[r]??``;if(i===`'`||i===`"`||i==="`"){let t=i;for(r++;r<e.length&&e[r]!==t;)e[r]===`\\`&&r++,r++;r<e.length&&r++;continue}if(i===`(`)n++;else if(i===`)`&&(n--,n===0))return r;r++}return-1}async function Je(e){let{name:t,outDir:n}=e,i=k(t),a=D(t),o=[],s=r(n,`${i}.adapter.ts`);return await b(s,`import {
|
|
1585
1594
|
defineAdapter,
|
|
1586
1595
|
type AdapterContext,
|
|
1587
1596
|
type AdapterMiddleware,
|
|
@@ -1750,7 +1759,7 @@ export const ${a}Adapter = defineAdapter<${a}AdapterConfig>({
|
|
|
1750
1759
|
}
|
|
1751
1760
|
},
|
|
1752
1761
|
})
|
|
1753
|
-
`),o.push(s),o}const
|
|
1762
|
+
`),o.push(s),o}const Ye={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},Xe={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},Ze={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function Q(e){let{type:t,outDir:n,moduleName:a,modulesDir:o=`src/modules`,defaultDir:s,pattern:c=`ddd`,shouldPluralize:l=!0}=e;if(n)return i(n);if(a){let e=c===`ddd`?Ye:c===`cqrs`?Ze:Xe,n=k(a),s=l?A(n):n,u=e[t]??``,d=r(o,s);return i(u?r(d,u):d)}return i(s)}async function Qe(e){let{name:t,moduleName:n,modulesDir:i,pattern:a}=e,o=Q({type:`middleware`,outDir:e.outDir,moduleName:n,modulesDir:i,defaultDir:`src/middleware`,pattern:a,shouldPluralize:e.pluralize??!0}),s=k(t),c=O(t),l=[],u=r(o,`${s}.middleware.ts`);return await b(u,`import type { Request, Response, NextFunction } from 'express'
|
|
1754
1763
|
|
|
1755
1764
|
export interface ${D(t)}Options {
|
|
1756
1765
|
// Add configuration options here
|
|
@@ -1774,7 +1783,7 @@ export function ${c}(options: ${D(t)}Options = {}) {
|
|
|
1774
1783
|
next()
|
|
1775
1784
|
}
|
|
1776
1785
|
}
|
|
1777
|
-
`),l.push(u),l}async function
|
|
1786
|
+
`),l.push(u),l}async function $e(e){let{name:t,moduleName:n,modulesDir:i,pattern:a}=e,o=Q({type:`guard`,outDir:e.outDir,moduleName:n,modulesDir:i,defaultDir:`src/guards`,pattern:a,shouldPluralize:e.pluralize??!0}),s=k(t),c=O(t),l=D(t),u=[],d=r(o,`${s}.guard.ts`);return await b(d,`import { Container, HttpException } from '@forinda/kickjs'
|
|
1778
1787
|
import type { RequestContext } from '@forinda/kickjs'
|
|
1779
1788
|
|
|
1780
1789
|
/**
|
|
@@ -1810,7 +1819,7 @@ export async function ${c}Guard(ctx: RequestContext, next: () => void): Promise<
|
|
|
1810
1819
|
ctx.res.status(401).json({ message: 'Invalid or expired token' })
|
|
1811
1820
|
}
|
|
1812
1821
|
}
|
|
1813
|
-
`),u.push(d),u}async function
|
|
1822
|
+
`),u.push(d),u}async function et(e){let{name:t,moduleName:n,modulesDir:i,pattern:a}=e,o=Q({type:`service`,outDir:e.outDir,moduleName:n,modulesDir:i,defaultDir:`src/services`,pattern:a,shouldPluralize:e.pluralize??!0}),s=k(t),c=D(t),l=[],u=r(o,`${s}.service.ts`);return await b(u,`import { Service } from '@forinda/kickjs'
|
|
1814
1823
|
|
|
1815
1824
|
@Service()
|
|
1816
1825
|
export class ${c}Service {
|
|
@@ -1819,7 +1828,7 @@ export class ${c}Service {
|
|
|
1819
1828
|
// @Inject(MY_REPO) private readonly repo: IMyRepository,
|
|
1820
1829
|
// ) {}
|
|
1821
1830
|
}
|
|
1822
|
-
`),l.push(u),l}async function
|
|
1831
|
+
`),l.push(u),l}async function tt(e){let{name:t,moduleName:n,modulesDir:i,pattern:a}=e,o=Q({type:`controller`,outDir:e.outDir,moduleName:n,modulesDir:i,defaultDir:`src/controllers`,pattern:a,shouldPluralize:e.pluralize??!0}),s=k(t),c=D(t),l=[],u=r(o,`${s}.controller.ts`);return await b(u,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
|
|
1823
1832
|
|
|
1824
1833
|
// \`Ctx<KickRoutes.${c}Controller['<method>']>\` is generated by
|
|
1825
1834
|
// \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
|
|
@@ -1840,7 +1849,7 @@ export class ${c}Controller {
|
|
|
1840
1849
|
ctx.created({ message: '${c} created', data: ctx.body })
|
|
1841
1850
|
}
|
|
1842
1851
|
}
|
|
1843
|
-
`),l.push(u),l}async function
|
|
1852
|
+
`),l.push(u),l}async function nt(e){let{name:t,moduleName:n,modulesDir:i,pattern:a}=e,o=Q({type:`dto`,outDir:e.outDir,moduleName:n,modulesDir:i,defaultDir:`src/dtos`,pattern:a,shouldPluralize:e.pluralize??!0}),s=k(t),c=D(t),l=O(t),u=[],d=r(o,`${s}.dto.ts`);return await b(d,`import { z } from 'zod'
|
|
1844
1853
|
|
|
1845
1854
|
export const ${l}Schema = z.object({
|
|
1846
1855
|
// Define your schema fields here
|
|
@@ -1848,7 +1857,7 @@ export const ${l}Schema = z.object({
|
|
|
1848
1857
|
})
|
|
1849
1858
|
|
|
1850
1859
|
export type ${c}DTO = z.infer<typeof ${l}Schema>
|
|
1851
|
-
`),u.push(d),u}const
|
|
1860
|
+
`),u.push(d),u}const rt={auth:`@forinda/kickjs-auth`,swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function $(e,t){let n=e[t];if(!n)throw Error(`generatePackageJson: missing resolved version for ${t}. Add it to SIBLING_PACKAGES in generators/project.ts.`);return n}function it(e,t,n,r=[]){let i={"@forinda/kickjs":$(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`,pino:`^10.3.1`,"pino-pretty":`^13.1.3`};for(let e of r){let t=rt[e];t&&!i[t]&&(i[t]=$(n,t))}return JSON.stringify({name:e,version:`0.0.0`,type:`module`,scripts:{dev:`vite`,"dev:debug":`kick dev:debug`,build:`kick build`,start:`kick start`,test:`vitest run`,"test:watch":`vitest`,typecheck:`tsc --noEmit`,typegen:`kick typegen`,lint:`eslint src/`,format:`prettier --write src/`},dependencies:i,devDependencies:{"@forinda/kickjs-cli":$(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":$(n,`@forinda/kickjs-vite`),"@swc/core":`^1.15.21`,"@types/express":`^5.0.6`,"@types/node":`^25.0.0`,"unplugin-swc":`^1.5.9`,vite:`^8.0.3`,vitest:`^4.1.2`,typescript:`^6.0.3`,prettier:`^3.8.1`}},null,2)}function at(){return`import { defineConfig } from 'vite'
|
|
1852
1861
|
import { resolve } from 'node:path'
|
|
1853
1862
|
import swc from 'unplugin-swc'
|
|
1854
1863
|
import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
|
|
@@ -1883,7 +1892,7 @@ export default defineConfig({
|
|
|
1883
1892
|
},
|
|
1884
1893
|
},
|
|
1885
1894
|
})
|
|
1886
|
-
`}function
|
|
1895
|
+
`}function ot(){return JSON.stringify({compilerOptions:{target:`ES2022`,module:`ESNext`,moduleResolution:`bundler`,lib:[`ES2022`],types:[`node`,`vite/client`],strict:!0,esModuleInterop:!0,skipLibCheck:!0,sourceMap:!0,declaration:!0,experimentalDecorators:!0,emitDecoratorMetadata:!0,outDir:`dist`,paths:{"@/*":[`./src/*`]}},include:[`src`,`.kickjs/types/**/*.d.ts`,`.kickjs/types/**/*.ts`]},null,2)}function st(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function ct(){return`# https://editorconfig.org
|
|
1887
1896
|
root = true
|
|
1888
1897
|
|
|
1889
1898
|
[*]
|
|
@@ -1896,14 +1905,14 @@ insert_final_newline = true
|
|
|
1896
1905
|
|
|
1897
1906
|
[*.md]
|
|
1898
1907
|
trim_trailing_whitespace = false
|
|
1899
|
-
`}function
|
|
1908
|
+
`}function lt(){return`node_modules/
|
|
1900
1909
|
dist/
|
|
1901
1910
|
.env
|
|
1902
1911
|
coverage/
|
|
1903
1912
|
.DS_Store
|
|
1904
1913
|
*.tsbuildinfo
|
|
1905
1914
|
.kickjs/
|
|
1906
|
-
`}function
|
|
1915
|
+
`}function ut(){return`# Auto-detect text files and normalise line endings to LF
|
|
1907
1916
|
* text=auto eol=lf
|
|
1908
1917
|
|
|
1909
1918
|
# Explicitly mark generated / binary files
|
|
@@ -1921,11 +1930,11 @@ coverage/
|
|
|
1921
1930
|
pnpm-lock.yaml -diff linguist-generated
|
|
1922
1931
|
yarn.lock -diff linguist-generated
|
|
1923
1932
|
package-lock.json -diff linguist-generated
|
|
1924
|
-
`}function
|
|
1933
|
+
`}function dt(){return`PORT=3000
|
|
1925
1934
|
NODE_ENV=development
|
|
1926
|
-
`}function
|
|
1935
|
+
`}function ft(){return`PORT=3000
|
|
1927
1936
|
NODE_ENV=development
|
|
1928
|
-
`}function
|
|
1937
|
+
`}function pt(){return`import { defineConfig } from 'vitest/config'
|
|
1929
1938
|
import swc from 'unplugin-swc'
|
|
1930
1939
|
|
|
1931
1940
|
export default defineConfig({
|
|
@@ -1936,7 +1945,7 @@ export default defineConfig({
|
|
|
1936
1945
|
include: ['src/**/*.test.ts'],
|
|
1937
1946
|
},
|
|
1938
1947
|
})
|
|
1939
|
-
`}function
|
|
1948
|
+
`}function mt(e,t,n){let r={rest:`REST API`,ddd:`Domain-Driven Design`,cqrs:`CQRS + Event-Driven`,minimal:`Minimal`},i=[`@forinda/kickjs`,`@forinda/kickjs-vite`];return t!==`minimal`&&i.push(`@forinda/kickjs-swagger`,`@forinda/kickjs-devtools`),t===`cqrs`&&i.push(`@forinda/kickjs-queue`,`@forinda/kickjs-ws`),`# ${e}
|
|
1940
1949
|
|
|
1941
1950
|
A **${r[t]??`REST API`}** built with [KickJS](https://forinda.github.io/kick-js/) — a decorator-driven Node.js framework on Express 5 and TypeScript.
|
|
1942
1951
|
|
|
@@ -1999,7 +2008,7 @@ Copy \`.env.example\` to \`.env\` and configure:
|
|
|
1999
2008
|
|
|
2000
2009
|
- [KickJS Documentation](https://forinda.github.io/kick-js/)
|
|
2001
2010
|
- [CLI Reference](https://forinda.github.io/kick-js/api/cli.html)
|
|
2002
|
-
`}function
|
|
2011
|
+
`}function ht(e,t,n){return`# CLAUDE.md — ${e}
|
|
2003
2012
|
|
|
2004
2013
|
**Read \`./AGENTS.md\` first.** It is the canonical, multi-agent
|
|
2005
2014
|
reference for this project (Claude, Copilot, Codex, Gemini, etc.) —
|
|
@@ -2065,7 +2074,7 @@ When generating or modifying code in this project, stay aligned with the v4 conv
|
|
|
2065
2074
|
- **Refresh these files**: \`kick g agents -f\` regenerates \`AGENTS.md\` + \`CLAUDE.md\` from the latest CLI templates. Hand-edited content is overwritten — keep customisation in \`AGENTS.local.md\`.
|
|
2066
2075
|
|
|
2067
2076
|
For everything else (controllers, services, modules, RequestContext API, generators, CLI commands, package additions, env wiring, troubleshooting) → \`AGENTS.md\`.
|
|
2068
|
-
`}function
|
|
2077
|
+
`}function gt(e,t,n){return`# AGENTS.md — AI Agent Guide for ${e}
|
|
2069
2078
|
|
|
2070
2079
|
This guide is the **canonical, multi-agent reference** for this KickJS
|
|
2071
2080
|
application — Claude, Copilot, Codex, Gemini, etc. all read it first.
|
|
@@ -2169,8 +2178,10 @@ mistakes:
|
|
|
2169
2178
|
inline registration in the entry file:
|
|
2170
2179
|
|
|
2171
2180
|
\`\`\`ts
|
|
2172
|
-
// src/modules/index.ts
|
|
2173
|
-
export const modules
|
|
2181
|
+
// src/modules/index.ts — fluent chain (default for \`modules.style: 'define'\`)
|
|
2182
|
+
export const modules = defineModules().mount(HelloModule()).mount(UsersModule())
|
|
2183
|
+
// OR with \`modules.style: 'class'\`:
|
|
2184
|
+
// export const modules: AppModuleEntry[] = [HelloModule, UsersModule]
|
|
2174
2185
|
|
|
2175
2186
|
// src/middleware/index.ts
|
|
2176
2187
|
export const middleware = [helmet(), cors(), requestId(), ...]
|
|
@@ -2286,8 +2297,8 @@ If not using generators:
|
|
|
2286
2297
|
- [ ] Create \`src/modules/<name>/<name>.controller.ts\`
|
|
2287
2298
|
- [ ] Add \`@Controller()\` decorator
|
|
2288
2299
|
- [ ] Add route handlers with \`@Get()\`, \`@Post()\`, etc.
|
|
2289
|
-
- [ ] Create module file with \`defineModule({ name, build: () => ({ routes() { return { path, controller } } }) })\`
|
|
2290
|
-
- [ ] Register module in \`src/modules/index.ts
|
|
2300
|
+
- [ ] Create module file with \`defineModule({ name, build: () => ({ routes() { return { path, controller } } }) })\` — the framework derives the Express router from the controller. Class-form (\`class XModule implements AppModule\`) is the legacy alternative; toggle via \`kick.config.ts > modules.style\`.
|
|
2301
|
+
- [ ] Register module in \`src/modules/index.ts\`. Default form is the fluent chain: \`defineModules().mount(MyModule()).mount(...)\`. \`kick g module <name>\` appends \`.mount(NewModule())\` automatically.
|
|
2291
2302
|
- [ ] Test with \`kick dev\`
|
|
2292
2303
|
|
|
2293
2304
|
### Manual Service
|
|
@@ -2489,7 +2500,9 @@ These work anywhere — scripts, plain files, outside \`@Service\`/\`@Controller
|
|
|
2489
2500
|
### Dependency Injection
|
|
2490
2501
|
| Decorator | Purpose |
|
|
2491
2502
|
|-----------|---------|
|
|
2492
|
-
| \`
|
|
2503
|
+
| \`defineModule({...})\` | Define feature module (factory; preferred — paired with \`defineModules()\` registry) |
|
|
2504
|
+
| \`defineModules()\` | Build the modules registry as a chainable list (\`.mount(X())\`) |
|
|
2505
|
+
| \`AppModule\` interface | Legacy module shape — \`class X implements AppModule\` (toggle via \`modules.style: 'class'\`) |
|
|
2493
2506
|
| \`@Service()\` | Register singleton service |
|
|
2494
2507
|
| \`@Repository()\` | Register repository |
|
|
2495
2508
|
| \`@Autowired()\` | Property injection |
|
|
@@ -2506,7 +2519,7 @@ is a value other code reads off \`ctx\`.
|
|
|
2506
2519
|
|---------|----------------|
|
|
2507
2520
|
| \`defineContextDecorator({ key, deps, dependsOn, optional, onError, resolve })\` | \`@forinda/kickjs\` |
|
|
2508
2521
|
| Method/class decorator | \`@LoadX\` on a controller method/class |
|
|
2509
|
-
| Module hook | \`
|
|
2522
|
+
| Module hook | \`build: () => ({ contributors() { return [...] } })\` (\`defineModule\`) — or \`AppModule.contributors?()\` for class form |
|
|
2510
2523
|
| Adapter hook | \`AppAdapter.contributors?(): ContributorRegistration[]\` |
|
|
2511
2524
|
| Global registration | \`bootstrap({ contributors: [LoadX.registration] })\` |
|
|
2512
2525
|
| Type augmentation | \`declare module '@forinda/kickjs' { interface ContextMeta { ... } }\` |
|
|
@@ -2568,7 +2581,7 @@ ${t===`cqrs`?`### Background Jobs
|
|
|
2568
2581
|
- [Decorators Guide](https://forinda.github.io/kick-js/guide/decorators.html)
|
|
2569
2582
|
- [DI System](https://forinda.github.io/kick-js/guide/dependency-injection.html)
|
|
2570
2583
|
- [Testing](https://forinda.github.io/kick-js/api/testing.html)
|
|
2571
|
-
`}function
|
|
2584
|
+
`}function _t(e,t,n){return`# kickjs-skills.md — Task Skills for AI Agents (${e})
|
|
2572
2585
|
|
|
2573
2586
|
This file is the agent-facing **skills index** for KickJS work in this
|
|
2574
2587
|
repo. Each block below is a short, rigid workflow keyed to a specific
|
|
@@ -2703,8 +2716,10 @@ description: Use when src/index.ts is accumulating module/middleware/plugin/adap
|
|
|
2703
2716
|
**Refactor target**:
|
|
2704
2717
|
|
|
2705
2718
|
\`\`\`ts
|
|
2706
|
-
// src/modules/index.ts
|
|
2707
|
-
export const modules
|
|
2719
|
+
// src/modules/index.ts — fluent chain (default for \`modules.style: 'define'\`)
|
|
2720
|
+
export const modules = defineModules().mount(HelloModule()).mount(UsersModule())
|
|
2721
|
+
// OR for class-form projects (\`modules.style: 'class'\`):
|
|
2722
|
+
// export const modules: AppModuleEntry[] = [HelloModule, UsersModule]
|
|
2708
2723
|
|
|
2709
2724
|
// src/middleware/index.ts
|
|
2710
2725
|
export const middleware = [helmet(), cors(), requestId(), ...]
|
|
@@ -2815,7 +2830,7 @@ description: Patterns to refuse outright when the user asks for them — they br
|
|
|
2815
2830
|
- [Decorators](https://forinda.github.io/kick-js/guide/decorators.html)
|
|
2816
2831
|
- [Context Decorators](https://forinda.github.io/kick-js/guide/context-decorators.html)
|
|
2817
2832
|
- [Testing](https://forinda.github.io/kick-js/api/testing.html)
|
|
2818
|
-
`}const
|
|
2819
|
-
Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${i} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-
|
|
2820
|
-
Project scaffolded successfully!`),console.log();let
|
|
2821
|
-
//# sourceMappingURL=generator-extension-
|
|
2833
|
+
`}const vt=t(g(import.meta.url)),yt=JSON.parse(o(r(vt,`..`,`package.json`),`utf-8`)),bt=`^${yt.version}`,xt=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`,`@forinda/kickjs-auth`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function St(){let e=await Promise.all(xt.map(async e=>{try{let t=m(`npm`,[`view`,e,`version`],{encoding:`utf-8`,timeout:5e3,stdio:[`ignore`,`pipe`,`ignore`]}).toString().trim();if(t&&/^\d+\.\d+\.\d+/.test(t))return[e,`^${t}`]}catch{}return[e,bt]}));return Object.fromEntries(e)}async function Ct(e){let{name:t,directory:n,packageManager:i=`pnpm`,template:a=`rest`,defaultRepo:o=`inmemory`,packages:s=[]}=e,c=n,l=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${t}\n`),l(`Resolving package versions...`);let u=await St();if(await b(r(c,`package.json`),it(t,a,u,s)),await b(r(c,`vite.config.ts`),at()),await b(r(c,`tsconfig.json`),ot()),await b(r(c,`.prettierrc`),st()),await b(r(c,`.editorconfig`),ct()),await b(r(c,`.gitignore`),lt()),await b(r(c,`.gitattributes`),ut()),await b(r(c,`.env`),dt()),await b(r(c,`.env.example`),ft()),await b(r(c,`src/config/index.ts`),Fe()),await b(r(c,`src/index.ts`),Ne(t,a,yt.version,s)),await b(r(c,`src/modules/index.ts`),Pe()),await b(r(c,`src/modules/hello/hello.service.ts`),Ie()),await b(r(c,`src/modules/hello/hello.controller.ts`),Le()),await b(r(c,`src/modules/hello/hello.module.ts`),Re()),await b(r(c,`kick.config.ts`),ze(a,o,i)),await b(r(c,`vitest.config.ts`),pt()),await b(r(c,`README.md`),mt(t,a,i)),await b(r(c,`CLAUDE.md`),ht(t,a,i)),await b(r(c,`AGENTS.md`),gt(t,a,i)),await b(r(c,`kickjs-skills.md`),_t(t,a,i)),e.installDeps){console.log(`\n Installing dependencies with ${i}...\n`);try{h(`${i} install`,{cwd:c,stdio:`inherit`}),console.log(`
|
|
2834
|
+
Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${i} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-DzmDwZvN.mjs`).then(e=>e.r);await e({cwd:c,allowDuplicates:!0,silent:!0})}catch{}if(e.initGit)try{h(`git init`,{cwd:c,stdio:`pipe`}),h(`git branch -M main`,{cwd:c,stdio:`pipe`}),h(`git add -A`,{cwd:c,stdio:`pipe`}),h(`git commit -m "chore: initial commit from kick new"`,{cwd:c,stdio:`pipe`}),l(`Git repository initialized`)}catch{l(`Warning: git init failed (git may not be installed)`)}console.log(`
|
|
2835
|
+
Project scaffolded successfully!`),console.log();let d=c!==process.cwd();l(`Next steps:`),d&&l(` cd ${t}`),e.installDeps||l(` ${i} install`);let f={rest:`kick g module user`,ddd:`kick g module user --repo drizzle`,cqrs:`kick g module user --pattern cqrs`,minimal:`# add your routes to src/index.ts`};l(` ${f[a]??f.rest}`),l(` kick dev`),l(``),l(`Commands:`),l(` kick dev Start dev server with Vite HMR`),l(` kick build Production build via Vite`),l(` kick start Run production build`),l(``),l(`Generators:`),l(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),l(` kick g scaffold <n> <f..> CRUD module from field definitions`),l(` kick g controller <name> Standalone controller`),l(` kick g service <name> @Service() class`),l(` kick g middleware <name> Express middleware`),l(` kick g guard <name> Route guard (auth, roles, etc.)`),l(` kick g adapter <name> AppAdapter with lifecycle hooks`),l(` kick g dto <name> Zod DTO schema`),a===`cqrs`&&l(` kick g job <name> Queue job processor`),l(` kick g config Generate kick.config.ts`),l(``),l(`Add packages:`),l(` kick add <pkg> Install a KickJS package + peers`),l(` kick add --list Show all available packages`),l(``),l(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),l(``)}function wt(e){return e}function Tt(e){return k(e).replace(/-/g,`_`)}function Et(e){let t=e.cwd??process.cwd(),n=e.pluralize??!0,r=D(e.name),i=O(e.name),a=k(e.name),o=Tt(e.name),s={name:e.name,pascal:r,camel:i,kebab:a,snake:o,modulesDir:e.modulesDir??`src/modules`,cwd:t,args:e.args??[],flags:e.flags??{}};if(n){let e=A(a);s.pluralKebab=e,s.pluralPascal=D(e),s.pluralCamel=O(e)}return s}function Dt(e,t){return i(e.cwd,t)}async function Ot(e){return import(_(e).href)}const kt=new Map;async function At(e){let t=kt.get(e);if(t)return t;let n=jt(e);return kt.set(e,n),n}async function jt(n){let r=i(n,`package.json`);if(!a(r))return{generators:[],loaded:[],failed:[]};let o=Mt(JSON.parse(await l(r,`utf-8`))),s=e(i(n,`package.json`)),c=[],u=[],d=[];for(let e of o){let n;try{n=s.resolve(`${e}/package.json`)}catch{continue}let r;try{r=JSON.parse(await l(n,`utf-8`))}catch(t){d.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!r.kickjs?.generators)continue;let o=r.kickjs.generators,f=i(t(n),o);if(!a(f)){d.push({source:e,reason:`kickjs.generators points to missing file: ${o}`});continue}let p;try{p=await Ot(f)}catch(t){d.push({source:e,reason:`failed to import manifest: ${t}`});continue}let m=p.default;if(!Array.isArray(m)){d.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of m){if(!Nt(t)){d.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}c.push({source:e,spec:t})}u.push(e)}return{generators:c,loaded:u,failed:d}}function Mt(e){let t=new Set;for(let n of[e.dependencies,e.devDependencies,e.peerDependencies])if(n)for(let e of Object.keys(n))t.add(e);return Array.from(t)}function Nt(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function Pt(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return Lt(r.spec,r.source,e,n);let i=It(await At(n),e.generatorName);return i?Lt(i.spec,i.source,e,n):null}async function Ft(e,t=[]){let n=await At(e),r=new Set(t.map(e=>e.spec.name)),i=n.generators.filter(e=>!r.has(e.spec.name));return{generators:[...t,...i],loaded:n.loaded,failed:n.failed}}function It(e,t){return e.generators.find(e=>e.spec.name===t)}async function Lt(e,t,n,r){let i=Et({name:n.itemName,args:n.args,flags:n.flags,modulesDir:n.modulesDir,pluralize:n.pluralize,cwd:r}),a=await e.files(i),o=[];for(let e of a){let t=Dt(i,e.path);await b(t,e.content),o.push(t)}return{files:o,source:t}}export{ue as A,k as C,E as D,se as E,oe as F,C as I,y as L,le as M,ae as N,de as O,f as P,b as R,O as S,T,Ge as _,Ct as a,A as b,_t as c,et as d,$e as f,Y as g,q as h,wt as i,fe as j,ce as k,nt as l,Je as m,Pt as n,gt as o,Qe as p,Et as r,ht as s,Ft as t,tt as u,We as v,D as w,j as x,M as y};
|
|
2836
|
+
//# sourceMappingURL=generator-extension-Ds2fzYZS.mjs.map
|