@buenojs/bueno 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +136 -16
  2. package/dist/cli/{index.js → bin.js} +3036 -1421
  3. package/dist/container/index.js +250 -0
  4. package/dist/context/index.js +219 -0
  5. package/dist/database/index.js +493 -0
  6. package/dist/frontend/index.js +7697 -0
  7. package/dist/health/index.js +364 -0
  8. package/dist/i18n/index.js +345 -0
  9. package/dist/index.js +11043 -6482
  10. package/dist/jobs/index.js +819 -0
  11. package/dist/lock/index.js +367 -0
  12. package/dist/logger/index.js +281 -0
  13. package/dist/metrics/index.js +289 -0
  14. package/dist/middleware/index.js +77 -0
  15. package/dist/migrations/index.js +571 -0
  16. package/dist/modules/index.js +3346 -0
  17. package/dist/notification/index.js +484 -0
  18. package/dist/observability/index.js +331 -0
  19. package/dist/openapi/index.js +776 -0
  20. package/dist/orm/index.js +1356 -0
  21. package/dist/router/index.js +886 -0
  22. package/dist/rpc/index.js +691 -0
  23. package/dist/schema/index.js +400 -0
  24. package/dist/telemetry/index.js +595 -0
  25. package/dist/template/index.js +640 -0
  26. package/dist/templates/index.js +640 -0
  27. package/dist/testing/index.js +1111 -0
  28. package/dist/types/index.js +60 -0
  29. package/package.json +121 -27
  30. package/src/cache/index.ts +2 -1
  31. package/src/cli/bin.ts +2 -2
  32. package/src/cli/commands/build.ts +183 -165
  33. package/src/cli/commands/dev.ts +96 -89
  34. package/src/cli/commands/generate.ts +142 -111
  35. package/src/cli/commands/help.ts +20 -16
  36. package/src/cli/commands/index.ts +3 -6
  37. package/src/cli/commands/migration.ts +124 -105
  38. package/src/cli/commands/new.ts +392 -438
  39. package/src/cli/commands/start.ts +81 -79
  40. package/src/cli/core/args.ts +68 -50
  41. package/src/cli/core/console.ts +89 -95
  42. package/src/cli/core/index.ts +4 -4
  43. package/src/cli/core/prompt.ts +65 -62
  44. package/src/cli/core/spinner.ts +23 -20
  45. package/src/cli/index.ts +46 -38
  46. package/src/cli/templates/database/index.ts +61 -0
  47. package/src/cli/templates/database/mysql.ts +14 -0
  48. package/src/cli/templates/database/none.ts +16 -0
  49. package/src/cli/templates/database/postgresql.ts +14 -0
  50. package/src/cli/templates/database/sqlite.ts +14 -0
  51. package/src/cli/templates/deploy.ts +29 -26
  52. package/src/cli/templates/docker.ts +41 -30
  53. package/src/cli/templates/frontend/index.ts +63 -0
  54. package/src/cli/templates/frontend/none.ts +17 -0
  55. package/src/cli/templates/frontend/react.ts +140 -0
  56. package/src/cli/templates/frontend/solid.ts +134 -0
  57. package/src/cli/templates/frontend/svelte.ts +131 -0
  58. package/src/cli/templates/frontend/vue.ts +130 -0
  59. package/src/cli/templates/generators/index.ts +339 -0
  60. package/src/cli/templates/generators/types.ts +56 -0
  61. package/src/cli/templates/index.ts +35 -2
  62. package/src/cli/templates/project/api.ts +81 -0
  63. package/src/cli/templates/project/default.ts +140 -0
  64. package/src/cli/templates/project/fullstack.ts +111 -0
  65. package/src/cli/templates/project/index.ts +95 -0
  66. package/src/cli/templates/project/minimal.ts +45 -0
  67. package/src/cli/templates/project/types.ts +94 -0
  68. package/src/cli/templates/project/website.ts +263 -0
  69. package/src/cli/utils/fs.ts +55 -41
  70. package/src/cli/utils/index.ts +3 -2
  71. package/src/cli/utils/strings.ts +47 -33
  72. package/src/cli/utils/version.ts +47 -0
  73. package/src/config/env-validation.ts +100 -0
  74. package/src/config/env.ts +169 -41
  75. package/src/config/index.ts +28 -20
  76. package/src/config/loader.ts +25 -16
  77. package/src/config/merge.ts +21 -10
  78. package/src/config/types.ts +545 -25
  79. package/src/config/validation.ts +215 -7
  80. package/src/container/forward-ref.ts +22 -22
  81. package/src/container/index.ts +34 -12
  82. package/src/context/index.ts +11 -1
  83. package/src/database/index.ts +7 -190
  84. package/src/database/orm/builder.ts +457 -0
  85. package/src/database/orm/casts/index.ts +130 -0
  86. package/src/database/orm/casts/types.ts +25 -0
  87. package/src/database/orm/compiler.ts +304 -0
  88. package/src/database/orm/hooks/index.ts +114 -0
  89. package/src/database/orm/index.ts +61 -0
  90. package/src/database/orm/model-registry.ts +59 -0
  91. package/src/database/orm/model.ts +821 -0
  92. package/src/database/orm/relationships/base.ts +146 -0
  93. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  94. package/src/database/orm/relationships/belongs-to.ts +56 -0
  95. package/src/database/orm/relationships/has-many.ts +45 -0
  96. package/src/database/orm/relationships/has-one.ts +41 -0
  97. package/src/database/orm/relationships/index.ts +11 -0
  98. package/src/database/orm/scopes/index.ts +55 -0
  99. package/src/events/__tests__/event-system.test.ts +235 -0
  100. package/src/events/config.ts +238 -0
  101. package/src/events/example-usage.ts +185 -0
  102. package/src/events/index.ts +278 -0
  103. package/src/events/manager.ts +385 -0
  104. package/src/events/registry.ts +182 -0
  105. package/src/events/types.ts +124 -0
  106. package/src/frontend/api-routes.ts +65 -23
  107. package/src/frontend/bundler.ts +76 -34
  108. package/src/frontend/console-client.ts +2 -2
  109. package/src/frontend/console-stream.ts +94 -38
  110. package/src/frontend/dev-server.ts +94 -46
  111. package/src/frontend/file-router.ts +61 -19
  112. package/src/frontend/frameworks/index.ts +37 -10
  113. package/src/frontend/frameworks/react.ts +10 -8
  114. package/src/frontend/frameworks/solid.ts +11 -9
  115. package/src/frontend/frameworks/svelte.ts +15 -9
  116. package/src/frontend/frameworks/vue.ts +13 -11
  117. package/src/frontend/hmr-client.ts +12 -10
  118. package/src/frontend/hmr.ts +146 -103
  119. package/src/frontend/index.ts +14 -5
  120. package/src/frontend/islands.ts +41 -22
  121. package/src/frontend/isr.ts +59 -37
  122. package/src/frontend/layout.ts +36 -21
  123. package/src/frontend/ssr/react.ts +74 -27
  124. package/src/frontend/ssr/solid.ts +54 -20
  125. package/src/frontend/ssr/svelte.ts +48 -14
  126. package/src/frontend/ssr/vue.ts +50 -18
  127. package/src/frontend/ssr.ts +83 -39
  128. package/src/frontend/types.ts +91 -56
  129. package/src/health/index.ts +21 -9
  130. package/src/i18n/engine.ts +305 -0
  131. package/src/i18n/index.ts +38 -0
  132. package/src/i18n/loader.ts +218 -0
  133. package/src/i18n/middleware.ts +164 -0
  134. package/src/i18n/negotiator.ts +162 -0
  135. package/src/i18n/types.ts +158 -0
  136. package/src/index.ts +179 -27
  137. package/src/jobs/drivers/memory.ts +315 -0
  138. package/src/jobs/drivers/redis.ts +459 -0
  139. package/src/jobs/index.ts +30 -0
  140. package/src/jobs/queue.ts +281 -0
  141. package/src/jobs/types.ts +295 -0
  142. package/src/jobs/worker.ts +380 -0
  143. package/src/logger/index.ts +1 -3
  144. package/src/logger/transports/index.ts +62 -22
  145. package/src/metrics/index.ts +25 -16
  146. package/src/migrations/index.ts +9 -0
  147. package/src/modules/filters.ts +13 -17
  148. package/src/modules/guards.ts +49 -26
  149. package/src/modules/index.ts +409 -298
  150. package/src/modules/interceptors.ts +58 -20
  151. package/src/modules/lazy.ts +11 -19
  152. package/src/modules/lifecycle.ts +15 -7
  153. package/src/modules/metadata.ts +15 -5
  154. package/src/modules/pipes.ts +94 -72
  155. package/src/notification/channels/base.ts +68 -0
  156. package/src/notification/channels/email.ts +105 -0
  157. package/src/notification/channels/push.ts +104 -0
  158. package/src/notification/channels/sms.ts +105 -0
  159. package/src/notification/channels/whatsapp.ts +104 -0
  160. package/src/notification/index.ts +48 -0
  161. package/src/notification/service.ts +354 -0
  162. package/src/notification/types.ts +344 -0
  163. package/src/observability/__tests__/observability.test.ts +483 -0
  164. package/src/observability/breadcrumbs.ts +114 -0
  165. package/src/observability/index.ts +136 -0
  166. package/src/observability/interceptor.ts +85 -0
  167. package/src/observability/service.ts +303 -0
  168. package/src/observability/trace.ts +37 -0
  169. package/src/observability/types.ts +196 -0
  170. package/src/openapi/__tests__/decorators.test.ts +335 -0
  171. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  172. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  173. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  174. package/src/openapi/decorators.ts +328 -0
  175. package/src/openapi/document-builder.ts +274 -0
  176. package/src/openapi/index.ts +112 -0
  177. package/src/openapi/metadata.ts +112 -0
  178. package/src/openapi/route-scanner.ts +289 -0
  179. package/src/openapi/schema-generator.ts +256 -0
  180. package/src/openapi/swagger-module.ts +166 -0
  181. package/src/openapi/types.ts +398 -0
  182. package/src/orm/index.ts +10 -0
  183. package/src/rpc/index.ts +3 -1
  184. package/src/schema/index.ts +9 -0
  185. package/src/security/index.ts +15 -6
  186. package/src/ssg/index.ts +9 -8
  187. package/src/telemetry/index.ts +76 -22
  188. package/src/template/index.ts +7 -0
  189. package/src/templates/engine.ts +224 -0
  190. package/src/templates/index.ts +9 -0
  191. package/src/templates/loader.ts +331 -0
  192. package/src/templates/renderers/markdown.ts +212 -0
  193. package/src/templates/renderers/simple.ts +269 -0
  194. package/src/templates/types.ts +154 -0
  195. package/src/testing/index.ts +100 -27
  196. package/src/types/optional-deps.d.ts +347 -187
  197. package/src/validation/index.ts +92 -2
  198. package/src/validation/schemas.ts +536 -0
  199. package/tests/integration/fullstack.test.ts +4 -4
  200. package/tests/unit/database.test.ts +2 -72
  201. package/tests/unit/env-validation.test.ts +166 -0
  202. package/tests/unit/events.test.ts +910 -0
  203. package/tests/unit/i18n.test.ts +455 -0
  204. package/tests/unit/jobs.test.ts +493 -0
  205. package/tests/unit/notification.test.ts +988 -0
  206. package/tests/unit/observability.test.ts +453 -0
  207. package/tests/unit/orm/builder.test.ts +323 -0
  208. package/tests/unit/orm/casts.test.ts +179 -0
  209. package/tests/unit/orm/compiler.test.ts +220 -0
  210. package/tests/unit/orm/eager-loading.test.ts +285 -0
  211. package/tests/unit/orm/hooks.test.ts +191 -0
  212. package/tests/unit/orm/model.test.ts +373 -0
  213. package/tests/unit/orm/relationships.test.ts +303 -0
  214. package/tests/unit/orm/scopes.test.ts +74 -0
  215. package/tests/unit/templates-simple.test.ts +53 -0
  216. package/tests/unit/templates.test.ts +454 -0
  217. package/tests/unit/validation.test.ts +18 -24
  218. package/tsconfig.json +11 -3
