stratal 0.0.17 → 0.0.19

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 (200) hide show
  1. package/README.md +8 -8
  2. package/dist/{base-email.provider-DypUAfWm.mjs → base-email.provider-mjynzewK.mjs} +1 -1
  3. package/dist/{base-email.provider-DypUAfWm.mjs.map → base-email.provider-mjynzewK.mjs.map} +1 -1
  4. package/dist/bin/cloudflare-workers-loader.mjs +33 -1
  5. package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
  6. package/dist/bin/quarry.mjs +169 -7
  7. package/dist/bin/quarry.mjs.map +1 -1
  8. package/dist/cache/index.d.mts +3 -2
  9. package/dist/cache/index.d.mts.map +1 -1
  10. package/dist/cache/index.mjs +3 -10
  11. package/dist/cache/index.mjs.map +1 -1
  12. package/dist/{colors-Y7WIFXs7.mjs → colors-DJaRDXoS.mjs} +1 -1
  13. package/dist/{colors-Y7WIFXs7.mjs.map → colors-DJaRDXoS.mjs.map} +1 -1
  14. package/dist/{command-B1CPgsrU.mjs → command-BgSlsS4M.mjs} +3 -3
  15. package/dist/command-BgSlsS4M.mjs.map +1 -0
  16. package/dist/{command-TnkPYWta.d.mts → command-DsQq56Lp.d.mts} +2 -2
  17. package/dist/{command-TnkPYWta.d.mts.map → command-DsQq56Lp.d.mts.map} +1 -1
  18. package/dist/config/index.d.mts +81 -37
  19. package/dist/config/index.d.mts.map +1 -1
  20. package/dist/config/index.mjs +135 -61
  21. package/dist/config/index.mjs.map +1 -1
  22. package/dist/{consumer-registry-Bymm6ff4.d.mts → consumer-registry-Doom7BEh.d.mts} +1 -1
  23. package/dist/{consumer-registry-Bymm6ff4.d.mts.map → consumer-registry-Doom7BEh.d.mts.map} +1 -1
  24. package/dist/controller.decorator-LZY9aHYG.mjs +66 -0
  25. package/dist/controller.decorator-LZY9aHYG.mjs.map +1 -0
  26. package/dist/cron/index.d.mts +4 -3
  27. package/dist/cron/index.d.mts.map +1 -1
  28. package/dist/cron/index.mjs +1 -3
  29. package/dist/{cron-manager-CFBamKKk.mjs → cron-manager-C30t9UZM.mjs} +29 -19
  30. package/dist/cron-manager-C30t9UZM.mjs.map +1 -0
  31. package/dist/{cron-manager-D7imGwUT.d.mts → cron-manager-RuPtFVLy.d.mts} +28 -14
  32. package/dist/cron-manager-RuPtFVLy.d.mts.map +1 -0
  33. package/dist/di/index.d.mts +2 -2
  34. package/dist/di/index.mjs +3 -3
  35. package/dist/email/index.d.mts +3 -3
  36. package/dist/email/index.mjs +87 -18
  37. package/dist/email/index.mjs.map +1 -1
  38. package/dist/{en-DaewN8hc.mjs → en-rHmW6vD9.mjs} +14 -31
  39. package/dist/en-rHmW6vD9.mjs.map +1 -0
  40. package/dist/env-CamWD-U1.d.mts +25 -0
  41. package/dist/env-CamWD-U1.d.mts.map +1 -0
  42. package/dist/errors/index.d.mts +2 -2
  43. package/dist/errors/index.mjs +2 -3
  44. package/dist/errors-B4pYgYON.mjs +1714 -0
  45. package/dist/errors-B4pYgYON.mjs.map +1 -0
  46. package/dist/{errors-DuAR5Wke.mjs → errors-BUyUfr2Z.mjs} +14 -7
  47. package/dist/errors-BUyUfr2Z.mjs.map +1 -0
  48. package/dist/events/index.d.mts +2 -2
  49. package/dist/events/index.mjs +1 -2
  50. package/dist/{events-CvUSgEuN.mjs → events-COKixqnG.mjs} +2 -2
  51. package/dist/{events-CvUSgEuN.mjs.map → events-COKixqnG.mjs.map} +1 -1
  52. package/dist/{gateway-context-CNOLkLUC.mjs → gateway-context-cqZ8wMoi.mjs} +4 -9
  53. package/dist/gateway-context-cqZ8wMoi.mjs.map +1 -0
  54. package/dist/guards/index.d.mts +14 -5
  55. package/dist/guards/index.d.mts.map +1 -1
  56. package/dist/guards/index.mjs +1 -1
  57. package/dist/{guards-DUk_Kzst.mjs → guards-DMbsAxSX.mjs} +1 -1
  58. package/dist/guards-DMbsAxSX.mjs.map +1 -0
  59. package/dist/http-method.decorator-BT3ufnz8.mjs +96 -0
  60. package/dist/http-method.decorator-BT3ufnz8.mjs.map +1 -0
  61. package/dist/i18n/index.d.mts +3 -3
  62. package/dist/i18n/index.mjs +3 -16
  63. package/dist/i18n/messages/en/index.d.mts +1 -1
  64. package/dist/i18n/messages/en/index.mjs +1 -1
  65. package/dist/i18n/utils/index.d.mts +30 -0
  66. package/dist/i18n/utils/index.d.mts.map +1 -0
  67. package/dist/i18n/utils/index.mjs +2 -0
  68. package/dist/i18n/validation/index.d.mts +1 -1
  69. package/dist/i18n/validation/index.mjs +1 -1
  70. package/dist/i18n.module-CI_prYFD.mjs +2340 -0
  71. package/dist/i18n.module-CI_prYFD.mjs.map +1 -0
  72. package/dist/{index-NGxg-KP_.d.mts → index-B437eK7p.d.mts} +59 -16
  73. package/dist/index-B437eK7p.d.mts.map +1 -0
  74. package/dist/{index-Dp6A5ywM.d.mts → index-CWRS7Ri3.d.mts} +1 -1
  75. package/dist/{index-Dp6A5ywM.d.mts.map → index-CWRS7Ri3.d.mts.map} +1 -1
  76. package/dist/{index-D_w_Rmtd.d.mts → index-DFhEeFfC.d.mts} +13 -30
  77. package/dist/{index-D_w_Rmtd.d.mts.map → index-DFhEeFfC.d.mts.map} +1 -1
  78. package/dist/index-DPFqRs8L.d.mts +4318 -0
  79. package/dist/index-DPFqRs8L.d.mts.map +1 -0
  80. package/dist/{index-DGRe6Yoa.d.mts → index-Dnqm9ZB6.d.mts} +5 -4
  81. package/dist/index-Dnqm9ZB6.d.mts.map +1 -0
  82. package/dist/index-SHx31sBJ.d.mts +101 -0
  83. package/dist/index-SHx31sBJ.d.mts.map +1 -0
  84. package/dist/index.d.mts +5 -3
  85. package/dist/index.d.mts.map +1 -1
  86. package/dist/index.mjs +1 -20
  87. package/dist/{is-command-DJVI6wEJ.mjs → is-command-C6a7WTPw.mjs} +2 -2
  88. package/dist/{is-command-DJVI6wEJ.mjs.map → is-command-C6a7WTPw.mjs.map} +1 -1
  89. package/dist/{is-seeder-D5MIEcdz.mjs → is-seeder-CebjZCDn.mjs} +1 -1
  90. package/dist/{is-seeder-D5MIEcdz.mjs.map → is-seeder-CebjZCDn.mjs.map} +1 -1
  91. package/dist/logger/index.d.mts +1 -1
  92. package/dist/logger/index.mjs +1 -1
  93. package/dist/{logger-CGT91VY6.mjs → logger-V6Ms3QnQ.mjs} +63 -45
  94. package/dist/logger-V6Ms3QnQ.mjs.map +1 -0
  95. package/dist/macroable/index.d.mts +2 -0
  96. package/dist/macroable/index.mjs +2 -0
  97. package/dist/macroable-BmufBshB.mjs +122 -0
  98. package/dist/macroable-BmufBshB.mjs.map +1 -0
  99. package/dist/module/index.d.mts +3 -4
  100. package/dist/module/index.d.mts.map +1 -1
  101. package/dist/module/index.mjs +1 -10
  102. package/dist/module-qGE_1duv.mjs +732 -0
  103. package/dist/module-qGE_1duv.mjs.map +1 -0
  104. package/dist/openapi/index.d.mts +3 -3
  105. package/dist/openapi/index.mjs +2 -15
  106. package/dist/{openapi-tools.service-B3TxYKoQ.mjs → openapi-tools.service-CYWGuhue.mjs} +4 -1
  107. package/dist/{openapi-tools.service-B3TxYKoQ.mjs.map → openapi-tools.service-CYWGuhue.mjs.map} +1 -1
  108. package/dist/{openapi.service-DGnX3Fc4.d.mts → openapi.service-Bv_NioM9.d.mts} +9 -17
  109. package/dist/openapi.service-Bv_NioM9.d.mts.map +1 -0
  110. package/dist/quarry/index.d.mts +26 -12
  111. package/dist/quarry/index.d.mts.map +1 -1
  112. package/dist/quarry/index.mjs +4 -8
  113. package/dist/{quarry-registry-B2rkO-JS.mjs → quarry-registry-DFfRRkA7.mjs} +45 -40
  114. package/dist/quarry-registry-DFfRRkA7.mjs.map +1 -0
  115. package/dist/queue/index.d.mts +2 -2
  116. package/dist/queue/index.mjs +3 -13
  117. package/dist/queue/index.mjs.map +1 -1
  118. package/dist/{queue.module-BtI8f4Jo.mjs → queue.module-P-G-nCYz.mjs} +39 -42
  119. package/dist/queue.module-P-G-nCYz.mjs.map +1 -0
  120. package/dist/r2-storage.provider-LdzK9tfG.mjs +244 -0
  121. package/dist/r2-storage.provider-LdzK9tfG.mjs.map +1 -0
  122. package/dist/{resend.provider-bXMEkdRJ.mjs → resend.provider-bwILp0WI.mjs} +2 -4
  123. package/dist/{resend.provider-bXMEkdRJ.mjs.map → resend.provider-bwILp0WI.mjs.map} +1 -1
  124. package/dist/router/index.d.mts +2 -2
  125. package/dist/router/index.mjs +7 -16
  126. package/dist/seeder/index.d.mts +3 -4
  127. package/dist/seeder/index.d.mts.map +1 -1
  128. package/dist/seeder/index.mjs +2 -6
  129. package/dist/{seeder-R7RXJC35.mjs → seeder-BcqIFa2X.mjs} +5 -5
  130. package/dist/{seeder-R7RXJC35.mjs.map → seeder-BcqIFa2X.mjs.map} +1 -1
  131. package/dist/setup-CtekcwuO.mjs +37 -0
  132. package/dist/setup-CtekcwuO.mjs.map +1 -0
  133. package/dist/signed-url-COX7cCWR.mjs +74 -0
  134. package/dist/signed-url-COX7cCWR.mjs.map +1 -0
  135. package/dist/{smtp.provider-DrbHQztF.mjs → smtp.provider-B07yuARi.mjs} +2 -4
  136. package/dist/{smtp.provider-DrbHQztF.mjs.map → smtp.provider-B07yuARi.mjs.map} +1 -1
  137. package/dist/storage/index.d.mts +39 -17
  138. package/dist/storage/index.d.mts.map +1 -1
  139. package/dist/storage/index.mjs +3 -14
  140. package/dist/storage/providers/index.d.mts +30 -69
  141. package/dist/storage/providers/index.d.mts.map +1 -1
  142. package/dist/storage/providers/index.mjs +2 -5
  143. package/dist/{storage-CZKHOhci.mjs → storage-P6X4h9So.mjs} +102 -29
  144. package/dist/storage-P6X4h9So.mjs.map +1 -0
  145. package/dist/{storage-provider.interface-0IqcdhBf.d.mts → storage-provider.interface-CC1nniHk.d.mts} +20 -15
  146. package/dist/storage-provider.interface-CC1nniHk.d.mts.map +1 -0
  147. package/dist/stratal-BCiwCFN9.mjs +533 -0
  148. package/dist/stratal-BCiwCFN9.mjs.map +1 -0
  149. package/dist/{types-DahElfUw.d.mts → types-DIWemRad.d.mts} +2 -2
  150. package/dist/types-DIWemRad.d.mts.map +1 -0
  151. package/dist/{usage-generator-CVIsENuE.mjs → usage-generator-MBcRo0Q2.mjs} +2 -2
  152. package/dist/{usage-generator-CVIsENuE.mjs.map → usage-generator-MBcRo0Q2.mjs.map} +1 -1
  153. package/dist/{validation-DQTC259A.mjs → validation-Dbg3ehdP.mjs} +2 -2
  154. package/dist/{validation-DQTC259A.mjs.map → validation-Dbg3ehdP.mjs.map} +1 -1
  155. package/dist/websocket/index.d.mts +3 -3
  156. package/dist/websocket/index.d.mts.map +1 -1
  157. package/dist/websocket/index.mjs +1 -4
  158. package/dist/workers/index.d.mts +2 -1
  159. package/dist/workers/index.d.mts.map +1 -1
  160. package/dist/workers/index.mjs +2 -20
  161. package/dist/workers/index.mjs.map +1 -1
  162. package/package.json +41 -50
  163. package/dist/application-DfPtIzxF.d.mts +0 -177
  164. package/dist/application-DfPtIzxF.d.mts.map +0 -1
  165. package/dist/command-B1CPgsrU.mjs.map +0 -1
  166. package/dist/cron-manager-CFBamKKk.mjs.map +0 -1
  167. package/dist/cron-manager-D7imGwUT.d.mts.map +0 -1
  168. package/dist/en-DaewN8hc.mjs.map +0 -1
  169. package/dist/errors-DSKapqD8.mjs +0 -707
  170. package/dist/errors-DSKapqD8.mjs.map +0 -1
  171. package/dist/errors-DuAR5Wke.mjs.map +0 -1
  172. package/dist/gateway-context-CNOLkLUC.mjs.map +0 -1
  173. package/dist/guards-DUk_Kzst.mjs.map +0 -1
  174. package/dist/i18n.module-Dn9SrFdS.mjs +0 -1841
  175. package/dist/i18n.module-Dn9SrFdS.mjs.map +0 -1
  176. package/dist/index-BFCxSp_f.d.mts +0 -2625
  177. package/dist/index-BFCxSp_f.d.mts.map +0 -1
  178. package/dist/index-DGRe6Yoa.d.mts.map +0 -1
  179. package/dist/index-NGxg-KP_.d.mts.map +0 -1
  180. package/dist/logger-CGT91VY6.mjs.map +0 -1
  181. package/dist/middleware/index.d.mts +0 -2
  182. package/dist/middleware/index.mjs +0 -5
  183. package/dist/middleware-Bl-b5pkt.mjs +0 -362
  184. package/dist/middleware-Bl-b5pkt.mjs.map +0 -1
  185. package/dist/module-registry-CmjBX6ol.d.mts +0 -121
  186. package/dist/module-registry-CmjBX6ol.d.mts.map +0 -1
  187. package/dist/module-tUtyVJ5E.mjs +0 -371
  188. package/dist/module-tUtyVJ5E.mjs.map +0 -1
  189. package/dist/openapi.service-DGnX3Fc4.d.mts.map +0 -1
  190. package/dist/quarry-registry-B2rkO-JS.mjs.map +0 -1
  191. package/dist/queue.module-BtI8f4Jo.mjs.map +0 -1
  192. package/dist/router-context-D9R1v2Ac.mjs +0 -267
  193. package/dist/router-context-D9R1v2Ac.mjs.map +0 -1
  194. package/dist/s3-storage.provider-CttzNnDR.mjs +0 -335
  195. package/dist/s3-storage.provider-CttzNnDR.mjs.map +0 -1
  196. package/dist/storage-CZKHOhci.mjs.map +0 -1
  197. package/dist/storage-provider.interface-0IqcdhBf.d.mts.map +0 -1
  198. package/dist/stratal-D5smIU1y.mjs +0 -315
  199. package/dist/stratal-D5smIU1y.mjs.map +0 -1
  200. package/dist/types-DahElfUw.d.mts.map +0 -1
