@forinda/kickjs-cli 4.1.0 → 5.0.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/index.d.mts CHANGED
@@ -19,7 +19,7 @@ interface KickCommandDefinition {
19
19
  aliases?: string[];
20
20
  }
21
21
  /** Project pattern — controls what generators produce and which deps are installed */
22
- type ProjectPattern = 'rest' | 'graphql' | 'ddd' | 'cqrs' | 'minimal';
22
+ type ProjectPattern = 'rest' | 'ddd' | 'cqrs' | 'minimal';
23
23
  /** Package manager used for `kick add` and other dep-installing commands */
24
24
  type PackageManager = 'pnpm' | 'npm' | 'yarn' | 'bun';
25
25
  /** Built-in repository types with first-class code generation support */
@@ -143,7 +143,6 @@ interface KickConfig {
143
143
  /**
144
144
  * Project pattern — controls default generator behavior.
145
145
  * - 'rest' — Express + Swagger (default)
146
- * - 'graphql' — GraphQL + GraphiQL
147
146
  * - 'ddd' — Full DDD modules with use cases, entities, value objects
148
147
  * - 'cqrs' — CQRS with commands, queries, events, WebSocket + queue
149
148
  * - 'minimal' — Bare Express with no scaffolding
@@ -287,7 +286,6 @@ interface GenerateModuleOptions {
287
286
  * Patterns:
288
287
  * rest — flat folder: controller + service + DTOs + repo
289
288
  * ddd — nested DDD: presentation/ application/ domain/ infrastructure/
290
- * graphql — flat folder: resolver + service + DTOs + repo (future)
291
289
  * cqrs — commands, queries, events with WS/queue integration
292
290
  * minimal — just controller + module index
293
291
  */
@@ -367,7 +365,7 @@ interface GenerateDtoOptions {
367
365
  declare function generateDto(options: GenerateDtoOptions): Promise<string[]>;
368
366
  //#endregion
369
367
  //#region src/generators/project.d.ts
370
- type ProjectTemplate = 'rest' | 'graphql' | 'ddd' | 'cqrs' | 'minimal';
368
+ type ProjectTemplate = 'rest' | 'ddd' | 'cqrs' | 'minimal';
371
369
  interface InitProjectOptions {
372
370
  name: string;
373
371
  directory: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/generators/module.ts","../src/generators/adapter.ts","../src/generators/middleware.ts","../src/generators/guard.ts","../src/generators/service.ts","../src/generators/controller.ts","../src/generators/dto.ts","../src/generators/project.ts","../src/generator-extension/define.ts","../src/generator-extension/discover.ts","../src/generator-extension/context.ts","../src/utils/naming.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/generators/module.ts","../src/generators/adapter.ts","../src/generators/middleware.ts","../src/generators/guard.ts","../src/generators/service.ts","../src/generators/controller.ts","../src/generators/dto.ts","../src/generators/project.ts","../src/generator-extension/define.ts","../src/generator-extension/discover.ts","../src/generator-extension/context.ts","../src/utils/naming.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs-cli v4.1.0
2
+ * @forinda/kickjs-cli v5.0.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -1588,54 +1588,9 @@ export class Prisma${pascal}Repository implements I${pascal}Repository {
1588
1588
  */
1589
1589
  function generateEntryFile(name, template, version, packages = []) {
1590
1590
  switch (template) {
1591
- case "graphql": {
1592
- const gqlImports = [];
1593
- const gqlAdapters = [];
1594
- if (packages.includes("devtools")) {
1595
- gqlImports.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`);
1596
- gqlAdapters.push(` DevToolsAdapter(),`);
1597
- }
1598
- if (packages.includes("otel")) {
1599
- gqlImports.push(`import { OtelAdapter } from '@forinda/kickjs-otel'`);
1600
- gqlAdapters.push(` OtelAdapter({ serviceName: '${name}' }),`);
1601
- }
1602
- if (packages.includes("swagger")) {
1603
- gqlImports.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`);
1604
- gqlAdapters.push(` SwaggerAdapter({ info: { title: '${name}', version: '${version}' } }),`);
1605
- }
1606
- return `import 'reflect-metadata'
1607
- // Side-effect import — registers the extended env schema with kickjs
1608
- // **before** any controller / service / @Value gets resolved. Without
1609
- // this line ConfigService.get('YOUR_KEY') returns undefined because the
1610
- // cached schema would still be the base shape. See guide/configuration.
1611
- import './config'
1612
- import { bootstrap } from '@forinda/kickjs'
1613
- import { GraphQLAdapter } from '@forinda/kickjs-graphql'
1614
- ${gqlImports.length ? gqlImports.join("\n") + "\n" : ""}import { modules } from './modules'
1615
-
1616
- // Import your resolvers here
1617
- // import { UserResolver } from './resolvers/user.resolver'
1618
-
1619
- // Export the app for the Vite plugin (dev mode)
1620
- export const app = await bootstrap({
1621
- modules,
1622
- adapters: [
1623
- ${gqlAdapters.length ? gqlAdapters.join("\n") + "\n" : ""} new GraphQLAdapter({
1624
- resolvers: [/* UserResolver */],
1625
- // Add custom type definitions here:
1626
- // typeDefs: userTypeDefs,
1627
- }),
1628
- ],
1629
- })
1630
- `;
1631
- }
1632
1591
  case "cqrs": {
1633
1592
  const cqrsImports = [];
1634
1593
  const cqrsAdapters = [];
1635
- if (packages.includes("otel")) {
1636
- cqrsImports.push(`import { OtelAdapter } from '@forinda/kickjs-otel'`);
1637
- cqrsAdapters.push(` OtelAdapter({ serviceName: '${name}' }),`);
1638
- }
1639
1594
  if (packages.includes("devtools")) {
1640
1595
  cqrsImports.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`);
1641
1596
  cqrsAdapters.push(` DevToolsAdapter(),`);
@@ -1644,10 +1599,6 @@ ${gqlAdapters.length ? gqlAdapters.join("\n") + "\n" : ""} new GraphQLAdapter
1644
1599
  cqrsImports.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`);
1645
1600
  cqrsAdapters.push(` SwaggerAdapter({\n info: { title: '${name}', version: '${version}' },\n }),`);
1646
1601
  }
1647
- if (packages.includes("graphql")) {
1648
- cqrsImports.push(`import { GraphQLAdapter } from '@forinda/kickjs-graphql'`);
1649
- cqrsAdapters.push(` new GraphQLAdapter({ resolvers: [] }),`);
1650
- }
1651
1602
  return `import 'reflect-metadata'
1652
1603
  // Side-effect import — registers the extended env schema with kickjs
1653
1604
  // **before** any controller / service / @Value gets resolved. Without
@@ -1676,14 +1627,6 @@ export const app = await bootstrap({
1676
1627
  imports.push(`import { DevToolsAdapter } from '@forinda/kickjs-devtools'`);
1677
1628
  adapters.push(` DevToolsAdapter(),`);
1678
1629
  }
1679
- if (packages.includes("otel")) {
1680
- imports.push(`import { OtelAdapter } from '@forinda/kickjs-otel'`);
1681
- adapters.push(` OtelAdapter({ serviceName: '${name}' }),`);
1682
- }
1683
- if (packages.includes("graphql")) {
1684
- imports.push(`import { GraphQLAdapter } from '@forinda/kickjs-graphql'`);
1685
- adapters.push(` new GraphQLAdapter({ resolvers: [] }),`);
1686
- }
1687
1630
  return `import 'reflect-metadata'
1688
1631
  // Side-effect import — registers the extended env schema with kickjs
1689
1632
  // **before** any controller / service / @Value gets resolved. Without
@@ -1708,10 +1651,6 @@ export const app = await bootstrap({ modules${adapters.length ? `,\n adapters:
1708
1651
  restImports.push(`import { SwaggerAdapter } from '@forinda/kickjs-swagger'`);
1709
1652
  restAdapters.push(` SwaggerAdapter({\n info: { title: '${name}', version: '${version}' },\n }),`);
1710
1653
  }
1711
- if (packages.includes("otel")) {
1712
- restImports.push(`import { OtelAdapter } from '@forinda/kickjs-otel'`);
1713
- restAdapters.push(` OtelAdapter({ serviceName: '${name}' }),`);
1714
- }
1715
1654
  return `import 'reflect-metadata'
1716
1655
  // Side-effect import — registers the extended env schema with kickjs
1717
1656
  // **before** any controller / service / @Value gets resolved. Without
@@ -2265,7 +2204,6 @@ async function generateDddFiles(ctx) {
2265
2204
  * Patterns:
2266
2205
  * rest — flat folder: controller + service + DTOs + repo
2267
2206
  * ddd — nested DDD: presentation/ application/ domain/ infrastructure/
2268
- * graphql — flat folder: resolver + service + DTOs + repo (future)
2269
2207
  * cqrs — commands, queries, events with WS/queue integration
2270
2208
  * minimal — just controller + module index
2271
2209
  */
@@ -2378,7 +2316,13 @@ async function generateAdapter(options) {
2378
2316
  const pascal = toPascalCase(name);
2379
2317
  const files = [];
2380
2318
  const filePath = join(outDir, `${kebab}.adapter.ts`);
2381
- await writeFileSafe(filePath, `import { defineAdapter, type AdapterContext, type AdapterMiddleware } from '@forinda/kickjs'
2319
+ await writeFileSafe(filePath, `import {
2320
+ defineAdapter,
2321
+ type AdapterContext,
2322
+ type AdapterMiddleware,
2323
+ type ContributorRegistrations,
2324
+ type Constructor,
2325
+ } from '@forinda/kickjs'
2382
2326
 
2383
2327
  /**
2384
2328
  * Configuration for the ${pascal} adapter.
@@ -2399,7 +2343,12 @@ export interface ${pascal}AdapterConfig {
2399
2343
  * factory's call / \`.scoped()\` / \`.async()\` surfaces for free.
2400
2344
  *
2401
2345
  * Hooks into the Application lifecycle to add middleware, routes,
2402
- * or external service connections.
2346
+ * Context Contributors, or external service connections.
2347
+ *
2348
+ * Every lifecycle hook below is OPTIONAL. The scaffold emits all of
2349
+ * them so adopters can browse what's available and delete what they
2350
+ * don't need — \`build()\` returning \`{}\` is also valid for an adapter
2351
+ * that only contributes config defaults.
2403
2352
  *
2404
2353
  * @example
2405
2354
  * \`\`\`ts
@@ -2415,59 +2364,126 @@ export interface ${pascal}AdapterConfig {
2415
2364
  export const ${pascal}Adapter = defineAdapter<${pascal}AdapterConfig>({
2416
2365
  name: '${pascal}Adapter',
2417
2366
  defaults: {
2418
- // Default config values go here
2367
+ // Default config values go here. The adopter's overrides shallow-merge
2368
+ // on top of these before \`build()\` runs.
2419
2369
  },
2420
- build: (_config, { name: _name }) => ({
2421
- /**
2422
- * Return middleware entries that the Application will mount.
2423
- * \`phase\` controls where in the pipeline they run:
2424
- * 'beforeGlobal' | 'afterGlobal' | 'beforeRoutes' | 'afterRoutes'.
2425
- */
2426
- middleware(): AdapterMiddleware[] {
2427
- return [
2428
- // Example: add a custom header to all responses
2429
- // {
2430
- // phase: 'beforeGlobal',
2431
- // handler: (_req, res, next) => {
2432
- // res.setHeader('X-${pascal}', 'true')
2433
- // next()
2434
- // },
2435
- // },
2436
- ]
2437
- },
2438
-
2439
- /**
2440
- * Called before global middleware. Use this to mount routes that
2441
- * bypass the middleware stack (health checks, docs UI, static
2442
- * assets).
2443
- */
2444
- beforeMount(_ctx: AdapterContext): void {
2445
- // Example:
2446
- // _ctx.app.get('/${kebab}/status', (_req, res) => res.json({ status: 'ok' }))
2447
- },
2448
-
2449
- /**
2450
- * Called after modules and routes are registered, before the
2451
- * server starts. Use this for late-stage DI registrations or
2452
- * config validation.
2453
- */
2454
- beforeStart(_ctx: AdapterContext): void {
2455
- // Example: _ctx.container.bindToken(MY_TOKEN, new MyService(_config))
2456
- },
2457
-
2458
- /**
2459
- * Called after the HTTP server is listening. Use this to attach
2460
- * to the raw http.Server (Socket.IO, gRPC, etc).
2461
- */
2462
- afterStart(_ctx: AdapterContext): void {
2463
- // Example: const io = new Server(_ctx.server)
2464
- },
2370
+ build: (_config, { name: _name }) => {
2371
+ // Closures inside \`build()\` are how each adapter instance owns its
2372
+ // own state (database client, Map, timer handle, …). The same
2373
+ // \`_config\` is visible to every hook below.
2465
2374
 
2466
- /** Called on graceful shutdown. Clean up connections. */
2467
- async shutdown(): Promise<void> {
2468
- // Example: await this.pool.end()
2469
- },
2470
- }),
2375
+ return {
2376
+ /**
2377
+ * Express middleware entries the Application mounts at named phases.
2378
+ *
2379
+ * \`phase\` controls where each handler sits in the pipeline:
2380
+ * 'beforeGlobal' | 'afterGlobal' | 'beforeRoutes' | 'afterRoutes'.
2381
+ *
2382
+ * \`path\` (optional) scopes the entry to a path prefix.
2383
+ *
2384
+ * Delete this hook entirely if you don't add middleware.
2385
+ */
2386
+ middleware(): AdapterMiddleware[] {
2387
+ return [
2388
+ // Example: add a custom header to all responses
2389
+ // {
2390
+ // phase: 'beforeGlobal',
2391
+ // handler: (_req, res, next) => {
2392
+ // res.setHeader('X-${pascal}', 'true')
2393
+ // next()
2394
+ // },
2395
+ // },
2396
+ // Example: scope a rate limiter to one path prefix
2397
+ // {
2398
+ // phase: 'beforeRoutes',
2399
+ // path: '/api/v1/auth',
2400
+ // handler: rateLimit({ max: 10 }),
2401
+ // },
2402
+ ]
2403
+ },
2404
+
2405
+ /**
2406
+ * Runs BEFORE global middleware. Mount routes that should bypass the
2407
+ * middleware stack — health checks, docs UI, static assets, OAuth
2408
+ * callbacks. Anything you want reachable even if a global middleware
2409
+ * later in the chain rejects requests.
2410
+ *
2411
+ * Delete this hook if you have no early routes.
2412
+ */
2413
+ beforeMount(_ctx: AdapterContext): void {
2414
+ // Example:
2415
+ // _ctx.app.get('/${kebab}/status', (_req, res) => res.json({ status: 'ok' }))
2416
+ },
2417
+
2418
+ /**
2419
+ * Fires once per controller class as the router mounts. Use this to
2420
+ * collect route metadata for OpenAPI specs, dependency graphs, route
2421
+ * inventories, devtools dashboards.
2422
+ *
2423
+ * Delete this hook unless your adapter introspects the route registry.
2424
+ */
2425
+ onRouteMount(_controllerClass: Constructor, _mountPath: string): void {
2426
+ // Example (Swagger-style): collect routes for the spec.
2427
+ // openApiSpec.addController(_controllerClass, _mountPath)
2428
+ },
2429
+
2430
+ /**
2431
+ * Runs AFTER modules + routes are wired, BEFORE the server starts.
2432
+ * Right place for late-stage DI registrations or final config validation.
2433
+ *
2434
+ * Delete this hook if there's nothing to wire post-modules.
2435
+ */
2436
+ beforeStart(_ctx: AdapterContext): void {
2437
+ // Example: _ctx.container.registerInstance(MY_TOKEN, new MyService(_config))
2438
+ },
2439
+
2440
+ /**
2441
+ * Runs AFTER the HTTP server is listening. The raw \`http.Server\` is
2442
+ * available on \`ctx.server\` — attach upgrade handlers (Socket.IO,
2443
+ * gRPC, GraphQL subscriptions), warm caches, log a banner.
2444
+ *
2445
+ * Delete this hook if you don't need the running server reference.
2446
+ */
2447
+ afterStart(_ctx: AdapterContext): void {
2448
+ // Example: const io = new Server(_ctx.server)
2449
+ },
2450
+
2451
+ /**
2452
+ * Returns Context Contributors to merge into every route's pipeline
2453
+ * at the \`'adapter'\` precedence level. Per-route handlers can
2454
+ * override the value at the method / class / module level.
2455
+ *
2456
+ * Delete this hook unless your adapter ships typed per-request values
2457
+ * (auth user, tenant, locale, feature flags, geo, etc).
2458
+ */
2459
+ contributors(): ContributorRegistrations {
2460
+ return [
2461
+ // Example:
2462
+ // import { defineHttpContextDecorator } from '@forinda/kickjs'
2463
+ // declare module '@forinda/kickjs' { interface ContextMeta { ${kebab}: { id: string } } }
2464
+ // const Load${pascal} = defineHttpContextDecorator({
2465
+ // key: '${kebab}',
2466
+ // resolve: (ctx) => ({ id: ctx.req.headers['x-${kebab}-id'] as string }),
2467
+ // })
2468
+ // return [Load${pascal}.registration]
2469
+ ]
2470
+ },
2471
+
2472
+ /**
2473
+ * Runs on graceful shutdown (SIGINT/SIGTERM). Clean up long-lived
2474
+ * resources the adapter owns: close connections, flush buffers,
2475
+ * cancel timers. The framework runs every adapter's \`shutdown\`
2476
+ * concurrently via \`Promise.allSettled\` — one failure won't block
2477
+ * sibling adapters.
2478
+ *
2479
+ * Delete this hook if your adapter holds no resources.
2480
+ */
2481
+ async shutdown(): Promise<void> {
2482
+ // Example: await this.pool.end()
2483
+ // Example: clearInterval(this.heartbeatTimer)
2484
+ },
2485
+ }
2486
+ },
2471
2487
  })
2472
2488
  `);
2473
2489
  files.push(filePath);
@@ -2741,15 +2757,9 @@ export type ${pascal}DTO = z.infer<typeof ${camel}Schema>
2741
2757
  const PACKAGE_DEPS = {
2742
2758
  auth: "@forinda/kickjs-auth",
2743
2759
  swagger: "@forinda/kickjs-swagger",
2744
- otel: "@forinda/kickjs-otel",
2745
2760
  ws: "@forinda/kickjs-ws",
2746
2761
  queue: "@forinda/kickjs-queue",
2747
- cron: "@forinda/kickjs-cron",
2748
- mailer: "@forinda/kickjs-mailer",
2749
- graphql: "@forinda/kickjs-graphql",
2750
- devtools: "@forinda/kickjs-devtools",
2751
- notifications: "@forinda/kickjs-notifications",
2752
- "multi-tenant": "@forinda/kickjs-multi-tenant"
2762
+ devtools: "@forinda/kickjs-devtools"
2753
2763
  };
2754
2764
  /** Generate package.json with template-aware dependencies */
2755
2765
  function generatePackageJson(name, template, kickjsVersion, packages = []) {
@@ -2762,15 +2772,10 @@ function generatePackageJson(name, template, kickjsVersion, packages = []) {
2762
2772
  pino: "^10.3.1",
2763
2773
  "pino-pretty": "^13.1.3"
2764
2774
  };
2765
- if (template === "graphql") {
2766
- baseDeps["@forinda/kickjs-graphql"] = kickjsVersion;
2767
- baseDeps["graphql"] = "^16.11.0";
2768
- }
2769
2775
  for (const pkg of packages) {
2770
2776
  const dep = PACKAGE_DEPS[pkg];
2771
2777
  if (dep && !baseDeps[dep]) baseDeps[dep] = kickjsVersion;
2772
2778
  }
2773
- if (packages.includes("graphql") && !baseDeps["graphql"]) baseDeps["graphql"] = "^16.11.0";
2774
2779
  return JSON.stringify({
2775
2780
  name,
2776
2781
  version: kickjsVersion.replace("^", ""),
@@ -2970,15 +2975,13 @@ export default defineConfig({
2970
2975
  function generateReadme(name, template, pm) {
2971
2976
  const templateLabels = {
2972
2977
  rest: "REST API",
2973
- graphql: "GraphQL API",
2974
2978
  ddd: "Domain-Driven Design",
2975
2979
  cqrs: "CQRS + Event-Driven",
2976
2980
  minimal: "Minimal"
2977
2981
  };
2978
2982
  const packages = ["@forinda/kickjs", "@forinda/kickjs-vite"];
2979
2983
  if (template !== "minimal") packages.push("@forinda/kickjs-swagger", "@forinda/kickjs-devtools");
2980
- if (template === "graphql") packages.push("@forinda/kickjs-graphql");
2981
- if (template === "cqrs") packages.push("@forinda/kickjs-queue", "@forinda/kickjs-ws", "@forinda/kickjs-otel");
2984
+ if (template === "cqrs") packages.push("@forinda/kickjs-queue", "@forinda/kickjs-ws");
2982
2985
  return `# ${name}
2983
2986
 
2984
2987
  A **${templateLabels[template] ?? "REST API"}** built with [KickJS](https://forinda.github.io/kick-js/) — a decorator-driven Node.js framework on Express 5 and TypeScript.
@@ -3023,11 +3026,11 @@ kick add auth # Authentication (JWT, API key, OAuth)
3023
3026
  kick add swagger # OpenAPI documentation
3024
3027
  kick add ws # WebSocket support
3025
3028
  kick add queue # Background job processing
3026
- kick add mailer # Email sending
3027
- kick add cron # Scheduled tasks
3028
3029
  kick add --list # Show all available packages
3029
3030
  \`\`\`
3030
3031
 
3032
+ For email, scheduled tasks, multi-tenancy, OpenTelemetry, GraphQL, and notifications use the BYO recipes in the [KickJS guides](https://forinda.github.io/kick-js/guide/) — they wire the upstream library through \`defineAdapter()\` / \`definePlugin()\` directly, so you keep control of the integration.
3033
+
3031
3034
  ## Environment Variables
3032
3035
 
3033
3036
  Copy \`.env.example\` to \`.env\` and configure:
@@ -3202,8 +3205,8 @@ mistakes:
3202
3205
  property assignment (\`ctx.tenant = …\`) sticks to the contributor
3203
3206
  instance only — the handler instance never sees it.
3204
3207
  - **Read across instances via \`ctx.set\` / \`ctx.get\`** (or
3205
- \`requestStore.getStore()?.values.get('key')\` from a service that
3206
- has no \`ctx\` reference). \`ctx.req\` works because the underlying
3208
+ \`getRequestValue(key)\` from a service that has no \`ctx\` reference
3209
+ typed via \`MetaValue<K>\`). \`ctx.req\` works because the underlying
3207
3210
  Express request is shared; bespoke property assignments don't.
3208
3211
 
3209
3212
  - **Test isolation** — default to \`Container.create()\` for fresh DI state.
@@ -3271,7 +3274,7 @@ package additions, env access patterns, troubleshooting) is detailed below.
3271
3274
  | Module registry | \`src/modules/index.ts\` |
3272
3275
  | Feature modules | \`src/modules/<module-name>/\` |
3273
3276
  | **Module entry file** | \`src/modules/<name>/<name>.module.ts\` (filename suffix is required — see Vite HMR contract below) |
3274
- ${template === "graphql" ? "| GraphQL resolvers | `src/resolvers/` |\n" : ""}| Env values | \`.env\` |
3277
+ | Env values | \`.env\` |
3275
3278
  | Env schema (Zod) | \`src/config/index.ts\` |
3276
3279
  | TypeScript config | \`tsconfig.json\` |
3277
3280
  | Vite config (HMR) | \`vite.config.ts\` |
@@ -3308,12 +3311,6 @@ ${template === "ddd" ? `\`\`\`
3308
3311
  ├── <name>.repository.ts # Data access
3309
3312
  └── <name>.module.ts # Module definition (implements AppModule)
3310
3313
  \`\`\`
3311
- ` : template === "graphql" ? `\`\`\`
3312
- resolvers/
3313
- ├── <name>.resolver.ts # @Resolver, @Query, @Mutation
3314
- ├── <name>.types.ts # GraphQL type definitions
3315
- └── <name>.service.ts # Business logic
3316
- \`\`\`
3317
3314
  ` : template === "rest" ? `\`\`\`
3318
3315
  <name>/
3319
3316
  ├── <name>.controller.ts # HTTP routes (@Controller)
@@ -3586,15 +3583,7 @@ fast). The \`onError\` hook is async-permitted.
3586
3583
 
3587
3584
  Full guide: <https://forinda.github.io/kick-js/guide/context-decorators>.
3588
3585
 
3589
- ${template === "graphql" ? `### GraphQL
3590
- | Decorator | Purpose |
3591
- |-----------|---------|
3592
- | \`@Resolver()\` | GraphQL resolver class |
3593
- | \`@Query()\` | Query handler |
3594
- | \`@Mutation()\` | Mutation handler |
3595
- | \`@Arg('name')\` | Resolver argument |
3596
-
3597
- ` : ""}${template === "cqrs" ? `### Background Jobs
3586
+ ${template === "cqrs" ? `### Background Jobs
3598
3587
  | Decorator | Purpose |
3599
3588
  |-----------|---------|
3600
3589
  | \`@Job('name')\` | Queue job handler |
@@ -3852,10 +3841,11 @@ Precedence high → low: **method > class > module > adapter > global**.
3852
3841
  Cycles or unmet \`dependsOn\` keys throw \`MissingContributorError\` at boot.
3853
3842
 
3854
3843
  **Critical rules — all stem from the same shared-via-ALS instance model**:
3855
- - Every per-request stage (middleware → contributors → handler) gets its OWN \`RequestContext\` instance, but they all read/write the SAME \`AsyncLocalStorage\`-backed Map (\`requestStore.getStore().values\`).
3844
+ - Every per-request stage (middleware → contributors → handler) gets its OWN \`RequestContext\` instance, but they all read/write the SAME \`AsyncLocalStorage\`-backed bag.
3856
3845
  - **\`resolve\` and \`onError\` must RETURN the value** — the runner writes it via \`ctx.set(key, value)\`. Direct property assignment (\`ctx.tenant = …\`) sticks to one instance only and the handler instance never sees it.
3857
3846
  - \`ctx.set('tenant', x)\` then \`ctx.get('tenant')\` works across instances. \`ctx.req.headers[...]\` works (the underlying Express request is shared).
3858
- - Services can read contributor output without a \`ctx\` reference via \`requestStore.getStore()?.values.get('tenant')\` same Map, no DI plumbing needed.
3847
+ - Services with no \`ctx\` reference: \`getRequestValue('tenant')\` returns \`MetaValue<'tenant'> | undefined\` (typed via the augmented \`ContextMeta\`). For \`requestId\` use \`getRequestStore()\`.
3848
+ - **No \`setRequestValue\` — writes flow through \`ctx.set\` or a contributor's return value.** Avoids "spooky action at a distance" where any service can pollute the per-request bag.
3859
3849
 
3860
3850
  **Don't use this for**: response short-circuit, stream mutation, or
3861
3851
  pre-route-matching work — keep \`@Middleware()\` for those.
@@ -3928,7 +3918,6 @@ async function initProject(options) {
3928
3918
  await writeFileSafe(join(dir, "src/modules/hello/hello.service.ts"), generateHelloService());
3929
3919
  await writeFileSafe(join(dir, "src/modules/hello/hello.controller.ts"), generateHelloController());
3930
3920
  await writeFileSafe(join(dir, "src/modules/hello/hello.module.ts"), generateHelloModule());
3931
- if (template === "graphql") await writeFileSafe(join(dir, "src/resolvers/.gitkeep"), "");
3932
3921
  await writeFileSafe(join(dir, "kick.config.ts"), generateKickConfig(template, defaultRepo, packageManager));
3933
3922
  await writeFileSafe(join(dir, "vitest.config.ts"), generateVitestConfig());
3934
3923
  await writeFileSafe(join(dir, "README.md"), generateReadme(name, template, packageManager));
@@ -3948,7 +3937,7 @@ async function initProject(options) {
3948
3937
  }
3949
3938
  }
3950
3939
  try {
3951
- const { runTypegen } = await import("./typegen-C-H8pg-y.mjs");
3940
+ const { runTypegen } = await import("./typegen-B13guHZF.mjs");
3952
3941
  await runTypegen({
3953
3942
  cwd: dir,
3954
3943
  allowDuplicates: true,
@@ -3984,7 +3973,6 @@ async function initProject(options) {
3984
3973
  if (!options.installDeps) log(` ${packageManager} install`);
3985
3974
  const genHint = {
3986
3975
  rest: "kick g module user",
3987
- graphql: "kick g resolver user",
3988
3976
  ddd: "kick g module user --repo drizzle",
3989
3977
  cqrs: "kick g module user --pattern cqrs",
3990
3978
  minimal: "# add your routes to src/index.ts"
@@ -4006,7 +3994,6 @@ async function initProject(options) {
4006
3994
  log(" kick g guard <name> Route guard (auth, roles, etc.)");
4007
3995
  log(" kick g adapter <name> AppAdapter with lifecycle hooks");
4008
3996
  log(" kick g dto <name> Zod DTO schema");
4009
- if (template === "graphql") log(" kick g resolver <name> GraphQL resolver");
4010
3997
  if (template === "cqrs") log(" kick g job <name> Queue job processor");
4011
3998
  log(" kick g config Generate kick.config.ts");
4012
3999
  log("");
@@ -4014,8 +4001,7 @@ async function initProject(options) {
4014
4001
  log(" kick add <pkg> Install a KickJS package + peers");
4015
4002
  log(" kick add --list Show all available packages");
4016
4003
  log("");
4017
- log("Available: auth, swagger, graphql, drizzle, prisma, ws, cron,");
4018
- log(" queue, mailer, otel, devtools, multi-tenant, notifications, mcp, testing");
4004
+ log("Available: auth, swagger, drizzle, prisma, ws, queue, devtools, mcp, testing");
4019
4005
  log("");
4020
4006
  }
4021
4007
  //#endregion