stratal 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/cache/index.d.mts +1 -1
  2. package/dist/cache/index.mjs +2 -2
  3. package/dist/{command-CPhFHjG3.d.mts → command-4HnKnC-G.d.mts} +2 -2
  4. package/dist/{command-CPhFHjG3.d.mts.map → command-4HnKnC-G.d.mts.map} +1 -1
  5. package/dist/config/index.d.mts +1 -1
  6. package/dist/config/index.mjs +2 -2
  7. package/dist/{controller.decorator-C5UVeJS3.mjs → controller.decorator-DKeZ71aP.mjs} +3 -3
  8. package/dist/{controller.decorator-C5UVeJS3.mjs.map → controller.decorator-DKeZ71aP.mjs.map} +1 -1
  9. package/dist/cron/index.d.mts +1 -1
  10. package/dist/cron/index.mjs +1 -1
  11. package/dist/{cron.module-Bgzq5hiT.mjs → cron.module-DgxLe8Xy.mjs} +3 -3
  12. package/dist/{cron.module-Bgzq5hiT.mjs.map → cron.module-DgxLe8Xy.mjs.map} +1 -1
  13. package/dist/di/index.d.mts +1 -1
  14. package/dist/di/index.mjs +1 -1
  15. package/dist/{di-DseMn-z9.mjs → di-B0NXIdRF.mjs} +17 -1
  16. package/dist/di-B0NXIdRF.mjs.map +1 -0
  17. package/dist/email/index.d.mts +2 -2
  18. package/dist/email/index.mjs +3 -3
  19. package/dist/errors/index.d.mts +1 -1
  20. package/dist/errors/index.mjs +2 -2
  21. package/dist/{errors-mXYxG0XB.mjs → errors-EUtwVfNm.mjs} +3 -3
  22. package/dist/{errors-mXYxG0XB.mjs.map → errors-EUtwVfNm.mjs.map} +1 -1
  23. package/dist/events/index.d.mts +8 -0
  24. package/dist/events/index.d.mts.map +1 -1
  25. package/dist/events/index.mjs +1 -1
  26. package/dist/{events-BXJGZjpG.mjs → events-zbCMY_Gf.mjs} +5 -2
  27. package/dist/events-zbCMY_Gf.mjs.map +1 -0
  28. package/dist/{exception-context-kEoMFwze.mjs → exception-context-Bd5Hk2c_.mjs} +2 -2
  29. package/dist/{exception-context-kEoMFwze.mjs.map → exception-context-Bd5Hk2c_.mjs.map} +1 -1
  30. package/dist/{gateway-context-TMu_AlJt.mjs → gateway-context-I0tKgGfh.mjs} +4 -4
  31. package/dist/{gateway-context-TMu_AlJt.mjs.map → gateway-context-I0tKgGfh.mjs.map} +1 -1
  32. package/dist/guards/index.d.mts +1 -1
  33. package/dist/{hono-app-CvV3hOfT.mjs → hono-app-C7-1m9eK.mjs} +6 -6
  34. package/dist/{hono-app-CvV3hOfT.mjs.map → hono-app-C7-1m9eK.mjs.map} +1 -1
  35. package/dist/{http-method.decorator-ByWZb9DO.mjs → http-method.decorator-xCuGoZPC.mjs} +2 -2
  36. package/dist/{http-method.decorator-ByWZb9DO.mjs.map → http-method.decorator-xCuGoZPC.mjs.map} +1 -1
  37. package/dist/i18n/index.d.mts +1 -1
  38. package/dist/i18n/index.mjs +3 -3
  39. package/dist/{i18n.module-DRQAZoSZ.mjs → i18n.module-JOPUNpvi.mjs} +3 -3
  40. package/dist/{i18n.module-DRQAZoSZ.mjs.map → i18n.module-JOPUNpvi.mjs.map} +1 -1
  41. package/dist/{index-B5JBRcWD.d.mts → index-BPJSBHhq.d.mts} +2 -2
  42. package/dist/{index-B5JBRcWD.d.mts.map → index-BPJSBHhq.d.mts.map} +1 -1
  43. package/dist/{index-B_JoEl3V.d.mts → index-C_t8VVQD.d.mts} +12 -1
  44. package/dist/index-C_t8VVQD.d.mts.map +1 -0
  45. package/dist/index.d.mts +3 -3
  46. package/dist/index.mjs +2 -2
  47. package/dist/{lazy-module-loader-Ib383jH_.d.mts → lazy-module-loader-DZQxOgRZ.d.mts} +2 -2
  48. package/dist/{lazy-module-loader-Ib383jH_.d.mts.map → lazy-module-loader-DZQxOgRZ.d.mts.map} +1 -1
  49. package/dist/{locale-path.service-D-dHiIPc.mjs → locale-path.service-DzA01Kvc.mjs} +3 -3
  50. package/dist/{locale-path.service-D-dHiIPc.mjs.map → locale-path.service-DzA01Kvc.mjs.map} +1 -1
  51. package/dist/{locale-url.service-C2EWmGdq.mjs → locale-url.service-DwTXZid3.mjs} +2 -2
  52. package/dist/{locale-url.service-C2EWmGdq.mjs.map → locale-url.service-DwTXZid3.mjs.map} +1 -1
  53. package/dist/logger/index.mjs +1 -1
  54. package/dist/module/index.d.mts +2 -2
  55. package/dist/module/index.mjs +2 -2
  56. package/dist/{module-registry-Dm-pqHd3.mjs → module-registry-MfWmniZ7.mjs} +4 -4
  57. package/dist/{module-registry-Dm-pqHd3.mjs.map → module-registry-MfWmniZ7.mjs.map} +1 -1
  58. package/dist/openapi/index.d.mts +2 -2
  59. package/dist/openapi/index.mjs +1 -1
  60. package/dist/{openapi-CstuTM8S.mjs → openapi-BKDwQKh-.mjs} +3 -3
  61. package/dist/{openapi-CstuTM8S.mjs.map → openapi-BKDwQKh-.mjs.map} +1 -1
  62. package/dist/{openapi.service-YhTiJ1bO.d.mts → openapi.service-CM40bnBB.d.mts} +2 -2
  63. package/dist/{openapi.service-YhTiJ1bO.d.mts.map → openapi.service-CM40bnBB.d.mts.map} +1 -1
  64. package/dist/quarry/index.d.mts +3 -3
  65. package/dist/quarry/index.mjs +1 -1
  66. package/dist/quarry/runner.d.mts +6 -6
  67. package/dist/quarry/runner.mjs +5 -5
  68. package/dist/{quarry-registry-CXg0RFXq.d.mts → quarry-registry-CsStq0DB.d.mts} +3 -3
  69. package/dist/{quarry-registry-CXg0RFXq.d.mts.map → quarry-registry-CsStq0DB.d.mts.map} +1 -1
  70. package/dist/{quarry.module-BuRPGMDm.mjs → quarry.module-BOgcNJMU.mjs} +3 -3
  71. package/dist/{quarry.module-BuRPGMDm.mjs.map → quarry.module-BOgcNJMU.mjs.map} +1 -1
  72. package/dist/queue/index.d.mts +1 -1
  73. package/dist/queue/index.mjs +2 -2
  74. package/dist/{queue.module-nddvxzCB.mjs → queue.module-DSAH88gZ.mjs} +3 -3
  75. package/dist/{queue.module-nddvxzCB.mjs.map → queue.module-DSAH88gZ.mjs.map} +1 -1
  76. package/dist/{r2-storage.provider-DCxQt9dD.mjs → r2-storage.provider-BJ4j23W6.mjs} +2 -2
  77. package/dist/{r2-storage.provider-DCxQt9dD.mjs.map → r2-storage.provider-BJ4j23W6.mjs.map} +1 -1
  78. package/dist/{rate-limit.decorator-BPAie_p3.mjs → rate-limit.decorator-B35jBEVD.mjs} +2 -2
  79. package/dist/{rate-limit.decorator-BPAie_p3.mjs.map → rate-limit.decorator-B35jBEVD.mjs.map} +1 -1
  80. package/dist/rate-limiter/index.d.mts +1 -1
  81. package/dist/rate-limiter/index.mjs +3 -3
  82. package/dist/{route-registration.service-D6vSwiKP.mjs → route-registration.service-HN8WgIis.mjs} +9 -9
  83. package/dist/{route-registration.service-D6vSwiKP.mjs.map → route-registration.service-HN8WgIis.mjs.map} +1 -1
  84. package/dist/{route-registry-CYqLp2Nj.mjs → route-registry-CtW26Suv.mjs} +3 -3
  85. package/dist/{route-registry-CYqLp2Nj.mjs.map → route-registry-CtW26Suv.mjs.map} +1 -1
  86. package/dist/router/index.d.mts +1 -1
  87. package/dist/router/index.mjs +13 -13
  88. package/dist/{router-CWGBD-Bg.mjs → router-OCnf4VB6.mjs} +13 -13
  89. package/dist/{router-CWGBD-Bg.mjs.map → router-OCnf4VB6.mjs.map} +1 -1
  90. package/dist/{router-resolver-D4YlPNlm.mjs → router-resolver-CMNuw-s0.mjs} +2 -2
  91. package/dist/{router-resolver-D4YlPNlm.mjs.map → router-resolver-CMNuw-s0.mjs.map} +1 -1
  92. package/dist/seeder/index.d.mts +2 -2
  93. package/dist/seeder/index.mjs +3 -3
  94. package/dist/{seeder-7ubkms-Y.mjs → seeder-DI-rUoZx.mjs} +4 -4
  95. package/dist/{seeder-7ubkms-Y.mjs.map → seeder-DI-rUoZx.mjs.map} +1 -1
  96. package/dist/{seeder-registry-CyUmKsJq.mjs → seeder-registry-B5FwBeCU.mjs} +3 -3
  97. package/dist/{seeder-registry-CyUmKsJq.mjs.map → seeder-registry-B5FwBeCU.mjs.map} +1 -1
  98. package/dist/{seeder.module-CYYwk3Qk.mjs → seeder.module-DaY0RYoB.mjs} +2 -2
  99. package/dist/{seeder.module-CYYwk3Qk.mjs.map → seeder.module-DaY0RYoB.mjs.map} +1 -1
  100. package/dist/storage/index.d.mts +1 -1
  101. package/dist/storage/index.mjs +2 -2
  102. package/dist/storage/providers/index.mjs +1 -1
  103. package/dist/{storage-MDZypIE9.mjs → storage-BE6-kzaN.mjs} +7 -7
  104. package/dist/{storage-MDZypIE9.mjs.map → storage-BE6-kzaN.mjs.map} +1 -1
  105. package/dist/{storage.error-Dnib4VHc.mjs → storage.error-Dai3rShJ.mjs} +2 -2
  106. package/dist/{storage.error-Dnib4VHc.mjs.map → storage.error-Dai3rShJ.mjs.map} +1 -1
  107. package/dist/{stratal-DwDJPY9N.d.mts → stratal-Bmc6WT3k.d.mts} +2 -2
  108. package/dist/{stratal-DwDJPY9N.d.mts.map → stratal-Bmc6WT3k.d.mts.map} +1 -1
  109. package/dist/{stratal-DL9M38_s.mjs → stratal-DtAj21uF.mjs} +21 -20
  110. package/dist/stratal-DtAj21uF.mjs.map +1 -0
  111. package/dist/{uri-h7Q8Jug9.mjs → uri-h6ITRpqr.mjs} +3 -3
  112. package/dist/{uri-h7Q8Jug9.mjs.map → uri-h6ITRpqr.mjs.map} +1 -1
  113. package/dist/{versioning.service-C6aHky8-.mjs → versioning.service-B4rtmgMQ.mjs} +3 -3
  114. package/dist/{versioning.service-C6aHky8-.mjs.map → versioning.service-B4rtmgMQ.mjs.map} +1 -1
  115. package/dist/websocket/index.d.mts +1 -1
  116. package/dist/websocket/index.mjs +1 -1
  117. package/dist/workers/index.d.mts +1 -1
  118. package/dist/workers/index.mjs +2 -2
  119. package/package.json +1 -1
  120. package/dist/di-DseMn-z9.mjs.map +0 -1
  121. package/dist/events-BXJGZjpG.mjs.map +0 -1
  122. package/dist/index-B_JoEl3V.d.mts.map +0 -1
  123. package/dist/stratal-DL9M38_s.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"openapi-CstuTM8S.mjs","names":[],"sources":["../src/openapi/services/openapi-config.service.ts","../src/openapi/services/openapi-config.store.ts","../src/openapi/services/openapi.service.ts","../src/openapi/openapi.module.ts"],"sourcesContent":["import { inject } from '../../di'\nimport { Request } from '../../di/decorators'\nimport { OPENAPI_TOKENS } from '../openapi.tokens'\nimport type {\n IOpenAPIConfigService,\n IOpenAPIConfigStore,\n OpenAPIConfigOverride,\n OpenAPIEffectiveConfig\n} from '../types'\n\n/**\n * OpenAPI Config Service\n *\n * Request-scoped service that manages OpenAPI configuration for the current request.\n * Supports runtime overrides via middleware while preserving base configuration.\n *\n * @example\n * ```typescript\n * // In middleware (e.g., RouteAccessMiddleware)\n * constructor(\n * @inject(OPENAPI_TOKENS.ConfigService) private openAPIConfig: IOpenAPIConfigService\n * ) {}\n *\n * async handle(ctx, next) {\n * this.openAPIConfig.override({\n * info: { title: 'Custom API' },\n * routeFilter: (path) => shouldInclude(path)\n * })\n * await next()\n * }\n * ```\n */\n@Request(OPENAPI_TOKENS.ConfigService)\nexport class OpenAPIConfigService implements IOpenAPIConfigService {\n private overrides: OpenAPIConfigOverride[] = []\n\n constructor(\n @inject(OPENAPI_TOKENS.ConfigStore) private store: IOpenAPIConfigStore\n ) { }\n\n /**\n * Add configuration override for this request.\n * Overrides are merged in the order they are added.\n */\n override(config: OpenAPIConfigOverride): void {\n this.overrides.push(config)\n }\n\n /** Get effective configuration (base merged with all overrides) */\n getEffectiveConfig(): OpenAPIEffectiveConfig {\n let effective = this.store.getBaseConfig()\n\n for (const override of this.overrides) {\n effective = this.mergeConfig(effective, override)\n }\n\n return effective\n }\n\n /**\n * Merge override into effective config.\n * Info is shallow-merged, routeFilter is replaced.\n */\n private mergeConfig(\n base: OpenAPIEffectiveConfig,\n override: OpenAPIConfigOverride\n ): OpenAPIEffectiveConfig {\n return {\n ...base,\n info: {\n ...base.info,\n ...(override.info && {\n title: override.info.title ?? base.info.title,\n version: override.info.version ?? base.info.version,\n description: override.info.description ?? base.info.description\n })\n },\n routeFilter: override.routeFilter ?? base.routeFilter\n }\n }\n}\n","import { inject } from '../../di'\nimport { Singleton } from '../../di/decorators'\nimport { OPENAPI_TOKENS } from '../openapi.tokens'\nimport type {\n IOpenAPIConfigStore,\n OpenAPIEffectiveConfig,\n OpenAPIModuleOptions\n} from '../types'\n\n/**\n * OpenAPI Config Store\n *\n * Singleton holder of the static base configuration (mount paths, base info,\n * security schemes) derived from `OpenAPIModule.forRoot()` options. It carries\n * no per-request state, so it is the thing to resolve when you need OpenAPI\n * config OUTSIDE a request scope — endpoint mounting at bootstrap, the\n * `mcp:serve` CLI command, etc. Resolving it never throws on its own.\n *\n * Per-request overrides live on {@link OpenAPIConfigService}, which reads the\n * base config from here and merges its overrides on top.\n */\n@Singleton(OPENAPI_TOKENS.ConfigStore)\nexport class OpenAPIConfigStore implements IOpenAPIConfigStore {\n constructor(\n @inject(OPENAPI_TOKENS.Options, { isOptional: true }) private baseOptions?: OpenAPIModuleOptions\n ) { }\n\n getBaseConfig(): OpenAPIEffectiveConfig {\n return {\n jsonPath: this.baseOptions?.jsonPath ?? '/api/openapi.json',\n ui: this.baseOptions?.ui,\n info: {\n title: this.baseOptions?.info?.title ?? 'API',\n version: this.baseOptions?.info?.version ?? '1.0.0',\n description: this.baseOptions?.info?.description\n },\n securitySchemes: this.baseOptions?.securitySchemes\n }\n }\n}\n","import type { Container } from '../../di/container'\nimport { Singleton } from '../../di/decorators'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport type { II18nService } from '../../i18n/i18n.types'\nimport type { OpenAPIHono, OpenAPIObject, PathItemObject } from '../../i18n/validation/zod'\nimport { ROUTER_CONTEXT_KEYS, SECURITY_SCHEMES } from '../../router/constants'\nimport type { RouterEnv } from '../../router/types'\nimport { OPENAPI_TOKENS } from '../openapi.tokens'\nimport type { IOpenAPIConfigService, IOpenAPIConfigStore, OpenAPIEffectiveConfig } from '../types'\n\n/**\n * OpenAPI Service\n *\n * Generates OpenAPI specifications with support for:\n * - Runtime configuration via OpenAPIConfigService\n * - Route filtering via custom routeFilter\n * - i18n support for titles and descriptions\n * - Security scheme definitions\n *\n * Hidden routes (hideFromDocs) are excluded at registration time via\n * @hono/zod-openapi's `hide` option and don't appear in the spec.\n *\n * Configuration is resolved per-request from OpenAPIConfigService,\n * allowing middleware to override config based on domain context.\n */\n@Singleton(OPENAPI_TOKENS.OpenAPIService)\nexport class OpenAPIService {\n\n /**\n * Generate a filtered OpenAPI spec using the user's config.\n * Usable from both HTTP handlers and CLI commands.\n */\n getSpec(app: OpenAPIHono<RouterEnv>, container: Container): OpenAPIObject {\n const configService = container.resolve<IOpenAPIConfigService>(OPENAPI_TOKENS.ConfigService)\n const i18n = container.resolve<II18nService>(I18N_TOKENS.I18nService)\n const config = configService.getEffectiveConfig()\n\n const fullSpec = app.getOpenAPIDocument({\n openapi: '3.0.0',\n info: {\n version: config.info.version,\n title: config.info.title,\n description: config.info.description,\n },\n })\n\n // Security schemes\n fullSpec.components ??= {}\n fullSpec.components.securitySchemes = this.getSecuritySchemeDefinitions(i18n)\n\n // Apply custom routeFilter if provided\n if (config.routeFilter) {\n fullSpec.paths = this.filterRoutes(\n fullSpec.paths as Record<string, PathItemObject>,\n config,\n )\n }\n\n // Filter unreferenced schemas\n if (fullSpec.components.schemas) {\n fullSpec.components.schemas = this.filterSchemas(fullSpec as unknown as Record<string, unknown>) as typeof fullSpec.components.schemas\n }\n\n return fullSpec\n }\n\n /**\n * Setup OpenAPI documentation endpoints\n */\n setupEndpoints(app: OpenAPIHono<RouterEnv>, container: Container): void {\n // Endpoints are mounted at bootstrap (no request scope), so read the static\n // mount paths from the singleton config store — request overrides (info /\n // routeFilter) never affect jsonPath/ui and are resolved per request inside\n // the handlers below via the request-scoped config service.\n const config = container.resolve<IOpenAPIConfigStore>(OPENAPI_TOKENS.ConfigStore).getBaseConfig()\n const jsonPath = config.jsonPath\n const ui = config.ui\n\n // OpenAPI JSON spec endpoint\n app.get(jsonPath, (c) => {\n const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER)\n const fullSpec = this.getSpec(app, requestContainer)\n\n // Add servers (HTTP-specific — needs request URL context)\n const url = new URL(c.req.raw.url)\n const i18n = requestContainer.resolve<II18nService>(I18N_TOKENS.I18nService)\n fullSpec.servers = [{\n url: `${url.protocol}//${url.host}`,\n description: i18n.t('common.api.serverDescription'),\n }]\n\n return c.json(fullSpec)\n })\n this.nameLastHandler(app, 'OpenAPI', 'spec')\n\n // Docs UI endpoint\n if (ui !== false) {\n const uiPath = ui?.path ?? '/api/docs'\n const uiRenderer = ui?.renderer\n\n app.get(uiPath, async (c, next) => {\n const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER)\n const requestConfigService = requestContainer.resolve<IOpenAPIConfigService>(\n OPENAPI_TOKENS.ConfigService\n )\n const effectiveConfig = requestConfigService.getEffectiveConfig()\n const uiContext = { specUrl: effectiveConfig.jsonPath, title: effectiveConfig.info.title }\n\n if (uiRenderer) {\n return uiRenderer(uiContext)(c, next)\n }\n\n const { swaggerUI } = await import('@hono/swagger-ui')\n return swaggerUI<RouterEnv>({ url: uiContext.specUrl })(c, next)\n })\n this.nameLastHandler(app, 'OpenAPI', 'docs')\n }\n }\n\n private nameLastHandler(app: OpenAPIHono<RouterEnv>, controller: string, method: string): void {\n const last = app.routes[app.routes.length - 1]\n Object.defineProperty(last.handler, 'name', { value: `http:${controller}.${method}` })\n }\n\n /**\n * Get localized security scheme definitions\n */\n private getSecuritySchemeDefinitions(i18n: II18nService) {\n return {\n [SECURITY_SCHEMES.BEARER_AUTH]: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n description: i18n.t('common.api.security.bearerAuth')\n },\n [SECURITY_SCHEMES.API_KEY]: {\n type: 'apiKey',\n in: 'header',\n name: 'X-API-Key',\n description: i18n.t('common.api.security.apiKey')\n },\n [SECURITY_SCHEMES.SESSION_COOKIE]: {\n type: 'apiKey',\n in: 'cookie',\n name: 'session',\n description: i18n.t('common.api.security.sessionCookie')\n }\n } as const\n }\n\n /**\n * Filter OpenAPI paths using custom routeFilter\n */\n private filterRoutes(\n paths: Record<string, PathItemObject>,\n config: OpenAPIEffectiveConfig\n ): Record<string, PathItemObject> {\n const filteredPaths: Record<string, PathItemObject> = {}\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (config.routeFilter && !config.routeFilter(path, pathItem)) {\n continue\n }\n\n filteredPaths[path] = pathItem\n }\n\n return filteredPaths\n }\n\n /**\n * Filter unreferenced schemas from OpenAPI spec\n */\n private filterSchemas(spec: Record<string, unknown>): Record<string, unknown> {\n const referencedSchemas = new Set<string>()\n\n // Collect all schema references from paths\n this.collectSchemaRefs(spec.paths, referencedSchemas)\n\n // Filter schemas to only include referenced ones\n const filteredSchemas: Record<string, unknown> = {}\n const components = spec.components as Record<string, unknown> | undefined\n if (components?.schemas) {\n const allSchemas = components.schemas as Record<string, unknown>\n let prevSize = 0\n while (referencedSchemas.size > prevSize) {\n prevSize = referencedSchemas.size\n for (const [schemaName, schemaValue] of Object.entries(allSchemas)) {\n if (referencedSchemas.has(schemaName) && !filteredSchemas[schemaName]) {\n filteredSchemas[schemaName] = schemaValue\n this.collectSchemaRefs(schemaValue, referencedSchemas)\n }\n }\n }\n }\n\n return filteredSchemas\n }\n\n /**\n * Recursively collect all schema references from an object\n */\n private collectSchemaRefs(obj: unknown, refs: Set<string>): void {\n if (!obj || typeof obj !== 'object') {\n return\n }\n\n const record = obj as Record<string, unknown>\n\n // Check if this object has a $ref property\n if (record.$ref && typeof record.$ref === 'string') {\n // Extract schema name from $ref (format: #/components/schemas/SchemaName)\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(record.$ref)\n if (match) {\n refs.add(match[1])\n }\n }\n\n // Recursively check all properties\n if (Array.isArray(obj)) {\n for (const item of obj) {\n this.collectSchemaRefs(item, refs)\n }\n } else {\n for (const value of Object.values(record)) {\n this.collectSchemaRefs(value, refs)\n }\n }\n }\n}\n","/**\n * OpenAPI Module\n *\n * Provides configurable OpenAPI documentation endpoints with runtime override support.\n *\n * Features:\n * - Configurable paths for /openapi.json and /docs\n * - Runtime config overrides via middleware\n * - i18n support for titles and descriptions\n * - Route filtering via hideFromDocs and custom routeFilter\n *\n * @example Basic usage\n * ```typescript\n * @Module({\n * imports: [\n * OpenAPIModule.forRoot({\n * info: { title: 'My API', version: '1.0.0' }\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n *\n * @example With runtime override in middleware\n * ```typescript\n * // In RouteAccessMiddleware\n * constructor(\n * @inject(OPENAPI_TOKENS.ConfigService) private openAPIConfig: IOpenAPIConfigService\n * ) {}\n *\n * async handle(ctx, next) {\n * this.openAPIConfig.override({\n * info: { title: 'Custom API' },\n * routeFilter: (path) => this.shouldInclude(path)\n * })\n * await next()\n * }\n * ```\n */\n\nimport { Module } from '../module'\nimport type { AsyncModuleOptions, DynamicModule } from '../module/types'\nimport { OPENAPI_TOKENS } from './openapi.tokens'\nimport { OpenAPIConfigService, OpenAPIConfigStore, OpenAPIService } from './services'\nimport type { OpenAPIModuleOptions } from './types'\n\n/** Default options when none provided */\nconst DEFAULT_OPTIONS: OpenAPIModuleOptions = {\n jsonPath: '/api/openapi.json',\n info: {\n title: 'API',\n version: '1.0.0'\n }\n}\n\n@Module({\n providers: [\n // Static base config (singleton — resolvable outside a request scope)\n { provide: OPENAPI_TOKENS.ConfigStore, useClass: OpenAPIConfigStore },\n // OpenAPI config service (request-scoped, supports runtime overrides)\n { provide: OPENAPI_TOKENS.ConfigService, useClass: OpenAPIConfigService },\n // OpenAPI service (singleton — serves spec and docs endpoints)\n { provide: OPENAPI_TOKENS.OpenAPIService, useClass: OpenAPIService },\n ],\n})\nexport class OpenAPIModule {\n /**\n * Configure OpenAPI module with static options\n *\n * @param options - OpenAPI configuration (paths, info, security schemes)\n * @returns DynamicModule with options provider\n */\n static forRoot(options: OpenAPIModuleOptions = {}): DynamicModule {\n // Merge with defaults\n const mergedOptions: OpenAPIModuleOptions = {\n ...DEFAULT_OPTIONS,\n ...options,\n info: {\n ...DEFAULT_OPTIONS.info,\n ...options.info,\n title: options.info?.title ?? DEFAULT_OPTIONS.info?.title ?? 'API',\n version: options.info?.version ?? DEFAULT_OPTIONS.info?.version ?? '1.0.0',\n }\n }\n\n return {\n module: OpenAPIModule,\n providers: [\n { provide: OPENAPI_TOKENS.Options, useValue: mergedOptions }\n ]\n }\n }\n\n static forRootAsync(options: AsyncModuleOptions<OpenAPIModuleOptions>): DynamicModule {\n return {\n module: OpenAPIModule,\n providers: [\n {\n provide: OPENAPI_TOKENS.Options,\n useFactory: options.useFactory,\n inject: options.inject\n },\n ]\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"openapi-BKDwQKh-.mjs","names":[],"sources":["../src/openapi/services/openapi-config.service.ts","../src/openapi/services/openapi-config.store.ts","../src/openapi/services/openapi.service.ts","../src/openapi/openapi.module.ts"],"sourcesContent":["import { inject } from '../../di'\nimport { Request } from '../../di/decorators'\nimport { OPENAPI_TOKENS } from '../openapi.tokens'\nimport type {\n IOpenAPIConfigService,\n IOpenAPIConfigStore,\n OpenAPIConfigOverride,\n OpenAPIEffectiveConfig\n} from '../types'\n\n/**\n * OpenAPI Config Service\n *\n * Request-scoped service that manages OpenAPI configuration for the current request.\n * Supports runtime overrides via middleware while preserving base configuration.\n *\n * @example\n * ```typescript\n * // In middleware (e.g., RouteAccessMiddleware)\n * constructor(\n * @inject(OPENAPI_TOKENS.ConfigService) private openAPIConfig: IOpenAPIConfigService\n * ) {}\n *\n * async handle(ctx, next) {\n * this.openAPIConfig.override({\n * info: { title: 'Custom API' },\n * routeFilter: (path) => shouldInclude(path)\n * })\n * await next()\n * }\n * ```\n */\n@Request(OPENAPI_TOKENS.ConfigService)\nexport class OpenAPIConfigService implements IOpenAPIConfigService {\n private overrides: OpenAPIConfigOverride[] = []\n\n constructor(\n @inject(OPENAPI_TOKENS.ConfigStore) private store: IOpenAPIConfigStore\n ) { }\n\n /**\n * Add configuration override for this request.\n * Overrides are merged in the order they are added.\n */\n override(config: OpenAPIConfigOverride): void {\n this.overrides.push(config)\n }\n\n /** Get effective configuration (base merged with all overrides) */\n getEffectiveConfig(): OpenAPIEffectiveConfig {\n let effective = this.store.getBaseConfig()\n\n for (const override of this.overrides) {\n effective = this.mergeConfig(effective, override)\n }\n\n return effective\n }\n\n /**\n * Merge override into effective config.\n * Info is shallow-merged, routeFilter is replaced.\n */\n private mergeConfig(\n base: OpenAPIEffectiveConfig,\n override: OpenAPIConfigOverride\n ): OpenAPIEffectiveConfig {\n return {\n ...base,\n info: {\n ...base.info,\n ...(override.info && {\n title: override.info.title ?? base.info.title,\n version: override.info.version ?? base.info.version,\n description: override.info.description ?? base.info.description\n })\n },\n routeFilter: override.routeFilter ?? base.routeFilter\n }\n }\n}\n","import { inject } from '../../di'\nimport { Singleton } from '../../di/decorators'\nimport { OPENAPI_TOKENS } from '../openapi.tokens'\nimport type {\n IOpenAPIConfigStore,\n OpenAPIEffectiveConfig,\n OpenAPIModuleOptions\n} from '../types'\n\n/**\n * OpenAPI Config Store\n *\n * Singleton holder of the static base configuration (mount paths, base info,\n * security schemes) derived from `OpenAPIModule.forRoot()` options. It carries\n * no per-request state, so it is the thing to resolve when you need OpenAPI\n * config OUTSIDE a request scope — endpoint mounting at bootstrap, the\n * `mcp:serve` CLI command, etc. Resolving it never throws on its own.\n *\n * Per-request overrides live on {@link OpenAPIConfigService}, which reads the\n * base config from here and merges its overrides on top.\n */\n@Singleton(OPENAPI_TOKENS.ConfigStore)\nexport class OpenAPIConfigStore implements IOpenAPIConfigStore {\n constructor(\n @inject(OPENAPI_TOKENS.Options, { isOptional: true }) private baseOptions?: OpenAPIModuleOptions\n ) { }\n\n getBaseConfig(): OpenAPIEffectiveConfig {\n return {\n jsonPath: this.baseOptions?.jsonPath ?? '/api/openapi.json',\n ui: this.baseOptions?.ui,\n info: {\n title: this.baseOptions?.info?.title ?? 'API',\n version: this.baseOptions?.info?.version ?? '1.0.0',\n description: this.baseOptions?.info?.description\n },\n securitySchemes: this.baseOptions?.securitySchemes\n }\n }\n}\n","import type { Container } from '../../di/container'\nimport { Singleton } from '../../di/decorators'\nimport { I18N_TOKENS } from '../../i18n/i18n.tokens'\nimport type { II18nService } from '../../i18n/i18n.types'\nimport type { OpenAPIHono, OpenAPIObject, PathItemObject } from '../../i18n/validation/zod'\nimport { ROUTER_CONTEXT_KEYS, SECURITY_SCHEMES } from '../../router/constants'\nimport type { RouterEnv } from '../../router/types'\nimport { OPENAPI_TOKENS } from '../openapi.tokens'\nimport type { IOpenAPIConfigService, IOpenAPIConfigStore, OpenAPIEffectiveConfig } from '../types'\n\n/**\n * OpenAPI Service\n *\n * Generates OpenAPI specifications with support for:\n * - Runtime configuration via OpenAPIConfigService\n * - Route filtering via custom routeFilter\n * - i18n support for titles and descriptions\n * - Security scheme definitions\n *\n * Hidden routes (hideFromDocs) are excluded at registration time via\n * @hono/zod-openapi's `hide` option and don't appear in the spec.\n *\n * Configuration is resolved per-request from OpenAPIConfigService,\n * allowing middleware to override config based on domain context.\n */\n@Singleton(OPENAPI_TOKENS.OpenAPIService)\nexport class OpenAPIService {\n\n /**\n * Generate a filtered OpenAPI spec using the user's config.\n * Usable from both HTTP handlers and CLI commands.\n */\n getSpec(app: OpenAPIHono<RouterEnv>, container: Container): OpenAPIObject {\n const configService = container.resolve<IOpenAPIConfigService>(OPENAPI_TOKENS.ConfigService)\n const i18n = container.resolve<II18nService>(I18N_TOKENS.I18nService)\n const config = configService.getEffectiveConfig()\n\n const fullSpec = app.getOpenAPIDocument({\n openapi: '3.0.0',\n info: {\n version: config.info.version,\n title: config.info.title,\n description: config.info.description,\n },\n })\n\n // Security schemes\n fullSpec.components ??= {}\n fullSpec.components.securitySchemes = this.getSecuritySchemeDefinitions(i18n)\n\n // Apply custom routeFilter if provided\n if (config.routeFilter) {\n fullSpec.paths = this.filterRoutes(\n fullSpec.paths as Record<string, PathItemObject>,\n config,\n )\n }\n\n // Filter unreferenced schemas\n if (fullSpec.components.schemas) {\n fullSpec.components.schemas = this.filterSchemas(fullSpec as unknown as Record<string, unknown>) as typeof fullSpec.components.schemas\n }\n\n return fullSpec\n }\n\n /**\n * Setup OpenAPI documentation endpoints\n */\n setupEndpoints(app: OpenAPIHono<RouterEnv>, container: Container): void {\n // Endpoints are mounted at bootstrap (no request scope), so read the static\n // mount paths from the singleton config store — request overrides (info /\n // routeFilter) never affect jsonPath/ui and are resolved per request inside\n // the handlers below via the request-scoped config service.\n const config = container.resolve<IOpenAPIConfigStore>(OPENAPI_TOKENS.ConfigStore).getBaseConfig()\n const jsonPath = config.jsonPath\n const ui = config.ui\n\n // OpenAPI JSON spec endpoint\n app.get(jsonPath, (c) => {\n const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER)\n const fullSpec = this.getSpec(app, requestContainer)\n\n // Add servers (HTTP-specific — needs request URL context)\n const url = new URL(c.req.raw.url)\n const i18n = requestContainer.resolve<II18nService>(I18N_TOKENS.I18nService)\n fullSpec.servers = [{\n url: `${url.protocol}//${url.host}`,\n description: i18n.t('common.api.serverDescription'),\n }]\n\n return c.json(fullSpec)\n })\n this.nameLastHandler(app, 'OpenAPI', 'spec')\n\n // Docs UI endpoint\n if (ui !== false) {\n const uiPath = ui?.path ?? '/api/docs'\n const uiRenderer = ui?.renderer\n\n app.get(uiPath, async (c, next) => {\n const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER)\n const requestConfigService = requestContainer.resolve<IOpenAPIConfigService>(\n OPENAPI_TOKENS.ConfigService\n )\n const effectiveConfig = requestConfigService.getEffectiveConfig()\n const uiContext = { specUrl: effectiveConfig.jsonPath, title: effectiveConfig.info.title }\n\n if (uiRenderer) {\n return uiRenderer(uiContext)(c, next)\n }\n\n const { swaggerUI } = await import('@hono/swagger-ui')\n return swaggerUI<RouterEnv>({ url: uiContext.specUrl })(c, next)\n })\n this.nameLastHandler(app, 'OpenAPI', 'docs')\n }\n }\n\n private nameLastHandler(app: OpenAPIHono<RouterEnv>, controller: string, method: string): void {\n const last = app.routes[app.routes.length - 1]\n Object.defineProperty(last.handler, 'name', { value: `http:${controller}.${method}` })\n }\n\n /**\n * Get localized security scheme definitions\n */\n private getSecuritySchemeDefinitions(i18n: II18nService) {\n return {\n [SECURITY_SCHEMES.BEARER_AUTH]: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n description: i18n.t('common.api.security.bearerAuth')\n },\n [SECURITY_SCHEMES.API_KEY]: {\n type: 'apiKey',\n in: 'header',\n name: 'X-API-Key',\n description: i18n.t('common.api.security.apiKey')\n },\n [SECURITY_SCHEMES.SESSION_COOKIE]: {\n type: 'apiKey',\n in: 'cookie',\n name: 'session',\n description: i18n.t('common.api.security.sessionCookie')\n }\n } as const\n }\n\n /**\n * Filter OpenAPI paths using custom routeFilter\n */\n private filterRoutes(\n paths: Record<string, PathItemObject>,\n config: OpenAPIEffectiveConfig\n ): Record<string, PathItemObject> {\n const filteredPaths: Record<string, PathItemObject> = {}\n\n for (const [path, pathItem] of Object.entries(paths)) {\n if (config.routeFilter && !config.routeFilter(path, pathItem)) {\n continue\n }\n\n filteredPaths[path] = pathItem\n }\n\n return filteredPaths\n }\n\n /**\n * Filter unreferenced schemas from OpenAPI spec\n */\n private filterSchemas(spec: Record<string, unknown>): Record<string, unknown> {\n const referencedSchemas = new Set<string>()\n\n // Collect all schema references from paths\n this.collectSchemaRefs(spec.paths, referencedSchemas)\n\n // Filter schemas to only include referenced ones\n const filteredSchemas: Record<string, unknown> = {}\n const components = spec.components as Record<string, unknown> | undefined\n if (components?.schemas) {\n const allSchemas = components.schemas as Record<string, unknown>\n let prevSize = 0\n while (referencedSchemas.size > prevSize) {\n prevSize = referencedSchemas.size\n for (const [schemaName, schemaValue] of Object.entries(allSchemas)) {\n if (referencedSchemas.has(schemaName) && !filteredSchemas[schemaName]) {\n filteredSchemas[schemaName] = schemaValue\n this.collectSchemaRefs(schemaValue, referencedSchemas)\n }\n }\n }\n }\n\n return filteredSchemas\n }\n\n /**\n * Recursively collect all schema references from an object\n */\n private collectSchemaRefs(obj: unknown, refs: Set<string>): void {\n if (!obj || typeof obj !== 'object') {\n return\n }\n\n const record = obj as Record<string, unknown>\n\n // Check if this object has a $ref property\n if (record.$ref && typeof record.$ref === 'string') {\n // Extract schema name from $ref (format: #/components/schemas/SchemaName)\n const match = /^#\\/components\\/schemas\\/(.+)$/.exec(record.$ref)\n if (match) {\n refs.add(match[1])\n }\n }\n\n // Recursively check all properties\n if (Array.isArray(obj)) {\n for (const item of obj) {\n this.collectSchemaRefs(item, refs)\n }\n } else {\n for (const value of Object.values(record)) {\n this.collectSchemaRefs(value, refs)\n }\n }\n }\n}\n","/**\n * OpenAPI Module\n *\n * Provides configurable OpenAPI documentation endpoints with runtime override support.\n *\n * Features:\n * - Configurable paths for /openapi.json and /docs\n * - Runtime config overrides via middleware\n * - i18n support for titles and descriptions\n * - Route filtering via hideFromDocs and custom routeFilter\n *\n * @example Basic usage\n * ```typescript\n * @Module({\n * imports: [\n * OpenAPIModule.forRoot({\n * info: { title: 'My API', version: '1.0.0' }\n * })\n * ]\n * })\n * export class AppModule {}\n * ```\n *\n * @example With runtime override in middleware\n * ```typescript\n * // In RouteAccessMiddleware\n * constructor(\n * @inject(OPENAPI_TOKENS.ConfigService) private openAPIConfig: IOpenAPIConfigService\n * ) {}\n *\n * async handle(ctx, next) {\n * this.openAPIConfig.override({\n * info: { title: 'Custom API' },\n * routeFilter: (path) => this.shouldInclude(path)\n * })\n * await next()\n * }\n * ```\n */\n\nimport { Module } from '../module'\nimport type { AsyncModuleOptions, DynamicModule } from '../module/types'\nimport { OPENAPI_TOKENS } from './openapi.tokens'\nimport { OpenAPIConfigService, OpenAPIConfigStore, OpenAPIService } from './services'\nimport type { OpenAPIModuleOptions } from './types'\n\n/** Default options when none provided */\nconst DEFAULT_OPTIONS: OpenAPIModuleOptions = {\n jsonPath: '/api/openapi.json',\n info: {\n title: 'API',\n version: '1.0.0'\n }\n}\n\n@Module({\n providers: [\n // Static base config (singleton — resolvable outside a request scope)\n { provide: OPENAPI_TOKENS.ConfigStore, useClass: OpenAPIConfigStore },\n // OpenAPI config service (request-scoped, supports runtime overrides)\n { provide: OPENAPI_TOKENS.ConfigService, useClass: OpenAPIConfigService },\n // OpenAPI service (singleton — serves spec and docs endpoints)\n { provide: OPENAPI_TOKENS.OpenAPIService, useClass: OpenAPIService },\n ],\n})\nexport class OpenAPIModule {\n /**\n * Configure OpenAPI module with static options\n *\n * @param options - OpenAPI configuration (paths, info, security schemes)\n * @returns DynamicModule with options provider\n */\n static forRoot(options: OpenAPIModuleOptions = {}): DynamicModule {\n // Merge with defaults\n const mergedOptions: OpenAPIModuleOptions = {\n ...DEFAULT_OPTIONS,\n ...options,\n info: {\n ...DEFAULT_OPTIONS.info,\n ...options.info,\n title: options.info?.title ?? DEFAULT_OPTIONS.info?.title ?? 'API',\n version: options.info?.version ?? DEFAULT_OPTIONS.info?.version ?? '1.0.0',\n }\n }\n\n return {\n module: OpenAPIModule,\n providers: [\n { provide: OPENAPI_TOKENS.Options, useValue: mergedOptions }\n ]\n }\n }\n\n static forRootAsync(options: AsyncModuleOptions<OpenAPIModuleOptions>): DynamicModule {\n return {\n module: OpenAPIModule,\n providers: [\n {\n provide: OPENAPI_TOKENS.Options,\n useFactory: options.useFactory,\n inject: options.inject\n },\n ]\n }\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Y as Container, or as RouterEnv } from "./index-B_JoEl3V.mjs";
1
+ import { Y as Container, or as RouterEnv } from "./index-C_t8VVQD.mjs";
2
2
  import { n as OpenAPIObject, t as OpenAPIHono } from "./zod-wecrEVAs.mjs";
3
3
 
4
4
  //#region src/openapi/services/openapi.service.d.ts
@@ -47,4 +47,4 @@ declare class OpenAPIService {
47
47
  }
48
48
  //#endregion
49
49
  export { OpenAPIService as t };
50
- //# sourceMappingURL=openapi.service-YhTiJ1bO.d.mts.map
50
+ //# sourceMappingURL=openapi.service-CM40bnBB.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.service-YhTiJ1bO.d.mts","names":[],"sources":["../src/openapi/services/openapi.service.ts"],"mappings":";;;;;AAyBA;;;;;;;;;;;;;;cACa,cAAA;EAMH;;;;EAAR,OAAA,CAAQ,GAAA,EAAK,WAAA,CAAY,SAAA,GAAY,SAAA,EAAW,SAAA,GAAY,aAAA;EAqCxC;;;EAApB,cAAA,CAAe,GAAA,EAAK,WAAA,CAAY,SAAA,GAAY,SAAA,EAAW,SAAA;EAAA,QAkD/C,eAAA;EAAA;;;EAAA,QAQA,4BAAA;EA2EA;;AAAiB;EAAjB,QAjDA,YAAA;;;;UAoBA,aAAA;;;;UA6BA,iBAAA;AAAA"}
1
+ {"version":3,"file":"openapi.service-CM40bnBB.d.mts","names":[],"sources":["../src/openapi/services/openapi.service.ts"],"mappings":";;;;;AAyBA;;;;;;;;;;;;;;cACa,cAAA;EAMH;;;;EAAR,OAAA,CAAQ,GAAA,EAAK,WAAA,CAAY,SAAA,GAAY,SAAA,EAAW,SAAA,GAAY,aAAA;EAqCxC;;;EAApB,cAAA,CAAe,GAAA,EAAK,WAAA,CAAY,SAAA,GAAY,SAAA,EAAW,SAAA;EAAA,QAkD/C,eAAA;EAAA;;;EAAA,QAQA,4BAAA;EA2EA;;AAAiB;EAAjB,QAjDA,YAAA;;;;UAoBA,aAAA;;;;UA6BA,iBAAA;AAAA"}
@@ -1,7 +1,7 @@
1
- import { Cn as ParsedArgument, En as Quarry, Sn as CommandResult, Tn as ParsedSignature, bn as CommandInput, wn as ParsedOption } from "../index-B_JoEl3V.mjs";
1
+ import { Cn as ParsedArgument, En as Quarry, Sn as CommandResult, Tn as ParsedSignature, bn as CommandInput, wn as ParsedOption } from "../index-C_t8VVQD.mjs";
2
2
  import { t as Constructor } from "../types-CmV_9xBD.mjs";
3
- import { t as Command } from "../command-CPhFHjG3.mjs";
4
- import { t as QuarryRegistry } from "../quarry-registry-CXg0RFXq.mjs";
3
+ import { t as Command } from "../command-4HnKnC-G.mjs";
4
+ import { t as QuarryRegistry } from "../quarry-registry-CsStq0DB.mjs";
5
5
 
6
6
  //#region src/quarry/errors/command-not-found.error.d.ts
7
7
  /**
@@ -1,6 +1,6 @@
1
1
  import { n as CommandError, t as Command } from "../command-BvmUAPPQ.mjs";
2
2
  import { t as isCommand } from "../is-command-CEPO9n8c.mjs";
3
3
  import { t as CommandNotFoundError } from "../command-not-found.error-ONAZ2Bpk.mjs";
4
- import { i as parseSignature, r as QuarryRegistry, t as QuarryModule } from "../quarry.module-BuRPGMDm.mjs";
4
+ import { i as parseSignature, r as QuarryRegistry, t as QuarryModule } from "../quarry.module-BOgcNJMU.mjs";
5
5
  import { t as generateUsage } from "../usage-generator-DAWYasuP.mjs";
6
6
  export { Command, CommandError, CommandNotFoundError, QuarryModule, QuarryRegistry, generateUsage, isCommand, parseSignature };
@@ -1,11 +1,11 @@
1
- import { ct as Application, d as ExceptionHandler, ln as ModuleRegistry, mn as LocalePathService, sn as RouteRegistry } from "../index-B_JoEl3V.mjs";
1
+ import { ct as Application, d as ExceptionHandler, ln as ModuleRegistry, mn as LocalePathService, sn as RouteRegistry } from "../index-C_t8VVQD.mjs";
2
2
  import { t as Constructor } from "../types-CmV_9xBD.mjs";
3
3
  import { n as ConsumerRegistry } from "../consumer-registry-D3iMTSdy.mjs";
4
- import { t as Stratal } from "../stratal-DwDJPY9N.mjs";
5
- import { t as LazyModuleLoader } from "../lazy-module-loader-Ib383jH_.mjs";
6
- import { t as OpenAPIService } from "../openapi.service-YhTiJ1bO.mjs";
7
- import { t as Command } from "../command-CPhFHjG3.mjs";
8
- import { t as QuarryRegistry } from "../quarry-registry-CXg0RFXq.mjs";
4
+ import { t as Stratal } from "../stratal-Bmc6WT3k.mjs";
5
+ import { t as LazyModuleLoader } from "../lazy-module-loader-DZQxOgRZ.mjs";
6
+ import { t as OpenAPIService } from "../openapi.service-CM40bnBB.mjs";
7
+ import { t as Command } from "../command-4HnKnC-G.mjs";
8
+ import { t as QuarryRegistry } from "../quarry-registry-CsStq0DB.mjs";
9
9
 
10
10
  //#region src/quarry/builtin-quarry.module.d.ts
11
11
  /**
@@ -1,15 +1,15 @@
1
- import { d as inject, r as DI_TOKENS, v as ROUTER_TOKENS } from "../di-DseMn-z9.mjs";
1
+ import { d as inject, r as DI_TOKENS, v as ROUTER_TOKENS } from "../di-B0NXIdRF.mjs";
2
2
  import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
3
3
  import "../logger/index.mjs";
4
- import { a as getListenerHandlers } from "../events-BXJGZjpG.mjs";
4
+ import { a as getListenerHandlers } from "../events-zbCMY_Gf.mjs";
5
5
  import { n as Module } from "../module.decorator-CYHY6pG5.mjs";
6
6
  import { a as cyan, c as green, i as bold, l as red, t as Command, u as yellow } from "../command-BvmUAPPQ.mjs";
7
- import { t as Stratal } from "../stratal-DL9M38_s.mjs";
7
+ import { t as Stratal } from "../stratal-DtAj21uF.mjs";
8
8
  import { t as QUEUE_TOKENS } from "../queue.tokens-DjHnFmre.mjs";
9
9
  import { t as I18N_TOKENS } from "../i18n.tokens-CZ_v8oyS.mjs";
10
10
  import { n as OPENAPI_TOKENS, t as OpenApiToolsService } from "../openapi-tools.service-BC5EC3R3.mjs";
11
11
  import { t as CommandNotFoundError } from "../command-not-found.error-ONAZ2Bpk.mjs";
12
- import { n as DbSeedListCommand, t as DbSeedCommand } from "../seeder-7ubkms-Y.mjs";
12
+ import { n as DbSeedListCommand, t as DbSeedCommand } from "../seeder-DI-rUoZx.mjs";
13
13
  import { z } from "zod";
14
14
  import { writeFileSync } from "node:fs";
15
15
  import { resolve } from "node:path";
@@ -863,7 +863,7 @@ let ScheduleListCommand = class ScheduleListCommand extends Command {
863
863
  this.loader = loader;
864
864
  }
865
865
  async handle() {
866
- const cron = (await this.loader.load(() => import("../cron.module-Bgzq5hiT.mjs").then((n) => n.n).then((m) => m.CronModule))).get(DI_TOKENS.Cron);
866
+ const cron = (await this.loader.load(() => import("../cron.module-DgxLe8Xy.mjs").then((n) => n.n).then((m) => m.CronModule))).get(DI_TOKENS.Cron);
867
867
  const schedules = cron.getAllSchedules();
868
868
  if (schedules.length === 0) {
869
869
  this.info("No cron jobs found");
@@ -1,6 +1,6 @@
1
- import { En as Quarry, Sn as CommandResult, Y as Container, bn as CommandInput } from "./index-B_JoEl3V.mjs";
1
+ import { En as Quarry, Sn as CommandResult, Y as Container, bn as CommandInput } from "./index-C_t8VVQD.mjs";
2
2
  import { t as Constructor } from "./types-CmV_9xBD.mjs";
3
- import { t as Command } from "./command-CPhFHjG3.mjs";
3
+ import { t as Command } from "./command-4HnKnC-G.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-CXg0RFXq.d.mts.map
69
+ //# sourceMappingURL=quarry-registry-CsStq0DB.d.mts.map
@@ -1 +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
+ {"version":3,"file":"quarry-registry-CsStq0DB.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,8 +1,8 @@
1
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";
2
+ import { d as inject, r as DI_TOKENS, s as Singleton } from "./di-B0NXIdRF.mjs";
3
3
  import { n as getContainer } from "./container-storage-BmOJ4_Na.mjs";
4
4
  import { n as __decorateParam, t as __decorate } from "./decorate-CuAoSZvs.mjs";
5
- import { t as createCliExceptionContext } from "./exception-context-kEoMFwze.mjs";
5
+ import { t as createCliExceptionContext } from "./exception-context-Bd5Hk2c_.mjs";
6
6
  import { n as Module } from "./module.decorator-CYHY6pG5.mjs";
7
7
  import { n as CommandError, r as COMMAND_INTERNALS } from "./command-BvmUAPPQ.mjs";
8
8
  import { t as CommandNotFoundError } from "./command-not-found.error-ONAZ2Bpk.mjs";
@@ -309,4 +309,4 @@ QuarryModule = __decorate([Module({ providers: [{
309
309
  //#endregion
310
310
  export { parseSignature as i, quarry_module_exports as n, QuarryRegistry as r, QuarryModule as t };
311
311
 
312
- //# sourceMappingURL=quarry.module-BuRPGMDm.mjs.map
312
+ //# sourceMappingURL=quarry.module-BOgcNJMU.mjs.map
@@ -1 +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
+ {"version":3,"file":"quarry.module-BOgcNJMU.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
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";
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-BPJSBHhq.mjs";
3
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,7 +1,7 @@
1
- import { c as Transient, d as inject } from "../di-DseMn-z9.mjs";
1
+ import { c as Transient, d as inject } from "../di-B0NXIdRF.mjs";
2
2
  import { n as __decorateParam, t as __decorate } from "../decorate-CuAoSZvs.mjs";
3
3
  import { LOGGER_TOKENS } from "../logger/index.mjs";
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";
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-DSAH88gZ.mjs";
5
5
  import { t as QUEUE_TOKENS } from "../queue.tokens-DjHnFmre.mjs";
6
6
  //#region src/queue/jobs/failed-job-cleanup.job.ts
7
7
  /** Retention applied when `failedJobs.retention` is not configured. */
@@ -1,9 +1,9 @@
1
1
  import { t as __exportAll } from "./chunk-BBjsoOtd.mjs";
2
- import { c as Transient, d as inject, o as Request, r as DI_TOKENS, s as Singleton } from "./di-DseMn-z9.mjs";
2
+ import { c as Transient, d as inject, o as Request, r as DI_TOKENS, s as Singleton } from "./di-B0NXIdRF.mjs";
3
3
  import { a as ApplicationError, n as getContainer, t as containerStorage } from "./container-storage-BmOJ4_Na.mjs";
4
4
  import { n as __decorateParam, t as __decorate } from "./decorate-CuAoSZvs.mjs";
5
5
  import { LOGGER_TOKENS } from "./logger/index.mjs";
6
- import "./errors-mXYxG0XB.mjs";
6
+ import "./errors-EUtwVfNm.mjs";
7
7
  import { n as Module } from "./module.decorator-CYHY6pG5.mjs";
8
8
  import "./module/index.mjs";
9
9
  import { CACHE_TOKENS, CacheModule } from "./cache/index.mjs";
@@ -610,4 +610,4 @@ QueueModule = _QueueModule = __decorate([Module({
610
610
  //#endregion
611
611
  export { CloudflareQueueProvider as a, QueueRegistry as c, QueueManager as d, QueueError as f, SyncQueueProvider as i, QueueSender as l, queue_module_exports as n, DEFAULT_STORE_BINDING as o, QueueProviderFactory as r, QueueStore as s, QueueModule as t, ConsumerRegistry as u };
612
612
 
613
- //# sourceMappingURL=queue.module-nddvxzCB.mjs.map
613
+ //# sourceMappingURL=queue.module-DSAH88gZ.mjs.map