stratal 0.0.23 → 0.0.25

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 (123) hide show
  1. package/dist/cache/index.d.mts +1 -1
  2. package/dist/cache/index.mjs +2 -2
  3. package/dist/{command-CPhFHjG3.d.mts → command-4HnKnC-G.d.mts} +2 -2
  4. package/dist/{command-CPhFHjG3.d.mts.map → command-4HnKnC-G.d.mts.map} +1 -1
  5. package/dist/config/index.d.mts +1 -1
  6. package/dist/config/index.mjs +2 -2
  7. package/dist/{controller.decorator-C5UVeJS3.mjs → controller.decorator-DKeZ71aP.mjs} +3 -3
  8. package/dist/{controller.decorator-C5UVeJS3.mjs.map → controller.decorator-DKeZ71aP.mjs.map} +1 -1
  9. package/dist/cron/index.d.mts +1 -1
  10. package/dist/cron/index.mjs +1 -1
  11. package/dist/{cron.module-Bgzq5hiT.mjs → cron.module-DgxLe8Xy.mjs} +3 -3
  12. package/dist/{cron.module-Bgzq5hiT.mjs.map → cron.module-DgxLe8Xy.mjs.map} +1 -1
  13. package/dist/di/index.d.mts +1 -1
  14. package/dist/di/index.mjs +1 -1
  15. package/dist/{di-DseMn-z9.mjs → di-B0NXIdRF.mjs} +17 -1
  16. package/dist/di-B0NXIdRF.mjs.map +1 -0
  17. package/dist/email/index.d.mts +2 -2
  18. package/dist/email/index.mjs +3 -3
  19. package/dist/errors/index.d.mts +1 -1
  20. package/dist/errors/index.mjs +2 -2
  21. package/dist/{errors-mXYxG0XB.mjs → errors-EUtwVfNm.mjs} +3 -3
  22. package/dist/{errors-mXYxG0XB.mjs.map → errors-EUtwVfNm.mjs.map} +1 -1
  23. package/dist/events/index.d.mts +8 -0
  24. package/dist/events/index.d.mts.map +1 -1
  25. package/dist/events/index.mjs +1 -1
  26. package/dist/{events-BXJGZjpG.mjs → events-zbCMY_Gf.mjs} +5 -2
  27. package/dist/events-zbCMY_Gf.mjs.map +1 -0
  28. package/dist/{exception-context-kEoMFwze.mjs → exception-context-Bd5Hk2c_.mjs} +2 -2
  29. package/dist/{exception-context-kEoMFwze.mjs.map → exception-context-Bd5Hk2c_.mjs.map} +1 -1
  30. package/dist/{gateway-context-TMu_AlJt.mjs → gateway-context-I0tKgGfh.mjs} +4 -4
  31. package/dist/{gateway-context-TMu_AlJt.mjs.map → gateway-context-I0tKgGfh.mjs.map} +1 -1
  32. package/dist/guards/index.d.mts +1 -1
  33. package/dist/{hono-app-CvV3hOfT.mjs → hono-app-C7-1m9eK.mjs} +6 -6
  34. package/dist/{hono-app-CvV3hOfT.mjs.map → hono-app-C7-1m9eK.mjs.map} +1 -1
  35. package/dist/{http-method.decorator-ByWZb9DO.mjs → http-method.decorator-xCuGoZPC.mjs} +2 -2
  36. package/dist/{http-method.decorator-ByWZb9DO.mjs.map → http-method.decorator-xCuGoZPC.mjs.map} +1 -1
  37. package/dist/i18n/index.d.mts +1 -1
  38. package/dist/i18n/index.mjs +3 -3
  39. package/dist/{i18n.module-DRQAZoSZ.mjs → i18n.module-JOPUNpvi.mjs} +3 -3
  40. package/dist/{i18n.module-DRQAZoSZ.mjs.map → i18n.module-JOPUNpvi.mjs.map} +1 -1
  41. package/dist/{index-B5JBRcWD.d.mts → index-BPJSBHhq.d.mts} +2 -2
  42. package/dist/{index-B5JBRcWD.d.mts.map → index-BPJSBHhq.d.mts.map} +1 -1
  43. package/dist/{index-B_JoEl3V.d.mts → index-C_t8VVQD.d.mts} +12 -1
  44. package/dist/index-C_t8VVQD.d.mts.map +1 -0
  45. package/dist/index.d.mts +3 -3
  46. package/dist/index.mjs +2 -2
  47. package/dist/{lazy-module-loader-Ib383jH_.d.mts → lazy-module-loader-DZQxOgRZ.d.mts} +2 -2
  48. package/dist/{lazy-module-loader-Ib383jH_.d.mts.map → lazy-module-loader-DZQxOgRZ.d.mts.map} +1 -1
  49. package/dist/{locale-path.service-D-dHiIPc.mjs → locale-path.service-DzA01Kvc.mjs} +3 -3
  50. package/dist/{locale-path.service-D-dHiIPc.mjs.map → locale-path.service-DzA01Kvc.mjs.map} +1 -1
  51. package/dist/{locale-url.service-C2EWmGdq.mjs → locale-url.service-DwTXZid3.mjs} +2 -2
  52. package/dist/{locale-url.service-C2EWmGdq.mjs.map → locale-url.service-DwTXZid3.mjs.map} +1 -1
  53. package/dist/logger/index.mjs +1 -1
  54. package/dist/module/index.d.mts +2 -2
  55. package/dist/module/index.mjs +2 -2
  56. package/dist/{module-registry-Dm-pqHd3.mjs → module-registry-MfWmniZ7.mjs} +4 -4
  57. package/dist/{module-registry-Dm-pqHd3.mjs.map → module-registry-MfWmniZ7.mjs.map} +1 -1
  58. package/dist/openapi/index.d.mts +2 -2
  59. package/dist/openapi/index.mjs +1 -1
  60. package/dist/{openapi-CstuTM8S.mjs → openapi-BKDwQKh-.mjs} +3 -3
  61. package/dist/{openapi-CstuTM8S.mjs.map → openapi-BKDwQKh-.mjs.map} +1 -1
  62. package/dist/{openapi.service-YhTiJ1bO.d.mts → openapi.service-CM40bnBB.d.mts} +2 -2
  63. package/dist/{openapi.service-YhTiJ1bO.d.mts.map → openapi.service-CM40bnBB.d.mts.map} +1 -1
  64. package/dist/quarry/index.d.mts +3 -3
  65. package/dist/quarry/index.mjs +1 -1
  66. package/dist/quarry/runner.d.mts +6 -6
  67. package/dist/quarry/runner.mjs +5 -5
  68. package/dist/{quarry-registry-CXg0RFXq.d.mts → quarry-registry-CsStq0DB.d.mts} +3 -3
  69. package/dist/{quarry-registry-CXg0RFXq.d.mts.map → quarry-registry-CsStq0DB.d.mts.map} +1 -1
  70. package/dist/{quarry.module-BuRPGMDm.mjs → quarry.module-BOgcNJMU.mjs} +3 -3
  71. package/dist/{quarry.module-BuRPGMDm.mjs.map → quarry.module-BOgcNJMU.mjs.map} +1 -1
  72. package/dist/queue/index.d.mts +1 -1
  73. package/dist/queue/index.mjs +2 -2
  74. package/dist/{queue.module-nddvxzCB.mjs → queue.module-DSAH88gZ.mjs} +3 -3
  75. package/dist/{queue.module-nddvxzCB.mjs.map → queue.module-DSAH88gZ.mjs.map} +1 -1
  76. package/dist/{r2-storage.provider-DCxQt9dD.mjs → r2-storage.provider-BJ4j23W6.mjs} +2 -2
  77. package/dist/{r2-storage.provider-DCxQt9dD.mjs.map → r2-storage.provider-BJ4j23W6.mjs.map} +1 -1
  78. package/dist/{rate-limit.decorator-BPAie_p3.mjs → rate-limit.decorator-B35jBEVD.mjs} +2 -2
  79. package/dist/{rate-limit.decorator-BPAie_p3.mjs.map → rate-limit.decorator-B35jBEVD.mjs.map} +1 -1
  80. package/dist/rate-limiter/index.d.mts +1 -1
  81. package/dist/rate-limiter/index.mjs +3 -3
  82. package/dist/{route-registration.service-D6vSwiKP.mjs → route-registration.service-HN8WgIis.mjs} +9 -9
  83. package/dist/{route-registration.service-D6vSwiKP.mjs.map → route-registration.service-HN8WgIis.mjs.map} +1 -1
  84. package/dist/{route-registry-CYqLp2Nj.mjs → route-registry-CtW26Suv.mjs} +3 -3
  85. package/dist/{route-registry-CYqLp2Nj.mjs.map → route-registry-CtW26Suv.mjs.map} +1 -1
  86. package/dist/router/index.d.mts +1 -1
  87. package/dist/router/index.mjs +13 -13
  88. package/dist/{router-CWGBD-Bg.mjs → router-OCnf4VB6.mjs} +13 -13
  89. package/dist/{router-CWGBD-Bg.mjs.map → router-OCnf4VB6.mjs.map} +1 -1
  90. package/dist/{router-resolver-D4YlPNlm.mjs → router-resolver-CMNuw-s0.mjs} +2 -2
  91. package/dist/{router-resolver-D4YlPNlm.mjs.map → router-resolver-CMNuw-s0.mjs.map} +1 -1
  92. package/dist/seeder/index.d.mts +2 -2
  93. package/dist/seeder/index.mjs +3 -3
  94. package/dist/{seeder-7ubkms-Y.mjs → seeder-DI-rUoZx.mjs} +4 -4
  95. package/dist/{seeder-7ubkms-Y.mjs.map → seeder-DI-rUoZx.mjs.map} +1 -1
  96. package/dist/{seeder-registry-CyUmKsJq.mjs → seeder-registry-B5FwBeCU.mjs} +3 -3
  97. package/dist/{seeder-registry-CyUmKsJq.mjs.map → seeder-registry-B5FwBeCU.mjs.map} +1 -1
  98. package/dist/{seeder.module-CYYwk3Qk.mjs → seeder.module-DaY0RYoB.mjs} +2 -2
  99. package/dist/{seeder.module-CYYwk3Qk.mjs.map → seeder.module-DaY0RYoB.mjs.map} +1 -1
  100. package/dist/storage/index.d.mts +1 -1
  101. package/dist/storage/index.mjs +2 -2
  102. package/dist/storage/providers/index.mjs +1 -1
  103. package/dist/{storage-MDZypIE9.mjs → storage-BE6-kzaN.mjs} +7 -7
  104. package/dist/{storage-MDZypIE9.mjs.map → storage-BE6-kzaN.mjs.map} +1 -1
  105. package/dist/{storage.error-Dnib4VHc.mjs → storage.error-Dai3rShJ.mjs} +2 -2
  106. package/dist/{storage.error-Dnib4VHc.mjs.map → storage.error-Dai3rShJ.mjs.map} +1 -1
  107. package/dist/{stratal-DwDJPY9N.d.mts → stratal-Bmc6WT3k.d.mts} +2 -2
  108. package/dist/{stratal-DwDJPY9N.d.mts.map → stratal-Bmc6WT3k.d.mts.map} +1 -1
  109. package/dist/{stratal-DL9M38_s.mjs → stratal-DtAj21uF.mjs} +21 -20
  110. package/dist/stratal-DtAj21uF.mjs.map +1 -0
  111. package/dist/{uri-h7Q8Jug9.mjs → uri-h6ITRpqr.mjs} +3 -3
  112. package/dist/{uri-h7Q8Jug9.mjs.map → uri-h6ITRpqr.mjs.map} +1 -1
  113. package/dist/{versioning.service-C6aHky8-.mjs → versioning.service-B4rtmgMQ.mjs} +3 -3
  114. package/dist/{versioning.service-C6aHky8-.mjs.map → versioning.service-B4rtmgMQ.mjs.map} +1 -1
  115. package/dist/websocket/index.d.mts +1 -1
  116. package/dist/websocket/index.mjs +1 -1
  117. package/dist/workers/index.d.mts +1 -1
  118. package/dist/workers/index.mjs +2 -2
  119. package/package.json +1 -1
  120. package/dist/di-DseMn-z9.mjs.map +0 -1
  121. package/dist/events-BXJGZjpG.mjs.map +0 -1
  122. package/dist/index-B_JoEl3V.d.mts.map +0 -1
  123. package/dist/stratal-DL9M38_s.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { Dr as ApplicationError } from "../index-B_JoEl3V.mjs";
1
+ import { Dr as ApplicationError } from "../index-C_t8VVQD.mjs";
2
2
  import { t as CacheService } from "../cache.service-uElmBtdS.mjs";
3
3
  import { t as TieredCacheService } from "../tiered-cache.service-Dv3BhxxE.mjs";
4
4
 
@@ -1,8 +1,8 @@
1
- import { d as inject, r as DI_TOKENS, s as Singleton } from "../di-DseMn-z9.mjs";
1
+ import { d as inject, r as DI_TOKENS, s as Singleton } from "../di-B0NXIdRF.mjs";
2
2
  import { a as ApplicationError } from "../container-storage-BmOJ4_Na.mjs";
3
3
  import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
4
4
  import { LOGGER_TOKENS } from "../logger/index.mjs";
5
- import "../errors-mXYxG0XB.mjs";
5
+ import "../errors-EUtwVfNm.mjs";
6
6
  import { n as Module } from "../module.decorator-CYHY6pG5.mjs";
7
7
  import "../module/index.mjs";
8
8
  //#region src/cache/cache.error.ts
@@ -1,4 +1,4 @@
1
- import { Sn as CommandResult, bn as CommandInput, xn as CommandInternals } from "./index-B_JoEl3V.mjs";
1
+ import { Sn as CommandResult, bn as CommandInput, xn as CommandInternals } from "./index-C_t8VVQD.mjs";
2
2
 
3
3
  //#region src/quarry/constants.d.ts
