stratal 0.0.22 → 0.0.24

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 (270) hide show
  1. package/README.md +1 -1
  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 +41 -54
  5. package/dist/bin/quarry.mjs.map +1 -1
  6. package/dist/cache/index.d.mts +5 -3
  7. package/dist/cache/index.d.mts.map +1 -1
  8. package/dist/cache/index.mjs +123 -39
  9. package/dist/cache/index.mjs.map +1 -1
  10. package/dist/{cache.service-e34gV6tz.d.mts → cache.service-uElmBtdS.d.mts} +24 -34
  11. package/dist/cache.service-uElmBtdS.d.mts.map +1 -0
  12. package/dist/{command-BU4ApTo5.mjs → command-BvmUAPPQ.mjs} +15 -3
  13. package/dist/command-BvmUAPPQ.mjs.map +1 -0
  14. package/dist/{command-wXfvHbBZ.d.mts → command-CPhFHjG3.d.mts} +2 -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 +3 -3
  19. package/dist/config/index.d.mts.map +1 -1
  20. package/dist/config/index.mjs +7 -6
  21. package/dist/config/index.mjs.map +1 -1
  22. package/dist/{consumer-registry-DHQtypr1.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-GpNNz79X.mjs → container-storage-BmOJ4_Na.mjs} +1 -1
  25. package/dist/{container-storage-GpNNz79X.mjs.map → container-storage-BmOJ4_Na.mjs.map} +1 -1
  26. package/dist/{controller.decorator-DIUazNU7.mjs → controller.decorator-C5UVeJS3.mjs} +4 -4
  27. package/dist/{controller.decorator-DIUazNU7.mjs.map → controller.decorator-C5UVeJS3.mjs.map} +1 -1
  28. package/dist/cron/index.d.mts +79 -4
  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-9bpN9bu4.mjs → cron.module-Bgzq5hiT.mjs} +17 -7
  34. package/dist/cron.module-Bgzq5hiT.mjs.map +1 -0
  35. package/dist/{decorate-HgTKAYK8.mjs → decorate-CuAoSZvs.mjs} +2 -2
  36. package/dist/{deep-merge-C8NgcXw4.mjs → deep-merge-ByiAOZ3r.mjs} +1 -1
  37. package/dist/{deep-merge-C8NgcXw4.mjs.map → deep-merge-ByiAOZ3r.mjs.map} +1 -1
  38. package/dist/di/index.d.mts +2 -2
  39. package/dist/di/index.mjs +3 -3
  40. package/dist/{di-BO1QIb5H.mjs → di-DseMn-z9.mjs} +244 -135
  41. package/dist/di-DseMn-z9.mjs.map +1 -0
  42. package/dist/email/index.d.mts +33 -40
  43. package/dist/email/index.d.mts.map +1 -1
  44. package/dist/email/index.mjs +456 -41
  45. package/dist/email/index.mjs.map +1 -1
  46. package/dist/{en-BPP6h6y5.mjs → en-CDZBMcc1.mjs} +2 -2
  47. package/dist/{en-BPP6h6y5.mjs.map → en-CDZBMcc1.mjs.map} +1 -1
  48. package/dist/{env-DKSbuBi5.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 +1 -1
  51. package/dist/errors/index.mjs +3 -3
  52. package/dist/{errors-BBZTnjdq.mjs → errors-mXYxG0XB.mjs} +5 -5
  53. package/dist/{errors-BBZTnjdq.mjs.map → errors-mXYxG0XB.mjs.map} +1 -1
  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-D1KdDaiP.mjs → events-BXJGZjpG.mjs} +16 -6
  58. package/dist/events-BXJGZjpG.mjs.map +1 -0
  59. package/dist/{exception-context-B4kM-M53.mjs → exception-context-kEoMFwze.mjs} +3 -3
  60. package/dist/{exception-context-B4kM-M53.mjs.map → exception-context-kEoMFwze.mjs.map} +1 -1
  61. package/dist/{gateway-context-CFe6a9gz.mjs → gateway-context-TMu_AlJt.mjs} +25 -6
  62. package/dist/{gateway-context-CFe6a9gz.mjs.map → gateway-context-TMu_AlJt.mjs.map} +1 -1
  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-Ced-uNIF.mjs → guards-DALPXy3_.mjs} +2 -2
  67. package/dist/{guards-Ced-uNIF.mjs.map → guards-DALPXy3_.mjs.map} +1 -1
  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-CdjKFJZZ.mjs → http-method.decorator-ByWZb9DO.mjs} +4 -4
  71. package/dist/{http-method.decorator-CdjKFJZZ.mjs.map → http-method.decorator-ByWZb9DO.mjs.map} +1 -1
  72. package/dist/i18n/index.d.mts +4 -4
  73. package/dist/i18n/index.d.mts.map +1 -1
  74. package/dist/i18n/index.mjs +5 -5
  75. package/dist/i18n/index.mjs.map +1 -1
  76. package/dist/i18n/messages/en/index.d.mts +1 -1
  77. package/dist/i18n/messages/en/index.mjs +1 -1
  78. package/dist/i18n/utils/index.mjs +1 -1
  79. package/dist/i18n/validation/index.d.mts +3 -3
  80. package/dist/i18n/validation/index.mjs +3 -3
  81. package/dist/{i18n.module-BlXrtAlV.mjs → i18n.module-DRQAZoSZ.mjs} +14 -11
  82. package/dist/{i18n.module-BlXrtAlV.mjs.map → i18n.module-DRQAZoSZ.mjs.map} +1 -1
  83. package/dist/{i18n.tokens-hwRpmjRq.mjs → i18n.tokens-CZ_v8oyS.mjs} +1 -1
  84. package/dist/{i18n.tokens-hwRpmjRq.mjs.map → i18n.tokens-CZ_v8oyS.mjs.map} +1 -1
  85. package/dist/{index-B4UBK-2T.d.mts → index-0ItCjaqw.d.mts} +1 -1
  86. package/dist/index-0ItCjaqw.d.mts.map +1 -0
  87. package/dist/{index-CW1YHSft.d.mts → index-B5JBRcWD.d.mts} +249 -103
  88. package/dist/index-B5JBRcWD.d.mts.map +1 -0
  89. package/dist/{index-BtlE9RuO.d.mts → index-BUt92sAE.d.mts} +1 -1
  90. package/dist/index-BUt92sAE.d.mts.map +1 -0
  91. package/dist/{index-DEncMcC6.d.mts → index-B_JoEl3V.d.mts} +221 -16
  92. package/dist/index-B_JoEl3V.d.mts.map +1 -0
  93. package/dist/{index-Dj5IMwtr.d.mts → index-DtBNIFuP.d.mts} +4 -6
  94. package/dist/index-DtBNIFuP.d.mts.map +1 -0
  95. package/dist/{index-KMgSCSM7.d.mts → index-HgOLNruQ.d.mts} +1 -1
  96. package/dist/{index-KMgSCSM7.d.mts.map → index-HgOLNruQ.d.mts.map} +1 -1
  97. package/dist/index.d.mts +6 -5
  98. package/dist/index.mjs +3 -2
  99. package/dist/{is-command-CX5rAfZW.mjs → is-command-CEPO9n8c.mjs} +2 -2
  100. package/dist/{is-command-CX5rAfZW.mjs.map → is-command-CEPO9n8c.mjs.map} +1 -1
  101. package/dist/{is-seeder-CYCtELlm.mjs → is-seeder-Gvh_AM71.mjs} +1 -1
  102. package/dist/{is-seeder-CYCtELlm.mjs.map → is-seeder-Gvh_AM71.mjs.map} +1 -1
  103. package/dist/lazy-module-loader-Ib383jH_.d.mts +60 -0
  104. package/dist/lazy-module-loader-Ib383jH_.d.mts.map +1 -0
  105. package/dist/locale-path.service-D-dHiIPc.mjs +165 -0
  106. package/dist/locale-path.service-D-dHiIPc.mjs.map +1 -0
  107. package/dist/locale-url-nZrZxqJP.mjs +44 -0
  108. package/dist/locale-url-nZrZxqJP.mjs.map +1 -0
  109. package/dist/locale-url.service-C2EWmGdq.mjs +41 -0
  110. package/dist/locale-url.service-C2EWmGdq.mjs.map +1 -0
  111. package/dist/logger/index.d.mts +1 -1
  112. package/dist/logger/index.mjs +2 -2
  113. package/dist/logger/index.mjs.map +1 -1
  114. package/dist/macroable/index.d.mts +2 -2
  115. package/dist/macroable/index.mjs +1 -1
  116. package/dist/{macroable-DzlfzT50.mjs → macroable-cvDTFZ_A.mjs} +1 -1
  117. package/dist/{macroable-DzlfzT50.mjs.map → macroable-cvDTFZ_A.mjs.map} +1 -1
  118. package/dist/{metadata-BVkc4aUu.mjs → metadata-DzzprcID.mjs} +1 -1
  119. package/dist/{metadata-BVkc4aUu.mjs.map → metadata-DzzprcID.mjs.map} +1 -1
  120. package/dist/module/index.d.mts +4 -3
  121. package/dist/module/index.d.mts.map +1 -1
  122. package/dist/module/index.mjs +10 -2
  123. package/dist/module/index.mjs.map +1 -0
  124. package/dist/{module-xYoHba6B.mjs → module-registry-Dm-pqHd3.mjs} +189 -57
  125. package/dist/module-registry-Dm-pqHd3.mjs.map +1 -0
  126. package/dist/module.decorator-CYHY6pG5.mjs +19 -0
  127. package/dist/module.decorator-CYHY6pG5.mjs.map +1 -0
  128. package/dist/openapi/index.d.mts +44 -8
  129. package/dist/openapi/index.d.mts.map +1 -1
  130. package/dist/openapi/index.mjs +3 -2
  131. package/dist/{openapi-C6lm0RmV.mjs → openapi-CstuTM8S.mjs} +55 -229
  132. package/dist/openapi-CstuTM8S.mjs.map +1 -0
  133. package/dist/openapi-tools.service-BC5EC3R3.mjs +206 -0
  134. package/dist/openapi-tools.service-BC5EC3R3.mjs.map +1 -0
  135. package/dist/{openapi.service-CrLlsXAd.d.mts → openapi.service-YhTiJ1bO.d.mts} +3 -3
  136. package/dist/{openapi.service-CrLlsXAd.d.mts.map → openapi.service-YhTiJ1bO.d.mts.map} +1 -1
  137. package/dist/quarry/index.d.mts +14 -5
  138. package/dist/quarry/index.d.mts.map +1 -1
  139. package/dist/quarry/index.mjs +6 -5
  140. package/dist/quarry/runner.d.mts +11 -11
  141. package/dist/quarry/runner.d.mts.map +1 -1
  142. package/dist/quarry/runner.mjs +192 -22
  143. package/dist/quarry/runner.mjs.map +1 -1
  144. package/dist/{quarry-registry-D4hIGScf.d.mts → quarry-registry-CXg0RFXq.d.mts} +4 -4
  145. package/dist/quarry-registry-CXg0RFXq.d.mts.map +1 -0
  146. package/dist/{quarry-registry-DkraZNwn.mjs → quarry.module-BuRPGMDm.mjs} +22 -21
  147. package/dist/quarry.module-BuRPGMDm.mjs.map +1 -0
  148. package/dist/queue/index.d.mts +3 -3
  149. package/dist/queue/index.mjs +42 -31
  150. package/dist/queue/index.mjs.map +1 -1
  151. package/dist/queue.module-nddvxzCB.mjs +613 -0
  152. package/dist/queue.module-nddvxzCB.mjs.map +1 -0
  153. package/dist/queue.tokens-DjHnFmre.mjs +11 -0
  154. package/dist/queue.tokens-DjHnFmre.mjs.map +1 -0
  155. package/dist/{r2-storage.provider-Hfm6LdZQ.mjs → r2-storage.provider-DCxQt9dD.mjs} +4 -4
  156. package/dist/{r2-storage.provider-Hfm6LdZQ.mjs.map → r2-storage.provider-DCxQt9dD.mjs.map} +1 -1
  157. package/dist/{rate-limit.decorator-D69zdZbp.mjs → rate-limit.decorator-BPAie_p3.mjs} +3 -3
  158. package/dist/{rate-limit.decorator-D69zdZbp.mjs.map → rate-limit.decorator-BPAie_p3.mjs.map} +1 -1
  159. package/dist/rate-limiter/index.d.mts +5 -5
  160. package/dist/rate-limiter/index.d.mts.map +1 -1
  161. package/dist/rate-limiter/index.mjs +26 -21
  162. package/dist/rate-limiter/index.mjs.map +1 -1
  163. package/dist/route-name-DGoBOfPg.mjs +171 -0
  164. package/dist/route-name-DGoBOfPg.mjs.map +1 -0
  165. package/dist/route-registration.service-D6vSwiKP.mjs +918 -0
  166. package/dist/route-registration.service-D6vSwiKP.mjs.map +1 -0
  167. package/dist/route-registry-CYqLp2Nj.mjs +123 -0
  168. package/dist/route-registry-CYqLp2Nj.mjs.map +1 -0
  169. package/dist/router/index.d.mts +2 -2
  170. package/dist/router/index.mjs +18 -8
  171. package/dist/router-CWGBD-Bg.mjs +78 -0
  172. package/dist/router-CWGBD-Bg.mjs.map +1 -0
  173. package/dist/router-resolver-D4YlPNlm.mjs +88 -0
  174. package/dist/router-resolver-D4YlPNlm.mjs.map +1 -0
  175. package/dist/seeder/index.d.mts +14 -4
  176. package/dist/seeder/index.d.mts.map +1 -1
  177. package/dist/seeder/index.mjs +5 -3
  178. package/dist/{seeder-BADTig4n.mjs → seeder-7ubkms-Y.mjs} +7 -56
  179. package/dist/seeder-7ubkms-Y.mjs.map +1 -0
  180. package/dist/seeder-registry-CyUmKsJq.mjs +57 -0
  181. package/dist/seeder-registry-CyUmKsJq.mjs.map +1 -0
  182. package/dist/seeder.module-CYYwk3Qk.mjs +15 -0
  183. package/dist/seeder.module-CYYwk3Qk.mjs.map +1 -0
  184. package/dist/{signed-url-BqUqt5dF.mjs → signed-url-DIU0sK_6.mjs} +1 -1
  185. package/dist/{signed-url-BqUqt5dF.mjs.map → signed-url-DIU0sK_6.mjs.map} +1 -1
  186. package/dist/storage/index.d.mts +3 -3
  187. package/dist/storage/index.d.mts.map +1 -1
  188. package/dist/storage/index.mjs +2 -2
  189. package/dist/storage/providers/index.d.mts +2 -2
  190. package/dist/storage/providers/index.d.mts.map +1 -1
  191. package/dist/storage/providers/index.mjs +1 -1
  192. package/dist/{storage-BA3ppVYM.mjs → storage-MDZypIE9.mjs} +12 -11
  193. package/dist/{storage-BA3ppVYM.mjs.map → storage-MDZypIE9.mjs.map} +1 -1
  194. package/dist/{storage-provider.interface-DQMtT42e.d.mts → storage-provider.interface-ClUwxz4S.d.mts} +2 -2
  195. package/dist/storage-provider.interface-ClUwxz4S.d.mts.map +1 -0
  196. package/dist/storage.error-Dnib4VHc.mjs +8 -0
  197. package/dist/{storage.error-C6FY037a.mjs.map → storage.error-Dnib4VHc.mjs.map} +1 -1
  198. package/dist/{stratal-Bdq4IdB3.mjs → stratal-DL9M38_s.mjs} +142 -140
  199. package/dist/stratal-DL9M38_s.mjs.map +1 -0
  200. package/dist/{stratal-BsKmvP6J.d.mts → stratal-DwDJPY9N.d.mts} +3 -3
  201. package/dist/{stratal-BsKmvP6J.d.mts.map → stratal-DwDJPY9N.d.mts.map} +1 -1
  202. package/dist/tiered-cache.service-Dv3BhxxE.d.mts +79 -0
  203. package/dist/tiered-cache.service-Dv3BhxxE.d.mts.map +1 -0
  204. package/dist/trailing-slash-CFyw8nYu.mjs +34 -0
  205. package/dist/trailing-slash-CFyw8nYu.mjs.map +1 -0
  206. package/dist/{types-BaeHi67f.d.mts → types-CmV_9xBD.d.mts} +1 -1
  207. package/dist/types-CmV_9xBD.d.mts.map +1 -0
  208. package/dist/uri-h7Q8Jug9.mjs +251 -0
  209. package/dist/uri-h7Q8Jug9.mjs.map +1 -0
  210. package/dist/{usage-generator-DTqaUMR9.mjs → usage-generator-DAWYasuP.mjs} +4 -4
  211. package/dist/usage-generator-DAWYasuP.mjs.map +1 -0
  212. package/dist/{validation-DUzcjb8Q.mjs → validation-CpOjviyT.mjs} +6 -6
  213. package/dist/{validation-DUzcjb8Q.mjs.map → validation-CpOjviyT.mjs.map} +1 -1
  214. package/dist/{validation.context-XTysWJ3b.mjs → validation.context-CRvmrhq7.mjs} +3 -3
  215. package/dist/{validation.context-XTysWJ3b.mjs.map → validation.context-CRvmrhq7.mjs.map} +1 -1
  216. package/dist/versioning.service-C6aHky8-.mjs +36 -0
  217. package/dist/versioning.service-C6aHky8-.mjs.map +1 -0
  218. package/dist/websocket/index.d.mts +11 -2
  219. package/dist/websocket/index.d.mts.map +1 -1
  220. package/dist/websocket/index.mjs +1 -1
  221. package/dist/workers/index.d.mts +2 -2
  222. package/dist/workers/index.d.mts.map +1 -1
  223. package/dist/workers/index.mjs +3 -3
  224. package/dist/workers/index.mjs.map +1 -1
  225. package/dist/{zod-hMa3rSHV.mjs → zod-eKqqhZ5_.mjs} +2 -2
  226. package/dist/{zod-hMa3rSHV.mjs.map → zod-eKqqhZ5_.mjs.map} +1 -1
  227. package/dist/{zod-DvWTfRpI.d.mts → zod-wecrEVAs.d.mts} +8 -3
  228. package/dist/zod-wecrEVAs.d.mts.map +1 -0
  229. package/package.json +19 -30
  230. package/dist/base-email.provider-BWZHIjt8.mjs +0 -42
  231. package/dist/base-email.provider-BWZHIjt8.mjs.map +0 -1
  232. package/dist/cache.service-e34gV6tz.d.mts.map +0 -1
  233. package/dist/cache.tokens-ovi_c52J.mjs +0 -6
  234. package/dist/cache.tokens-ovi_c52J.mjs.map +0 -1
  235. package/dist/colors-axmupKdp.mjs +0 -16
  236. package/dist/colors-axmupKdp.mjs.map +0 -1
  237. package/dist/command-BU4ApTo5.mjs.map +0 -1
  238. package/dist/command-wXfvHbBZ.d.mts.map +0 -1
  239. package/dist/consumer-registry-DHQtypr1.d.mts.map +0 -1
  240. package/dist/cron-manager-9bpN9bu4.mjs.map +0 -1
  241. package/dist/cron-manager-CSTIBPcM.d.mts +0 -124
  242. package/dist/cron-manager-CSTIBPcM.d.mts.map +0 -1
  243. package/dist/di-BO1QIb5H.mjs.map +0 -1
  244. package/dist/env-DKSbuBi5.d.mts.map +0 -1
  245. package/dist/events-D1KdDaiP.mjs.map +0 -1
  246. package/dist/index-B4UBK-2T.d.mts.map +0 -1
  247. package/dist/index-BtlE9RuO.d.mts.map +0 -1
  248. package/dist/index-CW1YHSft.d.mts.map +0 -1
  249. package/dist/index-DEncMcC6.d.mts.map +0 -1
  250. package/dist/index-Dj5IMwtr.d.mts.map +0 -1
  251. package/dist/module-xYoHba6B.mjs.map +0 -1
  252. package/dist/openapi-C6lm0RmV.mjs.map +0 -1
  253. package/dist/quarry-registry-D4hIGScf.d.mts.map +0 -1
  254. package/dist/quarry-registry-DkraZNwn.mjs.map +0 -1
  255. package/dist/queue.module-DeWJ0tQM.mjs +0 -355
  256. package/dist/queue.module-DeWJ0tQM.mjs.map +0 -1
  257. package/dist/resend.provider-Ur6tU7fK.mjs +0 -68
  258. package/dist/resend.provider-Ur6tU7fK.mjs.map +0 -1
  259. package/dist/router-Cy6DjkvP.mjs +0 -1852
  260. package/dist/router-Cy6DjkvP.mjs.map +0 -1
  261. package/dist/seeder-BADTig4n.mjs.map +0 -1
  262. package/dist/smtp.provider-C129sNBT.mjs +0 -76
  263. package/dist/smtp.provider-C129sNBT.mjs.map +0 -1
  264. package/dist/storage-provider.interface-DQMtT42e.d.mts.map +0 -1
  265. package/dist/storage.error-C6FY037a.mjs +0 -8
  266. package/dist/stratal-Bdq4IdB3.mjs.map +0 -1
  267. package/dist/types-BaeHi67f.d.mts.map +0 -1
  268. package/dist/usage-generator-DTqaUMR9.mjs.map +0 -1
  269. package/dist/zod-DvWTfRpI.d.mts.map +0 -1
  270. /package/dist/{chunk-D1SwGrFN.mjs → chunk-BBjsoOtd.mjs} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"runner.mjs","names":[],"sources":["../../src/quarry/commands/api.command.ts","../../src/quarry/commands/event-list.command.ts","../../src/quarry/commands/help.command.ts","../../src/quarry/commands/i18n-utils.ts","../../src/quarry/commands/i18n-check.command.ts","../../src/quarry/commands/i18n-duplicates.command.ts","../../src/quarry/commands/i18n-list.command.ts","../../src/quarry/commands/i18n-namespaces.command.ts","../../src/quarry/commands/i18n-search.command.ts","../../src/quarry/commands/i18n-stats.command.ts","../../src/quarry/commands/mcp-serve.command.ts","../../src/quarry/commands/mcp-tools.command.ts","../../src/quarry/commands/queue-list.command.ts","../../src/quarry/commands/route-list.command.ts","../../src/quarry/commands/route-types.command.ts","../../src/quarry/commands/schedule-list.command.ts","../../src/quarry/builtin-quarry.module.ts","../../src/quarry/quarry-runner.ts"],"sourcesContent":["import { inject } from '../../di'\nimport type { Application } from '../../application'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { Command } from '../command'\nimport { bold, cyan, green, red, yellow } from '../colors'\n\nexport class ApiCommand extends Command {\n static command = 'api {route?} {--method= : HTTP method} {--data= : JSON request body} {--header=* : Headers (Key:Value)} {--query=* : Query params (key=value)}'\n static description = 'Call an API route directly'\n static aliases = ['api:call']\n\n constructor(@inject(DI_TOKENS.Application) private app: Application) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const route = this.string('route')\n\n if (!route) {\n return (await this.call('route:list')).exitCode\n }\n\n return this.callRoute(route)\n }\n\n private async callRoute(route: string): Promise<number> {\n const method = (this.string('method') || 'GET').toUpperCase()\n const data = this.string('data')\n const headerArgs = this.array('header')\n const queryArgs = this.array('query')\n\n const headers: Record<string, string> = {}\n if (data) {\n headers['Content-Type'] = 'application/json'\n }\n for (const h of headerArgs) {\n const colonIdx = h.indexOf(':')\n if (colonIdx > 0) {\n headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim()\n }\n }\n\n // Build query string\n let url = route\n if (queryArgs.length > 0) {\n const parts = queryArgs.map((q) => {\n const eqIdx = q.indexOf('=')\n if (eqIdx > 0) {\n return `${encodeURIComponent(q.slice(0, eqIdx))}=${encodeURIComponent(q.slice(eqIdx + 1))}`\n }\n return encodeURIComponent(q)\n })\n url += `?${parts.join('&')}`\n }\n\n const request = new Request(`http://localhost${url}`, {\n method,\n headers,\n body: data || undefined,\n })\n\n const hono = await this.app.ensureHono()\n const response = await hono.fetch(request, this.app.env)\n const body = await response.text()\n\n // Color-coded status\n const statusText = `${response.status} ${response.statusText}`\n let coloredStatus: string\n if (response.status >= 200 && response.status < 300) {\n coloredStatus = green(bold(statusText))\n } else if (response.status >= 300 && response.status < 400) {\n coloredStatus = yellow(bold(statusText))\n } else {\n coloredStatus = red(bold(statusText))\n }\n\n this.line(`${cyan(method)} ${route} ${coloredStatus}`)\n this.newLine()\n\n // Response headers\n const headerLines: string[] = []\n response.headers.forEach((value, key) => {\n headerLines.push(` ${key}: ${value}`)\n })\n if (headerLines.length > 0) {\n this.line(bold('Headers:'))\n for (const hl of headerLines) {\n this.line(hl)\n }\n this.newLine()\n }\n\n // Body\n if (body) {\n this.line(bold('Body:'))\n try {\n this.line(JSON.stringify(JSON.parse(body), null, 2))\n } catch {\n this.line(body)\n }\n }\n\n return response.status >= 400 ? 1 : 0\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { getListenerHandlers } from '../../events'\nimport type { ModuleRegistry } from '../../module/module-registry'\nimport { Command } from '../command'\n\nexport class EventListCommand extends Command {\n static command = 'event:list'\n static description = 'List all registered event listeners'\n\n constructor(@inject(DI_TOKENS.ModuleRegistry) private modules: ModuleRegistry) {\n super()\n }\n\n handle(): number | undefined {\n const listeners = this.modules.getAllListeners()\n\n if (listeners.length === 0) {\n this.info('No event listeners found')\n return 0\n }\n\n const rows: string[][] = []\n\n for (const ListenerClass of listeners) {\n const handlers = getListenerHandlers(ListenerClass)\n for (const { methodName, event, options } of handlers) {\n rows.push([\n event,\n ListenerClass.name,\n methodName,\n String(options?.priority ?? 0),\n options?.blocking ? 'Yes' : 'No',\n ])\n }\n }\n\n if (rows.length === 0) {\n this.info('No event handlers found')\n return 0\n }\n\n this.table(['Event', 'Listener', 'Method', 'Priority', 'Blocking'], rows)\n\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { Command } from '../command'\nimport { CommandNotFoundError } from '../errors/command-not-found.error'\nimport type { QuarryRegistry } from '../quarry-registry'\n\nexport class HelpCommand extends Command {\n static command = 'help {command?}'\n static description = 'Show help for a command or list all commands'\n static aliases = ['list']\n\n constructor(@inject(DI_TOKENS.Quarry) private quarryRegistry: QuarryRegistry) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const commandName = this.string('command')\n\n if (!commandName) {\n const listing = await this.quarryRegistry.listUsage()\n this.line(listing)\n return 0\n }\n\n try {\n const usage = await this.quarryRegistry.usage(commandName)\n this.line(usage)\n return 0\n } catch (error) {\n if (error instanceof CommandNotFoundError) {\n this.fail(`Unknown command: ${commandName}`)\n return 1\n }\n throw error\n }\n }\n}\n","export function computeKeyDiff(\n baseKeys: Set<string>,\n targetKeys: Set<string>,\n): { missing: string[]; extra: string[] } {\n const missing: string[] = []\n const extra: string[] = []\n\n for (const key of baseKeys) {\n if (!targetKeys.has(key)) missing.push(key)\n }\n for (const key of targetKeys) {\n if (!baseKeys.has(key)) extra.push(key)\n }\n\n return { missing: missing.sort(), extra: extra.sort() }\n}\n\nexport function extractNamespace(key: string, depth: number): string {\n return key.split('.').slice(0, depth).join('.')\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\nimport { computeKeyDiff } from './i18n-utils'\n\nexport class I18nCheckCommand extends Command {\n static command = 'i18n:check {--locale= : Check a specific locale only} {--prefix= : Filter by namespace prefix}'\n static description = 'Check i18n translations for missing or extra keys'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const localeFilter = this.string('locale')\n const prefix = this.string('prefix')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const enKeys = new Set(Object.keys(this.loader.getFilteredMessages('en', filterOptions)))\n\n if (enKeys.size === 0) {\n this.info('No message keys found')\n return 0\n }\n\n const locales = this.loader.getAvailableLocales().filter((l) => l !== 'en')\n const targets = localeFilter ? locales.filter((l) => l === localeFilter) : locales\n\n if (targets.length === 0) {\n this.info(localeFilter ? `Locale \"${localeFilter}\" not found` : 'No non-en locales configured')\n return 0\n }\n\n let totalIssues = 0\n const summaryRows: string[][] = []\n\n for (const locale of targets) {\n const localeKeys = new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions)))\n const { missing, extra } = computeKeyDiff(enKeys, localeKeys)\n\n this.newLine()\n this.info(`Locale: ${locale}`)\n\n if (missing.length > 0) {\n this.warn(` Missing (${missing.length}):`)\n for (const key of missing) {\n this.line(` ${key}`)\n }\n } else {\n this.line(' Missing (0)')\n }\n\n if (extra.length > 0) {\n this.warn(` Extra (${extra.length}):`)\n for (const key of extra) {\n this.line(` ${key}`)\n }\n } else {\n this.line(' Extra (0)')\n }\n\n totalIssues += missing.length + extra.length\n summaryRows.push([locale, String(enKeys.size), String(missing.length), String(extra.length)])\n }\n\n this.newLine()\n this.table(['Locale', 'Total', 'Missing', 'Extra'], summaryRows)\n\n if (totalIssues > 0) {\n this.newLine()\n this.fail(`${totalIssues} issue(s) found`)\n return undefined\n }\n\n this.newLine()\n this.success('All translations are complete')\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nDuplicatesCommand extends Command {\n static command = 'i18n:duplicates {--locale= : Locale to check (default: en)} {--prefix= : Filter by namespace prefix}'\n static description = 'Find i18n keys with duplicate translation values'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const locale = this.string('locale') || 'en'\n const prefix = this.string('prefix')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const messages = this.loader.getFilteredMessages(locale, filterOptions)\n const valueToKeys = new Map<string, string[]>()\n\n for (const [key, value] of Object.entries(messages)) {\n const existing = valueToKeys.get(value)\n if (existing) {\n existing.push(key)\n } else {\n valueToKeys.set(value, [key])\n }\n }\n\n const duplicates: [string, string][] = []\n for (const [value, keys] of valueToKeys) {\n if (keys.length > 1) {\n duplicates.push([value, keys.sort().join(', ')])\n }\n }\n\n if (duplicates.length === 0) {\n this.info('No duplicate values found')\n return 0\n }\n\n duplicates.sort((a, b) => a[0].localeCompare(b[0]))\n this.table(['Value', 'Keys'], duplicates)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nListCommand extends Command {\n static command = 'i18n:list {--locale= : Show keys for a specific locale} {--prefix= : Filter by namespace prefix} {--values : Show translated values}'\n static description = 'List all i18n message keys'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const localeFilter = this.string('locale')\n const prefix = this.string('prefix')\n const showValues = this.boolean('values')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const enMessages = this.loader.getFilteredMessages('en', filterOptions)\n const enKeys = Object.keys(enMessages).sort()\n\n if (enKeys.length === 0) {\n this.info('No message keys found')\n return 0\n }\n\n if (localeFilter && showValues) {\n const localeMessages = this.loader.getFilteredMessages(localeFilter, filterOptions)\n const rows = enKeys.map((key) => [key, localeMessages[key] ?? '-'])\n this.table(['Key', 'Value'], rows)\n return 0\n }\n\n const locales = localeFilter\n ? [localeFilter]\n : this.loader.getAvailableLocales()\n\n const localeMessages = new Map<string, Set<string>>()\n for (const locale of locales) {\n localeMessages.set(locale, new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions))))\n }\n\n const headers = ['Key', ...locales]\n const rows = enKeys.map((key) => {\n const coverage = locales.map((locale) => (localeMessages.get(locale)!.has(key) ? 'Y' : 'N'))\n return [key, ...coverage]\n })\n\n this.table(headers, rows)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\nimport { extractNamespace } from './i18n-utils'\n\nexport class I18nNamespacesCommand extends Command {\n static command = 'i18n:namespaces {--depth= : Namespace depth (default: 1)} {--locale= : Show counts for a specific locale}'\n static description = 'List i18n message namespaces with key counts'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const depth = this.number('depth') || 1\n const localeFilter = this.string('locale')\n\n const locales = localeFilter\n ? [localeFilter]\n : this.loader.getAvailableLocales()\n\n const namespaceCounts = new Map<string, Map<string, number>>()\n\n for (const locale of locales) {\n const messages = this.loader.getFilteredMessages(locale)\n\n for (const key of Object.keys(messages)) {\n const ns = extractNamespace(key, depth)\n\n if (!namespaceCounts.has(ns)) {\n namespaceCounts.set(ns, new Map())\n }\n const counts = namespaceCounts.get(ns)!\n counts.set(locale, (counts.get(locale) ?? 0) + 1)\n }\n }\n\n if (namespaceCounts.size === 0) {\n this.info('No namespaces found')\n return 0\n }\n\n const sortedNamespaces = [...namespaceCounts.keys()].sort()\n const headers = ['Namespace', ...locales]\n const rows = sortedNamespaces.map((ns) => {\n const counts = namespaceCounts.get(ns)!\n return [ns, ...locales.map((locale) => String(counts.get(locale) ?? 0))]\n })\n\n this.table(headers, rows)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nSearchCommand extends Command {\n static command = 'i18n:search {query : Search term (substring match)} {--locale= : Locale to search in (default: en)} {--keys-only : Only match key names, not values}'\n static description = 'Search for i18n message keys or values'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const query = this.string('query').toLowerCase()\n const locale = this.string('locale') || 'en'\n const keysOnly = this.boolean('keys-only')\n\n const messages = this.loader.getFilteredMessages(locale)\n const matches: [string, string][] = []\n\n for (const [key, value] of Object.entries(messages)) {\n const keyMatch = key.toLowerCase().includes(query)\n const valueMatch = !keysOnly && value.toLowerCase().includes(query)\n\n if (keyMatch || valueMatch) {\n matches.push([key, value])\n }\n }\n\n if (matches.length === 0) {\n this.info(`No keys matching \"${this.string('query')}\" found`)\n return 0\n }\n\n matches.sort((a, b) => a[0].localeCompare(b[0]))\n this.table(['Key', 'Value'], matches)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nStatsCommand extends Command {\n static command = 'i18n:stats {--prefix= : Filter by namespace prefix}'\n static description = 'Show i18n translation coverage statistics'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const prefix = this.string('prefix')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const enKeys = new Set(Object.keys(this.loader.getFilteredMessages('en', filterOptions)))\n\n if (enKeys.size === 0) {\n this.info('No message keys found')\n return 0\n }\n\n const locales = this.loader.getAvailableLocales()\n const rows: string[][] = []\n\n for (const locale of locales) {\n const localeKeys = new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions)))\n const isBase = locale === 'en'\n\n let translated = 0\n for (const key of enKeys) {\n if (localeKeys.has(key)) translated++\n }\n\n const missing = enKeys.size - translated\n let extra = 0\n for (const key of localeKeys) {\n if (!enKeys.has(key)) extra++\n }\n\n const coverage = ((translated / enKeys.size) * 100).toFixed(1) + '%'\n\n rows.push([\n locale,\n String(enKeys.size),\n String(translated),\n String(missing),\n isBase ? '-' : String(extra),\n coverage,\n ])\n }\n\n this.table(['Locale', 'Keys', 'Translated', 'Missing', 'Extra', 'Coverage'], rows)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport { z } from 'zod'\nimport type { Application } from '../../application'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { OPENAPI_TOKENS } from '../../openapi/openapi.tokens'\nimport type { Dispatcher } from '../../openapi/services/openapi-tools.service'\nimport { OpenApiToolsService } from '../../openapi/services/openapi-tools.service'\nimport type { OpenAPIService } from '../../openapi/services/openapi.service'\nimport type { IOpenAPIConfigService } from '../../openapi/types'\nimport { Command } from '../command'\n\nexport class McpServeCommand extends Command {\n static command = 'mcp:serve {--url= : Base URL for external dispatch} {--header=* : Headers (Key:Value)} {--tag=* : Only expose routes with these OpenAPI tags} {--path= : Only expose routes matching this path prefix}'\n static description = 'Start an MCP stdio server exposing API routes as tools'\n\n constructor(\n @inject(DI_TOKENS.Application) private app: Application,\n @inject(OPENAPI_TOKENS.OpenAPIService) private openAPIService: OpenAPIService,\n ) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js')\n const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js')\n\n const baseUrl = this.string('url')\n const headerArgs = this.array('header')\n const tags = this.array('tag')\n const pathPrefix = this.string('path')\n\n const headers: Record<string, string> = {}\n for (const h of headerArgs) {\n const colonIdx = h.indexOf(':')\n if (colonIdx > 0) {\n headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim()\n }\n }\n\n const hono = await this.app.ensureHono()\n const spec = this.openAPIService.getSpec(hono, this.app.container)\n\n const dispatcher: Dispatcher = baseUrl\n ? async (method, url, opts) => {\n const fullUrl = `${baseUrl}${url}`\n try {\n return await fetch(fullUrl, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n ...opts?.headers,\n },\n body: opts?.body !== undefined ? JSON.stringify(opts.body) : undefined,\n })\n } catch (error) {\n throw new Error(`MCP dispatch failed: ${method} ${fullUrl} — ${error instanceof Error ? error.message : String(error)}`, { cause: error })\n }\n }\n : async (method, url, opts) => {\n const request = new Request(`http://localhost${url}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n ...opts?.headers,\n },\n body: opts?.body !== undefined ? JSON.stringify(opts.body) : undefined,\n })\n try {\n return await hono.fetch(request, this.app.env)\n } catch (error) {\n throw new Error(`MCP dispatch failed: ${method} ${url} — ${error instanceof Error ? error.message : String(error)}`, { cause: error })\n }\n }\n\n const service = new OpenApiToolsService(spec, { dispatcher })\n const filter = {\n tags: tags.length > 0 ? tags : undefined,\n pathPrefix: pathPrefix || undefined,\n }\n const tools = service.getTools(filter)\n\n const configService = this.app.container.resolve<IOpenAPIConfigService>(OPENAPI_TOKENS.ConfigService)\n const config = configService.getEffectiveConfig()\n\n const server = new McpServer({\n name: config.info.title,\n version: config.info.version,\n })\n\n // Register each tool\n for (const tool of tools) {\n const inputSchema = z.fromJSONSchema(tool.inputSchema)\n server.registerTool(tool.name, { description: tool.description, inputSchema }, async (args) => {\n const result = await service.executeTool(tool.name, args as Record<string, unknown>)\n return {\n content: [{ type: 'text' as const, text: `Status: ${result.status}\\n\\n${result.body}` }],\n }\n })\n }\n\n // Expose OpenAPI spec as a resource\n server.registerResource(\n 'openapi-spec',\n 'openapi://spec',\n { description: 'Full OpenAPI specification', mimeType: 'application/json' },\n () => ({\n contents: [{\n uri: 'openapi://spec',\n mimeType: 'application/json',\n text: JSON.stringify(spec, null, 2),\n }],\n }),\n )\n\n const transport = new StdioServerTransport()\n const closed = new Promise<void>((resolve) => { transport.onclose = resolve })\n await server.connect(transport)\n\n // Write info to stderr (stdout is reserved for MCP JSON-RPC)\n process.stderr.write(`MCP server started with ${tools.length} tool(s)\\n`)\n\n // Keep process alive until client disconnects\n await closed\n\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { Application } from '../../application'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { OPENAPI_TOKENS } from '../../openapi/openapi.tokens'\nimport type { OpenAPIService } from '../../openapi/services/openapi.service'\nimport { OpenApiToolsService } from '../../openapi/services/openapi-tools.service'\nimport { Command } from '../command'\n\nexport class McpToolsCommand extends Command {\n static command = 'mcp:tools {--tag=* : Filter by OpenAPI tags} {--path= : Filter by path prefix}'\n static description = 'List API routes that would be exposed as MCP tools'\n\n constructor(\n @inject(DI_TOKENS.Application) private app: Application,\n @inject(OPENAPI_TOKENS.OpenAPIService) private openAPIService: OpenAPIService,\n ) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const tags = this.array('tag')\n const pathPrefix = this.string('path')\n\n const hono = await this.app.ensureHono()\n const spec = this.openAPIService.getSpec(hono, this.app.container)\n\n const service = new OpenApiToolsService(spec)\n const filter = {\n tags: tags.length > 0 ? tags : undefined,\n pathPrefix: pathPrefix || undefined,\n }\n const tools = service.getTools(filter)\n\n if (tools.length === 0) {\n this.info('No tools found')\n return 0\n }\n\n this.table(\n ['Name', 'Method', 'Path', 'Description'],\n tools.map((t) => [t.name, t.method, t.path, t.description]),\n )\n\n return 0\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport type { ConsumerRegistry } from '../../queue/consumer-registry'\nimport { Command } from '../command'\n\nexport class QueueListCommand extends Command {\n static command = 'queue:list'\n static description = 'List all registered queue consumers'\n\n constructor(@inject(DI_TOKENS.ConsumerRegistry) private consumers: ConsumerRegistry) {\n super()\n }\n\n handle(): number | undefined {\n const consumers = this.consumers.getAllConsumers()\n\n if (consumers.length === 0) {\n this.info('No queue consumers found')\n return 0\n }\n\n this.table(\n ['Consumer', 'Message Types'],\n consumers.map(c => [c.constructor.name, c.messageTypes.join(', ')]),\n )\n\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport type { RouteRegistry, RegisteredRoute } from '../../router/route-registry'\nimport { ROUTER_TOKENS } from '../../router/router.tokens'\nimport { Command } from '../command'\n\n/**\n * List all registered routes from RouteRegistry.\n *\n * By default, hidden routes (hideFromDocs) are excluded.\n * Use `--hidden` to include them.\n *\n * @example\n * ```bash\n * quarry route:list\n * quarry route:list --method=GET\n * quarry route:list --path=/users\n * quarry route:list --name=users\n * quarry route:list --hidden\n * ```\n */\nexport class RouteListCommand extends Command {\n static command = 'route:list {--method= : Filter by HTTP method} {--path= : Filter by path substring} {--name= : Filter by route name} {--hidden : Include hidden routes}'\n static description = 'List all registered routes'\n\n constructor(@inject(ROUTER_TOKENS.RouteRegistry) private registry: RouteRegistry) {\n super()\n }\n\n handle(): number | undefined {\n const methodFilter = this.string('method').toUpperCase()\n const pathFilter = this.string('path')\n const nameFilter = this.string('name')\n const showHidden = this.boolean('hidden')\n\n let routes = this.registry.all()\n\n // Filter hidden routes (default: exclude)\n if (!showHidden) {\n routes = routes.filter(r => !r.hidden)\n }\n\n if (methodFilter) {\n routes = routes.filter(r => r.method.toUpperCase() === methodFilter)\n }\n\n if (pathFilter) {\n routes = routes.filter(r => r.path.includes(pathFilter))\n }\n\n if (nameFilter) {\n routes = routes.filter(r => r.name?.includes(nameFilter))\n }\n\n if (routes.length === 0) {\n this.info('No routes found')\n return 0\n }\n\n this.table(\n ['Method', 'Path', 'Name', 'Handler', 'Domain'],\n routes.map(r => this.formatRow(r)),\n )\n\n return undefined\n }\n\n private formatRow(route: RegisteredRoute): string[] {\n return [\n route.method.toUpperCase(),\n route.path,\n route.name ?? '-',\n `${route.controller}.${route.action}`,\n route.domain ?? '-',\n ]\n }\n}\n","import { writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { inject } from '../../di'\nimport type { RouteRegistry, RegisteredRoute } from '../../router/route-registry'\nimport { ROUTER_TOKENS } from '../../router/router.tokens'\nimport type { LocalePathService } from '../../router/services/locale-path.service'\nimport { Command } from '../command'\n\n/**\n * Generate TypeScript types for named routes.\n *\n * Outputs a `stratal.d.ts` file with `StratalRouteMap` augmentation\n * that provides autocomplete and type-safe params for `route()` and `ctx.route()`.\n *\n * @example\n * ```bash\n * quarry route:types # → src/stratal.d.ts\n * quarry route:types --output=types/routes.d.ts\n * ```\n */\nexport class RouteTypesCommand extends Command {\n static command = 'route:types {--output=src/stratal.d.ts : Output file path}'\n static description = 'Generate TypeScript types for named routes'\n\n constructor(\n @inject(ROUTER_TOKENS.RouteRegistry) private registry: RouteRegistry,\n @inject(ROUTER_TOKENS.LocalePathService) private localePathService: LocalePathService,\n ) {\n super()\n }\n\n handle(): number | undefined {\n const outputPath = resolve(this.string('output') || 'src/stratal.d.ts')\n const namedRoutes = this.registry.named()\n\n if (namedRoutes.length === 0) {\n this.warn('No named routes found. Add name to your @Route() or @Get()/@Post() decorators.')\n return 0\n }\n\n const content = this.generateDeclaration(namedRoutes)\n writeFileSync(outputPath, content, 'utf-8')\n this.info(`Generated route types for ${namedRoutes.length} named routes → ${outputPath}`)\n\n return undefined\n }\n\n /**\n * Generate the StratalRouteMap declaration content.\n */\n private generateDeclaration(routes: RegisteredRoute[]): string {\n const localeConfig = this.localePathService.enabled ? this.localePathService.localePathConfig : null\n const localeType = localeConfig\n ? localeConfig.allLocales.map(l => `'${l}'`).join(' | ')\n : null\n const localeOptional = localeConfig ? this.localePathService.prefixDefaultLocale !== true : false\n\n const entries = routes\n .filter((r): r is RegisteredRoute & { name: string } => r.name !== undefined)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map(route => {\n const paramEntries = [\n ...route.paramNames.map(p => `${p}: string`),\n ...route.domainParamNames.map(p => `${p}: string`),\n ]\n\n if (localeType && route.localePaths?.length) {\n const optionalMarker = localeOptional ? '?' : ''\n paramEntries.push(`locale${optionalMarker}: StratalLocale`)\n }\n\n // Extra keys become query-string params at runtime, so allow any\n // string key. Typed path/domain params above still take precedence.\n const indexSignature = localeType && route.localePaths?.length\n ? '[key: string]: string | StratalLocale | undefined'\n : '[key: string]: string | undefined'\n paramEntries.push(indexSignature)\n\n const paramsType = `{ ${paramEntries.join('; ')} }`\n return ` '${route.name}': { params: ${paramsType} }`\n })\n .join('\\n')\n\n const lines = [\n '// Auto-generated by `quarry route:types` — do not edit manually',\n \"declare module 'stratal/router' {\",\n ]\n\n if (localeType) {\n lines.push(` type StratalLocale = ${localeType}`)\n lines.push('')\n }\n\n lines.push(\n ' interface StratalRouteMap {',\n entries,\n ' }',\n '}',\n )\n\n return [\n ...lines,\n '',\n 'export {}',\n '',\n ].join('\\n')\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport type { CronManager } from '../../cron/cron-manager'\nimport { Command } from '../command'\n\nexport class ScheduleListCommand extends Command {\n static command = 'schedule:list'\n static description = 'List all registered cron jobs'\n\n constructor(@inject(DI_TOKENS.Cron) private cron: CronManager) {\n super()\n }\n\n handle(): number | undefined {\n const schedules = this.cron.getAllSchedules()\n\n if (schedules.length === 0) {\n this.info('No cron jobs found')\n return 0\n }\n\n const rows: string[][] = []\n\n for (const schedule of schedules) {\n const jobs = this.cron.getJobsForSchedule(schedule)\n for (const { jobClass } of jobs) {\n rows.push([schedule, jobClass.name])\n }\n }\n\n this.table(['Schedule', 'Job'], rows)\n\n return undefined\n }\n}\n","import { Module } from '../module/module.decorator'\nimport { DbSeedCommand, DbSeedListCommand } from '../seeder'\nimport { ApiCommand } from './commands/api.command'\nimport { EventListCommand } from './commands/event-list.command'\nimport { HelpCommand } from './commands/help.command'\nimport { I18nCheckCommand } from './commands/i18n-check.command'\nimport { I18nDuplicatesCommand } from './commands/i18n-duplicates.command'\nimport { I18nListCommand } from './commands/i18n-list.command'\nimport { I18nNamespacesCommand } from './commands/i18n-namespaces.command'\nimport { I18nSearchCommand } from './commands/i18n-search.command'\nimport { I18nStatsCommand } from './commands/i18n-stats.command'\nimport { McpServeCommand } from './commands/mcp-serve.command'\nimport { McpToolsCommand } from './commands/mcp-tools.command'\nimport { QueueListCommand } from './commands/queue-list.command'\nimport { RouteListCommand } from './commands/route-list.command'\nimport { RouteTypesCommand } from './commands/route-types.command'\nimport { ScheduleListCommand } from './commands/schedule-list.command'\n\n/**\n * Built-in framework CLI commands.\n *\n * Registered automatically by `QuarryRunner` so they're available from\n * `src/quarry.ts` (CLI side). The worker entry (`src/index.ts`) never\n * imports this module, which keeps each command's transitive deps\n * (e.g. `@modelcontextprotocol/sdk` reached via `McpServeCommand`) out\n * of the worker bundle and the worker-env Vite dev optimizer.\n */\n@Module({\n providers: [\n HelpCommand,\n DbSeedCommand,\n DbSeedListCommand,\n RouteListCommand,\n RouteTypesCommand,\n EventListCommand,\n ScheduleListCommand,\n QueueListCommand,\n McpServeCommand,\n McpToolsCommand,\n ApiCommand,\n I18nCheckCommand,\n I18nDuplicatesCommand,\n I18nListCommand,\n I18nNamespacesCommand,\n I18nSearchCommand,\n I18nStatsCommand,\n ],\n})\nexport class BuiltinQuarryModule {}\n","import type { ExceptionHandler } from '../errors'\nimport { LogLevel } from '../logger/contracts/log-level'\nimport { Module } from '../module/module.decorator'\nimport { Stratal } from '../stratal'\nimport type { Constructor } from '../types'\nimport { BuiltinQuarryModule } from './builtin-quarry.module'\n\nexport interface QuarryRunOptions {\n /**\n * Modules to register for the CLI run. Always includes the app's root\n * module (e.g., `AppModule`); additional entries are typically CLI-only\n * command modules from stratal ecosystem packages (e.g.,\n * `InertiaQuarryModule` from `@stratal/inertia/quarry`). Anything listed\n * here stays out of the worker bundle because `src/index.ts` doesn't\n * import it.\n */\n imports: Constructor[]\n /**\n * Provider classes registered only for the CLI run — typically seeders\n * (classes extending `Seeder`) and other CLI-only services. Placed into a\n * synthesized wrapper module's `providers` so they go through the\n * standard DI registration path.\n */\n providers?: Constructor[]\n /** Optional custom exception handler. Same shape as `Stratal({ exceptionHandler })`. */\n exceptionHandler?: Constructor<ExceptionHandler>\n}\n\n/**\n * Builds a `Stratal` instance for the quarry CLI entry (`src/quarry.ts`).\n *\n * Synthesizes a wrapper module from the given `imports` and `providers`,\n * so CLI-only classes (seeders, ecosystem CLI commands) stay out of the\n * worker bundle — `src/index.ts` doesn't reference any of them. Forces\n * CLI-friendly logging defaults (`level: 'error'`, `formatter: 'pretty'`).\n *\n * @example\n * ```ts\n * // src/quarry.ts\n * export default QuarryRunner.run({\n * imports: [AppModule, InertiaQuarryModule],\n * providers: [GeoSeeder, DemoSeeder],\n * })\n * ```\n */\nexport class QuarryRunner {\n static run(options: QuarryRunOptions): Stratal {\n // `BuiltinQuarryModule` carries the framework's built-in CLI commands\n // (help, db:seed, route:list, mcp:serve, etc.). It's auto-included here\n // — and ONLY here — so the static graph that reaches `@modelcontextprotocol/sdk`\n // and friends never touches the worker entry's module graph.\n @Module({\n imports: [BuiltinQuarryModule, ...options.imports],\n providers: options.providers ?? [],\n })\n class QuarryEntryModule {}\n\n return new Stratal({\n module: QuarryEntryModule,\n exceptionHandler: options.exceptionHandler,\n logging: { level: LogLevel.ERROR, formatter: 'pretty' },\n })\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"runner.mjs","names":[],"sources":["../../src/quarry/commands/api.command.ts","../../src/quarry/commands/event-list.command.ts","../../src/quarry/commands/help.command.ts","../../src/quarry/commands/i18n-utils.ts","../../src/quarry/commands/i18n-check.command.ts","../../src/quarry/commands/i18n-duplicates.command.ts","../../src/quarry/commands/i18n-list.command.ts","../../src/quarry/commands/i18n-namespaces.command.ts","../../src/quarry/commands/i18n-search.command.ts","../../src/quarry/commands/i18n-stats.command.ts","../../src/quarry/commands/mcp-serve.command.ts","../../src/quarry/commands/mcp-tools.command.ts","../../src/quarry/commands/queue-failed.command.ts","../../src/quarry/commands/queue-list.command.ts","../../src/quarry/commands/queue-purge.command.ts","../../src/quarry/commands/queue-retry.command.ts","../../src/quarry/commands/route-list.command.ts","../../src/quarry/commands/route-types.command.ts","../../src/quarry/commands/schedule-list.command.ts","../../src/quarry/builtin-quarry.module.ts","../../src/quarry/quarry-runner.ts"],"sourcesContent":["import { inject } from '../../di'\nimport type { Application } from '../../application'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { Command } from '../command'\nimport { bold, cyan, green, red, yellow } from '../colors'\n\nexport class ApiCommand extends Command {\n static command = 'api {route?} {--method= : HTTP method} {--data= : JSON request body} {--header=* : Headers (Key:Value)} {--query=* : Query params (key=value)}'\n static description = 'Call an API route directly'\n static aliases = ['api:call']\n\n constructor(@inject(DI_TOKENS.Application) private app: Application) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const route = this.string('route')\n\n if (!route) {\n return (await this.call('route:list')).exitCode\n }\n\n return this.callRoute(route)\n }\n\n private async callRoute(route: string): Promise<number> {\n const method = (this.string('method') || 'GET').toUpperCase()\n const data = this.string('data')\n const headerArgs = this.array('header')\n const queryArgs = this.array('query')\n\n const headers: Record<string, string> = {}\n if (data) {\n headers['Content-Type'] = 'application/json'\n }\n for (const h of headerArgs) {\n const colonIdx = h.indexOf(':')\n if (colonIdx > 0) {\n headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim()\n }\n }\n\n // Build query string\n let url = route\n if (queryArgs.length > 0) {\n const parts = queryArgs.map((q) => {\n const eqIdx = q.indexOf('=')\n if (eqIdx > 0) {\n return `${encodeURIComponent(q.slice(0, eqIdx))}=${encodeURIComponent(q.slice(eqIdx + 1))}`\n }\n return encodeURIComponent(q)\n })\n url += `?${parts.join('&')}`\n }\n\n const request = new Request(`http://localhost${url}`, {\n method,\n headers,\n body: data || undefined,\n })\n\n const hono = await this.app.ensureHono()\n const response = await hono.fetch(request, this.app.env)\n const body = await response.text()\n\n // Color-coded status\n const statusText = `${response.status} ${response.statusText}`\n let coloredStatus: string\n if (response.status >= 200 && response.status < 300) {\n coloredStatus = green(bold(statusText))\n } else if (response.status >= 300 && response.status < 400) {\n coloredStatus = yellow(bold(statusText))\n } else {\n coloredStatus = red(bold(statusText))\n }\n\n this.line(`${cyan(method)} ${route} ${coloredStatus}`)\n this.newLine()\n\n // Response headers\n const headerLines: string[] = []\n response.headers.forEach((value, key) => {\n headerLines.push(` ${key}: ${value}`)\n })\n if (headerLines.length > 0) {\n this.line(bold('Headers:'))\n for (const hl of headerLines) {\n this.line(hl)\n }\n this.newLine()\n }\n\n // Body\n if (body) {\n this.line(bold('Body:'))\n try {\n this.line(JSON.stringify(JSON.parse(body), null, 2))\n } catch {\n this.line(body)\n }\n }\n\n return response.status >= 400 ? 1 : 0\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { getListenerHandlers } from '../../events'\nimport type { ModuleRegistry } from '../../module/module-registry'\nimport { Command } from '../command'\n\nexport class EventListCommand extends Command {\n static command = 'event:list'\n static description = 'List all registered event listeners'\n\n constructor(@inject(DI_TOKENS.ModuleRegistry) private modules: ModuleRegistry) {\n super()\n }\n\n handle(): number | undefined {\n const listeners = this.modules.getAllListeners()\n\n if (listeners.length === 0) {\n this.info('No event listeners found')\n return 0\n }\n\n const rows: string[][] = []\n\n for (const ListenerClass of listeners) {\n const handlers = getListenerHandlers(ListenerClass)\n for (const { methodName, event, options } of handlers) {\n rows.push([\n event,\n ListenerClass.name,\n methodName,\n String(options?.priority ?? 0),\n options?.blocking ? 'Yes' : 'No',\n ])\n }\n }\n\n if (rows.length === 0) {\n this.info('No event handlers found')\n return 0\n }\n\n this.table(['Event', 'Listener', 'Method', 'Priority', 'Blocking'], rows)\n\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { Command } from '../command'\nimport { CommandNotFoundError } from '../errors/command-not-found.error'\nimport type { QuarryRegistry } from '../quarry-registry'\n\nexport class HelpCommand extends Command {\n static command = 'help {command?}'\n static description = 'Show help for a command or list all commands'\n static aliases = ['list']\n\n constructor(@inject(DI_TOKENS.Quarry) private quarryRegistry: QuarryRegistry) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const commandName = this.string('command')\n\n if (!commandName) {\n const listing = await this.quarryRegistry.listUsage()\n this.line(listing)\n return 0\n }\n\n try {\n const usage = await this.quarryRegistry.usage(commandName)\n this.line(usage)\n return 0\n } catch (error) {\n if (error instanceof CommandNotFoundError) {\n this.fail(`Unknown command: ${commandName}`)\n return 1\n }\n throw error\n }\n }\n}\n","export function computeKeyDiff(\n baseKeys: Set<string>,\n targetKeys: Set<string>,\n): { missing: string[]; extra: string[] } {\n const missing: string[] = []\n const extra: string[] = []\n\n for (const key of baseKeys) {\n if (!targetKeys.has(key)) missing.push(key)\n }\n for (const key of targetKeys) {\n if (!baseKeys.has(key)) extra.push(key)\n }\n\n return { missing: missing.sort(), extra: extra.sort() }\n}\n\nexport function extractNamespace(key: string, depth: number): string {\n return key.split('.').slice(0, depth).join('.')\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\nimport { computeKeyDiff } from './i18n-utils'\n\nexport class I18nCheckCommand extends Command {\n static command = 'i18n:check {--locale= : Check a specific locale only} {--prefix= : Filter by namespace prefix}'\n static description = 'Check i18n translations for missing or extra keys'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const localeFilter = this.string('locale')\n const prefix = this.string('prefix')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const enKeys = new Set(Object.keys(this.loader.getFilteredMessages('en', filterOptions)))\n\n if (enKeys.size === 0) {\n this.info('No message keys found')\n return 0\n }\n\n const locales = this.loader.getAvailableLocales().filter((l) => l !== 'en')\n const targets = localeFilter ? locales.filter((l) => l === localeFilter) : locales\n\n if (targets.length === 0) {\n this.info(localeFilter ? `Locale \"${localeFilter}\" not found` : 'No non-en locales configured')\n return 0\n }\n\n let totalIssues = 0\n const summaryRows: string[][] = []\n\n for (const locale of targets) {\n const localeKeys = new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions)))\n const { missing, extra } = computeKeyDiff(enKeys, localeKeys)\n\n this.newLine()\n this.info(`Locale: ${locale}`)\n\n if (missing.length > 0) {\n this.warn(` Missing (${missing.length}):`)\n for (const key of missing) {\n this.line(` ${key}`)\n }\n } else {\n this.line(' Missing (0)')\n }\n\n if (extra.length > 0) {\n this.warn(` Extra (${extra.length}):`)\n for (const key of extra) {\n this.line(` ${key}`)\n }\n } else {\n this.line(' Extra (0)')\n }\n\n totalIssues += missing.length + extra.length\n summaryRows.push([locale, String(enKeys.size), String(missing.length), String(extra.length)])\n }\n\n this.newLine()\n this.table(['Locale', 'Total', 'Missing', 'Extra'], summaryRows)\n\n if (totalIssues > 0) {\n this.newLine()\n this.fail(`${totalIssues} issue(s) found`)\n return undefined\n }\n\n this.newLine()\n this.success('All translations are complete')\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nDuplicatesCommand extends Command {\n static command = 'i18n:duplicates {--locale= : Locale to check (default: en)} {--prefix= : Filter by namespace prefix}'\n static description = 'Find i18n keys with duplicate translation values'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const locale = this.string('locale') || 'en'\n const prefix = this.string('prefix')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const messages = this.loader.getFilteredMessages(locale, filterOptions)\n const valueToKeys = new Map<string, string[]>()\n\n for (const [key, value] of Object.entries(messages)) {\n const existing = valueToKeys.get(value)\n if (existing) {\n existing.push(key)\n } else {\n valueToKeys.set(value, [key])\n }\n }\n\n const duplicates: [string, string][] = []\n for (const [value, keys] of valueToKeys) {\n if (keys.length > 1) {\n duplicates.push([value, keys.sort().join(', ')])\n }\n }\n\n if (duplicates.length === 0) {\n this.info('No duplicate values found')\n return 0\n }\n\n duplicates.sort((a, b) => a[0].localeCompare(b[0]))\n this.table(['Value', 'Keys'], duplicates)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nListCommand extends Command {\n static command = 'i18n:list {--locale= : Show keys for a specific locale} {--prefix= : Filter by namespace prefix} {--values : Show translated values}'\n static description = 'List all i18n message keys'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const localeFilter = this.string('locale')\n const prefix = this.string('prefix')\n const showValues = this.boolean('values')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const enMessages = this.loader.getFilteredMessages('en', filterOptions)\n const enKeys = Object.keys(enMessages).sort()\n\n if (enKeys.length === 0) {\n this.info('No message keys found')\n return 0\n }\n\n if (localeFilter && showValues) {\n const localeMessages = this.loader.getFilteredMessages(localeFilter, filterOptions)\n const rows = enKeys.map((key) => [key, localeMessages[key] ?? '-'])\n this.table(['Key', 'Value'], rows)\n return 0\n }\n\n const locales = localeFilter\n ? [localeFilter]\n : this.loader.getAvailableLocales()\n\n const localeMessages = new Map<string, Set<string>>()\n for (const locale of locales) {\n localeMessages.set(locale, new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions))))\n }\n\n const headers = ['Key', ...locales]\n const rows = enKeys.map((key) => {\n const coverage = locales.map((locale) => (localeMessages.get(locale)!.has(key) ? 'Y' : 'N'))\n return [key, ...coverage]\n })\n\n this.table(headers, rows)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\nimport { extractNamespace } from './i18n-utils'\n\nexport class I18nNamespacesCommand extends Command {\n static command = 'i18n:namespaces {--depth= : Namespace depth (default: 1)} {--locale= : Show counts for a specific locale}'\n static description = 'List i18n message namespaces with key counts'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const depth = this.number('depth') || 1\n const localeFilter = this.string('locale')\n\n const locales = localeFilter\n ? [localeFilter]\n : this.loader.getAvailableLocales()\n\n const namespaceCounts = new Map<string, Map<string, number>>()\n\n for (const locale of locales) {\n const messages = this.loader.getFilteredMessages(locale)\n\n for (const key of Object.keys(messages)) {\n const ns = extractNamespace(key, depth)\n\n if (!namespaceCounts.has(ns)) {\n namespaceCounts.set(ns, new Map())\n }\n const counts = namespaceCounts.get(ns)!\n counts.set(locale, (counts.get(locale) ?? 0) + 1)\n }\n }\n\n if (namespaceCounts.size === 0) {\n this.info('No namespaces found')\n return 0\n }\n\n const sortedNamespaces = [...namespaceCounts.keys()].sort()\n const headers = ['Namespace', ...locales]\n const rows = sortedNamespaces.map((ns) => {\n const counts = namespaceCounts.get(ns)!\n return [ns, ...locales.map((locale) => String(counts.get(locale) ?? 0))]\n })\n\n this.table(headers, rows)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nSearchCommand extends Command {\n static command = 'i18n:search {query : Search term (substring match)} {--locale= : Locale to search in (default: en)} {--keys-only : Only match key names, not values}'\n static description = 'Search for i18n message keys or values'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const query = this.string('query').toLowerCase()\n const locale = this.string('locale') || 'en'\n const keysOnly = this.boolean('keys-only')\n\n const messages = this.loader.getFilteredMessages(locale)\n const matches: [string, string][] = []\n\n for (const [key, value] of Object.entries(messages)) {\n const keyMatch = key.toLowerCase().includes(query)\n const valueMatch = !keysOnly && value.toLowerCase().includes(query)\n\n if (keyMatch || valueMatch) {\n matches.push([key, value])\n }\n }\n\n if (matches.length === 0) {\n this.info(`No keys matching \"${this.string('query')}\" found`)\n return 0\n }\n\n matches.sort((a, b) => a[0].localeCompare(b[0]))\n this.table(['Key', 'Value'], matches)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { MessageLoaderService } from '../../i18n/services/message-loader.service'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport { Command } from '../command'\n\nexport class I18nStatsCommand extends Command {\n static command = 'i18n:stats {--prefix= : Filter by namespace prefix}'\n static description = 'Show i18n translation coverage statistics'\n\n constructor(@inject(I18N_TOKENS.MessageLoader) private loader: MessageLoaderService) {\n super()\n }\n\n handle(): number | undefined {\n const prefix = this.string('prefix')\n const filterOptions = prefix ? { only: [prefix] as never[] } : undefined\n\n const enKeys = new Set(Object.keys(this.loader.getFilteredMessages('en', filterOptions)))\n\n if (enKeys.size === 0) {\n this.info('No message keys found')\n return 0\n }\n\n const locales = this.loader.getAvailableLocales()\n const rows: string[][] = []\n\n for (const locale of locales) {\n const localeKeys = new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions)))\n const isBase = locale === 'en'\n\n let translated = 0\n for (const key of enKeys) {\n if (localeKeys.has(key)) translated++\n }\n\n const missing = enKeys.size - translated\n let extra = 0\n for (const key of localeKeys) {\n if (!enKeys.has(key)) extra++\n }\n\n const coverage = ((translated / enKeys.size) * 100).toFixed(1) + '%'\n\n rows.push([\n locale,\n String(enKeys.size),\n String(translated),\n String(missing),\n isBase ? '-' : String(extra),\n coverage,\n ])\n }\n\n this.table(['Locale', 'Keys', 'Translated', 'Missing', 'Extra', 'Coverage'], rows)\n return 0\n }\n}\n","import { inject } from '../../di'\nimport { z } from 'zod'\nimport type { Application } from '../../application'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { OPENAPI_TOKENS } from '../../openapi/openapi.tokens'\nimport type { Dispatcher } from '../../openapi/services/openapi-tools.service'\nimport { OpenApiToolsService } from '../../openapi/services/openapi-tools.service'\nimport type { OpenAPIService } from '../../openapi/services/openapi.service'\nimport type { IOpenAPIConfigStore } from '../../openapi/types'\nimport { Command } from '../command'\n\nexport class McpServeCommand extends Command {\n static command = 'mcp:serve {--url= : Base URL for external dispatch} {--header=* : Headers (Key:Value)} {--tag=* : Only expose routes with these OpenAPI tags} {--path= : Only expose routes matching this path prefix}'\n static description = 'Start an MCP stdio server exposing API routes as tools'\n\n constructor(\n @inject(DI_TOKENS.Application) private app: Application,\n @inject(OPENAPI_TOKENS.OpenAPIService) private openAPIService: OpenAPIService,\n ) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const { McpServer } = await import('@modelcontextprotocol/sdk/server/mcp.js')\n const { StdioServerTransport } = await import('@modelcontextprotocol/sdk/server/stdio.js')\n\n const baseUrl = this.string('url')\n const headerArgs = this.array('header')\n const tags = this.array('tag')\n const pathPrefix = this.string('path')\n\n const headers: Record<string, string> = {}\n for (const h of headerArgs) {\n const colonIdx = h.indexOf(':')\n if (colonIdx > 0) {\n headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim()\n }\n }\n\n const hono = await this.app.ensureHono()\n const spec = this.openAPIService.getSpec(hono, this.app.container)\n\n const dispatcher: Dispatcher = baseUrl\n ? async (method, url, opts) => {\n const fullUrl = `${baseUrl}${url}`\n try {\n return await fetch(fullUrl, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n ...opts?.headers,\n },\n body: opts?.body !== undefined ? JSON.stringify(opts.body) : undefined,\n })\n } catch (error) {\n throw new Error(`MCP dispatch failed: ${method} ${fullUrl} — ${error instanceof Error ? error.message : String(error)}`, { cause: error })\n }\n }\n : async (method, url, opts) => {\n const request = new Request(`http://localhost${url}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n ...opts?.headers,\n },\n body: opts?.body !== undefined ? JSON.stringify(opts.body) : undefined,\n })\n try {\n return await hono.fetch(request, this.app.env)\n } catch (error) {\n throw new Error(`MCP dispatch failed: ${method} ${url} — ${error instanceof Error ? error.message : String(error)}`, { cause: error })\n }\n }\n\n const service = new OpenApiToolsService(spec, { dispatcher })\n const filter = {\n tags: tags.length > 0 ? tags : undefined,\n pathPrefix: pathPrefix || undefined,\n }\n const tools = service.getTools(filter)\n\n // CLI runs outside a request scope; the store carries the static base config\n // (there are no per-request overrides here).\n const config = this.app.container\n .resolve<IOpenAPIConfigStore>(OPENAPI_TOKENS.ConfigStore)\n .getBaseConfig()\n\n const server = new McpServer({\n name: config.info.title,\n version: config.info.version,\n })\n\n // Register each tool\n for (const tool of tools) {\n const inputSchema = z.fromJSONSchema(tool.inputSchema)\n server.registerTool(tool.name, { description: tool.description, inputSchema }, async (args) => {\n const result = await service.executeTool(tool.name, args as Record<string, unknown>)\n return {\n content: [{ type: 'text' as const, text: `Status: ${result.status}\\n\\n${result.body}` }],\n }\n })\n }\n\n // Expose OpenAPI spec as a resource\n server.registerResource(\n 'openapi-spec',\n 'openapi://spec',\n { description: 'Full OpenAPI specification', mimeType: 'application/json' },\n () => ({\n contents: [{\n uri: 'openapi://spec',\n mimeType: 'application/json',\n text: JSON.stringify(spec, null, 2),\n }],\n }),\n )\n\n const transport = new StdioServerTransport()\n const closed = new Promise<void>((resolve) => { transport.onclose = resolve })\n await server.connect(transport)\n\n // Write info to stderr (stdout is reserved for MCP JSON-RPC)\n process.stderr.write(`MCP server started with ${tools.length} tool(s)\\n`)\n\n // Keep process alive until client disconnects\n await closed\n\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { Application } from '../../application'\nimport { DI_TOKENS } from '../../di/tokens'\nimport { OPENAPI_TOKENS } from '../../openapi/openapi.tokens'\nimport type { OpenAPIService } from '../../openapi/services/openapi.service'\nimport { OpenApiToolsService } from '../../openapi/services/openapi-tools.service'\nimport { Command } from '../command'\n\nexport class McpToolsCommand extends Command {\n static command = 'mcp:tools {--tag=* : Filter by OpenAPI tags} {--path= : Filter by path prefix}'\n static description = 'List API routes that would be exposed as MCP tools'\n\n constructor(\n @inject(DI_TOKENS.Application) private app: Application,\n @inject(OPENAPI_TOKENS.OpenAPIService) private openAPIService: OpenAPIService,\n ) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const tags = this.array('tag')\n const pathPrefix = this.string('path')\n\n const hono = await this.app.ensureHono()\n const spec = this.openAPIService.getSpec(hono, this.app.container)\n\n const service = new OpenApiToolsService(spec)\n const filter = {\n tags: tags.length > 0 ? tags : undefined,\n pathPrefix: pathPrefix || undefined,\n }\n const tools = service.getTools(filter)\n\n if (tools.length === 0) {\n this.info('No tools found')\n return 0\n }\n\n this.table(\n ['Name', 'Method', 'Path', 'Description'],\n tools.map((t) => [t.name, t.method, t.path, t.description]),\n )\n\n return 0\n }\n}\n","import { inject } from '../../di'\nimport type { QueueStore } from '../../queue/queue-store'\nimport { QUEUE_TOKENS } from '../../queue/queue.tokens'\nimport { Command } from '../command'\n\nexport class QueueFailedCommand extends Command {\n static command = 'queue:failed {--queue= : Filter by queue name} {--limit= : Max results (default 50)}'\n static description = 'List failed queue jobs'\n\n constructor(@inject(QUEUE_TOKENS.QueueStore) private store: QueueStore) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const queueFilter = this.string('queue')\n const limit = this.number('limit') || 50\n\n // Without a filter, one page of `limit` keys is the result. With a filter,\n // keep paginating until we've collected `limit` MATCHING jobs (or run out),\n // so `--limit` counts matching jobs rather than scanned keys.\n const filtered: { id: string; metadata: { queue: string; type: string; consumer: string; attempts: number; failedAt: string } }[] = []\n let cursor: string | undefined\n let more = false\n\n do {\n const result = await this.store.listFailedJobs({ cursor, limit })\n cursor = result.cursor\n for (const key of result.keys) {\n if (queueFilter && key.metadata.queue !== queueFilter) continue\n if (filtered.length >= limit) {\n more = true\n break\n }\n filtered.push(key)\n }\n } while (cursor && filtered.length < limit)\n\n if (cursor) more = true\n\n if (filtered.length === 0) {\n this.info('No failed jobs found')\n return 0\n }\n\n this.table(\n ['ID', 'Queue', 'Type', 'Consumer', 'Attempts', 'Failed At'],\n filtered.map((k) => [\n k.id,\n k.metadata.queue,\n k.metadata.type,\n k.metadata.consumer,\n String(k.metadata.attempts),\n k.metadata.failedAt,\n ]),\n )\n\n if (more) {\n this.comment(`Showing first ${limit} results. More jobs available.`)\n }\n\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport type { ConsumerRegistry } from '../../queue/consumer-registry'\nimport { Command } from '../command'\n\nexport class QueueListCommand extends Command {\n static command = 'queue:list'\n static description = 'List all registered queue consumers'\n\n constructor(@inject(DI_TOKENS.ConsumerRegistry) private consumers: ConsumerRegistry) {\n super()\n }\n\n handle(): number | undefined {\n const registrations = this.consumers.getRegistrations()\n\n if (registrations.length === 0) {\n this.info('No queue consumers found')\n return 0\n }\n\n this.table(\n ['Consumer', 'Message Types'],\n registrations.map(r => [r.consumerClass.name, r.messageTypes.join(', ')]),\n )\n\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport type { QueueStore } from '../../queue/queue-store'\nimport { QUEUE_TOKENS } from '../../queue/queue.tokens'\nimport { Command } from '../command'\n\nexport class QueuePurgeCommand extends Command {\n static command = 'queue:purge {id? : Message ID to purge} {--all : Purge all failed jobs} {--queue= : Filter by queue name}'\n static description = 'Delete failed queue jobs without retrying'\n\n constructor(@inject(QUEUE_TOKENS.QueueStore) private store: QueueStore) {\n super()\n }\n\n async handle(): Promise<number | undefined> {\n const id = this.string('id')\n const all = this.boolean('all')\n const queueFilter = this.string('queue')\n\n if (!id && !all) {\n this.fail('Provide a message ID or use --all')\n return 1\n }\n\n if (id) {\n await this.store.removeFailedJob(id)\n this.success(`Purged job ${id}`)\n return undefined\n }\n\n if (queueFilter) {\n // Collect all matching keys first, then delete: removing keys mid-listing\n // shifts the cursor and would skip jobs in a single pass.\n const ids: string[] = []\n let cursor: string | undefined\n\n do {\n const result = await this.store.listFailedJobs({ cursor, limit: 100 })\n cursor = result.cursor\n for (const key of result.keys) {\n if (key.metadata.queue !== queueFilter) continue\n ids.push(key.id)\n }\n } while (cursor)\n\n for (const id of ids) {\n await this.store.removeFailedJob(id)\n }\n\n this.success(`Purged ${ids.length} job(s) from queue \"${queueFilter}\"`)\n } else {\n await this.store.purgeFailedJobs()\n this.success('Purged all failed jobs')\n }\n\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport type { IQueueProvider } from '../../queue/providers'\nimport type { QueueStore } from '../../queue/queue-store'\nimport { QUEUE_TOKENS } from '../../queue/queue.tokens'\nimport type { QueueProviderFactory } from '../../queue/services'\nimport { Command } from '../command'\n\nexport class QueueRetryCommand extends Command {\n static command = 'queue:retry {id? : Message ID to retry} {--all : Retry all failed jobs} {--queue= : Filter by queue name}'\n static description = 'Retry failed queue jobs'\n\n private provider: IQueueProvider\n\n constructor(\n @inject(QUEUE_TOKENS.QueueStore) private store: QueueStore,\n @inject(QUEUE_TOKENS.QueueProviderFactory) factory: QueueProviderFactory,\n ) {\n super()\n this.provider = factory.create()\n }\n\n async handle(): Promise<number | undefined> {\n const id = this.string('id')\n const all = this.boolean('all')\n const queueFilter = this.string('queue')\n\n if (!id && !all) {\n this.fail('Provide a message ID or use --all')\n return 1\n }\n\n if (id) {\n return this.retryOne(id)\n }\n\n return this.retryAll(queueFilter)\n }\n\n private async retryOne(id: string): Promise<number | undefined> {\n const job = await this.store.getFailedJob(id)\n\n if (!job) {\n this.fail(`Failed job \"${id}\" not found`)\n return 1\n }\n\n await this.provider.send(job.binding, {\n ...job.message,\n id: crypto.randomUUID(),\n })\n await this.store.removeFailedJob(id)\n this.success(`Retried job ${id}`)\n\n return undefined\n }\n\n private async retryAll(queueFilter?: string): Promise<number | undefined> {\n // Collect every matching key across the full listing BEFORE mutating\n // anything: deleting keys while paginating with a cursor shifts cursor\n // positions and would cause a single pass to skip jobs.\n const ids: string[] = []\n let cursor: string | undefined\n\n do {\n const result = await this.store.listFailedJobs({ cursor, limit: 100 })\n cursor = result.cursor\n for (const key of result.keys) {\n if (queueFilter && key.metadata.queue !== queueFilter) continue\n ids.push(key.id)\n }\n } while (cursor)\n\n let count = 0\n for (const id of ids) {\n const job = await this.store.getFailedJob(id)\n if (!job) continue\n\n await this.provider.send(job.binding, {\n ...job.message,\n id: crypto.randomUUID(),\n })\n await this.store.removeFailedJob(id)\n count++\n }\n\n this.success(`Retried ${count} job(s)`)\n return undefined\n }\n}\n","import { inject } from '../../di'\nimport type { RouteRegistry, RegisteredRoute } from '../../router/route-registry'\nimport { ROUTER_TOKENS } from '../../router/router.tokens'\nimport { Command } from '../command'\n\n/**\n * List all registered routes from RouteRegistry.\n *\n * By default, hidden routes (hideFromDocs) are excluded.\n * Use `--hidden` to include them.\n *\n * @example\n * ```bash\n * quarry route:list\n * quarry route:list --method=GET\n * quarry route:list --path=/users\n * quarry route:list --name=users\n * quarry route:list --hidden\n * ```\n */\nexport class RouteListCommand extends Command {\n static command = 'route:list {--method= : Filter by HTTP method} {--path= : Filter by path substring} {--name= : Filter by route name} {--hidden : Include hidden routes}'\n static description = 'List all registered routes'\n\n constructor(@inject(ROUTER_TOKENS.RouteRegistry) private registry: RouteRegistry) {\n super()\n }\n\n handle(): number | undefined {\n const methodFilter = this.string('method').toUpperCase()\n const pathFilter = this.string('path')\n const nameFilter = this.string('name')\n const showHidden = this.boolean('hidden')\n\n let routes = this.registry.all()\n\n // Filter hidden routes (default: exclude)\n if (!showHidden) {\n routes = routes.filter(r => !r.hidden)\n }\n\n if (methodFilter) {\n routes = routes.filter(r => r.method.toUpperCase() === methodFilter)\n }\n\n if (pathFilter) {\n routes = routes.filter(r => r.path.includes(pathFilter))\n }\n\n if (nameFilter) {\n routes = routes.filter(r => r.name?.includes(nameFilter))\n }\n\n if (routes.length === 0) {\n this.info('No routes found')\n return 0\n }\n\n this.table(\n ['Method', 'Path', 'Name', 'Handler', 'Domain'],\n routes.map(r => this.formatRow(r)),\n )\n\n return undefined\n }\n\n private formatRow(route: RegisteredRoute): string[] {\n return [\n route.method.toUpperCase(),\n route.path,\n route.name ?? '-',\n `${route.controller}.${route.action}`,\n route.domain ?? '-',\n ]\n }\n}\n","import { writeFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport { inject } from '../../di'\nimport type { RouteRegistry, RegisteredRoute } from '../../router/route-registry'\nimport { ROUTER_TOKENS } from '../../router/router.tokens'\nimport type { LocalePathService } from '../../router/services/locale-path.service'\nimport { Command } from '../command'\n\n/**\n * Generate TypeScript types for named routes.\n *\n * Outputs a `stratal.d.ts` file with `StratalRouteMap` augmentation\n * that provides autocomplete and type-safe params for `route()` and `ctx.route()`.\n *\n * @example\n * ```bash\n * quarry route:types # → src/stratal.d.ts\n * quarry route:types --output=types/routes.d.ts\n * ```\n */\nexport class RouteTypesCommand extends Command {\n static command = 'route:types {--output=src/stratal.d.ts : Output file path}'\n static description = 'Generate TypeScript types for named routes'\n\n constructor(\n @inject(ROUTER_TOKENS.RouteRegistry) private registry: RouteRegistry,\n @inject(ROUTER_TOKENS.LocalePathService) private localePathService: LocalePathService,\n ) {\n super()\n }\n\n handle(): number | undefined {\n const outputPath = resolve(this.string('output') || 'src/stratal.d.ts')\n const namedRoutes = this.registry.named()\n\n if (namedRoutes.length === 0) {\n this.warn('No named routes found. Add name to your @Route() or @Get()/@Post() decorators.')\n return 0\n }\n\n const content = this.generateDeclaration(namedRoutes)\n writeFileSync(outputPath, content, 'utf-8')\n this.info(`Generated route types for ${namedRoutes.length} named routes → ${outputPath}`)\n\n return undefined\n }\n\n /**\n * Generate the StratalRouteMap declaration content.\n */\n private generateDeclaration(routes: RegisteredRoute[]): string {\n const localeConfig = this.localePathService.enabled ? this.localePathService.localePathConfig : null\n const localeType = localeConfig\n ? localeConfig.allLocales.map(l => `'${l}'`).join(' | ')\n : null\n const localeOptional = localeConfig ? this.localePathService.prefixDefaultLocale !== true : false\n\n const entries = routes\n .filter((r): r is RegisteredRoute & { name: string } => r.name !== undefined)\n .sort((a, b) => a.name.localeCompare(b.name))\n .map(route => {\n const paramEntries = [\n ...route.paramNames.map(p => `${p}: string`),\n ...route.domainParamNames.map(p => `${p}: string`),\n ]\n\n if (localeType && route.localePaths?.length) {\n const optionalMarker = localeOptional ? '?' : ''\n paramEntries.push(`locale${optionalMarker}: StratalLocale`)\n }\n\n // Extra keys become query-string params at runtime, so allow any\n // string key. Typed path/domain params above still take precedence.\n const indexSignature = localeType && route.localePaths?.length\n ? '[key: string]: string | StratalLocale | undefined'\n : '[key: string]: string | undefined'\n paramEntries.push(indexSignature)\n\n const paramsType = `{ ${paramEntries.join('; ')} }`\n return ` '${route.name}': { params: ${paramsType} }`\n })\n .join('\\n')\n\n const lines = [\n '// Auto-generated by `quarry route:types` — do not edit manually',\n \"declare module 'stratal/router' {\",\n ]\n\n if (localeType) {\n lines.push(` type StratalLocale = ${localeType}`)\n lines.push('')\n }\n\n lines.push(\n ' interface StratalRouteMap {',\n entries,\n ' }',\n '}',\n )\n\n return [\n ...lines,\n '',\n 'export {}',\n '',\n ].join('\\n')\n }\n}\n","import { inject } from '../../di'\nimport { DI_TOKENS } from '../../di/tokens'\nimport type { CronManager } from '../../cron/cron-manager'\nimport type { LazyModuleLoader } from '../../module/lazy-module-loader'\nimport { Command } from '../command'\n\nexport class ScheduleListCommand extends Command {\n static command = 'schedule:list'\n static description = 'List all registered cron jobs'\n\n constructor(@inject(DI_TOKENS.LazyModuleLoader) private loader: LazyModuleLoader) {\n super()\n }\n\n async handle(): Promise<number | void> {\n // Lazy-load the cron subsystem. For apps with jobs the manager singleton is\n // already populated (bootstrap ensureCron); for apps without jobs this is a\n // fresh empty manager → \"No cron jobs found\" instead of a resolve error.\n const ref = await this.loader.load(() => import('../../cron/cron.module').then(m => m.CronModule))\n const cron = ref.get<CronManager>(DI_TOKENS.Cron)\n\n const schedules = cron.getAllSchedules()\n\n if (schedules.length === 0) {\n this.info('No cron jobs found')\n return 0\n }\n\n const rows: string[][] = []\n\n for (const schedule of schedules) {\n const jobs = cron.getJobsForSchedule(schedule)\n for (const { jobClass } of jobs) {\n rows.push([schedule, jobClass.name])\n }\n }\n\n this.table(['Schedule', 'Job'], rows)\n }\n}\n","import { Module } from '../module/module.decorator'\nimport { DbSeedCommand, DbSeedListCommand } from '../seeder'\nimport { ApiCommand } from './commands/api.command'\nimport { EventListCommand } from './commands/event-list.command'\nimport { HelpCommand } from './commands/help.command'\nimport { I18nCheckCommand } from './commands/i18n-check.command'\nimport { I18nDuplicatesCommand } from './commands/i18n-duplicates.command'\nimport { I18nListCommand } from './commands/i18n-list.command'\nimport { I18nNamespacesCommand } from './commands/i18n-namespaces.command'\nimport { I18nSearchCommand } from './commands/i18n-search.command'\nimport { I18nStatsCommand } from './commands/i18n-stats.command'\nimport { McpServeCommand } from './commands/mcp-serve.command'\nimport { McpToolsCommand } from './commands/mcp-tools.command'\nimport { QueueFailedCommand } from './commands/queue-failed.command'\nimport { QueueListCommand } from './commands/queue-list.command'\nimport { QueuePurgeCommand } from './commands/queue-purge.command'\nimport { QueueRetryCommand } from './commands/queue-retry.command'\nimport { RouteListCommand } from './commands/route-list.command'\nimport { RouteTypesCommand } from './commands/route-types.command'\nimport { ScheduleListCommand } from './commands/schedule-list.command'\n\n/**\n * Built-in framework CLI commands.\n *\n * Registered automatically by `QuarryRunner` so they're available from\n * `src/quarry.ts` (CLI side). The worker entry (`src/index.ts`) never\n * imports this module, which keeps each command's transitive deps\n * (e.g. `@modelcontextprotocol/sdk` reached via `McpServeCommand`) out\n * of the worker bundle and the worker-env Vite dev optimizer.\n */\n@Module({\n providers: [\n HelpCommand,\n DbSeedCommand,\n DbSeedListCommand,\n RouteListCommand,\n RouteTypesCommand,\n EventListCommand,\n ScheduleListCommand,\n QueueListCommand,\n QueueFailedCommand,\n QueueRetryCommand,\n QueuePurgeCommand,\n McpServeCommand,\n McpToolsCommand,\n ApiCommand,\n I18nCheckCommand,\n I18nDuplicatesCommand,\n I18nListCommand,\n I18nNamespacesCommand,\n I18nSearchCommand,\n I18nStatsCommand,\n ],\n})\nexport class BuiltinQuarryModule {}\n","import type { ExceptionHandler } from '../errors'\nimport { LogLevel } from '../logger/contracts/log-level'\nimport { Module } from '../module/module.decorator'\nimport { Stratal } from '../stratal'\nimport type { Constructor } from '../types'\nimport { BuiltinQuarryModule } from './builtin-quarry.module'\n\nexport interface QuarryRunOptions {\n /**\n * Modules to register for the CLI run. Always includes the app's root\n * module (e.g., `AppModule`); additional entries are typically CLI-only\n * command modules from stratal ecosystem packages (e.g.,\n * `InertiaQuarryModule` from `@stratal/inertia/quarry`). Anything listed\n * here stays out of the worker bundle because `src/index.ts` doesn't\n * import it.\n */\n imports: Constructor[]\n /**\n * Provider classes registered only for the CLI run — typically seeders\n * (classes extending `Seeder`) and other CLI-only services. Placed into a\n * synthesized wrapper module's `providers` so they go through the\n * standard DI registration path.\n */\n providers?: Constructor[]\n /** Optional custom exception handler. Same shape as `Stratal({ exceptionHandler })`. */\n exceptionHandler?: Constructor<ExceptionHandler>\n}\n\n/**\n * Builds a `Stratal` instance for the quarry CLI entry (`src/quarry.ts`).\n *\n * Synthesizes a wrapper module from the given `imports` and `providers`,\n * so CLI-only classes (seeders, ecosystem CLI commands) stay out of the\n * worker bundle — `src/index.ts` doesn't reference any of them. Forces\n * CLI-friendly logging defaults (`level: 'error'`, `formatter: 'pretty'`).\n *\n * @example\n * ```ts\n * // src/quarry.ts\n * export default QuarryRunner.run({\n * imports: [AppModule, InertiaQuarryModule],\n * providers: [GeoSeeder, DemoSeeder],\n * })\n * ```\n */\nexport class QuarryRunner {\n static run(options: QuarryRunOptions): Stratal {\n // `BuiltinQuarryModule` carries the framework's built-in CLI commands\n // (help, db:seed, route:list, mcp:serve, etc.). It's auto-included here\n // — and ONLY here — so the static graph that reaches `@modelcontextprotocol/sdk`\n // and friends never touches the worker entry's module graph.\n @Module({\n imports: [BuiltinQuarryModule, ...options.imports],\n providers: options.providers ?? [],\n })\n class QuarryEntryModule {}\n\n return new Stratal({\n module: QuarryEntryModule,\n exceptionHandler: options.exceptionHandler,\n logging: { level: LogLevel.ERROR, formatter: 'pretty' },\n })\n }\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { Y as Container, _n as CommandResult, hn as CommandInput, xn as Quarry } from "./index-DEncMcC6.mjs";
2
- import { t as Constructor } from "./types-BaeHi67f.mjs";
3
- import { t as Command } from "./command-wXfvHbBZ.mjs";
1
+ import { En as Quarry, Sn as CommandResult, Y as Container, bn as CommandInput } from "./index-B_JoEl3V.mjs";
2
+ import { t as Constructor } from "./types-CmV_9xBD.mjs";
3
+ import { t as Command } from "./command-CPhFHjG3.mjs";
4
4
 
5
5
  //#region src/quarry/quarry-registry.d.ts
6
6
  /**
@@ -66,4 +66,4 @@ declare class QuarryRegistry implements Quarry {
66
66
  }
67
67
  //#endregion
68
68
  export { QuarryRegistry as t };
69
- //# sourceMappingURL=quarry-registry-D4hIGScf.d.mts.map
69
+ //# sourceMappingURL=quarry-registry-CXg0RFXq.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quarry-registry-CXg0RFXq.d.mts","names":[],"sources":["../src/quarry/quarry-registry.ts"],"mappings":";;;;;;AAwBA;;;;;;;;cACa,cAAA,YAA0B,MAAA;EAAA,iBAKqB,SAAA;EAAA,QAJlD,QAAA;EAAA,QACA,UAAA;EAAA,QACA,OAAA;cAEkD,SAAA,EAAW,SAAA;EAyJlC;;;;EAnJ7B,IAAA,CAAK,IAAA,UAAc,KAAA,GAAQ,YAAA,GAAe,OAAA,CAAQ,aAAA;EAXnB;;;EA8ErC,GAAA,CAAI,IAAA;EA3EI;;;EAmFR,GAAA,CAAI,IAAA,WAAe,WAAA,CAAY,OAAA;EA3EzB;;;EAmFN,GAAA,IAAO,GAAA,SAAY,WAAA,CAAY,OAAA;EAnFiB;;;EA0FhD,IAAA;IAAU,IAAA;IAAc,WAAA;IAAsB,OAAA;EAAA;EAP9C;;;EAiCM,SAAA,CAAU,OAAA;IAAY,UAAA;IAAqB,WAAA;IAAsB,aAAA;EAAA,IAA2B,OAAA;EAA5F;;;EAWA,KAAA,CAAM,IAAA,WAAe,OAAA;EAXX;;;;EA+BhB,QAAA,CAAS,YAAA,EAAc,WAAA,CAAY,OAAA;EAAA,QAkC3B,WAAA;EAAA,QAQA,WAAA;EAAA,QAIA,aAAA;AAAA"}
@@ -1,7 +1,11 @@
1
- import { c as DI_TOKENS, d as Transient, m as inject } from "./di-BO1QIb5H.mjs";
2
- import { n as __decorateParam, t as __decorate } from "./decorate-HgTKAYK8.mjs";
3
- import { t as createCliExceptionContext } from "./exception-context-B4kM-M53.mjs";
4
- import { n as CommandError, r as COMMAND_INTERNALS } from "./command-BU4ApTo5.mjs";
1
+ import { t as __exportAll } from "./chunk-BBjsoOtd.mjs";
2
+ import { d as inject, r as DI_TOKENS, s as Singleton } from "./di-DseMn-z9.mjs";
3
+ import { n as getContainer } from "./container-storage-BmOJ4_Na.mjs";
4
+ import { n as __decorateParam, t as __decorate } from "./decorate-CuAoSZvs.mjs";
5
+ import { t as createCliExceptionContext } from "./exception-context-kEoMFwze.mjs";
6
+ import { n as Module } from "./module.decorator-CYHY6pG5.mjs";
7
+ import { n as CommandError, r as COMMAND_INTERNALS } from "./command-BvmUAPPQ.mjs";
8
+ import { t as CommandNotFoundError } from "./command-not-found.error-ONAZ2Bpk.mjs";
5
9
  //#region src/quarry/command-internals.ts
6
10
  /** @internal Set the flat input values before calling handle() */
7
11
  function setCommandInputs(command, values) {
@@ -21,17 +25,6 @@ function getCommandResult(command) {
21
25
  };
22
26
  }
23
27
  //#endregion
24
- //#region src/quarry/errors/command-not-found.error.ts
25
- /**
26
- * Thrown when a command is not found in the Quarry registry.
27
- */
28
- var CommandNotFoundError = class extends Error {
29
- constructor(name) {
30
- super(`Command "${name}" is not registered.`);
31
- this.name = "CommandNotFoundError";
32
- }
33
- };
34
- //#endregion
35
28
  //#region src/quarry/signature-parser.ts
36
29
  /**
37
30
  * Parse a Laravel-style command signature string.
@@ -169,7 +162,7 @@ let QuarryRegistry = class QuarryRegistry {
169
162
  for (const arg of signature.arguments) if (arg.required && (mergedInput[arg.name] === void 0 || mergedInput[arg.name] === null)) throw new CommandError(`Missing required argument: ${arg.name}`);
170
163
  let command;
171
164
  try {
172
- command = this.container.resolve(CommandClass);
165
+ command = getContainer().resolve(CommandClass);
173
166
  setCommandQuarry(command, this);
174
167
  setCommandInputs(command, mergedInput);
175
168
  const exitCode = await command.handle();
@@ -253,7 +246,7 @@ let QuarryRegistry = class QuarryRegistry {
253
246
  */
254
247
  async listUsage(options) {
255
248
  const commands = this.list();
256
- const { generateListing } = await import("./usage-generator-DTqaUMR9.mjs").then((n) => n.n);
249
+ const { generateListing } = await import("./usage-generator-DAWYasuP.mjs").then((n) => n.n);
257
250
  return generateListing(commands, this.signatures, options);
258
251
  }
259
252
  /**
@@ -265,7 +258,7 @@ let QuarryRegistry = class QuarryRegistry {
265
258
  if (!CommandClass) throw new CommandNotFoundError(name);
266
259
  const signature = this.signatures.get(resolvedName);
267
260
  const staticCommand = CommandClass;
268
- const { generateUsage } = await import("./usage-generator-DTqaUMR9.mjs").then((n) => n.n);
261
+ const { generateUsage } = await import("./usage-generator-DAWYasuP.mjs").then((n) => n.n);
269
262
  return generateUsage(signature, staticCommand.description);
270
263
  }
271
264
  /**
@@ -304,8 +297,16 @@ let QuarryRegistry = class QuarryRegistry {
304
297
  return result;
305
298
  }
306
299
  };
307
- QuarryRegistry = __decorate([Transient(DI_TOKENS.Quarry), __decorateParam(0, inject(DI_TOKENS.Container))], QuarryRegistry);
300
+ QuarryRegistry = __decorate([Singleton(DI_TOKENS.Quarry), __decorateParam(0, inject(DI_TOKENS.Container))], QuarryRegistry);
301
+ //#endregion
302
+ //#region src/quarry/quarry.module.ts
303
+ var quarry_module_exports = /* @__PURE__ */ __exportAll({ QuarryModule: () => QuarryModule });
304
+ let QuarryModule = class QuarryModule {};
305
+ QuarryModule = __decorate([Module({ providers: [{
306
+ provide: DI_TOKENS.Quarry,
307
+ useClass: QuarryRegistry
308
+ }] })], QuarryModule);
308
309
  //#endregion
309
- export { parseSignature as n, CommandNotFoundError as r, QuarryRegistry as t };
310
+ export { parseSignature as i, quarry_module_exports as n, QuarryRegistry as r, QuarryModule as t };
310
311
 
311
- //# sourceMappingURL=quarry-registry-DkraZNwn.mjs.map
312
+ //# sourceMappingURL=quarry.module-BuRPGMDm.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quarry.module-BuRPGMDm.mjs","names":[],"sources":["../src/quarry/command-internals.ts","../src/quarry/signature-parser.ts","../src/quarry/quarry-registry.ts","../src/quarry/quarry.module.ts"],"sourcesContent":["import type { Command } from './command'\nimport { COMMAND_INTERNALS } from './constants'\nimport type { CommandInput, CommandInternals, CommandResult } from './types'\n\n/** @internal Set the flat input values before calling handle() */\nexport function setCommandInputs(command: Command, values: CommandInput): void {\n command[COMMAND_INTERNALS].inputs = { ...values }\n}\n\n/** @internal Set the Quarry reference for this.call() support */\nexport function setCommandQuarry(\n command: Command,\n quarry: { call(name: string, input?: CommandInput): Promise<CommandResult> },\n): void {\n command[COMMAND_INTERNALS].quarry = quarry\n}\n\n/** @internal Collect the result after handle() completes */\nexport function getCommandResult(command: Command): CommandResult {\n const internals: CommandInternals = command[COMMAND_INTERNALS]\n return {\n exitCode: internals.exitCode,\n output: [...internals.output],\n errors: [...internals.errors],\n }\n}\n\n/** @internal Reset state between invocations */\nexport function resetCommandState(command: Command): void {\n const internals: CommandInternals = command[COMMAND_INTERNALS]\n internals.inputs = {}\n internals.output = []\n internals.errors = []\n internals.exitCode = 0\n}\n","import { CommandError } from './errors/command.error'\nimport type { ParsedArgument, ParsedOption, ParsedSignature } from './types'\n\n/**\n * Parse a Laravel-style command signature string.\n *\n * Signature syntax:\n * command-name {arg} ... — flat command\n * group subcommand {arg} ... — subcommand hierarchy (space-separated)\n * namespace:command {arg} ... — namespaced flat command (colon-separated)\n * {--flag} {--name=} {--name=default} {--name=*} {--A|name} {--name= : desc}\n *\n * Pure function, zero dependencies, edge-compatible.\n */\nexport function parseSignature(signature: string): ParsedSignature {\n const tokens = extractTokens(signature)\n const name = extractCommandName(signature)\n const args: ParsedArgument[] = []\n const options: ParsedOption[] = []\n\n for (const token of tokens) {\n const inner = token.slice(1, -1).trim() // strip { }\n\n if (inner.startsWith('--')) {\n options.push(parseOption(inner))\n } else {\n args.push(parseArgument(inner))\n }\n }\n\n return { name, arguments: args, options }\n}\n\nfunction extractCommandName(signature: string): string {\n const match = /^[\\w:.-]+(?:\\s+[\\w:.-]+)*/.exec(signature)\n if (!match) {\n throw new CommandError(`Invalid signature: cannot extract command name from \"${signature}\"`)\n }\n return match[0]\n}\n\nfunction extractTokens(signature: string): string[] {\n const tokens: string[] = []\n const regex = /\\{[^}]+\\}/g\n let match: RegExpExecArray | null\n\n while ((match = regex.exec(signature)) !== null) {\n tokens.push(match[0])\n }\n\n return tokens\n}\n\nfunction parseArgument(inner: string): ParsedArgument {\n const { value, description } = splitDescription(inner)\n\n // {name*} — array/variadic argument\n if (value.endsWith('*')) {\n return {\n name: value.slice(0, -1).trim(),\n required: true,\n isArray: true,\n description,\n }\n }\n\n // {name=default} — argument with default value\n const eqIdx = value.indexOf('=')\n if (eqIdx !== -1) {\n return {\n name: value.slice(0, eqIdx).trim(),\n required: false,\n default: value.slice(eqIdx + 1).trim(),\n isArray: false,\n description,\n }\n }\n\n // {name?} — optional argument\n if (value.endsWith('?')) {\n return {\n name: value.slice(0, -1).trim(),\n required: false,\n isArray: false,\n description,\n }\n }\n\n // {name} — required argument\n return {\n name: value.trim(),\n required: true,\n isArray: false,\n description,\n }\n}\n\nfunction parseOption(inner: string): ParsedOption {\n // Remove leading --\n const withoutDashes = inner.slice(2)\n const { value, description } = splitDescription(withoutDashes)\n\n // Check for alias: {--A|name...}\n let alias: string | undefined\n let optBody = value\n\n const pipeIdx = optBody.indexOf('|')\n if (pipeIdx !== -1) {\n alias = optBody.slice(0, pipeIdx).trim()\n optBody = optBody.slice(pipeIdx + 1).trim()\n }\n\n // {--name=*} — array option\n if (optBody.endsWith('=*')) {\n return {\n name: optBody.slice(0, -2).trim(),\n alias,\n isFlag: false,\n isArray: true,\n description,\n }\n }\n\n // {--name=default} — option with default value\n const eqIdx = optBody.indexOf('=')\n if (eqIdx !== -1) {\n const name = optBody.slice(0, eqIdx).trim()\n const defaultValue = optBody.slice(eqIdx + 1).trim()\n\n return {\n name,\n alias,\n isFlag: false,\n isArray: false,\n default: defaultValue || undefined,\n description,\n }\n }\n\n // {--flag} — boolean flag\n return {\n name: optBody.trim(),\n alias,\n isFlag: true,\n isArray: false,\n description,\n }\n}\n\nfunction splitDescription(value: string): { value: string; description?: string } {\n const colonIdx = value.indexOf(' : ')\n if (colonIdx === -1) {\n return { value }\n }\n\n return {\n value: value.slice(0, colonIdx).trim(),\n description: value.slice(colonIdx + 3).trim(),\n }\n}\n","import { inject } from '../di'\nimport type { Container } from '../di/container'\nimport { getContainer } from '../di/container-storage'\nimport { Singleton } from '../di/decorators'\nimport { DI_TOKENS } from '../di/tokens'\nimport { createCliExceptionContext } from '../errors/exception-context'\nimport type { ExceptionHandler } from '../errors/exception-handler'\nimport type { Constructor } from '../types'\nimport { type Command } from './command'\nimport { getCommandResult, setCommandInputs, setCommandQuarry } from './command-internals'\nimport { CommandNotFoundError } from './errors/command-not-found.error'\nimport { CommandError } from './errors/command.error'\nimport { parseSignature } from './signature-parser'\nimport type { CommandInput, CommandResult, ParsedSignature, Quarry } from './types'\n\n/**\n * QuarryRegistry — edge-compatible programmatic API for running commands.\n *\n * Registered as a singleton via DI_TOKENS.Quarry.\n * Commands are auto-discovered from module providers and registered at bootstrap.\n * Command constructors are stored at bootstrap; fresh instances are resolved per `call()`.\n *\n * Users should inject and type as `Quarry` (the interface), which only exposes `call()`.\n */\n@Singleton(DI_TOKENS.Quarry)\nexport class QuarryRegistry implements Quarry {\n private commands = new Map<string, Constructor<Command>>()\n private signatures = new Map<string, ParsedSignature>()\n private aliases = new Map<string, string>()\n\n constructor(@inject(DI_TOKENS.Container) private readonly container: Container) { }\n\n /**\n * Execute a command by name with optional flat input.\n * A fresh command instance is resolved from the container per invocation.\n */\n async call(name: string, input?: CommandInput): Promise<CommandResult> {\n const resolvedName = this.resolveName(name)\n const CommandClass = this.commands.get(resolvedName)\n\n if (!CommandClass) {\n throw new CommandNotFoundError(name)\n }\n\n const signature = this.signatures.get(resolvedName)!\n const mergedInput = this.applyDefaults(input ?? {}, signature)\n\n // Validate required arguments\n for (const arg of signature.arguments) {\n if (arg.required && (mergedInput[arg.name] === undefined || mergedInput[arg.name] === null)) {\n throw new CommandError(`Missing required argument: ${arg.name}`)\n }\n }\n\n let command: Command | undefined\n\n try {\n // Resolve from the active request scope (handleCommand runs call() inside\n // runInRequestScope), not the global container — commands may inject\n // request-scoped providers (e.g. @InjectQueue → QueueRegistry).\n command = getContainer().resolve<Command>(CommandClass)\n\n setCommandQuarry(command, this)\n setCommandInputs(command, mergedInput)\n\n const exitCode = await command.handle()\n const result = getCommandResult(command)\n\n if (typeof exitCode === 'number') {\n return { ...result, exitCode }\n }\n\n return result\n } catch (error) {\n if (error instanceof CommandError) {\n if (command) {\n const result = getCommandResult(command)\n return {\n exitCode: result.exitCode === 0 ? 1 : result.exitCode,\n output: result.output,\n errors: [...result.errors, error.message],\n }\n }\n return { exitCode: 1, output: [], errors: [error.message] }\n }\n\n const errorMessage = this.handleError(error, resolvedName)\n\n if (command) {\n const result = getCommandResult(command)\n return {\n exitCode: result.exitCode === 0 ? 1 : result.exitCode,\n output: result.output,\n errors: [...result.errors, errorMessage],\n }\n }\n return { exitCode: 1, output: [], errors: [errorMessage] }\n }\n }\n\n /**\n * Check if a command exists by name or alias.\n */\n has(name: string): boolean {\n const resolved = this.resolveName(name)\n return this.commands.has(resolved)\n }\n\n /**\n * Get a command constructor by name or alias.\n */\n get(name: string): Constructor<Command> | undefined {\n const resolved = this.resolveName(name)\n return this.commands.get(resolved)\n }\n\n /**\n * Get all registered command constructors.\n */\n all(): Map<string, Constructor<Command>> {\n return new Map(this.commands)\n }\n\n /**\n * List all commands with their descriptions and aliases.\n */\n list(): { name: string; description?: string; aliases: string[] }[] {\n const result: { name: string; description?: string; aliases: string[] }[] = []\n\n for (const [name, CommandClass] of this.commands) {\n const staticCommand = CommandClass as unknown as typeof Command\n const commandAliases: string[] = []\n\n for (const [alias, target] of this.aliases) {\n if (target === name) {\n commandAliases.push(alias)\n }\n }\n\n result.push({\n name,\n description: staticCommand.description,\n aliases: commandAliases,\n })\n }\n\n return result.sort((a, b) => a.name.localeCompare(b.name))\n }\n\n /**\n * Generate a compact listing of all commands with visual hierarchy and colors.\n */\n async listUsage(options?: { binaryName?: string; binaryLabel?: string; binaryVersion?: string }): Promise<string> {\n const commands = this.list()\n\n // Dynamic import to keep usage-generator tree-shakeable\n const { generateListing } = await import('./usage-generator')\n return generateListing(commands, this.signatures, options)\n }\n\n /**\n * Get auto-generated usage text for a command.\n */\n async usage(name: string): Promise<string> {\n const resolvedName = this.resolveName(name)\n const CommandClass = this.commands.get(resolvedName)\n\n if (!CommandClass) {\n throw new CommandNotFoundError(name)\n }\n\n const signature = this.signatures.get(resolvedName)!\n const staticCommand = CommandClass as unknown as typeof Command\n\n // Dynamic import to keep usage-generator tree-shakeable\n const { generateUsage } = await import('./usage-generator')\n return generateUsage(signature, staticCommand.description)\n }\n\n /**\n * Register a command constructor with the registry.\n * @internal Called by Application during bootstrap.\n */\n register(commandClass: Constructor<Command>): void {\n const staticCommand = commandClass as unknown as typeof Command\n\n if (!staticCommand.command) {\n throw new CommandError(`Command class ${commandClass.name} is missing static \"command\" signature`)\n }\n\n const signature = parseSignature(staticCommand.command)\n const name = signature.name\n\n if (this.commands.has(name) || this.aliases.has(name)) {\n throw new CommandError(`Duplicate command name: \"${name}\" is already registered`)\n }\n\n // Validate all aliases before any mutation\n if (staticCommand.aliases) {\n for (const alias of staticCommand.aliases) {\n if (this.commands.has(alias) || this.aliases.has(alias)) {\n throw new CommandError(`Duplicate alias: \"${alias}\" conflicts with an existing command or alias`)\n }\n }\n }\n\n // All checks passed — safe to mutate\n this.commands.set(name, commandClass)\n this.signatures.set(name, signature)\n\n if (staticCommand.aliases) {\n for (const alias of staticCommand.aliases) {\n this.aliases.set(alias, name)\n }\n }\n }\n\n private handleError(error: unknown, commandName: string): string {\n const handler = this.container.resolve<ExceptionHandler>(DI_TOKENS.ExceptionHandler)\n const ctx = createCliExceptionContext(commandName)\n // Fire-and-forget — reporting happens via waitUntil internally\n void handler.handle(error, ctx)\n return error instanceof Error ? error.message : String(error)\n }\n\n private resolveName(name: string): string {\n return this.aliases.get(name) ?? name\n }\n\n private applyDefaults(input: CommandInput, signature: ParsedSignature): CommandInput {\n const result = { ...input }\n\n // Apply argument defaults\n for (const arg of signature.arguments) {\n if (result[arg.name] === undefined && arg.default !== undefined) {\n result[arg.name] = arg.default\n }\n }\n\n // Apply option defaults\n for (const opt of signature.options) {\n if (result[opt.name] === undefined) {\n if (opt.default !== undefined) {\n result[opt.name] = opt.default\n } else if (opt.isFlag) {\n result[opt.name] = false\n }\n }\n }\n\n return result\n }\n}\n","import { DI_TOKENS } from '../di/tokens'\nimport { Module } from '../module/module.decorator'\nimport { QuarryRegistry } from './quarry-registry'\n\n/**\n * Registers the Quarry command registry (`DI_TOKENS.Quarry`).\n *\n * Eager: resolved synchronously at bootstrap (`registerCommands`) and by the\n * CLI runner (`bin/quarry.ts`), so it cannot be lazily loaded.\n */\n@Module({\n providers: [\n { provide: DI_TOKENS.Quarry, useClass: QuarryRegistry },\n ],\n})\nexport class QuarryModule { }\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as IQueueConsumer, r as QueueMessage, t as ConsumerRegistry } from "../consumer-registry-DHQtypr1.mjs";
2
- import { a as QueueRegistry, c as QueueModuleOptions, d as CloudflareQueueProvider, f as IQueueProvider, g as QueueManager, h as QueueBinding, i as InjectQueue, l as QueueSender, m as IQueueSender, n as QUEUE_TOKENS, o as QueueProviderFactory, p as DispatchMessage, r as QueueToken, s as QueueModule, t as QueueError, u as SyncQueueProvider } from "../index-CW1YHSft.mjs";
3
- export { CloudflareQueueProvider, ConsumerRegistry, DispatchMessage, IQueueConsumer, IQueueProvider, IQueueSender, InjectQueue, QUEUE_TOKENS, QueueBinding, QueueError, QueueManager, QueueMessage, QueueModule, QueueModuleOptions, QueueProviderFactory, QueueRegistry, QueueSender, QueueToken, SyncQueueProvider };
1
+ import { a as QueueBinding, i as QueueMessage, n as ConsumerRegistry, r as IQueueConsumer, t as ConsumerRegistration } from "../consumer-registry-D3iMTSdy.mjs";
2
+ import { _ as QueueStore, a as FailedJobCleanupJob, b as QueueModule, c as QueueProviderFactory, d as CloudflareQueueProvider, f as IQueueProvider, g as DEFAULT_STORE_BINDING, h as QueueManager, i as InjectQueue, l as QueueSender, m as IQueueSender, n as QUEUE_TOKENS, o as failedJobCleanupJob, p as DispatchMessage, r as QueueToken, s as QueueRegistry, t as QueueError, u as SyncQueueProvider, v as FailedJob, x as QueueModuleOptions, y as FailedJobMetadata } from "../index-B5JBRcWD.mjs";
3
+ export { CloudflareQueueProvider, ConsumerRegistration, ConsumerRegistry, DEFAULT_STORE_BINDING, DispatchMessage, FailedJob, FailedJobCleanupJob, FailedJobMetadata, IQueueConsumer, IQueueProvider, IQueueSender, InjectQueue, QUEUE_TOKENS, QueueBinding, QueueError, QueueManager, QueueMessage, QueueModule, QueueModuleOptions, QueueProviderFactory, QueueRegistry, QueueSender, QueueStore, QueueToken, SyncQueueProvider, failedJobCleanupJob };
@@ -1,39 +1,50 @@
1
- import { c as DI_TOKENS, d as Transient, m as inject } from "../di-BO1QIb5H.mjs";
2
- import { n as __decorateParam, t as __decorate } from "../decorate-HgTKAYK8.mjs";
1
+ import { c as Transient, d as inject } from "../di-DseMn-z9.mjs";
2
+ import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
3
3
  import { LOGGER_TOKENS } from "../logger/index.mjs";
4
- import { a as QueueError, c as QueueSender, i as CloudflareQueueProvider, l as ConsumerRegistry, n as QueueProviderFactory, o as QueueRegistry, r as SyncQueueProvider, s as QUEUE_TOKENS, t as QueueModule } from "../queue.module-DeWJ0tQM.mjs";
5
- //#region src/queue/queue-manager.ts
6
- let QueueManager = class QueueManager {
7
- registry;
4
+ import { a as CloudflareQueueProvider, c as QueueRegistry, d as QueueManager, f as QueueError, i as SyncQueueProvider, l as QueueSender, o as DEFAULT_STORE_BINDING, r as QueueProviderFactory, s as QueueStore, t as QueueModule, u as ConsumerRegistry } from "../queue.module-nddvxzCB.mjs";
5
+ import { t as QUEUE_TOKENS } from "../queue.tokens-DjHnFmre.mjs";
6
+ //#region src/queue/jobs/failed-job-cleanup.job.ts
7
+ /** Retention applied when `failedJobs.retention` is not configured. */
8
+ const DEFAULT_RETENTION_SECONDS = 604800;
9
+ let FailedJobCleanupJob = class FailedJobCleanupJob {
10
+ store;
11
+ options;
8
12
  logger;
9
- constructor(registry, logger) {
10
- this.registry = registry;
13
+ static schedule = "0 0 * * *";
14
+ constructor(store, options, logger) {
15
+ this.store = store;
16
+ this.options = options;
11
17
  this.logger = logger;
12
18
  }
13
- async processBatch(queueName, batch) {
14
- for (const message of batch.messages) {
15
- const queueMessage = message.body;
16
- const consumers = this.registry.getConsumers(queueMessage.type);
17
- for (const consumer of consumers) try {
18
- await consumer.handle(queueMessage);
19
- message.ack();
20
- } catch (error) {
21
- const errorInstance = error instanceof Error ? error : new Error(String(error));
22
- this.logger.error("Queue message processing failed", errorInstance, {
23
- type: queueMessage.type,
24
- queue: queueName
25
- });
26
- if (consumer.onError) await consumer.onError(errorInstance, queueMessage);
27
- message.retry();
28
- }
29
- }
19
+ async execute() {
20
+ const retention = this.options.failedJobs?.retention ?? DEFAULT_RETENTION_SECONDS;
21
+ const removed = await this.store.purgeFailedJobsOlderThan(retention);
22
+ this.logger.info("Failed-job cleanup complete", {
23
+ removed,
24
+ retentionSeconds: retention
25
+ });
30
26
  }
31
27
  };
32
- QueueManager = __decorate([
33
- Transient(DI_TOKENS.Queue),
34
- __decorateParam(0, inject(DI_TOKENS.ConsumerRegistry)),
35
- __decorateParam(1, inject(LOGGER_TOKENS.LoggerService))
36
- ], QueueManager);
28
+ FailedJobCleanupJob = __decorate([
29
+ Transient(),
30
+ __decorateParam(0, inject(QUEUE_TOKENS.QueueStore)),
31
+ __decorateParam(1, inject(QUEUE_TOKENS.QueueModuleOptions)),
32
+ __decorateParam(2, inject(LOGGER_TOKENS.LoggerService))
33
+ ], FailedJobCleanupJob);
34
+ /**
35
+ * Create a {@link FailedJobCleanupJob} bound to a custom cron schedule (which
36
+ * must match a `wrangler.jsonc` trigger). Use when the default daily schedule
37
+ * isn't desired:
38
+ *
39
+ * ```ts
40
+ * @Module({ jobs: [failedJobCleanupJob('0 3 * * 0')] }) // weekly, Sundays 03:00
41
+ * ```
42
+ */
43
+ function failedJobCleanupJob(schedule) {
44
+ return class extends FailedJobCleanupJob {
45
+ static schedule = schedule;
46
+ };
47
+ }
37
48
  //#endregion
38
49
  //#region src/queue/decorators/inject-queue.decorator.ts
39
50
  /**
@@ -68,6 +79,6 @@ function InjectQueue(binding) {
68
79
  return inject(binding);
69
80
  }
70
81
  //#endregion
71
- export { CloudflareQueueProvider, ConsumerRegistry, InjectQueue, QUEUE_TOKENS, QueueError, QueueManager, QueueModule, QueueProviderFactory, QueueRegistry, QueueSender, SyncQueueProvider };
82
+ export { CloudflareQueueProvider, ConsumerRegistry, DEFAULT_STORE_BINDING, FailedJobCleanupJob, InjectQueue, QUEUE_TOKENS, QueueError, QueueManager, QueueModule, QueueProviderFactory, QueueRegistry, QueueSender, QueueStore, SyncQueueProvider, failedJobCleanupJob };
72
83
 
73
84
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/queue/queue-manager.ts","../../src/queue/decorators/inject-queue.decorator.ts"],"sourcesContent":["import { inject } from '../di';\nimport { Transient } from '../di/decorators';\nimport { DI_TOKENS } from '../di/tokens';\nimport { LOGGER_TOKENS, type LoggerService } from '../logger';\nimport { type ConsumerRegistry } from './consumer-registry';\nimport type { QueueMessage } from './queue-consumer';\n\n@Transient(DI_TOKENS.Queue)\nexport class QueueManager {\n constructor(\n @inject(DI_TOKENS.ConsumerRegistry) private readonly registry: ConsumerRegistry,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService,\n ) {}\n\n async processBatch(queueName: string, batch: MessageBatch): Promise<void> {\n for (const message of batch.messages) {\n const queueMessage = message.body as QueueMessage\n\n const consumers = this.registry.getConsumers(queueMessage.type)\n\n for (const consumer of consumers) {\n try {\n await consumer.handle(queueMessage)\n message.ack()\n } catch (error) {\n const errorInstance = error instanceof Error\n ? error\n : new Error(String(error))\n\n this.logger.error('Queue message processing failed', errorInstance, {\n type: queueMessage.type,\n queue: queueName,\n })\n\n if (consumer.onError) {\n await consumer.onError(errorInstance, queueMessage)\n }\n message.retry()\n }\n }\n }\n }\n}\n","import { inject } from '../../di'\nimport type { QueueBinding } from '../queue-binding'\n\n/**\n * Inject a queue sender by binding name.\n *\n * The binding name matches the `binding` field declared under `queues.producers`\n * in `wrangler.jsonc` (e.g. `BACKGROUND_QUEUE`). Stratal looks the binding up\n * directly on the worker's `env`; the underlying Cloudflare queue can be any\n * env-specific name (e.g. `background-queue-dev`) without affecting code.\n *\n * @param binding - Queue binding identifier (typed against `StratalEnv`).\n * @returns Parameter decorator for constructor injection\n *\n * @example\n * ```typescript\n * constructor(\n * @InjectQueue('NOTIFICATIONS_QUEUE') private queue: IQueueSender\n * ) {}\n *\n * await this.queue.dispatch({\n * type: 'email.send',\n * payload: { to: 'user@example.com', subject: 'Hello' }\n * })\n * ```\n *\n * @remarks\n * The binding must be registered via `QueueModule.registerQueue(binding)`\n * before injection. For module-internal bindings (e.g. EmailModule),\n * use `@inject(TOKEN)` with `useExisting` provider binding instead.\n */\nexport function InjectQueue(binding: QueueBinding): ParameterDecorator {\n return inject(binding)\n}\n"],"mappings":";;;;;AAQO,IAAA,eAAA,MAAM,aAAa;CAE+B;CACC;CAFxD,YACE,UACA,QACA;EAFqD,KAAA,WAAA;EACC,KAAA,SAAA;;CAGxD,MAAM,aAAa,WAAmB,OAAoC;EACxE,KAAK,MAAM,WAAW,MAAM,UAAU;GACpC,MAAM,eAAe,QAAQ;GAE7B,MAAM,YAAY,KAAK,SAAS,aAAa,aAAa,KAAK;GAE/D,KAAK,MAAM,YAAY,WACrB,IAAI;IACF,MAAM,SAAS,OAAO,aAAa;IACnC,QAAQ,KAAK;YACN,OAAO;IACd,MAAM,gBAAgB,iBAAiB,QACnC,QACA,IAAI,MAAM,OAAO,MAAM,CAAC;IAE5B,KAAK,OAAO,MAAM,mCAAmC,eAAe;KAClE,MAAM,aAAa;KACnB,OAAO;KACR,CAAC;IAEF,IAAI,SAAS,SACX,MAAM,SAAS,QAAQ,eAAe,aAAa;IAErD,QAAQ,OAAO;;;;;;CA9BxB,UAAU,UAAU,MAAM;oBAGtB,OAAO,UAAU,iBAAiB,CAAA;oBAClC,OAAO,cAAc,cAAc,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACoBxC,SAAgB,YAAY,SAA2C;CACrE,OAAO,OAAO,QAAQ"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/queue/jobs/failed-job-cleanup.job.ts","../../src/queue/decorators/inject-queue.decorator.ts"],"sourcesContent":["import type { CronJob } from '../../cron/cron-job'\nimport { inject } from '../../di'\nimport { Transient } from '../../di/decorators'\nimport { LOGGER_TOKENS, type LoggerService } from '../../logger'\nimport type { Constructor } from '../../types'\nimport type { QueueModuleOptions } from '../queue.module'\nimport type { QueueStore } from '../queue-store'\nimport { QUEUE_TOKENS } from '../queue.tokens'\n\n/** Retention applied when `failedJobs.retention` is not configured. */\nconst DEFAULT_RETENTION_SECONDS = 604800 // 7 days\n\n/**\n * Opt-in cron job that deletes failed jobs older than `failedJobs.retention`\n * (default 7 days). Failed jobs are persisted indefinitely by default; register\n * this job only if you want automatic cleanup.\n *\n * ```ts\n * @Module({\n * imports: [\n * QueueModule.forRoot({ provider: 'cloudflare', failedJobs: { retention: 1209600 } }),\n * ],\n * jobs: [FailedJobCleanupJob], // daily at 00:00 UTC\n * })\n * export class AppModule {}\n * ```\n *\n * Add a matching cron trigger to `wrangler.jsonc` (`\"0 0 * * *\"` for the\n * default schedule), or use {@link failedJobCleanupJob} for a custom one.\n */\n@Transient()\nexport class FailedJobCleanupJob implements CronJob {\n static schedule = '0 0 * * *' // daily at 00:00 UTC\n\n constructor(\n @inject(QUEUE_TOKENS.QueueStore) private readonly store: QueueStore,\n @inject(QUEUE_TOKENS.QueueModuleOptions) private readonly options: QueueModuleOptions,\n @inject(LOGGER_TOKENS.LoggerService) private readonly logger: LoggerService,\n ) {}\n\n async execute(): Promise<void> {\n const retention = this.options.failedJobs?.retention ?? DEFAULT_RETENTION_SECONDS\n const removed = await this.store.purgeFailedJobsOlderThan(retention)\n this.logger.info('Failed-job cleanup complete', { removed, retentionSeconds: retention })\n }\n}\n\n/**\n * Create a {@link FailedJobCleanupJob} bound to a custom cron schedule (which\n * must match a `wrangler.jsonc` trigger). Use when the default daily schedule\n * isn't desired:\n *\n * ```ts\n * @Module({ jobs: [failedJobCleanupJob('0 3 * * 0')] }) // weekly, Sundays 03:00\n * ```\n */\nexport function failedJobCleanupJob(schedule: string): Constructor<CronJob> {\n return class extends FailedJobCleanupJob {\n static schedule = schedule\n }\n}\n","import { inject } from '../../di'\nimport type { QueueBinding } from '../queue-binding'\n\n/**\n * Inject a queue sender by binding name.\n *\n * The binding name matches the `binding` field declared under `queues.producers`\n * in `wrangler.jsonc` (e.g. `BACKGROUND_QUEUE`). Stratal looks the binding up\n * directly on the worker's `env`; the underlying Cloudflare queue can be any\n * env-specific name (e.g. `background-queue-dev`) without affecting code.\n *\n * @param binding - Queue binding identifier (typed against `StratalEnv`).\n * @returns Parameter decorator for constructor injection\n *\n * @example\n * ```typescript\n * constructor(\n * @InjectQueue('NOTIFICATIONS_QUEUE') private queue: IQueueSender\n * ) {}\n *\n * await this.queue.dispatch({\n * type: 'email.send',\n * payload: { to: 'user@example.com', subject: 'Hello' }\n * })\n * ```\n *\n * @remarks\n * The binding must be registered via `QueueModule.registerQueue(binding)`\n * before injection. For module-internal bindings (e.g. EmailModule),\n * use `@inject(TOKEN)` with `useExisting` provider binding instead.\n */\nexport function InjectQueue(binding: QueueBinding): ParameterDecorator {\n return inject(binding)\n}\n"],"mappings":";;;;;;;AAUA,MAAM,4BAA4B;AAqB3B,IAAA,sBAAA,MAAM,oBAAuC;CAIE;CACQ;CACJ;CALxD,OAAO,WAAW;CAElB,YACE,OACA,SACA,QACA;EAHkD,KAAA,QAAA;EACQ,KAAA,UAAA;EACJ,KAAA,SAAA;CACrD;CAEH,MAAM,UAAyB;EAC7B,MAAM,YAAY,KAAK,QAAQ,YAAY,aAAa;EACxD,MAAM,UAAU,MAAM,KAAK,MAAM,yBAAyB,SAAS;EACnE,KAAK,OAAO,KAAK,+BAA+B;GAAE;GAAS,kBAAkB;EAAU,CAAC;CAC1F;AACF;;CAfC,UAAU;oBAKN,OAAO,aAAa,UAAU,CAAA;oBAC9B,OAAO,aAAa,kBAAkB,CAAA;oBACtC,OAAO,cAAc,aAAa,CAAA;;;;;;;;;;;AAmBvC,SAAgB,oBAAoB,UAAwC;CAC1E,OAAO,cAAc,oBAAoB;EACvC,OAAO,WAAW;CACpB;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7BA,SAAgB,YAAY,SAA2C;CACrE,OAAO,OAAO,OAAO;AACvB"}