stratal 0.0.16 → 0.0.17

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 (145) hide show
  1. package/README.md +4 -0
  2. package/dist/{application-zG8b-pol.d.mts → application-DfPtIzxF.d.mts} +65 -4
  3. package/dist/application-DfPtIzxF.d.mts.map +1 -0
  4. package/dist/{base-email.provider-Cuw4OAB0.mjs → base-email.provider-DypUAfWm.mjs} +1 -1
  5. package/dist/{base-email.provider-Cuw4OAB0.mjs.map → base-email.provider-DypUAfWm.mjs.map} +1 -1
  6. package/dist/bin/cloudflare-workers-loader.mjs +0 -0
  7. package/dist/bin/quarry.mjs +1 -50
  8. package/dist/bin/quarry.mjs.map +1 -1
  9. package/dist/cache/index.d.mts +1 -1
  10. package/dist/cache/index.mjs +10 -11
  11. package/dist/cache/index.mjs.map +1 -1
  12. package/dist/{colors-DJaRDXoS.mjs → colors-Y7WIFXs7.mjs} +1 -1
  13. package/dist/{colors-DJaRDXoS.mjs.map → colors-Y7WIFXs7.mjs.map} +1 -1
  14. package/dist/{command-BvCOD6df.mjs → command-B1CPgsrU.mjs} +6 -3
  15. package/dist/{command-BvCOD6df.mjs.map → command-B1CPgsrU.mjs.map} +1 -1
  16. package/dist/{command-B-QH-Vu3.d.mts → command-TnkPYWta.d.mts} +2 -2
  17. package/dist/{command-B-QH-Vu3.d.mts.map → command-TnkPYWta.d.mts.map} +1 -1
  18. package/dist/config/index.d.mts +2 -2
  19. package/dist/config/index.mjs +10 -11
  20. package/dist/config/index.mjs.map +1 -1
  21. package/dist/consumer-registry-Bymm6ff4.d.mts +142 -0
  22. package/dist/consumer-registry-Bymm6ff4.d.mts.map +1 -0
  23. package/dist/cron/index.d.mts +3 -116
  24. package/dist/cron/index.d.mts.map +1 -1
  25. package/dist/cron/index.mjs +3 -4
  26. package/dist/{cron-manager-DR7fiG6o.mjs → cron-manager-CFBamKKk.mjs} +3 -3
  27. package/dist/{cron-manager-DR7fiG6o.mjs.map → cron-manager-CFBamKKk.mjs.map} +1 -1
  28. package/dist/cron-manager-D7imGwUT.d.mts +117 -0
  29. package/dist/cron-manager-D7imGwUT.d.mts.map +1 -0
  30. package/dist/di/index.d.mts +1 -1
  31. package/dist/di/index.mjs +2 -3
  32. package/dist/email/index.d.mts +3 -3
  33. package/dist/email/index.mjs +16 -17
  34. package/dist/email/index.mjs.map +1 -1
  35. package/dist/errors/index.d.mts +1 -1
  36. package/dist/errors/index.mjs +2 -3
  37. package/dist/{errors-CtCi1wn6.mjs → errors-DSKapqD8.mjs} +4 -4
  38. package/dist/{errors-CtCi1wn6.mjs.map → errors-DSKapqD8.mjs.map} +1 -1
  39. package/dist/{errors-H3TZnVeX.mjs → errors-DuAR5Wke.mjs} +2 -2
  40. package/dist/{errors-H3TZnVeX.mjs.map → errors-DuAR5Wke.mjs.map} +1 -1
  41. package/dist/events/index.mjs +2 -3
  42. package/dist/{events-CXl-o1Ad.mjs → events-CvUSgEuN.mjs} +2 -3
  43. package/dist/{events-CXl-o1Ad.mjs.map → events-CvUSgEuN.mjs.map} +1 -1
  44. package/dist/{gateway-context-BkZ4UKaX.mjs → gateway-context-CNOLkLUC.mjs} +4 -4
  45. package/dist/{gateway-context-BkZ4UKaX.mjs.map → gateway-context-CNOLkLUC.mjs.map} +1 -1
  46. package/dist/guards/index.d.mts +1 -1
  47. package/dist/i18n/index.d.mts +3 -3
  48. package/dist/i18n/index.mjs +15 -15
  49. package/dist/i18n/validation/index.d.mts +1 -1
  50. package/dist/i18n/validation/index.mjs +1 -1
  51. package/dist/{i18n.module-W8OJxg3d.mjs → i18n.module-Dn9SrFdS.mjs} +210 -160
  52. package/dist/i18n.module-Dn9SrFdS.mjs.map +1 -0
  53. package/dist/{index-BJWm863C.d.mts → index-BFCxSp_f.d.mts} +82 -73
  54. package/dist/index-BFCxSp_f.d.mts.map +1 -0
  55. package/dist/{index-D9iYu2Yc.d.mts → index-DGRe6Yoa.d.mts} +5 -144
  56. package/dist/index-DGRe6Yoa.d.mts.map +1 -0
  57. package/dist/{index-DVhdhLvE.d.mts → index-NGxg-KP_.d.mts} +4 -4
  58. package/dist/{index-DVhdhLvE.d.mts.map → index-NGxg-KP_.d.mts.map} +1 -1
  59. package/dist/index.d.mts +2 -2
  60. package/dist/index.mjs +19 -19
  61. package/dist/{is-command-BfCgWAcQ.mjs → is-command-DJVI6wEJ.mjs} +2 -2
  62. package/dist/{is-command-BfCgWAcQ.mjs.map → is-command-DJVI6wEJ.mjs.map} +1 -1
  63. package/dist/{is-seeder-CebjZCDn.mjs → is-seeder-D5MIEcdz.mjs} +1 -1
  64. package/dist/{is-seeder-CebjZCDn.mjs.map → is-seeder-D5MIEcdz.mjs.map} +1 -1
  65. package/dist/logger/index.mjs +1 -2
  66. package/dist/{logger-BR1-s1Um.mjs → logger-CGT91VY6.mjs} +170 -4
  67. package/dist/logger-CGT91VY6.mjs.map +1 -0
  68. package/dist/middleware/index.d.mts +1 -1
  69. package/dist/middleware/index.mjs +4 -5
  70. package/dist/{middleware-C0Ebzswy.mjs → middleware-Bl-b5pkt.mjs} +3 -3
  71. package/dist/{middleware-C0Ebzswy.mjs.map → middleware-Bl-b5pkt.mjs.map} +1 -1
  72. package/dist/module/index.d.mts +2 -117
  73. package/dist/module/index.d.mts.map +1 -1
  74. package/dist/module/index.mjs +10 -11
  75. package/dist/module-registry-CmjBX6ol.d.mts +121 -0
  76. package/dist/module-registry-CmjBX6ol.d.mts.map +1 -0
  77. package/dist/{module-BgdxxzBe.mjs → module-tUtyVJ5E.mjs} +9 -8
  78. package/dist/module-tUtyVJ5E.mjs.map +1 -0
  79. package/dist/openapi/index.d.mts +54 -54
  80. package/dist/openapi/index.d.mts.map +1 -1
  81. package/dist/openapi/index.mjs +15 -15
  82. package/dist/openapi-tools.service-B3TxYKoQ.mjs +197 -0
  83. package/dist/openapi-tools.service-B3TxYKoQ.mjs.map +1 -0
  84. package/dist/openapi.service-DGnX3Fc4.d.mts +58 -0
  85. package/dist/openapi.service-DGnX3Fc4.d.mts.map +1 -0
  86. package/dist/quarry/index.d.mts +109 -28
  87. package/dist/quarry/index.d.mts.map +1 -1
  88. package/dist/quarry/index.mjs +9 -7
  89. package/dist/quarry-registry-B2rkO-JS.mjs +683 -0
  90. package/dist/quarry-registry-B2rkO-JS.mjs.map +1 -0
  91. package/dist/queue/index.d.mts +2 -1
  92. package/dist/queue/index.mjs +11 -12
  93. package/dist/queue/index.mjs.map +1 -1
  94. package/dist/{queue.module-BZvmeAMj.mjs → queue.module-BtI8f4Jo.mjs} +4 -4
  95. package/dist/{queue.module-BZvmeAMj.mjs.map → queue.module-BtI8f4Jo.mjs.map} +1 -1
  96. package/dist/{resend.provider-BCCACQAU.mjs → resend.provider-bXMEkdRJ.mjs} +4 -5
  97. package/dist/{resend.provider-BCCACQAU.mjs.map → resend.provider-bXMEkdRJ.mjs.map} +1 -1
  98. package/dist/router/index.d.mts +1 -1
  99. package/dist/router/index.mjs +14 -14
  100. package/dist/{router-context-BEJe9HEB.mjs → router-context-D9R1v2Ac.mjs} +7 -4
  101. package/dist/router-context-D9R1v2Ac.mjs.map +1 -0
  102. package/dist/{s3-storage.provider-BLlzQYiJ.mjs → s3-storage.provider-CttzNnDR.mjs} +5 -6
  103. package/dist/{s3-storage.provider-BLlzQYiJ.mjs.map → s3-storage.provider-CttzNnDR.mjs.map} +1 -1
  104. package/dist/seeder/index.d.mts +3 -3
  105. package/dist/seeder/index.mjs +6 -7
  106. package/dist/{seeder-Cupi5jl-.mjs → seeder-R7RXJC35.mjs} +20 -17
  107. package/dist/seeder-R7RXJC35.mjs.map +1 -0
  108. package/dist/{smtp.provider-B8XtOcHU.mjs → smtp.provider-DrbHQztF.mjs} +4 -5
  109. package/dist/{smtp.provider-B8XtOcHU.mjs.map → smtp.provider-DrbHQztF.mjs.map} +1 -1
  110. package/dist/storage/index.d.mts +2 -195
  111. package/dist/storage/index.d.mts.map +1 -1
  112. package/dist/storage/index.mjs +13 -14
  113. package/dist/storage/providers/index.d.mts +272 -0
  114. package/dist/storage/providers/index.d.mts.map +1 -0
  115. package/dist/storage/providers/index.mjs +5 -0
  116. package/dist/{storage-By_ow2o_.mjs → storage-CZKHOhci.mjs} +7 -7
  117. package/dist/{storage-By_ow2o_.mjs.map → storage-CZKHOhci.mjs.map} +1 -1
  118. package/dist/storage-provider.interface-0IqcdhBf.d.mts +197 -0
  119. package/dist/storage-provider.interface-0IqcdhBf.d.mts.map +1 -0
  120. package/dist/{stratal-CE0iTz4f.mjs → stratal-D5smIU1y.mjs} +22 -12
  121. package/dist/stratal-D5smIU1y.mjs.map +1 -0
  122. package/dist/{usage-generator-C9hWziY4.mjs → usage-generator-CVIsENuE.mjs} +2 -2
  123. package/dist/{usage-generator-C9hWziY4.mjs.map → usage-generator-CVIsENuE.mjs.map} +1 -1
  124. package/dist/{validation-Bh875Lyg.mjs → validation-DQTC259A.mjs} +4 -4
  125. package/dist/{validation-Bh875Lyg.mjs.map → validation-DQTC259A.mjs.map} +1 -1
  126. package/dist/websocket/index.d.mts +1 -1
  127. package/dist/websocket/index.mjs +4 -5
  128. package/dist/workers/index.d.mts +1 -1
  129. package/dist/workers/index.mjs +19 -19
  130. package/package.json +13 -8
  131. package/dist/application-zG8b-pol.d.mts.map +0 -1
  132. package/dist/decorate-D5j-d9_z.mjs +0 -171
  133. package/dist/decorate-D5j-d9_z.mjs.map +0 -1
  134. package/dist/i18n.module-W8OJxg3d.mjs.map +0 -1
  135. package/dist/index-BJWm863C.d.mts.map +0 -1
  136. package/dist/index-D9iYu2Yc.d.mts.map +0 -1
  137. package/dist/logger-BR1-s1Um.mjs.map +0 -1
  138. package/dist/module-BgdxxzBe.mjs.map +0 -1
  139. package/dist/quarry-registry-DCwqVcRp.mjs +0 -310
  140. package/dist/quarry-registry-DCwqVcRp.mjs.map +0 -1
  141. package/dist/router-context-BEJe9HEB.mjs.map +0 -1
  142. package/dist/seeder-Cupi5jl-.mjs.map +0 -1
  143. package/dist/stratal-CE0iTz4f.mjs.map +0 -1
  144. package/dist/types-CLhOhYsQ.d.mts +0 -64
  145. package/dist/types-CLhOhYsQ.d.mts.map +0 -1