4
4
  /**
@@ -118,4 +118,4 @@ declare abstract class Command {
118
118
  }
119
119
  //#endregion
120
120
  export { Command as t };
121
- //# sourceMappingURL=command-CPhFHjG3.d.mts.map
121
+ //# sourceMappingURL=command-4HnKnC-G.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-CPhFHjG3.d.mts","names":[],"sources":["../src/quarry/constants.ts","../src/quarry/command.ts"],"mappings":";;;;;;AAIA;cAAa,iBAAA;;;;AAAb;;;;AAAwE;;;;ACoBxE;;;;;;;;;;uBAAsB,OAAA;EA8LmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,OA7JhD,OAAA;EA4HC;EAAA,OA1HD,WAAA;EA+HD;EAAA,OA7HC,OAAA;EAAA,CAEN,iBAAA,GAAoB,gBAAA;;EA4IC;;;;EAAA,SA3Hb,MAAA,oBAA0B,OAAA;EAsIa;;;EA/HhD,KAAA,IAAS,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;;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-4HnKnC-G.d.mts","names":[],"sources":["../src/quarry/constants.ts","../src/quarry/command.ts"],"mappings":";;;;;;AAIA;cAAa,iBAAA;;;;AAAb;;;;AAAwE;;;;ACoBxE;;;;;;;;;;uBAAsB,OAAA;EA8LmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA,OA7JhD,OAAA;EA4HC;EAAA,OA1HD,WAAA;EA+HD;EAAA,OA7HC,OAAA;EAAA,CAEN,iBAAA,GAAoB,gBAAA;;EA4IC;;;;EAAA,SA3Hb,MAAA,oBAA0B,OAAA;EAsIa;;;EA/HhD,KAAA,IAAS,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;;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,4 +1,4 @@
1
- import { Dr as ApplicationError, Hn as InjectionToken, In as OnInitialize, Nn as ModuleContext, jn as FactoryProvider, kn as DynamicModule } from "../index-B_JoEl3V.mjs";
1
+ import { Dr as ApplicationError, Hn as InjectionToken, In as OnInitialize, Nn as ModuleContext, jn as FactoryProvider, kn as DynamicModule } from "../index-C_t8VVQD.mjs";
2
2
  import { t as Macroable } from "../index-0ItCjaqw.mjs";
3
3
  import { a as z } from "../zod-wecrEVAs.mjs";
4
4
 
@@ -1,7 +1,7 @@
1
- import { d as inject, o as Request, r as DI_TOKENS, s as Singleton } from "../di-DseMn-z9.mjs";
1
+ import { d as inject, o as Request, r as DI_TOKENS, s as Singleton } from "../di-B0NXIdRF.mjs";
2
2
  import { a as ApplicationError } from "../container-storage-BmOJ4_Na.mjs";
3
3
  import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
4
- import "../errors-mXYxG0XB.mjs";
4
+ import "../errors-EUtwVfNm.mjs";
5
5
  import { t as Macroable } from "../macroable-cvDTFZ_A.mjs";
6
6
  import { n as Module } from "../module.decorator-CYHY6pG5.mjs";
7
7
  import "../module/index.mjs";
@@ -1,6 +1,6 @@
1
- import { c as Transient } from "./di-DseMn-z9.mjs";
1
+ import { c as Transient } from "./di-B0NXIdRF.mjs";
2
2
  import { n as getMetadata, t as defineMetadata } from "./metadata-DzzprcID.mjs";
3
- import { u as ROUTE_METADATA_KEYS } from "./exception-context-kEoMFwze.mjs";
3
+ import { u as ROUTE_METADATA_KEYS } from "./exception-context-Bd5Hk2c_.mjs";
4
4
  //#region src/router/decorators/controller.decorator.ts
5
5
  const CONTROLLER_ROUTE_KEY = ROUTE_METADATA_KEYS.CONTROLLER_ROUTE;
6
6
  /**
@@ -63,4 +63,4 @@ function getControllerVersion(target) {
63
63
  //#endregion
64
64
  export { getControllerVersion as i, getControllerOptions as n, getControllerRoute as r, Controller as t };
65
65
 
66
- //# sourceMappingURL=controller.decorator-C5UVeJS3.mjs.map
66
+ //# sourceMappingURL=controller.decorator-DKeZ71aP.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"controller.decorator-C5UVeJS3.mjs","names":[],"sources":["../src/router/decorators/controller.decorator.ts"],"sourcesContent":["import { Transient } from '../../di/decorators'\nimport { defineMetadata, getMetadata } from '../../di/metadata'\nimport { type Constructor } from '../../types'\nimport { ROUTE_METADATA_KEYS } from '../constants'\nimport { type ControllerOptions } from '../types'\n\nconst CONTROLLER_ROUTE_KEY = ROUTE_METADATA_KEYS.CONTROLLER_ROUTE\n\n/**\n * Base controller decorator for route registration\n *\n * This is the core controller decorator that handles:\n * - Transient scope registration (request-scoped)\n * - Route metadata storage\n * - Controller options (tags, security schemes, hideFromDocs)\n *\n * @param route - Base route for this controller (e.g., '/api/v1/users')\n * @param options - Optional configuration (tags, security schemes, hideFromDocs)\n *\n * @example\n * ```typescript\n * import { Controller } from 'stratal/router'\n *\n * @Controller('/api/v1/users', { tags: ['Users'] })\n * export class UsersController implements IController {\n * // All routes accessible\n * }\n * ```\n */\nexport function Controller(route: string, options?: ControllerOptions) {\n return function <T extends Constructor>(target: T) {\n // Wrap @Transient (handles @injectable and scope metadata)\n Transient()(target)\n\n // Store route metadata on the class\n defineMetadata(CONTROLLER_ROUTE_KEY, route, target)\n\n // Store options metadata if provided\n if (options) {\n defineMetadata(ROUTE_METADATA_KEYS.CONTROLLER_OPTIONS, options, target)\n }\n\n return target\n }\n}\n\n/**\n * Get the route from controller class metadata\n *\n * @param target - Controller class or instance\n * @returns Route string or undefined if not set\n */\nexport function getControllerRoute(target: object): string | undefined {\n // Check if target is a class constructor (function) or an instance\n // If class, get metadata from it directly; if instance, get from constructor\n const metadataTarget = typeof target === 'function' ? target : (target as { constructor: object }).constructor\n return getMetadata<string>(CONTROLLER_ROUTE_KEY, metadataTarget)\n}\n\n/**\n * Get the options from controller class metadata\n *\n * @param target - Controller class or instance\n * @returns Controller options or undefined if not set\n */\nexport function getControllerOptions(target: object): ControllerOptions | undefined {\n const metadataTarget = typeof target === 'function' ? target : (target as { constructor: object }).constructor\n return getMetadata<ControllerOptions>(ROUTE_METADATA_KEYS.CONTROLLER_OPTIONS, metadataTarget)\n}\n\n/**\n * Get the version from controller class metadata\n *\n * @param target - Controller class or instance\n * @returns Version string, array, VERSION_NEUTRAL symbol, or undefined if not set\n */\nexport function getControllerVersion(target: object): ControllerOptions['version'] {\n const options = getControllerOptions(target)\n return options?.version\n}\n"],"mappings":";;;;AAMA,MAAM,uBAAuB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;AAuBjD,SAAgB,WAAW,OAAe,SAA6B;CACrE,OAAO,SAAiC,QAAW;EAEjD,UAAU,EAAE,MAAM;EAGlB,eAAe,sBAAsB,OAAO,MAAM;EAGlD,IAAI,SACF,eAAe,oBAAoB,oBAAoB,SAAS,MAAM;EAGxE,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,mBAAmB,QAAoC;CAIrE,OAAO,YAAoB,sBADJ,OAAO,WAAW,aAAa,SAAU,OAAmC,WACpC;AACjE;;;;;;;AAQA,SAAgB,qBAAqB,QAA+C;CAClF,MAAM,iBAAiB,OAAO,WAAW,aAAa,SAAU,OAAmC;CACnG,OAAO,YAA+B,oBAAoB,oBAAoB,cAAc;AAC9F;;;;;;;AAQA,SAAgB,qBAAqB,QAA8C;CAEjF,OADgB,qBAAqB,MACxB,GAAG;AAClB"}
1
+ {"version":3,"file":"controller.decorator-DKeZ71aP.mjs","names":[],"sources":["../src/router/decorators/controller.decorator.ts"],"sourcesContent":["import { Transient } from '../../di/decorators'\nimport { defineMetadata, getMetadata } from '../../di/metadata'\nimport { type Constructor } from '../../types'\nimport { ROUTE_METADATA_KEYS } from '../constants'\nimport { type ControllerOptions } from '../types'\n\nconst CONTROLLER_ROUTE_KEY = ROUTE_METADATA_KEYS.CONTROLLER_ROUTE\n\n/**\n * Base controller decorator for route registration\n *\n * This is the core controller decorator that handles:\n * - Transient scope registration (request-scoped)\n * - Route metadata storage\n * - Controller options (tags, security schemes, hideFromDocs)\n *\n * @param route - Base route for this controller (e.g., '/api/v1/users')\n * @param options - Optional configuration (tags, security schemes, hideFromDocs)\n *\n * @example\n * ```typescript\n * import { Controller } from 'stratal/router'\n *\n * @Controller('/api/v1/users', { tags: ['Users'] })\n * export class UsersController implements IController {\n * // All routes accessible\n * }\n * ```\n */\nexport function Controller(route: string, options?: ControllerOptions) {\n return function <T extends Constructor>(target: T) {\n // Wrap @Transient (handles @injectable and scope metadata)\n Transient()(target)\n\n // Store route metadata on the class\n defineMetadata(CONTROLLER_ROUTE_KEY, route, target)\n\n // Store options metadata if provided\n if (options) {\n defineMetadata(ROUTE_METADATA_KEYS.CONTROLLER_OPTIONS, options, target)\n }\n\n return target\n }\n}\n\n/**\n * Get the route from controller class metadata\n *\n * @param target - Controller class or instance\n * @returns Route string or undefined if not set\n */\nexport function getControllerRoute(target: object): string | undefined {\n // Check if target is a class constructor (function) or an instance\n // If class, get metadata from it directly; if instance, get from constructor\n const metadataTarget = typeof target === 'function' ? target : (target as { constructor: object }).constructor\n return getMetadata<string>(CONTROLLER_ROUTE_KEY, metadataTarget)\n}\n\n/**\n * Get the options from controller class metadata\n *\n * @param target - Controller class or instance\n * @returns Controller options or undefined if not set\n */\nexport function getControllerOptions(target: object): ControllerOptions | undefined {\n const metadataTarget = typeof target === 'function' ? target : (target as { constructor: object }).constructor\n return getMetadata<ControllerOptions>(ROUTE_METADATA_KEYS.CONTROLLER_OPTIONS, metadataTarget)\n}\n\n/**\n * Get the version from controller class metadata\n *\n * @param target - Controller class or instance\n * @returns Version string, array, VERSION_NEUTRAL symbol, or undefined if not set\n */\nexport function getControllerVersion(target: object): ControllerOptions['version'] {\n const options = getControllerOptions(target)\n return options?.version\n}\n"],"mappings":";;;;AAMA,MAAM,uBAAuB,oBAAoB;;;;;;;;;;;;;;;;;;;;;;AAuBjD,SAAgB,WAAW,OAAe,SAA6B;CACrE,OAAO,SAAiC,QAAW;EAEjD,UAAU,EAAE,MAAM;EAGlB,eAAe,sBAAsB,OAAO,MAAM;EAGlD,IAAI,SACF,eAAe,oBAAoB,oBAAoB,SAAS,MAAM;EAGxE,OAAO;CACT;AACF;;;;;;;AAQA,SAAgB,mBAAmB,QAAoC;CAIrE,OAAO,YAAoB,sBADJ,OAAO,WAAW,aAAa,SAAU,OAAmC,WACpC;AACjE;;;;;;;AAQA,SAAgB,qBAAqB,QAA+C;CAClF,MAAM,iBAAiB,OAAO,WAAW,aAAa,SAAU,OAAmC;CACnG,OAAO,YAA+B,oBAAoB,oBAAoB,cAAc;AAC9F;;;;;;;AAQA,SAAgB,qBAAqB,QAA8C;CAEjF,OADgB,qBAAqB,MACxB,GAAG;AAClB"}
@@ -1,4 +1,4 @@
1
- import { Dr as ApplicationError, Y as Container } from "../index-B_JoEl3V.mjs";
1
+ import { Dr as ApplicationError, Y as Container } from "../index-C_t8VVQD.mjs";
2
2
  import { n as RegisteredJob, t as CronJob } from "../cron-job-NesZRk8F.mjs";
3
3
  import { ScheduledController as ScheduledController$1 } from "@cloudflare/workers-types";
4
4
 
@@ -1,2 +1,2 @@
1
- import { i as CronExecutionError, r as CronManager, t as CronModule } from "../cron.module-Bgzq5hiT.mjs";
1
+ import { i as CronExecutionError, r as CronManager, t as CronModule } from "../cron.module-DgxLe8Xy.mjs";
2
2
  export { CronExecutionError, CronManager, CronModule };
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./chunk-BBjsoOtd.mjs";
2
- import { r as DI_TOKENS, s as Singleton } from "./di-DseMn-z9.mjs";
2
+ import { r as DI_TOKENS, s as Singleton } from "./di-B0NXIdRF.mjs";
3
3
  import { a as ApplicationError } from "./container-storage-BmOJ4_Na.mjs";
4
4
  import { t as __decorate } from "./decorate-CuAoSZvs.mjs";
5
5
  import { LOGGER_TOKENS } from "./logger/index.mjs";
6
- import "./errors-mXYxG0XB.mjs";
6
+ import "./errors-EUtwVfNm.mjs";
7
7
  import { n as Module } from "./module.decorator-CYHY6pG5.mjs";
8
8
  //#region src/cron/errors/cron-execution.error.ts
9
9
  /**
@@ -150,4 +150,4 @@ CronModule = __decorate([Module({ providers: [{
150
150
  //#endregion
151
151
  export { CronExecutionError as i, cron_module_exports as n, CronManager as r, CronModule as t };
152
152
 
153
- //# sourceMappingURL=cron.module-Bgzq5hiT.mjs.map
153
+ //# sourceMappingURL=cron.module-DgxLe8Xy.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"cron.module-Bgzq5hiT.mjs","names":[],"sources":["../src/cron/errors/cron-execution.error.ts","../src/cron/cron-manager.ts","../src/cron/cron.module.ts"],"sourcesContent":["import { ApplicationError } from '../../errors'\n\nexport interface CronJobFailure {\n\tjob: string\n\terror: Error\n}\n\ninterface SerializedJobFailure {\n\tjob: string\n\tname: string\n\tcode?: number | string\n\tmessage: string\n\tdbErrorCode?: string\n\tsql?: string\n}\n\n/**\n * Error thrown when one or more cron jobs fail execution.\n *\n * Aggregates failures from multiple jobs that share the same schedule while\n * preserving each underlying error:\n * - The originals are kept on `this.failures` for typed access.\n * - `this.cause` is set to the only failure (1 job) or an `AggregateError`\n * wrapping all of them (2+ jobs), so `LoggerService.serializeError` can\n * walk the chain and surface every stack/cause.\n */\nexport class CronExecutionError extends ApplicationError {\n\tpublic readonly failures: readonly CronJobFailure[]\n\tpublic readonly schedule: string\n\tpublic readonly failureCount: number\n\tpublic readonly jobs: SerializedJobFailure[]\n\n\tconstructor(schedule: string, failures: CronJobFailure[]) {\n\t\tconst cause =\n\t\t\tfailures.length === 0\n\t\t\t\t? undefined\n\t\t\t\t: failures.length === 1\n\t\t\t\t\t? failures[0].error\n\t\t\t\t\t: new AggregateError(failures.map((f) => f.error), `${failures.length} cron jobs failed`)\n\n\t\tsuper(\n\t\t\t`${failures.length} cron job(s) failed for schedule \"${schedule}\"`,\n\t\t\tcause,\n\t\t)\n\n\t\tthis.failures = failures\n\t\tthis.schedule = schedule\n\t\tthis.failureCount = failures.length\n\t\tthis.jobs = failures.map((f) => serializeFailure(f))\n\t}\n}\n\nfunction serializeFailure({ job, error }: CronJobFailure): SerializedJobFailure {\n\tconst out: SerializedJobFailure = {\n\t\tjob,\n\t\tname: error.name,\n\t\tmessage: error.message,\n\t}\n\tconst maybeCoded = error as { code?: number | string }\n\tif (maybeCoded.code !== undefined) out.code = maybeCoded.code\n\treturn out\n}\n","import type { Container } from '../di/container'\nimport { Singleton } from '../di/decorators'\nimport { DI_TOKENS } from '../di/tokens'\nimport { LOGGER_TOKENS } from '../logger/logger.tokens'\nimport type { LoggerService } from '../logger/services/logger.service'\nimport type { CronJob, RegisteredJob } from './cron-job'\nimport { CronExecutionError } from './errors/cron-execution.error'\n\n/**\n * Manages cron job registration and execution\n *\n * CronManager is a singleton service that:\n * - Registers cron job class references from modules\n * - Routes scheduled events to matching jobs\n * - Resolves jobs from a request-scoped container at execution time\n *\n * Jobs are grouped by their cron expression, allowing multiple jobs\n * to run on the same schedule.\n */\n@Singleton(DI_TOKENS.Cron)\nexport class CronManager {\n\t/**\n\t * Map of cron expressions to registered job entries\n\t * Key: Cron expression (e.g., '0 2 * * *')\n\t * Value: Array of registered jobs (class ref + schedule)\n\t */\n\tprivate jobs = new Map<string, RegisteredJob[]>()\n\n\t/**\n\t * Register a cron job class\n\t *\n\t * Jobs with the same schedule are grouped together and executed\n\t * sequentially when the trigger fires.\n\t *\n\t * @param schedule - Cron expression (e.g., '0 2 * * *')\n\t * @param jobClass - CronJob class constructor (resolved at execution time)\n\t */\n\tregisterJob(schedule: string, jobClass: RegisteredJob['jobClass']): void {\n\t\tconst existing = this.jobs.get(schedule) ?? []\n\t\texisting.push({ schedule, jobClass })\n\t\tthis.jobs.set(schedule, existing)\n\t}\n\n\t/**\n\t * Execute all jobs matching the triggered cron expression\n\t *\n\t * Jobs are resolved from the provided request-scoped container,\n\t * ensuring dependencies (e.g. database) are properly scoped.\n\t *\n\t * Jobs are executed sequentially. If a job fails:\n\t * - Its onError() hook is called (if defined)\n\t * - Execution continues with the next job\n\t * - Errors are collected and thrown as CronExecutionError\n\t *\n\t * @param controller - Cloudflare ScheduledController\n\t * @param container - Request-scoped container to resolve jobs from\n\t */\n\tasync executeScheduled(controller: ScheduledController, container: Container): Promise<void> {\n\t\tconst { cron } = controller\n\t\tconst matchingJobs = this.jobs.get(cron) ?? []\n\n\t\tif (matchingJobs.length === 0) {\n\t\t\tconst logger = container.resolve<LoggerService>(LOGGER_TOKENS.LoggerService)\n\t\t\tlogger.warn('No cron jobs matched scheduled trigger', {\n\t\t\t\tincomingCron: cron,\n\t\t\t\tregisteredSchedules: Array.from(this.jobs.keys()),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tconst errors: { job: string; error: Error }[] = []\n\n\t\tfor (const { jobClass } of matchingJobs) {\n\t\t\tconst jobName = jobClass.name\n\n\t\t\ttry {\n\t\t\t\t// Register the job class in the request-scoped container so its\n\t\t\t\t// dependencies are resolved from request scope (not the parent).\n\t\t\t\tcontainer.register(jobClass, jobClass)\n\t\t\t\tconst job = container.resolve<CronJob>(jobClass)\n\t\t\t\tawait job.execute(controller)\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as Error\n\t\t\t\terrors.push({ job: jobName, error: err })\n\n\t\t\t\t// Try to resolve and call onError if possible\n\t\t\t\ttry {\n\t\t\t\t\tconst job = container.resolve<CronJob>(jobClass)\n\t\t\t\t\tif (job.onError) {\n\t\t\t\t\t\tawait job.onError(err, controller)\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// If resolution or onError fails, continue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If any jobs failed, throw an aggregate error so ExceptionHandler logs\n\t\t// it. The full per-job errors are passed through so cause/stacks survive.\n\t\tif (errors.length > 0) {\n\t\t\tthrow new CronExecutionError(cron, errors)\n\t\t}\n\t}\n\n\t/**\n\t * Get all registered jobs for a specific cron expression\n\t *\n\t * @param schedule - Cron expression\n\t * @returns Array of registered jobs, or empty array if none\n\t */\n\tgetJobsForSchedule(schedule: string): RegisteredJob[] {\n\t\treturn this.jobs.get(schedule) ?? []\n\t}\n\n\t/**\n\t * Get all registered cron expressions\n\t *\n\t * @returns Array of unique cron expressions\n\t */\n\tgetAllSchedules(): string[] {\n\t\treturn Array.from(this.jobs.keys())\n\t}\n\n\t/**\n\t * Get total number of registered jobs across all schedules\n\t *\n\t * @returns Total job count\n\t */\n\tgetTotalJobCount(): number {\n\t\tlet count = 0\n\t\tfor (const jobs of this.jobs.values()) {\n\t\t\tcount += jobs.length\n\t\t}\n\t\treturn count\n\t}\n}\n","import { DI_TOKENS } from '../di/tokens'\nimport { Module } from '../module/module.decorator'\nimport { CronManager } from './cron-manager'\n\n/**\n * Registers the cron manager (`DI_TOKENS.Cron`).\n *\n * Lazy: loaded on demand via `await import()` — by `Application.ensureCron`\n * (first scheduled trigger, or at bootstrap when the app declares jobs) and by\n * the `schedule:list` command. Kept out of cold start for apps without cron.\n */\n@Module({\n providers: [\n { provide: DI_TOKENS.Cron, useClass: CronManager },\n ],\n})\nexport class CronModule { }\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,IAAa,qBAAb,cAAwC,iBAAiB;CACxD;CACA;CACA;CACA;CAEA,YAAY,UAAkB,UAA4B;EACzD,MAAM,QACL,SAAS,WAAW,IACjB,KAAA,IACA,SAAS,WAAW,IACnB,SAAS,GAAG,QACZ,IAAI,eAAe,SAAS,KAAK,MAAM,EAAE,KAAK,GAAG,GAAG,SAAS,OAAO,kBAAkB;EAE3F,MACC,GAAG,SAAS,OAAO,oCAAoC,SAAS,IAChE,KACD;EAEA,KAAK,WAAW;EAChB,KAAK,WAAW;EAChB,KAAK,eAAe,SAAS;EAC7B,KAAK,OAAO,SAAS,KAAK,MAAM,iBAAiB,CAAC,CAAC;CACpD;AACD;AAEA,SAAS,iBAAiB,EAAE,KAAK,SAA+C;CAC/E,MAAM,MAA4B;EACjC;EACA,MAAM,MAAM;EACZ,SAAS,MAAM;CAChB;CACA,MAAM,aAAa;CACnB,IAAI,WAAW,SAAS,KAAA,GAAW,IAAI,OAAO,WAAW;CACzD,OAAO;AACR;;;ACzCO,IAAA,cAAA,MAAM,YAAY;;;;;;CAMxB,uBAAe,IAAI,IAA6B;;;;;;;;;;CAWhD,YAAY,UAAkB,UAA2C;EACxE,MAAM,WAAW,KAAK,KAAK,IAAI,QAAQ,KAAK,CAAC;EAC7C,SAAS,KAAK;GAAE;GAAU;EAAS,CAAC;EACpC,KAAK,KAAK,IAAI,UAAU,QAAQ;CACjC;;;;;;;;;;;;;;;CAgBA,MAAM,iBAAiB,YAAiC,WAAqC;EAC5F,MAAM,EAAE,SAAS;EACjB,MAAM,eAAe,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC;EAE7C,IAAI,aAAa,WAAW,GAAG;GAE9B,UADyB,QAAuB,cAAc,aACzD,EAAE,KAAK,0CAA0C;IACrD,cAAc;IACd,qBAAqB,MAAM,KAAK,KAAK,KAAK,KAAK,CAAC;GACjD,CAAC;GACD;EACD;EAEA,MAAM,SAA0C,CAAC;EAEjD,KAAK,MAAM,EAAE,cAAc,cAAc;GACxC,MAAM,UAAU,SAAS;GAEzB,IAAI;IAGH,UAAU,SAAS,UAAU,QAAQ;IAErC,MADY,UAAU,QAAiB,QAC/B,EAAE,QAAQ,UAAU;GAC7B,SAAS,OAAO;IACf,MAAM,MAAM;IACZ,OAAO,KAAK;KAAE,KAAK;KAAS,OAAO;IAAI,CAAC;IAGxC,IAAI;KACH,MAAM,MAAM,UAAU,QAAiB,QAAQ;KAC/C,IAAI,IAAI,SACP,MAAM,IAAI,QAAQ,KAAK,UAAU;IAEnC,QAAQ,CAER;GACD;EACD;EAIA,IAAI,OAAO,SAAS,GACnB,MAAM,IAAI,mBAAmB,MAAM,MAAM;CAE3C;;;;;;;CAQA,mBAAmB,UAAmC;EACrD,OAAO,KAAK,KAAK,IAAI,QAAQ,KAAK,CAAC;CACpC;;;;;;CAOA,kBAA4B;EAC3B,OAAO,MAAM,KAAK,KAAK,KAAK,KAAK,CAAC;CACnC;;;;;;CAOA,mBAA2B;EAC1B,IAAI,QAAQ;EACZ,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,GACnC,SAAS,KAAK;EAEf,OAAO;CACR;AACD;0BApHC,UAAU,UAAU,IAAI,CAAA,GAAA,WAAA;;;;ACHlB,IAAA,aAAA,MAAM,WAAW,CAAE;yBALzB,OAAO,EACN,WAAW,CACT;CAAE,SAAS,UAAU;CAAM,UAAU;AAAY,CACnD,EACF,CAAC,CAAA,GAAA,UAAA"}
1
+ {"version":3,"file":"cron.module-DgxLe8Xy.mjs","names":[],"sources":["../src/cron/errors/cron-execution.error.ts","../src/cron/cron-manager.ts","../src/cron/cron.module.ts"],"sourcesContent":["import { ApplicationError } from '../../errors'\n\nexport interface CronJobFailure {\n\tjob: string\n\terror: Error\n}\n\ninterface SerializedJobFailure {\n\tjob: string\n\tname: string\n\tcode?: number | string\n\tmessage: string\n\tdbErrorCode?: string\n\tsql?: string\n}\n\n/**\n * Error thrown when one or more cron jobs fail execution.\n *\n * Aggregates failures from multiple jobs that share the same schedule while\n * preserving each underlying error:\n * - The originals are kept on `this.failures` for typed access.\n * - `this.cause` is set to the only failure (1 job) or an `AggregateError`\n * wrapping all of them (2+ jobs), so `LoggerService.serializeError` can\n * walk the chain and surface every stack/cause.\n */\nexport class CronExecutionError extends ApplicationError {\n\tpublic readonly failures: readonly CronJobFailure[]\n\tpublic readonly schedule: string\n\tpublic readonly failureCount: number\n\tpublic readonly jobs: SerializedJobFailure[]\n\n\tconstructor(schedule: string, failures: CronJobFailure[]) {\n\t\tconst cause =\n\t\t\tfailures.length === 0\n\t\t\t\t? undefined\n\t\t\t\t: failures.length === 1\n\t\t\t\t\t? failures[0].error\n\t\t\t\t\t: new AggregateError(failures.map((f) => f.error), `${failures.length} cron jobs failed`)\n\n\t\tsuper(\n\t\t\t`${failures.length} cron job(s) failed for schedule \"${schedule}\"`,\n\t\t\tcause,\n\t\t)\n\n\t\tthis.failures = failures\n\t\tthis.schedule = schedule\n\t\tthis.failureCount = failures.length\n\t\tthis.jobs = failures.map((f) => serializeFailure(f))\n\t}\n}\n\nfunction serializeFailure({ job, error }: CronJobFailure): SerializedJobFailure {\n\tconst out: SerializedJobFailure = {\n\t\tjob,\n\t\tname: error.name,\n\t\tmessage: error.message,\n\t}\n\tconst maybeCoded = error as { code?: number | string }\n\tif (maybeCoded.code !== undefined) out.code = maybeCoded.code\n\treturn out\n}\n","import type { Container } from '../di/container'\nimport { Singleton } from '../di/decorators'\nimport { DI_TOKENS } from '../di/tokens'\nimport { LOGGER_TOKENS } from '../logger/logger.tokens'\nimport type { LoggerService } from '../logger/services/logger.service'\nimport type { CronJob, RegisteredJob } from './cron-job'\nimport { CronExecutionError } from './errors/cron-execution.error'\n\n/**\n * Manages cron job registration and execution\n *\n * CronManager is a singleton service that:\n * - Registers cron job class references from modules\n * - Routes scheduled events to matching jobs\n * - Resolves jobs from a request-scoped container at execution time\n *\n * Jobs are grouped by their cron expression, allowing multiple jobs\n * to run on the same schedule.\n */\n@Singleton(DI_TOKENS.Cron)\nexport class CronManager {\n\t/**\n\t * Map of cron expressions to registered job entries\n\t * Key: Cron expression (e.g., '0 2 * * *')\n\t * Value: Array of registered jobs (class ref + schedule)\n\t */\n\tprivate jobs = new Map<string, RegisteredJob[]>()\n\n\t/**\n\t * Register a cron job class\n\t *\n\t * Jobs with the same schedule are grouped together and executed\n\t * sequentially when the trigger fires.\n\t *\n\t * @param schedule - Cron expression (e.g., '0 2 * * *')\n\t * @param jobClass - CronJob class constructor (resolved at execution time)\n\t */\n\tregisterJob(schedule: string, jobClass: RegisteredJob['jobClass']): void {\n\t\tconst existing = this.jobs.get(schedule) ?? []\n\t\texisting.push({ schedule, jobClass })\n\t\tthis.jobs.set(schedule, existing)\n\t}\n\n\t/**\n\t * Execute all jobs matching the triggered cron expression\n\t *\n\t * Jobs are resolved from the provided request-scoped container,\n\t * ensuring dependencies (e.g. database) are properly scoped.\n\t *\n\t * Jobs are executed sequentially. If a job fails:\n\t * - Its onError() hook is called (if defined)\n\t * - Execution continues with the next job\n\t * - Errors are collected and thrown as CronExecutionError\n\t *\n\t * @param controller - Cloudflare ScheduledController\n\t * @param container - Request-scoped container to resolve jobs from\n\t */\n\tasync executeScheduled(controller: ScheduledController, container: Container): Promise<void> {\n\t\tconst { cron } = controller\n\t\tconst matchingJobs = this.jobs.get(cron) ?? []\n\n\t\tif (matchingJobs.length === 0) {\n\t\t\tconst logger = container.resolve<LoggerService>(LOGGER_TOKENS.LoggerService)\n\t\t\tlogger.warn('No cron jobs matched scheduled trigger', {\n\t\t\t\tincomingCron: cron,\n\t\t\t\tregisteredSchedules: Array.from(this.jobs.keys()),\n\t\t\t})\n\t\t\treturn\n\t\t}\n\n\t\tconst errors: { job: string; error: Error }[] = []\n\n\t\tfor (const { jobClass } of matchingJobs) {\n\t\t\tconst jobName = jobClass.name\n\n\t\t\ttry {\n\t\t\t\t// Register the job class in the request-scoped container so its\n\t\t\t\t// dependencies are resolved from request scope (not the parent).\n\t\t\t\tcontainer.register(jobClass, jobClass)\n\t\t\t\tconst job = container.resolve<CronJob>(jobClass)\n\t\t\t\tawait job.execute(controller)\n\t\t\t} catch (error) {\n\t\t\t\tconst err = error as Error\n\t\t\t\terrors.push({ job: jobName, error: err })\n\n\t\t\t\t// Try to resolve and call onError if possible\n\t\t\t\ttry {\n\t\t\t\t\tconst job = container.resolve<CronJob>(jobClass)\n\t\t\t\t\tif (job.onError) {\n\t\t\t\t\t\tawait job.onError(err, controller)\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// If resolution or onError fails, continue\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If any jobs failed, throw an aggregate error so ExceptionHandler logs\n\t\t// it. The full per-job errors are passed through so cause/stacks survive.\n\t\tif (errors.length > 0) {\n\t\t\tthrow new CronExecutionError(cron, errors)\n\t\t}\n\t}\n\n\t/**\n\t * Get all registered jobs for a specific cron expression\n\t *\n\t * @param schedule - Cron expression\n\t * @returns Array of registered jobs, or empty array if none\n\t */\n\tgetJobsForSchedule(schedule: string): RegisteredJob[] {\n\t\treturn this.jobs.get(schedule) ?? []\n\t}\n\n\t/**\n\t * Get all registered cron expressions\n\t *\n\t * @returns Array of unique cron expressions\n\t */\n\tgetAllSchedules(): string[] {\n\t\treturn Array.from(this.jobs.keys())\n\t}\n\n\t/**\n\t * Get total number of registered jobs across all schedules\n\t *\n\t * @returns Total job count\n\t */\n\tgetTotalJobCount(): number {\n\t\tlet count = 0\n\t\tfor (const jobs of this.jobs.values()) {\n\t\t\tcount += jobs.length\n\t\t}\n\t\treturn count\n\t}\n}\n","import { DI_TOKENS } from '../di/tokens'\nimport { Module } from '../module/module.decorator'\nimport { CronManager } from './cron-manager'\n\n/**\n * Registers the cron manager (`DI_TOKENS.Cron`).\n *\n * Lazy: loaded on demand via `await import()` — by `Application.ensureCron`\n * (first scheduled trigger, or at bootstrap when the app declares jobs) and by\n * the `schedule:list` command. Kept out of cold start for apps without cron.\n */\n@Module({\n providers: [\n { provide: DI_TOKENS.Cron, useClass: CronManager },\n ],\n})\nexport class CronModule { }\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,IAAa,qBAAb,cAAwC,iBAAiB;CACxD;CACA;CACA;CACA;CAEA,YAAY,UAAkB,UAA4B;EACzD,MAAM,QACL,SAAS,WAAW,IACjB,KAAA,IACA,SAAS,WAAW,IACnB,SAAS,GAAG,QACZ,IAAI,eAAe,SAAS,KAAK,MAAM,EAAE,KAAK,GAAG,GAAG,SAAS,OAAO,kBAAkB;EAE3F,MACC,GAAG,SAAS,OAAO,oCAAoC,SAAS,IAChE,KACD;EAEA,KAAK,WAAW;EAChB,KAAK,WAAW;EAChB,KAAK,eAAe,SAAS;EAC7B,KAAK,OAAO,SAAS,KAAK,MAAM,iBAAiB,CAAC,CAAC;CACpD;AACD;AAEA,SAAS,iBAAiB,EAAE,KAAK,SAA+C;CAC/E,MAAM,MAA4B;EACjC;EACA,MAAM,MAAM;EACZ,SAAS,MAAM;CAChB;CACA,MAAM,aAAa;CACnB,IAAI,WAAW,SAAS,KAAA,GAAW,IAAI,OAAO,WAAW;CACzD,OAAO;AACR;;;ACzCO,IAAA,cAAA,MAAM,YAAY;;;;;;CAMxB,uBAAe,IAAI,IAA6B;;;;;;;;;;CAWhD,YAAY,UAAkB,UAA2C;EACxE,MAAM,WAAW,KAAK,KAAK,IAAI,QAAQ,KAAK,CAAC;EAC7C,SAAS,KAAK;GAAE;GAAU;EAAS,CAAC;EACpC,KAAK,KAAK,IAAI,UAAU,QAAQ;CACjC;;;;;;;;;;;;;;;CAgBA,MAAM,iBAAiB,YAAiC,WAAqC;EAC5F,MAAM,EAAE,SAAS;EACjB,MAAM,eAAe,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC;EAE7C,IAAI,aAAa,WAAW,GAAG;GAE9B,UADyB,QAAuB,cAAc,aACzD,EAAE,KAAK,0CAA0C;IACrD,cAAc;IACd,qBAAqB,MAAM,KAAK,KAAK,KAAK,KAAK,CAAC;GACjD,CAAC;GACD;EACD;EAEA,MAAM,SAA0C,CAAC;EAEjD,KAAK,MAAM,EAAE,cAAc,cAAc;GACxC,MAAM,UAAU,SAAS;GAEzB,IAAI;IAGH,UAAU,SAAS,UAAU,QAAQ;IAErC,MADY,UAAU,QAAiB,QAC/B,EAAE,QAAQ,UAAU;GAC7B,SAAS,OAAO;IACf,MAAM,MAAM;IACZ,OAAO,KAAK;KAAE,KAAK;KAAS,OAAO;IAAI,CAAC;IAGxC,IAAI;KACH,MAAM,MAAM,UAAU,QAAiB,QAAQ;KAC/C,IAAI,IAAI,SACP,MAAM,IAAI,QAAQ,KAAK,UAAU;IAEnC,QAAQ,CAER;GACD;EACD;EAIA,IAAI,OAAO,SAAS,GACnB,MAAM,IAAI,mBAAmB,MAAM,MAAM;CAE3C;;;;;;;CAQA,mBAAmB,UAAmC;EACrD,OAAO,KAAK,KAAK,IAAI,QAAQ,KAAK,CAAC;CACpC;;;;;;CAOA,kBAA4B;EAC3B,OAAO,MAAM,KAAK,KAAK,KAAK,KAAK,CAAC;CACnC;;;;;;CAOA,mBAA2B;EAC1B,IAAI,QAAQ;EACZ,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,GACnC,SAAS,KAAK;EAEf,OAAO;CACR;AACD;0BApHC,UAAU,UAAU,IAAI,CAAA,GAAA,WAAA;;;;ACHlB,IAAA,aAAA,MAAM,WAAW,CAAE;yBALzB,OAAO,EACN,WAAW,CACT;CAAE,SAAS,UAAU;CAAM,UAAU;AAAY,CACnD,EACF,CAAC,CAAA,GAAA,UAAA"}
@@ -1,2 +1,2 @@
1
- import { $ as ConditionalBindingGive, B as Transient, Bn as ContainerLike, Er as DI_TOKENS, F as defineMetadata, G as InjectParam, Gn as LazyToken, H as getInjectionTokens, Hn as InjectionToken, I as getMetadata, J as ContainerError, K as ParamInjection, Kn as isLazyToken, L as hasMetadata, M as containerStorage, N as getContainer, P as runWithContainer, Q as ConditionalBindingBuilderImpl, R as Request, Tr as DIToken, U as inject, Un as Scope, V as getClassMetadata, Vn as ExtensionDecorator, W as INJECT_PARAM_METADATA_KEY, Wn as WhenOptions, X as ContainerOptions, Y as Container, Z as ConditionalBindingBuilder, et as ConditionalBindingUse, q as getMethodInjections, qn as lazy, tt as PredicateContainer, wr as CONTAINER_TOKEN, z as Singleton } from "../index-B_JoEl3V.mjs";
1
+ import { $ as ConditionalBindingGive, B as Transient, Bn as ContainerLike, Er as DI_TOKENS, F as defineMetadata, G as InjectParam, Gn as LazyToken, H as getInjectionTokens, Hn as InjectionToken, I as getMetadata, J as ContainerError, K as ParamInjection, Kn as isLazyToken, L as hasMetadata, M as containerStorage, N as getContainer, P as runWithContainer, Q as ConditionalBindingBuilderImpl, R as Request, Tr as DIToken, U as inject, Un as Scope, V as getClassMetadata, Vn as ExtensionDecorator, W as INJECT_PARAM_METADATA_KEY, Wn as WhenOptions, X as ContainerOptions, Y as Container, Z as ConditionalBindingBuilder, et as ConditionalBindingUse, q as getMethodInjections, qn as lazy, tt as PredicateContainer, wr as CONTAINER_TOKEN, z as Singleton } from "../index-C_t8VVQD.mjs";
2
2
  export { CONTAINER_TOKEN, ConditionalBindingBuilder, ConditionalBindingBuilderImpl, ConditionalBindingGive, ConditionalBindingUse, Container, ContainerError, ContainerLike, ContainerOptions, DIToken, DI_TOKENS, ExtensionDecorator, INJECT_PARAM_METADATA_KEY, InjectParam, InjectionToken, LazyToken, type ParamInjection, PredicateContainer, Request, Scope, Singleton, Transient, WhenOptions, containerStorage, defineMetadata, getClassMetadata, getContainer, getInjectionTokens, getMetadata, getMethodInjections, hasMetadata, inject, isLazyToken, lazy, runWithContainer };
package/dist/di/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as ContainerError, a as lazy, c as Transient, d as inject, f as INJECT_PARAM_METADATA_KEY, g as ConditionalBindingBuilderImpl, h as Scope, i as isLazyToken, l as getClassMetadata, m as getMethodInjections, n as CONTAINER_TOKEN, o as Request, p as InjectParam, r as DI_TOKENS, s as Singleton, t as Container, u as getInjectionTokens } from "../di-DseMn-z9.mjs";
1
+ import { _ as ContainerError, a as lazy, c as Transient, d as inject, f as INJECT_PARAM_METADATA_KEY, g as ConditionalBindingBuilderImpl, h as Scope, i as isLazyToken, l as getClassMetadata, m as getMethodInjections, n as CONTAINER_TOKEN, o as Request, p as InjectParam, r as DI_TOKENS, s as Singleton, t as Container, u as getInjectionTokens } from "../di-B0NXIdRF.mjs";
2
2
  import { n as getContainer, r as runWithContainer, t as containerStorage } from "../container-storage-BmOJ4_Na.mjs";
3
3
  import { n as getMetadata, r as hasMetadata, t as defineMetadata } from "../metadata-DzzprcID.mjs";
4
4
  export { CONTAINER_TOKEN, ConditionalBindingBuilderImpl, Container, ContainerError, DI_TOKENS, INJECT_PARAM_METADATA_KEY, InjectParam, Request, Scope, Singleton, Transient, containerStorage, defineMetadata, getClassMetadata, getContainer, getInjectionTokens, getMetadata, getMethodInjections, hasMetadata, inject, isLazyToken, lazy, runWithContainer };
@@ -335,6 +335,7 @@ var Container = class Container {
335
335
  tryResolve(token) {
336
336
  const realToken = isLazyToken(token) ? token.factory() : token;
337
337
  if (!this.isResolvable(realToken)) return void 0;
338
+ if (!this.isRequestScoped && this.scopeForToken(realToken) === 2) return void 0;
338
339
  return this.resolve(realToken);
339
340
  }
340
341
  isRegistered(token) {
@@ -418,6 +419,21 @@ var Container = class Container {
418
419
  if (typeof token === "function" && getClassMetadata(token)) return token;
419
420
  }
420
421
  /**
422
+ * The effective scope a token would resolve with, following alias
423
+ * registrations. Bare constructor tokens fall back to their decorator
424
+ * metadata — the same scope {@link resolve} uses when auto-registering.
425
+ */
426
+ scopeForToken(token) {
427
+ const reg = this.findRegistration(token);
428
+ if (reg) {
429
+ if (reg.kind === "class") return reg.scope;
430
+ if (reg.kind === "alias") return this.scopeForToken(reg.target);
431
+ if (reg.kind === "lazy") return getClassMetadata(reg.factory())?.scope ?? 0;
432
+ return;
433
+ }
434
+ if (typeof token === "function") return getClassMetadata(token)?.scope;
435
+ }
436
+ /**
421
437
  * Evict a token from the request cache along with every cached request-scoped
422
438
  * instance that transitively depends on it. Re-registering a value must
423
439
  * rebuild its dependents (so they pick up the new value) while leaving
@@ -521,4 +537,4 @@ var Container = class Container {
521
537
  //#endregion
522
538
  export { ContainerError as _, lazy as a, Transient as c, inject as d, INJECT_PARAM_METADATA_KEY as f, ConditionalBindingBuilderImpl as g, Scope as h, isLazyToken as i, getClassMetadata as l, getMethodInjections as m, CONTAINER_TOKEN as n, Request as o, InjectParam as p, DI_TOKENS as r, Singleton as s, Container as t, getInjectionTokens as u, ROUTER_TOKENS as v };
523
539
 
524
- //# sourceMappingURL=di-DseMn-z9.mjs.map
540
+ //# sourceMappingURL=di-B0NXIdRF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di-B0NXIdRF.mjs","names":["g"],"sources":["../src/router/router.tokens.ts","../src/di/container.error.ts","../src/di/conditional-binding-builder.ts","../src/di/types.ts","../src/di/decorators/inject-param.decorator.ts","../src/di/decorators/inject.decorator.ts","../src/di/decorators.ts","../src/di/lazy.ts","../src/di/tokens.ts","../src/di/container.ts"],"sourcesContent":["/**\n * Dependency injection tokens for the router system\n */\nexport const ROUTER_TOKENS = {\n /**\n * Token for RouterContext (request-scoped)\n * Contains Hono context wrapper with helper methods\n */\n RouterContext: Symbol.for('stratal:router:context'),\n\n /**\n * Token for RouteRegistry (singleton)\n * Central registry of all application routes — source of truth for route:list, route:types, URL generation\n */\n RouteRegistry: Symbol.for('stratal:router:route-registry'),\n\n /**\n * Token for VersioningService (singleton)\n * Resolves version prefixes for route paths\n */\n VersioningService: Symbol.for('stratal:router:versioning-service'),\n\n /**\n * Token for LocalePathService (singleton)\n * Resolves locale path variants and computes LocalePathConfig\n */\n LocalePathService: Symbol.for('stratal:router:locale-path-service'),\n\n /**\n * Token for LocaleUrlService (singleton)\n * Ergonomic wrapper around the pure locale-url helpers — applies, strips,\n * and tests locale prefixes against the resolved LocalePathService config.\n */\n LocaleUrlService: Symbol.for('stratal:router:locale-url-service'),\n\n /**\n * Token for RouterResolver (singleton, may be null)\n * Internal resolver that computes effective Router config per controller\n */\n RouterResolver: Symbol.for('stratal:router:router-resolver'),\n\n /**\n * Token for HonoApp (singleton)\n * The Hono application instance with Stratal-specific setup\n */\n HonoApp: Symbol.for('stratal:router:hono-app'),\n\n /**\n * Token for Uri (request-scoped)\n * URL generation service — route URLs, signed URLs, current/previous URL access\n */\n Uri: Symbol.for('stratal:router:uri'),\n} as const\n","import { ApplicationError } from '../errors/application-error';\n\nexport class ContainerError extends ApplicationError {\n}\n","import type { Container } from './container'\nimport { ContainerError } from './container.error'\nimport type { InjectionToken, WhenOptions } from './types'\nimport type { Constructor } from '../types'\n\nexport interface PredicateContainer {\n resolve<T>(token: InjectionToken<T>): T\n isRegistered<T>(token: InjectionToken<T>): boolean\n}\n\nexport interface ConditionalBindingBuilder {\n use<T extends object>(token: InjectionToken<T>): ConditionalBindingUse<T>\n}\n\nexport interface ConditionalBindingUse<T extends object> {\n give(implementation: Constructor<T>): ConditionalBindingGive<T>\n}\n\nexport interface ConditionalBindingGive<T extends object> {\n otherwise(implementation: Constructor<T>): void\n}\n\nexport class ConditionalBindingBuilderImpl implements ConditionalBindingBuilder {\n constructor(\n private readonly container: Container,\n private readonly predicate: (container: PredicateContainer) => boolean,\n private readonly options: WhenOptions,\n ) {}\n\n use<T extends object>(token: InjectionToken<T>): ConditionalBindingUse<T> {\n return new ConditionalBindingUseImpl<T>(\n this.container,\n this.predicate,\n this.options,\n token,\n )\n }\n}\n\nclass ConditionalBindingUseImpl<T extends object> implements ConditionalBindingUse<T> {\n constructor(\n private readonly container: Container,\n private readonly predicate: (container: PredicateContainer) => boolean,\n private readonly options: WhenOptions,\n private readonly token: InjectionToken<T>,\n ) {}\n\n give(trueImpl: Constructor<T>): ConditionalBindingGive<T> {\n this.registerConditional(trueImpl, undefined)\n\n return {\n otherwise: (falseImpl: Constructor<T>) => {\n this.registerConditional(trueImpl, falseImpl)\n },\n }\n }\n\n private registerConditional(trueImpl: Constructor<T>, falseImpl: Constructor<T> | undefined): void {\n const { predicate, container, options, token } = this\n let cachedResult: boolean | undefined\n\n // Register both implementations so the container can instantiate them\n container.register(trueImpl)\n if (falseImpl) container.register(falseImpl)\n\n container.registerFactory(token, (c) => {\n let result: boolean\n if (options.cache && cachedResult !== undefined) {\n result = cachedResult\n } else {\n result = predicate(c)\n if (options.cache) cachedResult = result\n }\n\n if (result) {\n return c.resolve(trueImpl as unknown as InjectionToken<T>)\n }\n\n if (falseImpl) {\n return c.resolve(falseImpl as unknown as InjectionToken<T>)\n }\n\n const tokenStr = typeof token === 'symbol'\n ? (token.description ?? 'unknown')\n : typeof token === 'function'\n ? token.name\n : typeof token === 'string'\n ? token\n : 'lazy'\n throw new ContainerError(`No fallback registered for conditional binding \"${tokenStr}\". Use .otherwise() or register a default implementation.`)\n })\n }\n}\n","import type { Constructor } from '../types'\nimport type { LazyToken } from './lazy'\n\nexport type InjectionToken<T = unknown> = Constructor<T> | string | symbol | LazyToken<T>\n\nexport enum Scope {\n Transient = 0,\n Singleton = 1,\n Request = 2,\n}\n\nexport interface WhenOptions {\n cache?: boolean\n}\n\nexport type ExtensionDecorator<T> = (service: T, container: ContainerLike) => T\n\nexport interface ContainerLike {\n resolve<T>(token: InjectionToken<T>): T\n /**\n * Resolves an optional dependency: `undefined` when nothing is registered,\n * or when a request-scoped provider is requested outside a request scope.\n */\n tryResolve<T>(token: InjectionToken<T>): T | undefined\n}\n","import type { InjectionToken } from '../types'\nimport { defineMetadata, getMetadata } from '../metadata'\n\nexport const INJECT_PARAM_METADATA_KEY = Symbol.for('stratal:inject:param')\n\nexport interface ParamInjection {\n index: number\n token: InjectionToken\n}\n\nexport function InjectParam<T>(token: InjectionToken<T>): ParameterDecorator {\n return (target: object, propertyKey: string | symbol | undefined, parameterIndex: number) => {\n if (propertyKey === undefined) {\n throw new Error('@InjectParam can only be used on method parameters, not constructor parameters')\n }\n\n const existing = getMetadata<ParamInjection[]>(INJECT_PARAM_METADATA_KEY, target, propertyKey) ?? []\n existing.push({ index: parameterIndex, token })\n defineMetadata(INJECT_PARAM_METADATA_KEY, existing, target, propertyKey)\n }\n}\n\nexport function getMethodInjections(target: object, propertyKey: string | symbol): ParamInjection[] {\n const injections = getMetadata<ParamInjection[]>(INJECT_PARAM_METADATA_KEY, target, propertyKey) ?? []\n return injections.sort((a, b) => a.index - b.index)\n}\n","import type { InjectionToken } from '../types'\n\ninterface InjectionEntry {\n token: InjectionToken\n optional: boolean\n}\n\nconst INJECTION_TOKENS_KEY = Symbol.for('stratal:di:injection-tokens')\nconst g = globalThis as Record<symbol, unknown>\nconst INJECTION_TOKENS: WeakMap<object, Map<number, InjectionEntry>> =\n (g[INJECTION_TOKENS_KEY] as WeakMap<object, Map<number, InjectionEntry>>) ??\n (g[INJECTION_TOKENS_KEY] = new WeakMap<object, Map<number, InjectionEntry>>())\n\nexport function inject<T>(\n token: InjectionToken<T>,\n options?: { isOptional?: boolean },\n): ParameterDecorator {\n return (target: object, _propertyKey: string | symbol | undefined, parameterIndex: number) => {\n let params = INJECTION_TOKENS.get(target)\n if (!params) {\n params = new Map()\n INJECTION_TOKENS.set(target, params)\n }\n params.set(parameterIndex, { token, optional: options?.isOptional ?? false })\n }\n}\n\nexport function getInjectionTokens(target: object): Map<number, InjectionEntry> {\n const direct = INJECTION_TOKENS.get(target)\n if (direct && direct.size > 0) return direct\n\n let proto = Object.getPrototypeOf(target) as object | null\n while (proto !== null && proto !== Function.prototype) {\n const inherited = INJECTION_TOKENS.get(proto)\n if (inherited && inherited.size > 0) return inherited\n proto = Object.getPrototypeOf(proto) as object | null\n }\n\n return new Map<number, InjectionEntry>()\n}\n","import type { InjectionToken } from './types'\nimport { Scope } from './types'\n\nexport {\n InjectParam,\n getMethodInjections,\n type ParamInjection,\n INJECT_PARAM_METADATA_KEY,\n} from './decorators/inject-param.decorator'\n\nexport { inject, getInjectionTokens } from './decorators/inject.decorator'\n\ninterface ClassMetadata {\n scope: Scope\n token?: InjectionToken\n}\n\nconst CLASS_METADATA_KEY = Symbol.for('stratal:di:class-metadata')\nconst g = globalThis as Record<symbol, unknown>\nconst CLASS_METADATA: WeakMap<object, ClassMetadata> =\n (g[CLASS_METADATA_KEY] as WeakMap<object, ClassMetadata>) ??\n (g[CLASS_METADATA_KEY] = new WeakMap<object, ClassMetadata>())\n\nfunction scopeDecorator(scope: Scope) {\n return <T>(token?: InjectionToken<T>) =>\n <TFunction extends abstract new (...args: never[]) => unknown>(target: TFunction): TFunction => {\n CLASS_METADATA.set(target, { scope, token })\n return target\n }\n}\n\nexport const Singleton = scopeDecorator(Scope.Singleton)\nexport const Request = scopeDecorator(Scope.Request)\nexport const Transient = scopeDecorator(Scope.Transient)\n\nexport function getClassMetadata(target: object): ClassMetadata | undefined {\n const direct = CLASS_METADATA.get(target)\n if (direct) return direct\n\n let proto = Object.getPrototypeOf(target) as object | null\n while (proto !== null && proto !== Function.prototype) {\n const inherited = CLASS_METADATA.get(proto)\n if (inherited) return inherited\n proto = Object.getPrototypeOf(proto) as object | null\n }\n\n return undefined\n}\n","import type { Constructor } from '../types'\n\nconst LAZY_MARKER = Symbol.for('stratal:lazy')\n\nexport interface LazyToken<T = unknown> {\n [LAZY_MARKER]: true\n factory: () => Constructor<T>\n}\n\nexport function lazy<T>(factory: () => Constructor<T>): LazyToken<T> {\n return { [LAZY_MARKER]: true, factory } as LazyToken<T>\n}\n\nexport function isLazyToken(value: unknown): value is LazyToken {\n return typeof value === 'object' && value !== null && LAZY_MARKER in value\n}\n","/**\n * Token for the Container instance\n * Used for injecting the Container into services that need dynamic resolution\n */\nexport const CONTAINER_TOKEN = Symbol.for('stratal:di:container')\n\nexport const DI_TOKENS = {\n // Cloudflare\n CloudflareEnv: Symbol.for('stratal:cloudflare:env'),\n ExecutionContext: Symbol.for('stratal:execution:context'),\n\n // Infrastructure\n Container: CONTAINER_TOKEN,\n Application: Symbol.for('stratal:application'),\n ModuleRegistry: Symbol.for('stratal:module:registry'),\n LazyModuleLoader: Symbol.for('stratal:lazy-module-loader'),\n ExceptionHandler: Symbol.for('stratal:exception:handler'),\n Database: Symbol.for('stratal:database:service'),\n Queue: Symbol.for('stratal:queue:manager'),\n ConsumerRegistry: Symbol.for('stratal:consumer:registry'),\n Cron: Symbol.for('stratal:cron:manager'),\n EventRegistry: Symbol.for('stratal:event:registry'),\n Quarry: Symbol.for('stratal:quarry'),\n\n // Context\n /**\n * AuthContext: Use for services that need user authentication (userId).\n */\n AuthContext: Symbol.for('stratal:auth:context'),\n\n // Workers\n DurableObjectState: Symbol.for('stratal:durable:object:state'),\n DurableObjectId: Symbol.for('stratal:durable:object:id'),\n} as const\n\nexport type DIToken = typeof DI_TOKENS[keyof typeof DI_TOKENS]\n","import type { RouterContext } from '../router/router-context';\nimport { ROUTER_TOKENS } from '../router/router.tokens';\nimport type { Constructor } from '../types';\nimport { ConditionalBindingBuilderImpl, type ConditionalBindingBuilder, type PredicateContainer } from './conditional-binding-builder';\nimport { containerStorage } from './container-storage';\nimport { ContainerError } from './container.error';\nimport { getClassMetadata } from './decorators';\nimport { getInjectionTokens } from './decorators/inject.decorator';\nimport { isLazyToken, type LazyToken } from './lazy';\nimport { CONTAINER_TOKEN } from './tokens';\nimport { Scope, type ExtensionDecorator, type InjectionToken, type WhenOptions } from './types';\n\ninterface ClassRegistration {\n kind: 'class'\n useClass: Constructor\n scope: Scope\n}\n\ninterface LazyClassRegistration {\n kind: 'lazy'\n factory: () => Constructor\n}\n\ninterface ValueRegistration {\n kind: 'value'\n value: unknown\n}\n\ninterface FactoryRegistration {\n kind: 'factory'\n factory: (container: Container) => unknown\n}\n\ninterface AliasRegistration {\n kind: 'alias'\n target: InjectionToken\n}\n\ntype Registration = ClassRegistration | LazyClassRegistration | ValueRegistration | FactoryRegistration | AliasRegistration\n\nfunction tokenToString(token: InjectionToken): string {\n if (typeof token === 'symbol') return token.description ?? 'Symbol'\n if (typeof token === 'function') return token.name\n if (typeof token === 'object' && token !== null && 'factory' in token) return '(lazy)'\n return String(token)\n}\n\nexport interface ContainerOptions {\n parent?: Container\n isRequestScoped?: boolean\n}\n\nexport class Container {\n private readonly registrations = new Map<InjectionToken, Registration>()\n private readonly singletons = new Map<InjectionToken, unknown>()\n private readonly requestCache = new Map<InjectionToken, unknown>()\n private readonly requestCacheDeps = new Map<InjectionToken, Set<InjectionToken>>()\n /**\n * Classes currently being constructed, held on the root so it spans the\n * global ↔ request-scope boundary. Used to turn an otherwise-opaque stack\n * overflow on a circular dependency into a clear error naming the cycle.\n */\n private readonly resolutionStack: Constructor[] = []\n private readonly parent: Container | null\n private readonly isRequestScoped: boolean\n\n constructor(options: ContainerOptions = {}) {\n this.parent = options.parent ?? null\n this.isRequestScoped = options.isRequestScoped ?? false\n\n if (!this.isRequestScoped) {\n this.registrations.set(CONTAINER_TOKEN, { kind: 'value', value: this })\n }\n }\n\n // ── Registration ──────────────────────────────────────────────\n\n register<T extends object>(serviceClass: Constructor<T>): void\n register<T extends object>(token: InjectionToken<T>, serviceClassOrLazy: Constructor<T> | LazyToken<T>): void\n register<T extends object>(\n tokenOrClass: InjectionToken<T> | Constructor<T>,\n serviceClassOrLazy?: Constructor<T> | LazyToken<T>,\n ): void {\n if (serviceClassOrLazy !== undefined && isLazyToken(serviceClassOrLazy)) {\n const lazyToken = serviceClassOrLazy\n this.registrations.set(tokenOrClass, {\n kind: 'lazy',\n factory: lazyToken.factory,\n })\n return\n }\n\n let token: InjectionToken<T>\n let impl: Constructor<T>\n\n if (serviceClassOrLazy !== undefined) {\n token = tokenOrClass\n impl = serviceClassOrLazy\n } else {\n token = tokenOrClass as Constructor<T>\n impl = tokenOrClass as Constructor<T>\n }\n\n const meta = getClassMetadata(impl)\n const scope = meta?.scope ?? Scope.Transient\n const effectiveToken = (serviceClassOrLazy === undefined && meta?.token) ? meta.token : token\n\n this.registrations.set(effectiveToken, { kind: 'class', useClass: impl, scope })\n }\n\n registerSingleton<T extends object>(serviceClass: Constructor<T>): void\n registerSingleton<T extends object>(token: InjectionToken<T>, serviceClass: Constructor<T>): void\n registerSingleton<T extends object>(\n tokenOrClass: InjectionToken<T> | Constructor<T>,\n serviceClass?: Constructor<T>,\n ): void {\n const impl = serviceClass ?? tokenOrClass as Constructor<T>\n const meta = getClassMetadata(impl)\n const token = serviceClass !== undefined\n ? tokenOrClass\n : (meta?.token ?? tokenOrClass as Constructor<T>)\n this.registrations.set(token, { kind: 'class', useClass: impl, scope: Scope.Singleton })\n }\n\n registerValue<T>(token: InjectionToken<T>, value: T): void {\n this.registrations.set(token, { kind: 'value', value })\n if (this.isRequestScoped) {\n this.invalidateRequestCache(token)\n }\n }\n\n registerFactory<T>(token: InjectionToken<T>, factory: (container: Container) => T): void {\n this.registrations.set(token, { kind: 'factory', factory })\n }\n\n registerExisting<T>(alias: InjectionToken<T>, target: InjectionToken<T>): void {\n this.registrations.set(alias, { kind: 'alias', target })\n }\n\n // ── Resolution ────────────────────────────────────────────────\n\n resolve<T>(token: InjectionToken<T>): T {\n if (isLazyToken(token)) {\n const realToken = token.factory() as InjectionToken<T>\n return this.resolve(realToken)\n }\n\n // Check request cache (request-scoped containers)\n if (this.isRequestScoped && this.requestCache.has(token)) {\n return this.requestCache.get(token) as T\n }\n\n // Check local registrations first\n const reg = this.registrations.get(token)\n if (reg) return this.resolveRegistration(token, reg) as T\n\n // Check parent chain — request-scoped containers resolve locally to access request values\n if (this.parent) {\n const parentReg = this.parent.findRegistration(token)\n if (parentReg) {\n if (this.isRequestScoped) {\n return this.resolveRegistration(token, parentReg) as T\n }\n return this.parent.resolve(token)\n }\n }\n\n // Auto-resolve class constructors: any class with DI decorators can be\n // instantiated without explicit registration\n if (typeof token === 'function') {\n const meta = getClassMetadata(token)\n const scope = meta?.scope ?? Scope.Transient\n const classReg: ClassRegistration = { kind: 'class', useClass: token as unknown as Constructor, scope }\n this.getRoot().registrations.set(token, classReg)\n return this.resolveClass(token, classReg) as T\n }\n\n throw new ContainerError(`No provider for ${tokenToString(token)}. Did you forget to register it?`)\n }\n\n tryResolve<T>(token: InjectionToken<T>): T | undefined {\n const realToken = isLazyToken(token) ? (token.factory() as InjectionToken<T>) : token\n\n // Only \"nothing is registered\" yields undefined for an optional dependency.\n // A provider that exists but throws while constructing is a real error and\n // must surface — swallowing it would silently inject `undefined` and turn a\n // bug into a baffling downstream failure.\n if (!this.isResolvable(realToken)) return undefined\n\n // An optional request-scoped dependency outside a request scope is absent,\n // not an error — mirrors `@inject(..., { isOptional: true })` semantics.\n if (!this.isRequestScoped && this.scopeForToken(realToken) === Scope.Request) return undefined\n\n return this.resolve(realToken)\n }\n\n isRegistered<T>(token: InjectionToken<T>): boolean {\n if (this.registrations.has(token)) return true\n return this.parent?.isRegistered(token) ?? false\n }\n\n /**\n * Whether a token has anything to resolve to: an explicit registration, or a\n * bare class constructor (auto-resolvable). Distinct from {@link isRegistered}\n * so {@link tryResolve} can tell \"no provider\" (→ undefined) apart from\n * \"provider exists but failed\" (→ rethrow).\n */\n private isResolvable(token: InjectionToken): boolean {\n return typeof token === 'function' || this.isRegistered(token)\n }\n\n // ── Conditional ───────────────────────────────────────────────\n\n when(\n predicate: (container: PredicateContainer) => boolean,\n options: WhenOptions = {},\n ): ConditionalBindingBuilder {\n return new ConditionalBindingBuilderImpl(this, predicate, options)\n }\n\n extend<T>(token: InjectionToken<T>, decorator: ExtensionDecorator<T>): void {\n const current = this.resolve<T>(token)\n const decorated = decorator(current, this)\n this.registerValue(token, decorated)\n }\n\n // ── Request Scope ─────────────────────────────────────────────\n\n async runInRequestScope<T>(\n routerContext: RouterContext,\n callback: (requestContainer: Container) => T | Promise<T>,\n ): Promise<T> {\n if (this.isRequestScoped) {\n throw new ContainerError('Cannot call runInRequestScope on a request-scoped container')\n }\n\n const requestContainer = this.createRequestScope(routerContext)\n return await containerStorage.run(requestContainer, () => callback(requestContainer))\n }\n\n createRequestScope(routerContext: RouterContext): Container {\n if (this.isRequestScoped) {\n throw new ContainerError('Cannot call createRequestScope on a request-scoped container')\n }\n\n const child = new Container({ parent: this, isRequestScoped: true })\n child.registerValue(ROUTER_TOKENS.RouterContext, routerContext)\n return child\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────\n\n dispose(): void {\n this.registrations.clear()\n this.singletons.clear()\n this.requestCache.clear()\n this.requestCacheDeps.clear()\n }\n\n // ── Internal ──────────────────────────────────────────────────\n\n /**\n * Transitive constructor dependency tokens of a class, with lazy tokens\n * unwrapped to the concrete token they resolve to. Recorded when a\n * request-scoped instance is cached so {@link invalidateRequestCache} can find\n * dependents.\n *\n * The walk follows class/alias registrations through transient intermediaries:\n * a cached service A that depends on a (non-cached) transient B which depends\n * on token C must still be invalidated when C is re-registered, even though B\n * itself is never cached. Value/factory/lazy providers are not traversed —\n * their dependencies aren't introspectable (factory) or would re-enter a\n * cycle (lazy). Over-collecting is safe: it only rebuilds extra request-scoped\n * instances, which is correct.\n */\n private collectDependencyTokens(Class: Constructor): Set<InjectionToken> {\n const deps = new Set<InjectionToken>()\n const visited = new Set<Constructor>()\n\n const walk = (cls: Constructor): void => {\n if (visited.has(cls)) return\n visited.add(cls)\n for (const { token } of getInjectionTokens(cls).values()) {\n const real = isLazyToken(token) ? token.factory() : token\n deps.add(real)\n const childClass = this.classForToken(real)\n if (childClass) walk(childClass)\n }\n }\n\n walk(Class)\n return deps\n }\n\n /** The implementing class for a token, following class/alias registrations. */\n private classForToken(token: InjectionToken): Constructor | undefined {\n const reg = this.findRegistration(token)\n if (reg) {\n if (reg.kind === 'class') return reg.useClass\n if (reg.kind === 'alias') return this.classForToken(reg.target)\n return undefined\n }\n // A bare constructor token that is auto-resolvable (carries DI metadata).\n if (typeof token === 'function' && getClassMetadata(token as Constructor)) {\n return token as unknown as Constructor\n }\n return undefined\n }\n\n /**\n * The effective scope a token would resolve with, following alias\n * registrations. Bare constructor tokens fall back to their decorator\n * metadata — the same scope {@link resolve} uses when auto-registering.\n */\n private scopeForToken(token: InjectionToken): Scope | undefined {\n const reg = this.findRegistration(token)\n if (reg) {\n if (reg.kind === 'class') return reg.scope\n if (reg.kind === 'alias') return this.scopeForToken(reg.target)\n // Same scope derivation `resolveRegistration` uses for lazy registrations\n if (reg.kind === 'lazy') return getClassMetadata(reg.factory())?.scope ?? Scope.Transient\n return undefined\n }\n if (typeof token === 'function') {\n return getClassMetadata(token as Constructor)?.scope\n }\n return undefined\n }\n\n /**\n * Evict a token from the request cache along with every cached request-scoped\n * instance that transitively depends on it. Re-registering a value must\n * rebuild its dependents (so they pick up the new value) while leaving\n * unrelated cached services intact.\n */\n private invalidateRequestCache(token: InjectionToken): void {\n const invalidated = new Set<InjectionToken>([token])\n\n let changed = true\n while (changed) {\n changed = false\n for (const [cachedToken, deps] of this.requestCacheDeps) {\n if (invalidated.has(cachedToken)) continue\n for (const dep of deps) {\n if (invalidated.has(dep)) {\n invalidated.add(cachedToken)\n changed = true\n break\n }\n }\n }\n }\n\n for (const t of invalidated) {\n this.requestCache.delete(t)\n this.requestCacheDeps.delete(t)\n }\n }\n\n private resolveRegistration(token: InjectionToken, reg: Registration): unknown {\n switch (reg.kind) {\n case 'value':\n return reg.value\n\n case 'alias':\n return this.resolve(reg.target)\n\n case 'factory':\n return reg.factory(this)\n\n case 'lazy': {\n const useClass = reg.factory()\n const scope = getClassMetadata(useClass)?.scope ?? Scope.Transient\n return this.resolveClass(token, { kind: 'class', useClass, scope })\n }\n\n case 'class':\n return this.resolveClass(token, reg)\n }\n }\n\n private resolveClass(token: InjectionToken, reg: ClassRegistration): unknown {\n const { useClass, scope } = reg\n\n // Singleton: check global cache (root or current)\n if (scope === Scope.Singleton) {\n const root = this.getRoot()\n if (root.singletons.has(token)) return root.singletons.get(token)\n // Always construct against the root container. Constructing against a\n // request-scoped child would let the singleton permanently capture that\n // one request's request-scoped dependencies (a captive dependency leaking\n // state across every later request on the isolate). Resolving a @Request\n // dependency from root instead throws the request-scope error below,\n // surfacing the illegal singleton→request dependency loudly.\n const instance = root.instantiate(useClass)\n root.singletons.set(token, instance)\n return instance\n }\n\n // Request: cache in the request-scoped container\n if (scope === Scope.Request) {\n if (!this.isRequestScoped) {\n throw new ContainerError(\n `Cannot resolve request-scoped provider ${tokenToString(token)} outside a request scope. ` +\n `Resolve it within an HTTP request, or via runInScope()/runInRequestScope() for queues, cron, and other non-HTTP entrypoints.`,\n )\n }\n if (this.requestCache.has(token)) return this.requestCache.get(token)\n const instance = this.instantiate(useClass)\n this.requestCache.set(token, instance)\n this.requestCacheDeps.set(token, this.collectDependencyTokens(useClass))\n return instance\n }\n\n // Transient: always new instance\n return this.instantiate(useClass)\n }\n\n private instantiate(Class: Constructor): unknown {\n const root = this.getRoot()\n\n // A class re-entering its own construction is a circular dependency. Detect\n // it and throw a clear error naming the cycle instead of recursing into a\n // stack overflow. `lazy()` only defers a forward *reference*, not\n // resolution, so it cannot break a true runtime cycle — the graph must be\n // refactored.\n if (root.resolutionStack.includes(Class)) {\n const cycle = [...root.resolutionStack, Class].map((c) => c.name).join(' → ')\n throw new ContainerError(\n `Circular dependency detected while constructing: ${cycle}. ` +\n `Break the cycle by extracting the shared dependency, or inject a provider/factory instead of the instance.`,\n )\n }\n\n root.resolutionStack.push(Class)\n try {\n const injections = getInjectionTokens(Class)\n\n // Without reflect-metadata there is no `design:paramtypes` fallback, so every\n // constructor dependency must carry an explicit @inject. A required parameter\n // with no entry would otherwise be silently injected as `undefined`; fail loud.\n if (injections.size === 0) {\n if (Class.length > 0) {\n throw new ContainerError(\n `${Class.name} has ${Class.length} required constructor parameter(s) but none are decorated with @inject. ` +\n `Every constructor dependency must be explicitly injected.`,\n )\n }\n return new Class()\n }\n\n const maxIndex = Math.max(...injections.keys())\n const args: unknown[] = new Array(maxIndex + 1)\n\n for (let index = 0; index <= maxIndex; index++) {\n const entry = injections.get(index)\n if (!entry) {\n throw new ContainerError(\n `${Class.name} is missing @inject on constructor parameter ${index}. ` +\n `Every constructor dependency must be explicitly injected.`,\n )\n }\n args[index] = entry.optional ? this.tryResolve(entry.token) : this.resolve(entry.token)\n }\n\n return new Class(...args)\n } finally {\n root.resolutionStack.pop()\n }\n }\n\n findRegistration(token: InjectionToken): Registration | undefined {\n const local = this.registrations.get(token)\n if (local) return local\n return this.parent?.findRegistration(token)\n }\n\n /**\n * The global (non-request-scoped) container at the top of the parent chain.\n * Lazy module loading registers providers here so singletons persist across\n * requests even when `load()` is called from within a request scope.\n */\n getRootContainer(): Container {\n return this.getRoot()\n }\n\n private getRoot(): Container {\n if (!this.parent) return this\n return this.parent.getRoot()\n }\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import { Dn as AsyncModuleOptions, Dr as ApplicationError, kn as DynamicModule } from "../index-B_JoEl3V.mjs";
1
+ import { Dn as AsyncModuleOptions, Dr as ApplicationError, kn as DynamicModule } from "../index-C_t8VVQD.mjs";
2
2
  import { a as z } from "../zod-wecrEVAs.mjs";
3
3
  import { a as QueueBinding } from "../consumer-registry-D3iMTSdy.mjs";
4
- import { m as IQueueSender } from "../index-B5JBRcWD.mjs";
4
+ import { m as IQueueSender } from "../index-BPJSBHhq.mjs";
5
5
  import { ReactElement } from "react";
6
6
 
7
7
  //#region src/email/email.error.d.ts
@@ -1,13 +1,13 @@
1
- import { c as Transient, d as inject } from "../di-DseMn-z9.mjs";
1
+ import { c as Transient, d as inject } from "../di-B0NXIdRF.mjs";
2
2
  import { a as ApplicationError } from "../container-storage-BmOJ4_Na.mjs";
3
3
  import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
4
4
  import { LOGGER_TOKENS } from "../logger/index.mjs";
5
- import "../errors-mXYxG0XB.mjs";
5
+ import "../errors-EUtwVfNm.mjs";
6
6
  import { n as Module } from "../module.decorator-CYHY6pG5.mjs";
7
7
  import "../module/index.mjs";
8
8
  import { t as QUEUE_TOKENS } from "../queue.tokens-DjHnFmre.mjs";
9
9
  import "../queue/index.mjs";
10
- import { p as STORAGE_TOKENS } from "../storage-MDZypIE9.mjs";
10
+ import { p as STORAGE_TOKENS } from "../storage-BE6-kzaN.mjs";
11
11
  import { r as z } from "../zod-eKqqhZ5_.mjs";
12
12
  import { t as withZodI18n } from "../validation-CpOjviyT.mjs";
13
13
  //#region src/email/email.error.ts
@@ -1,2 +1,2 @@
1
- import { A as ErrorResponse, C as HttpExceptionContext, D as createHttpExceptionContext, Dr as ApplicationError, E as createCronExceptionContext, O as createQueueExceptionContext, S as ExceptionContext, T as createCliExceptionContext, _ as Reportable, a as isApplicationError, b as CliExceptionContext, c as HttpException, d as ExceptionHandler, f as ApplicationErrorConstructor, g as RenderableCallback, h as LogSeverity, i as ContainerNotInitializedError, j as isErrorResponse, k as Environment, l as abort, m as ErrorPageCallback, n as DatabaseError, o as InternalError, p as ContextCallback, r as StratalNotInitializedError, s as HTTP_STATUS_MESSAGES, t as AuthError, u as DefaultExceptionHandler, v as ReportableCallback, w as QueueExceptionContext, x as CronExceptionContext, y as RespondCallback } from "../index-B_JoEl3V.mjs";
1
+ import { A as ErrorResponse, C as HttpExceptionContext, D as createHttpExceptionContext, Dr as ApplicationError, E as createCronExceptionContext, O as createQueueExceptionContext, S as ExceptionContext, T as createCliExceptionContext, _ as Reportable, a as isApplicationError, b as CliExceptionContext, c as HttpException, d as ExceptionHandler, f as ApplicationErrorConstructor, g as RenderableCallback, h as LogSeverity, i as ContainerNotInitializedError, j as isErrorResponse, k as Environment, l as abort, m as ErrorPageCallback, n as DatabaseError, o as InternalError, p as ContextCallback, r as StratalNotInitializedError, s as HTTP_STATUS_MESSAGES, t as AuthError, u as DefaultExceptionHandler, v as ReportableCallback, w as QueueExceptionContext, x as CronExceptionContext, y as RespondCallback } from "../index-C_t8VVQD.mjs";
2
2
  export { ApplicationError, ApplicationErrorConstructor, AuthError, CliExceptionContext, ContainerNotInitializedError, ContextCallback, CronExceptionContext, DatabaseError, DefaultExceptionHandler, Environment, ErrorPageCallback, ErrorResponse, ExceptionContext, ExceptionHandler, HTTP_STATUS_MESSAGES, HttpException, HttpExceptionContext, InternalError, LogSeverity, QueueExceptionContext, RenderableCallback, Reportable, ReportableCallback, RespondCallback, StratalNotInitializedError, abort, createCliExceptionContext, createCronExceptionContext, createHttpExceptionContext, createQueueExceptionContext, isApplicationError, isErrorResponse };
@@ -1,4 +1,4 @@
1
1
  import { a as ApplicationError, i as ContainerNotInitializedError } from "../container-storage-BmOJ4_Na.mjs";
2
- import { a as DefaultExceptionHandler, c as InternalError, d as abort, i as isErrorResponse, l as HTTP_STATUS_MESSAGES, n as DatabaseError, o as ExceptionHandler, r as StratalNotInitializedError, s as isApplicationError, t as AuthError, u as HttpException } from "../errors-mXYxG0XB.mjs";
3
- import { i as createQueueExceptionContext, n as createCronExceptionContext, r as createHttpExceptionContext, t as createCliExceptionContext } from "../exception-context-kEoMFwze.mjs";
2
+ import { a as DefaultExceptionHandler, c as InternalError, d as abort, i as isErrorResponse, l as HTTP_STATUS_MESSAGES, n as DatabaseError, o as ExceptionHandler, r as StratalNotInitializedError, s as isApplicationError, t as AuthError, u as HttpException } from "../errors-EUtwVfNm.mjs";
3
+ import { i as createQueueExceptionContext, n as createCronExceptionContext, r as createHttpExceptionContext, t as createCliExceptionContext } from "../exception-context-Bd5Hk2c_.mjs";
4
4
  export { ApplicationError, AuthError, ContainerNotInitializedError, DatabaseError, DefaultExceptionHandler, ExceptionHandler, HTTP_STATUS_MESSAGES, HttpException, InternalError, StratalNotInitializedError, abort, createCliExceptionContext, createCronExceptionContext, createHttpExceptionContext, createQueueExceptionContext, isApplicationError, isErrorResponse };
@@ -1,8 +1,8 @@
1
- import { c as Transient, d as inject, n as CONTAINER_TOKEN, r as DI_TOKENS } from "./di-DseMn-z9.mjs";
1
+ import { c as Transient, d as inject, n as CONTAINER_TOKEN, r as DI_TOKENS } from "./di-B0NXIdRF.mjs";
2
2
  import { a as ApplicationError } from "./container-storage-BmOJ4_Na.mjs";
3
3
  import { n as __decorateParam, t as __decorate } from "./decorate-CuAoSZvs.mjs";
4
4
  import { LOGGER_TOKENS } from "./logger/index.mjs";
5
- import "./exception-context-kEoMFwze.mjs";
5
+ import "./exception-context-Bd5Hk2c_.mjs";
6
6
  //#region src/errors/http-exception.ts
7
7
  const HTTP_STATUS_MESSAGES = {
8
8
  400: "Bad Request",
@@ -330,4 +330,4 @@ var AuthError = class extends ApplicationError {
330
330
  //#endregion
331
331
  export { DefaultExceptionHandler as a, InternalError as c, abort as d, isErrorResponse as i, HTTP_STATUS_MESSAGES as l, DatabaseError as n, ExceptionHandler as o, StratalNotInitializedError as r, isApplicationError as s, AuthError as t, HttpException as u };
332
332
 
333
- //# sourceMappingURL=errors-mXYxG0XB.mjs.map
333
+ //# sourceMappingURL=errors-EUtwVfNm.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors-mXYxG0XB.mjs","names":[],"sources":["../src/errors/http-exception.ts","../src/errors/internal-error.ts","../src/errors/is-application-error.ts","../src/errors/exception-handler.ts","../src/errors/default-exception-handler.ts","../src/errors/error-response.ts","../src/errors/stratal-not-initialized.error.ts","../src/errors/database.error.ts","../src/errors/auth.error.ts"],"sourcesContent":["import type { ContentfulStatusCode } from 'hono/utils/http-status'\nimport { ApplicationError } from './application-error'\n\nexport const HTTP_STATUS_MESSAGES: Partial<Record<number, string>> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 409: 'Conflict',\n 413: 'Content Too Large',\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n}\n\nexport class HttpException extends ApplicationError {\n public readonly httpStatus: ContentfulStatusCode\n\n constructor(httpStatus: ContentfulStatusCode, message?: string, cause?: unknown) {\n super(message ?? HTTP_STATUS_MESSAGES[httpStatus] ?? 'Internal Server Error', cause)\n this.httpStatus = httpStatus\n }\n}\n\nexport function abort(\n status: ContentfulStatusCode,\n message?: string,\n): never {\n throw new HttpException(status, message)\n}\n","import { ApplicationError } from './application-error'\n\nexport class InternalError extends ApplicationError {\n constructor(cause?: unknown) {\n super('Internal Server Error', cause)\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport function isApplicationError(error: unknown): error is ApplicationError {\n if (error instanceof ApplicationError) return true\n return error instanceof Error\n && typeof (error as ApplicationError).timestamp === 'string'\n}\n","import type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { inject } from '../di';\nimport { CONTAINER_TOKEN, type Container } from '../di';\nimport { Transient } from '../di/decorators';\nimport { DI_TOKENS } from '../di/tokens';\nimport { type StratalEnv } from '../env';\nimport type { StratalExecutionContext } from '../execution-context';\nimport { LOGGER_TOKENS, type LoggerService } from '../logger';\nimport type { ApplicationError } from './application-error';\nimport type { Environment, ErrorResponse } from './error-response';\nimport type { ExceptionContext, HttpExceptionContext } from './exception-context';\nimport type {\n ApplicationErrorConstructor,\n ContextCallback,\n ErrorPageCallback,\n LogSeverity,\n RenderableCallback,\n Reportable,\n ReportableCallback,\n RespondCallback,\n} from './exception-handler.types';\nimport { HTTP_STATUS_MESSAGES, HttpException } from './http-exception';\nimport { InternalError } from './internal-error';\nimport { isApplicationError } from './is-application-error';\n\ninterface ReportableEntry {\n errorClass: ApplicationErrorConstructor\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: ReportableCallback<any>\n shouldStop: boolean\n}\n\ninterface RenderableEntry {\n errorClass: ApplicationErrorConstructor\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: RenderableCallback<any>\n}\n\n@Transient()\nexport abstract class ExceptionHandler {\n private readonly reportables: ReportableEntry[] = []\n private readonly renderables: RenderableEntry[] = []\n private readonly dontReportSet = new Set<ApplicationErrorConstructor>()\n private readonly levelOverrides = new Map<ApplicationErrorConstructor, LogSeverity>()\n private readonly contextCallbacks: ContextCallback[] = []\n private readonly respondCallbacks: RespondCallback[] = []\n private readonly errorPages: ErrorPageCallback[] = []\n private readonly environment: Environment\n\n constructor(\n @inject(LOGGER_TOKENS.LoggerService) protected readonly logger: LoggerService,\n @inject(DI_TOKENS.CloudflareEnv) protected readonly env: StratalEnv,\n @inject(CONTAINER_TOKEN) private readonly container: Container,\n @inject(DI_TOKENS.ExecutionContext) private readonly executionContext: StratalExecutionContext,\n ) {\n this.environment = this.env.ENVIRONMENT as Environment\n }\n\n abstract register(): void\n\n // ── Public Configuration API ──────────────────────────────────────\n\n reportable<T extends ApplicationError>(\n errorClass: ApplicationErrorConstructor<T>,\n callback: ReportableCallback<T>,\n ): Reportable {\n const entry: ReportableEntry = { errorClass, callback, shouldStop: false }\n this.reportables.push(entry)\n return {\n stop: () => { entry.shouldStop = true },\n }\n }\n\n renderable<T extends ApplicationError>(\n errorClass: ApplicationErrorConstructor<T>,\n callback: RenderableCallback<T>,\n ): void {\n this.renderables.push({ errorClass, callback })\n }\n\n dontReport(errorClasses: ApplicationErrorConstructor[]): void {\n for (const cls of errorClasses) {\n this.dontReportSet.add(cls)\n }\n }\n\n level(errorClass: ApplicationErrorConstructor, severity: LogSeverity): void {\n this.levelOverrides.set(errorClass, severity)\n }\n\n context(callback: ContextCallback): void {\n this.contextCallbacks.push(callback)\n }\n\n respond(callback: RespondCallback): void {\n this.respondCallbacks.push(callback)\n }\n\n errorPage(callback: ErrorPageCallback): void {\n this.errorPages.push(callback)\n }\n\n resolve<T>(token: symbol | (new (...args: unknown[]) => T)): T {\n return this.container.resolve<T>(token)\n }\n\n // ── Pipeline Entry Point ──────────────────────────────────────────\n\n async handle(error: unknown, context: ExceptionContext): Promise<Response> {\n const appError = this.normalizeError(error)\n\n this.executionContext.waitUntil(this.performReport(appError, context))\n\n const response = await this.performRender(appError, context)\n\n return this.applyRespondCallbacks(response, appError, context)\n }\n\n // ── Internals ─────────────────────────────────────────────────────\n\n private normalizeError(error: unknown): ApplicationError {\n if (isApplicationError(error)) {\n return error\n }\n\n return new InternalError(error)\n }\n\n private async performReport(error: ApplicationError, context: ExceptionContext): Promise<void> {\n if (this.shouldNotReport(error)) return\n\n const entry = this.findReportable(error)\n if (entry) {\n await entry.callback(error, context)\n if (entry.shouldStop) return\n }\n\n this.defaultReport(error)\n }\n\n private async performRender(error: ApplicationError, context: ExceptionContext): Promise<Response> {\n const entry = this.findRenderable(error)\n if (entry) {\n const result = entry.callback(error, context)\n if (result !== undefined) {\n return this.toResponse(await result, error)\n }\n }\n\n return await this.defaultRender(error, context)\n }\n\n private applyRespondCallbacks(\n response: Response,\n error: ApplicationError,\n context: ExceptionContext,\n ): Response {\n let result = response\n for (const callback of this.respondCallbacks) {\n result = callback(result, error, context)\n }\n return result\n }\n\n private shouldNotReport(error: ApplicationError): boolean {\n for (const cls of this.dontReportSet) {\n if (error instanceof cls) return true\n }\n return false\n }\n\n private findReportable(error: ApplicationError): ReportableEntry | undefined {\n let best: ReportableEntry | undefined\n for (const entry of this.reportables) {\n if (this.matchesErrorClass(error, entry.errorClass)) {\n if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) {\n best = entry\n }\n }\n }\n return best\n }\n\n private findRenderable(error: ApplicationError): RenderableEntry | undefined {\n let best: RenderableEntry | undefined\n for (const entry of this.renderables) {\n if (this.matchesErrorClass(error, entry.errorClass)) {\n if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) {\n best = entry\n }\n }\n }\n return best\n }\n\n private matchesErrorClass(error: ApplicationError, cls: ApplicationErrorConstructor): boolean {\n if (error instanceof cls) return true\n return (error as Error).constructor.name === cls.name\n }\n\n private defaultReport(error: ApplicationError): void {\n const severity = this.resolveSeverity(error)\n const globalContext = this.gatherContext()\n\n const logData: Record<string, unknown> = {\n message: error.message,\n timestamp: error.timestamp,\n name: error.name,\n stack: error.stack,\n ...globalContext,\n }\n\n const chain = serializeErrorChain(error)\n if (chain) {\n logData.cause = chain\n }\n\n switch (severity) {\n case 'debug':\n this.logger.debug('[ApplicationError]', logData)\n break\n case 'info':\n this.logger.info('[ApplicationError]', logData)\n break\n case 'warn':\n this.logger.warn('[ApplicationError]', logData)\n break\n case 'error':\n this.logger.error('[ApplicationError]', logData)\n break\n }\n }\n\n private async defaultRender(error: ApplicationError, context: ExceptionContext): Promise<Response> {\n const status = this.resolveStatus(error)\n const errorResponse = this.buildErrorResponse(error, status)\n\n if (context.type === 'http' && this.wantsHtml(context)) {\n for (const callback of this.errorPages) {\n try {\n const result = await callback(errorResponse, status, context, error)\n if (result !== undefined) return result\n } catch (callbackError) {\n this.logger.warn('errorPage callback failed, falling back to next handler', {\n error: callbackError instanceof Error ? callbackError.message : String(callbackError),\n })\n }\n }\n return this.renderDefaultHtml(errorResponse, status)\n }\n\n return Response.json(errorResponse, { status })\n }\n\n // ── Content Negotiation ──────────────────────────────────────────\n\n protected wantsHtml(context: HttpExceptionContext): boolean {\n const accept = context.ctx.c.req.header('accept') ?? ''\n return accept.includes('text/html')\n }\n\n protected renderDefaultHtml(\n errorResponse: ErrorResponse,\n status: ContentfulStatusCode,\n ): Response {\n const title = this.escapeHtml(errorResponse.message)\n const html = `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${status} - ${title}</title>\n<link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.svg\">\n<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,-apple-system,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f8fafc;color:#334155}.container{text-align:center;padding:2rem}.status{font-size:6rem;font-weight:800;color:#13c397;line-height:1}.message{font-size:1.25rem;color:#64748b;margin-top:1rem}</style>\n</head><body><div class=\"container\"><div class=\"status\">${status}</div><div class=\"message\">${title}</div></div></body></html>`\n return new Response(html, {\n status,\n headers: { 'content-type': 'text/html; charset=utf-8' },\n })\n }\n\n private resolveStatus(error: ApplicationError): ContentfulStatusCode {\n if (error instanceof HttpException) return error.httpStatus\n const httpStatus = (error as { httpStatus?: number }).httpStatus\n if (typeof httpStatus === 'number') return httpStatus as ContentfulStatusCode\n return 500\n }\n\n private buildErrorResponse(error: ApplicationError, status: ContentfulStatusCode): ErrorResponse {\n const isServerError = status >= 500\n const isDev = this.environment === 'development'\n const message = isServerError && !isDev\n ? (HTTP_STATUS_MESSAGES[status] ?? 'Internal Server Error')\n : error.message\n\n return {\n message,\n timestamp: error.timestamp,\n stack: isDev ? error.stack : undefined,\n }\n }\n\n private escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n }\n\n private toResponse(result: Response | ErrorResponse, error: ApplicationError): Response {\n if (result instanceof Response) return result\n const status = this.resolveStatus(error)\n return Response.json(result, { status })\n }\n\n private resolveSeverity(error: ApplicationError): LogSeverity {\n let bestClass: ApplicationErrorConstructor | undefined\n let bestSeverity: LogSeverity | undefined\n\n for (const [cls, severity] of this.levelOverrides) {\n if (error instanceof cls) {\n if (!bestClass || cls.prototype instanceof bestClass) {\n bestClass = cls\n bestSeverity = severity\n }\n }\n }\n\n if (bestSeverity) return bestSeverity\n\n const status = this.resolveStatus(error)\n return this.getDefaultSeverity(status)\n }\n\n private getDefaultSeverity(status: number): LogSeverity {\n if (status >= 500) return 'error'\n if (status >= 400) return 'warn'\n return 'error'\n }\n\n private gatherContext(): Record<string, unknown> {\n if (this.contextCallbacks.length === 0) return {}\n const merged: Record<string, unknown> = {}\n for (const callback of this.contextCallbacks) {\n Object.assign(merged, callback())\n }\n return merged\n }\n}\n\ninterface SerializedErrorNode {\n name: string\n message: string\n stack?: string\n cause?: SerializedErrorNode | { value: unknown }\n errors?: SerializedErrorNode[]\n}\n\nconst MAX_CAUSE_DEPTH = 5\n\nfunction serializeErrorChain(error: Error): SerializedErrorNode | undefined {\n const cause = (error as { cause?: unknown }).cause\n const aggregated = error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0\n if (cause === undefined && !aggregated) {\n return undefined\n }\n if (cause !== undefined) {\n return cause instanceof Error\n ? serializeErrorNode(cause, 0)\n : ({ value: cause } as unknown as SerializedErrorNode)\n }\n return {\n name: error.name,\n message: error.message,\n errors: (error as AggregateError).errors.map((inner) =>\n inner instanceof Error\n ? serializeErrorNode(inner, 0)\n : { name: 'Unknown', message: String(inner) },\n ),\n }\n}\n\nfunction serializeErrorNode(error: Error, depth: number): SerializedErrorNode {\n const out: SerializedErrorNode = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n\n if (depth >= MAX_CAUSE_DEPTH) return out\n\n if (error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0) {\n out.errors = error.errors.map((inner) =>\n inner instanceof Error\n ? serializeErrorNode(inner, depth + 1)\n : { name: 'Unknown', message: String(inner) },\n )\n }\n\n const cause = (error as { cause?: unknown }).cause\n if (cause !== undefined) {\n out.cause = cause instanceof Error\n ? serializeErrorNode(cause, depth + 1)\n : { value: cause }\n }\n\n return out\n}\n","import { Transient } from '../di/decorators';\nimport { ExceptionHandler } from './exception-handler';\n\n/**\n * DefaultExceptionHandler — the built-in exception handler used when no\n * custom handler is provided via `ApplicationConfig.exceptionHandler`.\n *\n * Has an empty `register()` method, so all exceptions flow through the\n * default pipeline: severity-based logging, i18n translation, and JSON\n * error response serialization.\n *\n * To customize exception handling, extend {@link ExceptionHandler} and\n * override `register()`, then pass your class to the Stratal config:\n *\n * @example\n * ```typescript\n * new Stratal({\n * module: AppModule,\n * exceptionHandler: AppExceptionHandler,\n * })\n * ```\n */\n@Transient()\nexport class DefaultExceptionHandler extends ExceptionHandler {\n register(): void {\n // No custom configuration — uses all defaults\n }\n}\n","export type Environment = 'development' | 'staging' | 'production'\n\nexport interface ErrorResponse {\n message: string\n timestamp: string\n stack?: string\n}\n\nexport function isErrorResponse(obj: unknown): obj is ErrorResponse {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'message' in obj &&\n typeof (obj as ErrorResponse).message === 'string' &&\n 'timestamp' in obj &&\n typeof (obj as ErrorResponse).timestamp === 'string'\n )\n}\n","import { ApplicationError } from './application-error'\n\nexport class StratalNotInitializedError extends ApplicationError {\n constructor() {\n super('Stratal has not been initialized. Ensure you export a Stratal instance as the default export.')\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport class DatabaseError extends ApplicationError {\n constructor(message?: string, cause?: unknown) {\n super(message ?? 'Database error', cause)\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport class AuthError extends ApplicationError {\n constructor(message?: string, cause?: unknown) {\n super(message ?? 'Authentication error', cause)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"errors-EUtwVfNm.mjs","names":[],"sources":["../src/errors/http-exception.ts","../src/errors/internal-error.ts","../src/errors/is-application-error.ts","../src/errors/exception-handler.ts","../src/errors/default-exception-handler.ts","../src/errors/error-response.ts","../src/errors/stratal-not-initialized.error.ts","../src/errors/database.error.ts","../src/errors/auth.error.ts"],"sourcesContent":["import type { ContentfulStatusCode } from 'hono/utils/http-status'\nimport { ApplicationError } from './application-error'\n\nexport const HTTP_STATUS_MESSAGES: Partial<Record<number, string>> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 402: 'Payment Required',\n 403: 'Forbidden',\n 404: 'Not Found',\n 409: 'Conflict',\n 413: 'Content Too Large',\n 422: 'Unprocessable Entity',\n 423: 'Locked',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n}\n\nexport class HttpException extends ApplicationError {\n public readonly httpStatus: ContentfulStatusCode\n\n constructor(httpStatus: ContentfulStatusCode, message?: string, cause?: unknown) {\n super(message ?? HTTP_STATUS_MESSAGES[httpStatus] ?? 'Internal Server Error', cause)\n this.httpStatus = httpStatus\n }\n}\n\nexport function abort(\n status: ContentfulStatusCode,\n message?: string,\n): never {\n throw new HttpException(status, message)\n}\n","import { ApplicationError } from './application-error'\n\nexport class InternalError extends ApplicationError {\n constructor(cause?: unknown) {\n super('Internal Server Error', cause)\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport function isApplicationError(error: unknown): error is ApplicationError {\n if (error instanceof ApplicationError) return true\n return error instanceof Error\n && typeof (error as ApplicationError).timestamp === 'string'\n}\n","import type { ContentfulStatusCode } from 'hono/utils/http-status';\nimport { inject } from '../di';\nimport { CONTAINER_TOKEN, type Container } from '../di';\nimport { Transient } from '../di/decorators';\nimport { DI_TOKENS } from '../di/tokens';\nimport { type StratalEnv } from '../env';\nimport type { StratalExecutionContext } from '../execution-context';\nimport { LOGGER_TOKENS, type LoggerService } from '../logger';\nimport type { ApplicationError } from './application-error';\nimport type { Environment, ErrorResponse } from './error-response';\nimport type { ExceptionContext, HttpExceptionContext } from './exception-context';\nimport type {\n ApplicationErrorConstructor,\n ContextCallback,\n ErrorPageCallback,\n LogSeverity,\n RenderableCallback,\n Reportable,\n ReportableCallback,\n RespondCallback,\n} from './exception-handler.types';\nimport { HTTP_STATUS_MESSAGES, HttpException } from './http-exception';\nimport { InternalError } from './internal-error';\nimport { isApplicationError } from './is-application-error';\n\ninterface ReportableEntry {\n errorClass: ApplicationErrorConstructor\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: ReportableCallback<any>\n shouldStop: boolean\n}\n\ninterface RenderableEntry {\n errorClass: ApplicationErrorConstructor\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callback: RenderableCallback<any>\n}\n\n@Transient()\nexport abstract class ExceptionHandler {\n private readonly reportables: ReportableEntry[] = []\n private readonly renderables: RenderableEntry[] = []\n private readonly dontReportSet = new Set<ApplicationErrorConstructor>()\n private readonly levelOverrides = new Map<ApplicationErrorConstructor, LogSeverity>()\n private readonly contextCallbacks: ContextCallback[] = []\n private readonly respondCallbacks: RespondCallback[] = []\n private readonly errorPages: ErrorPageCallback[] = []\n private readonly environment: Environment\n\n constructor(\n @inject(LOGGER_TOKENS.LoggerService) protected readonly logger: LoggerService,\n @inject(DI_TOKENS.CloudflareEnv) protected readonly env: StratalEnv,\n @inject(CONTAINER_TOKEN) private readonly container: Container,\n @inject(DI_TOKENS.ExecutionContext) private readonly executionContext: StratalExecutionContext,\n ) {\n this.environment = this.env.ENVIRONMENT as Environment\n }\n\n abstract register(): void\n\n // ── Public Configuration API ──────────────────────────────────────\n\n reportable<T extends ApplicationError>(\n errorClass: ApplicationErrorConstructor<T>,\n callback: ReportableCallback<T>,\n ): Reportable {\n const entry: ReportableEntry = { errorClass, callback, shouldStop: false }\n this.reportables.push(entry)\n return {\n stop: () => { entry.shouldStop = true },\n }\n }\n\n renderable<T extends ApplicationError>(\n errorClass: ApplicationErrorConstructor<T>,\n callback: RenderableCallback<T>,\n ): void {\n this.renderables.push({ errorClass, callback })\n }\n\n dontReport(errorClasses: ApplicationErrorConstructor[]): void {\n for (const cls of errorClasses) {\n this.dontReportSet.add(cls)\n }\n }\n\n level(errorClass: ApplicationErrorConstructor, severity: LogSeverity): void {\n this.levelOverrides.set(errorClass, severity)\n }\n\n context(callback: ContextCallback): void {\n this.contextCallbacks.push(callback)\n }\n\n respond(callback: RespondCallback): void {\n this.respondCallbacks.push(callback)\n }\n\n errorPage(callback: ErrorPageCallback): void {\n this.errorPages.push(callback)\n }\n\n resolve<T>(token: symbol | (new (...args: unknown[]) => T)): T {\n return this.container.resolve<T>(token)\n }\n\n // ── Pipeline Entry Point ──────────────────────────────────────────\n\n async handle(error: unknown, context: ExceptionContext): Promise<Response> {\n const appError = this.normalizeError(error)\n\n this.executionContext.waitUntil(this.performReport(appError, context))\n\n const response = await this.performRender(appError, context)\n\n return this.applyRespondCallbacks(response, appError, context)\n }\n\n // ── Internals ─────────────────────────────────────────────────────\n\n private normalizeError(error: unknown): ApplicationError {\n if (isApplicationError(error)) {\n return error\n }\n\n return new InternalError(error)\n }\n\n private async performReport(error: ApplicationError, context: ExceptionContext): Promise<void> {\n if (this.shouldNotReport(error)) return\n\n const entry = this.findReportable(error)\n if (entry) {\n await entry.callback(error, context)\n if (entry.shouldStop) return\n }\n\n this.defaultReport(error)\n }\n\n private async performRender(error: ApplicationError, context: ExceptionContext): Promise<Response> {\n const entry = this.findRenderable(error)\n if (entry) {\n const result = entry.callback(error, context)\n if (result !== undefined) {\n return this.toResponse(await result, error)\n }\n }\n\n return await this.defaultRender(error, context)\n }\n\n private applyRespondCallbacks(\n response: Response,\n error: ApplicationError,\n context: ExceptionContext,\n ): Response {\n let result = response\n for (const callback of this.respondCallbacks) {\n result = callback(result, error, context)\n }\n return result\n }\n\n private shouldNotReport(error: ApplicationError): boolean {\n for (const cls of this.dontReportSet) {\n if (error instanceof cls) return true\n }\n return false\n }\n\n private findReportable(error: ApplicationError): ReportableEntry | undefined {\n let best: ReportableEntry | undefined\n for (const entry of this.reportables) {\n if (this.matchesErrorClass(error, entry.errorClass)) {\n if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) {\n best = entry\n }\n }\n }\n return best\n }\n\n private findRenderable(error: ApplicationError): RenderableEntry | undefined {\n let best: RenderableEntry | undefined\n for (const entry of this.renderables) {\n if (this.matchesErrorClass(error, entry.errorClass)) {\n if (!best || !this.matchesErrorClass(error, best.errorClass) || entry.errorClass.prototype instanceof best.errorClass) {\n best = entry\n }\n }\n }\n return best\n }\n\n private matchesErrorClass(error: ApplicationError, cls: ApplicationErrorConstructor): boolean {\n if (error instanceof cls) return true\n return (error as Error).constructor.name === cls.name\n }\n\n private defaultReport(error: ApplicationError): void {\n const severity = this.resolveSeverity(error)\n const globalContext = this.gatherContext()\n\n const logData: Record<string, unknown> = {\n message: error.message,\n timestamp: error.timestamp,\n name: error.name,\n stack: error.stack,\n ...globalContext,\n }\n\n const chain = serializeErrorChain(error)\n if (chain) {\n logData.cause = chain\n }\n\n switch (severity) {\n case 'debug':\n this.logger.debug('[ApplicationError]', logData)\n break\n case 'info':\n this.logger.info('[ApplicationError]', logData)\n break\n case 'warn':\n this.logger.warn('[ApplicationError]', logData)\n break\n case 'error':\n this.logger.error('[ApplicationError]', logData)\n break\n }\n }\n\n private async defaultRender(error: ApplicationError, context: ExceptionContext): Promise<Response> {\n const status = this.resolveStatus(error)\n const errorResponse = this.buildErrorResponse(error, status)\n\n if (context.type === 'http' && this.wantsHtml(context)) {\n for (const callback of this.errorPages) {\n try {\n const result = await callback(errorResponse, status, context, error)\n if (result !== undefined) return result\n } catch (callbackError) {\n this.logger.warn('errorPage callback failed, falling back to next handler', {\n error: callbackError instanceof Error ? callbackError.message : String(callbackError),\n })\n }\n }\n return this.renderDefaultHtml(errorResponse, status)\n }\n\n return Response.json(errorResponse, { status })\n }\n\n // ── Content Negotiation ──────────────────────────────────────────\n\n protected wantsHtml(context: HttpExceptionContext): boolean {\n const accept = context.ctx.c.req.header('accept') ?? ''\n return accept.includes('text/html')\n }\n\n protected renderDefaultHtml(\n errorResponse: ErrorResponse,\n status: ContentfulStatusCode,\n ): Response {\n const title = this.escapeHtml(errorResponse.message)\n const html = `<!DOCTYPE html>\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n<title>${status} - ${title}</title>\n<link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.svg\">\n<style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:system-ui,-apple-system,sans-serif;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f8fafc;color:#334155}.container{text-align:center;padding:2rem}.status{font-size:6rem;font-weight:800;color:#13c397;line-height:1}.message{font-size:1.25rem;color:#64748b;margin-top:1rem}</style>\n</head><body><div class=\"container\"><div class=\"status\">${status}</div><div class=\"message\">${title}</div></div></body></html>`\n return new Response(html, {\n status,\n headers: { 'content-type': 'text/html; charset=utf-8' },\n })\n }\n\n private resolveStatus(error: ApplicationError): ContentfulStatusCode {\n if (error instanceof HttpException) return error.httpStatus\n const httpStatus = (error as { httpStatus?: number }).httpStatus\n if (typeof httpStatus === 'number') return httpStatus as ContentfulStatusCode\n return 500\n }\n\n private buildErrorResponse(error: ApplicationError, status: ContentfulStatusCode): ErrorResponse {\n const isServerError = status >= 500\n const isDev = this.environment === 'development'\n const message = isServerError && !isDev\n ? (HTTP_STATUS_MESSAGES[status] ?? 'Internal Server Error')\n : error.message\n\n return {\n message,\n timestamp: error.timestamp,\n stack: isDev ? error.stack : undefined,\n }\n }\n\n private escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n }\n\n private toResponse(result: Response | ErrorResponse, error: ApplicationError): Response {\n if (result instanceof Response) return result\n const status = this.resolveStatus(error)\n return Response.json(result, { status })\n }\n\n private resolveSeverity(error: ApplicationError): LogSeverity {\n let bestClass: ApplicationErrorConstructor | undefined\n let bestSeverity: LogSeverity | undefined\n\n for (const [cls, severity] of this.levelOverrides) {\n if (error instanceof cls) {\n if (!bestClass || cls.prototype instanceof bestClass) {\n bestClass = cls\n bestSeverity = severity\n }\n }\n }\n\n if (bestSeverity) return bestSeverity\n\n const status = this.resolveStatus(error)\n return this.getDefaultSeverity(status)\n }\n\n private getDefaultSeverity(status: number): LogSeverity {\n if (status >= 500) return 'error'\n if (status >= 400) return 'warn'\n return 'error'\n }\n\n private gatherContext(): Record<string, unknown> {\n if (this.contextCallbacks.length === 0) return {}\n const merged: Record<string, unknown> = {}\n for (const callback of this.contextCallbacks) {\n Object.assign(merged, callback())\n }\n return merged\n }\n}\n\ninterface SerializedErrorNode {\n name: string\n message: string\n stack?: string\n cause?: SerializedErrorNode | { value: unknown }\n errors?: SerializedErrorNode[]\n}\n\nconst MAX_CAUSE_DEPTH = 5\n\nfunction serializeErrorChain(error: Error): SerializedErrorNode | undefined {\n const cause = (error as { cause?: unknown }).cause\n const aggregated = error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0\n if (cause === undefined && !aggregated) {\n return undefined\n }\n if (cause !== undefined) {\n return cause instanceof Error\n ? serializeErrorNode(cause, 0)\n : ({ value: cause } as unknown as SerializedErrorNode)\n }\n return {\n name: error.name,\n message: error.message,\n errors: (error as AggregateError).errors.map((inner) =>\n inner instanceof Error\n ? serializeErrorNode(inner, 0)\n : { name: 'Unknown', message: String(inner) },\n ),\n }\n}\n\nfunction serializeErrorNode(error: Error, depth: number): SerializedErrorNode {\n const out: SerializedErrorNode = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n\n if (depth >= MAX_CAUSE_DEPTH) return out\n\n if (error instanceof AggregateError && Array.isArray(error.errors) && error.errors.length > 0) {\n out.errors = error.errors.map((inner) =>\n inner instanceof Error\n ? serializeErrorNode(inner, depth + 1)\n : { name: 'Unknown', message: String(inner) },\n )\n }\n\n const cause = (error as { cause?: unknown }).cause\n if (cause !== undefined) {\n out.cause = cause instanceof Error\n ? serializeErrorNode(cause, depth + 1)\n : { value: cause }\n }\n\n return out\n}\n","import { Transient } from '../di/decorators';\nimport { ExceptionHandler } from './exception-handler';\n\n/**\n * DefaultExceptionHandler — the built-in exception handler used when no\n * custom handler is provided via `ApplicationConfig.exceptionHandler`.\n *\n * Has an empty `register()` method, so all exceptions flow through the\n * default pipeline: severity-based logging, i18n translation, and JSON\n * error response serialization.\n *\n * To customize exception handling, extend {@link ExceptionHandler} and\n * override `register()`, then pass your class to the Stratal config:\n *\n * @example\n * ```typescript\n * new Stratal({\n * module: AppModule,\n * exceptionHandler: AppExceptionHandler,\n * })\n * ```\n */\n@Transient()\nexport class DefaultExceptionHandler extends ExceptionHandler {\n register(): void {\n // No custom configuration — uses all defaults\n }\n}\n","export type Environment = 'development' | 'staging' | 'production'\n\nexport interface ErrorResponse {\n message: string\n timestamp: string\n stack?: string\n}\n\nexport function isErrorResponse(obj: unknown): obj is ErrorResponse {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n 'message' in obj &&\n typeof (obj as ErrorResponse).message === 'string' &&\n 'timestamp' in obj &&\n typeof (obj as ErrorResponse).timestamp === 'string'\n )\n}\n","import { ApplicationError } from './application-error'\n\nexport class StratalNotInitializedError extends ApplicationError {\n constructor() {\n super('Stratal has not been initialized. Ensure you export a Stratal instance as the default export.')\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport class DatabaseError extends ApplicationError {\n constructor(message?: string, cause?: unknown) {\n super(message ?? 'Database error', cause)\n }\n}\n","import { ApplicationError } from './application-error'\n\nexport class AuthError extends ApplicationError {\n constructor(message?: string, cause?: unknown) {\n super(message ?? 'Authentication error', cause)\n }\n}\n"],"mappings":"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"}
@@ -143,6 +143,13 @@ interface IEventRegistry {
143
143
  emit<E extends EventName>(event: E, context?: Partial<EventContext<E>>): Promise<void>;
144
144
  off<E extends EventName>(event: E, handler: EventHandler<E>): void;
145
145
  once<E extends EventName>(event: E, handler: EventHandler<E>, options?: EventOptions): void;
146
+ /**
147
+ * Whether any registered handler matches the event, using the same
148
+ * pattern matching as `emit()` (exact, model wildcard, operation
149
+ * wildcard, phase wildcard). Lets emitters skip expensive payload
150
+ * construction when nobody is listening.
151
+ */
152
+ hasListeners(event: EventName): boolean;
146
153
  }
147
154
  /**
148
155
  * Metadata stored by `@On()` decorator for each handler method
@@ -190,6 +197,7 @@ declare class EventRegistry implements IEventRegistry {
190
197
  on<E extends EventName>(event: E, handler: EventHandler<E>, options?: EventOptions): void;
191
198
  emit<E extends EventName>(event: E, context?: Partial<EventContext<E>>): Promise<void>;
192
199
  off<E extends EventName>(event: E, handler: EventHandler<E>): void;
200
+ hasListeners(event: EventName): boolean;
193
201
  once<E extends EventName>(event: E, handler: EventHandler<E>, options?: EventOptions): void;
194
202
  /**
195
203
  * Find all handlers matching the event using pattern matching.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/events/constants.ts","../../src/events/decorators/listener.decorator.ts","../../src/events/types.ts","../../src/events/decorators/on.decorator.ts","../../src/events/event-registry.ts","../../src/events/events.module.ts"],"mappings":";;;;;;;;AAMA;;cAAa,sBAAA;EAAA,SAGH,WAAA;EAAA,SAAA,cAAA;AAAA;;;;;;AAHV;;;;;;;;ACgBA;;;;;;iBAAgB,QAAA,eACa,WAAA,EAAa,MAAA,EAAQ,CAAA,KAAC,CAAA;;;;iBAUnC,UAAA,CAAW,MAAmB,EAAX,WAAW;;;;;;;AD3B9C;;;;;;;;ACgBA;;;;;;;;;;;;;;AACmD;AAUnD;;;;AAA8C;;;;ACS9C;;UAAiB,mBAAA;AAAmB;AAMpC;;;AANoC,KAMxB,SAAA,SAAkB,mBAAA,0BAE1B,OAAA,OAAc,mBAAA;;;;;;;;;AAAmB;AAkBrC;;;UAAiB,kBAAA;EACf,IAAA,EAAM,KAAA;EACN,QAAA,GAAW,MAAM;AAAA;;;;AAAA;AAQnB;KAAY,YAAA,WAAuB,SAAA,GAAY,SAAA,IAC7C,CAAA,eAAgB,mBAAA,GACd,mBAAA,CAAoB,CAAA;EAClB,IAAA;EAAgB,MAAA;AAAA;;;;UASL,YAAA;EAVQ;EAYvB,QAAA;EAduB;;;;;;;;EAuBvB,QAAQ;AAAA;AApBkB;AAS5B;;AAT4B,KA0BhB,YAAA,WAAuB,SAAA,GAAY,SAAA,KAC7C,OAAA,EAAS,YAAA,CAAa,CAAA,MACnB,OAAA;;AARK;AAMV;;UAQiB,iBAAA;EACf,OAAA,EAAS,YAAY;EACrB,QAAA;EACA,QAAA;AAAA;;;;UAMe,cAAA;EACf,EAAA,WAAa,SAAA,EACX,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,YAAA,CAAa,CAAA,GACtB,OAAA,GAAU,YAAA;EAGZ,IAAA,WAAe,SAAA,EACb,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,OAAA,CAAQ,YAAA,CAAa,CAAA,KAC9B,OAAA;EAEH,GAAA,WAAc,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA;EAEzD,IAAA,WAAe,SAAA,EACb,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,YAAA,CAAa,CAAA,GACtB,OAAA,GAAU,YAAA;AAAA;;;AAhCF;UA2CK,uBAAA;EACf,UAAA;EACA,KAAA;EACA,OAAA,GAAU,YAAY;AAAA;;;;;;AFrJxB;;;;;;;;ACgBA;;;;;;;;;;iBEGgB,EAAA,WAAa,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,GAAU,YAAA,IAExD,MAAA,UACA,WAAA,UACA,WAAA,EAAa,kBAAA;;;;iBAsBD,mBAAA,CAAoB,MAAA,WAAiB,uBAAuB;;;cCrC/D,aAAA,YAAyB,cAAA;EAAA,iBAImB,GAAA;EAAA,iBACC,MAAA;EAAA,QAJhD,QAAA;cAG+C,GAAA,EAAK,gBAAA,EACJ,MAAA,EAAQ,aAAA;EAGhE,EAAA,WAAa,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA,GAAI,OAAA,GAAU,YAAA;EAkBhE,IAAA,WAAe,SAAA,EACnB,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,OAAA,CAAQ,YAAA,CAAa,CAAA,KAC9B,OAAA;EAmCH,GAAA,WAAc,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA;EAczD,IAAA,WAAe,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA,GAAI,OAAA,GAAU,YAAA;;AHtE1E;;;UGmFU,oBAAA;EHlFwC;;;EAAA,QGuHxC,kBAAA;EHvHS;;;EAAA,QG0IH,cAAA;AAAA;;;;;;;AJ3JhB;;;;cKWa,YAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/events/constants.ts","../../src/events/decorators/listener.decorator.ts","../../src/events/types.ts","../../src/events/decorators/on.decorator.ts","../../src/events/event-registry.ts","../../src/events/events.module.ts"],"mappings":";;;;;;;;AAMA;;cAAa,sBAAA;EAAA,SAGH,WAAA;EAAA,SAAA,cAAA;AAAA;;;;;;AAHV;;;;;;;;ACgBA;;;;;;iBAAgB,QAAA,eACa,WAAA,EAAa,MAAA,EAAQ,CAAA,KAAC,CAAA;;;;iBAUnC,UAAA,CAAW,MAAmB,EAAX,WAAW;;;;;;;AD3B9C;;;;;;;;ACgBA;;;;;;;;;;;;;;AACmD;AAUnD;;;;AAA8C;;;;ACS9C;;UAAiB,mBAAA;AAAmB;AAMpC;;;AANoC,KAMxB,SAAA,SAAkB,mBAAA,0BAE1B,OAAA,OAAc,mBAAA;;;;;;;;;AAAmB;AAkBrC;;;UAAiB,kBAAA;EACf,IAAA,EAAM,KAAA;EACN,QAAA,GAAW,MAAM;AAAA;;;;AAAA;AAQnB;KAAY,YAAA,WAAuB,SAAA,GAAY,SAAA,IAC7C,CAAA,eAAgB,mBAAA,GACd,mBAAA,CAAoB,CAAA;EAClB,IAAA;EAAgB,MAAA;AAAA;;;;UASL,YAAA;EAVQ;EAYvB,QAAA;EAduB;;;;;;;;EAuBvB,QAAQ;AAAA;AApBkB;AAS5B;;AAT4B,KA0BhB,YAAA,WAAuB,SAAA,GAAY,SAAA,KAC7C,OAAA,EAAS,YAAA,CAAa,CAAA,MACnB,OAAA;;AARK;AAMV;;UAQiB,iBAAA;EACf,OAAA,EAAS,YAAY;EACrB,QAAA;EACA,QAAA;AAAA;;;;UAMe,cAAA;EACf,EAAA,WAAa,SAAA,EACX,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,YAAA,CAAa,CAAA,GACtB,OAAA,GAAU,YAAA;EAGZ,IAAA,WAAe,SAAA,EACb,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,OAAA,CAAQ,YAAA,CAAa,CAAA,KAC9B,OAAA;EAEH,GAAA,WAAc,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA;EAEzD,IAAA,WAAe,SAAA,EACb,KAAA,EAAO,CAAA,EACP,OAAA,EAAS,YAAA,CAAa,CAAA,GACtB,OAAA,GAAU,YAAA;EAjCZ;;;AACU;AAMZ;;EAmCE,YAAA,CAAa,KAAA,EAAO,SAAA;AAAA;;;;UAUL,uBAAA;EACf,UAAA;EACA,KAAA;EACA,OAAA,GAAU,YAAY;AAAA;;;;;;AF7JxB;;;;;;;;ACgBA;;;;;;;;;;iBEGgB,EAAA,WAAa,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,GAAU,YAAA,IAExD,MAAA,UACA,WAAA,UACA,WAAA,EAAa,kBAAA;;;;iBAsBD,mBAAA,CAAoB,MAAA,WAAiB,uBAAuB;;;cCrC/D,aAAA,YAAyB,cAAA;EAAA,iBAImB,GAAA;EAAA,iBACC,MAAA;EAAA,QAJhD,QAAA;cAG+C,GAAA,EAAK,gBAAA,EACJ,MAAA,EAAQ,aAAA;EAGhE,EAAA,WAAa,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA,GAAI,OAAA,GAAU,YAAA;EAkBhE,IAAA,WAAe,SAAA,EACnB,KAAA,EAAO,CAAA,EACP,OAAA,GAAU,OAAA,CAAQ,YAAA,CAAa,CAAA,KAC9B,OAAA;EAmCH,GAAA,WAAc,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA;EAczD,YAAA,CAAa,KAAA,EAAO,SAAA;EAIpB,IAAA,WAAe,SAAA,EAAW,KAAA,EAAO,CAAA,EAAG,OAAA,EAAS,YAAA,CAAa,CAAA,GAAI,OAAA,GAAU,YAAA;EH1E1D;;;;EAAA,QGuFN,oBAAA;EHtFyC;;;EAAA,QG2HzC,kBAAA;EH3HmB;;;EAAA,QG8Ib,cAAA;AAAA;;;;;;;AJ/JhB;;;;cKWa,YAAA"}
@@ -1,2 +1,2 @@
1
- import { a as getListenerHandlers, c as LISTENER_METADATA_KEYS, i as On, o as Listener, r as EventRegistry, s as isListener, t as EventsModule } from "../events-BXJGZjpG.mjs";
1
+ import { a as getListenerHandlers, c as LISTENER_METADATA_KEYS, i as On, o as Listener, r as EventRegistry, s as isListener, t as EventsModule } from "../events-zbCMY_Gf.mjs";
2
2
  export { EventRegistry, EventsModule, LISTENER_METADATA_KEYS, Listener, On, getListenerHandlers, isListener };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-BBjsoOtd.mjs";
2
- import { c as Transient, d as inject, r as DI_TOKENS, s as Singleton } from "./di-DseMn-z9.mjs";
2
+ import { c as Transient, d as inject, r as DI_TOKENS, s as Singleton } from "./di-B0NXIdRF.mjs";
3
3
  import { n as getMetadata, t as defineMetadata } from "./metadata-DzzprcID.mjs";
4
4
  import { n as __decorateParam, t as __decorate } from "./decorate-CuAoSZvs.mjs";
5
5
  import { LOGGER_TOKENS } from "./logger/index.mjs";
@@ -131,6 +131,9 @@ let EventRegistry = class EventRegistry {
131
131
  else this.handlers.delete(event);
132
132
  this.logger.debug("Event handler unregistered", { event });
133
133
  }
134
+ hasListeners(event) {
135
+ return this.findMatchingHandlers(event).length > 0;
136
+ }
134
137
  once(event, handler, options) {
135
138
  const wrappedHandler = (async (context) => {
136
139
  await handler(context);
@@ -199,4 +202,4 @@ EventsModule = __decorate([Module({ providers: [{
199
202
  //#endregion
200
203
  export { getListenerHandlers as a, LISTENER_METADATA_KEYS as c, On as i, events_module_exports as n, Listener as o, EventRegistry as r, isListener as s, EventsModule as t };
201
204
 
202
- //# sourceMappingURL=events-BXJGZjpG.mjs.map
205
+ //# sourceMappingURL=events-zbCMY_Gf.mjs.map