stratal 0.0.21 → 0.0.23

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 (296) hide show
  1. package/README.md +2 -2
  2. package/dist/bin/cloudflare-workers-loader.mjs +80 -7
  3. package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
  4. package/dist/bin/quarry.mjs +84 -160
  5. package/dist/bin/quarry.mjs.map +1 -1
  6. package/dist/cache/index.d.mts +8 -46
  7. package/dist/cache/index.d.mts.map +1 -1
  8. package/dist/cache/index.mjs +134 -97
  9. package/dist/cache/index.mjs.map +1 -1
  10. package/dist/{cache.service-DsnKuNyO.d.mts → cache.service-uElmBtdS.d.mts} +29 -39
  11. package/dist/cache.service-uElmBtdS.d.mts.map +1 -0
  12. package/dist/{command-BgSlsS4M.mjs → command-BvmUAPPQ.mjs} +15 -4
  13. package/dist/command-BvmUAPPQ.mjs.map +1 -0
  14. package/dist/{command-Cmmf0oHX.d.mts → command-CPhFHjG3.d.mts} +3 -2
  15. package/dist/command-CPhFHjG3.d.mts.map +1 -0
  16. package/dist/command-not-found.error-ONAZ2Bpk.mjs +14 -0
  17. package/dist/command-not-found.error-ONAZ2Bpk.mjs.map +1 -0
  18. package/dist/config/index.d.mts +24 -11
  19. package/dist/config/index.d.mts.map +1 -1
  20. package/dist/config/index.mjs +32 -57
  21. package/dist/config/index.mjs.map +1 -1
  22. package/dist/{consumer-registry-B7yUNh0q.d.mts → consumer-registry-D3iMTSdy.d.mts} +54 -22
  23. package/dist/consumer-registry-D3iMTSdy.d.mts.map +1 -0
  24. package/dist/container-storage-BmOJ4_Na.mjs +52 -0
  25. package/dist/container-storage-BmOJ4_Na.mjs.map +1 -0
  26. package/dist/{controller.decorator-B9vwn0zK.mjs → controller.decorator-C5UVeJS3.mjs} +8 -8
  27. package/dist/controller.decorator-C5UVeJS3.mjs.map +1 -0
  28. package/dist/cron/index.d.mts +103 -7
  29. package/dist/cron/index.d.mts.map +1 -1
  30. package/dist/cron/index.mjs +2 -2
  31. package/dist/cron-job-NesZRk8F.d.mts +58 -0
  32. package/dist/cron-job-NesZRk8F.d.mts.map +1 -0
  33. package/dist/{cron-manager-DQSK8uoV.mjs → cron.module-Bgzq5hiT.mjs} +47 -17
  34. package/dist/cron.module-Bgzq5hiT.mjs.map +1 -0
  35. package/dist/decorate-CuAoSZvs.mjs +16 -0
  36. package/dist/deep-merge-ByiAOZ3r.mjs +18 -0
  37. package/dist/deep-merge-ByiAOZ3r.mjs.map +1 -0
  38. package/dist/di/index.d.mts +2 -2
  39. package/dist/di/index.mjs +4 -3
  40. package/dist/di-DseMn-z9.mjs +524 -0
  41. package/dist/di-DseMn-z9.mjs.map +1 -0
  42. package/dist/email/index.d.mts +40 -122
  43. package/dist/email/index.d.mts.map +1 -1
  44. package/dist/email/index.mjs +446 -131
  45. package/dist/email/index.mjs.map +1 -1
  46. package/dist/en-CDZBMcc1.mjs +202 -0
  47. package/dist/en-CDZBMcc1.mjs.map +1 -0
  48. package/dist/{env-D1rcZ8_r.d.mts → env-ug22bJj7.d.mts} +1 -1
  49. package/dist/env-ug22bJj7.d.mts.map +1 -0
  50. package/dist/errors/index.d.mts +2 -2
  51. package/dist/errors/index.mjs +4 -2
  52. package/dist/errors-mXYxG0XB.mjs +333 -0
  53. package/dist/errors-mXYxG0XB.mjs.map +1 -0
  54. package/dist/events/index.d.mts +14 -3
  55. package/dist/events/index.d.mts.map +1 -1
  56. package/dist/events/index.mjs +2 -2
  57. package/dist/{events-CzCV8jI8.mjs → events-BXJGZjpG.mjs} +23 -13
  58. package/dist/events-BXJGZjpG.mjs.map +1 -0
  59. package/dist/exception-context-kEoMFwze.mjs +429 -0
  60. package/dist/exception-context-kEoMFwze.mjs.map +1 -0
  61. package/dist/{gateway-context-CXmXtaUP.mjs → gateway-context-TMu_AlJt.mjs} +38 -31
  62. package/dist/gateway-context-TMu_AlJt.mjs.map +1 -0
  63. package/dist/guards/index.d.mts +3 -3
  64. package/dist/guards/index.d.mts.map +1 -1
  65. package/dist/guards/index.mjs +1 -1
  66. package/dist/{guards-DU1_J9YA.mjs → guards-DALPXy3_.mjs} +6 -5
  67. package/dist/guards-DALPXy3_.mjs.map +1 -0
  68. package/dist/hono-app-CvV3hOfT.mjs +161 -0
  69. package/dist/hono-app-CvV3hOfT.mjs.map +1 -0
  70. package/dist/{http-method.decorator-BrgHMdLQ.mjs → http-method.decorator-ByWZb9DO.mjs} +7 -6
  71. package/dist/http-method.decorator-ByWZb9DO.mjs.map +1 -0
  72. package/dist/i18n/index.d.mts +238 -3
  73. package/dist/i18n/index.d.mts.map +1 -0
  74. package/dist/i18n/index.mjs +39 -3
  75. package/dist/i18n/index.mjs.map +1 -0
  76. package/dist/i18n/messages/en/index.d.mts +2 -2
  77. package/dist/i18n/messages/en/index.mjs +2 -2
  78. package/dist/i18n/utils/index.d.mts +4 -26
  79. package/dist/i18n/utils/index.d.mts.map +1 -1
  80. package/dist/i18n/utils/index.mjs +2 -2
  81. package/dist/i18n/validation/index.d.mts +3 -2
  82. package/dist/i18n/validation/index.mjs +4 -2
  83. package/dist/i18n.module-DRQAZoSZ.mjs +222 -0
  84. package/dist/i18n.module-DRQAZoSZ.mjs.map +1 -0
  85. package/dist/i18n.tokens-CZ_v8oyS.mjs +19 -0
  86. package/dist/i18n.tokens-CZ_v8oyS.mjs.map +1 -0
  87. package/dist/{index-7-hU3GTV.d.mts → index-0ItCjaqw.d.mts} +1 -1
  88. package/dist/index-0ItCjaqw.d.mts.map +1 -0
  89. package/dist/index-B5JBRcWD.d.mts +544 -0
  90. package/dist/index-B5JBRcWD.d.mts.map +1 -0
  91. package/dist/index-BUt92sAE.d.mts +124 -0
  92. package/dist/index-BUt92sAE.d.mts.map +1 -0
  93. package/dist/{index-ByOyTmqf.d.mts → index-B_JoEl3V.d.mts} +751 -2229
  94. package/dist/index-B_JoEl3V.d.mts.map +1 -0
  95. package/dist/index-DtBNIFuP.d.mts +42 -0
  96. package/dist/index-DtBNIFuP.d.mts.map +1 -0
  97. package/dist/{index-C1KvMncZ.d.mts → index-HgOLNruQ.d.mts} +3 -108
  98. package/dist/index-HgOLNruQ.d.mts.map +1 -0
  99. package/dist/index.d.mts +6 -43
  100. package/dist/index.mjs +3 -2
  101. package/dist/{is-command-C6a7WTPw.mjs → is-command-CEPO9n8c.mjs} +2 -2
  102. package/dist/{is-command-C6a7WTPw.mjs.map → is-command-CEPO9n8c.mjs.map} +1 -1
  103. package/dist/{is-seeder-CebjZCDn.mjs → is-seeder-Gvh_AM71.mjs} +1 -1
  104. package/dist/{is-seeder-CebjZCDn.mjs.map → is-seeder-Gvh_AM71.mjs.map} +1 -1
  105. package/dist/lazy-module-loader-Ib383jH_.d.mts +60 -0
  106. package/dist/lazy-module-loader-Ib383jH_.d.mts.map +1 -0
  107. package/dist/locale-path.service-D-dHiIPc.mjs +165 -0
  108. package/dist/locale-path.service-D-dHiIPc.mjs.map +1 -0
  109. package/dist/locale-url-nZrZxqJP.mjs +44 -0
  110. package/dist/locale-url-nZrZxqJP.mjs.map +1 -0
  111. package/dist/locale-url.service-C2EWmGdq.mjs +41 -0
  112. package/dist/locale-url.service-C2EWmGdq.mjs.map +1 -0
  113. package/dist/logger/index.d.mts +2 -2
  114. package/dist/logger/index.mjs +170 -2
  115. package/dist/logger/index.mjs.map +1 -0
  116. package/dist/macroable/index.d.mts +2 -2
  117. package/dist/macroable/index.mjs +1 -1
  118. package/dist/{macroable-BmufBshB.mjs → macroable-cvDTFZ_A.mjs} +1 -1
  119. package/dist/{macroable-BmufBshB.mjs.map → macroable-cvDTFZ_A.mjs.map} +1 -1
  120. package/dist/metadata-DzzprcID.mjs +39 -0
  121. package/dist/metadata-DzzprcID.mjs.map +1 -0
  122. package/dist/module/index.d.mts +7 -24
  123. package/dist/module/index.d.mts.map +1 -1
  124. package/dist/module/index.mjs +10 -2
  125. package/dist/module/index.mjs.map +1 -0
  126. package/dist/module-registry-Dm-pqHd3.mjs +554 -0
  127. package/dist/module-registry-Dm-pqHd3.mjs.map +1 -0
  128. package/dist/module.decorator-CYHY6pG5.mjs +19 -0
  129. package/dist/module.decorator-CYHY6pG5.mjs.map +1 -0
  130. package/dist/openapi/index.d.mts +44 -8
  131. package/dist/openapi/index.d.mts.map +1 -1
  132. package/dist/openapi/index.mjs +3 -3
  133. package/dist/openapi-CstuTM8S.mjs +309 -0
  134. package/dist/openapi-CstuTM8S.mjs.map +1 -0
  135. package/dist/{openapi-tools.service-Zs-Ewv7F.mjs → openapi-tools.service-BC5EC3R3.mjs} +8 -2
  136. package/dist/openapi-tools.service-BC5EC3R3.mjs.map +1 -0
  137. package/dist/{openapi.service-Bt9bCIrd.d.mts → openapi.service-YhTiJ1bO.d.mts} +3 -3
  138. package/dist/openapi.service-YhTiJ1bO.d.mts.map +1 -0
  139. package/dist/quarry/index.d.mts +14 -163
  140. package/dist/quarry/index.d.mts.map +1 -1
  141. package/dist/quarry/index.mjs +6 -5
  142. package/dist/quarry/runner.d.mts +184 -0
  143. package/dist/quarry/runner.d.mts.map +1 -0
  144. package/dist/quarry/runner.mjs +945 -0
  145. package/dist/quarry/runner.mjs.map +1 -0
  146. package/dist/quarry-registry-CXg0RFXq.d.mts +69 -0
  147. package/dist/quarry-registry-CXg0RFXq.d.mts.map +1 -0
  148. package/dist/quarry.module-BuRPGMDm.mjs +312 -0
  149. package/dist/quarry.module-BuRPGMDm.mjs.map +1 -0
  150. package/dist/queue/index.d.mts +3 -3
  151. package/dist/queue/index.mjs +57 -48
  152. package/dist/queue/index.mjs.map +1 -1
  153. package/dist/queue.module-nddvxzCB.mjs +613 -0
  154. package/dist/queue.module-nddvxzCB.mjs.map +1 -0
  155. package/dist/queue.tokens-DjHnFmre.mjs +11 -0
  156. package/dist/queue.tokens-DjHnFmre.mjs.map +1 -0
  157. package/dist/{r2-storage.provider-DuonKeYm.mjs → r2-storage.provider-DCxQt9dD.mjs} +6 -6
  158. package/dist/r2-storage.provider-DCxQt9dD.mjs.map +1 -0
  159. package/dist/{rate-limit.decorator-6qzNcSOt.mjs → rate-limit.decorator-BPAie_p3.mjs} +6 -11
  160. package/dist/rate-limit.decorator-BPAie_p3.mjs.map +1 -0
  161. package/dist/rate-limiter/index.d.mts +11 -50
  162. package/dist/rate-limiter/index.d.mts.map +1 -1
  163. package/dist/rate-limiter/index.mjs +33 -42
  164. package/dist/rate-limiter/index.mjs.map +1 -1
  165. package/dist/route-name-DGoBOfPg.mjs +171 -0
  166. package/dist/route-name-DGoBOfPg.mjs.map +1 -0
  167. package/dist/route-registration.service-D6vSwiKP.mjs +918 -0
  168. package/dist/route-registration.service-D6vSwiKP.mjs.map +1 -0
  169. package/dist/route-registry-CYqLp2Nj.mjs +123 -0
  170. package/dist/route-registry-CYqLp2Nj.mjs.map +1 -0
  171. package/dist/router/index.d.mts +2 -2
  172. package/dist/router/index.mjs +18 -7
  173. package/dist/router-CWGBD-Bg.mjs +78 -0
  174. package/dist/router-CWGBD-Bg.mjs.map +1 -0
  175. package/dist/router-resolver-D4YlPNlm.mjs +88 -0
  176. package/dist/router-resolver-D4YlPNlm.mjs.map +1 -0
  177. package/dist/seeder/index.d.mts +16 -11
  178. package/dist/seeder/index.d.mts.map +1 -1
  179. package/dist/seeder/index.mjs +5 -3
  180. package/dist/seeder-7ubkms-Y.mjs +81 -0
  181. package/dist/seeder-7ubkms-Y.mjs.map +1 -0
  182. package/dist/seeder-registry-CyUmKsJq.mjs +57 -0
  183. package/dist/seeder-registry-CyUmKsJq.mjs.map +1 -0
  184. package/dist/seeder.module-CYYwk3Qk.mjs +15 -0
  185. package/dist/seeder.module-CYYwk3Qk.mjs.map +1 -0
  186. package/dist/{signed-url-BQPbv2In.mjs → signed-url-DIU0sK_6.mjs} +1 -1
  187. package/dist/{signed-url-BQPbv2In.mjs.map → signed-url-DIU0sK_6.mjs.map} +1 -1
  188. package/dist/storage/index.d.mts +15 -39
  189. package/dist/storage/index.d.mts.map +1 -1
  190. package/dist/storage/index.mjs +3 -3
  191. package/dist/storage/providers/index.d.mts +2 -2
  192. package/dist/storage/providers/index.d.mts.map +1 -1
  193. package/dist/storage/providers/index.mjs +1 -1
  194. package/dist/{storage-D8CBP72Z.mjs → storage-MDZypIE9.mjs} +66 -59
  195. package/dist/storage-MDZypIE9.mjs.map +1 -0
  196. package/dist/{storage-provider.interface-Bd6vA4ak.d.mts → storage-provider.interface-ClUwxz4S.d.mts} +2 -3
  197. package/dist/storage-provider.interface-ClUwxz4S.d.mts.map +1 -0
  198. package/dist/storage.error-Dnib4VHc.mjs +8 -0
  199. package/dist/storage.error-Dnib4VHc.mjs.map +1 -0
  200. package/dist/stratal-DL9M38_s.mjs +383 -0
  201. package/dist/stratal-DL9M38_s.mjs.map +1 -0
  202. package/dist/stratal-DwDJPY9N.d.mts +43 -0
  203. package/dist/stratal-DwDJPY9N.d.mts.map +1 -0
  204. package/dist/tiered-cache.service-Dv3BhxxE.d.mts +79 -0
  205. package/dist/tiered-cache.service-Dv3BhxxE.d.mts.map +1 -0
  206. package/dist/trailing-slash-CFyw8nYu.mjs +34 -0
  207. package/dist/trailing-slash-CFyw8nYu.mjs.map +1 -0
  208. package/dist/{types-cySNS_lp.d.mts → types-CmV_9xBD.d.mts} +1 -1
  209. package/dist/types-CmV_9xBD.d.mts.map +1 -0
  210. package/dist/uri-h7Q8Jug9.mjs +251 -0
  211. package/dist/uri-h7Q8Jug9.mjs.map +1 -0
  212. package/dist/{usage-generator-BUdlhnCK.mjs → usage-generator-DAWYasuP.mjs} +7 -4
  213. package/dist/usage-generator-DAWYasuP.mjs.map +1 -0
  214. package/dist/validation-CpOjviyT.mjs +49 -0
  215. package/dist/validation-CpOjviyT.mjs.map +1 -0
  216. package/dist/validation.context-CRvmrhq7.mjs +117 -0
  217. package/dist/validation.context-CRvmrhq7.mjs.map +1 -0
  218. package/dist/versioning.service-C6aHky8-.mjs +36 -0
  219. package/dist/versioning.service-C6aHky8-.mjs.map +1 -0
  220. package/dist/websocket/index.d.mts +16 -14
  221. package/dist/websocket/index.d.mts.map +1 -1
  222. package/dist/websocket/index.mjs +2 -2
  223. package/dist/workers/index.d.mts +2 -2
  224. package/dist/workers/index.d.mts.map +1 -1
  225. package/dist/workers/index.mjs +3 -2
  226. package/dist/workers/index.mjs.map +1 -1
  227. package/dist/zod-eKqqhZ5_.mjs +72 -0
  228. package/dist/zod-eKqqhZ5_.mjs.map +1 -0
  229. package/dist/{index-Bnpfq6uk.d.mts → zod-wecrEVAs.d.mts} +63 -133
  230. package/dist/zod-wecrEVAs.d.mts.map +1 -0
  231. package/package.json +28 -39
  232. package/dist/base-email.provider-CfQCA08m.mjs +0 -42
  233. package/dist/base-email.provider-CfQCA08m.mjs.map +0 -1
  234. package/dist/cache.service-DsnKuNyO.d.mts.map +0 -1
  235. package/dist/cache.tokens-B7Rw1C9Q.mjs +0 -6
  236. package/dist/cache.tokens-B7Rw1C9Q.mjs.map +0 -1
  237. package/dist/colors-DJaRDXoS.mjs +0 -16
  238. package/dist/colors-DJaRDXoS.mjs.map +0 -1
  239. package/dist/command-BgSlsS4M.mjs.map +0 -1
  240. package/dist/command-Cmmf0oHX.d.mts.map +0 -1
  241. package/dist/consumer-registry-B7yUNh0q.d.mts.map +0 -1
  242. package/dist/controller.decorator-B9vwn0zK.mjs.map +0 -1
  243. package/dist/cron-manager-CmTimEjf.d.mts +0 -131
  244. package/dist/cron-manager-CmTimEjf.d.mts.map +0 -1
  245. package/dist/cron-manager-DQSK8uoV.mjs.map +0 -1
  246. package/dist/en-DSH_bhh6.mjs +0 -308
  247. package/dist/en-DSH_bhh6.mjs.map +0 -1
  248. package/dist/env-D1rcZ8_r.d.mts.map +0 -1
  249. package/dist/errors-COW9-Mar.mjs +0 -1739
  250. package/dist/errors-COW9-Mar.mjs.map +0 -1
  251. package/dist/errors-ORxu1-Bb.mjs +0 -74
  252. package/dist/errors-ORxu1-Bb.mjs.map +0 -1
  253. package/dist/events-CzCV8jI8.mjs.map +0 -1
  254. package/dist/gateway-context-CXmXtaUP.mjs.map +0 -1
  255. package/dist/guards-DU1_J9YA.mjs.map +0 -1
  256. package/dist/http-method.decorator-BrgHMdLQ.mjs.map +0 -1
  257. package/dist/i18n.module-CzXLW9Hy.mjs +0 -2532
  258. package/dist/i18n.module-CzXLW9Hy.mjs.map +0 -1
  259. package/dist/index-7-hU3GTV.d.mts.map +0 -1
  260. package/dist/index-Bnpfq6uk.d.mts.map +0 -1
  261. package/dist/index-ByOyTmqf.d.mts.map +0 -1
  262. package/dist/index-C1KvMncZ.d.mts.map +0 -1
  263. package/dist/index-DBd_2wv8.d.mts +0 -263
  264. package/dist/index-DBd_2wv8.d.mts.map +0 -1
  265. package/dist/index-DUzWs0z7.d.mts +0 -494
  266. package/dist/index-DUzWs0z7.d.mts.map +0 -1
  267. package/dist/index.d.mts.map +0 -1
  268. package/dist/logger-DlV7NtvD.mjs +0 -440
  269. package/dist/logger-DlV7NtvD.mjs.map +0 -1
  270. package/dist/module-BzLg57FK.mjs +0 -866
  271. package/dist/module-BzLg57FK.mjs.map +0 -1
  272. package/dist/openapi-tools.service-Zs-Ewv7F.mjs.map +0 -1
  273. package/dist/openapi.service-Bt9bCIrd.d.mts.map +0 -1
  274. package/dist/quarry-registry-BwY2hOxm.mjs +0 -699
  275. package/dist/quarry-registry-BwY2hOxm.mjs.map +0 -1
  276. package/dist/queue.module-BhCjZp6H.mjs +0 -409
  277. package/dist/queue.module-BhCjZp6H.mjs.map +0 -1
  278. package/dist/r2-storage.provider-DuonKeYm.mjs.map +0 -1
  279. package/dist/rate-limit.decorator-6qzNcSOt.mjs.map +0 -1
  280. package/dist/resend.provider-DB4IlFjG.mjs +0 -68
  281. package/dist/resend.provider-DB4IlFjG.mjs.map +0 -1
  282. package/dist/seeder-zoEfEw9i.mjs +0 -138
  283. package/dist/seeder-zoEfEw9i.mjs.map +0 -1
  284. package/dist/setup-CefZKV_e.mjs +0 -37
  285. package/dist/setup-CefZKV_e.mjs.map +0 -1
  286. package/dist/smtp.provider-B6D7zuWX.mjs +0 -76
  287. package/dist/smtp.provider-B6D7zuWX.mjs.map +0 -1
  288. package/dist/storage-D8CBP72Z.mjs.map +0 -1
  289. package/dist/storage-provider.interface-Bd6vA4ak.d.mts.map +0 -1
  290. package/dist/stratal-CNwpbSZl.mjs +0 -535
  291. package/dist/stratal-CNwpbSZl.mjs.map +0 -1
  292. package/dist/types-cySNS_lp.d.mts.map +0 -1
  293. package/dist/usage-generator-BUdlhnCK.mjs.map +0 -1
  294. package/dist/validation-DtJwAv7O.mjs +0 -248
  295. package/dist/validation-DtJwAv7O.mjs.map +0 -1
  296. /package/dist/{chunk-D1SwGrFN.mjs → chunk-BBjsoOtd.mjs} +0 -0