@@ -7,108 +7,108 @@
7
7
 
8
8
  import {
9
9
  Container,
10
+ type ForwardRef,
10
11
  type Provider,
11
12
  type Token,
12
- type ForwardRef,
13
13
  forwardRef,
14
+ getContainerMetadata,
15
+ getInjectTokens,
14
16
  isForwardRef,
15
17
  resolveForwardRef,
16
- getInjectTokens,
17
18
  setContainerMetadata,
18
- getContainerMetadata,
19
19
  } from "../container";
20
+ import type { Context } from "../context";
21
+ import { Router } from "../router";
22
+ import type { RouteHandler } from "../types";
23
+ import {
24
+ AllExceptionsFilter,
25
+ Catch,
26
+ type ExceptionFilter,
27
+ type ExecuteFiltersOptions,
28
+ type Filter,
29
+ type FilterFn,
30
+ HttpExceptionFilter,
31
+ NotFoundFilter,
32
+ UseFilters,
33
+ ValidationFilter,
34
+ canHandleException,
35
+ createDefaultErrorResponse,
36
+ createInternalErrorResponse,
37
+ executeFilter,
38
+ findAndExecuteFilter,
39
+ getCatchType,
40
+ getClassFilters,
41
+ getMethodFilters,
42
+ isExceptionFilter,
43
+ isFilterFn,
44
+ } from "./filters";
45
+ import {
46
+ type CanActivate,
47
+ type Guard,
48
+ type GuardFn,
49
+ createForbiddenResponse,
50
+ executeGuards,
51
+ getClassGuards,
52
+ getMethodGuards,
53
+ } from "./guards";
54
+ import {
55
+ type CallHandler,
56
+ type Interceptor,
57
+ type InterceptorFn,
58
+ type NestInterceptor,
59
+ executeInterceptors,
60
+ getClassInterceptors,
61
+ getMethodInterceptors,
62
+ isInterceptorFn,
63
+ isNestInterceptor,
64
+ } from "./interceptors";
20
65
  import {
21
- type LazyModuleLoader,
22
66
  type Constructor as LazyConstructor,
23
- type ModuleLoaderFn,
24
- type LazyModuleMetadata,
25
- LazyModuleLoaderImpl,
26
67
  LazyModule,
27
- ModuleLoader,
68
+ type LazyModuleLoader,
69
+ LazyModuleLoaderImpl,
70
+ type LazyModuleMetadata,
71
+ LazyModuleRegistry,
28
72
  MODULE_LOADER_TOKEN,
73
+ ModuleLoader,
74
+ type ModuleLoaderFn,
29
75
  getLazyMetadata,
30
76
  isLazyModule,
31
- LazyModuleRegistry,
32
77
  } from "./lazy";
