stratal 0.0.21 → 0.0.22

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 (246) hide show
  1. package/README.md +1 -1
  2. package/dist/{base-email.provider-CfQCA08m.mjs → base-email.provider-BWZHIjt8.mjs} +1 -1
  3. package/dist/{base-email.provider-CfQCA08m.mjs.map → base-email.provider-BWZHIjt8.mjs.map} +1 -1
  4. package/dist/bin/quarry.mjs +46 -109
  5. package/dist/bin/quarry.mjs.map +1 -1
  6. package/dist/cache/index.d.mts +6 -46
  7. package/dist/cache/index.d.mts.map +1 -1
  8. package/dist/cache/index.mjs +20 -67
  9. package/dist/cache/index.mjs.map +1 -1
  10. package/dist/{cache.service-DsnKuNyO.d.mts → cache.service-e34gV6tz.d.mts} +8 -8
  11. package/dist/{cache.service-DsnKuNyO.d.mts.map → cache.service-e34gV6tz.d.mts.map} +1 -1
  12. package/dist/{cache.tokens-B7Rw1C9Q.mjs → cache.tokens-ovi_c52J.mjs} +1 -1
  13. package/dist/{cache.tokens-B7Rw1C9Q.mjs.map → cache.tokens-ovi_c52J.mjs.map} +1 -1
  14. package/dist/{colors-DJaRDXoS.mjs → colors-axmupKdp.mjs} +1 -1
  15. package/dist/{colors-DJaRDXoS.mjs.map → colors-axmupKdp.mjs.map} +1 -1
  16. package/dist/{command-BgSlsS4M.mjs → command-BU4ApTo5.mjs} +2 -3
  17. package/dist/command-BU4ApTo5.mjs.map +1 -0
  18. package/dist/{command-Cmmf0oHX.d.mts → command-wXfvHbBZ.d.mts} +3 -2
  19. package/dist/command-wXfvHbBZ.d.mts.map +1 -0
  20. package/dist/config/index.d.mts +24 -11
  21. package/dist/config/index.d.mts.map +1 -1
  22. package/dist/config/index.mjs +31 -57
  23. package/dist/config/index.mjs.map +1 -1
  24. package/dist/{consumer-registry-B7yUNh0q.d.mts → consumer-registry-DHQtypr1.d.mts} +1 -1
  25. package/dist/{consumer-registry-B7yUNh0q.d.mts.map → consumer-registry-DHQtypr1.d.mts.map} +1 -1
  26. package/dist/container-storage-GpNNz79X.mjs +52 -0
  27. package/dist/container-storage-GpNNz79X.mjs.map +1 -0
  28. package/dist/{controller.decorator-B9vwn0zK.mjs → controller.decorator-DIUazNU7.mjs} +8 -8
  29. package/dist/controller.decorator-DIUazNU7.mjs.map +1 -0
  30. package/dist/cron/index.d.mts +26 -5
  31. package/dist/cron/index.d.mts.map +1 -1
  32. package/dist/cron/index.mjs +1 -1
  33. package/dist/{cron-manager-DQSK8uoV.mjs → cron-manager-9bpN9bu4.mjs} +35 -15
  34. package/dist/cron-manager-9bpN9bu4.mjs.map +1 -0
  35. package/dist/{cron-manager-CmTimEjf.d.mts → cron-manager-CSTIBPcM.d.mts} +6 -13
  36. package/dist/cron-manager-CSTIBPcM.d.mts.map +1 -0
  37. package/dist/decorate-HgTKAYK8.mjs +16 -0
  38. package/dist/deep-merge-C8NgcXw4.mjs +18 -0
  39. package/dist/deep-merge-C8NgcXw4.mjs.map +1 -0
  40. package/dist/di/index.d.mts +2 -2
  41. package/dist/di/index.mjs +4 -3
  42. package/dist/di-BO1QIb5H.mjs +415 -0
  43. package/dist/di-BO1QIb5H.mjs.map +1 -0
  44. package/dist/email/index.d.mts +14 -89
  45. package/dist/email/index.d.mts.map +1 -1
  46. package/dist/email/index.mjs +25 -125
  47. package/dist/email/index.mjs.map +1 -1
  48. package/dist/en-BPP6h6y5.mjs +202 -0
  49. package/dist/en-BPP6h6y5.mjs.map +1 -0
  50. package/dist/{env-D1rcZ8_r.d.mts → env-DKSbuBi5.d.mts} +1 -1
  51. package/dist/env-DKSbuBi5.d.mts.map +1 -0
  52. package/dist/errors/index.d.mts +2 -2
  53. package/dist/errors/index.mjs +4 -2
  54. package/dist/errors-BBZTnjdq.mjs +333 -0
  55. package/dist/errors-BBZTnjdq.mjs.map +1 -0
  56. package/dist/events/index.d.mts +2 -2
  57. package/dist/events/index.d.mts.map +1 -1
  58. package/dist/events/index.mjs +1 -1
  59. package/dist/{events-CzCV8jI8.mjs → events-D1KdDaiP.mjs} +11 -11
  60. package/dist/events-D1KdDaiP.mjs.map +1 -0
  61. package/dist/exception-context-B4kM-M53.mjs +429 -0
  62. package/dist/exception-context-B4kM-M53.mjs.map +1 -0
  63. package/dist/{gateway-context-CXmXtaUP.mjs → gateway-context-CFe6a9gz.mjs} +19 -31
  64. package/dist/gateway-context-CFe6a9gz.mjs.map +1 -0
  65. package/dist/guards/index.d.mts +3 -3
  66. package/dist/guards/index.d.mts.map +1 -1
  67. package/dist/guards/index.mjs +1 -1
  68. package/dist/{guards-DU1_J9YA.mjs → guards-Ced-uNIF.mjs} +6 -5
  69. package/dist/guards-Ced-uNIF.mjs.map +1 -0
  70. package/dist/{http-method.decorator-BrgHMdLQ.mjs → http-method.decorator-CdjKFJZZ.mjs} +7 -6
  71. package/dist/http-method.decorator-CdjKFJZZ.mjs.map +1 -0
  72. package/dist/i18n/index.d.mts +238 -3
  73. package/dist/i18n/index.d.mts.map +1 -0
  74. package/dist/i18n/index.mjs +39 -3
  75. package/dist/i18n/index.mjs.map +1 -0
  76. package/dist/i18n/messages/en/index.d.mts +2 -2
  77. package/dist/i18n/messages/en/index.mjs +2 -2
  78. package/dist/i18n/utils/index.d.mts +4 -26
  79. package/dist/i18n/utils/index.d.mts.map +1 -1
  80. package/dist/i18n/utils/index.mjs +2 -2
  81. package/dist/i18n/validation/index.d.mts +3 -2
  82. package/dist/i18n/validation/index.mjs +4 -2
  83. package/dist/i18n.module-BlXrtAlV.mjs +219 -0
  84. package/dist/i18n.module-BlXrtAlV.mjs.map +1 -0
  85. package/dist/i18n.tokens-hwRpmjRq.mjs +19 -0
  86. package/dist/i18n.tokens-hwRpmjRq.mjs.map +1 -0
  87. package/dist/{index-7-hU3GTV.d.mts → index-B4UBK-2T.d.mts} +1 -1
  88. package/dist/{index-7-hU3GTV.d.mts.map → index-B4UBK-2T.d.mts.map} +1 -1
  89. package/dist/index-BtlE9RuO.d.mts +124 -0
  90. package/dist/index-BtlE9RuO.d.mts.map +1 -0
  91. package/dist/{index-DUzWs0z7.d.mts → index-CW1YHSft.d.mts} +71 -167
  92. package/dist/index-CW1YHSft.d.mts.map +1 -0
  93. package/dist/{index-ByOyTmqf.d.mts → index-DEncMcC6.d.mts} +554 -2237
  94. package/dist/index-DEncMcC6.d.mts.map +1 -0
  95. package/dist/index-Dj5IMwtr.d.mts +44 -0
  96. package/dist/index-Dj5IMwtr.d.mts.map +1 -0
  97. package/dist/{index-C1KvMncZ.d.mts → index-KMgSCSM7.d.mts} +3 -108
  98. package/dist/index-KMgSCSM7.d.mts.map +1 -0
  99. package/dist/index.d.mts +5 -43
  100. package/dist/index.mjs +1 -1
  101. package/dist/{is-command-C6a7WTPw.mjs → is-command-CX5rAfZW.mjs} +2 -2
  102. package/dist/{is-command-C6a7WTPw.mjs.map → is-command-CX5rAfZW.mjs.map} +1 -1
  103. package/dist/{is-seeder-CebjZCDn.mjs → is-seeder-CYCtELlm.mjs} +1 -1
  104. package/dist/{is-seeder-CebjZCDn.mjs.map → is-seeder-CYCtELlm.mjs.map} +1 -1
  105. package/dist/logger/index.d.mts +2 -2
  106. package/dist/logger/index.mjs +170 -2
  107. package/dist/logger/index.mjs.map +1 -0
  108. package/dist/macroable/index.d.mts +1 -1
  109. package/dist/macroable/index.mjs +1 -1
  110. package/dist/{macroable-BmufBshB.mjs → macroable-DzlfzT50.mjs} +1 -1
  111. package/dist/{macroable-BmufBshB.mjs.map → macroable-DzlfzT50.mjs.map} +1 -1
  112. package/dist/metadata-BVkc4aUu.mjs +39 -0
  113. package/dist/metadata-BVkc4aUu.mjs.map +1 -0
  114. package/dist/module/index.d.mts +6 -24
  115. package/dist/module/index.d.mts.map +1 -1
  116. package/dist/module/index.mjs +2 -2
  117. package/dist/module-xYoHba6B.mjs +422 -0
  118. package/dist/module-xYoHba6B.mjs.map +1 -0
  119. package/dist/openapi/index.d.mts +3 -3
  120. package/dist/openapi/index.d.mts.map +1 -1
  121. package/dist/openapi/index.mjs +1 -2
  122. package/dist/openapi-C6lm0RmV.mjs +483 -0
  123. package/dist/openapi-C6lm0RmV.mjs.map +1 -0
  124. package/dist/{openapi.service-Bt9bCIrd.d.mts → openapi.service-CrLlsXAd.d.mts} +3 -3
  125. package/dist/openapi.service-CrLlsXAd.d.mts.map +1 -0
  126. package/dist/quarry/index.d.mts +5 -163
  127. package/dist/quarry/index.d.mts.map +1 -1
  128. package/dist/quarry/index.mjs +5 -5
  129. package/dist/quarry/runner.d.mts +184 -0
  130. package/dist/quarry/runner.d.mts.map +1 -0
  131. package/dist/quarry/runner.mjs +775 -0
  132. package/dist/quarry/runner.mjs.map +1 -0
  133. package/dist/quarry-registry-D4hIGScf.d.mts +69 -0
  134. package/dist/quarry-registry-D4hIGScf.d.mts.map +1 -0
  135. package/dist/quarry-registry-DkraZNwn.mjs +311 -0
  136. package/dist/quarry-registry-DkraZNwn.mjs.map +1 -0
  137. package/dist/queue/index.d.mts +3 -3
  138. package/dist/queue/index.mjs +26 -28
  139. package/dist/queue/index.mjs.map +1 -1
  140. package/dist/{queue.module-BhCjZp6H.mjs → queue.module-DeWJ0tQM.mjs} +59 -113
  141. package/dist/queue.module-DeWJ0tQM.mjs.map +1 -0
  142. package/dist/{r2-storage.provider-DuonKeYm.mjs → r2-storage.provider-Hfm6LdZQ.mjs} +5 -5
  143. package/dist/r2-storage.provider-Hfm6LdZQ.mjs.map +1 -0
  144. package/dist/{rate-limit.decorator-6qzNcSOt.mjs → rate-limit.decorator-D69zdZbp.mjs} +6 -11
  145. package/dist/rate-limit.decorator-D69zdZbp.mjs.map +1 -0
  146. package/dist/rate-limiter/index.d.mts +11 -50
  147. package/dist/rate-limiter/index.d.mts.map +1 -1
  148. package/dist/rate-limiter/index.mjs +16 -30
  149. package/dist/rate-limiter/index.mjs.map +1 -1
  150. package/dist/{resend.provider-DB4IlFjG.mjs → resend.provider-Ur6tU7fK.mjs} +7 -7
  151. package/dist/resend.provider-Ur6tU7fK.mjs.map +1 -0
  152. package/dist/router/index.d.mts +2 -2
  153. package/dist/router/index.mjs +8 -7
  154. package/dist/{i18n.module-CzXLW9Hy.mjs → router-Cy6DjkvP.mjs} +171 -851
  155. package/dist/router-Cy6DjkvP.mjs.map +1 -0
  156. package/dist/seeder/index.d.mts +6 -11
  157. package/dist/seeder/index.d.mts.map +1 -1
  158. package/dist/seeder/index.mjs +3 -3
  159. package/dist/{seeder-zoEfEw9i.mjs → seeder-BADTig4n.mjs} +14 -22
  160. package/dist/seeder-BADTig4n.mjs.map +1 -0
  161. package/dist/{signed-url-BQPbv2In.mjs → signed-url-BqUqt5dF.mjs} +1 -1
  162. package/dist/{signed-url-BQPbv2In.mjs.map → signed-url-BqUqt5dF.mjs.map} +1 -1
  163. package/dist/{smtp.provider-B6D7zuWX.mjs → smtp.provider-C129sNBT.mjs} +6 -6
  164. package/dist/smtp.provider-C129sNBT.mjs.map +1 -0
  165. package/dist/storage/index.d.mts +15 -39
  166. package/dist/storage/index.d.mts.map +1 -1
  167. package/dist/storage/index.mjs +3 -3
  168. package/dist/storage/providers/index.d.mts +2 -2
  169. package/dist/storage/providers/index.mjs +1 -1
  170. package/dist/{storage-D8CBP72Z.mjs → storage-BA3ppVYM.mjs} +65 -59
  171. package/dist/storage-BA3ppVYM.mjs.map +1 -0
  172. package/dist/{storage-provider.interface-Bd6vA4ak.d.mts → storage-provider.interface-DQMtT42e.d.mts} +2 -3
  173. package/dist/storage-provider.interface-DQMtT42e.d.mts.map +1 -0
  174. package/dist/storage.error-C6FY037a.mjs +8 -0
  175. package/dist/storage.error-C6FY037a.mjs.map +1 -0
  176. package/dist/{stratal-CNwpbSZl.mjs → stratal-Bdq4IdB3.mjs} +31 -185
  177. package/dist/stratal-Bdq4IdB3.mjs.map +1 -0
  178. package/dist/stratal-BsKmvP6J.d.mts +43 -0
  179. package/dist/stratal-BsKmvP6J.d.mts.map +1 -0
  180. package/dist/{types-cySNS_lp.d.mts → types-BaeHi67f.d.mts} +1 -1
  181. package/dist/types-BaeHi67f.d.mts.map +1 -0
  182. package/dist/{usage-generator-BUdlhnCK.mjs → usage-generator-DTqaUMR9.mjs} +6 -3
  183. package/dist/usage-generator-DTqaUMR9.mjs.map +1 -0
  184. package/dist/validation-DUzcjb8Q.mjs +49 -0
  185. package/dist/validation-DUzcjb8Q.mjs.map +1 -0
  186. package/dist/validation.context-XTysWJ3b.mjs +117 -0
  187. package/dist/validation.context-XTysWJ3b.mjs.map +1 -0
  188. package/dist/websocket/index.d.mts +7 -14
  189. package/dist/websocket/index.d.mts.map +1 -1
  190. package/dist/websocket/index.mjs +2 -2
  191. package/dist/workers/index.d.mts +2 -2
  192. package/dist/workers/index.mjs +3 -2
  193. package/dist/workers/index.mjs.map +1 -1
  194. package/dist/{index-Bnpfq6uk.d.mts → zod-DvWTfRpI.d.mts} +58 -133
  195. package/dist/zod-DvWTfRpI.d.mts.map +1 -0
  196. package/dist/zod-hMa3rSHV.mjs +72 -0
  197. package/dist/zod-hMa3rSHV.mjs.map +1 -0
  198. package/package.json +10 -10
  199. package/dist/command-BgSlsS4M.mjs.map +0 -1
  200. package/dist/command-Cmmf0oHX.d.mts.map +0 -1
  201. package/dist/controller.decorator-B9vwn0zK.mjs.map +0 -1
  202. package/dist/cron-manager-CmTimEjf.d.mts.map +0 -1
  203. package/dist/cron-manager-DQSK8uoV.mjs.map +0 -1
  204. package/dist/en-DSH_bhh6.mjs +0 -308
  205. package/dist/en-DSH_bhh6.mjs.map +0 -1
  206. package/dist/env-D1rcZ8_r.d.mts.map +0 -1
  207. package/dist/errors-COW9-Mar.mjs +0 -1739
  208. package/dist/errors-COW9-Mar.mjs.map +0 -1
  209. package/dist/errors-ORxu1-Bb.mjs +0 -74
  210. package/dist/errors-ORxu1-Bb.mjs.map +0 -1
  211. package/dist/events-CzCV8jI8.mjs.map +0 -1
  212. package/dist/gateway-context-CXmXtaUP.mjs.map +0 -1
  213. package/dist/guards-DU1_J9YA.mjs.map +0 -1
  214. package/dist/http-method.decorator-BrgHMdLQ.mjs.map +0 -1
  215. package/dist/i18n.module-CzXLW9Hy.mjs.map +0 -1
  216. package/dist/index-Bnpfq6uk.d.mts.map +0 -1
  217. package/dist/index-ByOyTmqf.d.mts.map +0 -1
  218. package/dist/index-C1KvMncZ.d.mts.map +0 -1
  219. package/dist/index-DBd_2wv8.d.mts +0 -263
  220. package/dist/index-DBd_2wv8.d.mts.map +0 -1
  221. package/dist/index-DUzWs0z7.d.mts.map +0 -1
  222. package/dist/index.d.mts.map +0 -1
  223. package/dist/logger-DlV7NtvD.mjs +0 -440
  224. package/dist/logger-DlV7NtvD.mjs.map +0 -1
  225. package/dist/module-BzLg57FK.mjs +0 -866
  226. package/dist/module-BzLg57FK.mjs.map +0 -1
  227. package/dist/openapi-tools.service-Zs-Ewv7F.mjs +0 -200
  228. package/dist/openapi-tools.service-Zs-Ewv7F.mjs.map +0 -1
  229. package/dist/openapi.service-Bt9bCIrd.d.mts.map +0 -1
  230. package/dist/quarry-registry-BwY2hOxm.mjs +0 -699
  231. package/dist/quarry-registry-BwY2hOxm.mjs.map +0 -1
  232. package/dist/queue.module-BhCjZp6H.mjs.map +0 -1
  233. package/dist/r2-storage.provider-DuonKeYm.mjs.map +0 -1
  234. package/dist/rate-limit.decorator-6qzNcSOt.mjs.map +0 -1
  235. package/dist/resend.provider-DB4IlFjG.mjs.map +0 -1
  236. package/dist/seeder-zoEfEw9i.mjs.map +0 -1
  237. package/dist/setup-CefZKV_e.mjs +0 -37
  238. package/dist/setup-CefZKV_e.mjs.map +0 -1
  239. package/dist/smtp.provider-B6D7zuWX.mjs.map +0 -1
  240. package/dist/storage-D8CBP72Z.mjs.map +0 -1
  241. package/dist/storage-provider.interface-Bd6vA4ak.d.mts.map +0 -1
  242. package/dist/stratal-CNwpbSZl.mjs.map +0 -1
  243. package/dist/types-cySNS_lp.d.mts.map +0 -1
  244. package/dist/usage-generator-BUdlhnCK.mjs.map +0 -1
  245. package/dist/validation-DtJwAv7O.mjs +0 -248
  246. package/dist/validation-DtJwAv7O.mjs.map +0 -1