@@ -1,3 +1,4 @@
1
+ import { n as getMetadata, t as defineMetadata } from "./metadata-DzzprcID.mjs";
1
2
  //#region src/guards/types.ts
2
3
  /**
3
4
  * Metadata key for guard storage
@@ -63,8 +64,8 @@ const GUARD_METADATA_KEY = Symbol.for("stratal:guards");
63
64
  function UseGuards(...guards) {
64
65
  return (target, propertyKey) => {
65
66
  const metadata = { guards };
66
- if (propertyKey !== void 0) Reflect.defineMetadata(GUARD_METADATA_KEY, metadata, target, propertyKey);
67
- else Reflect.defineMetadata(GUARD_METADATA_KEY, metadata, target);
67
+ if (propertyKey !== void 0) defineMetadata(GUARD_METADATA_KEY, metadata, target, propertyKey);
68
+ else defineMetadata(GUARD_METADATA_KEY, metadata, target);
68
69
  };
69
70
  }
70
71
  /**
@@ -74,7 +75,7 @@ function UseGuards(...guards) {
74
75
  * @returns Guard metadata or undefined if not decorated
75
76
  */
76
77
  function getControllerGuards(target) {
77
- return Reflect.getMetadata(GUARD_METADATA_KEY, target);
78
+ return getMetadata(GUARD_METADATA_KEY, target);
78
79
  }
