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,4 +1,4 @@
1
- import { a as CommandInternals, i as CommandInput, o as CommandResult } from "./application-DfPtIzxF.mjs";
1
+ import { cn as CommandResult, on as CommandInput, sn as CommandInternals } from "./index-DPFqRs8L.mjs";
2
2
  //#region src/quarry/constants.d.ts
3
3
  /**
4
4
  * Symbol key for storing internal mutable state on Command instances.
@@ -117,4 +117,4 @@ declare abstract class Command {
117
117
  }
118
118
  //#endregion
119
119
  export { Command as t };
120
- //# sourceMappingURL=command-TnkPYWta.d.mts.map
120
+ //# sourceMappingURL=command-DsQq56Lp.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-TnkPYWta.d.mts","names":[],"sources":["../src/quarry/constants.ts","../src/quarry/command.ts"],"mappings":";;;;;;cAIa,iBAAA;;;;AAAb;;;;;;;;ACsBA;;;;;;;;;;uBAAsB,OAAA;EA8LmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,OA7JhD,OAAA;EA4HC;EAAA,OA1HD,WAAA;EA+HD;EAAA,OA7HC,OAAA;EAAA,CAEN,iBAAA,GAAoB,gBAAA;;EA4IC;;;;EAAA,SA3Hb,MAAA,CAAA,mBAA0B,OAAA;EAsIa;;;EA/HhD,KAAA,GAAA,CAAS,IAAA,WAAe,CAAA;;;;EAOxB,MAAA,CAAO,IAAA;;;;EAcP,OAAA,CAAQ,IAAA;;;;EAcR,MAAA,CAAO,IAAA;;;;EAeP,KAAA,CAAM,IAAA;;EAcN,IAAA,CAAK,OAAA;;EAKL,OAAA,CAAQ,OAAA;;EAKR,IAAA,CAAK,OAAA;;EAKL,KAAA,CAAM,OAAA;;EAKN,IAAA,CAAK,OAAA;;EAKL,OAAA,CAAA;;EAKA,OAAA,CAAQ,OAAA;;EAKR,KAAA,CAAM,OAAA,YAAmB,IAAA;;EAiBzB,IAAA,CAAK,OAAA,UAAiB,QAAA;;;;;EAWhB,IAAA,CAAK,IAAA,UAAc,KAAA,GAAQ,YAAA,GAAe,OAAA,CAAQ,aAAA;AAAA"}
1
+ {"version":3,"file":"command-DsQq56Lp.d.mts","names":[],"sources":["../src/quarry/constants.ts","../src/quarry/command.ts"],"mappings":";;;;;;cAIa,iBAAA;;;;AAAb;;;;;;;;ACsBA;;;;;;;;;;uBAAsB,OAAA;EA8LmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,OA7JhD,OAAA;EA4HC;EAAA,OA1HD,WAAA;EA+HD;EAAA,OA7HC,OAAA;EAAA,CAEN,iBAAA,GAAoB,gBAAA;;EA4IC;;;;EAAA,SA3Hb,MAAA,CAAA,mBAA0B,OAAA;EAsIa;;;EA/HhD,KAAA,GAAA,CAAS,IAAA,WAAe,CAAA;;;;EAOxB,MAAA,CAAO,IAAA;;;;EAcP,OAAA,CAAQ,IAAA;;;;EAcR,MAAA,CAAO,IAAA;;;;EAeP,KAAA,CAAM,IAAA;;EAcN,IAAA,CAAK,OAAA;;EAKL,OAAA,CAAQ,OAAA;;EAKR,IAAA,CAAK,OAAA;;EAKL,KAAA,CAAM,OAAA;;EAKN,IAAA,CAAK,OAAA;;EAKL,OAAA,CAAA;;EAKA,OAAA,CAAQ,OAAA;;EAKR,KAAA,CAAM,OAAA,YAAmB,IAAA;;EAiBzB,IAAA,CAAK,OAAA,UAAiB,QAAA;;;;;EAWhB,IAAA,CAAK,IAAA,UAAc,KAAA,GAAQ,YAAA,GAAe,OAAA,CAAQ,aAAA;AAAA"}
@@ -1,10 +1,12 @@
1
- import { at as DynamicModule, ft as OnInitialize, st as FactoryProvider, ut as ModuleContext } from "../index-BFCxSp_f.mjs";
2
- import { o as z } from "../index-NGxg-KP_.mjs";
1
+ import { Cn as OnInitialize, _n as FactoryProvider, bn as ModuleContext, hn as DynamicModule } from "../index-DPFqRs8L.mjs";
2
+ import { t as Macroable } from "../index-SHx31sBJ.mjs";
3
+ import { o as z } from "../index-B437eK7p.mjs";
3
4
  import { InjectionToken } from "tsyringe";
4
5
 
5
6
  //#region src/config/config.tokens.d.ts
6
7
  declare const CONFIG_TOKENS: {
7
8
  readonly ConfigService: symbol;
9
+ readonly ConfigStore: symbol;
8
10
  };
9
11
  //#endregion
10
12
  //#region src/config/register-as.d.ts
@@ -177,14 +179,13 @@ type ConfigPath<T> = { [K in keyof T & string]: T[K] extends Record<string, unkn
177
179
  */
178
180
  type ConfigPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? T[K] extends Record<string, unknown> ? ConfigPathValue<T[K], Rest> : never : never : P extends keyof T ? T[P] : never;
179
181
  /**
180
- * ConfigService interface with dot notation support
182
+ * ConfigService interface with dot notation support.
183
+ *
184
+ * Values are initialized on the underlying {@link ConfigStore} via
185
+ * {@link ConfigModule}; the service itself exposes request-scoped
186
+ * reads and per-request overrides.
181
187
  */