@@ -1,2625 +0,0 @@
1
- import { t as index_d_exports } from "./index-D_w_Rmtd.mjs";
2
- import { t as Constructor } from "./types-DahElfUw.mjs";
3
- import { _ as II18nService, a as index_d_exports$1, o as z, t as OpenAPIHono, v as MessageKeys, y as MessageParams } from "./index-NGxg-KP_.mjs";
4
- import { i as LoggerService } from "./index-Dp6A5ywM.mjs";
5
- import { DependencyContainer, DependencyContainer as DependencyContainer$1, container as container$1, delay, inject as inject$1, injectable as injectable$1, instancePerContainerCachingFactory as instancePerContainerCachingFactory$1, singleton } from "tsyringe";
6
- import { SSEMessage, SSEStreamingApi, SSEStreamingApi as SSEStreamingApi$1 } from "hono/streaming";
7
- import { CoreContext } from "@intlify/core-base";
8
- import { Context } from "hono";
9
- import { ContentfulStatusCode, RedirectStatusCode } from "hono/utils/http-status";
10
- import { StreamingApi, StreamingApi as StreamingApi$1 } from "hono/utils/stream";
11
- import InjectionToken$1, { default as InjectionToken$2 } from "tsyringe/dist/typings/providers/injection-token";
12
-
13
- //#region src/errors/error-response.d.ts
14
- type Environment = 'development' | 'staging' | 'production';
15
- interface ErrorResponse {
16
- /**
17
- * Numeric error code for identification and escalation
18
- * See error-codes.ts for the complete registry
19
- */
20
- code: number;
21
- /**
22
- * Human-readable error message
23
- * Fixed per error type, not customizable
24
- */
25
- message: string;
26
- /**
27
- * ISO timestamp when the error occurred
28
- */
29
- timestamp: string;
30
- /**
31
- * Additional structured data about the error
32
- * Only included in development environment
33
- */
34
- metadata?: Record<string, unknown>;
35
- /**
36
- * Stack trace for debugging
37
- * Only included in development environment
38
- */
39
- stack?: string;
40
- }
41
- /**
42
- * Type guard to check if an object is an ErrorResponse
43
- */
44
- declare function isErrorResponse(obj: unknown): obj is ErrorResponse;
45
- //#endregion
46
- //#region src/i18n/messages/index.d.ts
47
- /**
48
- * All locale messages
49
- * Explicitly import and export (no filesystem scanning - Cloudflare Workers compatible)
50
- */
51
- declare const messages: {
52
- readonly en: typeof index_d_exports;
53
- };
54
- /**
55
- * Type for all messages
56
- */
57
- type Messages = typeof messages;
58
- /**
59
- * Get messages for all locales
60
- */
61
- declare function getMessages(): Record<string, Record<string, unknown>>;
62
- /**
63
- * Get available locales
64
- */
65
- declare function getLocales(): string[];
66
- //#endregion
67
- //#region src/di/types.d.ts
68
- /**
69
- * Service scope for DI registration
70
- *
71
- * Maps directly to tsyringe's Lifecycle enum.
72
- * Scope is specified at registration time via provider configuration,
73
- * not at class decoration time.
74
- *
75
- * @example
76
- * ```typescript
77
- * // In module providers:
78
- * { provide: MY_TOKEN, useClass: MyService, scope: Scope.Singleton }
79
- *
80
- * // In Application.ts:
81
- * container.register(MY_TOKEN, MyService, Scope.Request)
82
- * ```
83
- */
84
- declare enum Scope {
85
- /** New instance per resolution (default) */
86
- Transient = 0,
87
- /** Single instance shared globally */
88
- Singleton = 1,
89
- /** New instance per child container (per request) */
90
- Request = 3
91
- }
92
- /**
93
- * Options for conditional binding with `when()` method
94
- */
95
- interface WhenOptions {
96
- /**
97
- * Cache predicate result after first evaluation.
98
- * When true, the predicate is evaluated once and the result is reused.
99
- * When false (default), predicate is evaluated on each resolution.
100
- */
101
- cache?: boolean;
102
- }
103
- /**
104
- * Decorator function type for extend() method
105
- *
106
- * @template T The service type being decorated
107
- */
108
- type ExtensionDecorator<T> = (service: T, container: ContainerLike) => T;
109
- /**
110
- * Minimal container interface for decorator functions
111
- * Avoids circular dependency with Container class
112
- */
113
- interface ContainerLike {
114
- resolve<T>(token: InjectionToken$1<T>): T;
115
- }
116
- //#endregion
117
- //#region src/di/conditional-binding-builder.d.ts
118
- /**
119
- * Container interface for predicate functions
120
- * Using a minimal interface to avoid circular imports
121
- */
122
- interface PredicateContainer {
123
- resolve<T>(token: InjectionToken$1<T>): T;
124
- isRegistered<T>(token: InjectionToken$1<T>): boolean;
125
- }
126
- /**
127
- * Initial builder returned by container.when()
128
- */
129
- interface ConditionalBindingBuilder {
130
- /**
131
- * Specify the token to conditionally bind
132
- *
133
- * @param token - DI token for the service
134
- * @returns Builder for specifying implementations
135
- */
136
- use<T extends object>(token: InjectionToken$1<T>): ConditionalBindingUse<T>;
137
- }
138
- /**
139
- * Builder after specifying token with use()
140
- */
141
- interface ConditionalBindingUse<T extends object> {
142
- /**
143
- * Specify the implementation when predicate returns true.
144
- * Registration is completed immediately.
145
- *
146
- * If predicate is false at resolution time:
147
- * - Uses `otherwise()` implementation if provided
148
- * - Falls back to existing registration if available
149
- * - Throws error if no fallback exists
150
- *
151
- * @param implementation - Service class to use when predicate is true
152
- * @returns Builder for optional fallback specification
153
- */
154
- give(implementation: Constructor<T>): ConditionalBindingGive<T>;
155
- }
156
- /**
157
- * Builder after specifying true implementation with give()
158
- * Registration is already complete at this point.
159
- */
160
- interface ConditionalBindingGive<T extends object> {
161
- /**
162
- * Optionally specify a fallback implementation when predicate returns false.
163
- * This re-registers with the explicit fallback instead of existing registration.
164
- *
165
- * @param implementation - Service class to use when predicate is false
166
- */
167
- otherwise(implementation: Constructor<T>): void;
168
- }
169
- /**
170
- * Implementation of ConditionalBindingBuilder
171
- *
172
- * @internal
173
- */
174
- declare class ConditionalBindingBuilderImpl implements ConditionalBindingBuilder {
175
- private readonly tsyringeContainer;
176
- private readonly predicateContainer;
177
- private readonly predicate;
178
- private readonly options;
179
- constructor(tsyringeContainer: DependencyContainer, predicateContainer: PredicateContainer, predicate: (container: PredicateContainer) => boolean, options: WhenOptions);
180
- use<T extends object>(token: InjectionToken$1<T>): ConditionalBindingUse<T>;
181
- }
182
- //#endregion
183
- //#region src/di/container.d.ts
184
- /**
185
- * Options for creating a Container instance
186
- */
187
- interface ContainerOptions {
188
- /** Pre-created DependencyContainer */
189
- container: DependencyContainer;
190
- /** Whether this is a request-scoped container */
191
- isRequestScoped?: boolean;
192
- }
193
- /**
194
- * Unified Container for DI management
195
- *
196
- * Manages the two-tier container hierarchy:
197
- * - Global scope: Singletons, base instances of request-scoped services
198
- * - Request scope: Context-enriched instances per HTTP request
199
- *
200
- * @example Basic registration
201
- * ```typescript
202
- * import { container as tsyringeRootContainer } from 'tsyringe'
203
- *
204
- * const container = new Container({
205
- * container: tsyringeRootContainer.createChildContainer()
206
- * })
207
- *
208
- * container.register(I18nService)
209
- * container.register(MY_TOKEN, MyService)
210
- * container.registerSingleton(ConfigService)
211
- * container.registerValue(MY_TOKEN, myInstance)
212
- * ```
213
- *
214
- * @example Request scope (automatic lifecycle)
215
- * ```typescript
216
- * await container.runInRequestScope(routerContext, async (requestContainer) => {
217
- * const i18n = requestContainer.resolve(I18N_TOKEN)
218
- * })
219
- * ```
220
- */
221
- declare class Container {
222
- private readonly container;
223
- private readonly isRequestScoped;
224
- constructor(options: ContainerOptions);
225
- /**
226
- * Register a service with optional explicit token and scope
227
- */
228
- register<T extends object>(serviceClass: Constructor<T>, scope?: Scope): void;
229
- register<T extends object>(token: InjectionToken$1<T>, serviceClass: Constructor<T>, scope?: Scope): void;
230
- /**
231
- * Register a service as singleton
232
- */
233
- registerSingleton<T extends object>(serviceClass: Constructor<T>): void;
234
- registerSingleton<T extends object>(token: InjectionToken$1<T>, serviceClass: Constructor<T>): void;
235
- /**
236
- * Register a value (instance) directly
237
- */
238
- registerValue<T>(token: InjectionToken$1<T>, value: T): void;
239
- /**
240
- * Register with factory function
241
- */
242
- registerFactory<T>(token: InjectionToken$1<T>, factory: (container: Container) => T): void;
243
- /**
244
- * Register an alias to an existing token
245
- */
246
- registerExisting<T>(alias: InjectionToken$1<T>, target: InjectionToken$1<T>): void;
247
- /**
248
- * Resolve a service from the container
249
- */
250
- resolve<T>(token: InjectionToken$1<T>): T;
251
- /**
252
- * Check if a token is registered
253
- */
254
- isRegistered<T>(token: InjectionToken$1<T>): boolean;
255
- /**
256
- * Start a conditional binding with predicate evaluation
257
- */
258
- when(predicate: (container: PredicateContainer) => boolean, options?: WhenOptions): ConditionalBindingBuilder;
259
- /**
260
- * Replace a service registration with a decorated version
261
- */
262
- extend<T>(token: InjectionToken$1<T>, decorator: ExtensionDecorator<T>): void;
263
- /**
264
- * Run callback within request scope
265
- *
266
- * Creates a child container with fresh instances for services registered with `scope: Scope.Request`.
267
- * Callback receives the request-scoped container as argument.
268
- *
269
- * Can only be called on global container (not request-scoped).
270
- */
271
- runInRequestScope<T>(routerContext: RouterContext, callback: (requestContainer: Container) => T | Promise<T>): Promise<T>;
272
- /**
273
- * Create request scope container
274
- *
275
- * Can only be called on global container (not request-scoped).
276
- */
277
- createRequestScope(routerContext: RouterContext): Container;
278
- /**
279
- * Get underlying tsyringe container
280
- */
281
- getTsyringeContainer(): DependencyContainer;
282
- dispose(): void | Promise<void>;
283
- }
284
- //#endregion
285
- //#region src/di/tokens.d.ts
286
- /**
287
- * Token for the Container instance
288
- * Used for injecting the Container into services that need dynamic resolution
289
- */
290
- declare const CONTAINER_TOKEN: unique symbol;
291
- declare const DI_TOKENS: {
292
- readonly CloudflareEnv: symbol;
293
- readonly ExecutionContext: symbol;
294
- readonly Container: typeof CONTAINER_TOKEN;
295
- readonly Application: symbol;
296
- readonly ModuleRegistry: symbol;
297
- readonly ErrorHandler: symbol;
298
- readonly Database: symbol;
299
- readonly Queue: symbol;
300
- readonly ConsumerRegistry: symbol;
301
- readonly Cron: symbol;
302
- readonly EventRegistry: symbol;
303
- readonly Quarry: symbol;
304
- /**
305
- * AuthContext: Use for services that need user authentication (userId).
306
- */
307
- readonly AuthContext: symbol;
308
- readonly DurableObjectState: symbol;
309
- readonly DurableObjectId: symbol;
310
- };
311
- type DIToken = typeof DI_TOKENS[keyof typeof DI_TOKENS];
312
- //#endregion
313
- //#region src/di/decorators/inject-param.decorator.d.ts
314
- /**
315
- * Metadata key for storing parameter injection information
316
- */
317
- declare const INJECT_PARAM_METADATA_KEY: unique symbol;
318
- /**
319
- * Describes a parameter injection
320
- */
321
- interface ParamInjection {
322
- /** Parameter index in the method signature (0-based) */
323
- index: number;
324
- /** DI token to resolve */
325
- token: InjectionToken$1;
326
- }
327
- /**
328
- * Mark a method parameter for DI injection
329
- *
330
- * The parameter will be resolved from the request-scoped container
331
- * when the controller method is invoked.
332
- *
333
- * @param token - DI token to resolve (class or symbol)
334
- *
335
- * @example With class token
336
- * ```typescript
337
- * async show(
338
- * ctx: RouterContext,
339
- * @InjectParam(UserService) userService: UserService
340
- * ) { }
341
- * ```
342
- *
343
- * @example With symbol token
344
- * ```typescript
345
- * async show(
346
- * ctx: RouterContext,
347
- * @InjectParam(DI_TOKENS.Cache) cache: ICacheService
348
- * ) { }
349
- * ```
350
- */
351
- declare function InjectParam<T>(token: InjectionToken$1<T>): ParameterDecorator;
352
- /**
353
- * Get method parameter injections
354
- *
355
- * @param target - Controller prototype
356
- * @param propertyKey - Method name
357
- * @returns Array of parameter injections sorted by index
358
- */
359
- declare function getMethodInjections(target: object, propertyKey: string | symbol): ParamInjection[];
360
- //#endregion
361
- //#region src/di/decorators.d.ts
362
- /**
363
- * Mark a class as injectable
364
- *
365
- * This decorator wraps tsyringe's `@injectable` decorator and optionally
366
- * associates a token with the class. The actual lifecycle (Singleton, Request,
367
- * Transient) is determined at registration time, not decoration time.
368
- *
369
- * **Lifecycle Control:**
370
- * - Use `scope: Scope.Singleton` in module providers for singleton
371
- * - Use `scope: Scope.Request` in module providers for request-scoped
372
- * - Default is Transient (new instance per resolution)
373
- *
374
- * @param token - Optional DI token for service resolution
375
- *
376
- * @example Basic usage (no token)
377
- * ```typescript
378
- * @Transient()
379
- * export class UserService {
380
- * constructor(@inject(DI_TOKENS.Database) private db: DatabaseService) {}
381
- * }
382
- *
383
- * // In module:
384
- * @Module({
385
- * providers: [UserService] // Transient by default
386
- * })
387
- * ```
388
- *
389
- * @example With token
390
- * ```typescript
391
- * @Transient(DI_TOKENS.ConnectionManager)
392
- * export class ConnectionManager implements Disposable {
393
- * // ...
394
- * }
395
- *
396
- * // In Application.ts:
397
- * container.register(DI_TOKENS.ConnectionManager, ConnectionManager, Scope.Request)
398
- * ```
399
- *
400
- * @example Singleton via provider scope
401
- * ```typescript
402
- * @Transient()
403
- * export class ConsumerRegistry {
404
- * // ...
405
- * }
406
- *
407
- * // In module:
408
- * @Module({
409
- * providers: [
410
- * { provide: DI_TOKENS.ConsumerRegistry, useClass: ConsumerRegistry, scope: Scope.Singleton }
411
- * ]
412
- * })
413
- * ```
414
- */
415
- declare function Transient<T>(token?: InjectionToken$1<T>): <TFunction extends abstract new (...args: never[]) => unknown>(target: TFunction) => TFunction;
416
- //#endregion
417
- //#region src/di/errors/conditional-binding-fallback.error.d.ts
418
- /**
419
- * ConditionalBindingFallbackError
420
- *
421
- * Thrown when a conditional binding predicate returns false but no fallback
422
- * implementation was provided and no existing registration exists for the token.
423
- *
424
- * This typically indicates a misconfiguration in the DI setup where:
425
- * - A `when().use().give()` chain was used without `otherwise()`
426
- * - AND the token wasn't previously registered
427
- * - AND the predicate evaluated to false at resolution time
428
- */
429
- declare class ConditionalBindingFallbackError extends ApplicationError {
430
- constructor(token: string);
431
- }
432
- //#endregion
433
- //#region src/di/errors/request-scope-operation-not-allowed.error.d.ts
434
- /**
435
- * RequestScopeOperationNotAllowedError
436
- *
437
- * Thrown when attempting to call a method that is not allowed on the current container scope.
438
- * - `createRequestScope()` and `runInRequestScope()` can only be called on global containers
439
- */
440
- declare class RequestScopeOperationNotAllowedError extends ApplicationError {
441
- constructor(methodName: string);
442
- }
443
- //#endregion
444
- //#region src/env.d.ts
445
- /**
446
- * Cloudflare Worker Environment Bindings
447
- *
448
- * This interface defines the base environment bindings required by Stratal.
449
- * Use TypeScript module augmentation to add your own application-specific bindings.
450
- *
451
- * @example
452
- * ```typescript
453
- * declare module 'stratal' {
454
- * interface StratalEnv {
455
- * DATABASE: D1Database
456
- * NOTIFICATIONS_QUEUE: Queue
457
- * }
458
- * }
459
- * ```
460
- */
461
- interface StratalEnv {
462
- ENVIRONMENT: string;
463
- CACHE: KVNamespace;
464
- }
465
- //#endregion
466
- //#region src/router/constants.d.ts
467
- /**
468
- * Type-safe context keys for Hono router variables
469
- * Using symbols to avoid string collisions
470
- */
471
- declare const ROUTER_CONTEXT_KEYS: {
472
- readonly REQUEST_CONTAINER: "requestContainer";
473
- readonly LOCALE: "locale";
474
- };
475
- /**
476
- * Metadata keys for storing route and controller configuration
477
- * Using symbols to avoid collisions with other decorators
478
- */
479
- declare const ROUTE_METADATA_KEYS: {
480
- readonly CONTROLLER_ROUTE: symbol;
481
- readonly CONTROLLER_OPTIONS: symbol;
482
- readonly CONTROLLER_MIDDLEWARES: symbol;
483
- readonly ROUTE_CONFIG: symbol;
484
- readonly DECORATED_METHODS: symbol;
485
- readonly HTTP_ROUTE_CONFIG: symbol;
486
- readonly HTTP_DECORATED_METHODS: symbol;
487
- readonly AUTH_GUARD: symbol;
488
- readonly GATEWAY_MARKER: symbol;
489
- readonly WS_ON_MESSAGE: symbol;
490
- readonly WS_ON_CLOSE: symbol;
491
- readonly WS_ON_ERROR: symbol;
492
- };
493
- /**
494
- * Security scheme identifiers for OpenAPI
495
- * These reference the security scheme definitions in security.schemas.ts
496
- */
497
- declare const SECURITY_SCHEMES: {
498
- readonly BEARER_AUTH: "bearerAuth";
499
- readonly API_KEY: "apiKey";
500
- readonly SESSION_COOKIE: "sessionCookie";
501
- };
502
- /**
503
- * HTTP method mapping for RESTful controller methods
504
- * Maps controller method names to HTTP verbs and path patterns
505
- */
506
- declare const HTTP_METHODS: {
507
- readonly index: {
508
- readonly method: "get";
509
- readonly path: "";
510
- };
511
- readonly show: {
512
- readonly method: "get";
513
- readonly path: "/:id";
514
- };
515
- readonly create: {
516
- readonly method: "post";
517
- readonly path: "";
518
- };
519
- readonly update: {
520
- readonly method: "put";
521
- readonly path: "/:id";
522
- };
523
- readonly patch: {
524
- readonly method: "patch";
525
- readonly path: "/:id";
526
- };
527
- readonly destroy: {
528
- readonly method: "delete";
529
- readonly path: "/:id";
530
- };
531
- };
532
- /**
533
- * Sentinel symbol to opt a controller out of versioning.
534
- * When used as the version, no prefix is applied even when defaultVersion is set.
535
- */
536
- declare const VERSION_NEUTRAL: unique symbol;
537
- //#endregion
538
- //#region src/router/types.d.ts
539
- /**
540
- * Route parameter type for OpenAPI
541
- * ZodObject or ZodPipe (piped validation)
542
- */
543
- type ZodObjectWithEffect = index_d_exports$1.ZodObject<any> | index_d_exports$1.ZodPipe<any, any>;
544
- type RouteParameter = ZodObjectWithEffect | undefined;
545
- /**
546
- * Hono context variables with type-safe keys
547
- */
548
- interface RouterVariables {
549
- [ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER]: Container;
550
- [ROUTER_CONTEXT_KEYS.LOCALE]?: string;
551
- }
552
- /**
553
- * Hono environment type for router
554
- */
555
- interface RouterEnv {
556
- Bindings: StratalEnv;
557
- Variables: RouterVariables;
558
- }
559
- /**
560
- * Security scheme identifier type
561
- * Matches the keys in SECURITY_SCHEMES constant
562
- */
563
- type SecurityScheme = typeof SECURITY_SCHEMES[keyof typeof SECURITY_SCHEMES];
564
- /**
565
- * HTTP method type from OpenAPI spec
566
- */
567
- type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'options' | 'trace' | 'all';
568
- /**
569
- * Object form for request body with optional content type
570
- */
571
- interface RouteBodyObject {
572
- schema: index_d_exports$1.ZodType;
573
- contentType?: string;
574
- }
575
- /**
576
- * Request body definition for @Route() decorator
577
- * Bare ZodType defaults to application/json
578
- */
579
- type RouteBody = index_d_exports$1.ZodType | RouteBodyObject;
580
- /**
581
- * Object form for response with optional description and content type
582
- */
583
- interface RouteResponseObject {
584
- schema: index_d_exports$1.ZodType;
585
- description?: string;
586
- contentType?: string;
587
- }
588
- /**
589
- * Single response definition for @Route() decorator
590
- * Status code is auto-derived from method name (create->201, others->200)
591
- */
592
- type RouteResponse = index_d_exports$1.ZodType | RouteResponseObject;
593
- /**
594
- * Route configuration for @Route() decorator
595
- * Defines OpenAPI metadata for a controller method
596
- */
597
- interface RouteConfig {
598
- /**
599
- * Request body schema (for POST, PUT, PATCH)
600
- * @example z.object({}) or { schema: z.object({}), contentType: 'multipart/form-data' }
601
- */
602
- body?: RouteBody;
603
- /**
604
- * URL parameters schema (e.g., { id: z.string().uuid() })
605
- * Must be ZodObject or ZodPipe for OpenAPI compatibility
606
- */
607
- params?: RouteParameter;
608
- /**
609
- * Query parameters schema (e.g., pagination, filters)
610
- * Must be ZodObject or ZodPipe for OpenAPI compatibility
611
- */
612
- query?: RouteParameter;
613
- /**
614
- * Response schema for success case
615
- * Status code auto-derived: create()->201, others->200
616
- * @example userSchema or { schema: userSchema, description: 'User details' }
617
- */
618
- response: RouteResponse;
619
- /**
620
- * OpenAPI tags for grouping endpoints
621
- * Merged with controller-level tags
622
- */
623
- tags?: string[];
624
- /**
625
- * Security schemes required for this route
626
- * Merged with controller-level security
627
- * Empty array = public route (no auth)
628
- */
629
- security?: SecurityScheme[];
630
- /**
631
- * Human-readable description for OpenAPI docs
632
- */
633
- description?: string;
634
- /**
635
- * Detailed summary for OpenAPI docs
636
- */
637
- summary?: string;
638
- /**
639
- * Hide this route from OpenAPI documentation
640
- * Route remains functional but won't appear in /api/docs or /api/openapi.json
641
- * Useful for internal-only endpoints, debug routes, or work-in-progress features
642
- */
643
- hideFromDocs?: boolean;
644
- /**
645
- * HTTP success status code for the response
646
- * Used by HTTP method decorators (@Get, @Post, etc.) to set the success status
647
- * For @Route() decorator, status code is auto-derived from method name
648
- */
649
- statusCode?: number;
650
- }
651
- /**
652
- * Metadata stored by HTTP method decorators (@Get, @Post, etc.)
653
- * Contains the explicit HTTP method, path, and route configuration
654
- */
655
- interface HttpRouteMetadata {
656
- method: HttpMethod;
657
- path: string;
658
- config: RouteConfig;
659
- }
660
- /**
661
- * Controller options for @Controller() decorator
662
- * Provides default configuration for all routes in the controller
663
- */
664
- interface ControllerOptions {
665
- /**
666
- * Default tags applied to all routes in this controller
667
- * Routes can append additional tags
668
- */
669
- tags?: string[];
670
- /**
671
- * Default security schemes applied to all routes
672
- * Routes can add more schemes or override with empty array
673
- */
674
- security?: SecurityScheme[];
675
- /**
676
- * Hide all routes in this controller from OpenAPI documentation
677
- * Routes remain functional but won't appear in /api/docs or /api/openapi.json
678
- * Can be overridden at route level with hideFromDocs: false
679
- * Useful for internal-only controllers, debug endpoints, or utilities
680
- */
681
- hideFromDocs?: boolean;
682
- /**
683
- * API version(s) for this controller.
684
- * When versioning is enabled, routes are prefixed with the version (e.g., /v1/users).
685
- * Use VERSION_NEUTRAL to opt out of versioning (no prefix applied).
686
- * Can be a single version string, array of versions, or VERSION_NEUTRAL symbol.
687
- */
688
- version?: string | string[] | typeof VERSION_NEUTRAL;
689
- }
690
- /**
691
- * Versioning configuration for the application.
692
- * Enables URI-based API versioning when provided to Stratal config.
693
- */
694
- interface VersioningOptions {
695
- /**
696
- * Prefix for version segments in the URL.
697
- * @default 'v'
698
- * @example 'v' produces /v1, /v2; 'api/v' produces /api/v1, /api/v2
699
- */
700
- prefix?: string;
701
- /**
702
- * Default version applied to controllers without explicit version.
703
- * Controllers with VERSION_NEUTRAL are not affected.
704
- */
705
- defaultVersion?: string | string[];
706
- }
707
- //#endregion
708
- //#region src/router/router-context.d.ts
709
- type ContextQueryResult<R extends Record<string, unknown> | undefined, K extends string | undefined> = K extends string ? string : R extends undefined ? Record<string, unknown> : R;
710
- /**
711
- * Router context wrapper with helper methods
712
- *
713
- * Provides convenient access to Hono's context and common request/response operations.
714
- * The native Hono context is available via the `c` property for advanced use cases.
715
- *
716
- * @example
717
- * ```typescript
718
- * async index(ctx: RouterContext): Promise<Response> {
719
- * // Use helper methods
720
- * const users = await this.service.findAll()
721
- * return ctx.json(users)
722
- * }
723
- *
724
- * async show(ctx: RouterContext): Promise<Response> {
725
- * // Access route params
726
- * const id = ctx.param('id')
727
- * const user = await this.service.findById(id)
728
- * return ctx.json(user)
729
- * }
730
- *
731
- * async create(ctx: RouterContext): Promise<Response> {
732
- * // Parse request body
733
- * const body = await ctx.body<CreateUserInput>()
734
- * const user = await this.service.create(body)
735
- * return ctx.json(user, 201)
736
- * }
737
- * ```
738
- */
739
- declare class RouterContext<T extends RouterEnv = RouterEnv> {
740
- readonly c: Context<T>;
741
- /**
742
- * Native Hono context
743
- * Access for advanced use cases not covered by helper methods
744
- */
745
- constructor(c: Context<T>);
746
- /**
747
- * Get request-scoped DI container
748
- * Contains request-specific services and context (AuthContext)
749
- *
750
- * @throws Error if container not initialized
751
- */
752
- getContainer(): Container;
753
- /**
754
- * Set locale for the current request
755
- * Locale is determined by X-Locale header or defaults to config
756
- *
757
- * @param locale - Locale code (e.g., 'en', 'fr')
758
- */
759
- setLocale(locale: string): void;
760
- /**
761
- * Get locale for the current request
762
- *
763
- * @returns Current locale code
764
- */
765
- getLocale(): string;
766
- /**
767
- * Return JSON response
768
- *
769
- * When data is null, automatically returns 204 No Content (configurable via status param).
770
- *
771
- * @param data - Data to serialize as JSON, or null for 204
772
- * @param status - HTTP status code (default: 200, or 204 when data is null)
773
- */
774
- json(data: object | null, status?: ContentfulStatusCode): Response;
775
- /**
776
- * Get route parameter value
777
- *
778
- * @param key - Parameter name (e.g., 'id' for /users/:id)
779
- */
780
- param(key: string): string;
781
- /**
782
- * Get query parameter value
783
- *
784
- * @param key - Query parameter name
785
- */
786
- query<R extends Record<string, unknown> | undefined = undefined, K extends string | undefined = undefined>(key?: K): ContextQueryResult<R, K>;
787
- /**
788
- * Get request header value
789
- *
790
- * @param name - Header name (case-insensitive)
791
- */
792
- header(name: string): string | undefined;
793
- /**
794
- * Get validated request body from OpenAPI route
795
- * Returns pre-validated data that has passed schema validation
796
- *
797
- * @returns Validated JSON body
798
- */
799
- body<T>(): Promise<T>;
800
- /**
801
- * Return text response
802
- *
803
- * @param text - Text content
804
- * @param status - HTTP status code (default: 200)
805
- */
806
- text(text: string, status?: ContentfulStatusCode): Response;
807
- /**
808
- * Return HTML response
809
- *
810
- * @param html - HTML content
811
- * @param status - HTTP status code (default: 200)
812
- */
813
- html(html: string, status?: ContentfulStatusCode): Response;
814
- /**
815
- * Redirect to another URL
816
- *
817
- * @param url - Target URL
818
- * @param status - HTTP status code (default: 302)
819
- */
820
- redirect(url: string, status?: RedirectStatusCode): Response;
821
- /**
822
- * Return a streaming response (binary/generic)
823
- *
824
- * @param callback - Async function that writes to the stream
825
- * @param onError - Optional error handler called if an error occurs during streaming
826
- */
827
- stream(callback: (stream: StreamingApi) => Promise<void>, onError?: (err: Error, stream: StreamingApi) => Promise<void>): Response;
828
- /**
829
- * Return a streaming text response
830
- *
831
- * Automatically sets `Content-Encoding: Identity` for Cloudflare Workers compatibility.
832
- *
833
- * @param callback - Async function that writes text to the stream
834
- * @param onError - Optional error handler called if an error occurs during streaming
835
- */
836
- streamText(callback: (stream: StreamingApi) => Promise<void>, onError?: (err: Error, stream: StreamingApi) => Promise<void>): Response;
837
- /**
838
- * Return a Server-Sent Events (SSE) streaming response
839
- *
840
- * Automatically sets `Content-Encoding: Identity` for Cloudflare Workers compatibility.
841
- *
842
- * @param callback - Async function that writes SSE events to the stream
843
- * @param onError - Optional error handler called if an error occurs during streaming
844
- */
845
- streamSSE(callback: (stream: SSEStreamingApi) => Promise<void>, onError?: (err: Error, stream: SSEStreamingApi) => Promise<void>): Response;
846
- }
847
- //#endregion
848
- //#region src/router/controller.d.ts
849
- /**
850
- * Controller interface for handling HTTP requests
851
- *
852
- * Controllers can implement RESTful methods or a custom handle() method.
853
- * The route for the controller is set via the `@Controller` decorator.
854
- *
855
- * RESTful methods auto-map to HTTP verbs:
856
- * - index() → GET /route
857
- * - show() → GET /route/:id
858
- * - create() → POST /route
859
- * - update() → PUT /route/:id
860
- * - patch() → PATCH /route/:id
861
- * - destroy() → DELETE /route/:id
862
- *
863
- * For non-RESTful routes (wildcards, custom patterns), implement handle()
864
- */
865
- interface IController {
866
- /**
867
- * GET /route
868
- * List all resources
869
- */
870
- index?(ctx: RouterContext): Promise<Response> | Response;
871
- /**
872
- * GET /route/:id
873
- * Show a specific resource
874
- */
875
- show?(ctx: RouterContext): Promise<Response> | Response;
876
- /**
877
- * POST /route
878
- * Create a new resource
879
- */
880
- create?(ctx: RouterContext): Promise<Response> | Response;
881
- /**
882
- * PUT /route/:id
883
- * Update a resource (full replacement)
884
- */
885
- update?(ctx: RouterContext): Promise<Response> | Response;
886
- /**
887
- * PATCH /route/:id
888
- * Patch a resource (partial update)
889
- */
890
- patch?(ctx: RouterContext): Promise<Response> | Response;
891
- /**
892
- * DELETE /route/:id
893
- * Delete a resource
894
- */
895
- destroy?(ctx: RouterContext): Promise<Response> | Response;
896
- /**
897
- * Custom handler for non-RESTful routes
898
- * Use this for wildcards (e.g., /api/v1/auth/*) or custom patterns
899
- * Takes precedence over RESTful methods if defined
900
- */
901
- handle?(ctx: RouterContext): Promise<Response> | Response;
902
- }
903
- //#endregion
904
- //#region src/router/middleware.interface.d.ts
905
- /**
906
- * Middleware interface for request processing
907
- *
908
- * Middlewares use the `@Transient()` decorator and are registered via
909
- * the `configure(consumer)` method in modules implementing `MiddlewareConfigurable`.
910
- *
911
- * @example
912
- * ```typescript
913
- * @Transient()
914
- * export class LoggingMiddleware implements Middleware {
915
- * async handle(ctx: RouterContext, next: () => Promise<void>): Promise<void> {
916
- * const start = Date.now()
917
- * await next()
918
- * console.log(`Request took ${Date.now() - start}ms`)
919
- * }
920
- * }
921
- *
922
- * // Register in module:
923
- * @Module({ providers: [...] })
924
- * export class AppModule implements MiddlewareConfigurable {
925
- * configure(consumer: MiddlewareConsumer): void {
926
- * consumer.apply(LoggingMiddleware).forRoutes('*')
927
- * }
928
- * }
929
- * ```
930
- */
931
- interface Middleware {
932
- /**
933
- * Handle middleware logic
934
- * Call next() to continue the middleware chain
935
- *
936
- * @param ctx - Router context with request/response helpers
937
- * @param next - Function to call the next middleware or route handler
938
- */
939
- handle(ctx: RouterContext, next: () => Promise<void>): Promise<void>;
940
- }
941
- //#endregion
942
- //#region src/middleware/types.d.ts
943
- /**
944
- * Route information for middleware targeting
945
- */
946
- interface RouteInfo {
947
- /** Route path pattern (e.g., '/api/v1/users', '/health') */
948
- path: string;
949
- /** HTTP method(s) to match. If omitted, matches all methods */
950
- method?: HttpMethod | HttpMethod[];
951
- /** API version(s) to target. When versioning is enabled, resolves to versioned path. */
952
- version?: string | string[];
953
- }
954
- /**
955
- * Internal configuration entry for middleware registration
956
- */
957
- interface MiddlewareConfigEntry {
958
- /** Middleware classes to apply */
959
- middlewares: Constructor<Middleware>[];
960
- /** Routes to exclude from middleware */
961
- excludes: RouteInfo[];
962
- /** Target routes for middleware */
963
- routes: MiddlewareRouteTarget[];
964
- }
965
- /**
966
- * Valid targets for middleware routes
967
- * - Controller class: Apply to all routes in that controller
968
- * - RouteInfo: Apply to specific path/method combination
969
- * - '*': Apply to all routes (global middleware)
970
- */
971
- type MiddlewareRouteTarget = Constructor<IController> | RouteInfo | '*';
972
- /**
973
- * Interface for modules that configure middleware
974
- *
975
- * Implement this interface in your module class to configure
976
- * middleware using the consumer pattern.
977
- *
978
- * @example
979
- * ```typescript
980
- * @Module({ providers: [...] })
981
- * export class AppModule implements MiddlewareConfigurable {
982
- * configure(consumer: MiddlewareConsumer): void {
983
- * consumer
984
- * .apply(LoggingMiddleware, CorsMiddleware)
985
- * .exclude({ path: '/health', method: 'get' })
986
- * .forRoutes('*')
987
- *
988
- * consumer
989
- * .apply(CorsMiddleware)
990
- * .forRoutes(ApiController, WebhooksController)
991
- * }
992
- * }
993
- * ```
994
- */
995
- interface MiddlewareConfigurable {
996
- /**
997
- * Configure middleware for this module
998
- * @param consumer - Middleware consumer for fluent configuration
999
- */
1000
- configure(consumer: MiddlewareConsumer): void;
1001
- }
1002
- /**
1003
- * Forward declaration for MiddlewareConsumer
1004
- * Implementation in middleware-consumer.ts
1005
- */
1006
- interface MiddlewareConsumer {
1007
- /**
1008
- * Specify middleware(s) to apply
1009
- * @param middlewares - Middleware classes to apply
1010
- * @returns Builder for configuring routes
1011
- */
1012
- apply(...middlewares: Constructor<Middleware>[]): MiddlewareBuilder;
1013
- /**
1014
- * Get all configured middleware entries
1015
- */
1016
- getEntries(): MiddlewareConfigEntry[];
1017
- }
1018
- /**
1019
- * Forward declaration for MiddlewareBuilder
1020
- * Implementation in middleware-consumer.ts
1021
- */
1022
- interface MiddlewareBuilder {
1023
- /**
1024
- * Exclude routes from middleware
1025
- * @param routes - Routes to exclude (path strings or RouteInfo objects)
1026
- */
1027
- exclude(...routes: (string | RouteInfo)[]): this;
1028
- /**
1029
- * Apply middleware to specified routes
1030
- * @param targets - Controller classes, route patterns, or '*' for global
1031
- */
1032
- forRoutes(...targets: MiddlewareRouteTarget[]): void;
1033
- }
1034
- //#endregion
1035
- //#region src/module/types.d.ts
1036
- /**
1037
- * Provider that uses a class constructor
1038
- *
1039
- * @example Transient (default)
1040
- * ```typescript
1041
- * { provide: UserService, useClass: UserService }
1042
- * ```
1043
- *
1044
- * @example Singleton
1045
- * ```typescript
1046
- * { provide: DI_TOKENS.ConsumerRegistry, useClass: ConsumerRegistry, scope: Scope.Singleton }
1047
- * ```
1048
- *
1049
- * @example Request-scoped
1050
- * ```typescript
1051
- * { provide: DI_TOKENS.ConnectionManager, useClass: ConnectionManager, scope: Scope.Request }
1052
- * ```
1053
- */
1054
- interface ClassProvider<T extends object = object> {
1055
- provide: InjectionToken$2<T>;
1056
- useClass: Constructor<T>;
1057
- /** Lifecycle scope - defaults to Transient if not specified */
1058
- scope?: Scope;
1059
- }
1060
- /**
1061
- * Provider that uses a pre-created value
1062
- *
1063
- * Note: Values are inherently singleton-like (same instance always returned).
1064
- * No scope option needed.
1065
- */
1066
- interface ValueProvider<T extends object = object> {
1067
- provide: InjectionToken$2<T>;
1068
- useValue: T;
1069
- }
1070
- /**
1071
- * Provider that uses a factory function with auto-injection support
1072
- *
1073
- * Note: Factory providers do not support scope/lifecycle in tsyringe.
1074
- * Factories are always called fresh on each resolution (transient-like behavior).
1075
- *
1076
- * @example Factory with dependencies
1077
- * ```typescript
1078
- * {
1079
- * provide: LOGGER_TOKENS.Transports,
1080
- * useFactory: (console) => [console],
1081
- * inject: [LOGGER_TOKENS.ConsoleTransport]
1082
- * }
1083
- * ```
1084
- */
1085
- interface FactoryProvider<T extends object = object> {
1086
- provide: InjectionToken$2<T>;
1087
- useFactory: (...deps: any[]) => T | Promise<T>;
1088
- inject?: InjectionToken$2<unknown>[];
1089
- }
1090
- /**
1091
- * Provider that creates an alias to an existing token
1092
- *
1093
- * When the `provide` token is resolved, the container resolves `useExisting` instead.
1094
- * Both tokens return the same instance (for singleton/request-scoped services).
1095
- *
1096
- * Use cases:
1097
- * - Creating interface tokens that alias concrete implementations
1098
- * - Multiple tokens resolving to the same service
1099
- *
1100
- * @example Basic alias
1101
- * ```typescript
1102
- * {
1103
- * provide: 'IUserService',
1104
- * useExisting: UserService
1105
- * }
1106
- * // Resolving 'IUserService' returns the UserService instance
1107
- * ```
1108
- *
1109
- * @example Interface abstraction
1110
- * ```typescript
1111
- * providers: [
1112
- * UserService,
1113
- * { provide: I_USER_SERVICE, useExisting: UserService }
1114
- * ]
1115
- * // Both UserService and I_USER_SERVICE resolve to the same instance
1116
- * ```
1117
- */
1118
- interface ExistingProvider<T extends object = object> {
1119
- provide: InjectionToken$2<T>;
1120
- useExisting: InjectionToken$2<T>;
1121
- }
1122
- /**
1123
- * Union type for all provider types
1124
- */
1125
- type Provider<T extends object = object> = Constructor<T> | ClassProvider<T> | ValueProvider<T> | FactoryProvider<T> | ExistingProvider<T>;
1126
- /**
1127
- * Module class type (decorated with @Module)
1128
- *
1129
- * Static methods for dynamic module configuration:
1130
- * - forRoot: Synchronous configuration (like NestJS forRoot)
1131
- * - forRootAsync: Async configuration with factory (like NestJS forRootAsync)
1132
- */
1133
- interface ModuleClass<T extends object = object> extends Constructor<T> {
1134
- /**
1135
- * Synchronous module configuration
1136
- *
1137
- * Use for global singleton modules with static configuration
1138
- *
1139
- * @example
1140
- * ```typescript
1141
- * @Module({ providers: [] })
1142
- * export class ConfigModule {
1143
- * static forRoot(options: ConfigOptions): DynamicModule {
1144
- * return {
1145
- * providers: [
1146
- * { provide: CONFIG_TOKEN, useValue: options }
1147
- * ]
1148
- * }
1149
- * }
1150
- * }
1151
- *
1152
- * // Usage in AppModule
1153
- * @Module({ imports: [ConfigModule.forRoot({ apiKey: '...' })] })
1154
- * ```
1155
- */
1156
- forRoot?: (...args: unknown[]) => DynamicModule;
1157
- /**
1158
- * Async module configuration with dependency injection
1159
- *
1160
- * Use when configuration depends on other services
1161
- *
1162
- * @example
1163
- * ```typescript
1164
- * @Module({ providers: [] })
1165
- * export class DatabaseModule {
1166
- * static forRootAsync<T>(options: AsyncModuleOptions<T>): DynamicModule {
1167
- * return {
1168
- * providers: [
1169
- * {
1170
- * provide: DB_TOKEN,
1171
- * useFactory: options.useFactory,
1172
- * inject: options.inject
1173
- * }
1174
- * ]
1175
- * }
1176
- * }
1177
- * }
1178
- *
1179
- * // Usage in AppModule
1180
- * @Module({
1181
- * imports: [
1182
- * DatabaseModule.forRootAsync({
1183
- * inject: [CONFIG_TOKEN],
1184
- * useFactory: (config) => ({ url: config.databaseUrl })
1185
- * })
1186
- * ]
1187
- * })
1188
- * ```
1189
- */
1190
- forRootAsync?: <TOptions>(options: AsyncModuleOptions<TOptions>) => DynamicModule;
1191
- }
1192
- /**
1193
- * Module options for `@Module` decorator
1194
- *
1195
- * Note: Middlewares are configured via the MiddlewareConfigurable interface's
1196
- * configure() method, not via this options object. See middleware/types.ts.
1197
- */
1198
- interface ModuleOptions {
1199
- imports?: (ModuleClass | DynamicModule)[];
1200
- providers?: Provider[];
1201
- controllers?: Constructor[];
1202
- consumers?: Constructor[];
1203
- jobs?: Constructor[];
1204
- }
1205
- /**
1206
- * Dynamic module returned by forRoot/forRootAsync
1207
- *
1208
- * Contains additional providers, controllers, consumers, and jobs
1209
- * that are added to the module when configured dynamically.
1210
- */
1211
- interface DynamicModule extends Omit<ModuleOptions, 'imports'> {
1212
- /**
1213
- * Reference to the module class that created this dynamic module
1214
- *
1215
- * Required for dynamic modules to support lifecycle methods (configure, onInitialize, onShutdown).
1216
- * ModuleRegistry uses this to instantiate the actual module class instead of an anonymous wrapper.
1217
- *
1218
- * Note: This is NOT for provider scoping (tsyringe is always global).
1219
- * It's purely for preserving the class reference for lifecycle method calls.
1220
- */
1221
- module: Constructor;
1222
- }
1223
- /**
1224
- * Async configuration options for forRootAsync
1225
- */
1226
- interface AsyncModuleOptions<TOptions> {
1227
- inject?: InjectionToken$2<unknown>[];
1228
- useFactory: (...deps: any[]) => TOptions | Promise<TOptions>;
1229
- }
1230
- /**
1231
- * Context passed to lifecycle hooks
1232
- */
1233
- interface ModuleContext {
1234
- container: Container;
1235
- logger: LoggerService;
1236
- }
1237
- /**
1238
- * Lifecycle hook: called after all providers are registered
1239
- */
1240
- interface OnInitialize {
1241
- onInitialize(context: ModuleContext): void | Promise<void>;
1242
- }
1243
- /**
1244
- * Lifecycle hook: called during application shutdown
1245
- */
1246
- interface OnShutdown {
1247
- onShutdown(context: ModuleContext): void | Promise<void>;
1248
- }
1249
- /**
1250
- * Tsyringe registry entry type (for internal use)
1251
- *
1252
- * Note: useFactory receives DependencyContainer from tsyringe,
1253
- * but we resolve our Container via CONTAINER_TOKEN for consistency.
1254
- */
1255
- interface RegistryEntry<T extends object = object> {
1256
- token: InjectionToken$2<T>;
1257
- useClass?: Constructor<T>;
1258
- useValue?: T;
1259
- useFactory?: (dependencyContainer: DependencyContainer) => T;
1260
- useToken?: InjectionToken$2<T>;
1261
- }
1262
- //#endregion
1263
- //#region src/i18n/i18n.options.d.ts
1264
- /**
1265
- * I18n Module Options
1266
- *
1267
- * Configuration options for the I18n dynamic module.
1268
- * Use with I18nModule.forRoot() to configure locale settings.
1269
- * Use I18nModule.registerMessages() to add translations.
1270
- */
1271
- /**
1272
- * Options for configuring the I18n module
1273
- *
1274
- * @example
1275
- * ```typescript
1276
- * I18nModule.forRoot({
1277
- * defaultLocale: 'en',
1278
- * fallbackLocale: 'en',
1279
- * locales: ['en', 'fr'],
1280
- * })
1281
- *
1282
- * I18nModule.registerMessages({
1283
- * en: { common: { hello: 'Hello' } },
1284
- * fr: { common: { hello: 'Bonjour' } },
1285
- * })
1286
- * ```
1287
- */
1288
- interface I18nModuleOptions {
1289
- /**
1290
- * Default locale for the application
1291
- * Used when no locale is specified in request headers
1292
- * @default 'en'
1293
- */
1294
- defaultLocale?: string;
1295
- /**
1296
- * Fallback locale when translation is missing
1297
- * @default 'en'
1298
- */
1299
- fallbackLocale?: string;
1300
- /**
1301
- * List of supported locales
1302
- * Request locales not in this list will fall back to defaultLocale
1303
- */
1304
- locales?: string[];
1305
- }
1306
- /**
1307
- * Resolved options with all defaults applied
1308
- * Used internally by I18n services
1309
- */
1310
- interface ResolvedI18nOptions {
1311
- defaultLocale: string;
1312
- fallbackLocale: string;
1313
- locales: string[];
1314
- }
1315
- /**
1316
- * Resolve I18n options with defaults
1317
- */
1318
- declare function resolveI18nOptions(options?: I18nModuleOptions): ResolvedI18nOptions;
1319
- //#endregion
1320
- //#region src/i18n/i18n.module.d.ts
1321
- declare class I18nModule implements MiddlewareConfigurable {
1322
- /**
1323
- * Configure I18n locale settings
1324
- *
1325
- * Call once in the root module. Does not accept messages —
1326
- * use `registerMessages()` to add translations.
1327
- *
1328
- * @param options - Locale configuration (defaultLocale, fallbackLocale, locales)
1329
- */
1330
- static forRoot(options?: I18nModuleOptions): DynamicModule;
1331
- /**
1332
- * Register i18n messages
1333
- *
1334
- * Can be called from any module, as many times as needed.
1335
- * Messages are deep-merged in registration order — later calls override earlier ones at leaf level.
1336
- *
1337
- * @param messages - Messages keyed by locale code
1338
- *
1339
- * @example App-level messages
1340
- * ```typescript
1341
- * I18nModule.registerMessages({
1342
- * en: { common: { hello: 'Hello' }, errors: { notFound: 'Not found' } },
1343
- * fr: { common: { hello: 'Bonjour' }, errors: { notFound: 'Introuvable' } },
1344
- * })
1345
- * ```
1346
- *
1347
- * @example Package-level messages
1348
- * ```typescript
1349
- * I18nModule.registerMessages({
1350
- * en: { tenancy: { tenantNotFound: 'Tenant not found' } },
1351
- * })
1352
- * ```
1353
- */
1354
- static registerMessages(messages: Record<string, Record<string, unknown>>): DynamicModule;
1355
- configure(consumer: MiddlewareConsumer): void;
1356
- }
1357
- //#endregion
1358
- //#region src/i18n/i18n.tokens.d.ts
1359
- /**
1360
- * I18n Module DI Tokens
1361
- * Symbol-based tokens to avoid string collisions
1362
- */
1363
- declare const I18N_TOKENS: {
1364
- /** MessageLoaderService - loads and caches locale messages */readonly MessageLoader: symbol; /** I18nService - request-scoped translation service */
1365
- readonly I18nService: symbol; /** I18nModuleOptions - configuration options from forRoot() */
1366
- readonly Options: symbol; /** MessageRegistry - singleton accumulator for registerMessages() contributions */
1367
- readonly MessageRegistry: symbol;
1368
- };
1369
- //#endregion
1370
- //#region src/i18n/services/message-registry.d.ts
1371
- /**
1372
- * Message Registry
1373
- *
1374
- * Accumulates i18n messages from multiple `I18nModule.registerMessages()` calls.
1375
- * Messages are collected statically (at module import time) and deep-merged
1376
- * when `getMergedMessages()` is called by `MessageLoaderService`.
1377
- *
1378
- * Later registrations override earlier ones at leaf level.
1379
- */
1380
- declare class MessageRegistry {
1381
- private static contributions;
1382
- /**
1383
- * Add messages (called statically by I18nModule.registerMessages)
1384
- */
1385
- static addMessages(messages: Record<string, Record<string, unknown>>): void;
1386
- /**
1387
- * Get all messages deep-merged in registration order
1388
- */
1389
- getMergedMessages(): Record<string, Record<string, unknown>>;
1390
- /**
1391
- * Reset registry (for testing)
1392
- * @internal
1393
- */
1394
- static reset(): void;
1395
- }
1396
- //#endregion
1397
- //#region src/i18n/setup.d.ts
1398
- /**
1399
- * I18n Setup - Message Compiler Registration
1400
- *
1401
- * Registers a JIT (Just-In-Time) message compiler for @intlify/core-base
1402
- * that works in Cloudflare Workers edge runtime.
1403
- *
1404
- * This must be called ONCE at application startup, before any I18nService instances are created.
1405
- */
1406
- /**
1407
- * Setup JIT message compiler for i18n
1408
- *
1409
- * Registers a message compiler that uses JIT compilation mode.
1410
- * In @intlify/core-base v10+, JIT mode is enabled by default, which generates
1411
- * AST (Abstract Syntax Tree) instead of JavaScript code, making it compatible
1412
- * with CSP-restricted environments like Cloudflare Workers.
1413
- *
1414
- * **IMPORTANT:** Call this function once at application startup before creating
1415
- * any I18nService instances. Safe to call multiple times (only registers once).
1416
- *
1417
- * @example
1418
- * ```typescript
1419
- * // In application entry point (before app.initialize())
1420
- * setupI18nCompiler()
1421
- * ```
1422
- */
1423
- declare function setupI18nCompiler(): void;
1424
- //#endregion
1425
- //#region src/i18n/errors/locale-not-supported.error.d.ts
1426
- declare class LocaleNotSupportedError extends ApplicationError {
1427
- constructor(locale: string, supportedLocales: string[]);
1428
- }
1429
- //#endregion
1430
- //#region src/i18n/errors/translation-missing.error.d.ts
1431
- declare class TranslationMissingError extends ApplicationError {
1432
- constructor(key: string, locale: string);
1433
- }
1434
- //#endregion
1435
- //#region src/i18n/services/message-loader.service.d.ts
1436
- declare class MessageLoaderService {
1437
- private readonly registry;
1438
- private readonly options?;
1439
- private readonly cache;
1440
- private readonly contextCache;
1441
- private readonly locales;
1442
- private readonly defaultLocale;
1443
- constructor(registry: MessageRegistry, options?: I18nModuleOptions | undefined);
1444
- /**
1445
- * Get CoreContext for a locale (lazily built and cached on first access)
1446
- * Falls back to default locale if locale not found
1447
- */
1448
- getCoreContext(locale: string): CoreContext;
1449
- /**
1450
- * Get messages for a specific locale.
1451
- * Falls back to default locale if not found.
1452
- */
1453
- getMessages(locale: string): Record<string, unknown>;
1454
- /** Get list of available locale codes */
1455
- getAvailableLocales(): string[];
1456
- /** Check if a locale is supported */
1457
- isLocaleSupported(locale: string): boolean;
1458
- /** Get default locale */
1459
- getDefaultLocale(): string;
1460
- /**
1461
- * Flatten nested messages to dot-notation.
1462
- * e.g. `{ a: { b: 'hello' } }` → `{ 'a.b': 'hello' }`
1463
- */
1464
- private flattenMessages;
1465
- }
1466
- //#endregion
1467
- //#region src/i18n/middleware/locale-extraction.middleware.d.ts
1468
- declare class LocaleExtractionMiddleware implements Middleware {
1469
- private readonly loader;
1470
- constructor(loader: MessageLoaderService);
1471
- handle(ctx: RouterContext, next: () => Promise<void>): Promise<void>;
1472
- /**
1473
- * Extract and validate locale from X-Locale header
1474
- */
1475
- private extractLocale;
1476
- }
1477
- //#endregion
1478
- //#region src/middleware/middleware-consumer.d.ts
1479
- /**
1480
- * Consumer for configuring middleware in modules
1481
- *
1482
- * Provides fluent API for registering middleware with route targeting.
1483
- * Used by modules implementing MiddlewareConfigurable interface.
1484
- *
1485
- * @example
1486
- * ```typescript
1487
- * @Module({ providers: [...] })
1488
- * export class AppModule implements MiddlewareConfigurable {
1489
- * configure(consumer: MiddlewareConsumer): void {
1490
- * // Global logging middleware (excludes health check)
1491
- * consumer
1492
- * .apply(LoggingMiddleware)
1493
- * .exclude('/health')
1494
- * .forRoutes('*')
1495
- *
1496
- * // CORS middleware for specific controllers
1497
- * consumer
1498
- * .apply(CorsMiddleware)
1499
- * .forRoutes(ApiController, WebhooksController)
1500
- *
1501
- * // Rate limiting for auth endpoints
1502
- * consumer
1503
- * .apply(RateLimitMiddleware)
1504
- * .forRoutes({ path: '/api/v1/auth/*', method: 'post' })
1505
- * }
1506
- * }
1507
- * ```
1508
- */
1509
- declare class MiddlewareConsumerImpl implements MiddlewareConsumer {
1510
- private entries;
1511
- /**
1512
- * Start configuring middleware
1513
- *
1514
- * @param middlewares - Middleware classes to apply
1515
- * @returns Builder for configuring routes and exclusions
1516
- */
1517
- apply(...middlewares: Constructor<Middleware>[]): MiddlewareBuilder;
1518
- /**
1519
- * Add a configuration entry (called by builder)
1520
- * @internal
1521
- */
1522
- addEntry(entry: MiddlewareConfigEntry): void;
1523
- /**
1524
- * Get all configured middleware entries
1525
- */
1526
- getEntries(): MiddlewareConfigEntry[];
1527
- }
1528
- /**
1529
- * Create a new middleware consumer instance
1530
- */
1531
- declare function createMiddlewareConsumer(): MiddlewareConsumer;
1532
- //#endregion
1533
- //#region src/middleware/middleware-configuration.service.d.ts
1534
- /**
1535
- * Service for applying middleware configurations to Hono app
1536
- *
1537
- * Processes MiddlewareConfigEntry[] from modules and registers
1538
- * appropriate middleware handlers with route matching.
1539
- */
1540
- declare class MiddlewareConfigurationService {
1541
- private readonly logger;
1542
- private readonly versioningOptions;
1543
- constructor(logger: LoggerService, versioningOptions?: VersioningOptions | null);
1544
- /**
1545
- * Apply middleware configurations to the Hono app
1546
- *
1547
- * @param app - Hono application instance
1548
- * @param configs - Middleware configuration entries from modules
1549
- * @param controllers - All registered controller classes (for route resolution)
1550
- * @param container - DI container for resolving middleware instances
1551
- */
1552
- applyMiddlewares(app: OpenAPIHono<RouterEnv>, configs: MiddlewareConfigEntry[], controllers: Constructor<IController>[], container: Container): void;
1553
- /**
1554
- * Apply a single middleware configuration entry
1555
- */
1556
- private applyMiddlewareConfig;
1557
- /**
1558
- * Resolve route targets into concrete route patterns
1559
- */
1560
- private resolveRoutePatterns;
1561
- /**
1562
- * Resolve a RouteInfo with version into versioned path(s).
1563
- * If versioning is disabled or no version is specified, returns the RouteInfo as-is.
1564
- */
1565
- private resolveVersionedRouteInfo;
1566
- /**
1567
- * Register middleware handlers for a specific route pattern
1568
- */
1569
- private registerMiddlewareForPattern;
1570
- /**
1571
- * Register handler for a specific HTTP method
1572
- */
1573
- private registerForMethod;
1574
- /**
1575
- * Create a middleware handler function that executes the middleware chain
1576
- */
1577
- private createMiddlewareHandler;
1578
- /**
1579
- * Check if a request matches any exclusion pattern
1580
- */
1581
- private isExcluded;
1582
- /**
1583
- * Check if request matches a route pattern
1584
- */
1585
- private matchesRoute;
1586
- /**
1587
- * Match request path against pattern
1588
- * Supports wildcards: /api/* matches /api/users, /api/v1/users
1589
- */
1590
- private matchesPath;
1591
- /**
1592
- * Execute middleware chain in order
1593
- */
1594
- private executeMiddlewareChain;
1595
- }
1596
- //#endregion
1597
- //#region src/router/hono-app.d.ts
1598
- /**
1599
- * HonoApp — extends OpenAPIHono with Stratal-specific setup
1600
- *
1601
- * Absorbs all Hono-related setup from the former RouterService and RequestScopeService:
1602
- * - Request scope middleware (child container per request)
1603
- * - Global middleware (CORS, logging, error handling)
1604
- * - defaultHook for validation errors
1605
- * - `use()` overload for Stratal middleware classes
1606
- * - `configure()` for module middleware, OpenAPI, routes, and 404
1607
- */
1608
- declare class HonoApp extends OpenAPIHono<RouterEnv> {
1609
- private configured;
1610
- private readonly _container;
1611
- private readonly _logger;
1612
- /**
1613
- * Reference to the original Hono `use` implementation.
1614
- * Captured in constructor after super() sets it as an instance property.
1615
- * Used by private methods to register middleware without going through the override.
1616
- */
1617
- private nativeUse;
1618
- constructor(container: Container, logger: LoggerService);
1619
- /**
1620
- * Configure module middleware, OpenAPI endpoints, controller routes, and 404 handler.
1621
- * Called once by Application.initialize().
1622
- */
1623
- configure(middlewareConfigs: MiddlewareConfigEntry[], controllers: Constructor<IController>[], versioningOptions?: VersioningOptions | null): Promise<void>;
1624
- private setupRequestScope;
1625
- private setupGlobalMiddleware;
1626
- private applyMiddlewareClasses;
1627
- }
1628
- //#endregion
1629
- //#region src/router/services/route-registration.service.d.ts
1630
- /**
1631
- * Route registration service
1632
- * Manages controller and route registration with OpenAPI support
1633
- *
1634
- * Responsibilities:
1635
- * - Register RESTful controllers with OpenAPI metadata
1636
- * - Auto-derive HTTP methods/paths from controller method names
1637
- * - Build OpenAPI route configurations with guard execution
1638
- * - Validate all controllers have access decorators (strict mode)
1639
- * - Create controller handlers with DI resolution
1640
- */
1641
- declare class RouteRegistrationService {
1642
- private logger;
1643
- private versioningOptions;
1644
- private controllerClasses;
1645
- constructor(logger: LoggerService, versioningOptions?: VersioningOptions | null);
1646
- /**
1647
- * Configure router with controllers
1648
- *
1649
- * @param app - OpenAPIHono application instance
1650
- * @param controllers - Array of controller classes from modules
1651
- */
1652
- configure(app: OpenAPIHono<RouterEnv>, controllers: Constructor<IController>[]): Promise<void>;
1653
- /**
1654
- * Register a WebSocket gateway
1655
- * Applies versioning and guards, then registers an upgradeWebSocket handler
1656
- */
1657
- private registerGateway;
1658
- /**
1659
- * Register a single WebSocket gateway route
1660
- */
1661
- private registerGatewayRoute;
1662
- /**
1663
- * Register a single controller with all its routes
1664
- * Validates that controller has access decorator (strict mode)
1665
- */
1666
- private registerController;
1667
- /**
1668
- * Dispatch route registration based on decorator type
1669
- */
1670
- private dispatchRoutes;
1671
- /**
1672
- * Resolve versioned paths for a controller based on versioning configuration.
1673
- *
1674
- * @param basePath - The base path from @Controller decorator
1675
- * @param controllerOpts - Controller options (may contain version)
1676
- * @returns Array of resolved paths (with version prefix if applicable)
1677
- */
1678
- private resolveVersionedPaths;
1679
- /**
1680
- * Create a guard execution middleware
1681
- *
1682
- * This middleware executes all guards for a route before the handler.
1683
- * Guards are executed in order; all must pass for the request to proceed.
1684
- *
1685
- * @param guards - Array of guards to execute
1686
- * @returns Hono middleware function
1687
- */
1688
- private createGuardMiddleware;
1689
- /**
1690
- * Register wildcard route for non-RESTful controllers
1691
- */
1692
- private registerWildcardRoute;
1693
- /**
1694
- * Register OpenAPI routes with metadata
1695
- */
1696
- private registerOpenAPIRoutes;
1697
- /**
1698
- * Register routes using HTTP method decorators (@Get, @Post, etc.)
1699
- * These use explicit method + path instead of convention-based derivation
1700
- */
1701
- private registerHttpRoutes;
1702
- /**
1703
- * Join a base path and a route path, normalizing slashes
1704
- */
1705
- private joinPaths;
1706
- /**
1707
- * Register route without OpenAPI metadata (for hidden routes)
1708
- * Route is functional but won't appear in documentation
1709
- */
1710
- private registerRouteWithoutOpenAPI;
1711
- /**
1712
- * Register traditional RESTful routes without OpenAPI
1713
- */
1714
- private registerRESTfulRoutes;
1715
- /**
1716
- * Auto-derive HTTP method and path from controller method name
1717
- * Uses HTTP_METHODS constant for RESTful convention mapping
1718
- */
1719
- private deriveHttpMethodAndPath;
1720
- /**
1721
- * Merge controller-level and route-level metadata
1722
- * Tags are merged (appended), security is merged (union)
1723
- * Guards automatically add sessionCookie security if present
1724
- */
1725
- private mergeMetadata;
1726
- /**
1727
- * Build OpenAPI route configuration from metadata
1728
- * Creates a route definition compatible with @hono/zod-openapi
1729
- * Includes guard execution for proper access control
1730
- *
1731
- * Execution order: Global middlewares → Guards → Handler
1732
- */
1733
- private buildOpenAPIRoute;
1734
- /**
1735
- * Check if a body definition is a RouteBodyObject (has schema key) vs bare ZodType
1736
- */
1737
- private isRouteBodyObject;
1738
- /**
1739
- * Resolve method parameter injections from the container
1740
- *
1741
- * @param prototype - Controller prototype
1742
- * @param methodName - Method name to get injections for
1743
- * @param container - Request-scoped container
1744
- * @returns Array of resolved dependencies in parameter order
1745
- */
1746
- private resolveMethodInjections;
1747
- /**
1748
- * Name a handler function so Hono's inspectRoutes() can identify it.
1749
- * Format: `{type}:{Controller}.{method}` (e.g. `http:UsersController.create`)
1750
- */
1751
- private nameHandler;
1752
- /**
1753
- * Create controller handler that resolves controller from request-scoped container
1754
- * This ensures each request gets a fresh controller with request-scoped context
1755
- */
1756
- private createControllerHandler;
1757
- }
1758
- //#endregion
1759
- //#region src/router/router.tokens.d.ts
1760
- /**
1761
- * Dependency injection tokens for the router system
1762
- */
1763
- declare const ROUTER_TOKENS: {
1764
- /**
1765
- * Token for RouterContext (request-scoped)
1766
- * Contains Hono context wrapper with helper methods
1767
- */
1768
- readonly RouterContext: symbol;
1769
- };
1770
- //#endregion
1771
- //#region src/router/decorators/controller.decorator.d.ts
1772
- /**
1773
- * Base controller decorator for route registration
1774
- *
1775
- * This is the core controller decorator that handles:
1776
- * - Transient scope registration (request-scoped)
1777
- * - Route metadata storage
1778
- * - Controller options (tags, security schemes, hideFromDocs)
1779
- *
1780
- * @param route - Base route for this controller (e.g., '/api/v1/users')
1781
- * @param options - Optional configuration (tags, security schemes, hideFromDocs)
1782
- *
1783
- * @example
1784
- * ```typescript
1785
- * import { Controller } from 'stratal/router'
1786
- *
1787
- * @Controller('/api/v1/users', { tags: ['Users'] })
1788
- * export class UsersController implements IController {
1789
- * // All routes accessible
1790
- * }
1791
- * ```
1792
- */
1793
- declare function Controller(route: string, options?: ControllerOptions): <T extends Constructor>(target: T) => T;
1794
- /**
1795
- * Get the route from controller class metadata
1796
- *
1797
- * @param target - Controller class or instance
1798
- * @returns Route string or undefined if not set
1799
- */
1800
- declare function getControllerRoute(target: object): string | undefined;
1801
- /**
1802
- * Get the options from controller class metadata
1803
- *
1804
- * @param target - Controller class or instance
1805
- * @returns Controller options or undefined if not set
1806
- */
1807
- declare function getControllerOptions(target: object): ControllerOptions | undefined;
1808
- /**
1809
- * Get the version from controller class metadata
1810
- *
1811
- * @param target - Controller class or instance
1812
- * @returns Version string, array, VERSION_NEUTRAL symbol, or undefined if not set
1813
- */
1814
- declare function getControllerVersion(target: object): ControllerOptions['version'];
1815
- //#endregion
1816
- //#region src/router/decorators/http-method.decorator.d.ts
1817
- /**
1818
- * Registers a GET route on the controller method.
1819
- *
1820
- * @param path - Route path relative to the controller base path
1821
- * @param config - Optional route configuration (response schema, body, params, etc.)
1822
- *
1823
- * @example
1824
- * ```typescript
1825
- * @Controller('/api/v1/users')
1826
- * class UsersController {
1827
- * @Get('/', { response: z.array(userSchema), summary: 'List users' })
1828
- * async list(ctx: RouterContext) { ... }
1829
- *
1830
- * @Get('/:id', { params: z.object({ id: z.string().uuid() }), response: userSchema })
1831
- * async getUser(ctx: RouterContext) { ... }
1832
- * }
1833
- * ```
1834
- */
1835
- declare const Get: (path: string, config?: RouteConfig) => (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1836
- /**
1837
- * Registers a POST route on the controller method.
1838
- *
1839
- * @param path - Route path relative to the controller base path
1840
- * @param config - Optional route configuration (response schema, body, params, etc.)
1841
- *
1842
- * @example
1843
- * ```typescript
1844
- * @Controller('/api/v1/users')
1845
- * class UsersController {
1846
- * @Post('/', { body: createUserSchema, response: userSchema, statusCode: 201 })
1847
- * async createUser(ctx: RouterContext) { ... }
1848
- * }
1849
- * ```
1850
- */
1851
- declare const Post: (path: string, config?: RouteConfig) => (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1852
- /**
1853
- * Registers a PUT route on the controller method.
1854
- *
1855
- * @param path - Route path relative to the controller base path
1856
- * @param config - Optional route configuration
1857
- */
1858
- declare const Put: (path: string, config?: RouteConfig) => (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1859
- /**
1860
- * Registers a PATCH route on the controller method.
1861
- *
1862
- * @param path - Route path relative to the controller base path
1863
- * @param config - Optional route configuration
1864
- */
1865
- declare const Patch: (path: string, config?: RouteConfig) => (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1866
- /**
1867
- * Registers a DELETE route on the controller method.
1868
- *
1869
- * @param path - Route path relative to the controller base path
1870
- * @param config - Optional route configuration
1871
- */
1872
- declare const Delete: (path: string, config?: RouteConfig) => (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1873
- /**
1874
- * Registers an ALL (any HTTP method) route on the controller method.
1875
- * Routes using @All are automatically hidden from OpenAPI documentation
1876
- * since OpenAPI does not support a catch-all HTTP method.
1877
- *
1878
- * @param path - Route path relative to the controller base path
1879
- * @param config - Optional route configuration
1880
- */
1881
- declare const All: (path: string, config?: RouteConfig) => (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1882
- /**
1883
- * Get the HTTP route metadata from a controller method decorated with
1884
- * @Get, @Post, @Put, @Patch, @Delete, or @All.
1885
- *
1886
- * @param target - Controller prototype
1887
- * @param methodName - Name of the method
1888
- * @returns HTTP route metadata or undefined if not decorated
1889
- */
1890
- declare function getHttpRouteMetadata(target: object, methodName: string): HttpRouteMetadata | undefined;
1891
- /**
1892
- * Get all methods decorated with HTTP method decorators from a controller class.
1893
- *
1894
- * @param ControllerClass - Controller class
1895
- * @returns Array of method names that have HTTP route metadata
1896
- */
1897
- declare function getHttpDecoratedMethods(ControllerClass: new (...args: unknown[]) => object): string[];
1898
- //#endregion
1899
- //#region src/router/decorators/route.decorator.d.ts
1900
- /**
1901
- * Decorator to add OpenAPI metadata to a controller method using convention-based routing.
1902
- *
1903
- * **Cannot be mixed with HTTP method decorators** (`@Get`, `@Post`, `@Put`, `@Patch`,
1904
- * `@Delete`, `@All`) in the same controller. Use one pattern or the other.
1905
- *
1906
- * Stores route configuration (schemas, response, tags, security) in metadata.
1907
- * HTTP method, path, and success status code are auto-derived from the method name:
1908
- * - index() → GET /base-path → 200
1909
- * - show() → GET /base-path/:id → 200
1910
- * - create() → POST /base-path → 201
1911
- * - update() → PUT /base-path/:id → 200
1912
- * - patch() → PATCH /base-path/:id → 200
1913
- * - destroy() → DELETE /base-path/:id → 200
1914
- *
1915
- * @param config - Route configuration (schemas, response, tags, security)
1916
- *
1917
- * @example
1918
- * ```typescript
1919
- * @Controller('/api/v1/notes', {
1920
- * tags: ['Notes'],
1921
- * security: ['bearerAuth']
1922
- * })
1923
- * export class NotesController implements Controller {
1924
- * @Route({
1925
- * body: createNoteSchema,
1926
- * response: noteSchema, // 201 auto-derived from 'create' method
1927
- * tags: ['Mutations'],
1928
- * description: 'Create a new note'
1929
- * })
1930
- * async create(ctx: RouterContext): Promise<Response> {
1931
- * // POST /api/v1/notes (auto-derived from method name)
1932
- * // Body schema: createNoteSchema (auto-validated)
1933
- * // Response: 201 → noteSchema (status auto-derived)
1934
- * // Tags: ['Notes', 'Mutations'] (merged with controller)
1935
- * // Security: ['bearerAuth'] (inherited from controller)
1936
- * const body = ctx.body()
1937
- * const note = await this.notesService.create(body)
1938
- * return ctx.json(note, 201)
1939
- * }
1940
- *
1941
- * @Route({
1942
- * query: paginationSchema,
1943
- * response: z.array(noteSchema) // 200 auto-derived from 'index' method
1944
- * })
1945
- * async index(ctx: RouterContext): Promise<Response> {
1946
- * // GET /api/v1/notes (auto-derived)
1947
- * // Query params auto-validated
1948
- * const notes = await this.notesService.list()
1949
- * return ctx.json(notes)
1950
- * }
1951
- *
1952
- * @Route({
1953
- * params: z.object({ id: z.string().uuid() }),
1954
- * response: {
1955
- * schema: noteSchema,
1956
- * description: 'Note details'
1957
- * },
1958
- * security: [] // Override to make public
1959
- * })
1960
- * async show(ctx: RouterContext): Promise<Response> {
1961
- * // GET /api/v1/notes/:id (auto-derived)
1962
- * // URL params auto-validated
1963
- * // Response: 200 → noteSchema (status auto-derived)
1964
- * // Security: [] (public route, override controller security)
1965
- * const id = ctx.param('id')
1966
- * const note = await this.notesService.findById(id)
1967
- * return ctx.json(note)
1968
- * }
1969
- * }
1970
- * ```
1971
- */
1972
- declare function Route(config: Omit<RouteConfig, 'statusCode'>): (target: object, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
1973
- /**
1974
- * Get the route configuration from a controller method
1975
- *
1976
- * @param target - Controller instance or prototype
1977
- * @param methodName - Name of the method
1978
- * @returns Route configuration or undefined if not decorated
1979
- */
1980
- declare function getRouteConfig(target: object, methodName: string): RouteConfig | undefined;
1981
- /**
1982
- * Get all methods with @Route() decorator from a controller
1983
- *
1984
- * @param ControllerClass - Controller class
1985
- * @returns Array of method names that have route config
1986
- */
1987
- declare function getDecoratedMethods(ControllerClass: new (...args: unknown[]) => object): string[];
1988
- //#endregion
1989
- //#region src/router/schemas/common.schemas.d.ts
1990
- /**
1991
- * Common OpenAPI Schemas
1992
- *
1993
- * Reusable schema definitions for common API patterns:
1994
- * - Error responses
1995
- * - Pagination
1996
- * - Common parameters
1997
- */
1998
- /**
1999
- * Generic error response schema
2000
- * Used for all error responses (4xx, 5xx)
2001
- * Matches ApplicationError.toErrorResponse() structure
2002
- */
2003
- declare const errorResponseSchema: z.ZodObject<{
2004
- code: z.ZodNumber;
2005
- message: z.ZodString;
2006
- timestamp: z.ZodString;
2007
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2008
- stack: z.ZodOptional<z.ZodString>;
2009
- }, z.core.$strip>;
2010
- /**
2011
- * Validation error response schema
2012
- * Used for 400 Bad Request with validation failures
2013
- * Matches ApplicationError.toErrorResponse() structure with validation-specific metadata
2014
- */
2015
- declare const validationErrorResponseSchema: z.ZodObject<{
2016
- code: z.ZodNumber;
2017
- message: z.ZodString;
2018
- timestamp: z.ZodString;
2019
- metadata: z.ZodObject<{
2020
- issues: z.ZodArray<z.ZodObject<{
2021
- path: z.ZodString;
2022
- message: z.ZodString;
2023
- code: z.ZodString;
2024
- }, z.core.$strip>>;
2025
- }, z.core.$strip>;
2026
- stack: z.ZodOptional<z.ZodString>;
2027
- }, z.core.$strip>;
2028
- /**
2029
- * Pagination query parameters schema
2030
- * Used for list endpoints
2031
- */
2032
- declare const paginationQuerySchema: z.ZodObject<{
2033
- page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
2034
- limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
2035
- }, z.core.$strip>;
2036
- /**
2037
- * Paginated response wrapper schema
2038
- * Generic wrapper for paginated list responses
2039
- */
2040
- declare const paginatedResponseSchema: <T extends z.ZodType>(itemSchema: T) => z.ZodObject<{
2041
- data: z.ZodArray<T>;
2042
- pagination: z.ZodObject<{
2043
- page: z.ZodNumber;
2044
- limit: z.ZodNumber;
2045
- total: z.ZodNumber;
2046
- totalPages: z.ZodNumber;
2047
- }, z.core.$strip>;
2048
- }, z.core.$strip>;
2049
- /**
2050
- * UUID parameter schema
2051
- * Used for :id parameters in RESTful routes
2052
- */
2053
- declare const uuidParamSchema: z.ZodObject<{
2054
- id: z.ZodString;
2055
- }, z.core.$strip>;
2056
- /**
2057
- * Success message response schema
2058
- * Used for operations that don't return data (e.g., DELETE)
2059
- */
2060
- declare const successMessageSchema: z.ZodObject<{
2061
- message: z.ZodString;
2062
- data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2063
- }, z.core.$strip>;
2064
- /**
2065
- * Common HTTP status error schemas
2066
- * Pre-configured for standard error responses
2067
- */
2068
- declare const commonErrorSchemas: {
2069
- readonly 400: {
2070
- readonly schema: z.ZodObject<{
2071
- code: z.ZodNumber;
2072
- message: z.ZodString;
2073
- timestamp: z.ZodString;
2074
- metadata: z.ZodObject<{
2075
- issues: z.ZodArray<z.ZodObject<{
2076
- path: z.ZodString;
2077
- message: z.ZodString;
2078
- code: z.ZodString;
2079
- }, z.core.$strip>>;
2080
- }, z.core.$strip>;
2081
- stack: z.ZodOptional<z.ZodString>;
2082
- }, z.core.$strip>;
2083
- readonly description: "Validation error";
2084
- };
2085
- readonly 401: {
2086
- readonly schema: z.ZodObject<{
2087
- code: z.ZodNumber;
2088
- message: z.ZodString;
2089
- timestamp: z.ZodString;
2090
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2091
- stack: z.ZodOptional<z.ZodString>;
2092
- }, z.core.$strip>;
2093
- readonly description: "Unauthorized";
2094
- };
2095
- readonly 403: {
2096
- readonly schema: z.ZodObject<{
2097
- code: z.ZodNumber;
2098
- message: z.ZodString;
2099
- timestamp: z.ZodString;
2100
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2101
- stack: z.ZodOptional<z.ZodString>;
2102
- }, z.core.$strip>;
2103
- readonly description: "Forbidden";
2104
- };
2105
- readonly 404: {
2106
- readonly schema: z.ZodObject<{
2107
- code: z.ZodNumber;
2108
- message: z.ZodString;
2109
- timestamp: z.ZodString;
2110
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2111
- stack: z.ZodOptional<z.ZodString>;
2112
- }, z.core.$strip>;
2113
- readonly description: "Not found";
2114
- };
2115
- readonly 409: {
2116
- readonly schema: z.ZodObject<{
2117
- code: z.ZodNumber;
2118
- message: z.ZodString;
2119
- timestamp: z.ZodString;
2120
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2121
- stack: z.ZodOptional<z.ZodString>;
2122
- }, z.core.$strip>;
2123
- readonly description: "Conflict";
2124
- };
2125
- readonly 500: {
2126
- readonly schema: z.ZodObject<{
2127
- code: z.ZodNumber;
2128
- message: z.ZodString;
2129
- timestamp: z.ZodString;
2130
- metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2131
- stack: z.ZodOptional<z.ZodString>;
2132
- }, z.core.$strip>;
2133
- readonly description: "Internal server error";
2134
- };
2135
- };
2136
- //#endregion
2137
- //#region src/router/errors/hono-app-already-configured.error.d.ts
2138
- /**
2139
- * Error thrown when HonoApp.configure() is called more than once.
2140
- *
2141
- * HonoApp can only be configured a single time during application bootstrap.
2142
- */
2143
- declare class HonoAppAlreadyConfiguredError extends ApplicationError {
2144
- constructor();
2145
- }
2146
- //#endregion
2147
- //#region src/router/errors/controller-registration.error.d.ts
2148
- /**
2149
- * Error thrown when a controller fails to register
2150
- *
2151
- * This typically happens when:
2152
- * - Controller is missing the `@Controller` decorator
2153
- * - Controller route metadata is not set
2154
- * - Controller class name is invalid
2155
- *
2156
- * Error Code: 9005
2157
- */
2158
- declare class ControllerRegistrationError extends ApplicationError {
2159
- constructor(controllerName: string, reason?: string);
2160
- }
2161
- //#endregion
2162
- //#region src/router/errors/openapi-route-registration.error.d.ts
2163
- /**
2164
- * OpenAPIRouteRegistrationError
2165
- *
2166
- * Thrown when an OpenAPI route fails to register properly
2167
- * This indicates a configuration issue with route decorators or metadata
2168
- * Uses i18n key for localized error messages
2169
- *
2170
- * @example
2171
- * ```typescript
2172
- * throw new OpenAPIRouteRegistrationError('/api/v1/users', 'Missing response schema')
2173
- * ```
2174
- */
2175
- declare class OpenAPIRouteRegistrationError extends ApplicationError {
2176
- constructor(path: string, reason: string);
2177
- }
2178
- //#endregion
2179
- //#region src/router/errors/openapi-validation.error.d.ts
2180
- /**
2181
- * OpenAPIValidationError
2182
- *
2183
- * Thrown when OpenAPI request/response validation fails
2184
- * Uses i18n key for localized error messages
2185
- *
2186
- * HTTP Status: 400 Bad Request
2187
- * Error Code: 1004
2188
- *
2189
- * @example
2190
- * ```typescript
2191
- * throw new OpenAPIValidationError('Request body missing required field: email')
2192
- * ```
2193
- */
2194
- declare class OpenAPIValidationError extends ApplicationError {
2195
- constructor(details: string);
2196
- }
2197
- //#endregion
2198
- //#region src/router/errors/route-not-found.error.d.ts
2199
- /**
2200
- * Error thrown when a requested route is not found
2201
- *
2202
- * HTTP Status: 404 Not Found
2203
- * Error Code: 4004
2204
- */
2205
- declare class RouteNotFoundError extends ApplicationError {
2206
- constructor(path: string, method: string);
2207
- }
2208
- //#endregion
2209
- //#region src/i18n/services/i18n.service.d.ts
2210
- /**
2211
- * I18n Service
2212
- *
2213
- * Provides internationalization (i18n) support for the application.
2214
- * Injects RouterContext to access request-specific locale.
2215
- *
2216
- * @example Usage in services
2217
- * ```typescript
2218
- * @Transient(MY_TOKENS.UserService)
2219
- * export class UserService {
2220
- * constructor(
2221
- * @inject(I18N_TOKENS.I18nService) private readonly i18n: II18nService
2222
- * ) {}
2223
- *
2224
- * getWelcomeMessage(): string {
2225
- * return this.i18n.t('common.welcome')
2226
- * }
2227
- * }
2228
- * ```
2229
- */
2230
- declare class I18nService implements II18nService {
2231
- private readonly loader;
2232
- private readonly routerContext?;
2233
- constructor(loader: MessageLoaderService, routerContext?: RouterContext | undefined);
2234
- /**
2235
- * Translate a message key
2236
- *
2237
- * @param key - Message key (e.g., 'common.actions.save')
2238
- * @param params - Optional parameters for interpolation
2239
- * @returns Translated string
2240
- */
2241
- t(key: MessageKeys, params?: MessageParams): string;
2242
- /**
2243
- * Get current locale
2244
- *
2245
- * @returns Current locale code from RouterContext or default locale
2246
- */
2247
- getLocale(): string;
2248
- }
2249
- //#endregion
2250
- //#region src/i18n/middleware/i18n-context.middleware.d.ts
2251
- declare class I18nContextMiddleware implements Middleware {
2252
- private readonly i18n;
2253
- constructor(i18n: I18nService);
2254
- handle(ctx: RouterContext, next: () => Promise<void>): Promise<void>;
2255
- }
2256
- //#endregion
2257
- //#region src/errors/error-codes.d.ts
2258
- /**
2259
- * Centralized Error Code Registry
2260
- *
2261
- * Error codes are organized by category with specific ranges:
2262
- * - 1000-1999: Validation errors
2263
- * - 2000-2999: Database errors (generic)
2264
- * - 3000-3999: Authentication & Authorization
2265
- * - 4000-4999: Resource errors
2266
- * - 5000-5999: Domain-specific business logic (per module)
2267
- * - 9000-9999: System/Internal errors
2268
- * - 9000-9099: Router errors
2269
- * - 9100-9199: Configuration errors
2270
- * - 9200-9299: Infrastructure errors
2271
- * - 9300-9399: I18n errors
2272
- */
2273
- declare const ERROR_CODES: {
2274
- /**
2275
- * Database Errors (2000-2999)
2276
- * Generic database errors thrown by Prisma client extensions
2277
- */
2278
- readonly DATABASE: {
2279
- /** Generic database error */readonly GENERIC: 2000; /** Record not found in database */
2280
- readonly RECORD_NOT_FOUND: 2001; /** Unique constraint violation */
2281
- readonly UNIQUE_CONSTRAINT: 2002; /** Foreign key constraint violation */
2282
- readonly FOREIGN_KEY_CONSTRAINT: 2003; /** Database connection failed */
2283
- readonly CONNECTION_FAILED: 2004; /** Database timeout */
2284
- readonly TIMEOUT: 2005; /** Null constraint violation */
2285
- readonly NULL_CONSTRAINT: 2006; /** Too many database connections */
2286
- readonly TOO_MANY_CONNECTIONS: 2007; /** Transaction conflict or deadlock */
2287
- readonly TRANSACTION_CONFLICT: 2008;
2288
- };
2289
- /**
2290
- * Authentication Errors (3000-3099)
2291
- * Authentication-related failures
2292
- */
2293
- readonly AUTH: {
2294
- /** Invalid credentials provided */readonly INVALID_CREDENTIALS: 3000; /** Session expired or invalid */
2295
- readonly SESSION_EXPIRED: 3001; /** Account locked or disabled */
2296
- readonly ACCOUNT_LOCKED: 3002; /** Invalid or expired token */
2297
- readonly INVALID_TOKEN: 3003; /** Context not initialized */
2298
- readonly CONTEXT_NOT_INITIALIZED: 3004; /** User not authenticated */
2299
- readonly USER_NOT_AUTHENTICATED: 3005; /** Email verification required before login */
2300
- readonly EMAIL_NOT_VERIFIED: 3007; /** Password doesn't meet minimum length */
2301
- readonly PASSWORD_TOO_SHORT: 3008; /** Password exceeds maximum length */
2302
- readonly PASSWORD_TOO_LONG: 3009; /** Account with email already exists */
2303
- readonly ACCOUNT_ALREADY_EXISTS: 3010; /** User creation failed */
2304
- readonly FAILED_TO_CREATE_USER: 3011; /** Session creation failed */
2305
- readonly FAILED_TO_CREATE_SESSION: 3012; /** User update failed */
2306
- readonly FAILED_TO_UPDATE_USER: 3013; /** Social account already linked */
2307
- readonly SOCIAL_ACCOUNT_LINKED: 3014; /** Last account cannot be unlinked */
2308
- readonly CANNOT_UNLINK_LAST_ACCOUNT: 3015;
2309
- };
2310
- /**
2311
- * Authorization Errors (3100-3199)
2312
- * Permission and access control failures
2313
- */
2314
- readonly AUTHZ: {
2315
- /** Insufficient permissions */readonly FORBIDDEN: 3100; /** Resource access denied */
2316
- readonly ACCESS_DENIED: 3101; /** User lacks required role */
2317
- readonly INSUFFICIENT_PERMISSIONS: 3102;
2318
- };
2319
- /**
2320
- * Resource Errors (4000-4999)
2321
- * Generic resource-related errors
2322
- */
2323
- readonly RESOURCE: {
2324
- /** Generic resource not found */readonly NOT_FOUND: 4000; /** Route/endpoint not found */
2325
- readonly ROUTE_NOT_FOUND: 4004; /** Resource conflict or duplicate */
2326
- readonly CONFLICT: 4100; /** Resource already exists */
2327
- readonly ALREADY_EXISTS: 4101;
2328
- };
2329
- /**
2330
- * Validation Errors (1000-1999)
2331
- * Input validation failures
2332
- */
2333
- readonly VALIDATION: {
2334
- /** Generic validation error */readonly GENERIC: 1000; /** Required field missing */
2335
- readonly REQUIRED_FIELD: 1001; /** Invalid format */
2336
- readonly INVALID_FORMAT: 1002; /** Schema validation failed */
2337
- readonly SCHEMA_VALIDATION: 1003; /** Request validation failed (OpenAPI, etc.) */
2338
- readonly REQUEST_VALIDATION: 1004;
2339
- };
2340
- /**
2341
- * Router Errors (9000-9099)
2342
- * Router and controller-related INTERNAL errors
2343
- */
2344
- readonly ROUTER: {
2345
- /** Controller registration error */readonly CONTROLLER_REGISTRATION_ERROR: 9005; /** Controller method not found */
2346
- readonly CONTROLLER_METHOD_NOT_FOUND: 9006; /** OpenAPI route registration failed */
2347
- readonly OPENAPI_ROUTE_REGISTRATION: 9008;
2348
- };
2349
- /**
2350
- * I18n Errors (9300-9399)
2351
- * Internationalization and localization errors
2352
- */
2353
- readonly I18N: {
2354
- /** Translation key missing from all locales */readonly TRANSLATION_MISSING: 9300; /** Requested locale not supported */
2355
- readonly LOCALE_NOT_SUPPORTED: 9301;
2356
- };
2357
- /**
2358
- * System Errors (9000-9999)
2359
- * Internal system errors and unexpected failures
2360
- */
2361
- readonly SYSTEM: {
2362
- /** Internal server error */readonly INTERNAL_ERROR: 9000; /** Generic configuration error */
2363
- readonly CONFIGURATION_ERROR: 9100; /** ConfigService not initialized */
2364
- readonly CONFIG_NOT_INITIALIZED: 9101; /** Module already registered */
2365
- readonly MODULE_ALREADY_REGISTERED: 9102; /** Circular module dependency detected */
2366
- readonly MODULE_CIRCULAR_DEPENDENCY: 9103; /** Module dependency not found */
2367
- readonly MODULE_DEPENDENCY_NOT_FOUND: 9104; /** Invalid error code range */
2368
- readonly INVALID_ERROR_CODE_RANGE: 9105; /** Invalid module provider configuration */
2369
- readonly INVALID_MODULE_PROVIDER: 9106; /** ConfigModule.forRoot() was not called */
2370
- readonly CONFIG_MODULE_NOT_INITIALIZED: 9107; /** Generic infrastructure error */
2371
- readonly INFRASTRUCTURE_ERROR: 9200; /** Execution context not initialized */
2372
- readonly EXECUTION_CONTEXT_NOT_INITIALIZED: 9201; /** Request container not initialized */
2373
- readonly REQUEST_CONTAINER_NOT_INITIALIZED: 9202; /** Queue binding not found */
2374
- readonly QUEUE_BINDING_NOT_FOUND: 9203; /** Cron job execution failed */
2375
- readonly CRON_EXECUTION_FAILED: 9204; /** Queue provider not supported */
2376
- readonly QUEUE_PROVIDER_NOT_SUPPORTED: 9205; /** body() called on WebSocket gateway context */
2377
- readonly WEBSOCKET_BODY_NOT_AVAILABLE: 9206; /** Duplicate WebSocket event decorator on a gateway */
2378
- readonly WEBSOCKET_DUPLICATE_EVENT_HANDLER: 9207; /** Seeder name collision — two seeders share the same class name */
2379
- readonly SEEDER_NAME_COLLISION: 9208; /** Seeder not registered in the SeederRegistry */
2380
- readonly SEEDER_NOT_REGISTERED: 9209;
2381
- };
2382
- };
2383
- /**
2384
- * Recursively extract all leaf values from a nested object type
2385
- * Similar to DeepKeys but extracts values instead of keys
2386
- *
2387
- * Example:
2388
- * { DATABASE: { GENERIC: 2000, NOT_FOUND: 2001 }, AUTH: { INVALID: 3000 } }
2389
- * becomes
2390
- * 2000 | 2001 | 3000
2391
- */
2392
- type DeepValues<T> = T extends object ? { [K in keyof T]: DeepValues<T[K]> }[keyof T] : T;
2393
- /**
2394
- * Type helper to extract all error code values
2395
- * Union type of all numeric error codes defined in ERROR_CODES
2396
- *
2397
- * Type: 2000 | 2001 | 2002 | ... | 9203
2398
- */
2399
- type ErrorCode = DeepValues<typeof ERROR_CODES>;
2400
- //#endregion
2401
- //#region src/errors/application-error.d.ts
2402
- /**
2403
- * ApplicationError
2404
- *
2405
- * Abstract base class for all application errors.
2406
- * This class should never be used directly - always extend it to create specific error types.
2407
- *
2408
- * Features:
2409
- * - Type-safe error codes from ERROR_CODES registry
2410
- * - Type-safe message keys from i18n module
2411
- * - Localized message keys (translated by GlobalErrorHandler)
2412
- * - Structured metadata for logging and interpolation
2413
- * - Proper Error prototype chain
2414
- * - Automatic timestamp generation
2415
- * - Serialization for RPC transmission
2416
- *
2417
- * Message Localization:
2418
- * - Each error class passes an i18n key (e.g., 'errors.userNotFound') to super()
2419
- * - `Error.message` contains the i18n key for useful stack traces and fallback display
2420
- * - Metadata provides interpolation parameters (e.g., { userId: '123' })
2421
- * - GlobalErrorHandler translates the message key using I18nService before sending response
2422
- * - This ensures errors are localized based on the user's locale (from X-Locale header)
2423
- */
2424
- declare abstract class ApplicationError extends Error {
2425
- /**
2426
- * Controls whether stack traces are captured.
2427
- * Set to false in production to skip the expensive Error.captureStackTrace() call,
2428
- * since stack traces are stripped from responses in production anyway.
2429
- */
2430
- static captureStackTraces: boolean;
2431
- /**
2432
- * Type-safe error code from ERROR_CODES registry
2433
- * See error-codes.ts for the complete registry
2434
- */
2435
- readonly code: ErrorCode;
2436
- /**
2437
- * ISO timestamp when the error was created
2438
- */
2439
- readonly timestamp: string;
2440
- /**
2441
- * Additional structured data about the error
2442
- * Used for:
2443
- * 1. Logging and debugging
2444
- * 2. Message interpolation (e.g., { userId: '123', email: 'user@example.com' })
2445
- */
2446
- readonly metadata?: Record<string, unknown>;
2447
- /**
2448
- * @param i18nKey - Type-safe i18n message key (e.g., 'errors.userNotFound')
2449
- * @param code - Type-safe error code from ERROR_CODES registry
2450
- * @param metadata - Optional data for logging and interpolation
2451
- */
2452
- constructor(i18nKey: MessageKeys, code: ErrorCode, metadata?: Record<string, unknown>);
2453
- /**
2454
- * Filter metadata to include only user-facing properties
2455
- *
2456
- * User-facing properties (validation/constraint errors):
2457
- * - issues: Validation errors from SchemaValidationError
2458
- * - fields: Constraint violation fields
2459
- * - field: Single field constraint/foreign key
2460
- *
2461
- * Internal properties (excluded from response):
2462
- * - path, method: Route debugging
2463
- * - controllerName, reason: Controller errors
2464
- * - details, etc.: Internal debugging info
2465
- *
2466
- * @param metadata - Raw metadata object
2467
- * @returns Filtered metadata with only whitelisted properties
2468
- */
2469
- private static filterMetadata;
2470
- /**
2471
- * Serialize error to ErrorResponse format for RPC transmission
2472
- *
2473
- * @param env - Environment (development | production)
2474
- * @param translatedMessage - Optional translated message (from GlobalErrorHandler)
2475
- * @returns ErrorResponse object suitable for JSON serialization
2476
- */
2477
- toErrorResponse(env: Environment, translatedMessage?: string): ErrorResponse;
2478
- /**
2479
- * JSON serialization (used by JSON.stringify)
2480
- * Defaults to development mode for backward compatibility
2481
- * Note: This will use the untranslated message key - use GlobalErrorHandler for proper localization
2482
- */
2483
- toJSON(): ErrorResponse;
2484
- }
2485
- //#endregion
2486
- //#region src/errors/get-http-status.d.ts
2487
- /**
2488
- * Maps error codes to HTTP status codes
2489
- *
2490
- * This utility is used by the frontend to set appropriate HTTP status codes
2491
- * when returning errors from API routes.
2492
- *
2493
- * @param code - Numeric error code from ERROR_CODES registry
2494
- * @returns HTTP status code (200-599)
2495
- */
2496
- declare function getHttpStatus(code: number): ContentfulStatusCode;
2497
- //#endregion
2498
- //#region src/errors/global-error-handler.d.ts
2499
- /**
2500
- * GlobalErrorHandler
2501
- *
2502
- * Centralized error handler registered in the DI container.
2503
- * Responsible for:
2504
- * - Intercepting all errors in the application
2505
- * - Logging errors with appropriate severity via Logger service
2506
- * - Translating error message keys using I18nService (when available)
2507
- * - Serializing errors for RPC transmission
2508
- * - Wrapping unexpected errors in InternalError
2509
- *
2510
- * **Translation Availability by Context:**
2511
- *
2512
- * ✅ **HTTP Requests**: Errors are fully translated
2513
- * - GlobalErrorHandler resolved from request container
2514
- * - I18nService available via AsyncLocalStorage with user's locale
2515
- * - Full translation with parameter interpolation
2516
- *
2517
- * ✅ **Queue Processing**: Errors are fully translated
2518
- * - Error handling executes inside AsyncLocalStorage scope
2519
- * - Locale extracted from queue message metadata
2520
- * - Request container created with mock RouterContext
2521
- * - I18nService available with correct locale
2522
- *
2523
- * ⚠️ **RPC/Startup**: Message keys returned as-is (i18n unavailable)
2524
- * - No request context available during service binding or startup
2525
- * - No locale information available
2526
- * - Frontend can translate message keys using its own i18n if needed
2527
- * - This is expected behavior, not a bug
2528
- *
2529
- * **Implementation Note:**
2530
- * The `isAvailable()` check exists to gracefully handle RPC/startup contexts
2531
- * where no request container exists. For HTTP and Queue contexts, i18n is
2532
- * always available thanks to AsyncLocalStorage scope propagation. This follows
2533
- * the "Laravel philosophy" - transparent dependency injection for request contexts,
2534
- * with explicit handling only for legitimate non-request edge cases.
2535
- */
2536
- declare class GlobalErrorHandler {
2537
- private readonly logger;
2538
- private readonly i18n;
2539
- private readonly env;
2540
- private readonly environment;
2541
- constructor(logger: LoggerService, i18n: II18nService, env: StratalEnv);
2542
- /**
2543
- * Handle an error, log it, and serialize for response
2544
- *
2545
- * @param error - The error to handle
2546
- * @returns Serialized ErrorResponse for RPC transmission
2547
- */
2548
- handle(error: unknown): ErrorResponse;
2549
- /**
2550
- * Translate error message key using I18nService
2551
- * Uses error metadata as interpolation parameters
2552
- *
2553
- * No try/catch - if translation fails, it's a bug that should fail loudly
2554
- *
2555
- * **Note**: This method is only called when isAvailable() returns true,
2556
- * so the service is guaranteed to be resolved.
2557
- *
2558
- * @param error - ApplicationError with messageKey and metadata
2559
- * @returns Translated message string
2560
- */
2561
- private translateError;
2562
- /**
2563
- * Log an ApplicationError with appropriate severity
2564
- */
2565
- private log;
2566
- /**
2567
- * Log an unexpected error
2568
- */
2569
- private logUnexpectedError;
2570
- /**
2571
- * Determine log severity based on error code
2572
- */
2573
- private getSeverity;
2574
- }
2575
- //#endregion
2576
- //#region src/errors/internal-error.d.ts
2577
- /**
2578
- * InternalError
2579
- *
2580
- * Represents an unexpected internal server error.
2581
- * Used to wrap unknown errors that don't fit into specific error categories.
2582
- *
2583
- * This error is thrown when:
2584
- * - An unexpected exception occurs
2585
- * - An error type is not recognized
2586
- * - A system-level failure happens
2587
- */
2588
- declare class InternalError extends ApplicationError {
2589
- constructor(metadata?: Record<string, unknown>);
2590
- }
2591
- //#endregion
2592
- //#region src/errors/is-application-error.d.ts
2593
- /**
2594
- * Type guard to check if an error is an ApplicationError
2595
- *
2596
- * @param error - The error to check
2597
- * @returns True if the error is an ApplicationError instance
2598
- */
2599
- declare function isApplicationError(error: unknown): error is ApplicationError;
2600
- //#endregion
2601
- //#region src/errors/request-container-not-initialized.error.d.ts
2602
- /**
2603
- * RequestContainerNotInitializedError
2604
- *
2605
- * Thrown when attempting to access the request-scoped container before it has been initialized.
2606
- * This typically indicates that the RouterService middleware hasn't run yet,
2607
- * or the router context is being accessed outside of a request lifecycle.
2608
- */
2609
- declare class RequestContainerNotInitializedError extends ApplicationError {
2610
- constructor();
2611
- }
2612
- //#endregion
2613
- //#region src/errors/stratal-not-initialized.error.d.ts
2614
- /**
2615
- * StratalNotInitializedError
2616
- *
2617
- * Thrown when attempting to resolve the Application instance before Stratal has been instantiated.
2618
- * This typically indicates that the Stratal instance is not exported as the default export.
2619
- */
2620
- declare class StratalNotInitializedError extends ApplicationError {
2621
- constructor();
2622
- }
2623
- //#endregion
2624
- export { I18nModule as $, DI_TOKENS as $t, Delete as A, RouteBodyObject as At, getControllerVersion as B, ROUTE_METADATA_KEYS as Bt, successMessageSchema as C, ErrorResponse as Cn, Middleware as Ct, getDecoratedMethods as D, ControllerOptions as Dt, Route as E, RouterContext as Et, getHttpDecoratedMethods as F, RouterVariables as Ft, MiddlewareConsumerImpl as G, ConditionalBindingFallbackError as Gt, RouteRegistrationService as H, VERSION_NEUTRAL as Ht, getHttpRouteMetadata as I, SecurityScheme as It, TranslationMissingError as J, InjectParam as Jt, createMiddlewareConsumer as K, Transient as Kt, Controller as L, VersioningOptions as Lt, Patch as M, RouteResponse as Mt, Post as N, RouteResponseObject as Nt, getRouteConfig as O, HttpRouteMetadata as Ot, Put as P, RouterEnv as Pt, I18N_TOKENS as Q, DIToken as Qt, getControllerOptions as R, HTTP_METHODS as Rt, paginationQuerySchema as S, Environment as Sn, RouteInfo as St, validationErrorResponseSchema as T, ContextQueryResult as Tt, HonoApp as U, StratalEnv as Ut, ROUTER_TOKENS as V, SECURITY_SCHEMES as Vt, MiddlewareConfigurationService as W, RequestScopeOperationNotAllowedError as Wt, setupI18nCompiler as X, getMethodInjections as Xt, LocaleNotSupportedError as Y, ParamInjection as Yt, MessageRegistry as Z, CONTAINER_TOKEN as Zt, ControllerRegistrationError as _, WhenOptions as _n, MiddlewareBuilder as _t, GlobalErrorHandler as a, inject$1 as an, DynamicModule as at, errorResponseSchema as b, getMessages as bn, MiddlewareConsumer as bt, ERROR_CODES as c, singleton as cn, InjectionToken$2 as ct, SSEMessage as d, ConditionalBindingGive as dn, ModuleOptions as dt, Container as en, I18nModuleOptions as et, SSEStreamingApi$1 as f, ConditionalBindingUse as fn, OnInitialize as ft, OpenAPIRouteRegistrationError as g, Scope as gn, ValueProvider as gt, OpenAPIValidationError as h, ExtensionDecorator as hn, RegistryEntry as ht, InternalError as i, delay as in, ClassProvider as it, Get as j, RouteConfig as jt, All as k, RouteBody as kt, ErrorCode as l, ConditionalBindingBuilder as ln, ModuleClass as lt, RouteNotFoundError as m, ContainerLike as mn, Provider as mt, RequestContainerNotInitializedError as n, DependencyContainer$1 as nn, resolveI18nOptions as nt, getHttpStatus as o, injectable$1 as on, ExistingProvider as ot, StreamingApi$1 as p, PredicateContainer as pn, OnShutdown as pt, LocaleExtractionMiddleware as q, INJECT_PARAM_METADATA_KEY as qt, isApplicationError as r, container$1 as rn, AsyncModuleOptions as rt, ApplicationError as s, instancePerContainerCachingFactory$1 as sn, FactoryProvider as st, StratalNotInitializedError as t, ContainerOptions as tn, ResolvedI18nOptions as tt, I18nContextMiddleware as u, ConditionalBindingBuilderImpl as un, ModuleContext as ut, HonoAppAlreadyConfiguredError as v, Messages as vn, MiddlewareConfigEntry as vt, uuidParamSchema as w, isErrorResponse as wn, IController as wt, paginatedResponseSchema as x, messages as xn, MiddlewareRouteTarget as xt, commonErrorSchemas as y, getLocales as yn, MiddlewareConfigurable as yt, getControllerRoute as z, ROUTER_CONTEXT_KEYS as zt };
2625
- //# sourceMappingURL=index-BFCxSp_f.d.mts.map