33
- import type { Context } from "../context";
34
- import { Router } from "../router";
35
- import type { RouteHandler } from "../types";
36
78
  import {
79
+ type ApplicationLifecycle,
80
+ type BeforeApplicationShutdown,
81
+ type FullLifecycle,
37
82
  LifecycleHookManager,
38
- ShutdownSignalHandler,
39
- type OnModuleInit,
83
+ type OnAfterRequest,
40
84
  type OnApplicationBootstrap,
41
- type OnModuleDestroy,
42
- type BeforeApplicationShutdown,
43
85
  type OnApplicationShutdown,
44
86
  type OnBeforeRequest,
45
- type OnAfterRequest,
87
+ type OnModuleDestroy,
88
+ type OnModuleInit,
46
89
  type OnRequestError,
47
- type ApplicationLifecycle,
48
90
  type RequestLifecycle,
49
- type FullLifecycle,
50
- isOnModuleInit,
51
- isOnApplicationBootstrap,
52
- isOnModuleDestroy,
91
+ ShutdownSignalHandler,
53
92
  isBeforeApplicationShutdown,
93
+ isOnAfterRequest,
94
+ isOnApplicationBootstrap,
54
95
  isOnApplicationShutdown,
55
96
  isOnBeforeRequest,
56
- isOnAfterRequest,
97
+ isOnModuleDestroy,
98
+ isOnModuleInit,
57
99
  isOnRequestError,
58
100
  } from "./lifecycle";
59
101
  import {
60
- type Guard,
61
- type CanActivate,
62
- type GuardFn,
63
- getClassGuards,
64
- getMethodGuards,
65
- executeGuards,
66
- createForbiddenResponse,
67
- } from "./guards";
68
- import {
69
- type Interceptor,
70
- type NestInterceptor,
71
- type InterceptorFn,
72
- type CallHandler,
73
- getClassInterceptors,
74
- getMethodInterceptors,
75
- executeInterceptors,
76
- isNestInterceptor,
77
- isInterceptorFn,
78
- } from "./interceptors";
79
- import {
102
+ type ParameterPipeMetadata,
80
103
  type Pipe,
81
- type PipeTransform,
82
- type PipeFn,
83
104
  type PipeContext,
84
- type ParameterPipeMetadata,
85
- getMethodPipes,
105
+ type PipeFn,
106
+ type PipeTransform,
107
+ createBadRequestResponse,
86
108
  executePipes,
87
109
  extractParameterValue,
88
- createBadRequestResponse,
110
+ getMethodPipes,
89
111
  } from "./pipes";
90
- import {
91
- type Filter,
92
- type ExceptionFilter,
93
- type FilterFn,
94
- type ExecuteFiltersOptions,
95
- UseFilters,
96
- Catch,
97
- getClassFilters,
98
- getMethodFilters,
99
- getCatchType,
100
- canHandleException,
101
- isExceptionFilter,
102
- isFilterFn,
103
- executeFilter,
104
- findAndExecuteFilter,
105
- HttpExceptionFilter,
106
- ValidationFilter,
107
- NotFoundFilter,
108
- AllExceptionsFilter,
109
- createDefaultErrorResponse,
110
- createInternalErrorResponse,
111
- } from "./filters";
112
112
 