@@ -0,0 +1,775 @@
1
+ import { c as DI_TOKENS, m as inject, o as ROUTER_TOKENS } from "../di-BO1QIb5H.mjs";
2
+ import { n as __decorateParam, t as __decorate } from "../decorate-HgTKAYK8.mjs";
3
+ import "../logger/index.mjs";
4
+ import { f as Module } from "../module-xYoHba6B.mjs";
5
+ import { r as getListenerHandlers } from "../events-D1KdDaiP.mjs";
6
+ import { a as green, n as cyan, o as red, s as yellow, t as bold } from "../colors-axmupKdp.mjs";
7
+ import { t as Command } from "../command-BU4ApTo5.mjs";
8
+ import { t as I18N_TOKENS } from "../i18n.tokens-hwRpmjRq.mjs";
9
+ import { a as OPENAPI_TOKENS, t as OpenApiToolsService } from "../openapi-C6lm0RmV.mjs";
10
+ import { r as CommandNotFoundError } from "../quarry-registry-DkraZNwn.mjs";
11
+ import { t as Stratal } from "../stratal-Bdq4IdB3.mjs";
12
+ import { n as DbSeedListCommand, t as DbSeedCommand } from "../seeder-BADTig4n.mjs";
13
+ import { z } from "zod";
14
+ import { writeFileSync } from "node:fs";
15
+ import { resolve } from "node:path";
16
+ //#region src/quarry/commands/api.command.ts
17
+ let ApiCommand = class ApiCommand extends Command {
18
+ app;
19
+ static command = "api {route?} {--method= : HTTP method} {--data= : JSON request body} {--header=* : Headers (Key:Value)} {--query=* : Query params (key=value)}";
20
+ static description = "Call an API route directly";
21
+ static aliases = ["api:call"];
22
+ constructor(app) {
23
+ super();
24
+ this.app = app;
25
+ }
26
+ async handle() {
27
+ const route = this.string("route");
28
+ if (!route) return (await this.call("route:list")).exitCode;
29
+ return this.callRoute(route);
30
+ }
31
+ async callRoute(route) {
32
+ const method = (this.string("method") || "GET").toUpperCase();
33
+ const data = this.string("data");
34
+ const headerArgs = this.array("header");
35
+ const queryArgs = this.array("query");
36
+ const headers = {};
37
+ if (data) headers["Content-Type"] = "application/json";
38
+ for (const h of headerArgs) {
39
+ const colonIdx = h.indexOf(":");
40
+ if (colonIdx > 0) headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim();
41
+ }
42
+ let url = route;
43
+ if (queryArgs.length > 0) {
44
+ const parts = queryArgs.map((q) => {
45
+ const eqIdx = q.indexOf("=");
46
+ if (eqIdx > 0) return `${encodeURIComponent(q.slice(0, eqIdx))}=${encodeURIComponent(q.slice(eqIdx + 1))}`;
47
+ return encodeURIComponent(q);
48
+ });
49
+ url += `?${parts.join("&")}`;
50
+ }
51
+ const request = new Request(`http://localhost${url}`, {
52
+ method,
53
+ headers,
54
+ body: data || void 0
55
+ });
56
+ const response = await (await this.app.ensureHono()).fetch(request, this.app.env);
57
+ const body = await response.text();
58
+ const statusText = `${response.status} ${response.statusText}`;
59
+ let coloredStatus;
60
+ if (response.status >= 200 && response.status < 300) coloredStatus = green(bold(statusText));
61
+ else if (response.status >= 300 && response.status < 400) coloredStatus = yellow(bold(statusText));
62
+ else coloredStatus = red(bold(statusText));
63
+ this.line(`${cyan(method)} ${route} ${coloredStatus}`);
64
+ this.newLine();
65
+ const headerLines = [];
66
+ response.headers.forEach((value, key) => {
67
+ headerLines.push(` ${key}: ${value}`);
68
+ });
69
+ if (headerLines.length > 0) {
70
+ this.line(bold("Headers:"));
71
+ for (const hl of headerLines) this.line(hl);
72
+ this.newLine();
73
+ }
74
+ if (body) {
75
+ this.line(bold("Body:"));
76
+ try {
77
+ this.line(JSON.stringify(JSON.parse(body), null, 2));
78
+ } catch {
79
+ this.line(body);
80
+ }
81
+ }
82
+ return response.status >= 400 ? 1 : 0;
83
+ }
84
+ };
85
+ ApiCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Application))], ApiCommand);
86
+ //#endregion
87
+ //#region src/quarry/commands/event-list.command.ts
88
+ let EventListCommand = class EventListCommand extends Command {
89
+ modules;
90
+ static command = "event:list";
91
+ static description = "List all registered event listeners";
92
+ constructor(modules) {
93
+ super();
94
+ this.modules = modules;
95
+ }
96
+ handle() {
97
+ const listeners = this.modules.getAllListeners();
98
+ if (listeners.length === 0) {
99
+ this.info("No event listeners found");
100
+ return 0;
101
+ }
102
+ const rows = [];
103
+ for (const ListenerClass of listeners) {
104
+ const handlers = getListenerHandlers(ListenerClass);
105
+ for (const { methodName, event, options } of handlers) rows.push([
106
+ event,
107
+ ListenerClass.name,
108
+ methodName,
109
+ String(options?.priority ?? 0),
110
+ options?.blocking ? "Yes" : "No"
111
+ ]);
112
+ }
113
+ if (rows.length === 0) {
114
+ this.info("No event handlers found");
115
+ return 0;
116
+ }
117
+ this.table([
118
+ "Event",
119
+ "Listener",
120
+ "Method",
121
+ "Priority",
122
+ "Blocking"
123
+ ], rows);
124
+ }
125
+ };
126
+ EventListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.ModuleRegistry))], EventListCommand);
127
+ //#endregion
128
+ //#region src/quarry/commands/help.command.ts
129
+ let HelpCommand = class HelpCommand extends Command {
130
+ quarryRegistry;
131
+ static command = "help {command?}";
132
+ static description = "Show help for a command or list all commands";
133
+ static aliases = ["list"];
134
+ constructor(quarryRegistry) {
135
+ super();
136
+ this.quarryRegistry = quarryRegistry;
137
+ }
138
+ async handle() {
139
+ const commandName = this.string("command");
140
+ if (!commandName) {
141
+ const listing = await this.quarryRegistry.listUsage();
142
+ this.line(listing);
143
+ return 0;
144
+ }
145
+ try {
146
+ const usage = await this.quarryRegistry.usage(commandName);
147
+ this.line(usage);
148
+ return 0;
149
+ } catch (error) {
150
+ if (error instanceof CommandNotFoundError) {
151
+ this.fail(`Unknown command: ${commandName}`);
152
+ return 1;
153
+ }
154
+ throw error;
155
+ }
156
+ }
157
+ };
158
+ HelpCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Quarry))], HelpCommand);
159
+ //#endregion
160
+ //#region src/quarry/commands/i18n-utils.ts
161
+ function computeKeyDiff(baseKeys, targetKeys) {
162
+ const missing = [];
163
+ const extra = [];
164
+ for (const key of baseKeys) if (!targetKeys.has(key)) missing.push(key);
165
+ for (const key of targetKeys) if (!baseKeys.has(key)) extra.push(key);
166
+ return {
167
+ missing: missing.sort(),
168
+ extra: extra.sort()
169
+ };
170
+ }
171
+ function extractNamespace(key, depth) {
172
+ return key.split(".").slice(0, depth).join(".");
173
+ }
174
+ //#endregion
175
+ //#region src/quarry/commands/i18n-check.command.ts
176
+ let I18nCheckCommand = class I18nCheckCommand extends Command {
177
+ loader;
178
+ static command = "i18n:check {--locale= : Check a specific locale only} {--prefix= : Filter by namespace prefix}";
179
+ static description = "Check i18n translations for missing or extra keys";
180
+ constructor(loader) {
181
+ super();
182
+ this.loader = loader;
183
+ }
184
+ handle() {
185
+ const localeFilter = this.string("locale");
186
+ const prefix = this.string("prefix");
187
+ const filterOptions = prefix ? { only: [prefix] } : void 0;
188
+ const enKeys = new Set(Object.keys(this.loader.getFilteredMessages("en", filterOptions)));
189
+ if (enKeys.size === 0) {
190
+ this.info("No message keys found");
191
+ return 0;
192
+ }
193
+ const locales = this.loader.getAvailableLocales().filter((l) => l !== "en");
194
+ const targets = localeFilter ? locales.filter((l) => l === localeFilter) : locales;
195
+ if (targets.length === 0) {
196
+ this.info(localeFilter ? `Locale "${localeFilter}" not found` : "No non-en locales configured");
197
+ return 0;
198
+ }
199
+ let totalIssues = 0;
200
+ const summaryRows = [];
201
+ for (const locale of targets) {
202
+ const { missing, extra } = computeKeyDiff(enKeys, new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions))));
203
+ this.newLine();
204
+ this.info(`Locale: ${locale}`);
205
+ if (missing.length > 0) {
206
+ this.warn(` Missing (${missing.length}):`);
207
+ for (const key of missing) this.line(` ${key}`);
208
+ } else this.line(" Missing (0)");
209
+ if (extra.length > 0) {
210
+ this.warn(` Extra (${extra.length}):`);
211
+ for (const key of extra) this.line(` ${key}`);
212
+ } else this.line(" Extra (0)");
213
+ totalIssues += missing.length + extra.length;
214
+ summaryRows.push([
215
+ locale,
216
+ String(enKeys.size),
217
+ String(missing.length),
218
+ String(extra.length)
219
+ ]);
220
+ }
221
+ this.newLine();
222
+ this.table([
223
+ "Locale",
224
+ "Total",
225
+ "Missing",
226
+ "Extra"
227
+ ], summaryRows);
228
+ if (totalIssues > 0) {
229
+ this.newLine();
230
+ this.fail(`${totalIssues} issue(s) found`);
231
+ return;
232
+ }
233
+ this.newLine();
234
+ this.success("All translations are complete");
235
+ return 0;
236
+ }
237
+ };
238
+ I18nCheckCommand = __decorate([__decorateParam(0, inject(I18N_TOKENS.MessageLoader))], I18nCheckCommand);
239
+ //#endregion
240
+ //#region src/quarry/commands/i18n-duplicates.command.ts
241
+ let I18nDuplicatesCommand = class I18nDuplicatesCommand extends Command {
242
+ loader;
243
+ static command = "i18n:duplicates {--locale= : Locale to check (default: en)} {--prefix= : Filter by namespace prefix}";
244
+ static description = "Find i18n keys with duplicate translation values";
245
+ constructor(loader) {
246
+ super();
247
+ this.loader = loader;
248
+ }
249
+ handle() {
250
+ const locale = this.string("locale") || "en";
251
+ const prefix = this.string("prefix");
252
+ const filterOptions = prefix ? { only: [prefix] } : void 0;
253
+ const messages = this.loader.getFilteredMessages(locale, filterOptions);
254
+ const valueToKeys = /* @__PURE__ */ new Map();
255
+ for (const [key, value] of Object.entries(messages)) {
256
+ const existing = valueToKeys.get(value);
257
+ if (existing) existing.push(key);
258
+ else valueToKeys.set(value, [key]);
259
+ }
260
+ const duplicates = [];
261
+ for (const [value, keys] of valueToKeys) if (keys.length > 1) duplicates.push([value, keys.sort().join(", ")]);
262
+ if (duplicates.length === 0) {
263
+ this.info("No duplicate values found");
264
+ return 0;
265
+ }
266
+ duplicates.sort((a, b) => a[0].localeCompare(b[0]));
267
+ this.table(["Value", "Keys"], duplicates);
268
+ return 0;
269
+ }
270
+ };
271
+ I18nDuplicatesCommand = __decorate([__decorateParam(0, inject(I18N_TOKENS.MessageLoader))], I18nDuplicatesCommand);
272
+ //#endregion
273
+ //#region src/quarry/commands/i18n-list.command.ts
274
+ let I18nListCommand = class I18nListCommand extends Command {
275
+ loader;
276
+ static command = "i18n:list {--locale= : Show keys for a specific locale} {--prefix= : Filter by namespace prefix} {--values : Show translated values}";
277
+ static description = "List all i18n message keys";
278
+ constructor(loader) {
279
+ super();
280
+ this.loader = loader;
281
+ }
282
+ handle() {
283
+ const localeFilter = this.string("locale");
284
+ const prefix = this.string("prefix");
285
+ const showValues = this.boolean("values");
286
+ const filterOptions = prefix ? { only: [prefix] } : void 0;
287
+ const enMessages = this.loader.getFilteredMessages("en", filterOptions);
288
+ const enKeys = Object.keys(enMessages).sort();
289
+ if (enKeys.length === 0) {
290
+ this.info("No message keys found");
291
+ return 0;
292
+ }
293
+ if (localeFilter && showValues) {
294
+ const localeMessages = this.loader.getFilteredMessages(localeFilter, filterOptions);
295
+ const rows = enKeys.map((key) => [key, localeMessages[key] ?? "-"]);
296
+ this.table(["Key", "Value"], rows);
297
+ return 0;
298
+ }
299
+ const locales = localeFilter ? [localeFilter] : this.loader.getAvailableLocales();
300
+ const localeMessages = /* @__PURE__ */ new Map();
301
+ for (const locale of locales) localeMessages.set(locale, new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions))));
302
+ const headers = ["Key", ...locales];
303
+ const rows = enKeys.map((key) => {
304
+ return [key, ...locales.map((locale) => localeMessages.get(locale).has(key) ? "Y" : "N")];
305
+ });
306
+ this.table(headers, rows);
307
+ return 0;
308
+ }
309
+ };
310
+ I18nListCommand = __decorate([__decorateParam(0, inject(I18N_TOKENS.MessageLoader))], I18nListCommand);
311
+ //#endregion
312
+ //#region src/quarry/commands/i18n-namespaces.command.ts
313
+ let I18nNamespacesCommand = class I18nNamespacesCommand extends Command {
314
+ loader;
315
+ static command = "i18n:namespaces {--depth= : Namespace depth (default: 1)} {--locale= : Show counts for a specific locale}";
316
+ static description = "List i18n message namespaces with key counts";
317
+ constructor(loader) {
318
+ super();
319
+ this.loader = loader;
320
+ }
321
+ handle() {
322
+ const depth = this.number("depth") || 1;
323
+ const localeFilter = this.string("locale");
324
+ const locales = localeFilter ? [localeFilter] : this.loader.getAvailableLocales();
325
+ const namespaceCounts = /* @__PURE__ */ new Map();
326
+ for (const locale of locales) {
327
+ const messages = this.loader.getFilteredMessages(locale);
328
+ for (const key of Object.keys(messages)) {
329
+ const ns = extractNamespace(key, depth);
330
+ if (!namespaceCounts.has(ns)) namespaceCounts.set(ns, /* @__PURE__ */ new Map());
331
+ const counts = namespaceCounts.get(ns);
332
+ counts.set(locale, (counts.get(locale) ?? 0) + 1);
333
+ }
334
+ }
335
+ if (namespaceCounts.size === 0) {
336
+ this.info("No namespaces found");
337
+ return 0;
338
+ }
339
+ const sortedNamespaces = [...namespaceCounts.keys()].sort();
340
+ const headers = ["Namespace", ...locales];
341
+ const rows = sortedNamespaces.map((ns) => {
342
+ const counts = namespaceCounts.get(ns);
343
+ return [ns, ...locales.map((locale) => String(counts.get(locale) ?? 0))];
344
+ });
345
+ this.table(headers, rows);
346
+ return 0;
347
+ }
348
+ };
349
+ I18nNamespacesCommand = __decorate([__decorateParam(0, inject(I18N_TOKENS.MessageLoader))], I18nNamespacesCommand);
350
+ //#endregion
351
+ //#region src/quarry/commands/i18n-search.command.ts
352
+ let I18nSearchCommand = class I18nSearchCommand extends Command {
353
+ loader;
354
+ static command = "i18n:search {query : Search term (substring match)} {--locale= : Locale to search in (default: en)} {--keys-only : Only match key names, not values}";
355
+ static description = "Search for i18n message keys or values";
356
+ constructor(loader) {
357
+ super();
358
+ this.loader = loader;
359
+ }
360
+ handle() {
361
+ const query = this.string("query").toLowerCase();
362
+ const locale = this.string("locale") || "en";
363
+ const keysOnly = this.boolean("keys-only");
364
+ const messages = this.loader.getFilteredMessages(locale);
365
+ const matches = [];
366
+ for (const [key, value] of Object.entries(messages)) {
367
+ const keyMatch = key.toLowerCase().includes(query);
368
+ const valueMatch = !keysOnly && value.toLowerCase().includes(query);
369
+ if (keyMatch || valueMatch) matches.push([key, value]);
370
+ }
371
+ if (matches.length === 0) {
372
+ this.info(`No keys matching "${this.string("query")}" found`);
373
+ return 0;
374
+ }
375
+ matches.sort((a, b) => a[0].localeCompare(b[0]));
376
+ this.table(["Key", "Value"], matches);
377
+ return 0;
378
+ }
379
+ };
380
+ I18nSearchCommand = __decorate([__decorateParam(0, inject(I18N_TOKENS.MessageLoader))], I18nSearchCommand);
381
+ //#endregion
382
+ //#region src/quarry/commands/i18n-stats.command.ts
383
+ let I18nStatsCommand = class I18nStatsCommand extends Command {
384
+ loader;
385
+ static command = "i18n:stats {--prefix= : Filter by namespace prefix}";
386
+ static description = "Show i18n translation coverage statistics";
387
+ constructor(loader) {
388
+ super();
389
+ this.loader = loader;
390
+ }
391
+ handle() {
392
+ const prefix = this.string("prefix");
393
+ const filterOptions = prefix ? { only: [prefix] } : void 0;
394
+ const enKeys = new Set(Object.keys(this.loader.getFilteredMessages("en", filterOptions)));
395
+ if (enKeys.size === 0) {
396
+ this.info("No message keys found");
397
+ return 0;
398
+ }
399
+ const locales = this.loader.getAvailableLocales();
400
+ const rows = [];
401
+ for (const locale of locales) {
402
+ const localeKeys = new Set(Object.keys(this.loader.getFilteredMessages(locale, filterOptions)));
403
+ const isBase = locale === "en";
404
+ let translated = 0;
405
+ for (const key of enKeys) if (localeKeys.has(key)) translated++;
406
+ const missing = enKeys.size - translated;
407
+ let extra = 0;
408
+ for (const key of localeKeys) if (!enKeys.has(key)) extra++;
409
+ const coverage = (translated / enKeys.size * 100).toFixed(1) + "%";
410
+ rows.push([
411
+ locale,
412
+ String(enKeys.size),
413
+ String(translated),
414
+ String(missing),
415
+ isBase ? "-" : String(extra),
416
+ coverage
417
+ ]);
418
+ }
419
+ this.table([
420
+ "Locale",
421
+ "Keys",
422
+ "Translated",
423
+ "Missing",
424
+ "Extra",
425
+ "Coverage"
426
+ ], rows);
427
+ return 0;
428
+ }
429
+ };
430
+ I18nStatsCommand = __decorate([__decorateParam(0, inject(I18N_TOKENS.MessageLoader))], I18nStatsCommand);
431
+ //#endregion
432
+ //#region src/quarry/commands/mcp-serve.command.ts
433
+ let McpServeCommand = class McpServeCommand extends Command {
434
+ app;
435
+ openAPIService;
436
+ 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}";
437
+ static description = "Start an MCP stdio server exposing API routes as tools";
438
+ constructor(app, openAPIService) {
439
+ super();
440
+ this.app = app;
441
+ this.openAPIService = openAPIService;
442
+ }
443
+ async handle() {
444
+ const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
445
+ const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
446
+ const baseUrl = this.string("url");
447
+ const headerArgs = this.array("header");
448
+ const tags = this.array("tag");
449
+ const pathPrefix = this.string("path");
450
+ const headers = {};
451
+ for (const h of headerArgs) {
452
+ const colonIdx = h.indexOf(":");
453
+ if (colonIdx > 0) headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim();
454
+ }
455
+ const hono = await this.app.ensureHono();
456
+ const spec = this.openAPIService.getSpec(hono, this.app.container);
457
+ const service = new OpenApiToolsService(spec, { dispatcher: baseUrl ? async (method, url, opts) => {
458
+ const fullUrl = `${baseUrl}${url}`;
459
+ try {
460
+ return await fetch(fullUrl, {
461
+ method,
462
+ headers: {
463
+ "Content-Type": "application/json",
464
+ ...headers,
465
+ ...opts?.headers
466
+ },
467
+ body: opts?.body !== void 0 ? JSON.stringify(opts.body) : void 0
468
+ });
469
+ } catch (error) {
470
+ throw new Error(`MCP dispatch failed: ${method} ${fullUrl} — ${error instanceof Error ? error.message : String(error)}`, { cause: error });
471
+ }
472
+ } : async (method, url, opts) => {
473
+ const request = new Request(`http://localhost${url}`, {
474
+ method,
475
+ headers: {
476
+ "Content-Type": "application/json",
477
+ ...headers,
478
+ ...opts?.headers
479
+ },
480
+ body: opts?.body !== void 0 ? JSON.stringify(opts.body) : void 0
481
+ });
482
+ try {
483
+ return await hono.fetch(request, this.app.env);
484
+ } catch (error) {
485
+ throw new Error(`MCP dispatch failed: ${method} ${url} — ${error instanceof Error ? error.message : String(error)}`, { cause: error });
486
+ }
487
+ } });
488
+ const filter = {
489
+ tags: tags.length > 0 ? tags : void 0,
490
+ pathPrefix: pathPrefix || void 0
491
+ };
492
+ const tools = service.getTools(filter);
493
+ const config = this.app.container.resolve(OPENAPI_TOKENS.ConfigService).getEffectiveConfig();
494
+ const server = new McpServer({
495
+ name: config.info.title,
496
+ version: config.info.version
497
+ });
498
+ for (const tool of tools) {
499
+ const inputSchema = z.fromJSONSchema(tool.inputSchema);
500
+ server.registerTool(tool.name, {
501
+ description: tool.description,
502
+ inputSchema
503
+ }, async (args) => {
504
+ const result = await service.executeTool(tool.name, args);
505
+ return { content: [{
506
+ type: "text",
507
+ text: `Status: ${result.status}\n\n${result.body}`
508
+ }] };
509
+ });
510
+ }
511
+ server.registerResource("openapi-spec", "openapi://spec", {
512
+ description: "Full OpenAPI specification",
513
+ mimeType: "application/json"
514
+ }, () => ({ contents: [{
515
+ uri: "openapi://spec",
516
+ mimeType: "application/json",
517
+ text: JSON.stringify(spec, null, 2)
518
+ }] }));
519
+ const transport = new StdioServerTransport();
520
+ const closed = new Promise((resolve) => {
521
+ transport.onclose = resolve;
522
+ });
523
+ await server.connect(transport);
524
+ process.stderr.write(`MCP server started with ${tools.length} tool(s)\n`);
525
+ await closed;
526
+ return 0;
527
+ }
528
+ };
529
+ McpServeCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Application)), __decorateParam(1, inject(OPENAPI_TOKENS.OpenAPIService))], McpServeCommand);
530
+ //#endregion
531
+ //#region src/quarry/commands/mcp-tools.command.ts
532
+ let McpToolsCommand = class McpToolsCommand extends Command {
533
+ app;
534
+ openAPIService;
535
+ static command = "mcp:tools {--tag=* : Filter by OpenAPI tags} {--path= : Filter by path prefix}";
536
+ static description = "List API routes that would be exposed as MCP tools";
537
+ constructor(app, openAPIService) {
538
+ super();
539
+ this.app = app;
540
+ this.openAPIService = openAPIService;
541
+ }
542
+ async handle() {
543
+ const tags = this.array("tag");
544
+ const pathPrefix = this.string("path");
545
+ const hono = await this.app.ensureHono();
546
+ const service = new OpenApiToolsService(this.openAPIService.getSpec(hono, this.app.container));
547
+ const filter = {
548
+ tags: tags.length > 0 ? tags : void 0,
549
+ pathPrefix: pathPrefix || void 0
550
+ };
551
+ const tools = service.getTools(filter);
552
+ if (tools.length === 0) {
553
+ this.info("No tools found");
554
+ return 0;
555
+ }
556
+ this.table([
557
+ "Name",
558
+ "Method",
559
+ "Path",
560
+ "Description"
561
+ ], tools.map((t) => [
562
+ t.name,
563
+ t.method,
564
+ t.path,
565
+ t.description
566
+ ]));
567
+ return 0;
568
+ }
569
+ };
570
+ McpToolsCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Application)), __decorateParam(1, inject(OPENAPI_TOKENS.OpenAPIService))], McpToolsCommand);
571
+ //#endregion
572
+ //#region src/quarry/commands/queue-list.command.ts
573
+ let QueueListCommand = class QueueListCommand extends Command {
574
+ consumers;
575
+ static command = "queue:list";
576
+ static description = "List all registered queue consumers";
577
+ constructor(consumers) {
578
+ super();
579
+ this.consumers = consumers;
580
+ }
581
+ handle() {
582
+ const consumers = this.consumers.getAllConsumers();
583
+ if (consumers.length === 0) {
584
+ this.info("No queue consumers found");
585
+ return 0;
586
+ }
587
+ this.table(["Consumer", "Message Types"], consumers.map((c) => [c.constructor.name, c.messageTypes.join(", ")]));
588
+ }
589
+ };
590
+ QueueListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.ConsumerRegistry))], QueueListCommand);
591
+ //#endregion
592
+ //#region src/quarry/commands/route-list.command.ts
593
+ let RouteListCommand = class RouteListCommand extends Command {
594
+ registry;
595
+ static command = "route:list {--method= : Filter by HTTP method} {--path= : Filter by path substring} {--name= : Filter by route name} {--hidden : Include hidden routes}";
596
+ static description = "List all registered routes";
597
+ constructor(registry) {
598
+ super();
599
+ this.registry = registry;
600
+ }
601
+ handle() {
602
+ const methodFilter = this.string("method").toUpperCase();
603
+ const pathFilter = this.string("path");
604
+ const nameFilter = this.string("name");
605
+ const showHidden = this.boolean("hidden");
606
+ let routes = this.registry.all();
607
+ if (!showHidden) routes = routes.filter((r) => !r.hidden);
608
+ if (methodFilter) routes = routes.filter((r) => r.method.toUpperCase() === methodFilter);
609
+ if (pathFilter) routes = routes.filter((r) => r.path.includes(pathFilter));
610
+ if (nameFilter) routes = routes.filter((r) => r.name?.includes(nameFilter));
611
+ if (routes.length === 0) {
612
+ this.info("No routes found");
613
+ return 0;
614
+ }
615
+ this.table([
616
+ "Method",
617
+ "Path",
618
+ "Name",
619
+ "Handler",
620
+ "Domain"
621
+ ], routes.map((r) => this.formatRow(r)));
622
+ }
623
+ formatRow(route) {
624
+ return [
625
+ route.method.toUpperCase(),
626
+ route.path,
627
+ route.name ?? "-",
628
+ `${route.controller}.${route.action}`,
629
+ route.domain ?? "-"
630
+ ];
631
+ }
632
+ };
633
+ RouteListCommand = __decorate([__decorateParam(0, inject(ROUTER_TOKENS.RouteRegistry))], RouteListCommand);
634
+ //#endregion
635
+ //#region src/quarry/commands/route-types.command.ts
636
+ let RouteTypesCommand = class RouteTypesCommand extends Command {
637
+ registry;
638
+ localePathService;
639
+ static command = "route:types {--output=src/stratal.d.ts : Output file path}";
640
+ static description = "Generate TypeScript types for named routes";
641
+ constructor(registry, localePathService) {
642
+ super();
643
+ this.registry = registry;
644
+ this.localePathService = localePathService;
645
+ }
646
+ handle() {
647
+ const outputPath = resolve(this.string("output") || "src/stratal.d.ts");
648
+ const namedRoutes = this.registry.named();
649
+ if (namedRoutes.length === 0) {
650
+ this.warn("No named routes found. Add name to your @Route() or @Get()/@Post() decorators.");
651
+ return 0;
652
+ }
653
+ writeFileSync(outputPath, this.generateDeclaration(namedRoutes), "utf-8");
654
+ this.info(`Generated route types for ${namedRoutes.length} named routes → ${outputPath}`);
655
+ }
656
+ /**
657
+ * Generate the StratalRouteMap declaration content.
658
+ */
659
+ generateDeclaration(routes) {
660
+ const localeConfig = this.localePathService.enabled ? this.localePathService.localePathConfig : null;
661
+ const localeType = localeConfig ? localeConfig.allLocales.map((l) => `'${l}'`).join(" | ") : null;
662
+ const localeOptional = localeConfig ? this.localePathService.prefixDefaultLocale !== true : false;
663
+ const entries = routes.filter((r) => r.name !== void 0).sort((a, b) => a.name.localeCompare(b.name)).map((route) => {
664
+ const paramEntries = [...route.paramNames.map((p) => `${p}: string`), ...route.domainParamNames.map((p) => `${p}: string`)];
665
+ if (localeType && route.localePaths?.length) {
666
+ const optionalMarker = localeOptional ? "?" : "";
667
+ paramEntries.push(`locale${optionalMarker}: StratalLocale`);
668
+ }
669
+ const indexSignature = localeType && route.localePaths?.length ? "[key: string]: string | StratalLocale | undefined" : "[key: string]: string | undefined";
670
+ paramEntries.push(indexSignature);
671
+ const paramsType = `{ ${paramEntries.join("; ")} }`;
672
+ return ` '${route.name}': { params: ${paramsType} }`;
673
+ }).join("\n");
674
+ const lines = ["// Auto-generated by `quarry route:types` — do not edit manually", "declare module 'stratal/router' {"];
675
+ if (localeType) {
676
+ lines.push(` type StratalLocale = ${localeType}`);
677
+ lines.push("");
678
+ }
679
+ lines.push(" interface StratalRouteMap {", entries, " }", "}");
680
+ return [
681
+ ...lines,
682
+ "",
683
+ "export {}",
684
+ ""
685
+ ].join("\n");
686
+ }
687
+ };
688
+ RouteTypesCommand = __decorate([__decorateParam(0, inject(ROUTER_TOKENS.RouteRegistry)), __decorateParam(1, inject(ROUTER_TOKENS.LocalePathService))], RouteTypesCommand);
689
+ //#endregion
690
+ //#region src/quarry/commands/schedule-list.command.ts
691
+ let ScheduleListCommand = class ScheduleListCommand extends Command {
692
+ cron;
693
+ static command = "schedule:list";
694
+ static description = "List all registered cron jobs";
695
+ constructor(cron) {
696
+ super();
697
+ this.cron = cron;
698
+ }
699
+ handle() {
700
+ const schedules = this.cron.getAllSchedules();
701
+ if (schedules.length === 0) {
702
+ this.info("No cron jobs found");
703
+ return 0;
704
+ }
705
+ const rows = [];
706
+ for (const schedule of schedules) {
707
+ const jobs = this.cron.getJobsForSchedule(schedule);
708
+ for (const { jobClass } of jobs) rows.push([schedule, jobClass.name]);
709
+ }
710
+ this.table(["Schedule", "Job"], rows);
711
+ }
712
+ };
713
+ ScheduleListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Cron))], ScheduleListCommand);
714
+ //#endregion
715
+ //#region src/quarry/builtin-quarry.module.ts
716
+ let BuiltinQuarryModule = class BuiltinQuarryModule {};
717
+ BuiltinQuarryModule = __decorate([Module({ providers: [
718
+ HelpCommand,
719
+ DbSeedCommand,
720
+ DbSeedListCommand,
721
+ RouteListCommand,
722
+ RouteTypesCommand,
723
+ EventListCommand,
724
+ ScheduleListCommand,
725
+ QueueListCommand,
726
+ McpServeCommand,
727
+ McpToolsCommand,
728
+ ApiCommand,
729
+ I18nCheckCommand,
730
+ I18nDuplicatesCommand,
731
+ I18nListCommand,
732
+ I18nNamespacesCommand,
733
+ I18nSearchCommand,
734
+ I18nStatsCommand
735
+ ] })], BuiltinQuarryModule);
736
+ //#endregion
737
+ //#region src/quarry/quarry-runner.ts
738
+ /**
739
+ * Builds a `Stratal` instance for the quarry CLI entry (`src/quarry.ts`).
740
+ *
741
+ * Synthesizes a wrapper module from the given `imports` and `providers`,
742
+ * so CLI-only classes (seeders, ecosystem CLI commands) stay out of the
743
+ * worker bundle — `src/index.ts` doesn't reference any of them. Forces
744
+ * CLI-friendly logging defaults (`level: 'error'`, `formatter: 'pretty'`).
745
+ *
746
+ * @example
747
+ * ```ts
748
+ * // src/quarry.ts
749
+ * export default QuarryRunner.run({
750
+ * imports: [AppModule, InertiaQuarryModule],
751
+ * providers: [GeoSeeder, DemoSeeder],
752
+ * })
753
+ * ```
754
+ */
755
+ var QuarryRunner = class {
756
+ static run(options) {
757
+ let QuarryEntryModule = class QuarryEntryModule {};
758
+ QuarryEntryModule = __decorate([Module({
759
+ imports: [BuiltinQuarryModule, ...options.imports],
760
+ providers: options.providers ?? []
761
+ })], QuarryEntryModule);
762
+ return new Stratal({
763
+ module: QuarryEntryModule,
764
+ exceptionHandler: options.exceptionHandler,
765
+ logging: {
766
+ level: "error",
767
+ formatter: "pretty"
768
+ }
769
+ });
770
+ }
771
+ };
772
+ //#endregion
773
+ export { ApiCommand, BuiltinQuarryModule, EventListCommand, HelpCommand, McpServeCommand, McpToolsCommand, QuarryRunner, QueueListCommand, RouteListCommand, RouteTypesCommand, ScheduleListCommand };
774
+
775
+ //# sourceMappingURL=runner.mjs.map