79
80
  /**
80
81
  * Get method-level guard metadata
@@ -84,7 +85,7 @@ function getControllerGuards(target) {
84
85
  * @returns Guard metadata or undefined if not decorated
85
86
  */
86
87
  function getMethodGuards(target, propertyKey) {
87
- return Reflect.getMetadata(GUARD_METADATA_KEY, target, propertyKey);
88
+ return getMetadata(GUARD_METADATA_KEY, target, propertyKey);
88
89
  }
89
90
  //#endregion
90
91
  //#region src/guards/guard-execution.service.ts
@@ -149,4 +150,4 @@ var GuardExecutionService = class {
149
150
  //#endregion
150
151
  export { GUARD_METADATA_KEY as a, getMethodGuards as i, UseGuards as n, getControllerGuards as r, GuardExecutionService as t };
151
152
 
152
- //# sourceMappingURL=guards-DU1_J9YA.mjs.map
153
+ //# sourceMappingURL=guards-DALPXy3_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards-DALPXy3_.mjs","names":[],"sources":["../src/guards/types.ts","../src/guards/use-guards.decorator.ts","../src/guards/guard-execution.service.ts"],"sourcesContent":["import type { RouterContext } from '../router'\nimport type { Constructor } from '../types'\n\n/**\n * Interface for guards that control access to routes\n *\n * Guards are executed after middlewares but before route handlers.\n * They determine if a request should be allowed to proceed.\n *\n * @example\n * ```typescript\n * class RoleGuard implements CanActivate {\n * constructor(private readonly role: string) {}\n *\n * async canActivate(context: RouterContext): Promise<boolean> {\n * const user = context.getUser()\n * return user?.roles.includes(this.role) ?? false\n * }\n * }\n * ```\n */\nexport interface CanActivate {\n /**\n * Determine if the request should be allowed\n *\n * @param context - Router context with request/response helpers\n * @returns true to allow, false to deny (throws 403)\n */\n canActivate(context: RouterContext): boolean | Promise<boolean>\n}\n\n/**\n * Type for guard class constructors\n */\nexport type GuardClass = Constructor<CanActivate>\n\n/**\n * Guard can be a class constructor or an instance\n * Instances are used for factory-created guards with configuration\n */\nexport type Guard = GuardClass | CanActivate\n\n/**\n * Options for AuthGuard factory\n */\nexport interface AuthGuardOptions {\n /**\n * Required permissions for authorization as `\"resource:action\"` strings.\n * If provided, permission check is performed after authentication.\n * If omitted, only authentication is required.\n *\n * Multiple permissions are combined with AND logic (all must be satisfied).\n *\n * @example\n * ```typescript\n * @UseGuards(AuthGuard({ permissions: 'posts:update' }))\n * @UseGuards(AuthGuard({ permissions: ['posts:update', 'posts:delete'] }))\n * @UseGuards(AuthGuard({ permissions: 'admin:access' }))\n * ```\n */\n permissions?: string | string[]\n}\n\n/**\n * Metadata stored by `@UseGuards` decorator\n */\nexport interface GuardMetadata {\n guards: Guard[]\n}\n\n/**\n * Metadata key for guard storage\n */\nexport const GUARD_METADATA_KEY = Symbol.for('stratal:guards')\n","import { defineMetadata, getMetadata } from '../di/metadata'\nimport { GUARD_METADATA_KEY, type Guard, type GuardMetadata } from './types'\n\n/**\n * UseGuards Decorator\n *\n * Applies one or more guards to a controller or method.\n * Guards are executed in order and all must pass for the request to proceed.\n *\n * **Execution Order:**\n * 1. Request → Global Middlewares → Route Middlewares\n * 2. **Guards (controller-level, then method-level)**\n * 3. Route Handler\n *\n * **Guard Resolution:**\n * - Guard classes are resolved from the request-scoped DI container\n * - Guard instances (from factory functions) are used directly\n *\n * @param guards - Guard classes or instances to apply\n *\n * @example Authentication only\n * ```typescript\n * @Controller('/api/v1/profile')\n * @UseGuards(AuthGuard())\n * export class ProfileController {\n * show() { } // Requires authentication\n * }\n * ```\n *\n * @example Authentication with permissions\n * ```typescript\n * @Controller('/api/v1/students')\n * @UseGuards(AuthGuard({ scopes: ['students:read'] }))\n * export class StudentsController {\n * index() { } // Requires 'students:read' permission\n * }\n * ```\n *\n * @example Method-level guards\n * ```typescript\n * @Controller('/api/v1/students')\n * @UseGuards(AuthGuard()) // Controller-level: auth only\n * export class StudentsController {\n * index() { } // Auth only (inherited)\n *\n * @UseGuards(AuthGuard({ scopes: ['students:create'] }))\n * create() { } // Auth + 'students:create' permission\n * }\n * ```\n *\n * @example Multiple guards\n * ```typescript\n * @UseGuards(AuthGuard(), RateLimitGuard(), CustomGuard())\n * export class SecureController {\n * // All guards must pass\n * }\n * ```\n */\nexport function UseGuards(...guards: Guard[]): ClassDecorator & MethodDecorator {\n return (target: object, propertyKey?: string | symbol) => {\n const metadata: GuardMetadata = { guards }\n\n if (propertyKey !== undefined) {\n // Method decorator - store on method\n defineMetadata(GUARD_METADATA_KEY, metadata, target, propertyKey)\n } else {\n // Class decorator - store on class\n defineMetadata(GUARD_METADATA_KEY, metadata, target)\n }\n }\n}\n\n/**\n * Get controller-level guard metadata\n *\n * @param target - Controller class\n * @returns Guard metadata or undefined if not decorated\n */\nexport function getControllerGuards(target: object): GuardMetadata | undefined {\n return getMetadata<GuardMetadata>(GUARD_METADATA_KEY, target)\n}\n\n/**\n * Get method-level guard metadata\n *\n * @param target - Controller prototype\n * @param propertyKey - Method name\n * @returns Guard metadata or undefined if not decorated\n */\nexport function getMethodGuards(target: object, propertyKey: string | symbol): GuardMetadata | undefined {\n return getMetadata<GuardMetadata>(GUARD_METADATA_KEY, target, propertyKey)\n}\n","import type { Container } from '../di'\nimport type { LoggerService } from '../logger'\nimport type { RouterContext } from '../router'\nimport type { CanActivate, Guard } from './types'\n\n/**\n * Guard Execution Service\n *\n * Executes guards for a route and determines if the request should proceed.\n * Guards are executed in order; all must pass for the request to proceed.\n */\nexport class GuardExecutionService {\n constructor(private readonly logger: LoggerService) { }\n\n /**\n * Execute all guards for a route\n *\n * @param guards - Array of guards (classes or instances)\n * @param context - Router context\n * @param container - Request-scoped DI container\n * @returns true if all guards pass\n * @throws Error from first failing guard\n */\n async executeGuards(\n guards: Guard[],\n context: RouterContext,\n container: Container\n ): Promise<boolean> {\n if (guards.length === 0) {\n return true\n }\n\n this.logger.debug('Executing guards', {\n guardCount: guards.length,\n path: context.c.req.path,\n method: context.c.req.method,\n })\n\n for (const guard of guards) {\n const guardInstance = this.resolveGuard(guard, container)\n const canActivate = await guardInstance.canActivate(context)\n\n if (!canActivate) {\n this.logger.debug('Guard denied access', {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- guard.constructor may be null at runtime\n guard: guard.constructor?.name || 'AnonymousGuard',\n path: context.c.req.path,\n })\n return false\n }\n }\n\n this.logger.debug('All guards passed', {\n guardCount: guards.length,\n path: context.c.req.path,\n })\n\n return true\n }\n\n /**\n * Resolve a guard to an instance\n *\n * @param guard - Guard class or instance\n * @param container - Request-scoped DI container\n * @returns Guard instance\n */\n private resolveGuard(guard: Guard, container: Container): CanActivate {\n // If already an instance (has canActivate method), use directly\n if (this.isGuardInstance(guard)) {\n return guard\n }\n\n // Otherwise, resolve from container\n return container.resolve<CanActivate>(guard)\n }\n\n /**\n * Type guard to check if value is a guard instance\n */\n private isGuardInstance(guard: Guard): guard is CanActivate {\n return (\n typeof guard === 'object' &&\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typeof null === 'object', null check is required\n guard !== null &&\n 'canActivate' in guard &&\n typeof guard.canActivate === 'function'\n )\n }\n}\n"],"mappings":";;;;;AAyEA,MAAa,qBAAqB,OAAO,IAAI,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACf7D,SAAgB,UAAU,GAAG,QAAmD;CAC9E,QAAQ,QAAgB,gBAAkC;EACxD,MAAM,WAA0B,EAAE,OAAO;EAEzC,IAAI,gBAAgB,KAAA,GAElB,eAAe,oBAAoB,UAAU,QAAQ,WAAW;OAGhE,eAAe,oBAAoB,UAAU,MAAM;CAEvD;AACF;;;;;;;AAQA,SAAgB,oBAAoB,QAA2C;CAC7E,OAAO,YAA2B,oBAAoB,MAAM;AAC9D;;;;;;;;AASA,SAAgB,gBAAgB,QAAgB,aAAyD;CACvG,OAAO,YAA2B,oBAAoB,QAAQ,WAAW;AAC3E;;;;;;;;;AChFA,IAAa,wBAAb,MAAmC;CACJ;CAA7B,YAAY,QAAwC;EAAvB,KAAA,SAAA;CAAyB;;;;;;;;;;CAWtD,MAAM,cACJ,QACA,SACA,WACkB;EAClB,IAAI,OAAO,WAAW,GACpB,OAAO;EAGT,KAAK,OAAO,MAAM,oBAAoB;GACpC,YAAY,OAAO;GACnB,MAAM,QAAQ,EAAE,IAAI;GACpB,QAAQ,QAAQ,EAAE,IAAI;EACxB,CAAC;EAED,KAAK,MAAM,SAAS,QAIlB,IAAI,CAAC,MAHiB,KAAK,aAAa,OAAO,SACT,EAAE,YAAY,OAAO,GAEzC;GAChB,KAAK,OAAO,MAAM,uBAAuB;IAEvC,OAAO,MAAM,aAAa,QAAQ;IAClC,MAAM,QAAQ,EAAE,IAAI;GACtB,CAAC;GACD,OAAO;EACT;EAGF,KAAK,OAAO,MAAM,qBAAqB;GACrC,YAAY,OAAO;GACnB,MAAM,QAAQ,EAAE,IAAI;EACtB,CAAC;EAED,OAAO;CACT;;;;;;;;CASA,aAAqB,OAAc,WAAmC;EAEpE,IAAI,KAAK,gBAAgB,KAAK,GAC5B,OAAO;EAIT,OAAO,UAAU,QAAqB,KAAK;CAC7C;;;;CAKA,gBAAwB,OAAoC;EAC1D,OACE,OAAO,UAAU,YAEjB,UAAU,QACV,iBAAiB,SACjB,OAAO,MAAM,gBAAgB;CAEjC;AACF"}
@@ -0,0 +1,161 @@
1
+ import { t as __exportAll } from "./chunk-BBjsoOtd.mjs";
2
+ import { d as inject, n as CONTAINER_TOKEN, r as DI_TOKENS, s as Singleton } from "./di-DseMn-z9.mjs";
3
+ import { r as runWithContainer } from "./container-storage-BmOJ4_Na.mjs";
4
+ import { n as __decorateParam, t as __decorate } from "./decorate-CuAoSZvs.mjs";
5
+ import { LOGGER_TOKENS } from "./logger/index.mjs";
6
+ import { a as RouterContext, l as ROUTER_CONTEXT_KEYS, r as createHttpExceptionContext } from "./exception-context-kEoMFwze.mjs";
7
+ import { o as RouterError } from "./module-registry-Dm-pqHd3.mjs";
8
+ import { t as OpenAPIHono } from "./zod-eKqqhZ5_.mjs";
9
+ import { n as OPENAPI_TOKENS } from "./openapi-tools.service-BC5EC3R3.mjs";
10
+ import "./openapi-CstuTM8S.mjs";
11
+ import { p as createMiddlewareChain, t as RouteRegistrationService, v as SchemaValidationError, y as RouteNotFoundError } from "./route-registration.service-D6vSwiKP.mjs";
12
+ import { t as applyTrailingSlash } from "./trailing-slash-CFyw8nYu.mjs";
13
+ //#region src/router/middleware/logger.middleware.ts
14
+ /**
15
+ * Create a Hono middleware that logs HTTP requests using our Logger service
16
+ *
17
+ * Logs request method, path, status code, and duration in milliseconds.
18
+ * Format: [HTTP] METHOD /path -> STATUS (duration ms)
19
+ *
20
+ * @param logger - Logger service instance
21
+ * @returns Hono middleware handler
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const logger = container.resolve<LoggerService>(LOGGER_TOKENS.LoggerService)
26
+ * app.use('*', createLoggerMiddleware(logger))
27
+ * ```
28
+ */
29
+ function createLoggerMiddleware(logger) {
30
+ return async (c, next) => {
31
+ const start = Date.now();
32
+ const method = c.req.method;
33
+ const path = c.req.path;
34
+ await next();
35
+ const duration = Date.now() - start;
36
+ const status = c.res.status;
37
+ logger.info(`[HTTP] ${method} ${path} -> ${status}`, {
38
+ method,
39
+ path,
40
+ status,
41
+ duration
42
+ });
43
+ };
44
+ }
45
+ //#endregion
46
+ //#region src/router/middleware/trailing-slash-redirect.ts
47
+ const REDIRECT_STATUS = 308;
48
+ /**
49
+ * Create a Hono middleware that canonicalises trailing slashes via 308 redirects.
50
+ *
51
+ * - `'ignore'` — returns `null`; routes match both `/foo` and `/foo/` natively
52
+ * (Hono handles this when constructed with `strict: false`).
53
+ * - `'always'` — non-trailing requests redirect to the trailing-slash form.
54
+ * Paths whose last segment contains `.` (e.g. `/api/openapi.json`) are skipped.
55
+ * - `'never'` — trailing requests redirect to the non-trailing form.
56
+ *
57
+ * Root (`/`) is always passed through unchanged.
58
+ *
59
+ * 308 is used so that POST/PUT/PATCH bodies survive the redirect.
60
+ *
61
+ * Location headers are emitted as path-relative URIs so the user agent
62
+ * resolves them against the effective request URI — sidestepping scheme
63
+ * mismatches behind HTTPS-terminating proxies that proxy HTTPS pages to an
64
+ * HTTP-speaking backend (which would otherwise produce a mixed-content block).
65
+ */
66
+ function createTrailingSlashRedirect(mode) {
67
+ if (mode === "ignore") return null;
68
+ return async (c, next) => {
69
+ const url = new URL(c.req.url);
70
+ const canonicalPath = applyTrailingSlash(url.pathname, mode);
71
+ if (canonicalPath === url.pathname) return next();
72
+ return c.redirect(`${canonicalPath}${url.search}`, REDIRECT_STATUS);
73
+ };
74
+ }
75
+ //#endregion
76
+ //#region src/router/hono-app.ts
77
+ var hono_app_exports = /* @__PURE__ */ __exportAll({ HonoApp: () => HonoApp });
78
+ const isMiddlewareClass = (arg) => typeof arg === "function" && arg.prototype && "handle" in arg.prototype;
79
+ let HonoApp = class HonoApp extends OpenAPIHono {
80
+ configured = false;
81
+ _container;
82
+ _logger;
83
+ /**
84
+ * Reference to the original Hono `use` implementation.
85
+ * Captured in constructor after super() sets it as an instance property.
86
+ * Used by private methods to register middleware without going through the override.
87
+ */
88
+ nativeUse;
89
+ constructor(container, logger, application) {
90
+ const trailingSlash = application.config.trailingSlash ?? "ignore";
91
+ super({
92
+ strict: false,
93
+ defaultHook: (result) => {
94
+ if (!result.success) throw new SchemaValidationError(result.error);
95
+ }
96
+ });
97
+ this._container = container;
98
+ this._logger = logger;
99
+ this.nativeUse = this.use;
100
+ this.use = ((...args) => {
101
+ if (isMiddlewareClass(args[0])) {
102
+ this.nativeUse("*", createMiddlewareChain(args));
103
+ return this;
104
+ }
105
+ if (typeof args[0] === "string" && args.length > 1 && isMiddlewareClass(args[1])) {
106
+ this.nativeUse(args[0], createMiddlewareChain(args.slice(1)));
107
+ return this;
108
+ }
109
+ return this.nativeUse(...args);
110
+ });
111
+ const trailingSlashRedirect = createTrailingSlashRedirect(trailingSlash);
112
+ if (trailingSlashRedirect) this.nativeUse("*", trailingSlashRedirect);
113
+ this.setupRequestScope();
114
+ this.applyGlobalMiddleware();
115
+ }
116
+ /**
117
+ * Apply global middleware (logger + error handler).
118
+ * Called by Application after locale middleware is applied by LocalePathService.
119
+ */
120
+ applyGlobalMiddleware() {
121
+ this.nativeUse("*", createLoggerMiddleware(this._logger));
122
+ this.onError((err, c) => this.handleException(c, err));
123
+ }
124
+ /**
125
+ * Configure OpenAPI endpoints, controller routes, and 404 handler.
126
+ * Called once by Application.initialize().
127
+ */
128
+ async configure() {
129
+ if (this.configured) throw new RouterError("HonoApp has already been configured");
130
+ this._container.resolve(OPENAPI_TOKENS.OpenAPIService).setupEndpoints(this, this._container);
131
+ await this._container.resolve(RouteRegistrationService).configure();
132
+ this.notFound((c) => {
133
+ throw new RouteNotFoundError(c.req.path, c.req.method);
134
+ });
135
+ this.configured = true;
136
+ }
137
+ setupRequestScope() {
138
+ this.nativeUse("*", async (c, next) => {
139
+ const routerContext = new RouterContext(c);
140
+ const requestContainer = this._container.createRequestScope(routerContext);
141
+ c.set(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER, requestContainer);
142
+ await runWithContainer(requestContainer, next);
143
+ });
144
+ }
145
+ handleException(c, err) {
146
+ const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER) ?? this._container;
147
+ const handler = requestContainer.resolve(DI_TOKENS.ExceptionHandler);
148
+ const ctx = createHttpExceptionContext(c);
149
+ return runWithContainer(requestContainer, () => handler.handle(err, ctx));
150
+ }
151
+ };
152
+ HonoApp = __decorate([
153
+ Singleton(),
154
+ __decorateParam(0, inject(CONTAINER_TOKEN)),
155
+ __decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
156
+ __decorateParam(2, inject(DI_TOKENS.Application))
157
+ ], HonoApp);
158
+ //#endregion
159
+ export { hono_app_exports as n, HonoApp as t };
160
+
161
+ //# sourceMappingURL=hono-app-CvV3hOfT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hono-app-CvV3hOfT.mjs","names":[],"sources":["../src/router/middleware/logger.middleware.ts","../src/router/middleware/trailing-slash-redirect.ts","../src/router/hono-app.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type { LoggerService } from '../../logger'\n\n/**\n * Create a Hono middleware that logs HTTP requests using our Logger service\n *\n * Logs request method, path, status code, and duration in milliseconds.\n * Format: [HTTP] METHOD /path -> STATUS (duration ms)\n *\n * @param logger - Logger service instance\n * @returns Hono middleware handler\n *\n * @example\n * ```typescript\n * const logger = container.resolve<LoggerService>(LOGGER_TOKENS.LoggerService)\n * app.use('*', createLoggerMiddleware(logger))\n * ```\n */\nexport function createLoggerMiddleware(logger: LoggerService): MiddlewareHandler {\n return async (c, next) => {\n const start = Date.now()\n const method = c.req.method\n const path = c.req.path\n\n await next()\n\n const duration = Date.now() - start\n const status = c.res.status\n\n logger.info(`[HTTP] ${method} ${path} -> ${status}`, {\n method,\n path,\n status,\n duration,\n })\n }\n}\n","import type { MiddlewareHandler } from 'hono'\nimport { applyTrailingSlash } from '../trailing-slash'\nimport type { RouterEnv, TrailingSlashMode } from '../types'\n\nconst REDIRECT_STATUS = 308\n\n/**\n * Create a Hono middleware that canonicalises trailing slashes via 308 redirects.\n *\n * - `'ignore'` — returns `null`; routes match both `/foo` and `/foo/` natively\n * (Hono handles this when constructed with `strict: false`).\n * - `'always'` — non-trailing requests redirect to the trailing-slash form.\n * Paths whose last segment contains `.` (e.g. `/api/openapi.json`) are skipped.\n * - `'never'` — trailing requests redirect to the non-trailing form.\n *\n * Root (`/`) is always passed through unchanged.\n *\n * 308 is used so that POST/PUT/PATCH bodies survive the redirect.\n *\n * Location headers are emitted as path-relative URIs so the user agent\n * resolves them against the effective request URI — sidestepping scheme\n * mismatches behind HTTPS-terminating proxies that proxy HTTPS pages to an\n * HTTP-speaking backend (which would otherwise produce a mixed-content block).\n */\nexport function createTrailingSlashRedirect(\n mode: TrailingSlashMode,\n): MiddlewareHandler<RouterEnv> | null {\n if (mode === 'ignore') return null\n\n return async (c, next) => {\n const url = new URL(c.req.url)\n const canonicalPath = applyTrailingSlash(url.pathname, mode)\n if (canonicalPath === url.pathname) return next()\n return c.redirect(`${canonicalPath}${url.search}`, REDIRECT_STATUS)\n }\n}\n","import type { Context, MiddlewareHandler } from 'hono'\nimport { inject } from '../di'\nimport type { Application } from '../application'\nimport type { Container } from '../di/container'\nimport { runWithContainer } from '../di/container-storage'\nimport { Singleton } from '../di/decorators'\nimport { CONTAINER_TOKEN, DI_TOKENS } from '../di/tokens'\nimport { createHttpExceptionContext } from '../errors/exception-context'\nimport type { ExceptionHandler } from '../errors/exception-handler'\nimport { OpenAPIHono } from '../i18n/validation/zod'\nimport { LOGGER_TOKENS, type LoggerService } from '../logger'\nimport { OPENAPI_TOKENS, type OpenAPIService } from '../openapi'\nimport type { Constructor } from '../types'\nimport { ROUTER_CONTEXT_KEYS } from './constants'\nimport { RouteNotFoundError, SchemaValidationError } from './errors'\nimport { RouterError } from './router.error'\nimport { createLoggerMiddleware, createMiddlewareChain, createTrailingSlashRedirect } from './middleware'\nimport type { Middleware } from './middleware.interface'\nimport { RouterContext } from './router-context'\nimport { RouteRegistrationService } from './services/route-registration.service'\nimport type { RouterEnv, TrailingSlashMode } from './types'\n\nconst isMiddlewareClass = (arg: unknown): arg is Constructor<Middleware> =>\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n typeof arg === 'function' && arg.prototype && 'handle' in arg.prototype\n\n\n/**\n * HonoApp — extends OpenAPIHono with Stratal-specific setup\n *\n * - Request scope middleware (child container per request)\n * - Global middleware (CORS, logging, error handling)\n * - defaultHook for validation errors\n * - `use()` overload for Stratal middleware classes\n * - `configure()` for OpenAPI, routes, and 404\n */\n@Singleton()\nexport class HonoApp extends OpenAPIHono<RouterEnv> {\n private configured = false\n private readonly _container: Container\n private readonly _logger: LoggerService\n\n /**\n * Reference to the original Hono `use` implementation.\n * Captured in constructor after super() sets it as an instance property.\n * Used by private methods to register middleware without going through the override.\n */\n private nativeUse!: typeof this.use\n\n constructor(\n @inject(CONTAINER_TOKEN) container: Container,\n @inject(LOGGER_TOKENS.LoggerService) logger: LoggerService,\n @inject(DI_TOKENS.Application) application: Application,\n ) {\n const trailingSlash: TrailingSlashMode = application.config.trailingSlash ?? 'ignore'\n\n super({\n // Always non-strict: a registered `/foo` route matches both `/foo` and `/foo/`.\n // For the redirect modes, the trailing-slash middleware runs first and\n // canonicalises via 308 before matching reaches the registered route.\n strict: false,\n defaultHook: (result) => {\n if (!result.success) {\n throw new SchemaValidationError(result.error)\n }\n },\n })\n\n this._container = container\n this._logger = logger\n\n // Capture Hono's original `use` (set by super() as an instance property)\n this.nativeUse = this.use\n\n // Override `use` to support Stratal middleware classes alongside Hono-native handlers\n this.use = ((...args: unknown[]) => {\n if (isMiddlewareClass(args[0])) {\n this.nativeUse('*', createMiddlewareChain(args as Constructor<Middleware>[]))\n return this\n }\n\n if (typeof args[0] === 'string' && args.length > 1 && isMiddlewareClass(args[1])) {\n this.nativeUse(args[0], createMiddlewareChain(args.slice(1) as Constructor<Middleware>[]))\n return this\n }\n\n return (this.nativeUse as (...a: unknown[]) => unknown)(...args)\n }) as typeof this.use\n\n // Trailing-slash redirect runs first so redirected requests skip request-scope\n // and logger overhead.\n const trailingSlashRedirect = createTrailingSlashRedirect(trailingSlash)\n if (trailingSlashRedirect) {\n this.nativeUse('*', trailingSlashRedirect)\n }\n\n // Internal setup — uses nativeUse to bypass the override\n this.setupRequestScope()\n this.applyGlobalMiddleware()\n }\n\n /**\n * Apply global middleware (logger + error handler).\n * Called by Application after locale middleware is applied by LocalePathService.\n */\n private applyGlobalMiddleware(): void {\n this.nativeUse('*', createLoggerMiddleware(this._logger) as MiddlewareHandler<RouterEnv>)\n this.onError((err, c) => this.handleException(c, err))\n }\n\n /**\n * Configure OpenAPI endpoints, controller routes, and 404 handler.\n * Called once by Application.initialize().\n */\n async configure(): Promise<void> {\n if (this.configured) throw new RouterError('HonoApp has already been configured')\n\n // OpenAPI endpoints\n const openAPIService = this._container.resolve<OpenAPIService>(OPENAPI_TOKENS.OpenAPIService)\n openAPIService.setupEndpoints(this, this._container)\n\n // Controller routes + global middleware\n const routeRegistrationService = this._container.resolve<RouteRegistrationService>(RouteRegistrationService)\n await routeRegistrationService.configure()\n\n // 404 handler (must be last)\n this.notFound((c) => { throw new RouteNotFoundError(c.req.path, c.req.method) })\n\n this.configured = true\n }\n\n private setupRequestScope(): void {\n this.nativeUse('*', async (c: Context<RouterEnv>, next: () => Promise<void>) => {\n const routerContext = new RouterContext(c)\n const requestContainer = this._container.createRequestScope(routerContext)\n c.set(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER, requestContainer)\n\n await runWithContainer(requestContainer, next)\n })\n }\n\n private handleException(c: Context<RouterEnv>, err: unknown) {\n // Fallback to global container if request scope setup failed before storing REQUEST_CONTAINER\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- runtime guard: REQUEST_CONTAINER may be unset if request scope middleware throws\n const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER) ?? this._container\n const handler = requestContainer.resolve<ExceptionHandler>(DI_TOKENS.ExceptionHandler)\n const ctx = createHttpExceptionContext(c)\n // Run the handler within the request container's async context so standalone\n // helpers like `route()` (which read the ambient container via getContainer)\n // resolve correctly. Errors thrown before the request-scope middleware's\n // `runWithContainer` body — e.g. route-param validation failures — otherwise\n // reach here outside any container scope, breaking redirect-back rendering.\n return runWithContainer(requestContainer, () => handler.handle(err, ctx))\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,uBAAuB,QAA0C;CAC/E,OAAO,OAAO,GAAG,SAAS;EACxB,MAAM,QAAQ,KAAK,IAAI;EACvB,MAAM,SAAS,EAAE,IAAI;EACrB,MAAM,OAAO,EAAE,IAAI;EAEnB,MAAM,KAAK;EAEX,MAAM,WAAW,KAAK,IAAI,IAAI;EAC9B,MAAM,SAAS,EAAE,IAAI;EAErB,OAAO,KAAK,UAAU,OAAO,GAAG,KAAK,MAAM,UAAU;GACnD;GACA;GACA;GACA;EACF,CAAC;CACH;AACF;;;AChCA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;AAoBxB,SAAgB,4BACd,MACqC;CACrC,IAAI,SAAS,UAAU,OAAO;CAE9B,OAAO,OAAO,GAAG,SAAS;EACxB,MAAM,MAAM,IAAI,IAAI,EAAE,IAAI,GAAG;EAC7B,MAAM,gBAAgB,mBAAmB,IAAI,UAAU,IAAI;EAC3D,IAAI,kBAAkB,IAAI,UAAU,OAAO,KAAK;EAChD,OAAO,EAAE,SAAS,GAAG,gBAAgB,IAAI,UAAU,eAAe;CACpE;AACF;;;;ACbA,MAAM,qBAAqB,QAEzB,OAAO,QAAQ,cAAc,IAAI,aAAa,YAAY,IAAI;AAazD,IAAA,UAAA,MAAM,gBAAgB,YAAuB;CAClD,aAAqB;CACrB;CACA;;;;;;CAOA;CAEA,YACE,WACA,QACA,aACA;EACA,MAAM,gBAAmC,YAAY,OAAO,iBAAiB;EAE7E,MAAM;GAIJ,QAAQ;GACR,cAAc,WAAW;IACvB,IAAI,CAAC,OAAO,SACV,MAAM,IAAI,sBAAsB,OAAO,KAAK;GAEhD;EACF,CAAC;EAED,KAAK,aAAa;EAClB,KAAK,UAAU;EAGf,KAAK,YAAY,KAAK;EAGtB,KAAK,QAAQ,GAAG,SAAoB;GAClC,IAAI,kBAAkB,KAAK,EAAE,GAAG;IAC9B,KAAK,UAAU,KAAK,sBAAsB,IAAiC,CAAC;IAC5E,OAAO;GACT;GAEA,IAAI,OAAO,KAAK,OAAO,YAAY,KAAK,SAAS,KAAK,kBAAkB,KAAK,EAAE,GAAG;IAChF,KAAK,UAAU,KAAK,IAAI,sBAAsB,KAAK,MAAM,CAAC,CAA8B,CAAC;IACzF,OAAO;GACT;GAEA,OAAQ,KAAK,UAA2C,GAAG,IAAI;EACjE;EAIA,MAAM,wBAAwB,4BAA4B,aAAa;EACvE,IAAI,uBACF,KAAK,UAAU,KAAK,qBAAqB;EAI3C,KAAK,kBAAkB;EACvB,KAAK,sBAAsB;CAC7B;;;;;CAMA,wBAAsC;EACpC,KAAK,UAAU,KAAK,uBAAuB,KAAK,OAAO,CAAiC;EACxF,KAAK,SAAS,KAAK,MAAM,KAAK,gBAAgB,GAAG,GAAG,CAAC;CACvD;;;;;CAMA,MAAM,YAA2B;EAC/B,IAAI,KAAK,YAAY,MAAM,IAAI,YAAY,qCAAqC;EAIhF,KAD4B,WAAW,QAAwB,eAAe,cACjE,EAAE,eAAe,MAAM,KAAK,UAAU;EAInD,MADiC,KAAK,WAAW,QAAkC,wBACtD,EAAE,UAAU;EAGzC,KAAK,UAAU,MAAM;GAAE,MAAM,IAAI,mBAAmB,EAAE,IAAI,MAAM,EAAE,IAAI,MAAM;EAAE,CAAC;EAE/E,KAAK,aAAa;CACpB;CAEA,oBAAkC;EAChC,KAAK,UAAU,KAAK,OAAO,GAAuB,SAA8B;GAC9E,MAAM,gBAAgB,IAAI,cAAc,CAAC;GACzC,MAAM,mBAAmB,KAAK,WAAW,mBAAmB,aAAa;GACzE,EAAE,IAAI,oBAAoB,mBAAmB,gBAAgB;GAE7D,MAAM,iBAAiB,kBAAkB,IAAI;EAC/C,CAAC;CACH;CAEA,gBAAwB,GAAuB,KAAc;EAG3D,MAAM,mBAAmB,EAAE,IAAI,oBAAoB,iBAAiB,KAAK,KAAK;EAC9E,MAAM,UAAU,iBAAiB,QAA0B,UAAU,gBAAgB;EACrF,MAAM,MAAM,2BAA2B,CAAC;EAMxC,OAAO,iBAAiB,wBAAwB,QAAQ,OAAO,KAAK,GAAG,CAAC;CAC1E;AACF;;CAtHC,UAAU;oBAcN,OAAO,eAAe,CAAA;oBACtB,OAAO,cAAc,aAAa,CAAA;oBAClC,OAAO,UAAU,WAAW,CAAA"}
@@ -1,5 +1,6 @@
1
- import { f as ROUTE_METADATA_KEYS } from "./errors-COW9-Mar.mjs";
2
- import { i as z } from "./validation-DtJwAv7O.mjs";
1
+ import { n as getMetadata, t as defineMetadata } from "./metadata-DzzprcID.mjs";
2
+ import { u as ROUTE_METADATA_KEYS } from "./exception-context-kEoMFwze.mjs";
3
+ import { r as z } from "./zod-eKqqhZ5_.mjs";
3
4
  //#region src/router/decorators/http-method.decorator.ts
