@buenojs/bueno 0.8.4 → 0.8.6

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 (234) hide show
  1. package/README.md +264 -17
  2. package/dist/cli/{index.js → bin.js} +413 -332
  3. package/dist/container/index.js +273 -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/graphql/index.js +2156 -0
  8. package/dist/health/index.js +364 -0
  9. package/dist/i18n/index.js +345 -0
  10. package/dist/index.js +9694 -5047
  11. package/dist/jobs/index.js +819 -0
  12. package/dist/lock/index.js +367 -0
  13. package/dist/logger/index.js +281 -0
  14. package/dist/metrics/index.js +289 -0
  15. package/dist/middleware/index.js +77 -0
  16. package/dist/migrations/index.js +571 -0
  17. package/dist/modules/index.js +3411 -0
  18. package/dist/notification/index.js +484 -0
  19. package/dist/observability/index.js +331 -0
  20. package/dist/openapi/index.js +795 -0
  21. package/dist/orm/index.js +1356 -0
  22. package/dist/router/index.js +886 -0
  23. package/dist/rpc/index.js +691 -0
  24. package/dist/schema/index.js +400 -0
  25. package/dist/telemetry/index.js +595 -0
  26. package/dist/template/index.js +640 -0
  27. package/dist/templates/index.js +640 -0
  28. package/dist/testing/index.js +1111 -0
  29. package/dist/types/index.js +60 -0
  30. package/llms.txt +231 -0
  31. package/package.json +125 -27
  32. package/src/cache/index.ts +2 -1
  33. package/src/cli/ARCHITECTURE.md +3 -3
  34. package/src/cli/bin.ts +2 -2
  35. package/src/cli/commands/build.ts +183 -165
  36. package/src/cli/commands/dev.ts +96 -89
  37. package/src/cli/commands/generate.ts +142 -111
  38. package/src/cli/commands/help.ts +20 -16
  39. package/src/cli/commands/index.ts +3 -6
  40. package/src/cli/commands/migration.ts +124 -105
  41. package/src/cli/commands/new.ts +294 -232
  42. package/src/cli/commands/start.ts +81 -79
  43. package/src/cli/core/args.ts +68 -50
  44. package/src/cli/core/console.ts +89 -95
  45. package/src/cli/core/index.ts +4 -4
  46. package/src/cli/core/prompt.ts +65 -62
  47. package/src/cli/core/spinner.ts +23 -20
  48. package/src/cli/index.ts +46 -38
  49. package/src/cli/templates/database/index.ts +37 -18
  50. package/src/cli/templates/database/mysql.ts +3 -3
  51. package/src/cli/templates/database/none.ts +2 -2
  52. package/src/cli/templates/database/postgresql.ts +3 -3
  53. package/src/cli/templates/database/sqlite.ts +3 -3
  54. package/src/cli/templates/deploy.ts +29 -26
  55. package/src/cli/templates/docker.ts +41 -30
  56. package/src/cli/templates/frontend/index.ts +33 -15
  57. package/src/cli/templates/frontend/none.ts +2 -2
  58. package/src/cli/templates/frontend/react.ts +18 -18
  59. package/src/cli/templates/frontend/solid.ts +15 -15
  60. package/src/cli/templates/frontend/svelte.ts +17 -17
  61. package/src/cli/templates/frontend/vue.ts +15 -15
  62. package/src/cli/templates/generators/index.ts +29 -29
  63. package/src/cli/templates/generators/types.ts +21 -21
  64. package/src/cli/templates/index.ts +6 -6
  65. package/src/cli/templates/project/api.ts +37 -36
  66. package/src/cli/templates/project/default.ts +25 -25
  67. package/src/cli/templates/project/fullstack.ts +28 -26
  68. package/src/cli/templates/project/index.ts +55 -16
  69. package/src/cli/templates/project/minimal.ts +17 -12
  70. package/src/cli/templates/project/types.ts +10 -5
  71. package/src/cli/templates/project/website.ts +15 -15
  72. package/src/cli/utils/fs.ts +55 -41
  73. package/src/cli/utils/index.ts +3 -3
  74. package/src/cli/utils/strings.ts +47 -33
  75. package/src/cli/utils/version.ts +14 -8
  76. package/src/config/env-validation.ts +100 -0
  77. package/src/config/env.ts +169 -41
  78. package/src/config/index.ts +28 -20
  79. package/src/config/loader.ts +25 -16
  80. package/src/config/merge.ts +21 -10
  81. package/src/config/types.ts +566 -25
  82. package/src/config/validation.ts +215 -7
  83. package/src/container/forward-ref.ts +22 -22
  84. package/src/container/index.ts +34 -12
  85. package/src/context/index.ts +11 -1
  86. package/src/database/index.ts +7 -190
  87. package/src/database/orm/builder.ts +457 -0
  88. package/src/database/orm/casts/index.ts +130 -0
  89. package/src/database/orm/casts/types.ts +25 -0
  90. package/src/database/orm/compiler.ts +304 -0
  91. package/src/database/orm/hooks/index.ts +114 -0
  92. package/src/database/orm/index.ts +61 -0
  93. package/src/database/orm/model-registry.ts +59 -0
  94. package/src/database/orm/model.ts +821 -0
  95. package/src/database/orm/relationships/base.ts +146 -0
  96. package/src/database/orm/relationships/belongs-to-many.ts +179 -0
  97. package/src/database/orm/relationships/belongs-to.ts +56 -0
  98. package/src/database/orm/relationships/has-many.ts +45 -0
  99. package/src/database/orm/relationships/has-one.ts +41 -0
  100. package/src/database/orm/relationships/index.ts +11 -0
  101. package/src/database/orm/scopes/index.ts +55 -0
  102. package/src/events/__tests__/event-system.test.ts +235 -0
  103. package/src/events/config.ts +238 -0
  104. package/src/events/example-usage.ts +185 -0
  105. package/src/events/index.ts +278 -0
  106. package/src/events/manager.ts +385 -0
  107. package/src/events/registry.ts +182 -0
  108. package/src/events/types.ts +124 -0
  109. package/src/frontend/api-routes.ts +65 -23
  110. package/src/frontend/bundler.ts +76 -34
  111. package/src/frontend/console-client.ts +2 -2
  112. package/src/frontend/console-stream.ts +94 -38
  113. package/src/frontend/dev-server.ts +94 -46
  114. package/src/frontend/file-router.ts +61 -19
  115. package/src/frontend/frameworks/index.ts +37 -10
  116. package/src/frontend/frameworks/react.ts +10 -8
  117. package/src/frontend/frameworks/solid.ts +11 -9
  118. package/src/frontend/frameworks/svelte.ts +15 -9
  119. package/src/frontend/frameworks/vue.ts +13 -11
  120. package/src/frontend/hmr-client.ts +12 -10
  121. package/src/frontend/hmr.ts +146 -103
  122. package/src/frontend/index.ts +14 -5
  123. package/src/frontend/islands.ts +41 -22
  124. package/src/frontend/isr.ts +59 -37
  125. package/src/frontend/layout.ts +36 -21
  126. package/src/frontend/ssr/react.ts +74 -27
  127. package/src/frontend/ssr/solid.ts +54 -20
  128. package/src/frontend/ssr/svelte.ts +48 -14
  129. package/src/frontend/ssr/vue.ts +50 -18
  130. package/src/frontend/ssr.ts +83 -39
  131. package/src/frontend/types.ts +91 -56
  132. package/src/graphql/built-in-engine.ts +598 -0
  133. package/src/graphql/context-builder.ts +110 -0
  134. package/src/graphql/decorators.ts +358 -0
  135. package/src/graphql/execution-pipeline.ts +227 -0
  136. package/src/graphql/graphql-module.ts +563 -0
  137. package/src/graphql/index.ts +101 -0
  138. package/src/graphql/metadata.ts +237 -0
  139. package/src/graphql/schema-builder.ts +319 -0
  140. package/src/graphql/subscription-handler.ts +283 -0
  141. package/src/graphql/types.ts +324 -0
  142. package/src/health/index.ts +21 -9
  143. package/src/i18n/engine.ts +305 -0
  144. package/src/i18n/index.ts +38 -0
  145. package/src/i18n/loader.ts +218 -0
  146. package/src/i18n/middleware.ts +164 -0
  147. package/src/i18n/negotiator.ts +162 -0
  148. package/src/i18n/types.ts +158 -0
  149. package/src/index.ts +182 -27
  150. package/src/jobs/drivers/memory.ts +315 -0
  151. package/src/jobs/drivers/redis.ts +459 -0
  152. package/src/jobs/index.ts +30 -0
  153. package/src/jobs/queue.ts +281 -0
  154. package/src/jobs/types.ts +295 -0
  155. package/src/jobs/worker.ts +380 -0
  156. package/src/logger/index.ts +1 -3
  157. package/src/logger/transports/index.ts +62 -22
  158. package/src/metrics/index.ts +25 -16
  159. package/src/migrations/index.ts +9 -0
  160. package/src/modules/filters.ts +13 -17
  161. package/src/modules/guards.ts +49 -26
  162. package/src/modules/index.ts +457 -299
  163. package/src/modules/interceptors.ts +58 -20
  164. package/src/modules/lazy.ts +11 -19
  165. package/src/modules/lifecycle.ts +15 -7
  166. package/src/modules/metadata.ts +15 -5
  167. package/src/modules/pipes.ts +94 -72
  168. package/src/notification/channels/base.ts +68 -0
  169. package/src/notification/channels/email.ts +105 -0
  170. package/src/notification/channels/push.ts +104 -0
  171. package/src/notification/channels/sms.ts +105 -0
  172. package/src/notification/channels/whatsapp.ts +104 -0
  173. package/src/notification/index.ts +48 -0
  174. package/src/notification/service.ts +354 -0
  175. package/src/notification/types.ts +344 -0
  176. package/src/observability/__tests__/observability.test.ts +483 -0
  177. package/src/observability/breadcrumbs.ts +114 -0
  178. package/src/observability/index.ts +136 -0
  179. package/src/observability/interceptor.ts +85 -0
  180. package/src/observability/service.ts +303 -0
  181. package/src/observability/trace.ts +37 -0
  182. package/src/observability/types.ts +196 -0
  183. package/src/openapi/__tests__/decorators.test.ts +335 -0
  184. package/src/openapi/__tests__/document-builder.test.ts +285 -0
  185. package/src/openapi/__tests__/route-scanner.test.ts +334 -0
  186. package/src/openapi/__tests__/schema-generator.test.ts +275 -0
  187. package/src/openapi/decorators.ts +328 -0
  188. package/src/openapi/document-builder.ts +274 -0
  189. package/src/openapi/index.ts +112 -0
  190. package/src/openapi/metadata.ts +112 -0
  191. package/src/openapi/route-scanner.ts +289 -0
  192. package/src/openapi/schema-generator.ts +256 -0
  193. package/src/openapi/swagger-module.ts +166 -0
  194. package/src/openapi/types.ts +398 -0
  195. package/src/orm/index.ts +10 -0
  196. package/src/rpc/index.ts +3 -1
  197. package/src/schema/index.ts +9 -0
  198. package/src/security/index.ts +15 -6
  199. package/src/ssg/index.ts +9 -8
  200. package/src/telemetry/index.ts +76 -22
  201. package/src/template/index.ts +7 -0
  202. package/src/templates/engine.ts +224 -0
  203. package/src/templates/index.ts +9 -0
  204. package/src/templates/loader.ts +331 -0
  205. package/src/templates/renderers/markdown.ts +212 -0
  206. package/src/templates/renderers/simple.ts +269 -0
  207. package/src/templates/types.ts +154 -0
  208. package/src/testing/index.ts +100 -27
  209. package/src/types/optional-deps.d.ts +347 -187
  210. package/src/validation/index.ts +92 -2
  211. package/src/validation/schemas.ts +536 -0
  212. package/tests/integration/cli.test.ts +19 -19
  213. package/tests/integration/fullstack.test.ts +4 -4
  214. package/tests/unit/cli.test.ts +1 -1
  215. package/tests/unit/database.test.ts +2 -72
  216. package/tests/unit/env-validation.test.ts +166 -0
  217. package/tests/unit/events.test.ts +910 -0
  218. package/tests/unit/graphql.test.ts +991 -0
  219. package/tests/unit/i18n.test.ts +455 -0
  220. package/tests/unit/jobs.test.ts +493 -0
  221. package/tests/unit/notification.test.ts +988 -0
  222. package/tests/unit/observability.test.ts +453 -0
  223. package/tests/unit/orm/builder.test.ts +323 -0
  224. package/tests/unit/orm/casts.test.ts +179 -0
  225. package/tests/unit/orm/compiler.test.ts +220 -0
  226. package/tests/unit/orm/eager-loading.test.ts +285 -0
  227. package/tests/unit/orm/hooks.test.ts +191 -0
  228. package/tests/unit/orm/model.test.ts +373 -0
  229. package/tests/unit/orm/relationships.test.ts +303 -0
  230. package/tests/unit/orm/scopes.test.ts +74 -0
  231. package/tests/unit/templates-simple.test.ts +53 -0
  232. package/tests/unit/templates.test.ts +454 -0
  233. package/tests/unit/validation.test.ts +18 -24
  234. 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,9 +352,12 @@ 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>();