182
188
  interface IConfigService<T extends object = ModuleConfig> {
183
- /**
184
- * Initialize the config service with validated configuration
185
- * Should be called once during application startup
186
- */
187
- initialize(config: T): void;
188
189
  /**
189
190
  * Get config value using dot notation
190
191
  * @example config.get('database.url')
@@ -210,64 +211,107 @@ interface IConfigService<T extends object = ModuleConfig> {
210
211
  has(path: ConfigPath<T>): boolean;
211
212
  }
212
213
  //#endregion
214
+ //#region src/config/services/config.store.d.ts
215
+ /**
216
+ * ConfigStore
217
+ *
218
+ * Singleton-scoped holder of validated, merged configuration.
219
+ *
220
+ * ConfigStore is the source of truth for configuration values. It is
221
+ * initialized once during application startup by {@link ConfigModule}
222
+ * and never mutated afterwards.
223
+ *
224
+ * Per-request overrides live on {@link ConfigService}, which reads
225
+ * through to this store for any key not explicitly overridden.
226
+ */
227
+ declare class ConfigStore<T extends object = ModuleConfig> {
228
+ private data;
229
+ /**
230
+ * Initialize the store with validated configuration.
231
+ * Called by {@link ConfigModule} during initialization.
232
+ */
233
+ initialize(config: T): void;
234
+ /**
235
+ * Get config value using dot notation.
236
+ */
237
+ get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P>;
238
+ /**
239
+ * Check if a config path exists.
240
+ */
241
+ has(path: ConfigPath<T>): boolean;
242
+ /**
243
+ * Get the entire config object (readonly snapshot).
244
+ */
245
+ all(): Readonly<T>;
246
+ /**
247
+ * True once {@link initialize} has been called.
248
+ */
249
+ isInitialized(): boolean;
250
+ private getByPath;
251
+ private isDangerousKey;
252
+ private ensureInitialized;
253
+ private deepClone;
254
+ }
255
+ //#endregion
213
256
  //#region src/config/services/config.service.d.ts
214
257
  /**
215
- * ConfigService with dot notation support for get/set operations
258
+ * ConfigService with dot notation support and per-request overrides.
259
+ *
260
+ * ConfigService is **request-scoped**: each request gets its own
261
+ * instance with a private `overrides` map layered over the shared
262
+ * {@link ConfigStore}. Calls to {@link set} mutate only the current
263
+ * request's overrides, which makes it safe to mutate config from
264
+ * middleware (e.g. to pin `environment.appUrl` to the request host).
216
265
  *
217
- * Supports runtime overrides via set() - useful for request-specific config overrides.
218
- * Use reset() to restore original values.
266
+ * Extends {@link Macroable} so apps can add domain-specific getters
267
+ * and methods via `ConfigService.getter()` / `ConfigService.macro()`.
219
268
  *
220
269
  * @example
221
270
  * ```typescript
222
- * // Get with dot notation
271
+ * // Read with dot notation
223
272
  * const url = config.get('database.url')
224
273
  * const fromName = config.get('email.from.name')
225
274
  *
226
- * // Set at runtime (e.g., in middleware for runtime override)
227
- * config.set('email.from.name', 'Custom Name')
275
+ * // Per-request override (e.g. in middleware)
276
+ * config.set('environment.appUrl', `${proto}://${host}`)
228
277
  *
229
- * // Reset to original
230
- * config.reset('email.from.name') // reset specific path
231
- * config.reset() // reset entire config
278
+ * // Reset the override for the current request
279
+ * config.reset('environment.appUrl')
232
280
  * ```
233
281
  */
234
- declare class ConfigService<T extends object = ModuleConfig> implements IConfigService<T> {
235
- private originalConfig;
236
- private currentConfig;
282
+ declare class ConfigService<T extends object = ModuleConfig> extends Macroable implements IConfigService<T> {
283
+ private readonly store;
284
+ private overrides;
285
+ constructor(store: ConfigStore<T>);
237
286
  /**
238
- * Initialize the config service with validated configuration
239
- * Called by ConfigModule during initialization
240
- */
241
- initialize(config: T): void;
242
- /**
243
- * Get config value using dot notation
244
- * @example config.get('database.url')
287
+ * Get config value using dot notation. Request overrides take
288
+ * precedence over the shared store.
245
289
  */
246
290
  get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P>;
247
291
  /**
248
- * Set config value at runtime (for runtime overrides)
249
- * @example config.set('email.from.name', 'Custom Name')
292
+ * Set a config value for the lifetime of the current request.
293
+ * Does not mutate the shared store.
250
294
  */
251
295
  set<P extends ConfigPath<T>>(path: P, value: ConfigPathValue<T, P>): void;
252
296
  /**
253
- * Reset config to original value
254
- * @param path - Optional path to reset (resets entire config if omitted)
297
+ * Clear a single override, or all overrides for this request.
255
298
  */
256
299
  reset(path?: ConfigPath<T>): void;
257
300
  /**
258
- * Get entire config object
301
+ * Get the full config object, with request overrides merged in.
259
302
  */
260
303
  all(): Readonly<T>;
261
304
  /**
262
- * Check if a config path exists
305
+ * Check if a config path exists (in overrides or the store).
263
306
  */
264
307
  has(path: ConfigPath<T>): boolean;
265
- private getByPath;
266
- private setByPath;
308
+ private readOverride;
309
+ private walk;
310
+ private writeByPath;
311
+ private hasDangerousSegment;
267
312
  private isDangerousKey;
268
- private ensureInitialized;
269
313
  private deepClone;
270
314
  }
271
315
  //#endregion
272
- export { CONFIG_TOKENS, ConfigModule, type ConfigModuleOptions, type ConfigNamespace, type ConfigPath, type ConfigPathValue, ConfigService, ConfigValidationError, type IConfigService, type InferConfigType, type ModuleConfig, registerAs };
316
+ export { CONFIG_TOKENS, ConfigModule, type ConfigModuleOptions, type ConfigNamespace, type ConfigPath, type ConfigPathValue, ConfigService, ConfigStore, ConfigValidationError, type IConfigService, type InferConfigType, type ModuleConfig, registerAs };
273
317
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/config/config.tokens.ts","../../src/config/register-as.ts","../../src/config/config.module.ts","../../src/config/config.types.ts","../../src/config/services/config.service.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/config/config.tokens.ts","../../src/config/register-as.ts","../../src/config/config.module.ts","../../src/config/config.types.ts","../../src/config/services/config.store.ts","../../src/config/services/config.service.ts"],"mappings":";;;;;;cAAa,aAAA;EAAA,SAGH,aAAA;EAAA,SAAA,WAAA;AAAA;;;;;;UCIO,eAAA;EDPJ;EAAA,SCSF,GAAA,EAAK,cAAA,CAAe,OAAA;;WAEpB,SAAA,EAAW,IAAA;;WAEX,OAAA,GAAU,GAAA,EAAK,IAAA,KAAS,OAAA;;;AANnC;;EAWE,UAAA,IAAc,eAAA,CAAgB,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAkChC;;;;;;iBAAgB,UAAA,mDAAA,CACd,SAAA,EAAW,IAAA,EACX,OAAA,GAAU,GAAA,EAAK,IAAA,KAAS,OAAA,GACvB,eAAA,CAAgB,IAAA,EAAM,IAAA,EAAM,OAAA;;;;;;;;;;;KA2BnB,eAAA,MAAqB,CAAA,SAAU,eAAA,6BAA4C,CAAA;;;;;;KClE3E,kBAAA,GAAqB,eAAA;;;;UAKhB,mBAAA;;;;EAIf,IAAA,EAAM,kBAAA;EDlBwB;;;;ECwB9B,cAAA,GAAiB,CAAA,CAAE,OAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;ADqBrB;;;;;;;;;;;;;;;;;;;;;cC6Ca,YAAA,YAAwB,YAAA;ED1ClB;;;;;AA2BnB;EA3BmB,OCiDV,OAAA,CAAQ,OAAA,EAAS,mBAAA,GAAsB,aAAA;EDtBrB;;;;EC0CzB,YAAA,CAAa,OAAA,EAAS,aAAA;AAAA;;;cC1HX,qBAAA,SAA8B,KAAA;EAAA,SAGvB,MAAA,EAAQ,CAAA,CAAE,QAAA;cAD1B,OAAA,UACgB,MAAA,EAAQ,CAAA,CAAE,QAAA;AAAA;;AHL9B;;;;;;;;ACOA;;;;;;UEoBiB,YAAA;;;;;KAML,UAAA,oBACE,CAAA,YAAa,CAAA,CAAE,CAAA,UAAW,MAAA,oBACpC,CAAA,MAAO,CAAA,IAAK,UAAA,CAAW,CAAA,CAAE,CAAA,OACzB,CAAA,SACI,CAAA;;;;;KAMI,eAAA,wBAAuC,CAAA,sCAC/C,CAAA,eAAgB,CAAA,GAChB,CAAA,CAAE,CAAA,UAAW,MAAA,oBACb,eAAA,CAAgB,CAAA,CAAE,CAAA,GAAI,IAAA,oBAGtB,CAAA,eAAgB,CAAA,GAChB,CAAA,CAAE,CAAA;;;;;;;;UAUW,cAAA,oBAAkC,YAAA;EF1CZ;AAkCvC;;;EEaE,GAAA,WAAc,UAAA,CAAW,CAAA,GAAI,IAAA,EAAM,CAAA,GAAI,eAAA,CAAgB,CAAA,EAAG,CAAA;EFX3C;;;;EEiBf,GAAA,WAAc,UAAA,CAAW,CAAA,GAAI,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,eAAA,CAAgB,CAAA,EAAG,CAAA;EFhB/D;;;;EEsBD,KAAA,CAAM,IAAA,GAAO,UAAA,CAAW,CAAA;EFzB4B;;;EE8BpD,GAAA,IAAO,QAAA,CAAS,CAAA;EF5BN;;;EEiCV,GAAA,CAAI,IAAA,EAAM,UAAA,CAAW,CAAA;AAAA;;;;;;;;AHvFvB;;;;;;;cIkBa,WAAA,oBAA+B,YAAA;EAAA,QAClC,IAAA;EHZsB;;;;EGkB9B,UAAA,CAAW,MAAA,EAAQ,CAAA;EHZK;;;EGmBxB,GAAA,WAAc,UAAA,CAAW,CAAA,EAAA,CAAI,IAAA,EAAM,CAAA,GAAI,eAAA,CAAgB,CAAA,EAAG,CAAA;EHd7B;;;EGsB7B,GAAA,CAAI,IAAA,EAAM,UAAA,CAAW,CAAA;EHjCqC;;;EGyC1D,GAAA,CAAA,GAAO,QAAA,CAAS,CAAA;EHrCP;;;EG6CT,aAAA,CAAA;EAAA,QAIQ,SAAA;EAAA,QAWA,cAAA;EAAA,QAIA,iBAAA;EAAA,QAMA,SAAA;AAAA;;;;;;AJjFV;;;;;;;;ACOA;;;;;;;;;;;;;;cI0Ba,aAAA,oBAAiC,YAAA,UAAsB,SAAA,YAAqB,cAAA,CAAe,CAAA;EAAA,iBAIhD,KAAA;EAAA,QAH9C,SAAA;cAG8C,KAAA,EAAO,WAAA,CAAY,CAAA;EJ1BhE;;;;EImCT,GAAA,WAAc,UAAA,CAAW,CAAA,EAAA,CAAI,IAAA,EAAM,CAAA,GAAI,eAAA,CAAgB,CAAA,EAAG,CAAA;EJjCzB;;;;EI6CjC,GAAA,WAAc,UAAA,CAAW,CAAA,EAAA,CAAI,IAAA,EAAM,CAAA,EAAG,KAAA,EAAO,eAAA,CAAgB,CAAA,EAAG,CAAA;EJxC3B;AAkCvC;;EIcE,KAAA,CAAM,IAAA,GAAO,UAAA,CAAW,CAAA;EJbb;;;EIwBX,GAAA,CAAA,GAAO,QAAA,CAAS,CAAA;EJtBO;;;EIqCvB,GAAA,CAAI,IAAA,EAAM,UAAA,CAAW,CAAA;EAAA,QAKb,YAAA;EAAA,QAiBA,IAAA;EAAA,QASA,WAAA;EAAA,QAwBA,mBAAA;EAAA,QAIA,cAAA;EAAA,QAIA,SAAA;AAAA"}
@@ -1,15 +1,22 @@
1
- import { S as ApplicationError, b as ERROR_CODES, s as Scope } from "../errors-DSKapqD8.mjs";
2
- import { a as __decorate, d as Transient, g as DI_TOKENS } from "../logger-CGT91VY6.mjs";
3
- import { r as Module } from "../module-tUtyVJ5E.mjs";
4
- import "../events-CvUSgEuN.mjs";
5
- import "../middleware-Bl-b5pkt.mjs";
6
- import "../router-context-D9R1v2Ac.mjs";
7
- import "../colors-Y7WIFXs7.mjs";
8
- import "../command-B1CPgsrU.mjs";
9
- import "../is-command-DJVI6wEJ.mjs";
10
- import "../is-seeder-D5MIEcdz.mjs";
1
+ import { A as Scope, H as ApplicationError, k as ERROR_CODES } from "../errors-B4pYgYON.mjs";
2
+ import { a as __decorate, f as DI_TOKENS, o as __decorateParam, p as Transient, s as __decorateMetadata } from "../logger-V6Ms3QnQ.mjs";
3
+ import { t as Macroable } from "../macroable-BmufBshB.mjs";
4
+ import { C as Module } from "../module-qGE_1duv.mjs";
5
+ import { inject } from "tsyringe";
11
6
  //#region src/config/config.tokens.ts
12
- const CONFIG_TOKENS = { ConfigService: Symbol.for("stratal:config:service") };
7
+ const CONFIG_TOKENS = {
8
+ ConfigService: Symbol.for("stratal:config:service"),
9
+ ConfigStore: Symbol.for("stratal:config:store")
10
+ };
11
+ //#endregion
12
+ //#region src/config/config.types.ts
13
+ var ConfigValidationError = class extends Error {
14
+ constructor(message, errors) {
15
+ super(message);
16
+ this.errors = errors;
17
+ this.name = "ConfigValidationError";
18
+ }
19
+ };
13
20
  //#endregion
14
21
  //#region src/config/errors/config-module-not-initialized.error.ts
15
22
  /**
@@ -37,79 +44,78 @@ var ConfigNotInitializedError = class extends ApplicationError {
37
44
  }
38
45
  };
39
46
  //#endregion
40
- //#region src/config/config.types.ts
41
- var ConfigValidationError = class extends Error {
42
- constructor(message, errors) {
43
- super(message);
44
- this.errors = errors;
45
- this.name = "ConfigValidationError";
46
- }
47
- };
48
- //#endregion
49
47
  //#region src/config/services/config.service.ts
50
- let ConfigService = class ConfigService {
51
- originalConfig;
52
- currentConfig;
53
- /**
54
- * Initialize the config service with validated configuration
55
- * Called by ConfigModule during initialization
56
- */
57
- initialize(config) {
58
- this.originalConfig = this.deepClone(config);
59
- this.currentConfig = this.deepClone(config);
48
+ let ConfigService = class ConfigService extends Macroable {
49
+ overrides = /* @__PURE__ */ new Map();
50
+ constructor(store) {
51
+ super();
52
+ this.store = store;
60
53
  }
61
54
  /**
62
- * Get config value using dot notation
63
- * @example config.get('database.url')
55
+ * Get config value using dot notation. Request overrides take
56
+ * precedence over the shared store.
64
57
  */
65
58
  get(path) {
66
- this.ensureInitialized();
67
- return this.getByPath(this.currentConfig, path);
59
+ const override = this.readOverride(path);
60
+ if (override !== void 0) return override;
61
+ return this.store.get(path);
68
62
  }
69
63
  /**
70
- * Set config value at runtime (for runtime overrides)
71
- * @example config.set('email.from.name', 'Custom Name')
64
+ * Set a config value for the lifetime of the current request.
65
+ * Does not mutate the shared store.
72
66
  */
73
67
  set(path, value) {
74
- this.ensureInitialized();
75
- this.setByPath(this.currentConfig, path, value);
68
+ if (this.hasDangerousSegment(path)) return;
69
+ this.overrides.set(path, value);
76
70
  }
77
71
  /**
78
- * Reset config to original value
79
- * @param path - Optional path to reset (resets entire config if omitted)
72
+ * Clear a single override, or all overrides for this request.
80
73
  */
81
74
  reset(path) {
82
- this.ensureInitialized();
83
75
  if (path) {
84
- const originalValue = this.getByPath(this.originalConfig, path);
85
- this.setByPath(this.currentConfig, path, this.deepClone(originalValue));
86
- } else this.currentConfig = this.deepClone(this.originalConfig);
76
+ this.overrides.delete(path);
77
+ return;
78
+ }
79
+ this.overrides.clear();
87
80
  }
88
81
  /**
89
- * Get entire config object
82
+ * Get the full config object, with request overrides merged in.
90
83
  */
91
84
  all() {
92
- this.ensureInitialized();
93
- return this.currentConfig;
85
+ const base = this.store.all();
86
+ if (this.overrides.size === 0) return base;
87
+ const merged = this.deepClone(base);
88
+ for (const [path, value] of this.overrides) this.writeByPath(merged, path, value);
89
+ return merged;
94
90
  }
95
91
  /**
96
- * Check if a config path exists
92
+ * Check if a config path exists (in overrides or the store).
97
93
  */
98
94
  has(path) {
99
- this.ensureInitialized();
100
- return this.getByPath(this.currentConfig, path) !== void 0;
95
+ if (this.readOverride(path) !== void 0) return true;
96
+ return this.store.has(path);
101
97
  }
102
- getByPath(obj, path) {
103
- const keys = path.split(".");
104
- let current = obj;
98
+ readOverride(path) {
99
+ if (this.hasDangerousSegment(path)) return void 0;
100
+ if (this.overrides.has(path)) return this.overrides.get(path);
101
+ const segments = path.split(".");
102
+ for (let i = segments.length - 1; i > 0; i--) {
103
+ const parent = segments.slice(0, i).join(".");
104
+ if (this.overrides.has(parent)) {
105
+ const parentValue = this.overrides.get(parent);
106
+ return this.walk(parentValue, segments.slice(i));
107
+ }
108
+ }
109
+ }
110
+ walk(value, keys) {
111
+ let current = value;
105
112
  for (const key of keys) {
106
- if (this.isDangerousKey(key)) return void 0;
107
113
  if (current === null || current === void 0) return void 0;
108
114
  current = current[key];
109
115
  }
110
116
  return current;
111
117
  }
112
- setByPath(obj, path, value) {
118
+ writeByPath(obj, path, value) {
113
119
  const keys = path.split(".");
114
120
  if (keys.some((key) => this.isDangerousKey(key))) return;
115
121
  let current = obj;
@@ -130,18 +136,82 @@ let ConfigService = class ConfigService {
130
136
  configurable: true
131
137
  });
132
138
  }
139
+ hasDangerousSegment(path) {
140
+ return path.split(".").some((key) => this.isDangerousKey(key));
141
+ }
142
+ isDangerousKey(key) {
143
+ return key === "__proto__" || key === "constructor" || key === "prototype";
144
+ }
145
+ deepClone(obj) {
146
+ if (obj === null || typeof obj !== "object") return obj;
147
+ return JSON.parse(JSON.stringify(obj));
148
+ }
149
+ };
150
+ ConfigService = __decorate([
151
+ Transient(CONFIG_TOKENS.ConfigService),
152
+ __decorateParam(0, inject(CONFIG_TOKENS.ConfigStore)),
153
+ __decorateMetadata("design:paramtypes", [Object])
154
+ ], ConfigService);
155
+ //#endregion
156
+ //#region src/config/services/config.store.ts
157
+ let ConfigStore = class ConfigStore {
158
+ data;
159
+ /**
160
+ * Initialize the store with validated configuration.
161
+ * Called by {@link ConfigModule} during initialization.
162
+ */
163
+ initialize(config) {
164
+ this.data = this.deepClone(config);
165
+ }
166
+ /**
167
+ * Get config value using dot notation.
168
+ */
169
+ get(path) {
170
+ this.ensureInitialized();
171
+ return this.getByPath(this.data, path);
172
+ }
173
+ /**
174
+ * Check if a config path exists.
175
+ */
176
+ has(path) {
177
+ this.ensureInitialized();
178
+ return this.getByPath(this.data, path) !== void 0;
179
+ }
180
+ /**
181
+ * Get the entire config object (readonly snapshot).
182
+ */
183
+ all() {
184
+ this.ensureInitialized();
185
+ return this.data;
186
+ }
187
+ /**
188
+ * True once {@link initialize} has been called.
189
+ */
190
+ isInitialized() {
191
+ return this.data !== void 0;
192
+ }
193
+ getByPath(obj, path) {
194
+ const keys = path.split(".");
195
+ let current = obj;
196
+ for (const key of keys) {
197
+ if (this.isDangerousKey(key)) return void 0;
198
+ if (current === null || current === void 0) return void 0;
199
+ current = current[key];
200
+ }
201
+ return current;
202
+ }
133
203
  isDangerousKey(key) {
134
204
  return key === "__proto__" || key === "constructor" || key === "prototype";
135
205
  }
136
206
  ensureInitialized() {
137
- if (!this.currentConfig) throw new ConfigNotInitializedError();
207
+ if (this.data === void 0) throw new ConfigNotInitializedError();
138
208
  }
139
209
  deepClone(obj) {
140
210
  if (obj === null || typeof obj !== "object") return obj;
141
211
  return JSON.parse(JSON.stringify(obj));
142
212
  }
143
213
  };
144
- ConfigService = __decorate([Transient(CONFIG_TOKENS.ConfigService)], ConfigService);
214
+ ConfigStore = __decorate([Transient(CONFIG_TOKENS.ConfigStore)], ConfigStore);
145
215
  //#endregion
146
216
  //#region src/config/config.module.ts
147
217
  var _ConfigModule;
@@ -169,21 +239,25 @@ let ConfigModule = _ConfigModule = class ConfigModule {
169
239
  onInitialize(context) {
170
240
  if (!moduleOptions) throw new ConfigModuleNotInitializedError();
171
241
  const env = context.container.resolve(DI_TOKENS.CloudflareEnv);
172
- const configService = context.container.resolve(CONFIG_TOKENS.ConfigService);
242
+ const configStore = context.container.resolve(CONFIG_TOKENS.ConfigStore);
173
243
  const mergedConfig = {};
174
244
  for (const namespace of moduleOptions.load) mergedConfig[namespace.namespace] = namespace.factory(env);
175
245
  if (moduleOptions.validateSchema) {
176
246
  const result = moduleOptions.validateSchema.safeParse(mergedConfig);
177
247
  if (!result.success) throw new ConfigValidationError("Configuration validation failed", result.error);
178
248
  }
179
- configService.initialize(mergedConfig);
249
+ configStore.initialize(mergedConfig);
180
250
  context.logger.debug("ConfigModule initialized", { namespaces: moduleOptions.load.map((n) => n.namespace) });
181
251
  }
182
252
  };
183
253
  ConfigModule = _ConfigModule = __decorate([Module({ providers: [{
254
+ provide: CONFIG_TOKENS.ConfigStore,
255
+ useClass: ConfigStore,
256
+ scope: Scope.Singleton
257
+ }, {
184
258
  provide: CONFIG_TOKENS.ConfigService,
185
259
  useClass: ConfigService,
186
- scope: Scope.Singleton
260
+ scope: Scope.Request
187
261
  }] })], ConfigModule);
188
262
  //#endregion
189
263
  //#region src/config/register-as.ts
@@ -234,6 +308,6 @@ function registerAs(namespace, factory) {
234
308
  };
235
309
  }
236
310
  //#endregion
237
- export { CONFIG_TOKENS, ConfigModule, ConfigService, ConfigValidationError, registerAs };
311
+ export { CONFIG_TOKENS, ConfigModule, ConfigService, ConfigStore, ConfigValidationError, registerAs };
238
312
 
239
313
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/config/config.tokens.ts","../../src/config/errors/config-module-not-initialized.error.ts","../../src/config/errors/config-not-initialized.error.ts","../../src/config/config.types.ts","../../src/config/services/config.service.ts","../../src/config/config.module.ts","../../src/config/register-as.ts"],"sourcesContent":["export const CONFIG_TOKENS = {\n\tConfigService: Symbol.for('stratal:config:service'),\n} as const\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * Error thrown when ConfigModule's onInitialize runs but forRoot() was never called.\n *\n * This means the module was imported without calling ConfigModule.forRoot({ load: [...] }).\n */\nexport class ConfigModuleNotInitializedError extends ApplicationError {\n constructor() {\n super(\n 'errors.configModuleNotInitialized',\n ERROR_CODES.SYSTEM.CONFIG_MODULE_NOT_INITIALIZED\n )\n }\n}\n","import { ERROR_CODES } from '../../errors'\nimport { ApplicationError } from '../../errors'\n\n/**\n * ConfigNotInitializedError\n *\n * Thrown when attempting to access ConfigService before it has been initialized.\n * This typically indicates that ConfigModule's onInitialize hook hasn't run yet,\n * or the module wasn't registered properly.\n */\nexport class ConfigNotInitializedError extends ApplicationError {\n constructor() {\n super(\n 'errors.configNotInitialized',\n ERROR_CODES.SYSTEM.CONFIG_NOT_INITIALIZED\n )\n }\n}\n","import type { z } from '../i18n/validation'\n\nexport class ConfigValidationError extends Error {\n constructor(\n message: string,\n public readonly errors: z.ZodError\n ) {\n super(message)\n this.name = 'ConfigValidationError'\n }\n}\n\n/**\n * Configuration that can be augmented by applications\n * Apps should augment this interface with their AppConfig type using module augmentation\n *\n * @example\n * ```typescript\n * // In your app (e.g., apps/backend/src/config/types.ts)\n * declare module 'stratal' {\n * interface ModuleConfig {\n * database: { url: string; maxConnections: number }\n * email: { provider: string; from: { name: string; email: string } }\n * }\n * }\n * ```\n */\nexport interface ModuleConfig { }\n\n/**\n * Generate all valid dot-notation paths from a config object type\n * @example ConfigPath<{ database: { url: string } }> = 'database' | 'database.url'\n */\nexport type ConfigPath<T> = {\n [K in keyof T & string]: T[K] extends Record<string, unknown>\n ? K | `${K}.${ConfigPath<T[K]>}`\n : K\n}[keyof T & string]\n\n/**\n * Get the value type at a dot-notation path\n * @example ConfigPathValue<{ database: { url: string } }, 'database.url'> = string\n */\nexport type ConfigPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}`\n ? K extends keyof T\n ? T[K] extends Record<string, unknown>\n ? ConfigPathValue<T[K], Rest>\n : never\n : never\n : P extends keyof T\n ? T[P]\n : never\n\n/**\n * ConfigService interface with dot notation support\n */\nexport interface IConfigService<T extends object = ModuleConfig> {\n /**\n * Initialize the config service with validated configuration\n * Should be called once during application startup\n */\n initialize(config: T): void\n\n /**\n * Get config value using dot notation\n * @example config.get('database.url')\n */\n get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P>\n\n /**\n * Set config value at runtime (for runtime overrides)\n * @example config.set('email.from.name', 'Custom Name')\n */\n set<P extends ConfigPath<T>>(path: P, value: ConfigPathValue<T, P>): void\n\n /**\n * Reset config to original value\n * @param path - Optional path to reset (resets entire config if omitted)\n */\n reset(path?: ConfigPath<T>): void\n\n /**\n * Get entire config object\n */\n all(): Readonly<T>\n\n /**\n * Check if a config path exists\n */\n has(path: ConfigPath<T>): boolean\n}\n","import { Transient } from '../../di/decorators'\nimport { CONFIG_TOKENS } from '../config.tokens'\nimport type { ConfigPath, ConfigPathValue, IConfigService, ModuleConfig } from '../config.types'\nimport { ConfigNotInitializedError } from '../errors'\n\n/**\n * ConfigService with dot notation support for get/set operations\n *\n * Supports runtime overrides via set() - useful for request-specific config overrides.\n * Use reset() to restore original values.\n *\n * @example\n * ```typescript\n * // Get with dot notation\n * const url = config.get('database.url')\n * const fromName = config.get('email.from.name')\n *\n * // Set at runtime (e.g., in middleware for runtime override)\n * config.set('email.from.name', 'Custom Name')\n *\n * // Reset to original\n * config.reset('email.from.name') // reset specific path\n * config.reset() // reset entire config\n * ```\n */\n@Transient(CONFIG_TOKENS.ConfigService)\nexport class ConfigService<T extends object = ModuleConfig> implements IConfigService<T> {\n private originalConfig: T | undefined\n private currentConfig: T | undefined\n\n /**\n * Initialize the config service with validated configuration\n * Called by ConfigModule during initialization\n */\n initialize(config: T): void {\n this.originalConfig = this.deepClone(config)\n this.currentConfig = this.deepClone(config)\n }\n\n /**\n * Get config value using dot notation\n * @example config.get('database.url')\n */\n get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P> {\n this.ensureInitialized()\n return this.getByPath(this.currentConfig, path) as ConfigPathValue<T, P>\n }\n\n /**\n * Set config value at runtime (for runtime overrides)\n * @example config.set('email.from.name', 'Custom Name')\n */\n set<P extends ConfigPath<T>>(path: P, value: ConfigPathValue<T, P>): void {\n this.ensureInitialized()\n this.setByPath(this.currentConfig, path, value)\n }\n\n /**\n * Reset config to original value\n * @param path - Optional path to reset (resets entire config if omitted)\n */\n reset(path?: ConfigPath<T>): void {\n this.ensureInitialized()\n if (path) {\n const originalValue = this.getByPath(this.originalConfig, path)\n this.setByPath(this.currentConfig, path, this.deepClone(originalValue))\n } else {\n this.currentConfig = this.deepClone(this.originalConfig)\n }\n }\n\n /**\n * Get entire config object\n */\n all(): Readonly<T> {\n this.ensureInitialized()\n return this.currentConfig as Readonly<T>\n }\n\n /**\n * Check if a config path exists\n */\n has(path: ConfigPath<T>): boolean {\n this.ensureInitialized()\n return this.getByPath(this.currentConfig, path) !== undefined\n }\n\n private getByPath(obj: unknown, path: string): unknown {\n const keys = path.split('.')\n let current = obj\n for (const key of keys) {\n if (this.isDangerousKey(key)) return undefined\n if (current === null || current === undefined) return undefined\n current = (current as Record<string, unknown>)[key]\n }\n return current\n }\n\n private setByPath(obj: unknown, path: string, value: unknown): void {\n const keys = path.split('.')\n if (keys.some((key) => this.isDangerousKey(key))) return\n let current = obj as Record<string, unknown>\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i]\n if (!Object.hasOwn(current, key) || typeof current[key] !== 'object' || current[key] === null) {\n Object.defineProperty(current, key, {\n value: {},\n writable: true,\n enumerable: true,\n configurable: true,\n })\n }\n current = current[key] as Record<string, unknown>\n }\n Object.defineProperty(current, keys[keys.length - 1], {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n })\n }\n\n private isDangerousKey(key: string): boolean {\n return key === '__proto__' || key === 'constructor' || key === 'prototype'\n }\n\n private ensureInitialized(): void {\n if (!this.currentConfig) {\n throw new ConfigNotInitializedError()\n }\n }\n\n private deepClone<V>(obj: V): V {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n return JSON.parse(JSON.stringify(obj)) as V\n }\n}\n","import type { z } from '../i18n/validation'\nimport { ConfigModuleNotInitializedError } from './errors'\nimport { DI_TOKENS } from '../di/tokens'\nimport { Scope } from '../di/types'\nimport { Module } from '../module'\nimport type { DynamicModule, ModuleContext, OnInitialize, Provider } from '../module/types'\nimport { CONFIG_TOKENS } from './config.tokens'\nimport { ConfigValidationError, ModuleConfig } from './config.types'\nimport type { ConfigNamespace } from './register-as'\nimport { ConfigService } from './services/config.service'\n\n/**\n * Any config namespace - uses structural typing for flexibility\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyConfigNamespace = ConfigNamespace<string, any, object>\n\n/**\n * Options for ConfigModule.forRoot\n */\nexport interface ConfigModuleOptions {\n /**\n * Array of config namespaces created via registerAs()\n */\n load: AnyConfigNamespace[]\n\n /**\n * Optional Zod schema for validating the merged config\n * Validates the entire config object after all namespaces are merged\n */\n validateSchema?: z.ZodType<object>\n}\n\n// Store options for use in onInitialize\nlet moduleOptions: ConfigModuleOptions | null = null\n\n/**\n * ConfigModule\n *\n * Provides configuration management with namespace support.\n * Uses registerAs() to create typed config namespaces that can be injected.\n *\n * @example\n * ```typescript\n * // Define config namespaces\n * const databaseConfig = registerAs('database', (env) => ({\n * url: env.DATABASE_URL,\n * maxConnections: 10\n * }))\n *\n * const emailConfig = registerAs('email', (env) => ({\n * provider: env.EMAIL_PROVIDER,\n * from: { name: 'App', email: 'noreply@example.com' }\n * }))\n *\n * // Register in module\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * load: [databaseConfig, emailConfig],\n * validateSchema: AppConfigSchema\n * })\n * ]\n * })\n * export class AppModule {}\n *\n * // Inject config\n * constructor(\n * @inject(CONFIG_TOKENS.ConfigService) private config: IConfigService,\n * @inject(databaseConfig.KEY) private dbConfig: DatabaseConfig\n * ) {\n * // Use dot notation\n * const url = this.config.get('database.url')\n *\n * // Or inject namespace directly\n * const url = this.dbConfig.url\n * }\n * ```\n */\n@Module({\n providers: [\n // Register the main ConfigService as Singleton so initialization persists\n {\n provide: CONFIG_TOKENS.ConfigService,\n useClass: ConfigService,\n scope: Scope.Singleton,\n },\n ],\n})\nexport class ConfigModule implements OnInitialize {\n /**\n * Configure ConfigModule with namespace loaders\n *\n * @param options - Configuration options\n * @returns Dynamic module with config infrastructure\n */\n static forRoot(options: ConfigModuleOptions): DynamicModule {\n moduleOptions = options\n\n const providers: Provider[] = []\n\n // Register each namespace config using asProvider()\n for (const namespace of options.load) {\n providers.push(namespace.asProvider())\n }\n\n return {\n module: ConfigModule,\n providers,\n }\n }\n\n /**\n * Initialize config service with merged namespaces\n * Called after all providers are registered\n */\n onInitialize(context: ModuleContext): void {\n if (!moduleOptions) {\n throw new ConfigModuleNotInitializedError()\n }\n\n const env = context.container.resolve<unknown>(DI_TOKENS.CloudflareEnv)\n const configService = context.container.resolve<ConfigService>(CONFIG_TOKENS.ConfigService)\n\n // Build merged config from all namespaces\n const mergedConfig: Record<string, unknown> = {}\n\n for (const namespace of moduleOptions.load) {\n mergedConfig[namespace.namespace] = namespace.factory(env)\n }\n\n // Validate if schema provided\n if (moduleOptions.validateSchema) {\n const result = moduleOptions.validateSchema.safeParse(mergedConfig)\n if (!result.success) {\n throw new ConfigValidationError(\n 'Configuration validation failed',\n result.error\n )\n }\n }\n\n // Initialize ConfigService with merged config\n configService.initialize(mergedConfig as ModuleConfig)\n\n context.logger.debug('ConfigModule initialized', {\n namespaces: moduleOptions.load.map((n) => n.namespace),\n })\n }\n}\n","import type { InjectionToken } from 'tsyringe'\nimport { DI_TOKENS } from '../di/tokens'\nimport type { FactoryProvider } from '../module/types'\n\n/**\n * Configuration namespace registration result\n */\nexport interface ConfigNamespace<TKey extends string, TEnv, TConfig extends object> {\n /** Auto-derived injection token (e.g., 'database' -> Symbol('stratal:config:database')) */\n readonly KEY: InjectionToken<TConfig>\n /** The namespace key */\n readonly namespace: TKey\n /** The factory function that receives env and returns config */\n readonly factory: (env: TEnv) => TConfig\n /**\n * Returns a provider configuration for use in module registration\n * Automatically injects DI_TOKENS.CloudflareEnv\n */\n asProvider(): FactoryProvider<TConfig>\n}\n\n/**\n * Create a namespaced configuration factory\n * Similar to NestJS registerAs\n *\n * @param namespace - Configuration namespace (e.g., 'database', 'email')\n * @param factory - Factory function receiving env and returning config object\n * @returns ConfigNamespace with token, factory, and asProvider() method\n *\n * @example\n * ```typescript\n * // apps/backend/src/config/database.config.ts\n * export const databaseConfig = registerAs('database', (env: Env) => ({\n * url: env.DATABASE_URL,\n * maxConnections: parseInt(env.DATABASE_MAX_CONNECTIONS || '10'),\n * }))\n *\n * // Auto-generates: databaseConfig.KEY = Symbol('stratal:config:database')\n *\n * // Usage in module:\n * // Option 1: Manual provider\n * {\n * provide: databaseConfig.KEY,\n * useFactory: databaseConfig.factory,\n * inject: [DI_TOKENS.CloudflareEnv]\n * }\n *\n * // Option 2: asProvider() helper\n * databaseConfig.asProvider()\n * // Returns: { provide: databaseConfig.KEY, useFactory: ..., inject: [DI_TOKENS.CloudflareEnv] }\n * ```\n */\nexport function registerAs<TKey extends string, TEnv, TConfig extends object>(\n namespace: TKey,\n factory: (env: TEnv) => TConfig\n): ConfigNamespace<TKey, TEnv, TConfig> {\n const KEY = Symbol.for(`stratal:config:${namespace}`) as InjectionToken<TConfig>\n\n return {\n KEY,\n namespace,\n factory,\n asProvider(): FactoryProvider<TConfig> {\n return {\n provide: KEY,\n useFactory: factory,\n inject: [DI_TOKENS.CloudflareEnv],\n }\n },\n }\n}\n\n/**\n * Helper to derive config type from registerAs result\n *\n * @example\n * ```typescript\n * const databaseConfig = registerAs('database', (env) => ({ url: env.DATABASE_URL }))\n * type DatabaseConfig = InferConfigType<typeof databaseConfig>\n * // { url: string }\n * ```\n */\nexport type InferConfigType<T> = T extends ConfigNamespace<string, unknown, infer C> ? C : never\n"],"mappings":";;;;;;;;;;;AAAA,MAAa,gBAAgB,EAC5B,eAAe,OAAO,IAAI,yBAAyB,EACnD;;;;;;;;ACKD,IAAa,kCAAb,cAAqD,iBAAiB;CACpE,cAAc;AACZ,QACE,qCACA,YAAY,OAAO,8BACpB;;;;;;;;;;;;ACFL,IAAa,4BAAb,cAA+C,iBAAiB;CAC9D,cAAc;AACZ,QACE,+BACA,YAAY,OAAO,uBACpB;;;;;ACbL,IAAa,wBAAb,cAA2C,MAAM;CAC/C,YACE,SACA,QACA;AACA,QAAM,QAAQ;AAFE,OAAA,SAAA;AAGhB,OAAK,OAAO;;;;;ACkBT,IAAA,gBAAA,MAAM,cAA4E;CACvF;CACA;;;;;CAMA,WAAW,QAAiB;AAC1B,OAAK,iBAAiB,KAAK,UAAU,OAAO;AAC5C,OAAK,gBAAgB,KAAK,UAAU,OAAO;;;;;;CAO7C,IAA6B,MAAgC;AAC3D,OAAK,mBAAmB;AACxB,SAAO,KAAK,UAAU,KAAK,eAAe,KAAK;;;;;;CAOjD,IAA6B,MAAS,OAAoC;AACxE,OAAK,mBAAmB;AACxB,OAAK,UAAU,KAAK,eAAe,MAAM,MAAM;;;;;;CAOjD,MAAM,MAA4B;AAChC,OAAK,mBAAmB;AACxB,MAAI,MAAM;GACR,MAAM,gBAAgB,KAAK,UAAU,KAAK,gBAAgB,KAAK;AAC/D,QAAK,UAAU,KAAK,eAAe,MAAM,KAAK,UAAU,cAAc,CAAC;QAEvE,MAAK,gBAAgB,KAAK,UAAU,KAAK,eAAe;;;;;CAO5D,MAAmB;AACjB,OAAK,mBAAmB;AACxB,SAAO,KAAK;;;;;CAMd,IAAI,MAA8B;AAChC,OAAK,mBAAmB;AACxB,SAAO,KAAK,UAAU,KAAK,eAAe,KAAK,KAAK,KAAA;;CAGtD,UAAkB,KAAc,MAAuB;EACrD,MAAM,OAAO,KAAK,MAAM,IAAI;EAC5B,IAAI,UAAU;AACd,OAAK,MAAM,OAAO,MAAM;AACtB,OAAI,KAAK,eAAe,IAAI,CAAE,QAAO,KAAA;AACrC,OAAI,YAAY,QAAQ,YAAY,KAAA,EAAW,QAAO,KAAA;AACtD,aAAW,QAAoC;;AAEjD,SAAO;;CAGT,UAAkB,KAAc,MAAc,OAAsB;EAClE,MAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,MAAI,KAAK,MAAM,QAAQ,KAAK,eAAe,IAAI,CAAC,CAAE;EAClD,IAAI,UAAU;AACd,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;GACxC,MAAM,MAAM,KAAK;AACjB,OAAI,CAAC,OAAO,OAAO,SAAS,IAAI,IAAI,OAAO,QAAQ,SAAS,YAAY,QAAQ,SAAS,KACvF,QAAO,eAAe,SAAS,KAAK;IAClC,OAAO,EAAE;IACT,UAAU;IACV,YAAY;IACZ,cAAc;IACf,CAAC;AAEJ,aAAU,QAAQ;;AAEpB,SAAO,eAAe,SAAS,KAAK,KAAK,SAAS,IAAI;GACpD;GACA,UAAU;GACV,YAAY;GACZ,cAAc;GACf,CAAC;;CAGJ,eAAuB,KAAsB;AAC3C,SAAO,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ;;CAGjE,oBAAkC;AAChC,MAAI,CAAC,KAAK,cACR,OAAM,IAAI,2BAA2B;;CAIzC,UAAqB,KAAW;AAC9B,MAAI,QAAQ,QAAQ,OAAO,QAAQ,SACjC,QAAO;AAET,SAAO,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;;;4BA/GzC,UAAU,cAAc,cAAc,CAAA,EAAA,cAAA;;;;ACSvC,IAAI,gBAA4C;AAuDzC,IAAA,eAAA,gBAAA,MAAM,aAAqC;;;;;;;CAOhD,OAAO,QAAQ,SAA6C;AAC1D,kBAAgB;EAEhB,MAAM,YAAwB,EAAE;AAGhC,OAAK,MAAM,aAAa,QAAQ,KAC9B,WAAU,KAAK,UAAU,YAAY,CAAC;AAGxC,SAAO;GACL,QAAA;GACA;GACD;;;;;;CAOH,aAAa,SAA8B;AACzC,MAAI,CAAC,cACH,OAAM,IAAI,iCAAiC;EAG7C,MAAM,MAAM,QAAQ,UAAU,QAAiB,UAAU,cAAc;EACvE,MAAM,gBAAgB,QAAQ,UAAU,QAAuB,cAAc,cAAc;EAG3F,MAAM,eAAwC,EAAE;AAEhD,OAAK,MAAM,aAAa,cAAc,KACpC,cAAa,UAAU,aAAa,UAAU,QAAQ,IAAI;AAI5D,MAAI,cAAc,gBAAgB;GAChC,MAAM,SAAS,cAAc,eAAe,UAAU,aAAa;AACnE,OAAI,CAAC,OAAO,QACV,OAAM,IAAI,sBACR,mCACA,OAAO,MACR;;AAKL,gBAAc,WAAW,aAA6B;AAEtD,UAAQ,OAAO,MAAM,4BAA4B,EAC/C,YAAY,cAAc,KAAK,KAAK,MAAM,EAAE,UAAU,EACvD,CAAC;;;2CApEL,OAAO,EACN,WAAW,CAET;CACE,SAAS,cAAc;CACvB,UAAU;CACV,OAAO,MAAM;CACd,CACF,EACF,CAAC,CAAA,EAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpCF,SAAgB,WACd,WACA,SACsC;CACtC,MAAM,MAAM,OAAO,IAAI,kBAAkB,YAAY;AAErD,QAAO;EACL;EACA;EACA;EACA,aAAuC;AACrC,UAAO;IACL,SAAS;IACT,YAAY;IACZ,QAAQ,CAAC,UAAU,cAAc;IAClC;;EAEJ"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/config/config.tokens.ts","../../src/config/config.types.ts","../../src/config/errors/config-module-not-initialized.error.ts","../../src/config/errors/config-not-initialized.error.ts","../../src/config/services/config.service.ts","../../src/config/services/config.store.ts","../../src/config/config.module.ts","../../src/config/register-as.ts"],"sourcesContent":["export const CONFIG_TOKENS = {\n\tConfigService: Symbol.for('stratal:config:service'),\n\tConfigStore: Symbol.for('stratal:config:store'),\n} as const\n","import type { z } from '../i18n/validation'\n\nexport class ConfigValidationError extends Error {\n constructor(\n message: string,\n public readonly errors: z.ZodError\n ) {\n super(message)\n this.name = 'ConfigValidationError'\n }\n}\n\n/**\n * Configuration that can be augmented by applications\n * Apps should augment this interface with their AppConfig type using module augmentation\n *\n * @example\n * ```typescript\n * // In your app (e.g., apps/backend/src/config/types.ts)\n * declare module 'stratal' {\n * interface ModuleConfig {\n * database: { url: string; maxConnections: number }\n * email: { provider: string; from: { name: string; email: string } }\n * }\n * }\n * ```\n */\nexport interface ModuleConfig { }\n\n/**\n * Generate all valid dot-notation paths from a config object type\n * @example ConfigPath<{ database: { url: string } }> = 'database' | 'database.url'\n */\nexport type ConfigPath<T> = {\n [K in keyof T & string]: T[K] extends Record<string, unknown>\n ? K | `${K}.${ConfigPath<T[K]>}`\n : K\n}[keyof T & string]\n\n/**\n * Get the value type at a dot-notation path\n * @example ConfigPathValue<{ database: { url: string } }, 'database.url'> = string\n */\nexport type ConfigPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}`\n ? K extends keyof T\n ? T[K] extends Record<string, unknown>\n ? ConfigPathValue<T[K], Rest>\n : never\n : never\n : P extends keyof T\n ? T[P]\n : never\n\n/**\n * ConfigService interface with dot notation support.\n *\n * Values are initialized on the underlying {@link ConfigStore} via\n * {@link ConfigModule}; the service itself exposes request-scoped\n * reads and per-request overrides.\n */\nexport interface IConfigService<T extends object = ModuleConfig> {\n /**\n * Get config value using dot notation\n * @example config.get('database.url')\n */\n get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P>\n\n /**\n * Set config value at runtime (for runtime overrides)\n * @example config.set('email.from.name', 'Custom Name')\n */\n set<P extends ConfigPath<T>>(path: P, value: ConfigPathValue<T, P>): void\n\n /**\n * Reset config to original value\n * @param path - Optional path to reset (resets entire config if omitted)\n */\n reset(path?: ConfigPath<T>): void\n\n /**\n * Get entire config object\n */\n all(): Readonly<T>\n\n /**\n * Check if a config path exists\n */\n has(path: ConfigPath<T>): boolean\n}\n","import { ApplicationError, ERROR_CODES } from '../../errors'\n\n/**\n * Error thrown when ConfigModule's onInitialize runs but forRoot() was never called.\n *\n * This means the module was imported without calling ConfigModule.forRoot({ load: [...] }).\n */\nexport class ConfigModuleNotInitializedError extends ApplicationError {\n constructor() {\n super(\n 'errors.configModuleNotInitialized',\n ERROR_CODES.SYSTEM.CONFIG_MODULE_NOT_INITIALIZED\n )\n }\n}\n","import { ERROR_CODES } from '../../errors'\nimport { ApplicationError } from '../../errors'\n\n/**\n * ConfigNotInitializedError\n *\n * Thrown when attempting to access ConfigService before it has been initialized.\n * This typically indicates that ConfigModule's onInitialize hook hasn't run yet,\n * or the module wasn't registered properly.\n */\nexport class ConfigNotInitializedError extends ApplicationError {\n constructor() {\n super(\n 'errors.configNotInitialized',\n ERROR_CODES.SYSTEM.CONFIG_NOT_INITIALIZED\n )\n }\n}\n","import { inject } from 'tsyringe'\nimport { Transient } from '../../di/decorators'\nimport { Macroable } from '../../macroable/macroable'\nimport { CONFIG_TOKENS } from '../config.tokens'\nimport type { ConfigPath, ConfigPathValue, IConfigService, ModuleConfig } from '../config.types'\nimport { type ConfigStore } from './config.store'\n\n/**\n * ConfigService with dot notation support and per-request overrides.\n *\n * ConfigService is **request-scoped**: each request gets its own\n * instance with a private `overrides` map layered over the shared\n * {@link ConfigStore}. Calls to {@link set} mutate only the current\n * request's overrides, which makes it safe to mutate config from\n * middleware (e.g. to pin `environment.appUrl` to the request host).\n *\n * Extends {@link Macroable} so apps can add domain-specific getters\n * and methods via `ConfigService.getter()` / `ConfigService.macro()`.\n *\n * @example\n * ```typescript\n * // Read with dot notation\n * const url = config.get('database.url')\n * const fromName = config.get('email.from.name')\n *\n * // Per-request override (e.g. in middleware)\n * config.set('environment.appUrl', `${proto}://${host}`)\n *\n * // Reset the override for the current request\n * config.reset('environment.appUrl')\n * ```\n */\n@Transient(CONFIG_TOKENS.ConfigService)\nexport class ConfigService<T extends object = ModuleConfig> extends Macroable implements IConfigService<T> {\n private overrides = new Map<string, unknown>()\n\n constructor(\n @inject(CONFIG_TOKENS.ConfigStore) private readonly store: ConfigStore<T>,\n ) {\n super()\n }\n\n /**\n * Get config value using dot notation. Request overrides take\n * precedence over the shared store.\n */\n get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P> {\n const override = this.readOverride(path)\n if (override !== undefined) {\n return override as ConfigPathValue<T, P>\n }\n return this.store.get(path)\n }\n\n /**\n * Set a config value for the lifetime of the current request.\n * Does not mutate the shared store.\n */\n set<P extends ConfigPath<T>>(path: P, value: ConfigPathValue<T, P>): void {\n if (this.hasDangerousSegment(path)) return\n this.overrides.set(path, value)\n }\n\n /**\n * Clear a single override, or all overrides for this request.\n */\n reset(path?: ConfigPath<T>): void {\n if (path) {\n this.overrides.delete(path)\n return\n }\n this.overrides.clear()\n }\n\n /**\n * Get the full config object, with request overrides merged in.\n */\n all(): Readonly<T> {\n const base = this.store.all() as T\n if (this.overrides.size === 0) {\n return base as Readonly<T>\n }\n const merged = this.deepClone(base)\n for (const [path, value] of this.overrides) {\n this.writeByPath(merged, path, value)\n }\n return merged as Readonly<T>\n }\n\n /**\n * Check if a config path exists (in overrides or the store).\n */\n has(path: ConfigPath<T>): boolean {\n if (this.readOverride(path) !== undefined) return true\n return this.store.has(path)\n }\n\n private readOverride(path: string): unknown {\n if (this.hasDangerousSegment(path)) return undefined\n if (this.overrides.has(path)) {\n return this.overrides.get(path)\n }\n // Support partial-path reads: if an ancestor was overridden, walk into it.\n const segments = path.split('.')\n for (let i = segments.length - 1; i > 0; i--) {\n const parent = segments.slice(0, i).join('.')\n if (this.overrides.has(parent)) {\n const parentValue = this.overrides.get(parent)\n return this.walk(parentValue, segments.slice(i))\n }\n }\n return undefined\n }\n\n private walk(value: unknown, keys: string[]): unknown {\n let current = value\n for (const key of keys) {\n if (current === null || current === undefined) return undefined\n current = (current as Record<string, unknown>)[key]\n }\n return current\n }\n\n private writeByPath(obj: unknown, path: string, value: unknown): void {\n const keys = path.split('.')\n if (keys.some((key) => this.isDangerousKey(key))) return\n let current = obj as Record<string, unknown>\n for (let i = 0; i < keys.length - 1; i++) {\n const key = keys[i]\n if (!Object.hasOwn(current, key) || typeof current[key] !== 'object' || current[key] === null) {\n Object.defineProperty(current, key, {\n value: {},\n writable: true,\n enumerable: true,\n configurable: true,\n })\n }\n current = current[key] as Record<string, unknown>\n }\n Object.defineProperty(current, keys[keys.length - 1], {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n })\n }\n\n private hasDangerousSegment(path: string): boolean {\n return path.split('.').some((key) => this.isDangerousKey(key))\n }\n\n private isDangerousKey(key: string): boolean {\n return key === '__proto__' || key === 'constructor' || key === 'prototype'\n }\n\n private deepClone<V>(obj: V): V {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n return JSON.parse(JSON.stringify(obj)) as V\n }\n}\n","import { Transient } from '../../di/decorators'\nimport { CONFIG_TOKENS } from '../config.tokens'\nimport type { ConfigPath, ConfigPathValue, ModuleConfig } from '../config.types'\nimport { ConfigNotInitializedError } from '../errors'\n\n/**\n * ConfigStore\n *\n * Singleton-scoped holder of validated, merged configuration.\n *\n * ConfigStore is the source of truth for configuration values. It is\n * initialized once during application startup by {@link ConfigModule}\n * and never mutated afterwards.\n *\n * Per-request overrides live on {@link ConfigService}, which reads\n * through to this store for any key not explicitly overridden.\n */\n@Transient(CONFIG_TOKENS.ConfigStore)\nexport class ConfigStore<T extends object = ModuleConfig> {\n private data: T | undefined\n\n /**\n * Initialize the store with validated configuration.\n * Called by {@link ConfigModule} during initialization.\n */\n initialize(config: T): void {\n this.data = this.deepClone(config)\n }\n\n /**\n * Get config value using dot notation.\n */\n get<P extends ConfigPath<T>>(path: P): ConfigPathValue<T, P> {\n this.ensureInitialized()\n return this.getByPath(this.data, path) as ConfigPathValue<T, P>\n }\n\n /**\n * Check if a config path exists.\n */\n has(path: ConfigPath<T>): boolean {\n this.ensureInitialized()\n return this.getByPath(this.data, path) !== undefined\n }\n\n /**\n * Get the entire config object (readonly snapshot).\n */\n all(): Readonly<T> {\n this.ensureInitialized()\n return this.data as Readonly<T>\n }\n\n /**\n * True once {@link initialize} has been called.\n */\n isInitialized(): boolean {\n return this.data !== undefined\n }\n\n private getByPath(obj: unknown, path: string): unknown {\n const keys = path.split('.')\n let current = obj\n for (const key of keys) {\n if (this.isDangerousKey(key)) return undefined\n if (current === null || current === undefined) return undefined\n current = (current as Record<string, unknown>)[key]\n }\n return current\n }\n\n private isDangerousKey(key: string): boolean {\n return key === '__proto__' || key === 'constructor' || key === 'prototype'\n }\n\n private ensureInitialized(): void {\n if (this.data === undefined) {\n throw new ConfigNotInitializedError()\n }\n }\n\n private deepClone<V>(obj: V): V {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n return JSON.parse(JSON.stringify(obj)) as V\n }\n}\n","import { DI_TOKENS } from '../di/tokens'\nimport { Scope } from '../di/types'\nimport type { z } from '../i18n/validation'\nimport { Module } from '../module'\nimport type { DynamicModule, ModuleContext, OnInitialize, Provider } from '../module/types'\nimport { CONFIG_TOKENS } from './config.tokens'\nimport { ConfigValidationError, type ModuleConfig } from './config.types'\nimport { ConfigModuleNotInitializedError } from './errors'\nimport type { ConfigNamespace } from './register-as'\nimport { ConfigService } from './services/config.service'\nimport { ConfigStore } from './services/config.store'\n\n/**\n * Any config namespace - uses structural typing for flexibility\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type AnyConfigNamespace = ConfigNamespace<string, any, object>\n\n/**\n * Options for ConfigModule.forRoot\n */\nexport interface ConfigModuleOptions {\n /**\n * Array of config namespaces created via registerAs()\n */\n load: AnyConfigNamespace[]\n\n /**\n * Optional Zod schema for validating the merged config\n * Validates the entire config object after all namespaces are merged\n */\n validateSchema?: z.ZodType<object>\n}\n\n// Store options for use in onInitialize\nlet moduleOptions: ConfigModuleOptions | null = null\n\n/**\n * ConfigModule\n *\n * Provides configuration management with namespace support.\n * Uses registerAs() to create typed config namespaces that can be injected.\n *\n * @example\n * ```typescript\n * // Define config namespaces\n * const databaseConfig = registerAs('database', (env) => ({\n * url: env.DATABASE_URL,\n * maxConnections: 10\n * }))\n *\n * const emailConfig = registerAs('email', (env) => ({\n * provider: env.EMAIL_PROVIDER,\n * from: { name: 'App', email: 'noreply@example.com' }\n * }))\n *\n * // Register in module\n * @Module({\n * imports: [\n * ConfigModule.forRoot({\n * load: [databaseConfig, emailConfig],\n * validateSchema: AppConfigSchema\n * })\n * ]\n * })\n * export class AppModule {}\n *\n * // Inject config\n * constructor(\n * @inject(CONFIG_TOKENS.ConfigService) private config: IConfigService,\n * @inject(databaseConfig.KEY) private dbConfig: DatabaseConfig\n * ) {\n * // Use dot notation\n * const url = this.config.get('database.url')\n *\n * // Or inject namespace directly\n * const url = this.dbConfig.url\n * }\n * ```\n */\n@Module({\n providers: [\n // ConfigStore is the singleton source of truth for validated config.\n {\n provide: CONFIG_TOKENS.ConfigStore,\n useClass: ConfigStore,\n scope: Scope.Singleton,\n },\n // ConfigService is request-scoped: each request gets its own\n // overrides map layered over the shared ConfigStore.\n {\n provide: CONFIG_TOKENS.ConfigService,\n useClass: ConfigService,\n scope: Scope.Request,\n },\n ],\n})\nexport class ConfigModule implements OnInitialize {\n /**\n * Configure ConfigModule with namespace loaders\n *\n * @param options - Configuration options\n * @returns Dynamic module with config infrastructure\n */\n static forRoot(options: ConfigModuleOptions): DynamicModule {\n moduleOptions = options\n\n const providers: Provider[] = []\n\n // Register each namespace config using asProvider()\n for (const namespace of options.load) {\n providers.push(namespace.asProvider())\n }\n\n return {\n module: ConfigModule,\n providers,\n }\n }\n\n /**\n * Initialize config service with merged namespaces\n * Called after all providers are registered\n */\n onInitialize(context: ModuleContext): void {\n if (!moduleOptions) {\n throw new ConfigModuleNotInitializedError()\n }\n\n const env = context.container.resolve<unknown>(DI_TOKENS.CloudflareEnv)\n const configStore = context.container.resolve<ConfigStore>(CONFIG_TOKENS.ConfigStore)\n\n // Build merged config from all namespaces\n const mergedConfig: Record<string, unknown> = {}\n\n for (const namespace of moduleOptions.load) {\n mergedConfig[namespace.namespace] = namespace.factory(env)\n }\n\n // Validate if schema provided\n if (moduleOptions.validateSchema) {\n const result = moduleOptions.validateSchema.safeParse(mergedConfig)\n if (!result.success) {\n throw new ConfigValidationError(\n 'Configuration validation failed',\n result.error\n )\n }\n }\n\n // Initialize the shared ConfigStore with merged config.\n configStore.initialize(mergedConfig as ModuleConfig)\n\n context.logger.debug('ConfigModule initialized', {\n namespaces: moduleOptions.load.map((n) => n.namespace),\n })\n }\n}\n","import type { InjectionToken } from 'tsyringe'\nimport { DI_TOKENS } from '../di/tokens'\nimport type { FactoryProvider } from '../module/types'\n\n/**\n * Configuration namespace registration result\n */\nexport interface ConfigNamespace<TKey extends string, TEnv, TConfig extends object> {\n /** Auto-derived injection token (e.g., 'database' -> Symbol('stratal:config:database')) */\n readonly KEY: InjectionToken<TConfig>\n /** The namespace key */\n readonly namespace: TKey\n /** The factory function that receives env and returns config */\n readonly factory: (env: TEnv) => TConfig\n /**\n * Returns a provider configuration for use in module registration\n * Automatically injects DI_TOKENS.CloudflareEnv\n */\n asProvider(): FactoryProvider<TConfig>\n}\n\n/**\n * Create a namespaced configuration factory\n * Similar to NestJS registerAs\n *\n * @param namespace - Configuration namespace (e.g., 'database', 'email')\n * @param factory - Factory function receiving env and returning config object\n * @returns ConfigNamespace with token, factory, and asProvider() method\n *\n * @example\n * ```typescript\n * // apps/backend/src/config/database.config.ts\n * export const databaseConfig = registerAs('database', (env: Env) => ({\n * url: env.DATABASE_URL,\n * maxConnections: parseInt(env.DATABASE_MAX_CONNECTIONS || '10'),\n * }))\n *\n * // Auto-generates: databaseConfig.KEY = Symbol('stratal:config:database')\n *\n * // Usage in module:\n * // Option 1: Manual provider\n * {\n * provide: databaseConfig.KEY,\n * useFactory: databaseConfig.factory,\n * inject: [DI_TOKENS.CloudflareEnv]\n * }\n *\n * // Option 2: asProvider() helper\n * databaseConfig.asProvider()\n * // Returns: { provide: databaseConfig.KEY, useFactory: ..., inject: [DI_TOKENS.CloudflareEnv] }\n * ```\n */\nexport function registerAs<TKey extends string, TEnv, TConfig extends object>(\n namespace: TKey,\n factory: (env: TEnv) => TConfig\n): ConfigNamespace<TKey, TEnv, TConfig> {\n const KEY = Symbol.for(`stratal:config:${namespace}`) as InjectionToken<TConfig>\n\n return {\n KEY,\n namespace,\n factory,\n asProvider(): FactoryProvider<TConfig> {\n return {\n provide: KEY,\n useFactory: factory,\n inject: [DI_TOKENS.CloudflareEnv],\n }\n },\n }\n}\n\n/**\n * Helper to derive config type from registerAs result\n *\n * @example\n * ```typescript\n * const databaseConfig = registerAs('database', (env) => ({ url: env.DATABASE_URL }))\n * type DatabaseConfig = InferConfigType<typeof databaseConfig>\n * // { url: string }\n * ```\n */\nexport type InferConfigType<T> = T extends ConfigNamespace<string, unknown, infer C> ? C : never\n"],"mappings":";;;;;;AAAA,MAAa,gBAAgB;CAC5B,eAAe,OAAO,IAAI,yBAAyB;CACnD,aAAa,OAAO,IAAI,uBAAuB;CAC/C;;;ACDD,IAAa,wBAAb,cAA2C,MAAM;CAC/C,YACE,SACA,QACA;AACA,QAAM,QAAQ;AAFE,OAAA,SAAA;AAGhB,OAAK,OAAO;;;;;;;;;;ACDhB,IAAa,kCAAb,cAAqD,iBAAiB;CACpE,cAAc;AACZ,QACE,qCACA,YAAY,OAAO,8BACpB;;;;;;;;;;;;ACFL,IAAa,4BAAb,cAA+C,iBAAiB;CAC9D,cAAc;AACZ,QACE,+BACA,YAAY,OAAO,uBACpB;;;;;ACkBE,IAAA,gBAAA,MAAM,sBAAuD,UAAuC;CACzG,4BAAoB,IAAI,KAAsB;CAE9C,YACE,OACA;AACA,SAAO;AAF6C,OAAA,QAAA;;;;;;CAStD,IAA6B,MAAgC;EAC3D,MAAM,WAAW,KAAK,aAAa,KAAK;AACxC,MAAI,aAAa,KAAA,EACf,QAAO;AAET,SAAO,KAAK,MAAM,IAAI,KAAK;;;;;;CAO7B,IAA6B,MAAS,OAAoC;AACxE,MAAI,KAAK,oBAAoB,KAAK,CAAE;AACpC,OAAK,UAAU,IAAI,MAAM,MAAM;;;;;CAMjC,MAAM,MAA4B;AAChC,MAAI,MAAM;AACR,QAAK,UAAU,OAAO,KAAK;AAC3B;;AAEF,OAAK,UAAU,OAAO;;;;;CAMxB,MAAmB;EACjB,MAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,MAAI,KAAK,UAAU,SAAS,EAC1B,QAAO;EAET,MAAM,SAAS,KAAK,UAAU,KAAK;AACnC,OAAK,MAAM,CAAC,MAAM,UAAU,KAAK,UAC/B,MAAK,YAAY,QAAQ,MAAM,MAAM;AAEvC,SAAO;;;;;CAMT,IAAI,MAA8B;AAChC,MAAI,KAAK,aAAa,KAAK,KAAK,KAAA,EAAW,QAAO;AAClD,SAAO,KAAK,MAAM,IAAI,KAAK;;CAG7B,aAAqB,MAAuB;AAC1C,MAAI,KAAK,oBAAoB,KAAK,CAAE,QAAO,KAAA;AAC3C,MAAI,KAAK,UAAU,IAAI,KAAK,CAC1B,QAAO,KAAK,UAAU,IAAI,KAAK;EAGjC,MAAM,WAAW,KAAK,MAAM,IAAI;AAChC,OAAK,IAAI,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,KAAK;GAC5C,MAAM,SAAS,SAAS,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI;AAC7C,OAAI,KAAK,UAAU,IAAI,OAAO,EAAE;IAC9B,MAAM,cAAc,KAAK,UAAU,IAAI,OAAO;AAC9C,WAAO,KAAK,KAAK,aAAa,SAAS,MAAM,EAAE,CAAC;;;;CAMtD,KAAa,OAAgB,MAAyB;EACpD,IAAI,UAAU;AACd,OAAK,MAAM,OAAO,MAAM;AACtB,OAAI,YAAY,QAAQ,YAAY,KAAA,EAAW,QAAO,KAAA;AACtD,aAAW,QAAoC;;AAEjD,SAAO;;CAGT,YAAoB,KAAc,MAAc,OAAsB;EACpE,MAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,MAAI,KAAK,MAAM,QAAQ,KAAK,eAAe,IAAI,CAAC,CAAE;EAClD,IAAI,UAAU;AACd,OAAK,IAAI,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;GACxC,MAAM,MAAM,KAAK;AACjB,OAAI,CAAC,OAAO,OAAO,SAAS,IAAI,IAAI,OAAO,QAAQ,SAAS,YAAY,QAAQ,SAAS,KACvF,QAAO,eAAe,SAAS,KAAK;IAClC,OAAO,EAAE;IACT,UAAU;IACV,YAAY;IACZ,cAAc;IACf,CAAC;AAEJ,aAAU,QAAQ;;AAEpB,SAAO,eAAe,SAAS,KAAK,KAAK,SAAS,IAAI;GACpD;GACA,UAAU;GACV,YAAY;GACZ,cAAc;GACf,CAAC;;CAGJ,oBAA4B,MAAuB;AACjD,SAAO,KAAK,MAAM,IAAI,CAAC,MAAM,QAAQ,KAAK,eAAe,IAAI,CAAC;;CAGhE,eAAuB,KAAsB;AAC3C,SAAO,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ;;CAGjE,UAAqB,KAAW;AAC9B,MAAI,QAAQ,QAAQ,OAAO,QAAQ,SACjC,QAAO;AAET,SAAO,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;;;;CA/HzC,UAAU,cAAc,cAAc;oBAKlC,OAAO,cAAc,YAAY,CAAA;;;;;ACnB/B,IAAA,cAAA,MAAM,YAA6C;CACxD;;;;;CAMA,WAAW,QAAiB;AAC1B,OAAK,OAAO,KAAK,UAAU,OAAO;;;;;CAMpC,IAA6B,MAAgC;AAC3D,OAAK,mBAAmB;AACxB,SAAO,KAAK,UAAU,KAAK,MAAM,KAAK;;;;;CAMxC,IAAI,MAA8B;AAChC,OAAK,mBAAmB;AACxB,SAAO,KAAK,UAAU,KAAK,MAAM,KAAK,KAAK,KAAA;;;;;CAM7C,MAAmB;AACjB,OAAK,mBAAmB;AACxB,SAAO,KAAK;;;;;CAMd,gBAAyB;AACvB,SAAO,KAAK,SAAS,KAAA;;CAGvB,UAAkB,KAAc,MAAuB;EACrD,MAAM,OAAO,KAAK,MAAM,IAAI;EAC5B,IAAI,UAAU;AACd,OAAK,MAAM,OAAO,MAAM;AACtB,OAAI,KAAK,eAAe,IAAI,CAAE,QAAO,KAAA;AACrC,OAAI,YAAY,QAAQ,YAAY,KAAA,EAAW,QAAO,KAAA;AACtD,aAAW,QAAoC;;AAEjD,SAAO;;CAGT,eAAuB,KAAsB;AAC3C,SAAO,QAAQ,eAAe,QAAQ,iBAAiB,QAAQ;;CAGjE,oBAAkC;AAChC,MAAI,KAAK,SAAS,KAAA,EAChB,OAAM,IAAI,2BAA2B;;CAIzC,UAAqB,KAAW;AAC9B,MAAI,QAAQ,QAAQ,OAAO,QAAQ,SACjC,QAAO;AAET,SAAO,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;;;0BApEzC,UAAU,cAAc,YAAY,CAAA,EAAA,YAAA;;;;ACkBrC,IAAI,gBAA4C;AA8DzC,IAAA,eAAA,gBAAA,MAAM,aAAqC;;;;;;;CAOhD,OAAO,QAAQ,SAA6C;AAC1D,kBAAgB;EAEhB,MAAM,YAAwB,EAAE;AAGhC,OAAK,MAAM,aAAa,QAAQ,KAC9B,WAAU,KAAK,UAAU,YAAY,CAAC;AAGxC,SAAO;GACL,QAAA;GACA;GACD;;;;;;CAOH,aAAa,SAA8B;AACzC,MAAI,CAAC,cACH,OAAM,IAAI,iCAAiC;EAG7C,MAAM,MAAM,QAAQ,UAAU,QAAiB,UAAU,cAAc;EACvE,MAAM,cAAc,QAAQ,UAAU,QAAqB,cAAc,YAAY;EAGrF,MAAM,eAAwC,EAAE;AAEhD,OAAK,MAAM,aAAa,cAAc,KACpC,cAAa,UAAU,aAAa,UAAU,QAAQ,IAAI;AAI5D,MAAI,cAAc,gBAAgB;GAChC,MAAM,SAAS,cAAc,eAAe,UAAU,aAAa;AACnE,OAAI,CAAC,OAAO,QACV,OAAM,IAAI,sBACR,mCACA,OAAO,MACR;;AAKL,cAAY,WAAW,aAA6B;AAEpD,UAAQ,OAAO,MAAM,4BAA4B,EAC/C,YAAY,cAAc,KAAK,KAAK,MAAM,EAAE,UAAU,EACvD,CAAC;;;2CA3EL,OAAO,EACN,WAAW,CAET;CACE,SAAS,cAAc;CACvB,UAAU;CACV,OAAO,MAAM;CACd,EAGD;CACE,SAAS,cAAc;CACvB,UAAU;CACV,OAAO,MAAM;CACd,CACF,EACF,CAAC,CAAA,EAAA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5CF,SAAgB,WACd,WACA,SACsC;CACtC,MAAM,MAAM,OAAO,IAAI,kBAAkB,YAAY;AAErD,QAAO;EACL;EACA;EACA;EACA,aAAuC;AACrC,UAAO;IACL,SAAS;IACT,YAAY;IACZ,QAAQ,CAAC,UAAU,cAAc;IAClC;;EAEJ"}
@@ -139,4 +139,4 @@ declare class ConsumerRegistry {
139
139
  }
140
140
  //#endregion
141
141
  export { IQueueConsumer as n, QueueMessage as r, ConsumerRegistry as t };
142
- //# sourceMappingURL=consumer-registry-Bymm6ff4.d.mts.map
142
+ //# sourceMappingURL=consumer-registry-Doom7BEh.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consumer-registry-Bymm6ff4.d.mts","names":[],"sources":["../src/queue/queue-consumer.ts","../src/queue/consumer-registry.ts"],"mappings":";;AAMA;;;;;UAAiB,YAAA;EAIf;EAFA,EAAA;EAMA;EAJA,SAAA;EAMA;EAJA,IAAA;EAMG;EAJH,OAAA,EAAS,CAAA;EAIK;EAFd,QAAA;IACE,MAAA;IAAA,CACC,GAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;UAsBY,cAAA;EAsBQ;;;;;;EAAA,SAfd,YAAA;ECXE;;;;;EDkBX,MAAA,CAAO,OAAA,EAAS,YAAA,CAAa,CAAA,IAAK,OAAA;ECqDD;;;;;;ED7CjC,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,YAAA,CAAa,CAAA,IAAK,OAAA;AAAA;;;AAxDpD;;;;;;;;;;;;;;;AAkCA;;;;;;;;;;;;;;;;AAlCA,cC8Ba,gBAAA;EDkBJ;EAAA,QChBC,eAAA;EDwBR;EAAA,QCrBQ,YAAA;EDqBC;;;;;;;ECZT,QAAA,CAAS,QAAA,EAAU,cAAA;;;AAfrB;;;;;;;;EAuCE,YAAA,CAAa,WAAA,WAAsB,cAAA;EAjC3B;;;;;;EAgDR,YAAA,CAAa,WAAA;EAAb;;;;;EASA,eAAA,CAAA;EASiC;;;;;EAAjC,eAAA,CAAA,GAAmB,cAAA;AAAA"}
1
+ {"version":3,"file":"consumer-registry-Doom7BEh.d.mts","names":[],"sources":["../src/queue/queue-consumer.ts","../src/queue/consumer-registry.ts"],"mappings":";;AAMA;;;;;UAAiB,YAAA;EAIf;EAFA,EAAA;EAMA;EAJA,SAAA;EAMA;EAJA,IAAA;EAMG;EAJH,OAAA,EAAS,CAAA;EAIK;EAFd,QAAA;IACE,MAAA;IAAA,CACC,GAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;UAsBY,cAAA;EAsBQ;;;;;;EAAA,SAfd,YAAA;ECXE;;;;;EDkBX,MAAA,CAAO,OAAA,EAAS,YAAA,CAAa,CAAA,IAAK,OAAA;ECqDD;;;;;;ED7CjC,OAAA,EAAS,KAAA,EAAO,KAAA,EAAO,OAAA,EAAS,YAAA,CAAa,CAAA,IAAK,OAAA;AAAA;;;AAxDpD;;;;;;;;;;;;;;;AAkCA;;;;;;;;;;;;;;;;AAlCA,cC8Ba,gBAAA;EDkBJ;EAAA,QChBC,eAAA;EDwBR;EAAA,QCrBQ,YAAA;EDqBC;;;;;;;ECZT,QAAA,CAAS,QAAA,EAAU,cAAA;;;AAfrB;;;;;;;;EAuCE,YAAA,CAAa,WAAA,WAAsB,cAAA;EAjC3B;;;;;;EAgDR,YAAA,CAAa,WAAA;EAAb;;;;;EASA,eAAA,CAAA;EASiC;;;;;EAAjC,eAAA,CAAA,GAAmB,cAAA;AAAA"}