@@ -0,0 +1,683 @@
1
+ import { a as __decorate, d as Transient, g as DI_TOKENS, o as __decorateParam, s as __decorateMetadata } from "./logger-CGT91VY6.mjs";
2
+ import { r as getListenerHandlers } from "./events-CvUSgEuN.mjs";
3
+ import { a as green, n as cyan, o as red, s as yellow, t as bold } from "./colors-Y7WIFXs7.mjs";
4
+ import { n as CommandError, r as COMMAND_INTERNALS, t as Command } from "./command-B1CPgsrU.mjs";
5
+ import { n as OPENAPI_TOKENS, t as OpenApiToolsService } from "./openapi-tools.service-B3TxYKoQ.mjs";
6
+ import { inject } from "tsyringe";
7
+ import { z } from "zod";
8
+ //#region src/quarry/commands/api.command.ts
9
+ let ApiCommand = class ApiCommand extends Command {
10
+ static command = "api {route?} {--method= : HTTP method} {--data= : JSON request body} {--header=* : Headers (Key:Value)} {--query=* : Query params (key=value)}";
11
+ static description = "Call an API route directly";
12
+ static aliases = ["api:call"];
13
+ constructor(app) {
14
+ super();
15
+ this.app = app;
16
+ }
17
+ async handle() {
18
+ const route = this.string("route");
19
+ if (!route) return (await this.call("route:list")).exitCode;
20
+ return this.callRoute(route);
21
+ }
22
+ async callRoute(route) {
23
+ const method = (this.string("method") || "GET").toUpperCase();
24
+ const data = this.string("data");
25
+ const headerArgs = this.array("header");
26
+ const queryArgs = this.array("query");
27
+ const headers = {};
28
+ if (data) headers["Content-Type"] = "application/json";
29
+ for (const h of headerArgs) {
30
+ const colonIdx = h.indexOf(":");
31
+ if (colonIdx > 0) headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim();
32
+ }
33
+ let url = route;
34
+ if (queryArgs.length > 0) {
35
+ const parts = queryArgs.map((q) => {
36
+ const eqIdx = q.indexOf("=");
37
+ if (eqIdx > 0) return `${encodeURIComponent(q.slice(0, eqIdx))}=${encodeURIComponent(q.slice(eqIdx + 1))}`;
38
+ return encodeURIComponent(q);
39
+ });
40
+ url += `?${parts.join("&")}`;
41
+ }
42
+ const request = new Request(`http://localhost${url}`, {
43
+ method,
44
+ headers,
45
+ body: data || void 0
46
+ });
47
+ const response = await this.app.hono.fetch(request, this.app.env);
48
+ const body = await response.text();
49
+ const statusText = `${response.status} ${response.statusText}`;
50
+ let coloredStatus;
51
+ if (response.status >= 200 && response.status < 300) coloredStatus = green(bold(statusText));
52
+ else if (response.status >= 300 && response.status < 400) coloredStatus = yellow(bold(statusText));
53
+ else coloredStatus = red(bold(statusText));
54
+ this.line(`${cyan(method)} ${route} ${coloredStatus}`);
55
+ this.newLine();
56
+ const headerLines = [];
57
+ response.headers.forEach((value, key) => {
58
+ headerLines.push(` ${key}: ${value}`);
59
+ });
60
+ if (headerLines.length > 0) {
61
+ this.line(bold("Headers:"));
62
+ for (const hl of headerLines) this.line(hl);
63
+ this.newLine();
64
+ }
65
+ if (body) {
66
+ this.line(bold("Body:"));
67
+ try {
68
+ this.line(JSON.stringify(JSON.parse(body), null, 2));
69
+ } catch {
70
+ this.line(body);
71
+ }
72
+ }
73
+ return response.status >= 400 ? 1 : 0;
74
+ }
75
+ };
76
+ ApiCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Application)), __decorateMetadata("design:paramtypes", [Object])], ApiCommand);
77
+ //#endregion
78
+ //#region src/quarry/commands/event-list.command.ts
79
+ let EventListCommand = class EventListCommand extends Command {
80
+ static command = "event:list";
81
+ static description = "List all registered event listeners";
82
+ constructor(modules) {
83
+ super();
84
+ this.modules = modules;
85
+ }
86
+ handle() {
87
+ const listeners = this.modules.getAllListeners();
88
+ if (listeners.length === 0) {
89
+ this.info("No event listeners found");
90
+ return 0;
91
+ }
92
+ const rows = [];
93
+ for (const ListenerClass of listeners) {
94
+ const handlers = getListenerHandlers(ListenerClass);
95
+ for (const { methodName, event, options } of handlers) rows.push([
96
+ event,
97
+ ListenerClass.name,
98
+ methodName,
99
+ String(options?.priority ?? 0),
100
+ options?.blocking ? "Yes" : "No"
101
+ ]);
102
+ }
103
+ if (rows.length === 0) {
104
+ this.info("No event handlers found");
105
+ return 0;
106
+ }
107
+ this.table([
108
+ "Event",
109
+ "Listener",
110
+ "Method",
111
+ "Priority",
112
+ "Blocking"
113
+ ], rows);
114
+ }
115
+ };
116
+ EventListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.ModuleRegistry)), __decorateMetadata("design:paramtypes", [Object])], EventListCommand);
117
+ //#endregion
118
+ //#region src/quarry/errors/command-not-found.error.ts
119
+ /**
120
+ * Thrown when a command is not found in the Quarry registry.
121
+ */
122
+ var CommandNotFoundError = class extends Error {
123
+ constructor(name) {
124
+ super(`Command "${name}" is not registered.`);
125
+ this.name = "CommandNotFoundError";
126
+ }
127
+ };
128
+ //#endregion
129
+ //#region src/quarry/commands/help.command.ts
130
+ let HelpCommand = class HelpCommand extends Command {
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)), __decorateMetadata("design:paramtypes", [Object])], HelpCommand);
159
+ //#endregion
160
+ //#region src/quarry/commands/mcp-serve.command.ts
161
+ let McpServeCommand = class McpServeCommand extends Command {
162
+ 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}";
163
+ static description = "Start an MCP stdio server exposing API routes as tools";
164
+ constructor(app, openAPIService) {
165
+ super();
166
+ this.app = app;
167
+ this.openAPIService = openAPIService;
168
+ }
169
+ async handle() {
170
+ const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
171
+ const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
172
+ const baseUrl = this.string("url");
173
+ const headerArgs = this.array("header");
174
+ const tags = this.array("tag");
175
+ const pathPrefix = this.string("path");
176
+ const headers = {};
177
+ for (const h of headerArgs) {
178
+ const colonIdx = h.indexOf(":");
179
+ if (colonIdx > 0) headers[h.slice(0, colonIdx).trim()] = h.slice(colonIdx + 1).trim();
180
+ }
181
+ const spec = this.openAPIService.getSpec(this.app.hono, this.app.container);
182
+ const service = new OpenApiToolsService(spec, { dispatcher: baseUrl ? async (method, url, opts) => {
183
+ const fullUrl = `${baseUrl}${url}`;
184
+ try {
185
+ return await fetch(fullUrl, {
186
+ method,
187
+ headers: {
188
+ "Content-Type": "application/json",
189
+ ...headers,
190
+ ...opts?.headers
191
+ },
192
+ body: opts?.body !== void 0 ? JSON.stringify(opts.body) : void 0
193
+ });
194
+ } catch (error) {
195
+ throw new Error(`MCP dispatch failed: ${method} ${fullUrl} — ${error instanceof Error ? error.message : String(error)}`, { cause: error });
196
+ }
197
+ } : async (method, url, opts) => {
198
+ const request = new Request(`http://localhost${url}`, {
199
+ method,
200
+ headers: {
201
+ "Content-Type": "application/json",
202
+ ...headers,
203
+ ...opts?.headers
204
+ },
205
+ body: opts?.body !== void 0 ? JSON.stringify(opts.body) : void 0
206
+ });
207
+ try {
208
+ return await this.app.hono.fetch(request, this.app.env);
209
+ } catch (error) {
210
+ throw new Error(`MCP dispatch failed: ${method} ${url} — ${error instanceof Error ? error.message : String(error)}`, { cause: error });
211
+ }
212
+ } });
213
+ const filter = {
214
+ tags: tags.length > 0 ? tags : void 0,
215
+ pathPrefix: pathPrefix || void 0
216
+ };
217
+ const tools = service.getTools(filter);
218
+ const config = this.app.container.resolve(OPENAPI_TOKENS.ConfigService).getEffectiveConfig();
219
+ const server = new McpServer({
220
+ name: config.info.title,
221
+ version: config.info.version
222
+ });
223
+ for (const tool of tools) {
224
+ const inputSchema = z.fromJSONSchema(tool.inputSchema);
225
+ server.registerTool(tool.name, {
226
+ description: tool.description,
227
+ inputSchema
228
+ }, async (args) => {
229
+ const result = await service.executeTool(tool.name, args);
230
+ return { content: [{
231
+ type: "text",
232
+ text: `Status: ${result.status}\n\n${result.body}`
233
+ }] };
234
+ });
235
+ }
236
+ server.registerResource("openapi-spec", "openapi://spec", {
237
+ description: "Full OpenAPI specification",
238
+ mimeType: "application/json"
239
+ }, () => ({ contents: [{
240
+ uri: "openapi://spec",
241
+ mimeType: "application/json",
242
+ text: JSON.stringify(spec, null, 2)
243
+ }] }));
244
+ const transport = new StdioServerTransport();
245
+ const closed = new Promise((resolve) => {
246
+ transport.onclose = resolve;
247
+ });
248
+ await server.connect(transport);
249
+ process.stderr.write(`MCP server started with ${tools.length} tool(s)\n`);
250
+ await closed;
251
+ return 0;
252
+ }
253
+ };
254
+ McpServeCommand = __decorate([
255
+ __decorateParam(0, inject(DI_TOKENS.Application)),
256
+ __decorateParam(1, inject(OPENAPI_TOKENS.OpenAPIService)),
257
+ __decorateMetadata("design:paramtypes", [Object, Object])
258
+ ], McpServeCommand);
259
+ //#endregion
260
+ //#region src/quarry/commands/mcp-tools.command.ts
261
+ let McpToolsCommand = class McpToolsCommand extends Command {
262
+ static command = "mcp:tools {--tag=* : Filter by OpenAPI tags} {--path= : Filter by path prefix}";
263
+ static description = "List API routes that would be exposed as MCP tools";
264
+ constructor(app, openAPIService) {
265
+ super();
266
+ this.app = app;
267
+ this.openAPIService = openAPIService;
268
+ }
269
+ handle() {
270
+ const tags = this.array("tag");
271
+ const pathPrefix = this.string("path");
272
+ const service = new OpenApiToolsService(this.openAPIService.getSpec(this.app.hono, this.app.container));
273
+ const filter = {
274
+ tags: tags.length > 0 ? tags : void 0,
275
+ pathPrefix: pathPrefix || void 0
276
+ };
277
+ const tools = service.getTools(filter);
278
+ if (tools.length === 0) {
279
+ this.info("No tools found");
280
+ return 0;
281
+ }
282
+ this.table([
283
+ "Name",
284
+ "Method",
285
+ "Path",
286
+ "Description"
287
+ ], tools.map((t) => [
288
+ t.name,
289
+ t.method,
290
+ t.path,
291
+ t.description
292
+ ]));
293
+ return 0;
294
+ }
295
+ };
296
+ McpToolsCommand = __decorate([
297
+ __decorateParam(0, inject(DI_TOKENS.Application)),
298
+ __decorateParam(1, inject(OPENAPI_TOKENS.OpenAPIService)),
299
+ __decorateMetadata("design:paramtypes", [Object, Object])
300
+ ], McpToolsCommand);
301
+ //#endregion
302
+ //#region src/quarry/commands/queue-list.command.ts
303
+ let QueueListCommand = class QueueListCommand extends Command {
304
+ static command = "queue:list";
305
+ static description = "List all registered queue consumers";
306
+ constructor(consumers) {
307
+ super();
308
+ this.consumers = consumers;
309
+ }
310
+ handle() {
311
+ const consumers = this.consumers.getAllConsumers();
312
+ if (consumers.length === 0) {
313
+ this.info("No queue consumers found");
314
+ return 0;
315
+ }
316
+ this.table(["Consumer", "Message Types"], consumers.map((c) => [c.constructor.name, c.messageTypes.join(", ")]));
317
+ }
318
+ };
319
+ QueueListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.ConsumerRegistry)), __decorateMetadata("design:paramtypes", [Object])], QueueListCommand);
320
+ //#endregion
321
+ //#region src/quarry/commands/route-list.command.ts
322
+ let RouteListCommand = class RouteListCommand extends Command {
323
+ static command = "route:list {--method= : Filter by HTTP method} {--path= : Filter by path substring}";
324
+ static description = "List all registered routes";
325
+ constructor(app) {
326
+ super();
327
+ this.app = app;
328
+ }
329
+ handle() {
330
+ const methodFilter = this.string("method").toUpperCase();
331
+ const pathFilter = this.string("path");
332
+ const deduped = /* @__PURE__ */ new Map();
333
+ for (const r of this.app.hono.routes) deduped.set(`${r.method}:${r.path}`, {
334
+ method: r.method,
335
+ path: r.path,
336
+ name: r.handler.name
337
+ });
338
+ let routes = [...deduped.values()].filter((r) => r.name);
339
+ if (methodFilter) routes = routes.filter((r) => r.method.toUpperCase() === methodFilter);
340
+ if (pathFilter) routes = routes.filter((r) => r.path.includes(pathFilter));
341
+ if (routes.length === 0) {
342
+ this.info("No routes found");
343
+ return 0;
344
+ }
345
+ this.table([
346
+ "Method",
347
+ "Path",
348
+ "Action",
349
+ "Type"
350
+ ], routes.map((r) => {
351
+ const isWs = r.name.startsWith("ws:");
352
+ const action = r.name.replace(/^(http|ws):/, "");
353
+ return [
354
+ r.method.toUpperCase(),
355
+ r.path,
356
+ action || r.name,
357
+ isWs ? "WS" : "HTTP"
358
+ ];
359
+ }));
360
+ }
361
+ };
362
+ RouteListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Application)), __decorateMetadata("design:paramtypes", [Object])], RouteListCommand);
363
+ //#endregion
364
+ //#region src/quarry/commands/schedule-list.command.ts
365
+ let ScheduleListCommand = class ScheduleListCommand extends Command {
366
+ static command = "schedule:list";
367
+ static description = "List all registered cron jobs";
368
+ constructor(cron) {
369
+ super();
370
+ this.cron = cron;
371
+ }
372
+ handle() {
373
+ const schedules = this.cron.getAllSchedules();
374
+ if (schedules.length === 0) {
375
+ this.info("No cron jobs found");
376
+ return 0;
377
+ }
378
+ const rows = [];
379
+ for (const schedule of schedules) {
380
+ const jobs = this.cron.getJobsForSchedule(schedule);
381
+ for (const job of jobs) rows.push([schedule, job.constructor.name]);
382
+ }
383
+ this.table(["Schedule", "Job"], rows);
384
+ }
385
+ };
386
+ ScheduleListCommand = __decorate([__decorateParam(0, inject(DI_TOKENS.Cron)), __decorateMetadata("design:paramtypes", [Object])], ScheduleListCommand);
387
+ //#endregion
388
+ //#region src/quarry/command-internals.ts
389
+ /** @internal Set the flat input values before calling handle() */
390
+ function setCommandInputs(command, values) {
391
+ command[COMMAND_INTERNALS].inputs = { ...values };
392
+ }
393
+ /** @internal Set the Quarry reference for this.call() support */
394
+ function setCommandQuarry(command, quarry) {
395
+ command[COMMAND_INTERNALS].quarry = quarry;
396
+ }
397
+ /** @internal Collect the result after handle() completes */
398
+ function getCommandResult(command) {
399
+ const internals = command[COMMAND_INTERNALS];
400
+ return {
401
+ exitCode: internals.exitCode,
402
+ output: [...internals.output],
403
+ errors: [...internals.errors]
404
+ };
405
+ }
406
+ //#endregion
407
+ //#region src/quarry/signature-parser.ts
408
+ /**
409
+ * Parse a Laravel-style command signature string.
410
+ *
411
+ * Signature syntax:
412
+ * command-name {arg} ... — flat command
413
+ * group subcommand {arg} ... — subcommand hierarchy (space-separated)
414
+ * namespace:command {arg} ... — namespaced flat command (colon-separated)
415
+ * {--flag} {--name=} {--name=default} {--name=*} {--A|name} {--name= : desc}
416
+ *
417
+ * Pure function, zero dependencies, edge-compatible.
418
+ */
419
+ function parseSignature(signature) {
420
+ const tokens = extractTokens(signature);
421
+ const name = extractCommandName(signature);
422
+ const args = [];
423
+ const options = [];
424
+ for (const token of tokens) {
425
+ const inner = token.slice(1, -1).trim();
426
+ if (inner.startsWith("--")) options.push(parseOption(inner));
427
+ else args.push(parseArgument(inner));
428
+ }
429
+ return {
430
+ name,
431
+ arguments: args,
432
+ options
433
+ };
434
+ }
435
+ function extractCommandName(signature) {
436
+ const match = /^[\w:.-]+(?:\s+[\w:.-]+)*/.exec(signature);
437
+ if (!match) throw new CommandError(`Invalid signature: cannot extract command name from "${signature}"`);
438
+ return match[0];
439
+ }
440
+ function extractTokens(signature) {
441
+ const tokens = [];
442
+ const regex = /\{[^}]+\}/g;
443
+ let match;
444
+ while ((match = regex.exec(signature)) !== null) tokens.push(match[0]);
445
+ return tokens;
446
+ }
447
+ function parseArgument(inner) {
448
+ const { value, description } = splitDescription(inner);
449
+ if (value.endsWith("*")) return {
450
+ name: value.slice(0, -1).trim(),
451
+ required: true,
452
+ isArray: true,
453
+ description
454
+ };
455
+ const eqIdx = value.indexOf("=");
456
+ if (eqIdx !== -1) return {
457
+ name: value.slice(0, eqIdx).trim(),
458
+ required: false,
459
+ default: value.slice(eqIdx + 1).trim(),
460
+ isArray: false,
461
+ description
462
+ };
463
+ if (value.endsWith("?")) return {
464
+ name: value.slice(0, -1).trim(),
465
+ required: false,
466
+ isArray: false,
467
+ description
468
+ };
469
+ return {
470
+ name: value.trim(),
471
+ required: true,
472
+ isArray: false,
473
+ description
474
+ };
475
+ }
476
+ function parseOption(inner) {
477
+ const { value, description } = splitDescription(inner.slice(2));
478
+ let alias;
479
+ let optBody = value;
480
+ const pipeIdx = optBody.indexOf("|");
481
+ if (pipeIdx !== -1) {
482
+ alias = optBody.slice(0, pipeIdx).trim();
483
+ optBody = optBody.slice(pipeIdx + 1).trim();
484
+ }
485
+ if (optBody.endsWith("=*")) return {
486
+ name: optBody.slice(0, -2).trim(),
487
+ alias,
488
+ isFlag: false,
489
+ isArray: true,
490
+ description
491
+ };
492
+ const eqIdx = optBody.indexOf("=");
493
+ if (eqIdx !== -1) {
494
+ const name = optBody.slice(0, eqIdx).trim();
495
+ const defaultValue = optBody.slice(eqIdx + 1).trim();
496
+ return {
497
+ name,
498
+ alias,
499
+ isFlag: false,
500
+ isArray: false,
501
+ default: defaultValue || void 0,
502
+ description
503
+ };
504
+ }
505
+ return {
506
+ name: optBody.trim(),
507
+ alias,
508
+ isFlag: true,
509
+ isArray: false,
510
+ description
511
+ };
512
+ }
513
+ function splitDescription(value) {
514
+ const colonIdx = value.indexOf(" : ");
515
+ if (colonIdx === -1) return { value };
516
+ return {
517
+ value: value.slice(0, colonIdx).trim(),
518
+ description: value.slice(colonIdx + 3).trim()
519
+ };
520
+ }
521
+ //#endregion
522
+ //#region src/quarry/quarry-registry.ts
523
+ let QuarryRegistry = class QuarryRegistry {
524
+ commands = /* @__PURE__ */ new Map();
525
+ signatures = /* @__PURE__ */ new Map();
526
+ aliases = /* @__PURE__ */ new Map();
527
+ constructor(container) {
528
+ this.container = container;
529
+ }
530
+ /**
531
+ * Execute a command by name with optional flat input.
532
+ * A fresh command instance is resolved from the container per invocation.
533
+ */
534
+ async call(name, input) {
535
+ const resolvedName = this.resolveName(name);
536
+ const CommandClass = this.commands.get(resolvedName);
537
+ if (!CommandClass) throw new CommandNotFoundError(name);
538
+ const signature = this.signatures.get(resolvedName);
539
+ const mergedInput = this.applyDefaults(input ?? {}, signature);
540
+ 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}`);
541
+ let command;
542
+ try {
543
+ command = this.container.resolve(CommandClass);
544
+ setCommandQuarry(command, this);
545
+ setCommandInputs(command, mergedInput);
546
+ const exitCode = await command.handle();
547
+ const result = getCommandResult(command);
548
+ if (typeof exitCode === "number") return {
549
+ ...result,
550
+ exitCode
551
+ };
552
+ return result;
553
+ } catch (error) {
554
+ if (error instanceof CommandError) {
555
+ if (command) {
556
+ const result = getCommandResult(command);
557
+ return {
558
+ exitCode: result.exitCode === 0 ? 1 : result.exitCode,
559
+ output: result.output,
560
+ errors: [...result.errors, error.message]
561
+ };
562
+ }
563
+ return {
564
+ exitCode: 1,
565
+ output: [],
566
+ errors: [error.message]
567
+ };
568
+ }
569
+ const errorMessage = this.handleError(error);
570
+ if (command) {
571
+ const result = getCommandResult(command);
572
+ return {
573
+ exitCode: result.exitCode === 0 ? 1 : result.exitCode,
574
+ output: result.output,
575
+ errors: [...result.errors, errorMessage]
576
+ };
577
+ }
578
+ return {
579
+ exitCode: 1,
580
+ output: [],
581
+ errors: [errorMessage]
582
+ };
583
+ }
584
+ }
585
+ /**
586
+ * Check if a command exists by name or alias.
587
+ */
588
+ has(name) {
589
+ const resolved = this.resolveName(name);
590
+ return this.commands.has(resolved);
591
+ }
592
+ /**
593
+ * Get a command constructor by name or alias.
594
+ */
595
+ get(name) {
596
+ const resolved = this.resolveName(name);
597
+ return this.commands.get(resolved);
598
+ }
599
+ /**
600
+ * Get all registered command constructors.
601
+ */
602
+ all() {
603
+ return new Map(this.commands);
604
+ }
605
+ /**
606
+ * List all commands with their descriptions and aliases.
607
+ */
608
+ list() {
609
+ const result = [];
610
+ for (const [name, CommandClass] of this.commands) {
611
+ const staticCommand = CommandClass;
612
+ const commandAliases = [];
613
+ for (const [alias, target] of this.aliases) if (target === name) commandAliases.push(alias);
614
+ result.push({
615
+ name,
616
+ description: staticCommand.description,
617
+ aliases: commandAliases
618
+ });
619
+ }
620
+ return result.sort((a, b) => a.name.localeCompare(b.name));
621
+ }
622
+ /**
623
+ * Generate a compact listing of all commands with visual hierarchy and colors.
624
+ */
625
+ async listUsage(options) {
626
+ const commands = this.list();
627
+ const { generateListing } = await import("./usage-generator-CVIsENuE.mjs").then((n) => n.n);
628
+ return generateListing(commands, this.signatures, options);
629
+ }
630
+ /**
631
+ * Get auto-generated usage text for a command.
632
+ */
633
+ async usage(name) {
634
+ const resolvedName = this.resolveName(name);
635
+ const CommandClass = this.commands.get(resolvedName);
636
+ if (!CommandClass) throw new CommandNotFoundError(name);
637
+ const signature = this.signatures.get(resolvedName);
638
+ const staticCommand = CommandClass;
639
+ const { generateUsage } = await import("./usage-generator-CVIsENuE.mjs").then((n) => n.n);
640
+ return generateUsage(signature, staticCommand.description);
641
+ }
642
+ /**
643
+ * Register a command constructor with the registry.
644
+ * @internal Called by Application during bootstrap.
645
+ */
646
+ register(commandClass) {
647
+ const staticCommand = commandClass;
648
+ if (!staticCommand.command) throw new CommandError(`Command class ${commandClass.name} is missing static "command" signature`);
649
+ const signature = parseSignature(staticCommand.command);
650
+ const name = signature.name;
651
+ if (this.commands.has(name) || this.aliases.has(name)) throw new CommandError(`Duplicate command name: "${name}" is already registered`);
652
+ if (staticCommand.aliases) {
653
+ for (const alias of staticCommand.aliases) if (this.commands.has(alias) || this.aliases.has(alias)) throw new CommandError(`Duplicate alias: "${alias}" conflicts with an existing command or alias`);
654
+ }
655
+ this.commands.set(name, commandClass);
656
+ this.signatures.set(name, signature);
657
+ if (staticCommand.aliases) for (const alias of staticCommand.aliases) this.aliases.set(alias, name);
658
+ }
659
+ handleError(error) {
660
+ return this.container.resolve(DI_TOKENS.ErrorHandler).handle(error).message;
661
+ }
662
+ resolveName(name) {
663
+ return this.aliases.get(name) ?? name;
664
+ }
665
+ applyDefaults(input, signature) {
666
+ const result = { ...input };
667
+ for (const arg of signature.arguments) if (result[arg.name] === void 0 && arg.default !== void 0) result[arg.name] = arg.default;
668
+ for (const opt of signature.options) if (result[opt.name] === void 0) {
669
+ if (opt.default !== void 0) result[opt.name] = opt.default;
670
+ else if (opt.isFlag) result[opt.name] = false;
671
+ }
672
+ return result;
673
+ }
674
+ };
675
+ QuarryRegistry = __decorate([
676
+ Transient(DI_TOKENS.Quarry),
677
+ __decorateParam(0, inject(DI_TOKENS.Container)),
678
+ __decorateMetadata("design:paramtypes", [Object])
679
+ ], QuarryRegistry);
680
+ //#endregion
681
+ export { QueueListCommand as a, HelpCommand as c, ApiCommand as d, RouteListCommand as i, CommandNotFoundError as l, parseSignature as n, McpToolsCommand as o, ScheduleListCommand as r, McpServeCommand as s, QuarryRegistry as t, EventListCommand as u };
682
+
683
+ //# sourceMappingURL=quarry-registry-B2rkO-JS.mjs.map