359
+ // biome-ignore lint/suspicious/noExplicitAny: WebSocket data type is user-defined
360
+ private websocketHandler: Bun.WebSocketHandler<any> | null = null;
355
361
 
356
362
  constructor(moduleClass: Constructor) {
357
363
  this.container = new Container();
@@ -381,6 +387,37 @@ export class Application {
381
387
  return this;
382
388
  }
383
389
 
390
+ /**
391
+ * Get the list of global guards (live reference).
392
+ * Used by the GraphQL module to run guards on resolver methods.
393
+ */
394
+ getGlobalGuards(): Guard[] {
395
+ return this.globalGuards;
396
+ }
397
+
398
+ /**
399
+ * Get the list of global interceptors (live reference).
400
+ * Used by the GraphQL module to run interceptors on resolver methods.
401
+ */
402
+ getGlobalInterceptors(): Interceptor[] {
403
+ return this.globalInterceptors;
404
+ }
405
+
406
+ /**
407
+ * Register a WebSocket handler to be used when the server starts.
408
+ * Called by the GraphQL module to enable subscriptions on the same port.
409
+ *
410
+ * @example
411
+ * ```typescript
412
+ * app.setWebSocketHandler(subscriptionHandler.getWebSocketConfig());
413
+ * await app.listen(3000);
414
+ * ```
415
+ */
416
+ // biome-ignore lint/suspicious/noExplicitAny: WebSocket data type is user-defined
417
+ setWebSocketHandler(handler: Bun.WebSocketHandler<any>): void {
418
+ this.websocketHandler = handler;
419
+ }
420
+
384
421
  /**
385
422
  * Add global pipes that apply to all parameters
386
423
  * Global pipes run before parameter decorator pipes
@@ -454,8 +491,13 @@ export class Application {
454
491
 
455
492
  for (const provider of providers) {
456
493
  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);
494
+ const instance = this.container.resolve(
495
+ token as import("../container").Token,
496
+ );
497
+ this.providerInstances.set(
498
+ token as import("../container").Token,
499
+ instance,
500
+ );
459
501
  this.lifecycleManager.registerInstance(instance);
460
502
  }
461
503
  }
@@ -486,21 +528,35 @@ export class Application {
486
528
  // Create controller instance
487
529
  // First, check for explicit injection tokens from @Inject decorator
488
530
  let injectTokens =
489
- getInjectTokens<Array<Token | ForwardRef<Token>>>(controllerClass, "inject:tokens") ?? [];
490
-
531
+ getInjectTokens<Array<Token | ForwardRef<Token>>>(
532
+ controllerClass,
533
+ "inject:tokens",
534
+ ) ?? [];
535
+
491
536
  // If no explicit tokens, try to use TypeScript's design:paramtypes metadata
492
537
  // 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;
538
+ if (
539
+ injectTokens.length === 0 &&
540
+ typeof Reflect !== "undefined" &&
541
+ typeof Reflect.getMetadata === "function"
542
+ ) {
543
+ const paramTypes = Reflect.getMetadata(
544
+ "design:paramtypes",
545
+ controllerClass,
546
+ ) as Array<new (...args: unknown[]) => unknown> | undefined;
495
547
  if (paramTypes) {
496
548
  // Use the constructor parameter types as injection tokens
497
- injectTokens = paramTypes.map((paramType) => paramType as unknown as Token);
549
+ injectTokens = paramTypes.map(
550
+ (paramType) => paramType as unknown as Token,
551
+ );
498
552
  }
499
553
  }
500
-
554
+
501
555
  const deps = injectTokens.map((tokenOrRef) => {
502
556
  // Resolve forward reference if needed
503
- const token = isForwardRef(tokenOrRef) ? resolveForwardRef(tokenOrRef) : tokenOrRef;
557
+ const token = isForwardRef(tokenOrRef)
558
+ ? resolveForwardRef(tokenOrRef)
559
+ : tokenOrRef;
504
560
  return this.container.resolve(token);
505
561
  });
506
562
  const instance = new controllerClass(...deps);
@@ -530,19 +586,23 @@ export class Application {
530
586
  | "options";
531
587
 
532
588
  // Get method-level guards
533
- const methodGuards = getMethodGuards(controllerClass.prototype, route.handler) ?? [];
589
+ const methodGuards =
590
+ getMethodGuards(controllerClass.prototype, route.handler) ?? [];
534
591
 
535
592
  // Get method-level pipes
536
- const parameterPipes = getMethodPipes(controllerClass.prototype, route.handler) ?? [];
593
+ const parameterPipes =
594
+ getMethodPipes(controllerClass.prototype, route.handler) ?? [];
537
595
 
538
596
  // Get class-level filters
539
597
  const classFilters = getClassFilters(controllerClass) ?? [];
540
598
 
541
599
  // Get method-level filters
542
- const methodFilters = getMethodFilters(controllerClass.prototype, route.handler) ?? [];
600
+ const methodFilters =
601
+ getMethodFilters(controllerClass.prototype, route.handler) ?? [];
543
602
 
544
603
  // Get method-level interceptors
545
- const methodInterceptors = getMethodInterceptors(controllerClass.prototype, route.handler) ?? [];
604
+ const methodInterceptors =
605
+ getMethodInterceptors(controllerClass.prototype, route.handler) ?? [];
546
606
 
547
607
  // Store guard metadata for this route
548
608
  const routeKey = `${method.toUpperCase()}:${fullPath}`;
@@ -663,8 +723,13 @@ export class Application {
663
723
  if (metadata.providers) {
664
724
  for (const provider of metadata.providers) {
665
725
  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);
726
+ const instance = this.container.resolve(
727
+ provider.token as import("../container").Token,
728
+ );
729
+ this.providerInstances.set(
730
+ provider.token as import("../container").Token,
731
+ instance,
732
+ );
668
733
  this.lifecycleManager.registerInstance(instance);
669
734
  }
670
735
 
@@ -706,7 +771,7 @@ export class Application {
706
771
 
707
772
  /**
708
773
  * Perform graceful shutdown
709
- *
774
+ *
710
775
  * Execution order:
711
776
  * 1. Stop accepting new requests
712
777
  * 2. beforeApplicationShutdown(signal)
@@ -761,7 +826,21 @@ export class Application {
761
826
  this.server = Bun.serve({
762
827
  port,
763
828
  hostname,
764
- fetch: async (request: Request) => {
829
+ ...(this.websocketHandler ? { websocket: this.websocketHandler } : {}),
830
+ fetch: async (request: Request, server: Bun.Server) => {
831
+ // Handle WebSocket upgrade requests for subscriptions
832
+ if (
833
+ this.websocketHandler &&
834
+ request.headers.get("upgrade")?.toLowerCase() === "websocket"
835
+ ) {
836
+ // The GraphQL subscription handler may have registered an upgrade callback
837
+ const wsUpgradeHandler = (this.websocketHandler as unknown as { __upgradeHandler?: (req: Request, srv: Bun.Server) => Response | undefined }).__upgradeHandler;
838
+ if (wsUpgradeHandler) {
839
+ const response = wsUpgradeHandler(request, server);
840
+ if (response) return response;
841
+ }
842
+ }
843
+
765
844
  // Reject new requests during shutdown
766
845
  if (this.isShuttingDown) {
767
846
  return new Response("Service Unavailable", { status: 503 });
@@ -787,7 +866,7 @@ export class Application {
787
866
  // Execute guards (before interceptors and pipes)
788
867
  const routeKey = `${request.method}:${url.pathname}`;
789
868
  const guardMetadata = this.routeGuardMetadata.get(routeKey);
790
-
869
+
791
870
  if (guardMetadata || this.globalGuards.length > 0) {
792
871
  const guardsPassed = await executeGuards(context, {
793
872
  globalGuards: this.globalGuards,
@@ -795,7 +874,11 @@ export class Application {
795
874
  methodGuards: guardMetadata?.methodGuards ?? [],
796
875
  resolveGuard: (guard: Guard) => {
797
876
  // Try to resolve from container if it's a token
798
- if (typeof guard === "object" && guard !== null && !("canActivate" in guard)) {
877
+ if (
878
+ typeof guard === "object" &&
879
+ guard !== null &&
880
+ !("canActivate" in guard)
881
+ ) {
799
882
  try {
800
883
  return this.container.resolve(guard as Token) as CanActivate;
801
884
  } catch {
@@ -810,120 +893,155 @@ export class Application {
810
893
  return createForbiddenResponse();
811
894
  }
812
895
  }
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, {
896
+
897
+ // Get interceptor metadata
898
+ const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
899
+
900
+ // Create the handler function that executes pipes and middleware
901
+ const executeHandler = async (): Promise<Response> => {
902
+ // Execute pipes (after guards, before handler)
903
+ const pipeMetadata = this.routePipeMetadata.get(routeKey);
904
+ if (pipeMetadata || this.globalPipes.length > 0) {
905
+ try {
906
+ // Process each parameter with pipes
907
+ const params = pipeMetadata?.parameterPipes ?? [];
908
+ for (const paramMeta of params) {
909
+ // Extract the initial value for this parameter
910
+ const initialValue = await extractParameterValue(
911
+ context,
912
+ paramMeta,
913
+ );
914
+
915
+ // Create pipe context
916
+ const pipeContext: PipeContext = {
917
+ context,
918
+ metadata: {
919
+ index: paramMeta.index,
920
+ name: paramMeta.key,
921
+ decorator: paramMeta.decorator,
922
+ },
923
+ };
924
+
925
+ // Execute pipes for this parameter
926
+ const transformedValue = await executePipes(
927
+ initialValue,
928
+ pipeContext,
929
+ {
841
930
  globalPipes: this.globalPipes,
842
931
  parameterPipes: paramMeta.pipes,
843
932
  resolvePipe: (pipe: Pipe) => {
844
933
  // Try to resolve from container if it's a token
845
- if (typeof pipe === "object" && pipe !== null && !("transform" in pipe)) {
934
+ if (
935
+ typeof pipe === "object" &&
936
+ pipe !== null &&
937
+ !("transform" in pipe)
938
+ ) {
846
939
  try {
847
- return this.container.resolve(pipe as Token) as PipeTransform;
940
+ return this.container.resolve(
941
+ pipe as Token,
942
+ ) as PipeTransform;
848
943
  } catch {
849
944
  return null;
850
945
  }
851
946
  }
852
947
  return null;
853
948
  },
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"));
949
+ },
950
+ );
951
+
952
+ // Store the transformed value in context for handler access
953
+ context.set(`pipe:param:${paramMeta.index}`, transformedValue);
954
+ }
955
+ } catch (error) {
956
+ // Pipe transformation failed - return 400 Bad Request
957
+ if (error instanceof Error) {
958
+ return createBadRequestResponse(error);
865
959
  }
960
+ return createBadRequestResponse(
961
+ new Error("Pipe transformation failed"),
962
+ );
866
963
  }
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
- }
964
+ }
965
+
966
+ // Execute middleware and handler
967
+ const pipeline = compose(
968
+ (match.middleware ?? []) as import("../middleware").Middleware[],
969
+ );
970
+ return pipeline(
971
+ context,
972
+ match.handler as import("../middleware").Handler,
973
+ );
974
+ };
975
+
976
+ // Execute interceptors wrapping around the handler
977
+ // Interceptors run after guards, before pipes
978
+ try {
979
+ const response = await executeInterceptors(context, executeHandler, {
980
+ globalInterceptors: this.globalInterceptors,
981
+ classInterceptors: interceptorMetadata?.classInterceptors ?? [],
982
+ methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
983
+ resolveInterceptor: (
984
+ interceptor: Interceptor,
985
+ ): NestInterceptor | InterceptorFn | null => {
986
+ // Try to resolve from container if it's a token
987
+ if (
988
+ typeof interceptor === "object" &&
989
+ interceptor !== null &&
990
+ !isNestInterceptor(interceptor) &&
991
+ !isInterceptorFn(interceptor)
992
+ ) {
993
+ try {
994
+ return this.container.resolve(
995
+ interceptor as Token,
996
+ ) as NestInterceptor;
997
+ } catch {
998
+ return null;
888
999
  }
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
1000
+ }
1001
+ // Try to instantiate if it's a class constructor
1002
+ if (
1003
+ typeof interceptor === "function" &&
1004
+ !isInterceptorFn(interceptor)
1005
+ ) {
1006
+ try {
1007
+ const Constructor = interceptor as new () => NestInterceptor;
1008
+ const instance = new Constructor();
1009
+ if (isNestInterceptor(instance)) {
1010
+ return instance;
899
1011
  }
1012
+ } catch {
1013
+ // Cannot instantiate
900
1014
  }
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;
1015
+ }
1016
+ return null;
1017
+ },
1018
+ });
1019
+
1020
+ // Execute onAfterRequest hooks
1021
+ try {
1022
+ await this.lifecycleManager.executeOnAfterRequest(
1023
+ context,
1024
+ response as Response,
1025
+ );
913
1026
  } 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);
1027
+ console.error("Error in onAfterRequest hook:", error);
926
1028
  }
1029
+
1030
+ return response as Response;
1031
+ } catch (error) {
1032
+ // Execute onRequestError hooks
1033
+ try {
1034
+ await this.lifecycleManager.executeOnRequestError(
1035
+ context,
1036
+ error as Error,
1037
+ );
1038
+ } catch (hookError) {
1039
+ console.error("Error in onRequestError hook:", hookError);
1040
+ }
1041
+
1042
+ // Handle exception with filters
1043
+ return this.handleException(error as Error, context, routeKey);
1044
+ }
927
1045
  },
928
1046
  });
929
1047
 
@@ -949,7 +1067,7 @@ export class Application {
949
1067
  // Execute guards (before interceptors and pipes)
950
1068
  const routeKey = `${request.method}:${url.pathname}`;
951
1069
  const guardMetadata = this.routeGuardMetadata.get(routeKey);
952
-
1070
+
953
1071
  if (guardMetadata || this.globalGuards.length > 0) {
954
1072
  const guardsPassed = await executeGuards(context, {
955
1073
  globalGuards: this.globalGuards,
@@ -957,7 +1075,11 @@ export class Application {
957
1075
  methodGuards: guardMetadata?.methodGuards ?? [],
958
1076
  resolveGuard: (guard: Guard) => {
959
1077
  // Try to resolve from container if it's a token
960
- if (typeof guard === "object" && guard !== null && !("canActivate" in guard)) {
1078
+ if (
1079
+ typeof guard === "object" &&
1080
+ guard !== null &&
1081
+ !("canActivate" in guard)
1082
+ ) {
961
1083
  try {
962
1084
  return this.container.resolve(guard as Token) as CanActivate;
963
1085
  } catch {
@@ -972,123 +1094,155 @@ export class Application {
972
1094
  return createForbiddenResponse();
973
1095
  }
974
1096
  }
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, {
1097
+
1098
+ // Get interceptor metadata
1099
+ const interceptorMetadata = this.routeInterceptorMetadata.get(routeKey);
1100
+
1101
+ // Create the handler function that executes pipes and middleware
1102
+ const executeHandler = async (): Promise<Response> => {
1103
+ // Execute pipes (after guards, before handler)
1104
+ const pipeMetadata = this.routePipeMetadata.get(routeKey);
1105
+ if (pipeMetadata || this.globalPipes.length > 0) {
1106
+ try {
1107
+ // Process each parameter with pipes
1108
+ const params = pipeMetadata?.parameterPipes ?? [];
1109
+ for (const paramMeta of params) {
1110
+ // Extract the initial value for this parameter
1111
+ const initialValue = await extractParameterValue(
1112
+ context,
1113
+ paramMeta,
1114
+ );
1115
+
1116
+ // Create pipe context
1117
+ const pipeContext: PipeContext = {
1118
+ context,
1119
+ metadata: {
1120
+ index: paramMeta.index,
1121
+ name: paramMeta.key,
1122
+ decorator: paramMeta.decorator,
1123
+ },
1124
+ };
1125
+
1126
+ // Execute pipes for this parameter
1127
+ const transformedValue = await executePipes(
1128
+ initialValue,
1129
+ pipeContext,
1130
+ {
1003
1131
  globalPipes: this.globalPipes,
1004
1132
  parameterPipes: paramMeta.pipes,
1005
1133
  resolvePipe: (pipe: Pipe) => {
1006
1134
  // Try to resolve from container if it's a token
1007
- if (typeof pipe === "object" && pipe !== null && !("transform" in pipe)) {
1135
+ if (
1136
+ typeof pipe === "object" &&
1137
+ pipe !== null &&
1138
+ !("transform" in pipe)
1139
+ ) {
1008
1140
  try {
1009
- return this.container.resolve(pipe as Token) as PipeTransform;
1141
+ return this.container.resolve(
1142
+ pipe as Token,
1143
+ ) as PipeTransform;
1010
1144
  } catch {
1011
1145
  return null;
1012
1146
  }
1013
1147
  }
1014
1148
  return null;
1015
1149
  },
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"));
1150
+ },
1151
+ );
1152
+
1153
+ // Store the transformed value in context for handler access
1154
+ context.set(`pipe:param:${paramMeta.index}`, transformedValue);
1027
1155
  }
1156
+ } catch (error) {
1157
+ // Pipe transformation failed - return 400 Bad Request
1158
+ if (error instanceof Error) {
1159
+ return createBadRequestResponse(error);
1160
+ }
1161
+ return createBadRequestResponse(
1162
+ new Error("Pipe transformation failed"),
1163
+ );
1028
1164
  }
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
- }
1165
+ }
1166
+
1167
+ // Execute middleware and handler
1168
+ const pipeline = compose(
1169
+ (match.middleware ?? []) as import("../middleware").Middleware[],
1170
+ );
1171
+ return pipeline(
1172
+ context,
1173
+ match.handler as import("../middleware").Handler,
1174
+ );
1175
+ };
1176
+
1177
+ // Execute interceptors wrapping around the handler
1178
+ // Interceptors run after guards, before pipes
1179
+ try {
1180
+ const response = await executeInterceptors(context, executeHandler, {
1181
+ globalInterceptors: this.globalInterceptors,
1182
+ classInterceptors: interceptorMetadata?.classInterceptors ?? [],
1183
+ methodInterceptors: interceptorMetadata?.methodInterceptors ?? [],
1184
+ resolveInterceptor: (
1185
+ interceptor: Interceptor,
1186
+ ): NestInterceptor | InterceptorFn | null => {
1187
+ // Try to resolve from container if it's a token
1188
+ if (
1189
+ typeof interceptor === "object" &&
1190
+ interceptor !== null &&
1191
+ !isNestInterceptor(interceptor) &&
1192
+ !isInterceptorFn(interceptor)
1193
+ ) {
1194
+ try {
1195
+ return this.container.resolve(
1196
+ interceptor as Token,
1197
+ ) as NestInterceptor;
1198
+ } catch {
1199
+ return null;
1050
1200
  }
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
1201
+ }
1202
+ // Try to instantiate if it's a class constructor
1203
+ if (
1204
+ typeof interceptor === "function" &&
1205
+ !isInterceptorFn(interceptor)
1206
+ ) {
1207
+ try {
1208
+ const Constructor = interceptor as new () => NestInterceptor;
1209
+ const instance = new Constructor();
1210
+ if (isNestInterceptor(instance)) {
1211
+ return instance;
1061
1212
  }
1213
+ } catch {
1214
+ // Cannot instantiate
1062
1215
  }
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
- }
1216
+ }
1217
+ return null;
1218
+ },
1219
+ });
1220
+
1221
+ return response as Response;
1222
+ } catch (error) {
1223
+ // Handle exception with filters
1224
+ return this.handleException(error as Error, context, routeKey);
1072
1225
  }
1073
-
1074
- /**
1075
- * Get the lifecycle manager for this application
1076
- */
1226
+ }
1227
+
1228
+ /**
1229
+ * Get the lifecycle manager for this application
1230
+ */
1077
1231
  getLifecycleManager(): LifecycleHookManager {
1078
1232
  return this.lifecycleManager;
1079
1233
  }