113
113
  // ============= Types =============
114
114
 
@@ -129,14 +129,14 @@ export interface LifecycleHooks {
129
129
  // ============= Metadata Storage =============
130
130
  // Import metadata storage and decorators from isolated module to avoid circular dependencies
131
131
  import {
132
- setMetadata,
133
- getMetadata,
134
- setPrototypeMetadata,
135
- getPrototypeMetadata,
136
- Injectable,
137
132
  Controller,
133
+ Injectable,
138
134
  Module,
139
135
  type ModuleMetadata,
136
+ getMetadata,
137
+ getPrototypeMetadata,
138
+ setMetadata,
139
+ setPrototypeMetadata,
140
140
  } from "./metadata";
141
141
 
142
142
  // Re-export decorators and types for external use
@@ -166,7 +166,10 @@ export function Inject(token: Token | ForwardRef<Token>): ParameterDecorator {
166
166
  ) => {
167
167
  const targetObj = target as object;
168
168
  const existingTokens: Array<Token | ForwardRef<Token>> =
169
- getContainerMetadata<Array<Token | ForwardRef<Token>>>(targetObj, "inject:tokens") ?? [];
169
+ getContainerMetadata<Array<Token | ForwardRef<Token>>>(
170
+ targetObj,
171
+ "inject:tokens",
172
+ ) ?? [];
170
173
  existingTokens[parameterIndex] = token;
171
174
  setContainerMetadata(targetObj, "inject:tokens", existingTokens);
172
175
  };
@@ -250,9 +253,9 @@ export class AppModule {
250
253
 
251
254
  // Add providers (normalize class references to provider objects)
252
255
  if (metadata.providers) {
253
- const normalizedProviders = metadata.providers.map(p => {
256
+ const normalizedProviders = metadata.providers.map((p) => {
254
257
  // If it's a class constructor (function) without token, normalize it
255
- if (typeof p === 'function' && !p.token) {
258
+ if (typeof p === "function" && !p.token) {
256
259
  return { token: p, useClass: p };
257
260
  }
258
261
  return p;
@@ -349,7 +352,8 @@ export class Application {
349
352
  private routeGuardMetadata: Map<string, RouteGuardMetadata> = new Map();
350
353
  private routePipeMetadata: Map<string, RoutePipeMetadata> = new Map();
351
354
  private routeFilterMetadata: Map<string, RouteFilterMetadata> = new Map();
352
- private routeInterceptorMetadata: Map<string, RouteInterceptorMetadata> = new Map();
355
+ private routeInterceptorMetadata: Map<string, RouteInterceptorMetadata> =
356
+ new Map();
353
357
  private moduleLoader: ModuleLoader;
354
358
  private loadedLazyModules = new Set<Constructor>();
355
359
 
@@ -454,8 +458,13 @@ export class Application {
454
458
 
455
459
  for (const provider of providers) {
456
460
  const token = provider.token;
457
- const instance = this.container.resolve(token as import("../container").Token);
458
- this.providerInstances.set(token as import("../container").Token, instance);
461
+ const instance = this.container.resolve(
462
+ token as import("../container").Token,
463
+ );
464
+ this.providerInstances.set(
465
+ token as import("../container").Token,
466
+ instance,
467
+ );
459
468
  this.lifecycleManager.registerInstance(instance);
460
469
  }
461
470
  }
@@ -486,21 +495,35 @@ export class Application {
486
495
  // Create controller instance
487
496
  // First, check for explicit injection tokens from @Inject decorator
488
497
  let injectTokens =
489
- getInjectTokens<Array<Token | ForwardRef<Token>>>(controllerClass, "inject:tokens") ?? [];
490
-
498
+ getInjectTokens<Array<Token | ForwardRef<Token>>>(
499
+ controllerClass,
500
+ "inject:tokens",
501
+ ) ?? [];
502
+
491
503
  // If no explicit tokens, try to use TypeScript's design:paramtypes metadata
492
504
  // This requires the reflect-metadata polyfill to be imported by the user
493
- if (injectTokens.length === 0 && typeof Reflect !== 'undefined' && typeof Reflect.getMetadata === 'function') {
494
- const paramTypes = Reflect.getMetadata('design:paramtypes', controllerClass) as Array<new (...args: unknown[]) => unknown> | undefined;
505
+ if (
506
+ injectTokens.length === 0 &&
507
+ typeof Reflect !== "undefined" &&
508
+ typeof Reflect.getMetadata === "function"
509
+ ) {
510
+ const paramTypes = Reflect.getMetadata(
511
+ "design:paramtypes",
512
+ controllerClass,
513
+ ) as Array<new (...args: unknown[]) => unknown> | undefined;
495
514
  if (paramTypes) {
496
515
  // Use the constructor parameter types as injection tokens
497
- injectTokens = paramTypes.map((paramType) => paramType as unknown as Token);
516
+ injectTokens = paramTypes.map(
517
+ (paramType) => paramType as unknown as Token,
518
+ );
498
519
  }
499
520
  }
500
-
521
+
501
522
  const deps = injectTokens.map((tokenOrRef) => {
502
523
  // Resolve forward reference if needed
503
- const token = isForwardRef(tokenOrRef) ? resolveForwardRef(tokenOrRef) : tokenOrRef;
524
+ const token = isForwardRef(tokenOrRef)
525
+ ? resolveForwardRef(tokenOrRef)
526
+ : tokenOrRef;
504
527
  return this.container.resolve(token);
505
528
  });
506
529
  const instance = new controllerClass(...deps);
@@ -530,19 +553,23 @@ export class Application {
530
553
  | "options";
531
554
 
532
555
  // Get method-level guards
533
- const methodGuards = getMethodGuards(controllerClass.prototype, route.handler) ?? [];
556
+ const methodGuards =
557
+ getMethodGuards(controllerClass.prototype, route.handler) ?? [];
534
558
 
535
559
  // Get method-level pipes
536
- const parameterPipes = getMethodPipes(controllerClass.prototype, route.handler) ?? [];
560
+ const parameterPipes =
561
+ getMethodPipes(controllerClass.prototype, route.handler) ?? [];
537
562
 
538
563
  // Get class-level filters
539
564
  const classFilters = getClassFilters(controllerClass) ?? [];
540
565
 
541
566
  // Get method-level filters
542
- const methodFilters = getMethodFilters(controllerClass.prototype, route.handler) ?? [];
567
+ const methodFilters =
568
+ getMethodFilters(controllerClass.prototype, route.handler) ?? [];
543
569
 
544
570
  // Get method-level interceptors
545
- const methodInterceptors = getMethodInterceptors(controllerClass.prototype, route.handler) ?? [];
571
+ const methodInterceptors =
572
+ getMethodInterceptors(controllerClass.prototype, route.handler) ?? [];
546
573
 
547
574
  // Store guard metadata for this route
548
575
  const routeKey = `${method.toUpperCase()}:${fullPath}`;
@@ -663,8 +690,13 @@ export class Application {
663
690
  if (metadata.providers) {
664
691
  for (const provider of metadata.providers) {
665
692
  this.container.register(provider);
666
- const instance = this.container.resolve(provider.token as import("../container").Token);
667
- this.providerInstances.set(provider.token as import("../container").Token, instance);
693
+ const instance = this.container.resolve(
694
+ provider.token as import("../container").Token,
695
+ );
696
+ this.providerInstances.set(
697
+ provider.token as import("../container").Token,
698
+ instance,
699
+ );
668
700
  this.lifecycleManager.registerInstance(instance);
669
701
  }
670
702
 
@@ -706,7 +738,7 @@ export class Application {
706
738
 
707
739
  /**
708
740
  * Perform graceful shutdown
709
- *
741
+ *
710
742
  * Execution order:
711
743
  * 1. Stop accepting new requests
712
744
  * 2. beforeApplicationShutdown(signal)
@@ -787,7 +819,7 @@ export class Application {
787
819
  // Execute guards (before interceptors and pipes)
788
820
  const routeKey = `${request.method}:${url.pathname}`;
789
821
  const guardMetadata = this.routeGuardMetadata.get(routeKey);
790
-
822
+
791
823
  if (guardMetadata || this.globalGuards.length > 0) {
792
824
  const guardsPassed = await executeGuards(context, {
793
825
  globalGuards: this.globalGuards,
@@ -795,7 +827,11 @@ export class Application {
795
827
  methodGuards: guardMetadata?.methodGuards ?? [],
796
828
  resolveGuard: (guard: Guard) => {
797
829
  // Try to resolve from container if it's a token
798
- if (typeof guard === "object" && guard !== null && !("canActivate" in guard)) {
830
+ if (
831
+ typeof guard === "object" &&
832
+ guard !== null &&
833
+ !("canActivate" in guard)
834
+ ) {
799
835
  try {
800
836
  return this.container.resolve(guard as Token) as CanActivate;
801
837
  } catch {
@@ -810,120 +846,155 @@ export class Application {
810
846
  return createForbiddenResponse();
811
847
  }
812
848
  }
813
-
814
- // Get interceptor metadata
815
- const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
816
-
817
- // Create the handler function that executes pipes and middleware
818
- const executeHandler = async (): Promise<Response> => {
819
- // Execute pipes (after guards, before handler)
820
- const pipeMetadata = this.routePipeMetadata.get(routeKey);
821
- if (pipeMetadata || this.globalPipes.length > 0) {
822
- try {
823
- // Process each parameter with pipes
824
- const params = pipeMetadata?.parameterPipes ?? [];
825
- for (const paramMeta of params) {
826
- // Extract the initial value for this parameter
827
- const initialValue = await extractParameterValue(context, paramMeta);
828
-
829
- // Create pipe context
830
- const pipeContext: PipeContext = {
831
- context,
832
- metadata: {
833
- index: paramMeta.index,
834
- name: paramMeta.key,
835
- decorator: paramMeta.decorator,
836
- },
837
- };
838
-
839
- // Execute pipes for this parameter
840
- const transformedValue = await executePipes(initialValue, pipeContext, {
849
+
850
+ // Get interceptor metadata
851
+ const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
852
+
853
+ // Create the handler function that executes pipes and middleware
854
+ const executeHandler = async (): Promise<Response> => {
855
+ // Execute pipes (after guards, before handler)
856
+ const pipeMetadata = this.routePipeMetadata.get(routeKey);
857
+ if (pipeMetadata || this.globalPipes.length > 0) {
858
+ try {
859
+ // Process each parameter with pipes
860
+ const params = pipeMetadata?.parameterPipes ?? [];
861
+ for (const paramMeta of params) {
862
+ // Extract the initial value for this parameter
863
+ const initialValue = await extractParameterValue(
864
+ context,
865
+ paramMeta,
866
+ );
867
+
868
+ // Create pipe context
869
+ const pipeContext: PipeContext = {
870
+ context,
871
+ metadata: {
872
+ index: paramMeta.index,
873
+ name: paramMeta.key,
874
+ decorator: paramMeta.decorator,
875
+ },
876
+ };
877
+
878
+ // Execute pipes for this parameter
879
+ const transformedValue = await executePipes(
880
+ initialValue,
881
+ pipeContext,
882
+ {
841
883
  globalPipes: this.globalPipes,
842
884
  parameterPipes: paramMeta.pipes,
843
885
  resolvePipe: (pipe: Pipe) => {
844
886
  // Try to resolve from container if it's a token
845
- if (typeof pipe === "object" && pipe !== null && !("transform" in pipe)) {
887
+ if (
888
+ typeof pipe === "object" &&
889
+ pipe !== null &&
890
+ !("transform" in pipe)
891
+ ) {
846
892
  try {
847
- return this.container.resolve(pipe as Token) as PipeTransform;
893
+ return this.container.resolve(
894
+ pipe as Token,
895
+ ) as PipeTransform;
848
896
  } catch {
849
897
  return null;
850
898
  }
851
899
  }
852
900
  return null;
853
901
  },
854
- });
855
-
856
- // Store the transformed value in context for handler access
857
- context.set(`pipe:param:${paramMeta.index}`, transformedValue);
858
- }
859
- } catch (error) {
860
- // Pipe transformation failed - return 400 Bad Request
861
- if (error instanceof Error) {
862
- return createBadRequestResponse(error);
863
- }
864
- return createBadRequestResponse(new Error("Pipe transformation failed"));
902
+ },
903
+ );
904
+
905
+ // Store the transformed value in context for handler access
906
+ context.set(`pipe:param:${paramMeta.index}`, transformedValue);
865
907
  }
908
+ } catch (error) {
909
+ // Pipe transformation failed - return 400 Bad Request
910
+ if (error instanceof Error) {
911
+ return createBadRequestResponse(error);
912
+ }
913
+ return createBadRequestResponse(
914
+ new Error("Pipe transformation failed"),
915
+ );
866
916
  }
867
-
868
- // Execute middleware and handler
869
- const pipeline = compose((match.middleware ?? []) as import("../middleware").Middleware[]);
870
- return pipeline(context, match.handler as import("../middleware").Handler);
871
- };
872
-
873
- // Execute interceptors wrapping around the handler
874
- // Interceptors run after guards, before pipes
875
- try {
876
- const response = await executeInterceptors(context, executeHandler, {
877
- globalInterceptors: this.globalInterceptors,
878
- classInterceptors: interceptorMetadata?.classInterceptors ?? [],
879
- methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
880
- resolveInterceptor: (interceptor: Interceptor): NestInterceptor | InterceptorFn | null => {
881
- // Try to resolve from container if it's a token
882
- if (typeof interceptor === "object" && interceptor !== null && !isNestInterceptor(interceptor) && !isInterceptorFn(interceptor)) {
883
- try {
884
- return this.container.resolve(interceptor as Token) as NestInterceptor;
885
- } catch {
886
- return null;
887
- }
917
+ }
918
+
919
+ // Execute middleware and handler
920
+ const pipeline = compose(
921
+ (match.middleware ?? []) as import("../middleware").Middleware[],
922
+ );
923
+ return pipeline(
924
+ context,
925
+ match.handler as import("../middleware").Handler,
926
+ );
927
+ };
928
+
929
+ // Execute interceptors wrapping around the handler
930
+ // Interceptors run after guards, before pipes
931
+ try {
932
+ const response = await executeInterceptors(context, executeHandler, {
933
+ globalInterceptors: this.globalInterceptors,
934
+ classInterceptors: interceptorMetadata?.classInterceptors ?? [],
935
+ methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
936
+ resolveInterceptor: (
937
+ interceptor: Interceptor,
938
+ ): NestInterceptor | InterceptorFn | null => {
939
+ // Try to resolve from container if it's a token
940
+ if (
941
+ typeof interceptor === "object" &&
942
+ interceptor !== null &&
943
+ !isNestInterceptor(interceptor) &&
944
+ !isInterceptorFn(interceptor)
945
+ ) {
946
+ try {
947
+ return this.container.resolve(
948
+ interceptor as Token,
949
+ ) as NestInterceptor;
950
+ } catch {
951
+ return null;
888
952
  }
889
- // Try to instantiate if it's a class constructor
890
- if (typeof interceptor === "function" && !isInterceptorFn(interceptor)) {
891
- try {
892
- const Constructor = interceptor as new () => NestInterceptor;
893
- const instance = new Constructor();
894
- if (isNestInterceptor(instance)) {
895
- return instance;
896
- }
897
- } catch {
898
- // Cannot instantiate
953
+ }
954
+ // Try to instantiate if it's a class constructor
955
+ if (
956
+ typeof interceptor === "function" &&
957
+ !isInterceptorFn(interceptor)
958
+ ) {
959
+ try {
960
+ const Constructor = interceptor as new () => NestInterceptor;
961
+ const instance = new Constructor();
962
+ if (isNestInterceptor(instance)) {
963
+ return instance;
899
964
  }
965
+ } catch {
966
+ // Cannot instantiate
900
967
  }
901
- return null;
902
- },
903
- });
904
-
905
- // Execute onAfterRequest hooks
906
- try {
907
- await this.lifecycleManager.executeOnAfterRequest(context, response as Response);
908
- } catch (error) {
909
- console.error("Error in onAfterRequest hook:", error);
910
- }
911
-
912
- return response as Response;
968
+ }
969
+ return null;
970
+ },
971
+ });
972
+
973
+ // Execute onAfterRequest hooks
974
+ try {
975
+ await this.lifecycleManager.executeOnAfterRequest(
976
+ context,
977
+ response as Response,
978
+ );
913
979
  } catch (error) {
914
- // Execute onRequestError hooks
915
- try {
916
- await this.lifecycleManager.executeOnRequestError(
917
- context,
918
- error as Error,
919
- );
920
- } catch (hookError) {
921
- console.error("Error in onRequestError hook:", hookError);
922
- }
923
-
924
- // Handle exception with filters
925
- return this.handleException(error as Error, context, routeKey);
980
+ console.error("Error in onAfterRequest hook:", error);
981
+ }
982
+
983
+ return response as Response;
984
+ } catch (error) {
985
+ // Execute onRequestError hooks
986
+ try {
987
+ await this.lifecycleManager.executeOnRequestError(
988
+ context,
989
+ error as Error,
990
+ );
991
+ } catch (hookError) {
992
+ console.error("Error in onRequestError hook:", hookError);
926
993
  }
994
+
995
+ // Handle exception with filters
996
+ return this.handleException(error as Error, context, routeKey);
997
+ }
927
998
  },
928
999
  });
929
1000
 
@@ -949,7 +1020,7 @@ export class Application {
949
1020
  // Execute guards (before interceptors and pipes)
950
1021
  const routeKey = `${request.method}:${url.pathname}`;
951
1022
  const guardMetadata = this.routeGuardMetadata.get(routeKey);
952
-
1023
+
953
1024
  if (guardMetadata || this.globalGuards.length > 0) {
954
1025
  const guardsPassed = await executeGuards(context, {
955
1026
  globalGuards: this.globalGuards,
@@ -957,7 +1028,11 @@ export class Application {
957
1028
  methodGuards: guardMetadata?.methodGuards ?? [],
958
1029
  resolveGuard: (guard: Guard) => {
959
1030
  // Try to resolve from container if it's a token
960
- if (typeof guard === "object" && guard !== null && !("canActivate" in guard)) {
1031
+ if (
1032
+ typeof guard === "object" &&
1033
+ guard !== null &&
1034
+ !("canActivate" in guard)
1035
+ ) {
961
1036
  try {
962
1037
  return this.container.resolve(guard as Token) as CanActivate;
963
1038
  } catch {
@@ -972,123 +1047,155 @@ export class Application {
972
1047
  return createForbiddenResponse();
973
1048
  }
974
1049
  }
975
-
976
- // Get interceptor metadata
977
- const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
978
-
979
- // Create the handler function that executes pipes and middleware
980
- const executeHandler = async (): Promise<Response> => {
981
- // Execute pipes (after guards, before handler)
982
- const pipeMetadata = this.routePipeMetadata.get(routeKey);
983
- if (pipeMetadata || this.globalPipes.length > 0) {
984
- try {
985
- // Process each parameter with pipes
986
- const params = pipeMetadata?.parameterPipes ?? [];
987
- for (const paramMeta of params) {
988
- // Extract the initial value for this parameter
989
- const initialValue = await extractParameterValue(context, paramMeta);
990
-
991
- // Create pipe context
992
- const pipeContext: PipeContext = {
993
- context,
994
- metadata: {
995
- index: paramMeta.index,
996
- name: paramMeta.key,
997
- decorator: paramMeta.decorator,
998
- },
999
- };
1000
-
1001
- // Execute pipes for this parameter
1002
- const transformedValue = await executePipes(initialValue, pipeContext, {
1050
+
1051
+ // Get interceptor metadata
1052
+ const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
1053
+
1054
+ // Create the handler function that executes pipes and middleware
1055
+ const executeHandler = async (): Promise<Response> => {
1056
+ // Execute pipes (after guards, before handler)
1057
+ const pipeMetadata = this.routePipeMetadata.get(routeKey);
1058
+ if (pipeMetadata || this.globalPipes.length > 0) {
1059
+ try {
1060
+ // Process each parameter with pipes
1061
+ const params = pipeMetadata?.parameterPipes ?? [];
1062
+ for (const paramMeta of params) {
1063
+ // Extract the initial value for this parameter
1064
+ const initialValue = await extractParameterValue(
1065
+ context,
1066
+ paramMeta,
1067
+ );
1068
+
1069
+ // Create pipe context
1070
+ const pipeContext: PipeContext = {
1071
+ context,
1072
+ metadata: {
1073
+ index: paramMeta.index,
1074
+ name: paramMeta.key,
1075
+ decorator: paramMeta.decorator,
1076
+ },
1077
+ };
1078
+
1079
+ // Execute pipes for this parameter
1080
+ const transformedValue = await executePipes(
1081
+ initialValue,
1082
+ pipeContext,
1083
+ {
1003
1084
  globalPipes: this.globalPipes,
1004
1085
  parameterPipes: paramMeta.pipes,
1005
1086
  resolvePipe: (pipe: Pipe) => {
1006
1087
  // Try to resolve from container if it's a token
1007
- if (typeof pipe === "object" && pipe !== null && !("transform" in pipe)) {
1088
+ if (
1089
+ typeof pipe === "object" &&
1090
+ pipe !== null &&
1091
+ !("transform" in pipe)
1092
+ ) {
1008
1093
  try {
1009
- return this.container.resolve(pipe as Token) as PipeTransform;
1094
+ return this.container.resolve(
1095
+ pipe as Token,
1096
+ ) as PipeTransform;
1010
1097
  } catch {
1011
1098
  return null;
1012
1099
  }
1013
1100
  }
1014
1101
  return null;
1015
1102
  },
1016
- });
1017
-
1018
- // Store the transformed value in context for handler access
1019
- context.set(`pipe:param:${paramMeta.index}`, transformedValue);
1020
- }
1021
- } catch (error) {
1022
- // Pipe transformation failed - return 400 Bad Request
1023
- if (error instanceof Error) {
1024
- return createBadRequestResponse(error);
1025
- }
1026
- return createBadRequestResponse(new Error("Pipe transformation failed"));
1103
+ },
1104
+ );
1105
+
1106
+ // Store the transformed value in context for handler access
1107
+ context.set(`pipe:param:${paramMeta.index}`, transformedValue);
1108
+ }
1109
+ } catch (error) {
1110
+ // Pipe transformation failed - return 400 Bad Request
1111
+ if (error instanceof Error) {
1112
+ return createBadRequestResponse(error);
1027
1113
  }
1114
+ return createBadRequestResponse(
1115
+ new Error("Pipe transformation failed"),
1116
+ );
1028
1117
  }
1029
-
1030
- // Execute middleware and handler
1031
- const pipeline = compose((match.middleware ?? []) as import("../middleware").Middleware[]);
1032
- return pipeline(context, match.handler as import("../middleware").Handler);
1033
- };
1034
-
1035
- // Execute interceptors wrapping around the handler
1036
- // Interceptors run after guards, before pipes
1037
- try {
1038
- const response = await executeInterceptors(context, executeHandler, {
1039
- globalInterceptors: this.globalInterceptors,
1040
- classInterceptors: interceptorMetadata?.classInterceptors ?? [],
1041
- methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
1042
- resolveInterceptor: (interceptor: Interceptor): NestInterceptor | InterceptorFn | null => {
1043
- // Try to resolve from container if it's a token
1044
- if (typeof interceptor === "object" && interceptor !== null && !isNestInterceptor(interceptor) && !isInterceptorFn(interceptor)) {
1045
- try {
1046
- return this.container.resolve(interceptor as Token) as NestInterceptor;
1047
- } catch {
1048
- return null;
1049
- }
1118
+ }
1119
+
1120
+ // Execute middleware and handler
1121
+ const pipeline = compose(
1122
+ (match.middleware ?? []) as import("../middleware").Middleware[],
1123
+ );
1124
+ return pipeline(
1125
+ context,
1126
+ match.handler as import("../middleware").Handler,
1127
+ );
1128
+ };
1129
+
1130
+ // Execute interceptors wrapping around the handler
1131
+ // Interceptors run after guards, before pipes
1132
+ try {
1133
+ const response = await executeInterceptors(context, executeHandler, {
1134
+ globalInterceptors: this.globalInterceptors,
1135
+ classInterceptors: interceptorMetadata?.classInterceptors ?? [],
1136
+ methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
1137
+ resolveInterceptor: (
1138
+ interceptor: Interceptor,
1139
+ ): NestInterceptor | InterceptorFn | null => {
1140
+ // Try to resolve from container if it's a token
1141
+ if (
1142
+ typeof interceptor === "object" &&
1143
+ interceptor !== null &&
1144
+ !isNestInterceptor(interceptor) &&
1145
+ !isInterceptorFn(interceptor)
1146
+ ) {
1147
+ try {
1148
+ return this.container.resolve(
1149
+ interceptor as Token,
1150
+ ) as NestInterceptor;
1151
+ } catch {
1152
+ return null;
1050
1153
  }
1051
- // Try to instantiate if it's a class constructor
1052
- if (typeof interceptor === "function" && !isInterceptorFn(interceptor)) {
1053
- try {
1054
- const Constructor = interceptor as new () => NestInterceptor;
1055
- const instance = new Constructor();
1056
- if (isNestInterceptor(instance)) {
1057
- return instance;
1058
- }
1059
- } catch {
1060
- // Cannot instantiate
1154
+ }
1155
+ // Try to instantiate if it's a class constructor
1156
+ if (
1157
+ typeof interceptor === "function" &&
1158
+ !isInterceptorFn(interceptor)
1159
+ ) {
1160
+ try {
1161
+ const Constructor = interceptor as new () => NestInterceptor;
1162
+ const instance = new Constructor();
1163
+ if (isNestInterceptor(instance)) {
1164
+ return instance;
1061
1165
  }
1166
+ } catch {
1167
+ // Cannot instantiate
1062
1168
  }
1063
- return null;
1064
- },
1065
- });
1066
-
1067
- return response as Response;
1068
- } catch (error) {
1069
- // Handle exception with filters
1070
- return this.handleException(error as Error, context, routeKey);
1071
- }
1169
+ }
1170
+ return null;
1171
+ },
1172
+ });
1173
+
1174
+ return response as Response;
1175
+ } catch (error) {
1176
+ // Handle exception with filters
1177
+ return this.handleException(error as Error, context, routeKey);
1072
1178
  }
1073
-
1074
- /**
1075
- * Get the lifecycle manager for this application
1076
- */
1179
+ }
1180
+
1181
+ /**
1182
+ * Get the lifecycle manager for this application
1183
+ */
1077
1184
  getLifecycleManager(): LifecycleHookManager {
1078
1185
  return this.lifecycleManager;
1079
1186
  }
1080
1187
 
1081
1188
  /**
1082
- * Check if the application is shutting down
1083
- */
1189
+ * Check if the application is shutting down
1190
+ */
1084
1191
  isShuttingDownNow(): boolean {
1085
1192
  return this.isShuttingDown;
1086
1193
  }
1087
1194
 
1088
1195
  /**
1089
- * Handle an exception using the filters system
1090
- * Filters are checked in order: method → class → global
1091
- */
1196
+ * Handle an exception using the filters system
1197
+ * Filters are checked in order: method → class → global
1198
+ */
1092
1199
  private async handleException(
1093
1200
  exception: Error,
1094
1201
  context: Context,
@@ -1102,7 +1209,11 @@ export class Application {
1102
1209
  methodFilters: filterMetadata?.methodFilters ?? [],
1103
1210
  resolveFilter: (filter: Filter): ExceptionFilter | null => {
1104
1211
  // Try to resolve from container if it's a token
1105
- if (typeof filter === "object" && filter !== null && !isExceptionFilter(filter)) {
1212
+ if (
1213
+ typeof filter === "object" &&
1214
+ filter !== null &&
1215
+ !isExceptionFilter(filter)
1216
+ ) {
1106
1217
  try {
1107
1218
  return this.container.resolve(filter as Token) as ExceptionFilter;
1108
1219
  } catch {
@@ -1138,17 +1249,17 @@ export function createApp(moduleClass: Constructor): Application {
1138
1249
  export {
1139
1250
  LifecycleHookManager,
1140
1251
  ShutdownSignalHandler,
1141
- OnModuleInit,
1142
- OnApplicationBootstrap,
1143
- OnModuleDestroy,
1144
- BeforeApplicationShutdown,
1145
- OnApplicationShutdown,
1146
- OnBeforeRequest,
1147
- OnAfterRequest,
1148
- OnRequestError,
1149
- ApplicationLifecycle,
1150
- RequestLifecycle,
1151
- FullLifecycle,
1252
+ type OnModuleInit,
1253
+ type OnApplicationBootstrap,
1254
+ type OnModuleDestroy,
1255
+ type BeforeApplicationShutdown,
1256
+ type OnApplicationShutdown,
1257
+ type OnBeforeRequest,
1258
+ type OnAfterRequest,
1259
+ type OnRequestError,
1260
+ type ApplicationLifecycle,
1261
+ type RequestLifecycle,
1262
+ type FullLifecycle,
1152
1263
  isOnModuleInit,
1153
1264
  isOnApplicationBootstrap,
1154
1265
  isOnModuleDestroy,
@@ -1274,4 +1385,4 @@ export {
1274
1385
  forwardRef,
1275
1386
  isForwardRef,
1276
1387
  resolveForwardRef,
1277
- } from "../container";
1388
+ } from "../container";