4
5
  /**
5
6
  * Creates an HTTP method decorator factory for the given HTTP method.
@@ -17,10 +18,10 @@ function createHttpMethodDecorator(method) {
17
18
  path,
18
19
  config: config ?? { response: z.any() }
19
20
  };
20
- Reflect.defineMetadata(ROUTE_METADATA_KEYS.ROUTE_CONFIG, metadata, target, propertyKey);
21
- const existing = Reflect.getOwnMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, target) ?? [];
21
+ defineMetadata(ROUTE_METADATA_KEYS.ROUTE_CONFIG, metadata, target, propertyKey);
22
+ const existing = getMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, target) ?? [];
22
23
  existing.push(propertyKey);
23
- Reflect.defineMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, existing, target);
24
+ defineMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, existing, target);
24
25
  return descriptor;
25
26
  };
26
27
  };
@@ -93,4 +94,4 @@ const All = createHttpMethodDecorator("all");
93
94
  //#endregion
94
95
  export { Post as a, Patch as i, Delete as n, Put as o, Get as r, All as t };
95
96
 
96
- //# sourceMappingURL=http-method.decorator-BrgHMdLQ.mjs.map
97
+ //# sourceMappingURL=http-method.decorator-ByWZb9DO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-method.decorator-ByWZb9DO.mjs","names":[],"sources":["../src/router/decorators/http-method.decorator.ts"],"sourcesContent":["import { defineMetadata, getMetadata } from '../../di/metadata'\nimport { z } from '../../i18n/validation/zod'\nimport { ROUTE_METADATA_KEYS } from '../constants'\nimport type { ExplicitRouteMetadata, HttpMethod, RouteConfig } from '../types'\n\n/**\n * Creates an HTTP method decorator factory for the given HTTP method.\n *\n * The returned decorator stores {@link ExplicitRouteMetadata} on the method and\n * tracks the method name under {@link ROUTE_METADATA_KEYS.DECORATED_METHODS}\n * on the controller prototype so they can be discovered at registration time.\n */\nfunction createHttpMethodDecorator(method: HttpMethod) {\n return function (path: string, config?: RouteConfig) {\n return function (\n target: object,\n propertyKey: string,\n descriptor: PropertyDescriptor\n ) {\n const metadata: ExplicitRouteMetadata = {\n type: 'explicit',\n method,\n path,\n config: config ?? { response: z.any() },\n }\n\n defineMetadata(\n ROUTE_METADATA_KEYS.ROUTE_CONFIG,\n metadata,\n target,\n propertyKey\n )\n\n // Track this method as decorated on the prototype\n const existing: string[] =\n getMetadata<string[]>(ROUTE_METADATA_KEYS.DECORATED_METHODS, target) ?? []\n existing.push(propertyKey)\n defineMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, existing, target)\n\n return descriptor\n }\n }\n}\n\n/**\n * Registers a GET route on the controller method.\n *\n * @param path - Route path relative to the controller base path\n * @param config - Optional route configuration (response schema, body, params, etc.)\n *\n * @example\n * ```typescript\n * @Controller('/api/v1/users')\n * class UsersController {\n * @Get('/', { response: z.array(userSchema), summary: 'List users' })\n * async list(ctx: RouterContext) { ... }\n *\n * @Get('/:id', { params: z.object({ id: z.string().uuid() }), response: userSchema })\n * async getUser(ctx: RouterContext) { ... }\n * }\n * ```\n */\nexport const Get = createHttpMethodDecorator('get')\n\n/**\n * Registers a POST route on the controller method.\n *\n * @param path - Route path relative to the controller base path\n * @param config - Optional route configuration (response schema, body, params, etc.)\n *\n * @example\n * ```typescript\n * @Controller('/api/v1/users')\n * class UsersController {\n * @Post('/', { body: createUserSchema, response: userSchema, statusCode: 201 })\n * async createUser(ctx: RouterContext) { ... }\n * }\n * ```\n */\nexport const Post = createHttpMethodDecorator('post')\n\n/**\n * Registers a PUT route on the controller method.\n *\n * @param path - Route path relative to the controller base path\n * @param config - Optional route configuration\n */\nexport const Put = createHttpMethodDecorator('put')\n\n/**\n * Registers a PATCH route on the controller method.\n *\n * @param path - Route path relative to the controller base path\n * @param config - Optional route configuration\n */\nexport const Patch = createHttpMethodDecorator('patch')\n\n/**\n * Registers a DELETE route on the controller method.\n *\n * @param path - Route path relative to the controller base path\n * @param config - Optional route configuration\n */\nexport const Delete = createHttpMethodDecorator('delete')\n\n/**\n * Registers an ALL (any HTTP method) route on the controller method.\n * Routes using @All are registered without OpenAPI validation\n * since OpenAPI does not support a catch-all HTTP method.\n *\n * @param path - Route path relative to the controller base path\n * @param config - Optional route configuration\n */\nexport const All = createHttpMethodDecorator('all')\n"],"mappings":";;;;;;;;;;;AAYA,SAAS,0BAA0B,QAAoB;CACrD,OAAO,SAAU,MAAc,QAAsB;EACnD,OAAO,SACL,QACA,aACA,YACA;GACA,MAAM,WAAkC;IACtC,MAAM;IACN;IACA;IACA,QAAQ,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE;GACxC;GAEA,eACE,oBAAoB,cACpB,UACA,QACA,WACF;GAGA,MAAM,WACJ,YAAsB,oBAAoB,mBAAmB,MAAM,KAAK,CAAC;GAC3E,SAAS,KAAK,WAAW;GACzB,eAAe,oBAAoB,mBAAmB,UAAU,MAAM;GAEtE,OAAO;EACT;CACF;AACF;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,MAAM,0BAA0B,KAAK;;;;;;;;;;;;;;;;AAiBlD,MAAa,OAAO,0BAA0B,MAAM;;;;;;;AAQpD,MAAa,MAAM,0BAA0B,KAAK;;;;;;;AAQlD,MAAa,QAAQ,0BAA0B,OAAO;;;;;;;AAQtD,MAAa,SAAS,0BAA0B,QAAQ;;;;;;;;;AAUxD,MAAa,MAAM,0BAA0B,KAAK"}
@@ -1,3 +1,238 @@
1
- import { A as LocaleNotSupportedError, C as DetectionStrategy, D as buildDetectorOptions, E as ResolvedI18nOptions, O as resolveI18nOptions, S as I18nModule, T as LanguageDetectionOptions, _ as Messages, b as messages, g as MessageRegistry, h as MessageLoaderService, k as TranslationMissingError, m as I18nContextMiddleware, v as getLocales, w as I18nModuleOptions, x as I18N_TOKENS, y as getMessages } from "../index-ByOyTmqf.mjs";
2
- import { C as MessageParams, S as MessageKeys, T as SystemMessageKeys, _ as AppMessageNamespaces, b as II18nService, g as AppMessageKeys, v as AppMessages, w as Prefixes, x as MessageKeyPrefix, y as DeepKeys } from "../index-Bnpfq6uk.mjs";
3
- export { AppMessageKeys, AppMessageNamespaces, AppMessages, DeepKeys, DetectionStrategy, I18N_TOKENS, I18nContextMiddleware, I18nModule, I18nModuleOptions, II18nService, LanguageDetectionOptions, LocaleNotSupportedError, MessageKeyPrefix, MessageKeys, MessageLoaderService, MessageParams, MessageRegistry, Messages, Prefixes, ResolvedI18nOptions, SystemMessageKeys, TranslationMissingError, buildDetectorOptions, getLocales, getMessages, messages, resolveI18nOptions };
1
+ import { Dr as ApplicationError, In as OnInitialize, Nn as ModuleContext, kn as DynamicModule } from "../index-B_JoEl3V.mjs";
2
+ import { _ as MessageParams, d as AppMessages, f as DeepKeys, g as MessageKeys, h as MessageKeyPrefix, l as AppMessageKeys, m as II18nService, p as FilterByPrefix, u as AppMessageNamespaces, v as Prefixes, y as SystemMessageKeys } from "../zod-wecrEVAs.mjs";
3
+ import { t as index_d_exports } from "../index-HgOLNruQ.mjs";
4
+ import { DetectorOptions } from "hono/language";
5
+
6
+ //#region src/i18n/i18n.error.d.ts
7
+ declare class I18nError extends ApplicationError {}
8
+ //#endregion
9
+ //#region src/i18n/i18n.options.d.ts
10
+ /**
11
+ * Detection strategy for locale resolution
12
+ *
13
+ * - `'cookie'` — reads from the `locale` cookie (default)
14
+ * - `'header'` — reads from the `Accept-Language` header
15
+ * - `'querystring'` — reads from the `?locale=` query parameter
16
+ * - `'path'` — reads from the first URL path segment (e.g., `/en/api/users`)
17
+ */
18
+ type DetectionStrategy = 'cookie' | 'header' | 'querystring' | 'path';
19
+ interface BaseDetection {
20
+ /** Set to false to disable language detection entirely. @default true */
21
+ enabled?: boolean;
22
+ }
23
+ /**
24
+ * Language detection options (discriminated by strategy)
25
+ *
26
+ * @example Cookie detection (default)
27
+ * ```typescript
28
+ * { strategy: 'cookie' }
29
+ * ```
30
+ *
31
+ * @example Header detection
32
+ * ```typescript
33
+ * { strategy: 'header' }
34
+ * ```
35
+ *
36
+ * @example Path detection
37
+ * ```typescript
38
+ * { strategy: 'path' }
39
+ * ```
40
+ *
41
+ * @example Disable detection
42
+ * ```typescript
43
+ * { enabled: false }
44
+ * ```
45
+ */
46
+ type LanguageDetectionOptions = (BaseDetection & {
47
+ strategy?: 'cookie';
48
+ cookieOptions?: DetectorOptions['cookieOptions'];
49
+ }) | (BaseDetection & {
50
+ strategy: 'header';
51
+ }) | (BaseDetection & {
52
+ strategy: 'querystring';
53
+ }) | (BaseDetection & {
54
+ strategy: 'path';
55
+ /**
56
+ * Controls whether the default locale gets a URL path prefix.
57
+ *
58
+ * - `false` (default) — The default locale has no prefix (`/users`), other locales
59
+ * are prefixed (`/fr/users`). Requests to the prefixed default locale (`/en/users`) return 404.
60
+ * - `'redirect'` — Same as `false`, but requests to the prefixed default locale
61
+ * (`/en/users`) are 301-redirected to the unprefixed path (`/users`).
62
+ * - `true` — All locales are prefixed (`/en/users`, `/fr/users`).
63
+ *
64
+ * @default false
65
+ */
66
+ prefixDefaultLocale?: false | true | 'redirect';
67
+ }) | {
68
+ enabled: false;
69
+ };
70
+ /**
71
+ * Options for configuring the I18n module
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * I18nModule.forRoot({
76
+ * defaultLocale: 'en',
77
+ * fallbackLocale: 'en',
78
+ * locales: ['en', 'fr'],
79
+ * detection: { strategy: 'header' },
80
+ * })
81
+ * ```
82
+ */
83
+ interface I18nModuleOptions {
84
+ /**
85
+ * Default locale for the application
86
+ * @default 'en'
87
+ */
88
+ defaultLocale?: string;
89
+ /**
90
+ * Fallback locale when translation is missing
91
+ * @default 'en'
92
+ */
93
+ fallbackLocale?: string;
94
+ /**
95
+ * List of supported locales
96
+ * Request locales not in this list will fall back to defaultLocale
97
+ */
98
+ locales?: string[];
99
+ /**
100
+ * Language detection configuration
101
+ * Controls how the locale is extracted from incoming requests
102
+ */
103
+ detection?: LanguageDetectionOptions;
104
+ }
105
+ /**
106
+ * Resolved options with all defaults applied
107
+ * Used internally by I18n services
108
+ */
109
+ interface ResolvedI18nOptions {
110
+ defaultLocale: string;
111
+ fallbackLocale: string;
112
+ locales: string[];
113
+ detection: {
114
+ enabled: boolean;
115
+ strategy: DetectionStrategy; /** Resolved value of the path detection `prefixDefaultLocale` option. Only meaningful when `strategy` is `'path'`. */
116
+ prefixDefaultLocale: false | true | 'redirect';
117
+ };
118
+ }
119
+ /**
120
+ * Resolve I18n options with defaults
121
+ */
122
+ declare function resolveI18nOptions(options?: I18nModuleOptions): ResolvedI18nOptions;
123
+ /**
124
+ * Build Hono languageDetector options from I18n module options
125
+ */
126
+ declare function buildDetectorOptions(options?: I18nModuleOptions): Partial<DetectorOptions>;
127
+ //#endregion
128
+ //#region src/i18n/i18n.module.d.ts
129
+ declare class I18nModule implements OnInitialize {
130
+ onInitialize(_context: ModuleContext): void;
131
+ static forRoot(options?: I18nModuleOptions): DynamicModule;
132
+ static registerMessages(messages: Record<string, Record<string, unknown>>): DynamicModule;
133
+ }
134
+ //#endregion
135
+ //#region src/i18n/i18n.tokens.d.ts
136
+ /**
137
+ * I18n Module DI Tokens
138
+ * Symbol-based tokens to avoid string collisions
139
+ */
140
+ declare const I18N_TOKENS: {
141
+ /** MessageLoaderService - loads and caches locale messages */readonly MessageLoader: symbol; /** I18nService - request-scoped translation service */
142
+ readonly I18nService: symbol; /** I18nModuleOptions - configuration options from forRoot() */
143
+ readonly Options: symbol; /** MessageRegistry - singleton accumulator for registerMessages() contributions */
144
+ readonly MessageRegistry: symbol;
145
+ };
146
+ //#endregion
147
+ //#region src/i18n/messages/index.d.ts
148
+ /**
149
+ * All locale messages
150
+ * Explicitly import and export (no filesystem scanning - Cloudflare Workers compatible)
151
+ */
152
+ declare const messages: {
153
+ readonly en: typeof index_d_exports;
154
+ };
155
+ /**
156
+ * Type for all messages
157
+ */
158
+ type Messages = typeof messages;
159
+ /**
160
+ * Get messages for all locales
161
+ */
162
+ declare function getMessages(): Record<string, Record<string, unknown>>;
163
+ /**
164
+ * Get available locales
165
+ */
166
+ declare function getLocales(): string[];
167
+ //#endregion
168
+ //#region src/i18n/services/message-registry.d.ts
169
+ /**
170
+ * Message Registry
171
+ *
172
+ * Accumulates i18n messages from multiple `I18nModule.registerMessages()` calls.
173
+ * Messages are collected statically (at module import time) and deep-merged
174
+ * when `getMergedMessages()` is called by `MessageLoaderService`.
175
+ *
176
+ * Later registrations override earlier ones at leaf level.
177
+ */
178
+ declare class MessageRegistry {
179
+ /**
180
+ * Add messages (called statically by I18nModule.registerMessages)
181
+ */
182
+ static addMessages(messages: Record<string, Record<string, unknown>>): void;
183
+ /**
184
+ * Get all messages deep-merged in registration order
185
+ */
186
+ getMergedMessages(): Record<string, Record<string, unknown>>;
187
+ /**
188
+ * Reset registry (for testing)
189
+ * @internal
190
+ */
191
+ static reset(): void;
192
+ }
193
+ //#endregion
194
+ //#region src/i18n/services/message-loader.service.d.ts
195
+ declare class MessageLoaderService {
196
+ private readonly registry;
197
+ private readonly options?;
198
+ private readonly cache;
199
+ private readonly compiledCache;
200
+ private readonly locales;
201
+ private readonly defaultLocale;
202
+ constructor(registry: MessageRegistry, options?: I18nModuleOptions | undefined);
203
+ translate(locale: string, key: string, params?: Record<string, unknown>): string;
204
+ getMessages(locale: string): Record<string, unknown>;
205
+ getAvailableLocales(): string[];
206
+ isLocaleSupported(locale: string): boolean;
207
+ getDefaultLocale(): string;
208
+ getFilteredMessages(locale: string, options?: {
209
+ only?: MessageKeyPrefix[];
210
+ }): Record<string, string>;
211
+ private getCompiledMessages;
212
+ private flattenMessages;
213
+ }
214
+ //#endregion
215
+ //#region src/i18n/with-i18n.d.ts
216
+ /**
217
+ * Translate a message key using I18nService from the DI container.
218
+ *
219
+ * Works in both request scope (uses the request's detected locale) and
220
+ * global scope (defaults to 'en'). Can be used anywhere — services,
221
+ * middleware, error handlers, cron jobs, queue consumers, etc.
222
+ *
223
+ * @param key - Message key (e.g., 'common.welcome', 'errors.notFound')
224
+ * @param params - Optional interpolation parameters
225
+ * @returns Translated string, or the key itself if no container is available
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * import { withI18n } from 'stratal/i18n'
230
+ *
231
+ * const message = withI18n('errors.notFound')
232
+ * const greeting = withI18n('common.welcome', { name: 'Alice' })
233
+ * ```
234
+ */
235
+ declare function withI18n(key: MessageKeys, params?: MessageParams): string;
236
+ //#endregion
237
+ export { AppMessageKeys, AppMessageNamespaces, AppMessages, DeepKeys, DetectionStrategy, FilterByPrefix, I18N_TOKENS, I18nError, I18nModule, I18nModuleOptions, II18nService, LanguageDetectionOptions, MessageKeyPrefix, MessageKeys, MessageLoaderService, MessageParams, MessageRegistry, type Messages, Prefixes, ResolvedI18nOptions, SystemMessageKeys, buildDetectorOptions, getLocales, getMessages, messages, resolveI18nOptions, withI18n };
238
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/i18n/i18n.error.ts","../../src/i18n/i18n.options.ts","../../src/i18n/i18n.module.ts","../../src/i18n/i18n.tokens.ts","../../src/i18n/messages/index.ts","../../src/i18n/services/message-registry.ts","../../src/i18n/services/message-loader.service.ts","../../src/i18n/with-i18n.ts"],"mappings":";;;;;;cAEa,SAAA,SAAkB,gBAAgB;;;;;AAAA;;;;ACgB/C;;KAAY,iBAAA;AAAA,UAEF,aAAA;EAFmB;EAI3B,OAAO;AAAA;;;AAAA;AA0BT;;;;;;;;;;;;;;;;;;;;KAAY,wBAAA,IACP,aAAA;EAAkB,QAAA;EAAqB,aAAA,GAAgB,eAAA;AAAA,MACvD,aAAA;EAAkB,QAAA;AAAA,MAClB,aAAA;EAAkB,QAAA;AAAA,MAClB,aAAA;EACD,QAAA;EAwCF;;;;;AAYoC;AAOtC;;;;;EA/CI,mBAAA;AAAA;EAEE,OAAA;AAAA;;;;;AAqDiB;AAOvB;;;;;;;;UA7CiB,iBAAA;EAiED;;;;EA5Dd,aAAA;EA4DiE;;;;EAtDjE,cAAA;EAsDiE;;;AAAuB;EAhDxF,OAAA;;;ACzFF;;ED+FE,SAAA,GAAY,wBAAwB;AAAA;;;;;UAOrB,mBAAA;EACf,aAAA;EACA,cAAA;EACA,OAAA;EACA,SAAA;IACE,OAAA;IACA,QAAA,EAAU,iBAAiB,ECpGhB;IDsGX,mBAAA;EAAA;AAAA;;;;iBAOY,kBAAA,CAAmB,OAAA,GAAU,iBAAA,GAAoB,mBAAmB;;;;iBAoBpE,oBAAA,CAAqB,OAAA,GAAU,iBAAA,GAAoB,OAAA,CAAQ,eAAA;;;cClI9D,UAAA,YAAsB,YAAA;EACjC,YAAA,CAAa,QAAA,EAAU,aAAA;EAAA,OAIhB,OAAA,CAAQ,OAAA,GAAS,iBAAA,GAAyB,aAAA;EAAA,OAS1C,gBAAA,CAAiB,QAAA,EAAU,MAAA,SAAe,MAAA,qBAA2B,aAAA;AAAA;;;;;;;cC1BjE,WAAA;gGHHU;EAAA,8BAAwB;EAAA;;;;;;;;AAAA;cIWlC,QAAA;EAAA,oBAA0B,eAAA;AAAA;AHKvC;;;AAAA,KGAY,QAAA,UAAkB,QAAQ;AHAT;AAA+C;;AAA/C,iBGKb,WAAA,IAAe,MAAM,SAAS,MAAA;;AHDrC;AA0BT;iBGlBgB,UAAA;;;;;;;;;AJ5BhB;;;cK+Ba,eAAA;EL/BkC;;;EAAA,OKmCtC,WAAA,CAAY,QAAA,EAAU,MAAA,SAAe,MAAA;EJnBlC;;;EI4BV,iBAAA,IAAqB,MAAA,SAAe,MAAA;EJ5BT;AAA+C;;;EAA/C,OI+CpB,KAAA;AAAA;;;cCpDI,oBAAA;EAAA,iBAO6C,QAAA;EAAA,iBAErC,OAAA;EAAA,iBARF,KAAA;EAAA,iBACA,aAAA;EAAA,iBACA,OAAA;EAAA,iBACA,aAAA;cAGuC,QAAA,EAAU,eAAA,EAE/C,OAAA,GAAU,iBAAA;EAwB7B,SAAA,CAAU,MAAA,UAAgB,GAAA,UAAa,MAAA,GAAS,MAAA;EAOhD,WAAA,CAAY,MAAA,WAAiB,MAAA;EAI7B,mBAAA;EAIA,iBAAA,CAAkB,MAAA;EAIlB,gBAAA;EAIA,mBAAA,CACE,MAAA,UACA,OAAA;IAAY,IAAA,GAAO,gBAAA;EAAA,IAClB,MAAA;EAAA,QAeK,mBAAA;EAAA,QAmBA,eAAA;AAAA;;;;;;;;ANxGV;;;;AAA+C;;;;ACgB/C;;;;AAA6B;AAA+C;iBMK5D,QAAA,CAAS,GAAA,EAAK,WAAA,EAAa,MAAA,GAAS,aAAa"}
@@ -1,3 +1,39 @@
1
- import { w as I18N_TOKENS } from "../errors-COW9-Mar.mjs";
2
- import { B as LocaleNotSupportedError, F as getMessages, H as I18nContextMiddleware, I as messages, L as buildDetectorOptions, M as MessageRegistry, N as MessageLoaderService, P as getLocales, R as resolveI18nOptions, t as I18nModule, z as TranslationMissingError } from "../i18n.module-CzXLW9Hy.mjs";
3
- export { I18N_TOKENS, I18nContextMiddleware, I18nModule, LocaleNotSupportedError, MessageLoaderService, MessageRegistry, TranslationMissingError, buildDetectorOptions, getLocales, getMessages, messages, resolveI18nOptions };
1
+ import { a as ApplicationError, n as getContainer } from "../container-storage-BmOJ4_Na.mjs";
2
+ import "../errors-mXYxG0XB.mjs";
3
+ import { t as I18N_TOKENS } from "../i18n.tokens-CZ_v8oyS.mjs";
4
+ import { i as resolveI18nOptions, r as buildDetectorOptions } from "../locale-path.service-D-dHiIPc.mjs";
5
+ import { a as getLocales, i as MessageLoaderService, o as getMessages, r as MessageRegistry, s as messages, t as I18nModule } from "../i18n.module-DRQAZoSZ.mjs";
6
+ //#region src/i18n/i18n.error.ts
7
+ var I18nError = class extends ApplicationError {};
8
+ //#endregion
9
+ //#region src/i18n/with-i18n.ts
10
+ /**
11
+ * Translate a message key using I18nService from the DI container.
12
+ *
13
+ * Works in both request scope (uses the request's detected locale) and
14
+ * global scope (defaults to 'en'). Can be used anywhere — services,
15
+ * middleware, error handlers, cron jobs, queue consumers, etc.
16
+ *
17
+ * @param key - Message key (e.g., 'common.welcome', 'errors.notFound')
18
+ * @param params - Optional interpolation parameters
19
+ * @returns Translated string, or the key itself if no container is available
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { withI18n } from 'stratal/i18n'
24
+ *
25
+ * const message = withI18n('errors.notFound')
26
+ * const greeting = withI18n('common.welcome', { name: 'Alice' })
27
+ * ```
28
+ */
29
+ function withI18n(key, params) {
30
+ try {
31
+ return getContainer().resolve(I18N_TOKENS.I18nService).t(key, params);
32
+ } catch {
33
+ return key;
34
+ }
35
+ }
36
+ //#endregion
37
+ export { I18N_TOKENS, I18nError, I18nModule, MessageLoaderService, MessageRegistry, buildDetectorOptions, getLocales, getMessages, messages, resolveI18nOptions, withI18n };
38
+
39
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/i18n/i18n.error.ts","../../src/i18n/with-i18n.ts"],"sourcesContent":["import { ApplicationError } from '../errors'\n\nexport class I18nError extends ApplicationError {}\n","import { getContainer } from '../di/container-storage'\nimport { I18N_TOKENS } from './i18n.tokens'\nimport type { II18nService, MessageKeys, MessageParams } from './i18n.types'\n\n/**\n * Translate a message key using I18nService from the DI container.\n *\n * Works in both request scope (uses the request's detected locale) and\n * global scope (defaults to 'en'). Can be used anywhere — services,\n * middleware, error handlers, cron jobs, queue consumers, etc.\n *\n * @param key - Message key (e.g., 'common.welcome', 'errors.notFound')\n * @param params - Optional interpolation parameters\n * @returns Translated string, or the key itself if no container is available\n *\n * @example\n * ```typescript\n * import { withI18n } from 'stratal/i18n'\n *\n * const message = withI18n('errors.notFound')\n * const greeting = withI18n('common.welcome', { name: 'Alice' })\n * ```\n */\nexport function withI18n(key: MessageKeys, params?: MessageParams): string {\n try {\n const container = getContainer()\n const i18n = container.resolve<II18nService>(I18N_TOKENS.I18nService)\n return i18n.t(key, params)\n } catch {\n return key\n }\n}\n"],"mappings":";;;;;;AAEA,IAAa,YAAb,cAA+B,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;ACqBjD,SAAgB,SAAS,KAAkB,QAAgC;CACzE,IAAI;EAGF,OAFkB,aACG,EAAE,QAAsB,YAAY,WAC/C,EAAE,EAAE,KAAK,MAAM;CAC3B,QAAQ;EACN,OAAO;CACT;AACF"}
@@ -1,2 +1,2 @@
1
- import { a as errors, i as emails, n as zodI18n, o as common, r as validation } from "../../../index-C1KvMncZ.mjs";
2
- export { common, emails, errors, validation, zodI18n };
1
+ import { a as common, i as emails, n as zodI18n, r as validation } from "../../../index-HgOLNruQ.mjs";
2
+ export { common, emails, validation, zodI18n };
@@ -1,2 +1,2 @@
1
- import { a as errors, i as emails, n as zodI18n, o as common, r as validation } from "../../../en-DSH_bhh6.mjs";
2
- export { common, emails, errors, validation, zodI18n };
1
+ import { a as common, i as emails, n as zodI18n, r as validation } from "../../../en-CDZBMcc1.mjs";
2
+ export { common, emails, validation, zodI18n };
@@ -1,30 +1,8 @@
1
- //#region src/i18n/utils/setup.d.ts
1
+ //#region src/i18n/utils/deep-merge.d.ts
2
2
  /**
3
- * I18n Setup - Message Compiler Registration
4
- *
5
- * Registers a JIT (Just-In-Time) message compiler for @intlify/core-base
6
- * that works in Cloudflare Workers edge runtime.
7
- *
8
- * This must be called ONCE at application startup, before any I18nService instances are created.
3
+ * Deep merge two objects. Source values override target at leaf level.
9
4
  */
10
- /**
11
- * Setup JIT message compiler for i18n
12
- *
13
- * Registers a message compiler that uses JIT compilation mode.
14
- * In @intlify/core-base v10+, JIT mode is enabled by default, which generates
15
- * AST (Abstract Syntax Tree) instead of JavaScript code, making it compatible
16
- * with CSP-restricted environments like Cloudflare Workers.
17
- *
18
- * **IMPORTANT:** Call this function once at application startup before creating
19
- * any I18nService instances. Safe to call multiple times (only registers once).
20
- *
21
- * @example
22
- * ```typescript
23
- * // In application entry point (before app.initialize())
24
- * setupI18nCompiler()
25
- * ```
26
- */
27
- declare function setupI18nCompiler(): void;
5
+ declare function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown>;
28
6
  //#endregion
29
- export { setupI18nCompiler };
7
+ export { deepMerge };
30
8
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/i18n/utils/setup.ts"],"mappings":";;AA8BA;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,iBAAA,CAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../../src/i18n/utils/deep-merge.ts"],"mappings":";;AAGA;;iBAAgB,SAAA,CACd,MAAA,EAAQ,MAAA,mBACR,MAAA,EAAQ,MAAA,oBACP,MAAA"}