1080
1234
 
1081
1235
  /**
1082
- * Check if the application is shutting down
1083
- */
1236
+ * Check if the application is shutting down
1237
+ */
1084
1238
  isShuttingDownNow(): boolean {
1085
1239
  return this.isShuttingDown;
1086
1240
  }
1087
1241
 
1088
1242
  /**
1089
- * Handle an exception using the filters system
1090
- * Filters are checked in order: method → class → global
1091
- */
1243
+ * Handle an exception using the filters system
1244
+ * Filters are checked in order: method → class → global
1245
+ */
1092
1246
  private async handleException(
1093
1247
  exception: Error,
1094
1248
  context: Context,
@@ -1102,7 +1256,11 @@ export class Application {
1102
1256
  methodFilters: filterMetadata?.methodFilters ?? [],
1103
1257
  resolveFilter: (filter: Filter): ExceptionFilter | null => {
1104
1258
  // Try to resolve from container if it's a token
1105
- if (typeof filter === "object" && filter !== null && !isExceptionFilter(filter)) {
1259
+ if (
1260
+ typeof filter === "object" &&
1261
+ filter !== null &&
1262
+ !isExceptionFilter(filter)
1263
+ ) {
1106
1264
  try {
1107
1265
  return this.container.resolve(filter as Token) as ExceptionFilter;
1108
1266
  } catch {
@@ -1138,17 +1296,17 @@ export function createApp(moduleClass: Constructor): Application {
1138
1296
  export {
1139
1297
  LifecycleHookManager,
1140
1298
  ShutdownSignalHandler,
1141
- OnModuleInit,
1142
- OnApplicationBootstrap,
1143
- OnModuleDestroy,
1144
- BeforeApplicationShutdown,
1145
- OnApplicationShutdown,
1146
- OnBeforeRequest,
1147
- OnAfterRequest,
1148
- OnRequestError,
1149
- ApplicationLifecycle,
1150
- RequestLifecycle,
1151
- FullLifecycle,
1299
+ type OnModuleInit,
1300
+ type OnApplicationBootstrap,
1301
+ type OnModuleDestroy,
1302
+ type BeforeApplicationShutdown,
1303
+ type OnApplicationShutdown,
1304
+ type OnBeforeRequest,
1305
+ type OnAfterRequest,
1306
+ type OnRequestError,
1307
+ type ApplicationLifecycle,
1308
+ type RequestLifecycle,
1309
+ type FullLifecycle,
1152
1310
  isOnModuleInit,
1153
1311
  isOnApplicationBootstrap,
1154
1312
  isOnModuleDestroy,
@@ -1274,4 +1432,4 @@ export {
1274
1432
  forwardRef,
1275
1433
  isForwardRef,
1276
1434
  resolveForwardRef,
1277
- } from "../container";
1435
+ } from "../container";