@forinda/kickjs-cli 5.8.7 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-docs-C3deMUsF.mjs → agent-docs-wxgO-e4t.mjs} +3 -3
- package/dist/{agent-docs-C3deMUsF.mjs.map → agent-docs-wxgO-e4t.mjs.map} +1 -1
- package/dist/{builtins-1ZYIel1L.mjs → builtins-D7wPBRuN.mjs} +2 -2
- package/dist/cli.mjs +48 -40
- package/dist/{config-Bo4xxPHs.mjs → config-BXTsAmnY.mjs} +3 -3
- package/dist/{config-Bo4xxPHs.mjs.map → config-BXTsAmnY.mjs.map} +1 -1
- package/dist/{generator-extension-D4D7ANu6.mjs → doctor-BX8eDq-O.mjs} +81 -73
- package/dist/doctor-BX8eDq-O.mjs.map +1 -0
- package/dist/index.d.mts +139 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{plugin-CGr3DJ01.mjs → plugin-C4EmAaDi.mjs} +3 -3
- package/dist/{plugin-CGr3DJ01.mjs.map → plugin-C4EmAaDi.mjs.map} +1 -1
- package/dist/{project-docs-B5xYM3MX.mjs → project-docs-CGn7Z7h9.mjs} +2 -2
- package/dist/{project-docs-B5xYM3MX.mjs.map → project-docs-CGn7Z7h9.mjs.map} +1 -1
- package/dist/{project-root-C8msA9Mw.mjs → project-root-DFhXihBq.mjs} +3 -3
- package/dist/{project-root-C8msA9Mw.mjs.map → project-root-DFhXihBq.mjs.map} +1 -1
- package/dist/{rolldown-runtime-BMnC1RSc.mjs → rolldown-runtime-DEdkb7-k.mjs} +1 -1
- package/dist/{run-plugins-BiLXFAaa.mjs → run-plugins-CPnfwUUk.mjs} +74 -74
- package/dist/{run-plugins-BiLXFAaa.mjs.map → run-plugins-CPnfwUUk.mjs.map} +1 -1
- package/dist/{typegen-CL2GzEgc.mjs → typegen-C6c4B6mA.mjs} +4 -4
- package/dist/{typegen-CL2GzEgc.mjs.map → typegen-C6c4B6mA.mjs.map} +1 -1
- package/dist/{types-BtdFlcP3.mjs → types-BhbgPiYM.mjs} +2 -2
- package/dist/{types-BtdFlcP3.mjs.map → types-BhbgPiYM.mjs.map} +1 -1
- package/package.json +4 -4
- package/dist/generator-extension-D4D7ANu6.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @forinda/kickjs-cli v5.
|
|
2
|
+
* @forinda/kickjs-cli v5.9.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Felix Orinda
|
|
5
5
|
*
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
-
import{b as e,
|
|
11
|
+
import{b as e,c as t,d as n,g as r,l as i,o as a,s as o,v as s}from"./project-docs-CGn7Z7h9.mjs";import{i as c}from"./config-BXTsAmnY.mjs";import{t as l}from"./project-root-DFhXihBq.mjs";import{createRequire as u}from"node:module";import{dirname as d,join as f,relative as p,resolve as m}from"node:path";import{existsSync as h,readFileSync as g,readdirSync as _,statSync as v}from"node:fs";import{readFile as y,writeFile as b}from"node:fs/promises";import x from"pluralize";import{execFileSync as S,execSync as C}from"node:child_process";import{fileURLToPath as ee,pathToFileURL as te}from"node:url";function w(e){return e.replace(/[-_\s]+(.)?/g,(e,t)=>t?t.toUpperCase():``).replace(/^(.)/,e=>e.toUpperCase())}function T(e){let t=w(e);return t.charAt(0).toLowerCase()+t.slice(1)}function E(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).replace(/[\s_]+/g,`-`).toLowerCase()}function D(e){return x.plural(e)}function ne(e){return x.plural(e)}function O(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}const re={inmemory:`in-memory`,drizzle:`Drizzle`,prisma:`Prisma`};function k(e){return e.charAt(0).toUpperCase()+e.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase())}function ie(e){return e.replace(/([a-z])([A-Z])/g,`$1-$2`).toLowerCase()}function A(e){return re[e]??k(e)}function j(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]??`${k(n)}${e}Repository`,repoFile:i[n]??`${ie(n)}-${t}`}}function M(e){return e??`define`}function ae(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=j(t,n,i),c=M(a),l=`/**
|
|
12
12
|
* ${t} Module
|
|
13
13
|
*
|
|
14
14
|
* Self-contained feature module following Domain-Driven Design (DDD).
|
|
@@ -18,7 +18,7 @@ import{b as e,g as t,l as n,o as r,s as i,v as a}from"./project-docs-B5xYM3MX.mj
|
|
|
18
18
|
* presentation/ — HTTP controllers (entry points)
|
|
19
19
|
* application/ — Use cases (orchestration) and DTOs (validation)
|
|
20
20
|
* domain/ — Entities, value objects, repository interfaces, domain services
|
|
21
|
-
* infrastructure/ — Repository implementations (currently ${
|
|
21
|
+
* infrastructure/ — Repository implementations (currently ${A(i)})
|
|
22
22
|
*/`,u=`import { ${t.toUpperCase()}_REPOSITORY } from './domain/repositories/${n}.repository'
|
|
23
23
|
import { ${o} } from './infrastructure/repositories/${s}.repository'
|
|
24
24
|
import { ${t}Controller } from './presentation/${n}.controller'
|
|
@@ -52,7 +52,7 @@ export class ${t}Module implements AppModule {
|
|
|
52
52
|
/**
|
|
53
53
|
* Register module dependencies in the DI container.
|
|
54
54
|
* Bind repository interface tokens to their implementations here.
|
|
55
|
-
* Currently wired to ${
|
|
55
|
+
* Currently wired to ${A(i)}. To swap implementations, change the factory target.
|
|
56
56
|
*/
|
|
57
57
|
register(container: Container): void {
|
|
58
58
|
container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
|
|
@@ -78,7 +78,7 @@ export const ${t}Module = defineModule({
|
|
|
78
78
|
/**
|
|
79
79
|
* Register module dependencies in the DI container.
|
|
80
80
|
* Bind repository interface tokens to their implementations here.
|
|
81
|
-
* Currently wired to ${
|
|
81
|
+
* Currently wired to ${A(i)}. To swap implementations, change the factory target.
|
|
82
82
|
*/
|
|
83
83
|
register(container) {
|
|
84
84
|
container.registerFactory(${t.toUpperCase()}_REPOSITORY, () =>
|
|
@@ -95,7 +95,7 @@ ${d}
|
|
|
95
95
|
},
|
|
96
96
|
}),
|
|
97
97
|
})
|
|
98
|
-
`}function
|
|
98
|
+
`}function oe(e){let{pascal:t,kebab:n,plural:r=``,repo:i,style:a}=e,{repoClass:o,repoFile:s}=j(t,n,i),c=M(a),l=`/**
|
|
99
99
|
* ${t} Module
|
|
100
100
|
*
|
|
101
101
|
* REST module with a flat folder structure.
|
|
@@ -167,7 +167,7 @@ ${d}
|
|
|
167
167
|
},
|
|
168
168
|
}),
|
|
169
169
|
})
|
|
170
|
-
`}function
|
|
170
|
+
`}function se(e){let{pascal:t,kebab:n,plural:r=``,style:i}=e,a=M(i),o=` /**
|
|
171
171
|
* Declare HTTP routes. Return value shape:
|
|
172
172
|
*
|
|
173
173
|
* - \`path\` — URL prefix for this route set.
|
|
@@ -207,7 +207,7 @@ ${o}
|
|
|
207
207
|
},
|
|
208
208
|
}),
|
|
209
209
|
})
|
|
210
|
-
`}function
|
|
210
|
+
`}function ce(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'
|
|
211
211
|
import { ApiTags } from '@forinda/kickjs-swagger'
|
|
212
212
|
import { Create${t}UseCase } from '../application/use-cases/create-${n}.use-case'
|
|
213
213
|
import { Get${t}UseCase } from '../application/use-cases/get-${n}.use-case'
|
|
@@ -270,7 +270,7 @@ export class ${t}Controller {
|
|
|
270
270
|
ctx.noContent()
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
|
-
`}function
|
|
273
|
+
`}function le(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'
|
|
274
274
|
import { ApiTags } from '@forinda/kickjs-swagger'
|
|
275
275
|
import { ${t}Service } from './${n}.service'
|
|
276
276
|
import { create${t}Schema } from './dtos/create-${n}.dto'
|
|
@@ -325,14 +325,14 @@ export class ${t}Controller {
|
|
|
325
325
|
ctx.noContent()
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
|
-
`}function
|
|
328
|
+
`}function ue(e){let{pascal:t}=e;return`import type { QueryParamsConfig } from '@forinda/kickjs'
|
|
329
329
|
|
|
330
330
|
export const ${t.toUpperCase()}_QUERY_CONFIG: QueryParamsConfig = {
|
|
331
331
|
filterable: ['name'],
|
|
332
332
|
sortable: ['name', 'createdAt'],
|
|
333
333
|
searchable: ['name'],
|
|
334
334
|
}
|
|
335
|
-
`}function
|
|
335
|
+
`}function N(e){let{pascal:t}=e;return`import { z } from 'zod'
|
|
336
336
|
|
|
337
337
|
/**
|
|
338
338
|
* Create ${t} DTO — Zod schema for validating POST request bodies.
|
|
@@ -348,20 +348,20 @@ export const create${t}Schema = z.object({
|
|
|
348
348
|
})
|
|
349
349
|
|
|
350
350
|
export type Create${t}DTO = z.infer<typeof create${t}Schema>
|
|
351
|
-
`}function
|
|
351
|
+
`}function P(e){let{pascal:t}=e;return`import { z } from 'zod'
|
|
352
352
|
|
|
353
353
|
export const update${t}Schema = z.object({
|
|
354
354
|
name: z.string().min(1).max(200).optional(),
|
|
355
355
|
})
|
|
356
356
|
|
|
357
357
|
export type Update${t}DTO = z.infer<typeof update${t}Schema>
|
|
358
|
-
`}function
|
|
358
|
+
`}function F(e){let{pascal:t}=e;return`export interface ${t}ResponseDTO {
|
|
359
359
|
id: string
|
|
360
360
|
name: string
|
|
361
361
|
createdAt: string
|
|
362
362
|
updatedAt: string
|
|
363
363
|
}
|
|
364
|
-
`}function
|
|
364
|
+
`}function de(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`create-${n}.use-case.ts`,content:`/**
|
|
365
365
|
* Create ${t} Use Case
|
|
366
366
|
*
|
|
367
367
|
* Application layer — orchestrates a single business operation.
|
|
@@ -439,7 +439,7 @@ export class Delete${t}UseCase {
|
|
|
439
439
|
await this.repo.delete(id)
|
|
440
440
|
}
|
|
441
441
|
}
|
|
442
|
-
`}]}function
|
|
442
|
+
`}]}function I(e){let{pascal:t,kebab:n,dtoPrefix:r=`../../application/dtos`,tokenScope:i=`app`}=e;return`/**
|
|
443
443
|
* ${t} Repository Interface
|
|
444
444
|
*
|
|
445
445
|
* Defines the contract for data access.
|
|
@@ -474,7 +474,7 @@ export interface I${t}Repository {
|
|
|
474
474
|
* adopters must NOT use the reserved \`'kick/'\` namespace.
|
|
475
475
|
*/
|
|
476
476
|
export const ${t.toUpperCase()}_REPOSITORY = createToken<I${t}Repository>('${i}/${t}/repository')
|
|
477
|
-
`}function
|
|
477
|
+
`}function L(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
|
|
478
478
|
* In-Memory ${t} Repository
|
|
479
479
|
*
|
|
480
480
|
* Implements the repository interface using a Map.
|
|
@@ -534,7 +534,7 @@ export class InMemory${t}Repository implements I${t}Repository {
|
|
|
534
534
|
this.store.delete(id)
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
|
-
`}function
|
|
537
|
+
`}function R(e){let{pascal:t,kebab:n,repoType:r=``,repoPrefix:i=`../../domain/repositories`,dtoPrefix:a=`../../application/dtos`}=e,o=r.charAt(0).toUpperCase()+r.slice(1).replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
|
|
538
538
|
* ${o} ${t} Repository
|
|
539
539
|
*
|
|
540
540
|
* Stub implementation for a custom '${r}' repository.
|
|
@@ -603,7 +603,7 @@ export class ${o}${t}Repository implements I${t}Repository {
|
|
|
603
603
|
this.store.delete(id)
|
|
604
604
|
}
|
|
605
605
|
}
|
|
606
|
-
`}function
|
|
606
|
+
`}function fe(e){let{pascal:t,kebab:n}=e;return`/**
|
|
607
607
|
* ${t} Domain Service
|
|
608
608
|
*
|
|
609
609
|
* Domain layer — contains business rules that don't belong to a single entity.
|
|
@@ -626,7 +626,7 @@ export class ${t}DomainService {
|
|
|
626
626
|
}
|
|
627
627
|
}
|
|
628
628
|
}
|
|
629
|
-
`}function
|
|
629
|
+
`}function pe(e){let{pascal:t,kebab:n}=e;return`/**
|
|
630
630
|
* ${t} Entity
|
|
631
631
|
*
|
|
632
632
|
* Domain layer — the core business object.
|
|
@@ -695,7 +695,7 @@ export class ${t} {
|
|
|
695
695
|
}
|
|
696
696
|
}
|
|
697
697
|
}
|
|
698
|
-
`}function
|
|
698
|
+
`}function me(e){let{pascal:t}=e;return`/**
|
|
699
699
|
* ${t} ID Value Object
|
|
700
700
|
*
|
|
701
701
|
* Domain layer — wraps a primitive ID with type safety and validation.
|
|
@@ -729,7 +729,7 @@ export class ${t}Id {
|
|
|
729
729
|
return this.value === other.value
|
|
730
730
|
}
|
|
731
731
|
}
|
|
732
|
-
`}function
|
|
732
|
+
`}function z(e){let{pascal:t,kebab:n,plural:r=``}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
|
|
733
733
|
import { Container } from '@forinda/kickjs'
|
|
734
734
|
|
|
735
735
|
describe('${t}Controller', () => {
|
|
@@ -781,7 +781,7 @@ describe('${t}Controller', () => {
|
|
|
781
781
|
})
|
|
782
782
|
})
|
|
783
783
|
})
|
|
784
|
-
`}function
|
|
784
|
+
`}function B(e){let{pascal:t,kebab:n,plural:r=``,repoPrefix:i=`../infrastructure/repositories/in-memory-${n}.repository`}=e;return`import { describe, it, expect, beforeEach } from 'vitest'
|
|
785
785
|
import { InMemory${t}Repository } from '${i}'
|
|
786
786
|
|
|
787
787
|
describe('InMemory${t}Repository', () => {
|
|
@@ -843,7 +843,7 @@ describe('InMemory${t}Repository', () => {
|
|
|
843
843
|
expect(found).toBeNull()
|
|
844
844
|
})
|
|
845
845
|
})
|
|
846
|
-
`}function
|
|
846
|
+
`}function he(e){let{pascal:t,kebab:n}=e;return`import { Service, Inject, HttpException } from '@forinda/kickjs'
|
|
847
847
|
import type { ParsedQuery } from '@forinda/kickjs'
|
|
848
848
|
import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from './${n}.repository'
|
|
849
849
|
import type { ${t}ResponseDTO } from './dtos/${n}-response.dto'
|
|
@@ -880,14 +880,14 @@ export class ${t}Service {
|
|
|
880
880
|
await this.repo.delete(id)
|
|
881
881
|
}
|
|
882
882
|
}
|
|
883
|
-
`}function
|
|
883
|
+
`}function V(e){let{pascal:t}=e;return`import type { QueryFieldConfig } from '@forinda/kickjs'
|
|
884
884
|
|
|
885
885
|
export const ${t.toUpperCase()}_QUERY_CONFIG: QueryFieldConfig = {
|
|
886
886
|
filterable: ['name'],
|
|
887
887
|
sortable: ['name', 'createdAt'],
|
|
888
888
|
searchable: ['name'],
|
|
889
889
|
}
|
|
890
|
-
`}function
|
|
890
|
+
`}function ge(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=`/**
|
|
891
891
|
* ${t} Module — CQRS Pattern
|
|
892
892
|
*
|
|
893
893
|
* Separates read (queries) and write (commands) operations.
|
|
@@ -966,7 +966,7 @@ ${p}
|
|
|
966
966
|
},
|
|
967
967
|
}),
|
|
968
968
|
})
|
|
969
|
-
`}function
|
|
969
|
+
`}function _e(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'
|
|
970
970
|
import { ApiTags } from '@forinda/kickjs-swagger'
|
|
971
971
|
import { Create${t}Command } from './commands/create-${n}.command'
|
|
972
972
|
import { Update${t}Command } from './commands/update-${n}.command'
|
|
@@ -1029,7 +1029,7 @@ export class ${t}Controller {
|
|
|
1029
1029
|
ctx.noContent()
|
|
1030
1030
|
}
|
|
1031
1031
|
}
|
|
1032
|
-
`}function
|
|
1032
|
+
`}function ve(e){let{pascal:t,kebab:n}=e;return[{file:`create-${n}.command.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
|
|
1033
1033
|
import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
|
|
1034
1034
|
import type { Create${t}DTO } from '../dtos/create-${n}.dto'
|
|
1035
1035
|
import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
|
|
@@ -1083,7 +1083,7 @@ export class Delete${t}Command {
|
|
|
1083
1083
|
this.events.emit('${n}.deleted', { id })
|
|
1084
1084
|
}
|
|
1085
1085
|
}
|
|
1086
|
-
`}]}function
|
|
1086
|
+
`}]}function ye(e){let{pascal:t,kebab:n,plural:r=``,pluralPascal:i=``}=e;return[{file:`get-${n}.query.ts`,content:`import { Service, Inject } from '@forinda/kickjs'
|
|
1087
1087
|
import { ${t.toUpperCase()}_REPOSITORY, type I${t}Repository } from '../${n}.repository'
|
|
1088
1088
|
import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
|
|
1089
1089
|
|
|
@@ -1111,7 +1111,7 @@ export class List${i}Query {
|
|
|
1111
1111
|
return this.repo.findPaginated(parsed)
|
|
1112
1112
|
}
|
|
1113
1113
|
}
|
|
1114
|
-
`}]}function
|
|
1114
|
+
`}]}function be(e){let{pascal:t,kebab:n}=e;return[{file:`${n}.events.ts`,content:`import { Service } from '@forinda/kickjs'
|
|
1115
1115
|
import { EventEmitter } from 'node:events'
|
|
1116
1116
|
import type { ${t}ResponseDTO } from '../dtos/${n}-response.dto'
|
|
1117
1117
|
|
|
@@ -1197,7 +1197,7 @@ export class On${t}ChangeHandler {
|
|
|
1197
1197
|
})
|
|
1198
1198
|
}
|
|
1199
1199
|
}
|
|
1200
|
-
`}]}function
|
|
1200
|
+
`}]}function H(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e;return`/**
|
|
1201
1201
|
* Drizzle ${t} Repository
|
|
1202
1202
|
*
|
|
1203
1203
|
* Implements the repository interface using Drizzle ORM.
|
|
@@ -1279,7 +1279,7 @@ export class Drizzle${t}Repository implements I${t}Repository {
|
|
|
1279
1279
|
throw new Error('Drizzle ${t} repository not yet implemented')
|
|
1280
1280
|
}
|
|
1281
1281
|
}
|
|
1282
|
-
`}function
|
|
1282
|
+
`}function xe(e){let{pascal:t,kebab:n}=e;return`import type { DrizzleQueryParamsConfig } from '@forinda/kickjs-drizzle'
|
|
1283
1283
|
// TODO: Import your schema table and reference actual columns for type safety
|
|
1284
1284
|
// import { ${n}s } from '@/db/schema'
|
|
1285
1285
|
|
|
@@ -1297,7 +1297,7 @@ export const ${t.toUpperCase()}_QUERY_CONFIG: DrizzleQueryParamsConfig = {
|
|
|
1297
1297
|
// ${n}s.name,
|
|
1298
1298
|
],
|
|
1299
1299
|
}
|
|
1300
|
-
`}function
|
|
1300
|
+
`}function U(e){let{pascal:t,kebab:n,repoPrefix:r=`../../domain/repositories`,dtoPrefix:i=`../../application/dtos`}=e,a=n.replace(/-([a-z])/g,(e,t)=>t.toUpperCase());return`/**
|
|
1301
1301
|
* Prisma ${t} Repository
|
|
1302
1302
|
*
|
|
1303
1303
|
* Implements the repository interface using Prisma Client.
|
|
@@ -1355,7 +1355,7 @@ export class Prisma${t}Repository implements I${t}Repository {
|
|
|
1355
1355
|
await this.prisma.${a}.deleteMany({ where: { id } })
|
|
1356
1356
|
}
|
|
1357
1357
|
}
|
|
1358
|
-
`}function
|
|
1358
|
+
`}function Se(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'
|
|
1359
1359
|
// Side-effect import — registers the extended env schema with kickjs
|
|
1360
1360
|
// **before** any controller / service / @Value gets resolved. Without
|
|
1361
1361
|
// this line ConfigService.get('YOUR_KEY') returns undefined because the
|
|
@@ -1425,14 +1425,14 @@ export const app = await bootstrap({
|
|
|
1425
1425
|
express.json(),
|
|
1426
1426
|
],
|
|
1427
1427
|
})
|
|
1428
|
-
`}}}function
|
|
1428
|
+
`}}}function Ce(){return`import { defineModules } from '@forinda/kickjs'
|
|
1429
1429
|
import { HelloModule } from './hello/hello.module'
|
|
1430
1430
|
|
|
1431
1431
|
// Remove HelloModule and run: kick g module <name>
|
|
1432
1432
|
// \`defineModules()\` returns a chainable list — \`kick g module\` appends
|
|
1433
1433
|
// \`.mount(NewModule())\` to the chain on every generation.
|
|
1434
1434
|
export const modules = defineModules().mount(HelloModule())
|
|
1435
|
-
`}function
|
|
1435
|
+
`}function we(){return`import { defineEnv, loadEnv } from '@forinda/kickjs/config'
|
|
1436
1436
|
import { z } from 'zod'
|
|
1437
1437
|
|
|
1438
1438
|
/**
|
|
@@ -1467,7 +1467,7 @@ const envSchema = defineEnv((base) =>
|
|
|
1467
1467
|
export const env = loadEnv(envSchema)
|
|
1468
1468
|
|
|
1469
1469
|
export default envSchema
|
|
1470
|
-
`}function
|
|
1470
|
+
`}function Te(){return`import { Service } from '@forinda/kickjs'
|
|
1471
1471
|
|
|
1472
1472
|
@Service()
|
|
1473
1473
|
export class HelloService {
|
|
@@ -1479,7 +1479,7 @@ export class HelloService {
|
|
|
1479
1479
|
return { status: 'ok', uptime: process.uptime() }
|
|
1480
1480
|
}
|
|
1481
1481
|
}
|
|
1482
|
-
`}function
|
|
1482
|
+
`}function Ee(){return`import { Controller, Get, Autowired, type Ctx } from '@forinda/kickjs'
|
|
1483
1483
|
import { HelloService } from './hello.service'
|
|
1484
1484
|
|
|
1485
1485
|
// \`Ctx<KickRoutes.HelloController['<method>']>\` is generated by
|
|
@@ -1501,7 +1501,7 @@ export class HelloController {
|
|
|
1501
1501
|
ctx.json(this.helloService.healthCheck())
|
|
1502
1502
|
}
|
|
1503
1503
|
}
|
|
1504
|
-
`}function
|
|
1504
|
+
`}function De(){return`import { defineModule } from '@forinda/kickjs'
|
|
1505
1505
|
import { HelloController } from './hello.controller'
|
|
1506
1506
|
|
|
1507
1507
|
export const HelloModule = defineModule({
|
|
@@ -1522,7 +1522,7 @@ export const HelloModule = defineModule({
|
|
|
1522
1522
|
},
|
|
1523
1523
|
}),
|
|
1524
1524
|
})
|
|
1525
|
-
`}function
|
|
1525
|
+
`}function Oe(e,t=`inmemory`,n=`pnpm`){return`import { defineConfig } from '@forinda/kickjs-cli'
|
|
1526
1526
|
|
|
1527
1527
|
export default defineConfig({
|
|
1528
1528
|
pattern: '${e}',
|
|
@@ -1566,7 +1566,7 @@ export default defineConfig({
|
|
|
1566
1566
|
},
|
|
1567
1567
|
],
|
|
1568
1568
|
})
|
|
1569
|
-
`}async function
|
|
1569
|
+
`}async function ke(e){let{pascal:t,kebab:n,plural:r,style:i,write:a}=e;await a(`${n}.module.ts`,se({pascal:t,kebab:n,plural:r,style:i})),await a(`${n}.controller.ts`,`import { Controller, Get, type Ctx } from '@forinda/kickjs'
|
|
1570
1570
|
|
|
1571
1571
|
// \`Ctx<KickRoutes.${t}Controller['<method>']>\` is generated by
|
|
1572
1572
|
// \`kick typegen\` (auto-run on \`kick dev\`).
|
|
@@ -1578,19 +1578,19 @@ export class ${t}Controller {
|
|
|
1578
1578
|
ctx.json({ message: '${t} list' })
|
|
1579
1579
|
}
|
|
1580
1580
|
}
|
|
1581
|
-
`)}async function
|
|
1582
|
-
import { ${n}Module } from '${
|
|
1581
|
+
`)}async function Ae(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`,oe({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,V({pascal:t,kebab:n})),await u(`${n}.controller.ts`,le({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`${n}.service.ts`,he({pascal:t,kebab:n})),await u(`dtos/create-${n}.dto.ts`,N({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,P({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,F({pascal:t,kebab:n})),await u(`${n}.repository.ts`,I({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let d={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},f={inmemory:()=>L({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>H({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},p=d[a]??`${E(a)}-${n}`,m=f[a]??(()=>R({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`,L({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,z({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,B({pascal:t,kebab:n,plural:r,repoPrefix:`../${d.inmemory??`in-memory-${n}`}.repository`})))}async function je(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`,ge({pascal:t,kebab:n,plural:r,repo:a,style:l})),await u(`${n}.constants.ts`,V({pascal:t,kebab:n})),await u(`${n}.controller.ts`,_e({pascal:t,kebab:n,plural:r,pluralPascal:i})),await u(`dtos/create-${n}.dto.ts`,N({pascal:t,kebab:n})),await u(`dtos/update-${n}.dto.ts`,P({pascal:t,kebab:n})),await u(`dtos/${n}-response.dto.ts`,F({pascal:t,kebab:n}));let d=ve({pascal:t,kebab:n});for(let e of d)await u(`commands/${e.file}`,e.content);let f=ye({pascal:t,kebab:n,plural:r,pluralPascal:i});for(let e of f)await u(`queries/${e.file}`,e.content);let p=be({pascal:t,kebab:n});for(let e of p)await u(`events/${e.file}`,e.content);await u(`${n}.repository.ts`,I({pascal:t,kebab:n,dtoPrefix:`./dtos`,tokenScope:c}));let m={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},h={inmemory:()=>L({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),drizzle:()=>H({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`}),prisma:()=>U({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`,prismaClientPath:s})},g=m[a]??`${E(a)}-${n}`,_=h[a]??(()=>R({pascal:t,kebab:n,repoType:a,repoPrefix:`.`,dtoPrefix:`./dtos`}));await u(`${g}.repository.ts`,_()),o||(a!==`inmemory`&&await u(`in-memory-${n}.repository.ts`,L({pascal:t,kebab:n,repoPrefix:`.`,dtoPrefix:`./dtos`})),await u(`__tests__/${n}.controller.test.ts`,z({pascal:t,kebab:n,plural:r})),await u(`__tests__/${n}.repository.test.ts`,B({pascal:t,kebab:n,plural:r,repoPrefix:`../${m.inmemory??`in-memory-${n}`}.repository`})))}async function Me(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`,ae({pascal:t,kebab:n,plural:r,repo:a,style:u})),await d(`constants.ts`,a===`drizzle`?xe({pascal:t,kebab:n}):ue({pascal:t,kebab:n})),await d(`presentation/${n}.controller.ts`,ce({pascal:t,kebab:n,plural:r,pluralPascal:i})),await d(`application/dtos/create-${n}.dto.ts`,N({pascal:t,kebab:n})),await d(`application/dtos/update-${n}.dto.ts`,P({pascal:t,kebab:n})),await d(`application/dtos/${n}-response.dto.ts`,F({pascal:t,kebab:n}));let f=de({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`,I({pascal:t,kebab:n,tokenScope:l})),await d(`domain/services/${n}-domain.service.ts`,fe({pascal:t,kebab:n}));let p={inmemory:`in-memory-${n}`,drizzle:`drizzle-${n}`,prisma:`prisma-${n}`},m={inmemory:()=>L({pascal:t,kebab:n}),drizzle:()=>H({pascal:t,kebab:n}),prisma:()=>U({pascal:t,kebab:n,prismaClientPath:c})},h=p[a]??`${E(a)}-${n}`,g=m[a]??(()=>R({pascal:t,kebab:n,repoType:a}));await d(`infrastructure/repositories/${h}.repository.ts`,g()),o||(await d(`domain/entities/${n}.entity.ts`,pe({pascal:t,kebab:n})),await d(`domain/value-objects/${n}-id.vo.ts`,me({pascal:t,kebab:n}))),s||(a!==`inmemory`&&await d(`infrastructure/repositories/in-memory-${n}.repository.ts`,L({pascal:t,kebab:n})),await d(`__tests__/${n}.controller.test.ts`,z({pascal:t,kebab:n,plural:r})),await d(`__tests__/${n}.repository.test.ts`,B({pascal:t,kebab:n,plural:r})))}function Ne(e){return e?typeof e==`string`?e:e.name:`inmemory`}async function Pe(t){let{name:n,modulesDir:a,noEntity:c,noTests:l,repo:u=`inmemory`,force:d,dryRun:p}=t,m=t.pluralize!==!1,h=t.pattern??`ddd`;t.minimal&&(h=`minimal`);let g=E(n),_=w(n),v=m?D(g):g,y=m?ne(_):_,b=f(a,v),x=[],S=d??!1,C={kebab:g,pascal:_,plural:v,pluralPascal:y,moduleDir:b,repo:u,noEntity:c??!1,noTests:l??!1,prismaClientPath:t.prismaClientPath??`@prisma/client`,tokenScope:t.tokenScope??`app`,style:t.style??`define`,write:async(t,n)=>{let a=f(b,t);if(p){x.push(a);return}if(!S&&await s(a)&&!await o({message:`File exists: ${r.dim(t)}. Overwrite?`,initialValue:!1})){i.warn(`Skipped: ${t}`);return}await e(a,n),x.push(a)},files:x};switch(h){case`minimal`:await ke(C);break;case`rest`:await Ae(C);break;case`cqrs`:await je(C);break;default:await Me(C);break}return p||await Fe(a,_,v,g,C.style),x}async function Fe(t,n,r,i,a=`define`){let o=f(t,`index.ts`),c=await s(o),l=`./${r}/${i}.module`,u=a===`class`?`${n}Module`:`${n}Module()`;if(!c){await e(o,a===`class`?`import type { AppModuleEntry } from '@forinda/kickjs'
|
|
1582
|
+
import { ${n}Module } from '${l}'
|
|
1583
1583
|
|
|
1584
|
-
export const modules: AppModuleEntry[] = [${
|
|
1584
|
+
export const modules: AppModuleEntry[] = [${u}]
|
|
1585
1585
|
`:`import { defineModules } from '@forinda/kickjs'
|
|
1586
|
-
import { ${n}Module } from '${
|
|
1587
|
-
|
|
1588
|
-
export const modules = defineModules().mount(${
|
|
1589
|
-
`);return}let
|
|
1590
|
-
`,e);
|
|
1591
|
-
`+
|
|
1592
|
-
`+
|
|
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
|
|
1586
|
+
import { ${n}Module } from '${l}'
|
|
1587
|
+
|
|
1588
|
+
export const modules = defineModules().mount(${u})
|
|
1589
|
+
`);return}let d=await y(o,`utf-8`),p=`import { ${n}Module } from '${l}'`,m=O(l);if(!RegExp(`^import\\s*\\{[^}]*\\b${O(n)}Module\\b[^}]*\\}\\s*from\\s*['"]${m}['"]`,`m`).test(d)){let e=d.lastIndexOf(`import `);if(e!==-1){let t=d.indexOf(`
|
|
1590
|
+
`,e);d=d.slice(0,t+1)+p+`
|
|
1591
|
+
`+d.slice(t+1)}else d=p+`
|
|
1592
|
+
`+d}let h=G(d);if(h){let e=d.slice(h.rhsStart,h.rhsEnd+1);RegExp(`\\b${O(n)}Module\\b`).test(e)||(d=W(d,u))}else d=W(d,u);await b(o,d,`utf-8`)}function W(e,t){let n=G(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 G(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=Le(e,n);return t===-1?null:{shape:`array`,rhsStart:n,rhsEnd:t}}if(e.slice(n,n+13)===`defineModules`){let t=Ie(e,n);return t===-1?null:{shape:`chain`,rhsStart:n,rhsEnd:t-1,chainEnd:t}}return null}function Ie(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=q(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=q(e,t);if(n===-1)break;i=n+1}return i}function K(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 Le(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=K(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 q(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=K(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 Re(t){let{name:n,outDir:r}=t,i=E(n),a=w(n),o=[],s=f(r,`${i}.adapter.ts`);return await e(s,`import {
|
|
1594
1594
|
defineAdapter,
|
|
1595
1595
|
type AdapterContext,
|
|
1596
1596
|
type AdapterMiddleware,
|
|
@@ -1759,9 +1759,9 @@ export const ${a}Adapter = defineAdapter<${a}AdapterConfig>({
|
|
|
1759
1759
|
}
|
|
1760
1760
|
},
|
|
1761
1761
|
})
|
|
1762
|
-
`),o.push(s),o}const
|
|
1762
|
+
`),o.push(s),o}const ze={controller:`presentation`,service:`domain/services`,dto:`application/dtos`,guard:`presentation/guards`,middleware:`middleware`},Be={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`},Ve={controller:``,service:``,dto:`dtos`,guard:`guards`,middleware:`middleware`,command:`commands`,query:`queries`,event:`events`};function J(e){let{type:t,outDir:n,moduleName:r,modulesDir:i=`src/modules`,defaultDir:a,pattern:o=`ddd`,shouldPluralize:s=!0}=e;if(n)return m(n);if(r){let e=o===`ddd`?ze:o===`cqrs`?Ve:Be,n=E(r),a=s?D(n):n,c=e[t]??``,l=f(i,a);return m(c?f(l,c):l)}return m(a)}async function He(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=J({type:`middleware`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/middleware`,pattern:a,shouldPluralize:t.pluralize??!0}),s=E(n),c=T(n),l=[],u=f(o,`${s}.middleware.ts`);return await e(u,`import type { Request, Response, NextFunction } from 'express'
|
|
1763
1763
|
|
|
1764
|
-
export interface ${
|
|
1764
|
+
export interface ${w(n)}Options {
|
|
1765
1765
|
// Add configuration options here. The factory below closes over the
|
|
1766
1766
|
// resolved options object; pass them at the call site —
|
|
1767
1767
|
// \`${c}({ foo: 'bar' })\` — and the closure preserves them across
|
|
@@ -1769,7 +1769,7 @@ export interface ${b(n)}Options {
|
|
|
1769
1769
|
}
|
|
1770
1770
|
|
|
1771
1771
|
/**
|
|
1772
|
-
* ${
|
|
1772
|
+
* ${w(n)} middleware.
|
|
1773
1773
|
*
|
|
1774
1774
|
* Usage in bootstrap (fires on every request):
|
|
1775
1775
|
* middleware: [${c}()]
|
|
@@ -1801,7 +1801,7 @@ export interface ${b(n)}Options {
|
|
|
1801
1801
|
* Usage with @Middleware decorator:
|
|
1802
1802
|
* @Middleware(${c}())
|
|
1803
1803
|
*/
|
|
1804
|
-
export function ${c}(options: ${
|
|
1804
|
+
export function ${c}(options: ${w(n)}Options = {}) {
|
|
1805
1805
|
return (req: Request, res: Response, next: NextFunction) => {
|
|
1806
1806
|
// Implement your middleware logic here. \`options\` is captured by
|
|
1807
1807
|
// closure — log or read it anywhere in this handler body.
|
|
@@ -1809,11 +1809,11 @@ export function ${c}(options: ${b(n)}Options = {}) {
|
|
|
1809
1809
|
next()
|
|
1810
1810
|
}
|
|
1811
1811
|
}
|
|
1812
|
-
`),
|
|
1812
|
+
`),l.push(u),l}async function Ue(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=J({type:`guard`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/guards`,pattern:a,shouldPluralize:t.pluralize??!0}),s=E(n),c=T(n),l=w(n),u=[],d=f(o,`${s}.guard.ts`);return await e(d,`import { Container, HttpException } from '@forinda/kickjs'
|
|
1813
1813
|
import type { RequestContext } from '@forinda/kickjs'
|
|
1814
1814
|
|
|
1815
1815
|
/**
|
|
1816
|
-
* ${
|
|
1816
|
+
* ${l} guard.
|
|
1817
1817
|
*
|
|
1818
1818
|
* Guards protect routes by checking conditions before the handler runs.
|
|
1819
1819
|
* Return early with an error response to block access.
|
|
@@ -1845,7 +1845,7 @@ export async function ${c}Guard(ctx: RequestContext, next: () => void): Promise<
|
|
|
1845
1845
|
ctx.res.status(401).json({ message: 'Invalid or expired token' })
|
|
1846
1846
|
}
|
|
1847
1847
|
}
|
|
1848
|
-
`),
|
|
1848
|
+
`),u.push(d),u}async function We(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=J({type:`service`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/services`,pattern:a,shouldPluralize:t.pluralize??!0}),s=E(n),c=w(n),l=[],u=f(o,`${s}.service.ts`);return await e(u,`import { Service } from '@forinda/kickjs'
|
|
1849
1849
|
|
|
1850
1850
|
@Service()
|
|
1851
1851
|
export class ${c}Service {
|
|
@@ -1854,7 +1854,7 @@ export class ${c}Service {
|
|
|
1854
1854
|
// @Inject(MY_REPO) private readonly repo: IMyRepository,
|
|
1855
1855
|
// ) {}
|
|
1856
1856
|
}
|
|
1857
|
-
`),
|
|
1857
|
+
`),l.push(u),l}async function Ge(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=J({type:`controller`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/controllers`,pattern:a,shouldPluralize:t.pluralize??!0}),s=E(n),c=w(n),l=[],u=f(o,`${s}.controller.ts`);return await e(u,`import { Controller, Get, Post, type Ctx } from '@forinda/kickjs'
|
|
1858
1858
|
|
|
1859
1859
|
// \`Ctx<KickRoutes.${c}Controller['<method>']>\` is generated by
|
|
1860
1860
|
// \`kick typegen\` (auto-run on \`kick dev\`). After the first run, your IDE
|
|
@@ -1875,15 +1875,15 @@ export class ${c}Controller {
|
|
|
1875
1875
|
ctx.created({ message: '${c} created', data: ctx.body })
|
|
1876
1876
|
}
|
|
1877
1877
|
}
|
|
1878
|
-
`),
|
|
1878
|
+
`),l.push(u),l}async function Ke(t){let{name:n,moduleName:r,modulesDir:i,pattern:a}=t,o=J({type:`dto`,outDir:t.outDir,moduleName:r,modulesDir:i,defaultDir:`src/dtos`,pattern:a,shouldPluralize:t.pluralize??!0}),s=E(n),c=w(n),l=T(n),u=[],d=f(o,`${s}.dto.ts`);return await e(d,`import { z } from 'zod'
|
|
1879
1879
|
|
|
1880
|
-
export const ${
|
|
1880
|
+
export const ${l}Schema = z.object({
|
|
1881
1881
|
// Define your schema fields here
|
|
1882
1882
|
name: z.string().min(1).max(200),
|
|
1883
1883
|
})
|
|
1884
1884
|
|
|
1885
|
-
export type ${c}DTO = z.infer<typeof ${
|
|
1886
|
-
`),
|
|
1885
|
+
export type ${c}DTO = z.infer<typeof ${l}Schema>
|
|
1886
|
+
`),u.push(d),u}const qe={swagger:`@forinda/kickjs-swagger`,ws:`@forinda/kickjs-ws`,queue:`@forinda/kickjs-queue`,devtools:`@forinda/kickjs-devtools`};function Y(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 Je(e,t,n,r=[]){let i={"@forinda/kickjs":Y(n,`@forinda/kickjs`),dotenv:`^17.3.1`,express:`^5.1.0`,"reflect-metadata":`^0.2.2`,zod:`^4.3.6`};for(let e of r){let t=qe[e];t&&!i[t]&&(i[t]=Y(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":Y(n,`@forinda/kickjs-cli`),"@forinda/kickjs-vite":Y(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 Ye(){return`import { defineConfig } from 'vite'
|
|
1887
1887
|
import { resolve } from 'node:path'
|
|
1888
1888
|
import swc from 'unplugin-swc'
|
|
1889
1889
|
import { kickjsVitePlugin, envWatchPlugin } from '@forinda/kickjs-vite'
|
|
@@ -1913,7 +1913,7 @@ export default defineConfig({
|
|
|
1913
1913
|
},
|
|
1914
1914
|
},
|
|
1915
1915
|
})
|
|
1916
|
-
`}function
|
|
1916
|
+
`}function Xe(){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 Ze(){return JSON.stringify({semi:!1,singleQuote:!0,trailingComma:`all`,printWidth:100,tabWidth:2},null,2)}function Qe(){return`# https://editorconfig.org
|
|
1917
1917
|
root = true
|
|
1918
1918
|
|
|
1919
1919
|
[*]
|
|
@@ -1926,14 +1926,14 @@ insert_final_newline = true
|
|
|
1926
1926
|
|
|
1927
1927
|
[*.md]
|
|
1928
1928
|
trim_trailing_whitespace = false
|
|
1929
|
-
`}function
|
|
1929
|
+
`}function $e(){return`node_modules/
|
|
1930
1930
|
dist/
|
|
1931
1931
|
.env
|
|
1932
1932
|
coverage/
|
|
1933
1933
|
.DS_Store
|
|
1934
1934
|
*.tsbuildinfo
|
|
1935
1935
|
.kickjs/
|
|
1936
|
-
`}function
|
|
1936
|
+
`}function et(){return`# Auto-detect text files and normalise line endings to LF
|
|
1937
1937
|
* text=auto eol=lf
|
|
1938
1938
|
|
|
1939
1939
|
# Explicitly mark generated / binary files
|
|
@@ -1951,11 +1951,11 @@ coverage/
|
|
|
1951
1951
|
pnpm-lock.yaml -diff linguist-generated
|
|
1952
1952
|
yarn.lock -diff linguist-generated
|
|
1953
1953
|
package-lock.json -diff linguist-generated
|
|
1954
|
-
`}function
|
|
1954
|
+
`}function tt(){return`PORT=3000
|
|
1955
1955
|
NODE_ENV=development
|
|
1956
|
-
`}function
|
|
1956
|
+
`}function nt(){return`PORT=3000
|
|
1957
1957
|
NODE_ENV=development
|
|
1958
|
-
`}function
|
|
1958
|
+
`}function rt(){return`import { defineConfig } from 'vitest/config'
|
|
1959
1959
|
import swc from 'unplugin-swc'
|
|
1960
1960
|
|
|
1961
1961
|
export default defineConfig({
|
|
@@ -1966,7 +1966,15 @@ export default defineConfig({
|
|
|
1966
1966
|
include: ['src/**/*.test.ts'],
|
|
1967
1967
|
},
|
|
1968
1968
|
})
|
|
1969
|
-
`}const
|
|
1970
|
-
Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${
|
|
1971
|
-
Project scaffolded successfully!`),console.log();let m=
|
|
1972
|
-
|
|
1969
|
+
`}const it=d(ee(import.meta.url)),X=JSON.parse(g(f(it,`..`,`package.json`),`utf-8`)),at=`^${X.version}`,ot=[`@forinda/kickjs`,`@forinda/kickjs-cli`,`@forinda/kickjs-vite`,`@forinda/kickjs-swagger`,`@forinda/kickjs-ws`,`@forinda/kickjs-queue`,`@forinda/kickjs-devtools`,`@forinda/kickjs-testing`];async function st(){let e=await Promise.all(ot.map(async e=>{try{let t=S(`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,at]}));return Object.fromEntries(e)}async function ct(t){let{name:n,directory:r,packageManager:i=`pnpm`,template:o=`rest`,defaultRepo:s=`inmemory`,packages:c=[]}=t,l=r,u=e=>console.log(` ${e}`);console.log(`\n Creating KickJS project: ${n}\n`),u(`Resolving package versions...`);let d=await st();await e(f(l,`package.json`),Je(n,o,d,c)),await e(f(l,`vite.config.ts`),Ye()),await e(f(l,`tsconfig.json`),Xe()),await e(f(l,`.prettierrc`),Ze()),await e(f(l,`.editorconfig`),Qe()),await e(f(l,`.gitignore`),$e()),await e(f(l,`.gitattributes`),et()),await e(f(l,`.env`),tt()),await e(f(l,`.env.example`),nt()),await e(f(l,`src/config/index.ts`),we()),await e(f(l,`src/index.ts`),Se(n,o,X.version,c)),await e(f(l,`src/modules/index.ts`),Ce()),await e(f(l,`src/modules/hello/hello.service.ts`),Te()),await e(f(l,`src/modules/hello/hello.controller.ts`),Ee()),await e(f(l,`src/modules/hello/hello.module.ts`),De()),await e(f(l,`kick.config.ts`),Oe(o,s,i)),await e(f(l,`vitest.config.ts`),rt()),await e(f(l,`README.md`),a(n,o,i));let{generateAgentDocs:p}=await import(`./agent-docs-wxgO-e4t.mjs`).then(e=>e.t);if(await p({outDir:l,name:n,pm:i,template:o,only:`all`,force:!0}),t.installDeps){console.log(`\n Installing dependencies with ${i}...\n`);try{C(`${i} install`,{cwd:l,stdio:`inherit`}),console.log(`
|
|
1970
|
+
Dependencies installed successfully!`)}catch{console.log(`\n Warning: ${i} install failed. Run it manually.`)}}try{let{runTypegen:e}=await import(`./typegen-C6c4B6mA.mjs`).then(e=>e.r);await e({cwd:l,allowDuplicates:!0,silent:!0})}catch{}if(t.initGit)try{C(`git init`,{cwd:l,stdio:`pipe`}),C(`git branch -M main`,{cwd:l,stdio:`pipe`}),C(`git add -A`,{cwd:l,stdio:`pipe`}),C(`git commit -m "chore: initial commit from kick new"`,{cwd:l,stdio:`pipe`}),u(`Git repository initialized`)}catch{u(`Warning: git init failed (git may not be installed)`)}console.log(`
|
|
1971
|
+
Project scaffolded successfully!`),console.log();let m=l!==process.cwd();u(`Next steps:`),m&&u(` cd ${n}`),t.installDeps||u(` ${i} install`);let h={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`};u(` ${h[o]??h.rest}`),u(` kick dev`),u(``),u(`Commands:`),u(` kick dev Start dev server with Vite HMR`),u(` kick build Production build via Vite`),u(` kick start Run production build`),u(``),u(`Generators:`),u(` kick g module <name> Full DDD module (controller, DTOs, use-cases, repo)`),u(` kick g scaffold <n> <f..> CRUD module from field definitions`),u(` kick g controller <name> Standalone controller`),u(` kick g service <name> @Service() class`),u(` kick g middleware <name> Express middleware`),u(` kick g guard <name> Route guard (auth, roles, etc.)`),u(` kick g adapter <name> AppAdapter with lifecycle hooks`),u(` kick g dto <name> Zod DTO schema`),o===`cqrs`&&u(` kick g job <name> Queue job processor`),u(` kick g config Generate kick.config.ts`),u(``),u(`Add packages:`),u(` kick add <pkg> Install a KickJS package + peers`),u(` kick add --list Show all available packages`),u(``),u(`Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing`),u(``)}function lt(e){return e}function ut(e){return E(e).replace(/-/g,`_`)}function Z(e){let t=e.cwd??process.cwd(),n=e.projectRoot??l(t),r=e.pluralize??!0,i=w(e.name),a=T(e.name),o=E(e.name),s=ut(e.name),c={name:e.name,pascal:i,camel:a,kebab:o,snake:s,modulesDir:e.modulesDir??`src/modules`,cwd:t,projectRoot:n,args:e.args??[],flags:e.flags??{}};if(r){let e=D(o);c.pluralKebab=e,c.pluralPascal=w(e),c.pluralCamel=T(e)}return c}function dt(e,t){return m(e.cwd,t)}async function ft(e){return import(te(e).href)}const Q=new Map;async function pt(e){let t=Q.get(e);if(t)return t;let n=mt(e);return Q.set(e,n),n}async function mt(e){let t=m(e,`package.json`);if(!h(t))return{generators:[],loaded:[],failed:[]};let n=ht(JSON.parse(await y(t,`utf-8`))),r=u(m(e,`package.json`)),i=[],a=[],o=[];for(let e of n){let t;try{t=r.resolve(`${e}/package.json`)}catch{continue}let n;try{n=JSON.parse(await y(t,`utf-8`))}catch(t){o.push({source:e,reason:`failed to parse package.json: ${t}`});continue}if(!n.kickjs?.generators)continue;let s=n.kickjs.generators,c=m(d(t),s);if(!h(c)){o.push({source:e,reason:`kickjs.generators points to missing file: ${s}`});continue}let l;try{l=await ft(c)}catch(t){o.push({source:e,reason:`failed to import manifest: ${t}`});continue}let u=l.default;if(!Array.isArray(u)){o.push({source:e,reason:`manifest's default export is not an array of GeneratorSpec`});continue}for(let t of u){if(!gt(t)){o.push({source:e,reason:`manifest entry is not a valid GeneratorSpec (missing name/files)`});continue}i.push({source:e,spec:t})}a.push(e)}return{generators:i,loaded:a,failed:o}}function ht(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 gt(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.name==`string`&&typeof t.files==`function`}async function _t(e,t=[]){let n=e.cwd??process.cwd(),r=t.find(t=>t.spec.name===e.generatorName);if(r)return bt(r.spec,r.source,e,n);let i=yt(await pt(n),e.generatorName);return i?bt(i.spec,i.source,e,n):null}async function vt(e,t=[]){let n=await pt(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 yt(e,t){return e.generators.find(e=>e.spec.name===t)}async function bt(t,n,r,i){let a=Z({name:r.itemName,args:r.args,flags:r.flags,modulesDir:r.modulesDir,pluralize:r.pluralize,cwd:i,projectRoot:r.projectRoot}),o=await t.files(a),s=[];for(let t of o){let n=dt(a,t.path);await e(n,t.content),s.push(n)}return{files:s,source:n}}function xt(e){return e}function St(e){return e}function Ct(e){try{return JSON.parse(g(e,`utf-8`))}catch{return null}}function $(e){try{return g(e,`utf-8`)}catch{return null}}function wt(e){let t=$(f(e,`tsconfig.json`));if(!t)return null;let n=t.replace(/\/\*[\s\S]*?\*\//g,``).replace(/\/\/.*$/gm,``),r;try{r=JSON.parse(n)}catch{return null}if(typeof r?.extends==`string`){let t=Tt(e,r.extends);if(t){let e=Ct(t)??{};r.compilerOptions={...e.compilerOptions,...r.compilerOptions}}}return r}function Tt(e,t){if(t.startsWith(`.`)){let n=m(e,t);return h(n)?n:null}let n=f(e,`node_modules`,t);return h(n)?n:null}function Et(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function Dt(){let e=process.version,t=Number.parseInt(e.replace(/^v/,``).split(`.`)[0],10);return Number.isNaN(t)||t<20?{name:`Node version`,status:`fail`,message:e,fix:`KickJS requires Node 20 or newer.
|
|
1972
|
+
Install a supported version via nvm / fnm / volta.`}:{name:`Node version`,status:`pass`,message:e}}function Ot(e){if(!e.pkg)return{name:`@forinda/kickjs installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]?{name:`@forinda/kickjs installed`,status:`pass`,message:t[`@forinda/kickjs`]}:{name:`@forinda/kickjs installed`,status:`fail`,fix:"This directory does not look like a KickJS project — `@forinda/kickjs` is not in your package.json. Run `kick doctor` from the project root, or scaffold a fresh project with `kick new <name>`."}}function kt(e){if(!e.pkg)return null;let t={...e.pkg.dependencies,...e.pkg.peerDependencies};return t[`@forinda/kickjs`]&&!t.express?{name:`express installed`,status:`fail`,fix:"`@forinda/kickjs` declares `express` as a required peer dependency, but your package.json does not include it. Install: pnpm add express"}:t.express?{name:`express installed`,status:`pass`,message:t.express}:null}function At(e){if(!e.pkg)return{name:`reflect-metadata installed`,status:`warn`,message:`no package.json`};let t={...e.pkg.dependencies,...e.pkg.peerDependencies,...e.pkg.devDependencies};return t[`reflect-metadata`]?{name:`reflect-metadata installed`,status:`pass`,message:t[`reflect-metadata`]}:{name:`reflect-metadata installed`,status:`fail`,fix:`KickJS decorators require the reflect-metadata polyfill.
|
|
1973
|
+
Install it: pnpm add reflect-metadata
|
|
1974
|
+
Then import it at the top of src/index.ts:
|
|
1975
|
+
|
|
1976
|
+
import 'reflect-metadata'
|
|
1977
|
+
// ... rest of bootstrap`}}function jt(e){if(!e.tsconfig)return[{name:`tsconfig.json present`,status:`fail`,fix:"Create a tsconfig.json with `experimentalDecorators: true` and `emitDecoratorMetadata: true`. `kick new` scaffolds one automatically."}];let t=e.tsconfig.compilerOptions??{},n=[];return n.push(t.experimentalDecorators===!0?{name:`tsconfig: experimentalDecorators`,status:`pass`}:{name:`tsconfig: experimentalDecorators`,status:`fail`,fix:'Add `"experimentalDecorators": true` to compilerOptions in tsconfig.json. Without it, @Service / @Controller / @Get etc. don\'t register any metadata at compile time.'}),n.push(t.emitDecoratorMetadata===!0?{name:`tsconfig: emitDecoratorMetadata`,status:`pass`}:{name:`tsconfig: emitDecoratorMetadata`,status:`fail`,fix:'Add `"emitDecoratorMetadata": true` to compilerOptions in tsconfig.json. The DI container uses this metadata for constructor-parameter injection.'}),n}function Mt(e){let t=[`src/env.ts`,`src/env/index.ts`,`src/config/env.ts`,`src/config/index.ts`].map(t=>f(e.cwd,t)).filter(e=>h(e)).filter(e=>/\bloadEnv\s*\(/.test($(e)??``));if(t.length===0)return null;let n=[`src/index.ts`,`src/main.ts`].map(t=>f(e.cwd,t)).find(e=>h(e));if(!n)return{name:`env wiring`,status:`warn`,message:`env-init file exists but no src/index.ts or src/main.ts found`};let r=$(n)??``,i=d(n),a=[];for(let e of t){let t=p(i,e).replace(/\\/g,`/`).replace(/\.ts$/,``),n=t.startsWith(`.`)?t:`./`+t,r=n.replace(/\/index$/,``);a.push(n,r);let o=e.replace(/\\/g,`/`).match(/\/src\/(.+?)(?:\.ts)?$/);if(o){let e=`@/`+o[1],t=e.replace(/\/index$/,``);a.push(e,t)}}let o=-1;for(let e of new Set(a)){let t=RegExp(`^import\\s+(?:.*?from\\s+)?['"]${Et(e)}['"]`,`m`),n=r.match(t);n&&n.index!==void 0&&(o===-1||n.index<o)&&(o=n.index)}let s=r.search(/\bbootstrap\s*\(/),c=t.map(t=>p(e.cwd,t).replace(/\\/g,`/`)).join(`, `);return o===-1?{name:`env wiring`,status:`fail`,message:c,fix:`An env-init file (${c}) calls \`loadEnv(...)\` but \`${p(e.cwd,n).replace(/\\/g,`/`)}\` doesn't import it.\nWithout this, ConfigService.get('X') returns undefined while @Value('X') works via process.env fallback — a half-broken config you won't notice until something is missing.\n\nFix: add a side-effect import at the top of ${p(e.cwd,n).replace(/\\/g,`/`)} (above bootstrap()), pointing at one of the detected files. For example:\n\n import './env'\n // or\n import './config'\n // or, with the @/ alias:\n import '@/config/env'`}:s!==-1&&o>s?{name:`env wiring`,status:`warn`,message:`env-init imported AFTER bootstrap() — should be before`,fix:`Move the env import above the bootstrap() call so the schema runs before any service reads from ConfigService.`}:{name:`env wiring`,status:`pass`}}function Nt(e,t=Pt){let n=0,r=0,i=[e];for(;i.length>0&&r<t;){let e=i.pop(),a;try{a=_(e,{withFileTypes:!0})}catch{continue}for(let o of a){if(r>=t)break;r++;let a=f(e,o.name);if(o.isDirectory()){i.push(a);continue}try{let e=v(a).mtimeMs;e>n&&(n=e)}catch{}}}return n}const Pt=2e3;function Ft(e){let t=f(e.cwd,`.kickjs`,`types`);if(!h(t))return null;let n=Nt(t);if(n===0)return null;let r=Date.now()-n,i=Math.floor(r/6e4);return i>60?{name:`typegen freshness`,status:`warn`,message:`last updated ${i} minutes ago`,fix:"Re-run `kick typegen` (or `kick dev`, which runs it on every reload) so generated types match the current code."}:{name:`typegen freshness`,status:`pass`,message:i===0?`just now`:`${i}m ago`}}const It=[()=>Dt(),Ot,kt,At,jt,Mt,Ft];async function Lt(e,t={}){let n={cwd:e,pkg:Ct(f(e,`package.json`)),tsconfig:wt(e)},r=[...It,...t.extraChecks??[]],i=[];for(let e of r){let t;try{t=await e(n)}catch(t){i.push({name:e.name||`doctor check`,status:`fail`,message:t instanceof Error?t.message:String(t)});continue}t!=null&&(Array.isArray(t)?i.push(...t):i.push(t))}return i}function Rt(e){switch(e){case`pass`:return r.green(`✔`);case`warn`:return r.yellow(`⚠`);case`fail`:return r.red(`✖`)}}function zt(e){let t=Rt(e.status),n=e.message?` ${r.dim(`(${e.message})`)}`:``;return`${t} ${e.name}${n}`}function Bt(e){return e.split(`
|
|
1978
|
+
`).map(e=>` ${r.dim(`→`)} ${e}`).join(`
|
|
1979
|
+
`)}function Vt(e){return e?.doctor?.checks??[]}function Ht(e){e.command(`doctor`).description(`Pre-flight checks for your KickJS project (dev environment health)`).action(async()=>{let e=process.cwd(),a=Vt(await c(e));t(`KickJS Doctor`);let o=await Lt(e,{extraChecks:a});for(let e of o)i.message(zt(e)),e.fix&&e.status!==`pass`&&i.message(Bt(e.fix));let s=o.filter(e=>e.status===`pass`).length,l=o.filter(e=>e.status===`warn`).length,u=o.filter(e=>e.status===`fail`).length,d=[r.green(`${s} passed`),l>0?r.yellow(`${l} warning${l===1?``:`s`}`):`${l} warnings`,u>0?r.red(`${u} error${u===1?``:`s`}`):`${u} errors`].join(`, `);u>0?(n(`${d} — fix the errors above before running the app`),process.exit(1)):n(l>0?`${d} — review the warnings`:r.green(`${d} — your environment looks good`))})}export{E as C,T as S,Pe as _,_t as a,D as b,ct as c,We as d,Ue as f,G as g,Fe as h,vt as i,Ke as l,Re as m,xt as n,Z as o,He as p,Ht as r,lt as s,St as t,Ge as u,Ne as v,w,ne as x,O as y};
|
|
1980
|
+
//# sourceMappingURL=doctor-BX8eDq-O.mjs.map
|