stratal 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{base-email.provider-CfQCA08m.mjs → base-email.provider-BWZHIjt8.mjs} +1 -1
- package/dist/{base-email.provider-CfQCA08m.mjs.map → base-email.provider-BWZHIjt8.mjs.map} +1 -1
- package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
- package/dist/bin/quarry.mjs +46 -109
- package/dist/bin/quarry.mjs.map +1 -1
- package/dist/cache/index.d.mts +6 -46
- package/dist/cache/index.d.mts.map +1 -1
- package/dist/cache/index.mjs +22 -67
- package/dist/cache/index.mjs.map +1 -1
- package/dist/{cache.service-DsnKuNyO.d.mts → cache.service-e34gV6tz.d.mts} +8 -8
- package/dist/{cache.service-DsnKuNyO.d.mts.map → cache.service-e34gV6tz.d.mts.map} +1 -1
- package/dist/{cache.tokens-B7Rw1C9Q.mjs → cache.tokens-ovi_c52J.mjs} +1 -1
- package/dist/{cache.tokens-B7Rw1C9Q.mjs.map → cache.tokens-ovi_c52J.mjs.map} +1 -1
- package/dist/{colors-DJaRDXoS.mjs → colors-axmupKdp.mjs} +1 -1
- package/dist/{colors-DJaRDXoS.mjs.map → colors-axmupKdp.mjs.map} +1 -1
- package/dist/{command-BgSlsS4M.mjs → command-BU4ApTo5.mjs} +2 -3
- package/dist/command-BU4ApTo5.mjs.map +1 -0
- package/dist/{command-Bu-PjJrX.d.mts → command-wXfvHbBZ.d.mts} +3 -2
- package/dist/command-wXfvHbBZ.d.mts.map +1 -0
- package/dist/config/index.d.mts +24 -11
- package/dist/config/index.d.mts.map +1 -1
- package/dist/config/index.mjs +33 -57
- package/dist/config/index.mjs.map +1 -1
- package/dist/{consumer-registry-B7yUNh0q.d.mts → consumer-registry-DHQtypr1.d.mts} +1 -1
- package/dist/{consumer-registry-B7yUNh0q.d.mts.map → consumer-registry-DHQtypr1.d.mts.map} +1 -1
- package/dist/container-storage-GpNNz79X.mjs +52 -0
- package/dist/container-storage-GpNNz79X.mjs.map +1 -0
- package/dist/{controller.decorator-DQzenvSN.mjs → controller.decorator-DIUazNU7.mjs} +8 -8
- package/dist/controller.decorator-DIUazNU7.mjs.map +1 -0
- package/dist/cron/index.d.mts +26 -5
- package/dist/cron/index.d.mts.map +1 -1
- package/dist/cron/index.mjs +1 -1
- package/dist/{cron-manager-7Symz_TE.mjs → cron-manager-9bpN9bu4.mjs} +42 -16
- package/dist/cron-manager-9bpN9bu4.mjs.map +1 -0
- package/dist/{cron-manager-BEsH1mjW.d.mts → cron-manager-CSTIBPcM.d.mts} +6 -13
- package/dist/cron-manager-CSTIBPcM.d.mts.map +1 -0
- package/dist/decorate-HgTKAYK8.mjs +16 -0
- package/dist/deep-merge-C8NgcXw4.mjs +18 -0
- package/dist/deep-merge-C8NgcXw4.mjs.map +1 -0
- package/dist/di/index.d.mts +2 -2
- package/dist/di/index.mjs +4 -3
- package/dist/di-BO1QIb5H.mjs +415 -0
- package/dist/di-BO1QIb5H.mjs.map +1 -0
- package/dist/email/index.d.mts +14 -89
- package/dist/email/index.d.mts.map +1 -1
- package/dist/email/index.mjs +30 -125
- package/dist/email/index.mjs.map +1 -1
- package/dist/en-BPP6h6y5.mjs +202 -0
- package/dist/en-BPP6h6y5.mjs.map +1 -0
- package/dist/{env-D1rcZ8_r.d.mts → env-DKSbuBi5.d.mts} +1 -1
- package/dist/env-DKSbuBi5.d.mts.map +1 -0
- package/dist/errors/index.d.mts +2 -2
- package/dist/errors/index.mjs +4 -2
- package/dist/errors-BBZTnjdq.mjs +333 -0
- package/dist/errors-BBZTnjdq.mjs.map +1 -0
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.d.mts.map +1 -1
- package/dist/events/index.mjs +1 -1
- package/dist/{events-COKixqnG.mjs → events-D1KdDaiP.mjs} +13 -11
- package/dist/events-D1KdDaiP.mjs.map +1 -0
- package/dist/exception-context-B4kM-M53.mjs +429 -0
- package/dist/exception-context-B4kM-M53.mjs.map +1 -0
- package/dist/{gateway-context-CdJjpUCW.mjs → gateway-context-CFe6a9gz.mjs} +20 -31
- package/dist/gateway-context-CFe6a9gz.mjs.map +1 -0
- package/dist/guards/index.d.mts +3 -3
- package/dist/guards/index.d.mts.map +1 -1
- package/dist/guards/index.mjs +1 -1
- package/dist/{guards-DUk_Kzst.mjs → guards-Ced-uNIF.mjs} +7 -5
- package/dist/guards-Ced-uNIF.mjs.map +1 -0
- package/dist/{http-method.decorator-DXwxAfb_.mjs → http-method.decorator-CdjKFJZZ.mjs} +7 -6
- package/dist/http-method.decorator-CdjKFJZZ.mjs.map +1 -0
- package/dist/i18n/index.d.mts +238 -3
- package/dist/i18n/index.d.mts.map +1 -0
- package/dist/i18n/index.mjs +39 -3
- package/dist/i18n/index.mjs.map +1 -0
- package/dist/i18n/messages/en/index.d.mts +2 -2
- package/dist/i18n/messages/en/index.mjs +2 -2
- package/dist/i18n/utils/index.d.mts +4 -26
- package/dist/i18n/utils/index.d.mts.map +1 -1
- package/dist/i18n/utils/index.mjs +2 -2
- package/dist/i18n/validation/index.d.mts +3 -2
- package/dist/i18n/validation/index.mjs +4 -2
- package/dist/i18n.module-BlXrtAlV.mjs +219 -0
- package/dist/i18n.module-BlXrtAlV.mjs.map +1 -0
- package/dist/i18n.tokens-hwRpmjRq.mjs +19 -0
- package/dist/i18n.tokens-hwRpmjRq.mjs.map +1 -0
- package/dist/{index-7-hU3GTV.d.mts → index-B4UBK-2T.d.mts} +1 -1
- package/dist/{index-7-hU3GTV.d.mts.map → index-B4UBK-2T.d.mts.map} +1 -1
- package/dist/index-BtlE9RuO.d.mts +124 -0
- package/dist/index-BtlE9RuO.d.mts.map +1 -0
- package/dist/{index-CjaQ6_tZ.d.mts → index-CW1YHSft.d.mts} +71 -167
- package/dist/index-CW1YHSft.d.mts.map +1 -0
- package/dist/{index-D0US0X14.d.mts → index-DEncMcC6.d.mts} +559 -2239
- package/dist/index-DEncMcC6.d.mts.map +1 -0
- package/dist/index-Dj5IMwtr.d.mts +44 -0
- package/dist/index-Dj5IMwtr.d.mts.map +1 -0
- package/dist/{index-C1KvMncZ.d.mts → index-KMgSCSM7.d.mts} +3 -108
- package/dist/index-KMgSCSM7.d.mts.map +1 -0
- package/dist/index.d.mts +5 -43
- package/dist/index.mjs +1 -1
- package/dist/{is-command-C6a7WTPw.mjs → is-command-CX5rAfZW.mjs} +2 -2
- package/dist/{is-command-C6a7WTPw.mjs.map → is-command-CX5rAfZW.mjs.map} +1 -1
- package/dist/{is-seeder-CebjZCDn.mjs → is-seeder-CYCtELlm.mjs} +1 -1
- package/dist/{is-seeder-CebjZCDn.mjs.map → is-seeder-CYCtELlm.mjs.map} +1 -1
- package/dist/logger/index.d.mts +2 -2
- package/dist/logger/index.mjs +170 -2
- package/dist/logger/index.mjs.map +1 -0
- package/dist/macroable/index.d.mts +1 -1
- package/dist/macroable/index.mjs +1 -1
- package/dist/{macroable-BmufBshB.mjs → macroable-DzlfzT50.mjs} +1 -1
- package/dist/{macroable-BmufBshB.mjs.map → macroable-DzlfzT50.mjs.map} +1 -1
- package/dist/metadata-BVkc4aUu.mjs +39 -0
- package/dist/metadata-BVkc4aUu.mjs.map +1 -0
- package/dist/module/index.d.mts +6 -24
- package/dist/module/index.d.mts.map +1 -1
- package/dist/module/index.mjs +2 -2
- package/dist/module-xYoHba6B.mjs +422 -0
- package/dist/module-xYoHba6B.mjs.map +1 -0
- package/dist/openapi/index.d.mts +3 -3
- package/dist/openapi/index.d.mts.map +1 -1
- package/dist/openapi/index.mjs +1 -2
- package/dist/openapi-C6lm0RmV.mjs +483 -0
- package/dist/openapi-C6lm0RmV.mjs.map +1 -0
- package/dist/{openapi.service-BLgvn3hJ.d.mts → openapi.service-CrLlsXAd.d.mts} +3 -3
- package/dist/openapi.service-CrLlsXAd.d.mts.map +1 -0
- package/dist/quarry/index.d.mts +5 -163
- package/dist/quarry/index.d.mts.map +1 -1
- package/dist/quarry/index.mjs +5 -5
- package/dist/quarry/runner.d.mts +184 -0
- package/dist/quarry/runner.d.mts.map +1 -0
- package/dist/quarry/runner.mjs +775 -0
- package/dist/quarry/runner.mjs.map +1 -0
- package/dist/quarry-registry-D4hIGScf.d.mts +69 -0
- package/dist/quarry-registry-D4hIGScf.d.mts.map +1 -0
- package/dist/quarry-registry-DkraZNwn.mjs +311 -0
- package/dist/quarry-registry-DkraZNwn.mjs.map +1 -0
- package/dist/queue/index.d.mts +3 -3
- package/dist/queue/index.mjs +27 -28
- package/dist/queue/index.mjs.map +1 -1
- package/dist/{queue.module-BCdCiySt.mjs → queue.module-DeWJ0tQM.mjs} +67 -112
- package/dist/queue.module-DeWJ0tQM.mjs.map +1 -0
- package/dist/{r2-storage.provider-Co6F0ZYV.mjs → r2-storage.provider-Hfm6LdZQ.mjs} +8 -5
- package/dist/r2-storage.provider-Hfm6LdZQ.mjs.map +1 -0
- package/dist/{rate-limit.decorator--o6Q6p9w.mjs → rate-limit.decorator-D69zdZbp.mjs} +6 -11
- package/dist/rate-limit.decorator-D69zdZbp.mjs.map +1 -0
- package/dist/rate-limiter/index.d.mts +11 -50
- package/dist/rate-limiter/index.d.mts.map +1 -1
- package/dist/rate-limiter/index.mjs +25 -30
- package/dist/rate-limiter/index.mjs.map +1 -1
- package/dist/{resend.provider-M6qRLrcy.mjs → resend.provider-Ur6tU7fK.mjs} +8 -7
- package/dist/resend.provider-Ur6tU7fK.mjs.map +1 -0
- package/dist/router/index.d.mts +2 -2
- package/dist/router/index.mjs +8 -7
- package/dist/{i18n.module-BBlNNlcG.mjs → router-Cy6DjkvP.mjs} +215 -855
- package/dist/router-Cy6DjkvP.mjs.map +1 -0
- package/dist/seeder/index.d.mts +6 -11
- package/dist/seeder/index.d.mts.map +1 -1
- package/dist/seeder/index.mjs +3 -3
- package/dist/{seeder-CJAOHEIo.mjs → seeder-BADTig4n.mjs} +17 -22
- package/dist/seeder-BADTig4n.mjs.map +1 -0
- package/dist/{signed-url-BQPbv2In.mjs → signed-url-BqUqt5dF.mjs} +1 -1
- package/dist/{signed-url-BQPbv2In.mjs.map → signed-url-BqUqt5dF.mjs.map} +1 -1
- package/dist/{smtp.provider-w0Ve52Xg.mjs → smtp.provider-C129sNBT.mjs} +7 -6
- package/dist/smtp.provider-C129sNBT.mjs.map +1 -0
- package/dist/storage/index.d.mts +15 -39
- package/dist/storage/index.d.mts.map +1 -1
- package/dist/storage/index.mjs +3 -3
- package/dist/storage/providers/index.d.mts +2 -2
- package/dist/storage/providers/index.mjs +1 -1
- package/dist/{storage-1zw-6Yiz.mjs → storage-BA3ppVYM.mjs} +70 -59
- package/dist/storage-BA3ppVYM.mjs.map +1 -0
- package/dist/{storage-provider.interface-Bd6vA4ak.d.mts → storage-provider.interface-DQMtT42e.d.mts} +2 -3
- package/dist/storage-provider.interface-DQMtT42e.d.mts.map +1 -0
- package/dist/storage.error-C6FY037a.mjs +8 -0
- package/dist/storage.error-C6FY037a.mjs.map +1 -0
- package/dist/{stratal-DeEcGgdq.mjs → stratal-Bdq4IdB3.mjs} +31 -183
- package/dist/stratal-Bdq4IdB3.mjs.map +1 -0
- package/dist/stratal-BsKmvP6J.d.mts +43 -0
- package/dist/stratal-BsKmvP6J.d.mts.map +1 -0
- package/dist/{types-cySNS_lp.d.mts → types-BaeHi67f.d.mts} +1 -1
- package/dist/types-BaeHi67f.d.mts.map +1 -0
- package/dist/{usage-generator-BUdlhnCK.mjs → usage-generator-DTqaUMR9.mjs} +6 -3
- package/dist/usage-generator-DTqaUMR9.mjs.map +1 -0
- package/dist/validation-DUzcjb8Q.mjs +49 -0
- package/dist/validation-DUzcjb8Q.mjs.map +1 -0
- package/dist/validation.context-XTysWJ3b.mjs +117 -0
- package/dist/validation.context-XTysWJ3b.mjs.map +1 -0
- package/dist/websocket/index.d.mts +7 -14
- package/dist/websocket/index.d.mts.map +1 -1
- package/dist/websocket/index.mjs +2 -2
- package/dist/workers/index.d.mts +2 -2
- package/dist/workers/index.mjs +3 -2
- package/dist/workers/index.mjs.map +1 -1
- package/dist/{index-Bnpfq6uk.d.mts → zod-DvWTfRpI.d.mts} +58 -133
- package/dist/zod-DvWTfRpI.d.mts.map +1 -0
- package/dist/zod-hMa3rSHV.mjs +72 -0
- package/dist/zod-hMa3rSHV.mjs.map +1 -0
- package/package.json +20 -20
- package/dist/command-BgSlsS4M.mjs.map +0 -1
- package/dist/command-Bu-PjJrX.d.mts.map +0 -1
- package/dist/controller.decorator-DQzenvSN.mjs.map +0 -1
- package/dist/cron-manager-7Symz_TE.mjs.map +0 -1
- package/dist/cron-manager-BEsH1mjW.d.mts.map +0 -1
- package/dist/en-DSH_bhh6.mjs +0 -308
- package/dist/en-DSH_bhh6.mjs.map +0 -1
- package/dist/env-D1rcZ8_r.d.mts.map +0 -1
- package/dist/errors-BdyV5PnY.mjs +0 -1725
- package/dist/errors-BdyV5PnY.mjs.map +0 -1
- package/dist/errors-Da3Pz2X7.mjs +0 -74
- package/dist/errors-Da3Pz2X7.mjs.map +0 -1
- package/dist/events-COKixqnG.mjs.map +0 -1
- package/dist/gateway-context-CdJjpUCW.mjs.map +0 -1
- package/dist/guards-DUk_Kzst.mjs.map +0 -1
- package/dist/http-method.decorator-DXwxAfb_.mjs.map +0 -1
- package/dist/i18n.module-BBlNNlcG.mjs.map +0 -1
- package/dist/index-Bnpfq6uk.d.mts.map +0 -1
- package/dist/index-C1KvMncZ.d.mts.map +0 -1
- package/dist/index-CjaQ6_tZ.d.mts.map +0 -1
- package/dist/index-D0US0X14.d.mts.map +0 -1
- package/dist/index-DBd_2wv8.d.mts +0 -263
- package/dist/index-DBd_2wv8.d.mts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/logger-V6Ms3QnQ.mjs +0 -436
- package/dist/logger-V6Ms3QnQ.mjs.map +0 -1
- package/dist/module-Dk2qTa77.mjs +0 -860
- package/dist/module-Dk2qTa77.mjs.map +0 -1
- package/dist/openapi-tools.service-Zs-Ewv7F.mjs +0 -200
- package/dist/openapi-tools.service-Zs-Ewv7F.mjs.map +0 -1
- package/dist/openapi.service-BLgvn3hJ.d.mts.map +0 -1
- package/dist/quarry-registry-DNEej-Db.mjs +0 -688
- package/dist/quarry-registry-DNEej-Db.mjs.map +0 -1
- package/dist/queue.module-BCdCiySt.mjs.map +0 -1
- package/dist/r2-storage.provider-Co6F0ZYV.mjs.map +0 -1
- package/dist/rate-limit.decorator--o6Q6p9w.mjs.map +0 -1
- package/dist/resend.provider-M6qRLrcy.mjs.map +0 -1
- package/dist/seeder-CJAOHEIo.mjs.map +0 -1
- package/dist/setup-CefZKV_e.mjs +0 -37
- package/dist/setup-CefZKV_e.mjs.map +0 -1
- package/dist/smtp.provider-w0Ve52Xg.mjs.map +0 -1
- package/dist/storage-1zw-6Yiz.mjs.map +0 -1
- package/dist/storage-provider.interface-Bd6vA4ak.d.mts.map +0 -1
- package/dist/stratal-DeEcGgdq.mjs.map +0 -1
- package/dist/types-cySNS_lp.d.mts.map +0 -1
- package/dist/usage-generator-BUdlhnCK.mjs.map +0 -1
- package/dist/validation-DtJwAv7O.mjs +0 -248
- package/dist/validation-DtJwAv7O.mjs.map +0 -1
|
@@ -1,599 +1,74 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import "./
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import
|
|
1
|
+
import { n as getContainer, r as runWithContainer } from "./container-storage-GpNNz79X.mjs";
|
|
2
|
+
import { _ as getMethodInjections, c as DI_TOKENS, l as Request, m as inject, o as ROUTER_TOKENS, s as CONTAINER_TOKEN, u as Singleton } from "./di-BO1QIb5H.mjs";
|
|
3
|
+
import { n as getMetadata, t as defineMetadata } from "./metadata-BVkc4aUu.mjs";
|
|
4
|
+
import { n as __decorateParam, t as __decorate } from "./decorate-HgTKAYK8.mjs";
|
|
5
|
+
import { LOGGER_TOKENS } from "./logger/index.mjs";
|
|
6
|
+
import { d as abort, u as HttpException } from "./errors-BBZTnjdq.mjs";
|
|
7
|
+
import { a as RouterContext, c as METHOD_STATUS_CODES, d as SECURITY_SCHEMES, f as VERSION_NEUTRAL, l as ROUTER_CONTEXT_KEYS, o as DEFAULT_CONTENT_TYPE, r as createHttpExceptionContext, s as HTTP_METHODS, u as ROUTE_METADATA_KEYS } from "./exception-context-B4kM-M53.mjs";
|
|
8
|
+
import { o as RouterError, s as createThrottleMiddleware } from "./module-xYoHba6B.mjs";
|
|
9
|
+
import { t as I18N_TOKENS } from "./i18n.tokens-hwRpmjRq.mjs";
|
|
10
|
+
import { i as zod_exports, r as z, t as OpenAPIHono } from "./zod-hMa3rSHV.mjs";
|
|
11
|
+
import { a as OPENAPI_TOKENS } from "./openapi-C6lm0RmV.mjs";
|
|
12
|
+
import { i as getMethodGuards, r as getControllerGuards, t as GuardExecutionService } from "./guards-Ced-uNIF.mjs";
|
|
13
|
+
import { n as getRateLimits } from "./rate-limit.decorator-D69zdZbp.mjs";
|
|
14
|
+
import { n as getControllerOptions, r as getControllerRoute } from "./controller.decorator-DIUazNU7.mjs";
|
|
15
|
+
import { a as getWsOnCloseMethod, o as getWsOnErrorMethod, s as getWsOnMessageMethod, t as GatewayContext, u as isGateway } from "./gateway-context-CFe6a9gz.mjs";
|
|
16
|
+
import "./http-method.decorator-CdjKFJZZ.mjs";
|
|
17
|
+
import { n as verifySignedUrl, t as signUrl } from "./signed-url-BqUqt5dF.mjs";
|
|
17
18
|
import { languageDetector } from "hono/language";
|
|
18
|
-
//#region src/
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
constructor(i18n) {
|
|
27
|
-
this.i18n = i18n;
|
|
28
|
-
}
|
|
29
|
-
async handle(ctx, next) {
|
|
30
|
-
await runWithErrorMapContext({
|
|
31
|
-
t: (key, params) => this.i18n.t(key, params),
|
|
32
|
-
locale: ctx.getLocale()
|
|
33
|
-
}, () => next());
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
I18nContextMiddleware = __decorate([
|
|
37
|
-
Transient(),
|
|
38
|
-
__decorateParam(0, inject(I18N_TOKENS.I18nService)),
|
|
39
|
-
__decorateMetadata("design:paramtypes", [Object])
|
|
40
|
-
], I18nContextMiddleware);
|
|
41
|
-
//#endregion
|
|
42
|
-
//#region src/openapi/services/openapi-config.service.ts
|
|
43
|
-
let OpenAPIConfigService = class OpenAPIConfigService {
|
|
44
|
-
overrides = [];
|
|
45
|
-
constructor(baseOptions) {
|
|
46
|
-
this.baseOptions = baseOptions;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Add configuration override for this request.
|
|
50
|
-
* Overrides are merged in the order they are added.
|
|
51
|
-
*/
|
|
52
|
-
override(config) {
|
|
53
|
-
this.overrides.push(config);
|
|
54
|
-
}
|
|
55
|
-
/** Get effective configuration (base merged with all overrides) */
|
|
56
|
-
getEffectiveConfig() {
|
|
57
|
-
let effective = {
|
|
58
|
-
jsonPath: this.baseOptions?.jsonPath ?? "/api/openapi.json",
|
|
59
|
-
ui: this.baseOptions?.ui,
|
|
60
|
-
info: {
|
|
61
|
-
title: this.baseOptions?.info?.title ?? "API",
|
|
62
|
-
version: this.baseOptions?.info?.version ?? "1.0.0",
|
|
63
|
-
description: this.baseOptions?.info?.description
|
|
64
|
-
},
|
|
65
|
-
securitySchemes: this.baseOptions?.securitySchemes
|
|
66
|
-
};
|
|
67
|
-
for (const override of this.overrides) effective = this.mergeConfig(effective, override);
|
|
68
|
-
return effective;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Merge override into effective config.
|
|
72
|
-
* Info is shallow-merged, routeFilter is replaced.
|
|
73
|
-
*/
|
|
74
|
-
mergeConfig(base, override) {
|
|
75
|
-
return {
|
|
76
|
-
...base,
|
|
77
|
-
info: {
|
|
78
|
-
...base.info,
|
|
79
|
-
...override.info && {
|
|
80
|
-
title: override.info.title ?? base.info.title,
|
|
81
|
-
version: override.info.version ?? base.info.version,
|
|
82
|
-
description: override.info.description ?? base.info.description
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
routeFilter: override.routeFilter ?? base.routeFilter
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
OpenAPIConfigService = __decorate([
|
|
90
|
-
Transient(OPENAPI_TOKENS.ConfigService),
|
|
91
|
-
__decorateParam(0, inject(OPENAPI_TOKENS.Options, { isOptional: true })),
|
|
92
|
-
__decorateMetadata("design:paramtypes", [Object])
|
|
93
|
-
], OpenAPIConfigService);
|
|
94
|
-
//#endregion
|
|
95
|
-
//#region src/i18n/errors/locale-not-supported.error.ts
|
|
96
|
-
/**
|
|
97
|
-
* Locale Not Supported Error
|
|
98
|
-
* Thrown when an unsupported locale is requested
|
|
99
|
-
*
|
|
100
|
-
* HTTP Status: 500 Internal Server Error
|
|
101
|
-
* Error Code: 9301
|
|
102
|
-
*/
|
|
103
|
-
var LocaleNotSupportedError = class extends ApplicationError {
|
|
104
|
-
constructor(locale, supportedLocales) {
|
|
105
|
-
super("errors.localeNotSupported", ERROR_CODES.I18N.LOCALE_NOT_SUPPORTED, {
|
|
106
|
-
locale,
|
|
107
|
-
supportedLocales: supportedLocales.join(", ")
|
|
108
|
-
});
|
|
19
|
+
//#region src/router/errors/route-not-found.error.ts
|
|
20
|
+
var RouteNotFoundError = class extends HttpException {
|
|
21
|
+
path;
|
|
22
|
+
method;
|
|
23
|
+
constructor(path, method) {
|
|
24
|
+
super(404, `Route not found: ${method} ${path}`);
|
|
25
|
+
this.path = path;
|
|
26
|
+
this.method = method;
|
|
109
27
|
}
|
|
110
28
|
};
|
|
111
29
|
//#endregion
|
|
112
|
-
//#region src/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
super("errors.translationMissing", ERROR_CODES.I18N.TRANSLATION_MISSING, {
|
|
123
|
-
key,
|
|
124
|
-
locale
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
//#endregion
|
|
129
|
-
//#region src/i18n/i18n.options.ts
|
|
130
|
-
/**
|
|
131
|
-
* Resolve I18n options with defaults
|
|
132
|
-
*/
|
|
133
|
-
function resolveI18nOptions(options) {
|
|
134
|
-
const detection = options?.detection;
|
|
135
|
-
const enabled = detection ? detection.enabled !== false : true;
|
|
136
|
-
const strategy = detection && "strategy" in detection ? detection.strategy ?? "cookie" : "cookie";
|
|
137
|
-
const prefixDefaultLocale = detection && "prefixDefaultLocale" in detection && detection.prefixDefaultLocale !== void 0 ? detection.prefixDefaultLocale : false;
|
|
138
|
-
return {
|
|
139
|
-
defaultLocale: options?.defaultLocale ?? "en",
|
|
140
|
-
fallbackLocale: options?.fallbackLocale ?? "en",
|
|
141
|
-
locales: options?.locales ?? ["en"],
|
|
142
|
-
detection: {
|
|
143
|
-
enabled,
|
|
144
|
-
strategy,
|
|
145
|
-
prefixDefaultLocale
|
|
146
|
-
}
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Build Hono languageDetector options from I18n module options
|
|
151
|
-
*/
|
|
152
|
-
function buildDetectorOptions(options) {
|
|
153
|
-
const resolved = resolveI18nOptions(options);
|
|
154
|
-
const strategy = resolved.detection.strategy;
|
|
155
|
-
const detectorOptions = {
|
|
156
|
-
order: [strategy],
|
|
157
|
-
fallbackLanguage: resolved.defaultLocale,
|
|
158
|
-
supportedLanguages: resolved.locales,
|
|
159
|
-
lookupCookie: "locale",
|
|
160
|
-
lookupQueryString: "locale",
|
|
161
|
-
lookupFromPathIndex: 0,
|
|
162
|
-
ignoreCase: true
|
|
163
|
-
};
|
|
164
|
-
if (strategy === "cookie") {
|
|
165
|
-
detectorOptions.caches = ["cookie"];
|
|
166
|
-
if (options?.detection && "cookieOptions" in options.detection && options.detection.cookieOptions) detectorOptions.cookieOptions = options.detection.cookieOptions;
|
|
167
|
-
} else detectorOptions.caches = false;
|
|
168
|
-
return detectorOptions;
|
|
169
|
-
}
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/i18n/messages/index.ts
|
|
172
|
-
/**
|
|
173
|
-
* Core Messages
|
|
174
|
-
*
|
|
175
|
-
* Messages used by packages/modules infrastructure.
|
|
176
|
-
* These are automatically merged with application-specific messages.
|
|
177
|
-
*/
|
|
178
|
-
/**
|
|
179
|
-
* All locale messages
|
|
180
|
-
* Explicitly import and export (no filesystem scanning - Cloudflare Workers compatible)
|
|
181
|
-
*/
|
|
182
|
-
const messages = { en: en_exports };
|
|
183
|
-
/**
|
|
184
|
-
* Get messages for all locales
|
|
185
|
-
*/
|
|
186
|
-
function getMessages() {
|
|
187
|
-
return messages;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Get available locales
|
|
191
|
-
*/
|
|
192
|
-
function getLocales() {
|
|
193
|
-
return Object.keys(messages);
|
|
194
|
-
}
|
|
195
|
-
//#endregion
|
|
196
|
-
//#region src/i18n/utils/deep-merge.ts
|
|
197
|
-
/**
|
|
198
|
-
* Deep merge two objects. Source values override target at leaf level.
|
|
199
|
-
*/
|
|
200
|
-
function deepMerge(target, source) {
|
|
201
|
-
const result = { ...target };
|
|
202
|
-
for (const key of Object.keys(source)) {
|
|
203
|
-
const targetValue = target[key];
|
|
204
|
-
const sourceValue = source[key];
|
|
205
|
-
if (typeof targetValue === "object" && targetValue !== null && !Array.isArray(targetValue) && typeof sourceValue === "object" && sourceValue !== null && !Array.isArray(sourceValue)) result[key] = deepMerge(targetValue, sourceValue);
|
|
206
|
-
else result[key] = sourceValue;
|
|
207
|
-
}
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
|
-
//#endregion
|
|
211
|
-
//#region src/i18n/services/message-loader.service.ts
|
|
212
|
-
let MessageLoaderService = class MessageLoaderService {
|
|
213
|
-
cache;
|
|
214
|
-
contextCache;
|
|
215
|
-
locales;
|
|
216
|
-
defaultLocale;
|
|
217
|
-
constructor(registry, options) {
|
|
218
|
-
this.registry = registry;
|
|
219
|
-
this.options = options;
|
|
220
|
-
this.defaultLocale = this.options?.defaultLocale ?? "en";
|
|
221
|
-
this.cache = /* @__PURE__ */ new Map();
|
|
222
|
-
this.contextCache = /* @__PURE__ */ new Map();
|
|
223
|
-
const coreMessages = getMessages();
|
|
224
|
-
const coreLocales = getLocales();
|
|
225
|
-
const registryMessages = this.registry.getMergedMessages();
|
|
226
|
-
const registryLocales = Object.keys(registryMessages);
|
|
227
|
-
const allLocales = [...new Set([...coreLocales, ...registryLocales])];
|
|
228
|
-
this.locales = allLocales;
|
|
229
|
-
for (const locale of allLocales) {
|
|
230
|
-
const merged = deepMerge(coreMessages[locale] ?? {}, registryMessages[locale] ?? {});
|
|
231
|
-
this.cache.set(locale, merged);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Get CoreContext for a locale (lazily built and cached on first access)
|
|
236
|
-
* Falls back to default locale if locale not found
|
|
237
|
-
*/
|
|
238
|
-
getCoreContext(locale) {
|
|
239
|
-
const cached = this.contextCache.get(locale);
|
|
240
|
-
if (cached) return cached;
|
|
241
|
-
const effectiveLocale = this.cache.has(locale) ? locale : this.defaultLocale;
|
|
242
|
-
const cachedEffective = this.contextCache.get(effectiveLocale);
|
|
243
|
-
if (cachedEffective) return cachedEffective;
|
|
244
|
-
const messages = this.cache.get(effectiveLocale) ?? {};
|
|
245
|
-
const flattened = this.flattenMessages(messages);
|
|
246
|
-
const ctx = createCoreContext({
|
|
247
|
-
locale: effectiveLocale,
|
|
248
|
-
messages: { [effectiveLocale]: flattened },
|
|
249
|
-
missingWarn: false,
|
|
250
|
-
fallbackWarn: false
|
|
251
|
-
});
|
|
252
|
-
this.contextCache.set(effectiveLocale, ctx);
|
|
253
|
-
return ctx;
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Get messages for a specific locale.
|
|
257
|
-
* Falls back to default locale if not found.
|
|
258
|
-
*/
|
|
259
|
-
getMessages(locale) {
|
|
260
|
-
return this.cache.get(locale) ?? this.cache.get(this.defaultLocale) ?? {};
|
|
261
|
-
}
|
|
262
|
-
/** Get list of available locale codes */
|
|
263
|
-
getAvailableLocales() {
|
|
264
|
-
return this.locales;
|
|
265
|
-
}
|
|
266
|
-
/** Check if a locale is supported */
|
|
267
|
-
isLocaleSupported(locale) {
|
|
268
|
-
return this.cache.has(locale);
|
|
269
|
-
}
|
|
270
|
-
/** Get default locale */
|
|
271
|
-
getDefaultLocale() {
|
|
272
|
-
return this.defaultLocale;
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Get flattened (dot-notation) messages for a locale, optionally filtered by namespace prefixes.
|
|
276
|
-
*
|
|
277
|
-
* Returns flat key-value pairs matching the format used by `@intlify/core-base`'s
|
|
278
|
-
* `createCoreContext`. Requires `registerMessageCompiler(compile)` to be called
|
|
279
|
-
* before `translate()` can resolve these flat keys.
|
|
280
|
-
*
|
|
281
|
-
* @param locale - Locale code (falls back to default locale if not found)
|
|
282
|
-
* @param options - Optional filter configuration
|
|
283
|
-
* @param options.only - Dot-notation prefixes to include (e.g., `['common', 'nav.sidebar']`)
|
|
284
|
-
* @returns Flattened messages as `{ 'key.path': 'translated value' }`
|
|
285
|
-
*
|
|
286
|
-
* @example
|
|
287
|
-
* ```typescript
|
|
288
|
-
* // All messages for the locale
|
|
289
|
-
* loader.getFilteredMessages('en')
|
|
290
|
-
*
|
|
291
|
-
* // Only 'common' and 'nav' namespaces
|
|
292
|
-
* loader.getFilteredMessages('en', { only: ['common', 'nav'] })
|
|
293
|
-
*
|
|
294
|
-
* // Deeply nested prefix
|
|
295
|
-
* loader.getFilteredMessages('en', { only: ['common.actions'] })
|
|
296
|
-
* ```
|
|
297
|
-
*/
|
|
298
|
-
getFilteredMessages(locale, options) {
|
|
299
|
-
const messages = this.getMessages(locale);
|
|
300
|
-
const flattened = this.flattenMessages(messages);
|
|
301
|
-
if (!options?.only?.length) return flattened;
|
|
302
|
-
const result = {};
|
|
303
|
-
for (const [key, value] of Object.entries(flattened)) if (options.only.some((prefix) => key === prefix || key.startsWith(`${prefix}.`))) result[key] = value;
|
|
304
|
-
return result;
|
|
305
|
-
}
|
|
306
|
-
/**
|
|
307
|
-
* Flatten nested messages to dot-notation.
|
|
308
|
-
* e.g. `{ a: { b: 'hello' } }` → `{ 'a.b': 'hello' }`
|
|
309
|
-
*/
|
|
310
|
-
flattenMessages(messages, prefix = "") {
|
|
311
|
-
const result = {};
|
|
312
|
-
for (const key of Object.keys(messages)) {
|
|
313
|
-
const value = messages[key];
|
|
314
|
-
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
315
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value)) Object.assign(result, this.flattenMessages(value, newKey));
|
|
316
|
-
else result[newKey] = String(value);
|
|
317
|
-
}
|
|
318
|
-
return result;
|
|
30
|
+
//#region src/router/errors/schema-validation.error.ts
|
|
31
|
+
var SchemaValidationError = class extends HttpException {
|
|
32
|
+
issues;
|
|
33
|
+
constructor(zodError) {
|
|
34
|
+
super(400, "Schema validation failed");
|
|
35
|
+
this.issues = zodError.issues.map((err) => ({
|
|
36
|
+
path: err.path.join("."),
|
|
37
|
+
message: err.message,
|
|
38
|
+
code: err.code
|
|
39
|
+
}));
|
|
319
40
|
}
|
|
320
41
|
};
|
|
321
|
-
MessageLoaderService = __decorate([
|
|
322
|
-
Transient(I18N_TOKENS.MessageLoader),
|
|
323
|
-
__decorateParam(0, inject(I18N_TOKENS.MessageRegistry)),
|
|
324
|
-
__decorateParam(1, inject(I18N_TOKENS.Options, { isOptional: true })),
|
|
325
|
-
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
326
|
-
], MessageLoaderService);
|
|
327
42
|
//#endregion
|
|
328
|
-
//#region src/
|
|
43
|
+
//#region src/router/errors/index.ts
|
|
329
44
|
/**
|
|
330
|
-
*
|
|
45
|
+
* Error thrown when a signed URL has an invalid or expired signature.
|
|
331
46
|
*
|
|
332
|
-
*
|
|
333
|
-
* like esbuild may inline multiple copies of this module. Each copy gets its
|
|
334
|
-
* own static class fields, so messages registered by one copy are invisible
|
|
335
|
-
* to another. Using a `Symbol.for()` key on `globalThis` ensures all copies
|
|
336
|
-
* share the same contributions array.
|
|
47
|
+
* HTTP Status: 403 Forbidden
|
|
337
48
|
*/
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
g[CONTRIBUTIONS_KEY] ??= [];
|
|
342
|
-
return g[CONTRIBUTIONS_KEY];
|
|
343
|
-
}
|
|
344
|
-
let MessageRegistry = class MessageRegistry {
|
|
345
|
-
/**
|
|
346
|
-
* Add messages (called statically by I18nModule.registerMessages)
|
|
347
|
-
*/
|
|
348
|
-
static addMessages(messages) {
|
|
349
|
-
if (Boolean(messages) && typeof messages === "object" && Object.keys(messages).length > 0) getContributions().push(messages);
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Get all messages deep-merged in registration order
|
|
353
|
-
*/
|
|
354
|
-
getMergedMessages() {
|
|
355
|
-
const merged = {};
|
|
356
|
-
for (const contribution of getContributions()) for (const locale of Object.keys(contribution)) merged[locale] = deepMerge(merged[locale] ?? {}, contribution[locale]);
|
|
357
|
-
return merged;
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Reset registry (for testing)
|
|
361
|
-
* @internal
|
|
362
|
-
*/
|
|
363
|
-
static reset() {
|
|
364
|
-
globalThis[CONTRIBUTIONS_KEY] = [];
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
MessageRegistry = __decorate([Transient(I18N_TOKENS.MessageRegistry)], MessageRegistry);
|
|
368
|
-
//#endregion
|
|
369
|
-
//#region src/openapi/services/openapi.service.ts
|
|
370
|
-
let OpenAPIService = class OpenAPIService {
|
|
371
|
-
/**
|
|
372
|
-
* Generate a filtered OpenAPI spec using the user's config.
|
|
373
|
-
* Usable from both HTTP handlers and CLI commands.
|
|
374
|
-
*/
|
|
375
|
-
getSpec(app, container) {
|
|
376
|
-
const configService = container.resolve(OPENAPI_TOKENS.ConfigService);
|
|
377
|
-
const i18n = container.resolve(I18N_TOKENS.I18nService);
|
|
378
|
-
const config = configService.getEffectiveConfig();
|
|
379
|
-
const fullSpec = app.getOpenAPIDocument({
|
|
380
|
-
openapi: "3.0.0",
|
|
381
|
-
info: {
|
|
382
|
-
version: config.info.version,
|
|
383
|
-
title: config.info.title,
|
|
384
|
-
description: config.info.description
|
|
385
|
-
}
|
|
386
|
-
});
|
|
387
|
-
fullSpec.components ??= {};
|
|
388
|
-
fullSpec.components.securitySchemes = this.getSecuritySchemeDefinitions(i18n);
|
|
389
|
-
if (config.routeFilter) fullSpec.paths = this.filterRoutes(fullSpec.paths, config);
|
|
390
|
-
if (fullSpec.components.schemas) fullSpec.components.schemas = this.filterSchemas(fullSpec);
|
|
391
|
-
return fullSpec;
|
|
392
|
-
}
|
|
393
|
-
/**
|
|
394
|
-
* Setup OpenAPI documentation endpoints
|
|
395
|
-
*/
|
|
396
|
-
setupEndpoints(app, container) {
|
|
397
|
-
const config = container.resolve(OPENAPI_TOKENS.ConfigService).getEffectiveConfig();
|
|
398
|
-
app.get(config.jsonPath, (c) => {
|
|
399
|
-
const requestContainer = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER);
|
|
400
|
-
const fullSpec = this.getSpec(app, requestContainer);
|
|
401
|
-
const url = new URL(c.req.raw.url);
|
|
402
|
-
const i18n = requestContainer.resolve(I18N_TOKENS.I18nService);
|
|
403
|
-
fullSpec.servers = [{
|
|
404
|
-
url: `${url.protocol}//${url.host}`,
|
|
405
|
-
description: i18n.t("common.api.serverDescription")
|
|
406
|
-
}];
|
|
407
|
-
return c.json(fullSpec);
|
|
408
|
-
});
|
|
409
|
-
this.nameLastHandler(app, "OpenAPI", "spec");
|
|
410
|
-
if (config.ui !== false) {
|
|
411
|
-
const uiPath = config.ui?.path ?? "/api/docs";
|
|
412
|
-
const uiRenderer = config.ui?.renderer;
|
|
413
|
-
app.get(uiPath, (c, next) => {
|
|
414
|
-
const effectiveConfig = c.get(ROUTER_CONTEXT_KEYS.REQUEST_CONTAINER).resolve(OPENAPI_TOKENS.ConfigService).getEffectiveConfig();
|
|
415
|
-
const uiContext = {
|
|
416
|
-
specUrl: effectiveConfig.jsonPath,
|
|
417
|
-
title: effectiveConfig.info.title
|
|
418
|
-
};
|
|
419
|
-
if (uiRenderer) return uiRenderer(uiContext)(c, next);
|
|
420
|
-
return swaggerUI({ url: uiContext.specUrl })(c, next);
|
|
421
|
-
});
|
|
422
|
-
this.nameLastHandler(app, "OpenAPI", "docs");
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
nameLastHandler(app, controller, method) {
|
|
426
|
-
const last = app.routes[app.routes.length - 1];
|
|
427
|
-
Object.defineProperty(last.handler, "name", { value: `http:${controller}.${method}` });
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Get localized security scheme definitions
|
|
431
|
-
*/
|
|
432
|
-
getSecuritySchemeDefinitions(i18n) {
|
|
433
|
-
return {
|
|
434
|
-
[SECURITY_SCHEMES.BEARER_AUTH]: {
|
|
435
|
-
type: "http",
|
|
436
|
-
scheme: "bearer",
|
|
437
|
-
bearerFormat: "JWT",
|
|
438
|
-
description: i18n.t("common.api.security.bearerAuth")
|
|
439
|
-
},
|
|
440
|
-
[SECURITY_SCHEMES.API_KEY]: {
|
|
441
|
-
type: "apiKey",
|
|
442
|
-
in: "header",
|
|
443
|
-
name: "X-API-Key",
|
|
444
|
-
description: i18n.t("common.api.security.apiKey")
|
|
445
|
-
},
|
|
446
|
-
[SECURITY_SCHEMES.SESSION_COOKIE]: {
|
|
447
|
-
type: "apiKey",
|
|
448
|
-
in: "cookie",
|
|
449
|
-
name: "session",
|
|
450
|
-
description: i18n.t("common.api.security.sessionCookie")
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Filter OpenAPI paths using custom routeFilter
|
|
456
|
-
*/
|
|
457
|
-
filterRoutes(paths, config) {
|
|
458
|
-
const filteredPaths = {};
|
|
459
|
-
for (const [path, pathItem] of Object.entries(paths)) {
|
|
460
|
-
if (config.routeFilter && !config.routeFilter(path, pathItem)) continue;
|
|
461
|
-
filteredPaths[path] = pathItem;
|
|
462
|
-
}
|
|
463
|
-
return filteredPaths;
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Filter unreferenced schemas from OpenAPI spec
|
|
467
|
-
*/
|
|
468
|
-
filterSchemas(spec) {
|
|
469
|
-
const referencedSchemas = /* @__PURE__ */ new Set();
|
|
470
|
-
this.collectSchemaRefs(spec.paths, referencedSchemas);
|
|
471
|
-
const filteredSchemas = {};
|
|
472
|
-
const components = spec.components;
|
|
473
|
-
if (components?.schemas) {
|
|
474
|
-
const allSchemas = components.schemas;
|
|
475
|
-
let prevSize = 0;
|
|
476
|
-
while (referencedSchemas.size > prevSize) {
|
|
477
|
-
prevSize = referencedSchemas.size;
|
|
478
|
-
for (const [schemaName, schemaValue] of Object.entries(allSchemas)) if (referencedSchemas.has(schemaName) && !filteredSchemas[schemaName]) {
|
|
479
|
-
filteredSchemas[schemaName] = schemaValue;
|
|
480
|
-
this.collectSchemaRefs(schemaValue, referencedSchemas);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
return filteredSchemas;
|
|
485
|
-
}
|
|
486
|
-
/**
|
|
487
|
-
* Recursively collect all schema references from an object
|
|
488
|
-
*/
|
|
489
|
-
collectSchemaRefs(obj, refs) {
|
|
490
|
-
if (!obj || typeof obj !== "object") return;
|
|
491
|
-
const record = obj;
|
|
492
|
-
if (record.$ref && typeof record.$ref === "string") {
|
|
493
|
-
const match = /^#\/components\/schemas\/(.+)$/.exec(record.$ref);
|
|
494
|
-
if (match) refs.add(match[1]);
|
|
495
|
-
}
|
|
496
|
-
if (Array.isArray(obj)) for (const item of obj) this.collectSchemaRefs(item, refs);
|
|
497
|
-
else for (const value of Object.values(record)) this.collectSchemaRefs(value, refs);
|
|
49
|
+
var InvalidSignatureError = class extends HttpException {
|
|
50
|
+
constructor() {
|
|
51
|
+
super(403, "Invalid or expired signature");
|
|
498
52
|
}
|
|
499
53
|
};
|
|
500
|
-
OpenAPIService = __decorate([Transient(OPENAPI_TOKENS.OpenAPIService)], OpenAPIService);
|
|
501
|
-
//#endregion
|
|
502
|
-
//#region src/openapi/openapi.module.ts
|
|
503
54
|
/**
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
* Provides configurable OpenAPI documentation endpoints with runtime override support.
|
|
507
|
-
*
|
|
508
|
-
* Features:
|
|
509
|
-
* - Configurable paths for /openapi.json and /docs
|
|
510
|
-
* - Runtime config overrides via middleware
|
|
511
|
-
* - i18n support for titles and descriptions
|
|
512
|
-
* - Route filtering via hideFromDocs and custom routeFilter
|
|
513
|
-
*
|
|
514
|
-
* @example Basic usage
|
|
515
|
-
* ```typescript
|
|
516
|
-
* @Module({
|
|
517
|
-
* imports: [
|
|
518
|
-
* OpenAPIModule.forRoot({
|
|
519
|
-
* info: { title: 'My API', version: '1.0.0' }
|
|
520
|
-
* })
|
|
521
|
-
* ]
|
|
522
|
-
* })
|
|
523
|
-
* export class AppModule {}
|
|
524
|
-
* ```
|
|
525
|
-
*
|
|
526
|
-
* @example With runtime override in middleware
|
|
527
|
-
* ```typescript
|
|
528
|
-
* // In RouteAccessMiddleware
|
|
529
|
-
* constructor(
|
|
530
|
-
* @inject(OPENAPI_TOKENS.ConfigService) private openAPIConfig: IOpenAPIConfigService
|
|
531
|
-
* ) {}
|
|
55
|
+
* ResponseValidationError
|
|
532
56
|
*
|
|
533
|
-
*
|
|
534
|
-
*
|
|
535
|
-
*
|
|
536
|
-
* routeFilter: (path) => this.shouldInclude(path)
|
|
537
|
-
* })
|
|
538
|
-
* await next()
|
|
539
|
-
* }
|
|
540
|
-
* ```
|
|
57
|
+
* Thrown when a controller's response body does not match the declared Zod response schema.
|
|
58
|
+
* Indicates a server-side schema mismatch — the controller is returning data that
|
|
59
|
+
* violates its own API contract.
|
|
541
60
|
*/
|
|
542
|
-
var
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
};
|
|
551
|
-
let OpenAPIModule = _OpenAPIModule = class OpenAPIModule {
|
|
552
|
-
/**
|
|
553
|
-
* Configure OpenAPI module with static options
|
|
554
|
-
*
|
|
555
|
-
* @param options - OpenAPI configuration (paths, info, security schemes)
|
|
556
|
-
* @returns DynamicModule with options provider
|
|
557
|
-
*/
|
|
558
|
-
static forRoot(options = {}) {
|
|
559
|
-
const mergedOptions = {
|
|
560
|
-
...DEFAULT_OPTIONS,
|
|
561
|
-
...options,
|
|
562
|
-
info: {
|
|
563
|
-
...DEFAULT_OPTIONS.info,
|
|
564
|
-
...options.info,
|
|
565
|
-
title: options.info?.title ?? DEFAULT_OPTIONS.info?.title ?? "API",
|
|
566
|
-
version: options.info?.version ?? DEFAULT_OPTIONS.info?.version ?? "1.0.0"
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
return {
|
|
570
|
-
module: _OpenAPIModule,
|
|
571
|
-
providers: [{
|
|
572
|
-
provide: OPENAPI_TOKENS.Options,
|
|
573
|
-
useValue: mergedOptions
|
|
574
|
-
}]
|
|
575
|
-
};
|
|
576
|
-
}
|
|
577
|
-
static forRootAsync(options) {
|
|
578
|
-
return {
|
|
579
|
-
module: _OpenAPIModule,
|
|
580
|
-
providers: [{
|
|
581
|
-
provide: OPENAPI_TOKENS.Options,
|
|
582
|
-
useFactory: options.useFactory,
|
|
583
|
-
inject: options.inject
|
|
584
|
-
}]
|
|
585
|
-
};
|
|
61
|
+
var ResponseValidationError = class extends HttpException {
|
|
62
|
+
issues;
|
|
63
|
+
constructor(zodError) {
|
|
64
|
+
super(500, "Response validation failed");
|
|
65
|
+
this.issues = zodError.issues.map((err) => ({
|
|
66
|
+
path: err.path.join("."),
|
|
67
|
+
message: err.message,
|
|
68
|
+
code: err.code
|
|
69
|
+
}));
|
|
586
70
|
}
|
|
587
71
|
};
|
|
588
|
-
OpenAPIModule = _OpenAPIModule = __decorate([Module({ providers: [{
|
|
589
|
-
provide: OPENAPI_TOKENS.ConfigService,
|
|
590
|
-
useClass: OpenAPIConfigService,
|
|
591
|
-
scope: Scope.Request
|
|
592
|
-
}, {
|
|
593
|
-
provide: OPENAPI_TOKENS.OpenAPIService,
|
|
594
|
-
useClass: OpenAPIService,
|
|
595
|
-
scope: Scope.Singleton
|
|
596
|
-
}] })], OpenAPIModule);
|
|
597
72
|
//#endregion
|
|
598
73
|
//#region src/router/middleware/logger.middleware.ts
|
|
599
74
|
/**
|
|
@@ -666,7 +141,7 @@ function stripPort(host) {
|
|
|
666
141
|
* When the host matches, domain parameters are extracted and stored in context
|
|
667
142
|
* variables accessible via `ctx.domain(key)`.
|
|
668
143
|
*
|
|
669
|
-
* When the host does NOT match,
|
|
144
|
+
* When the host does NOT match, aborts with 404.
|
|
670
145
|
*
|
|
671
146
|
* @param pattern - Domain pattern with `{param}` placeholders (e.g., '{tenant}.myapp.com')
|
|
672
147
|
*
|
|
@@ -686,7 +161,7 @@ function createDomainMiddleware(pattern) {
|
|
|
686
161
|
return async (c, next) => {
|
|
687
162
|
const host = stripPort(c.req.header("host") ?? "");
|
|
688
163
|
const match = regex.exec(host);
|
|
689
|
-
if (!match)
|
|
164
|
+
if (!match) abort(404, "Domain mismatch");
|
|
690
165
|
for (let i = 0; i < paramNames.length; i++) c.set(`domain:${paramNames[i]}`, match[i + 1]);
|
|
691
166
|
await next();
|
|
692
167
|
};
|
|
@@ -714,12 +189,7 @@ function createMiddlewareChain(classes) {
|
|
|
714
189
|
const middleware = requestContainer.resolve(middlewareClass);
|
|
715
190
|
let called = false;
|
|
716
191
|
const guardedNext = () => {
|
|
717
|
-
if (called) {
|
|
718
|
-
const err = new MiddlewareNextCalledMultipleTimesError(middlewareClass.name ?? "anonymous");
|
|
719
|
-
console.error("[STRATAL DEBUG] next() called multiple times for " + middlewareClass.name);
|
|
720
|
-
console.error("[STRATAL DEBUG] Stack trace:", (/* @__PURE__ */ new Error()).stack);
|
|
721
|
-
return Promise.reject(err);
|
|
722
|
-
}
|
|
192
|
+
if (called) return Promise.reject(new RouterError(`Middleware "${middlewareClass.name ?? "anonymous"}" called next() multiple times`));
|
|
723
193
|
called = true;
|
|
724
194
|
return prevNext();
|
|
725
195
|
};
|
|
@@ -871,10 +341,10 @@ function Route(config) {
|
|
|
871
341
|
type: "convention",
|
|
872
342
|
config
|
|
873
343
|
};
|
|
874
|
-
|
|
875
|
-
const existing =
|
|
344
|
+
defineMetadata(ROUTE_METADATA_KEYS.ROUTE_CONFIG, metadata, target, propertyKey);
|
|
345
|
+
const existing = getMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, target) ?? [];
|
|
876
346
|
existing.push(propertyKey);
|
|
877
|
-
|
|
347
|
+
defineMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, existing, target);
|
|
878
348
|
return descriptor;
|
|
879
349
|
};
|
|
880
350
|
}
|
|
@@ -886,7 +356,7 @@ function Route(config) {
|
|
|
886
356
|
* @returns Route metadata or undefined if not decorated
|
|
887
357
|
*/
|
|
888
358
|
function getRouteMetadata(target, methodName) {
|
|
889
|
-
return
|
|
359
|
+
return getMetadata(ROUTE_METADATA_KEYS.ROUTE_CONFIG, target, methodName);
|
|
890
360
|
}
|
|
891
361
|
/**
|
|
892
362
|
* Get all methods with route decorators (@Route, @Get, @Post, etc.) from a controller
|
|
@@ -898,7 +368,7 @@ function getRouteDecoratedMethods(ControllerClass) {
|
|
|
898
368
|
const methods = /* @__PURE__ */ new Set();
|
|
899
369
|
let proto = ControllerClass.prototype;
|
|
900
370
|
while (proto && proto !== Object.prototype) {
|
|
901
|
-
const own =
|
|
371
|
+
const own = getMetadata(ROUTE_METADATA_KEYS.DECORATED_METHODS, proto);
|
|
902
372
|
if (own) for (const m of own) methods.add(m);
|
|
903
373
|
proto = Object.getPrototypeOf(proto);
|
|
904
374
|
}
|
|
@@ -917,31 +387,19 @@ function getRouteDecoratedMethods(ControllerClass) {
|
|
|
917
387
|
/**
|
|
918
388
|
* Generic error response schema
|
|
919
389
|
* Used for all error responses (4xx, 5xx)
|
|
920
|
-
* Matches
|
|
390
|
+
* Matches the ErrorResponse shape produced by ExceptionHandler
|
|
921
391
|
*/
|
|
922
392
|
const errorResponseSchema = z.object({
|
|
923
|
-
code: z.number().int().describe("Application error code"),
|
|
924
393
|
message: z.string().describe("Human-readable error message"),
|
|
925
394
|
timestamp: z.string().datetime().describe("ISO timestamp when error occurred"),
|
|
926
|
-
metadata: z.record(z.string(), z.unknown()).optional().describe("Additional error context"),
|
|
927
395
|
stack: z.string().optional().describe("Stack trace (development only)")
|
|
928
396
|
}).openapi("ErrorResponse");
|
|
929
397
|
/**
|
|
930
398
|
* Validation error response schema
|
|
931
399
|
* Used for 400 Bad Request with validation failures
|
|
932
|
-
* Matches
|
|
400
|
+
* Matches the ErrorResponse shape produced by ExceptionHandler
|
|
933
401
|
*/
|
|
934
|
-
const validationErrorResponseSchema =
|
|
935
|
-
code: z.number().int().describe("Application error code"),
|
|
936
|
-
message: z.string().describe("Human-readable error message"),
|
|
937
|
-
timestamp: z.string().datetime().describe("ISO timestamp when error occurred"),
|
|
938
|
-
metadata: z.object({ issues: z.array(z.object({
|
|
939
|
-
path: z.string().describe("Field path that failed validation"),
|
|
940
|
-
message: z.string().describe("Validation failure message"),
|
|
941
|
-
code: z.string().describe("Zod validation error code")
|
|
942
|
-
})) }).describe("Validation error details"),
|
|
943
|
-
stack: z.string().optional().describe("Stack trace (development only)")
|
|
944
|
-
}).openapi("ValidationErrorResponse");
|
|
402
|
+
const validationErrorResponseSchema = errorResponseSchema.openapi("ValidationErrorResponse");
|
|
945
403
|
/**
|
|
946
404
|
* Pagination query parameters schema
|
|
947
405
|
* Used for list endpoints
|
|
@@ -1050,10 +508,34 @@ function toRoutingOpenAPIPath(path) {
|
|
|
1050
508
|
* Scoring: static = 0, `:param{constraint}` = 5, `:param` = 10, wildcard `{.+}` / `{.*}` = 100.
|
|
1051
509
|
*
|
|
1052
510
|
* Packed as: score * 10000 - segmentCount (negative segment count so more segments = lower key = higher priority)
|
|
511
|
+
*
|
|
512
|
+
* Locale variants score against the path with the leading `/:locale{…}` segment
|
|
513
|
+
* stripped — the variant's score therefore matches its primary, but its larger
|
|
514
|
+
* segment count makes it sort just before the primary. Without this, a primary
|
|
515
|
+
* catch-all (e.g. `/:slug{.+}`) gobbles locale-prefixed URLs because Hono picks
|
|
516
|
+
* whichever matching route was registered first.
|
|
1053
517
|
*/
|
|
1054
|
-
function getPathSpecificityKey(
|
|
518
|
+
function getPathSpecificityKey(route) {
|
|
519
|
+
const segmentCount = countSegments(route.path);
|
|
520
|
+
const scoringPath = route.isLocaleVariant ? route.path.replace(/^\/:locale\{[^}]*\}/, "") || "/" : route.path;
|
|
1055
521
|
let score = 0;
|
|
1056
|
-
let
|
|
522
|
+
let i = 0;
|
|
523
|
+
while (i < scoringPath.length) {
|
|
524
|
+
if (scoringPath.charCodeAt(i) === 47) {
|
|
525
|
+
i++;
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
let end = scoringPath.indexOf("/", i);
|
|
529
|
+
if (end === -1) end = scoringPath.length;
|
|
530
|
+
const segment = scoringPath.substring(i, end);
|
|
531
|
+
if (segment.includes("{.+}") || segment.includes("{.*}")) score += 100;
|
|
532
|
+
else if (segment.charCodeAt(0) === 58) score += segment.includes("{") ? 5 : 10;
|
|
533
|
+
i = end;
|
|
534
|
+
}
|
|
535
|
+
return score * 1e4 - segmentCount;
|
|
536
|
+
}
|
|
537
|
+
function countSegments(path) {
|
|
538
|
+
let count = 0;
|
|
1057
539
|
let i = 0;
|
|
1058
540
|
while (i < path.length) {
|
|
1059
541
|
if (path.charCodeAt(i) === 47) {
|
|
@@ -1062,13 +544,10 @@ function getPathSpecificityKey(path) {
|
|
|
1062
544
|
}
|
|
1063
545
|
let end = path.indexOf("/", i);
|
|
1064
546
|
if (end === -1) end = path.length;
|
|
1065
|
-
|
|
1066
|
-
const segment = path.substring(i, end);
|
|
1067
|
-
if (segment.includes("{.+}") || segment.includes("{.*}")) score += 100;
|
|
1068
|
-
else if (segment.charCodeAt(0) === 58) score += segment.includes("{") ? 5 : 10;
|
|
547
|
+
count++;
|
|
1069
548
|
i = end;
|
|
1070
549
|
}
|
|
1071
|
-
return
|
|
550
|
+
return count;
|
|
1072
551
|
}
|
|
1073
552
|
/**
|
|
1074
553
|
* Compute a specificity score for route ordering.
|
|
@@ -1089,11 +568,13 @@ function getPathSpecificityScore(path) {
|
|
|
1089
568
|
*
|
|
1090
569
|
* 1. Static paths before parameterized before wildcards
|
|
1091
570
|
* 2. More segments = more specific (tie-breaker)
|
|
1092
|
-
* 3.
|
|
571
|
+
* 3. Locale-prefixed variants before their primary (so a locale-prefixed
|
|
572
|
+
* request matches the variant first; a primary catch-all would otherwise
|
|
573
|
+
* swallow the locale prefix into its param)
|
|
1093
574
|
*/
|
|
1094
575
|
function sortRoutesBySpecificity(routes) {
|
|
1095
576
|
const keys = /* @__PURE__ */ new Map();
|
|
1096
|
-
for (const route of routes) keys.set(route, getPathSpecificityKey(route
|
|
577
|
+
for (const route of routes) keys.set(route, getPathSpecificityKey(route));
|
|
1097
578
|
const copy = routes.slice();
|
|
1098
579
|
copy.sort((a, b) => keys.get(a) - keys.get(b));
|
|
1099
580
|
return copy;
|
|
@@ -1161,6 +642,12 @@ const invokeHandler = (instance, method, ...args) => {
|
|
|
1161
642
|
}
|
|
1162
643
|
};
|
|
1163
644
|
let RouteRegistrationService = class RouteRegistrationService {
|
|
645
|
+
logger;
|
|
646
|
+
registry;
|
|
647
|
+
routerResolver;
|
|
648
|
+
localePathService;
|
|
649
|
+
app;
|
|
650
|
+
moduleRegistry;
|
|
1164
651
|
controllerClasses = /* @__PURE__ */ new Map();
|
|
1165
652
|
upgradeWebSocketFn = null;
|
|
1166
653
|
constructor(logger, registry, routerResolver, localePathService, app, moduleRegistry) {
|
|
@@ -1196,7 +683,7 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1196
683
|
collectRoutes(ControllerClass, actions) {
|
|
1197
684
|
const isWsGateway = isGateway(ControllerClass);
|
|
1198
685
|
const controllerRoute = getControllerRoute(ControllerClass);
|
|
1199
|
-
if (!controllerRoute) throw new
|
|
686
|
+
if (!controllerRoute) throw new RouterError(`Controller "${ControllerClass.name}" registration failed: ${isWsGateway ? "Missing @Gateway decorator or route metadata" : "Missing @Controller decorator or route metadata"}`);
|
|
1200
687
|
const controllerOpts = getControllerOptions(ControllerClass);
|
|
1201
688
|
const controllerGuards = getControllerGuards(ControllerClass)?.guards ?? [];
|
|
1202
689
|
const routerConfig = this.routerResolver?.resolveForController(ControllerClass) ?? { middleware: [] };
|
|
@@ -1249,7 +736,7 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1249
736
|
return;
|
|
1250
737
|
}
|
|
1251
738
|
const decoratedMethods = getRouteDecoratedMethods(ControllerClass);
|
|
1252
|
-
if (decoratedMethods.length === 0) throw new
|
|
739
|
+
if (decoratedMethods.length === 0) throw new RouterError(`Controller "${ControllerClass.name}" registration failed: No route decorators found. Use @Route() or HTTP method decorators (@Get, @Post, etc.) on controller methods.`);
|
|
1253
740
|
const methodMetadata = [];
|
|
1254
741
|
let hasConvention = false;
|
|
1255
742
|
let hasExplicit = false;
|
|
@@ -1263,7 +750,7 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1263
750
|
if (meta.type === "convention") hasConvention = true;
|
|
1264
751
|
else if (meta.type === "explicit") hasExplicit = true;
|
|
1265
752
|
}
|
|
1266
|
-
if (hasConvention && hasExplicit) throw new
|
|
753
|
+
if (hasConvention && hasExplicit) throw new RouterError(`Controller "${ControllerClass.name}" registration failed: Cannot mix @Route() with HTTP method decorators (@Get, @Post, etc.) in the same controller. Use one pattern or the other.`);
|
|
1267
754
|
const routerHidden = routerConfig.hideFromDocs;
|
|
1268
755
|
const controllerHidden = controllerOpts?.hideFromDocs ?? false;
|
|
1269
756
|
const routerName = routerConfig.name;
|
|
@@ -1370,16 +857,16 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1370
857
|
const bindWsHandler = (method, onCatch) => {
|
|
1371
858
|
return (evt, ws) => {
|
|
1372
859
|
invokeHandler(gateway, method, evt, new GatewayContext(c, ws)).catch((err) => {
|
|
1373
|
-
this.logger.error(`WebSocket ${method} handler error`, {
|
|
1374
|
-
gateway: GatewayClass.name,
|
|
1375
|
-
error: err instanceof Error ? err.message : String(err)
|
|
1376
|
-
});
|
|
860
|
+
this.logger.error(`WebSocket ${method} handler error`, err, { gateway: GatewayClass.name });
|
|
1377
861
|
onCatch?.(err, ws);
|
|
1378
862
|
});
|
|
1379
863
|
};
|
|
1380
864
|
};
|
|
1381
865
|
if (onMsgMethod) events.onMessage = bindWsHandler(onMsgMethod, (_err, ws) => ws.close(1011, "Internal Error"));
|
|
1382
866
|
if (onCloseMethod) events.onClose = bindWsHandler(onCloseMethod);
|
|
867
|
+
else events.onClose = (_evt, ws) => {
|
|
868
|
+
ws.close();
|
|
869
|
+
};
|
|
1383
870
|
if (onErrMethod) events.onError = bindWsHandler(onErrMethod);
|
|
1384
871
|
return events;
|
|
1385
872
|
});
|
|
@@ -1462,7 +949,7 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1462
949
|
resolveMethodAndPath(meta, methodName, basePath, className) {
|
|
1463
950
|
if (meta.type === "convention") {
|
|
1464
951
|
const derived = this.deriveHttpMethodAndPath(methodName, basePath);
|
|
1465
|
-
if (!derived) throw new
|
|
952
|
+
if (!derived) throw new RouterError(`Cannot derive HTTP method/path for convention-based route "${className}.${methodName}". Ensure the method name follows the naming convention (e.g., index, create, show).`);
|
|
1466
953
|
return {
|
|
1467
954
|
httpMethod: derived.method,
|
|
1468
955
|
fullPath: derived.path,
|
|
@@ -1582,9 +1069,9 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1582
1069
|
if (metadata.security.length > 0) route.security = metadata.security;
|
|
1583
1070
|
if (routeConfig.description) route.description = routeConfig.description;
|
|
1584
1071
|
if (routeConfig.summary) route.summary = routeConfig.summary;
|
|
1585
|
-
return (0,
|
|
1072
|
+
return (0, zod_exports.createRoute)(route);
|
|
1586
1073
|
} catch (error) {
|
|
1587
|
-
throw new
|
|
1074
|
+
throw new RouterError(`OpenAPI route registration failed for "${path}": ${error instanceof Error ? error.message : String(error)}`);
|
|
1588
1075
|
}
|
|
1589
1076
|
}
|
|
1590
1077
|
/**
|
|
@@ -1629,7 +1116,7 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1629
1116
|
if (responseSchema && c.env.ENVIRONMENT !== "production") return this.validateResponse(response, responseSchema);
|
|
1630
1117
|
return response;
|
|
1631
1118
|
}
|
|
1632
|
-
throw new
|
|
1119
|
+
throw new RouterError(`Method "${methodName}" not found on controller "${ControllerClass.name}"`);
|
|
1633
1120
|
};
|
|
1634
1121
|
this.nameHandler(handler, ControllerClass.name, methodName);
|
|
1635
1122
|
return handler;
|
|
@@ -1679,21 +1166,13 @@ let RouteRegistrationService = class RouteRegistrationService {
|
|
|
1679
1166
|
}
|
|
1680
1167
|
};
|
|
1681
1168
|
RouteRegistrationService = __decorate([
|
|
1682
|
-
|
|
1169
|
+
Singleton(),
|
|
1683
1170
|
__decorateParam(0, inject(LOGGER_TOKENS.LoggerService)),
|
|
1684
1171
|
__decorateParam(1, inject(ROUTER_TOKENS.RouteRegistry)),
|
|
1685
|
-
__decorateParam(2, inject(ROUTER_TOKENS.RouterResolver)),
|
|
1172
|
+
__decorateParam(2, inject(ROUTER_TOKENS.RouterResolver, { isOptional: true })),
|
|
1686
1173
|
__decorateParam(3, inject(ROUTER_TOKENS.LocalePathService)),
|
|
1687
1174
|
__decorateParam(4, inject(ROUTER_TOKENS.HonoApp)),
|
|
1688
|
-
__decorateParam(5, inject(DI_TOKENS.ModuleRegistry))
|
|
1689
|
-
__decorateMetadata("design:paramtypes", [
|
|
1690
|
-
Object,
|
|
1691
|
-
Object,
|
|
1692
|
-
Object,
|
|
1693
|
-
Object,
|
|
1694
|
-
Object,
|
|
1695
|
-
Object
|
|
1696
|
-
])
|
|
1175
|
+
__decorateParam(5, inject(DI_TOKENS.ModuleRegistry))
|
|
1697
1176
|
], RouteRegistrationService);
|
|
1698
1177
|
//#endregion
|
|
1699
1178
|
//#region src/router/hono-app.ts
|
|
@@ -1750,7 +1229,7 @@ let HonoApp = class HonoApp extends OpenAPIHono {
|
|
|
1750
1229
|
* Called once by Application.initialize().
|
|
1751
1230
|
*/
|
|
1752
1231
|
async configure() {
|
|
1753
|
-
if (this.configured) throw new
|
|
1232
|
+
if (this.configured) throw new RouterError("HonoApp has already been configured");
|
|
1754
1233
|
this._container.resolve(OPENAPI_TOKENS.OpenAPIService).setupEndpoints(this, this._container);
|
|
1755
1234
|
await this._container.resolve(RouteRegistrationService).configure();
|
|
1756
1235
|
this.notFound((c) => {
|
|
@@ -1773,19 +1252,57 @@ let HonoApp = class HonoApp extends OpenAPIHono {
|
|
|
1773
1252
|
}
|
|
1774
1253
|
};
|
|
1775
1254
|
HonoApp = __decorate([
|
|
1776
|
-
|
|
1255
|
+
Singleton(),
|
|
1777
1256
|
__decorateParam(0, inject(CONTAINER_TOKEN)),
|
|
1778
1257
|
__decorateParam(1, inject(LOGGER_TOKENS.LoggerService)),
|
|
1779
|
-
__decorateParam(2, inject(DI_TOKENS.Application))
|
|
1780
|
-
__decorateMetadata("design:paramtypes", [
|
|
1781
|
-
Object,
|
|
1782
|
-
Object,
|
|
1783
|
-
Object
|
|
1784
|
-
])
|
|
1258
|
+
__decorateParam(2, inject(DI_TOKENS.Application))
|
|
1785
1259
|
], HonoApp);
|
|
1786
1260
|
//#endregion
|
|
1261
|
+
//#region src/i18n/i18n.options.ts
|
|
1262
|
+
/**
|
|
1263
|
+
* Resolve I18n options with defaults
|
|
1264
|
+
*/
|
|
1265
|
+
function resolveI18nOptions(options) {
|
|
1266
|
+
const detection = options?.detection;
|
|
1267
|
+
const enabled = detection ? detection.enabled !== false : true;
|
|
1268
|
+
const strategy = detection && "strategy" in detection ? detection.strategy ?? "cookie" : "cookie";
|
|
1269
|
+
const prefixDefaultLocale = detection && "prefixDefaultLocale" in detection && detection.prefixDefaultLocale !== void 0 ? detection.prefixDefaultLocale : false;
|
|
1270
|
+
return {
|
|
1271
|
+
defaultLocale: options?.defaultLocale ?? "en",
|
|
1272
|
+
fallbackLocale: options?.fallbackLocale ?? "en",
|
|
1273
|
+
locales: options?.locales ?? ["en"],
|
|
1274
|
+
detection: {
|
|
1275
|
+
enabled,
|
|
1276
|
+
strategy,
|
|
1277
|
+
prefixDefaultLocale
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
}
|
|
1281
|
+
/**
|
|
1282
|
+
* Build Hono languageDetector options from I18n module options
|
|
1283
|
+
*/
|
|
1284
|
+
function buildDetectorOptions(options) {
|
|
1285
|
+
const resolved = resolveI18nOptions(options);
|
|
1286
|
+
const strategy = resolved.detection.strategy;
|
|
1287
|
+
const detectorOptions = {
|
|
1288
|
+
order: [strategy],
|
|
1289
|
+
fallbackLanguage: resolved.defaultLocale,
|
|
1290
|
+
supportedLanguages: resolved.locales,
|
|
1291
|
+
lookupCookie: "locale",
|
|
1292
|
+
lookupQueryString: "locale",
|
|
1293
|
+
lookupFromPathIndex: 0,
|
|
1294
|
+
ignoreCase: true
|
|
1295
|
+
};
|
|
1296
|
+
if (strategy === "cookie") {
|
|
1297
|
+
detectorOptions.caches = ["cookie"];
|
|
1298
|
+
if (options?.detection && "cookieOptions" in options.detection && options.detection.cookieOptions) detectorOptions.cookieOptions = options.detection.cookieOptions;
|
|
1299
|
+
} else detectorOptions.caches = false;
|
|
1300
|
+
return detectorOptions;
|
|
1301
|
+
}
|
|
1302
|
+
//#endregion
|
|
1787
1303
|
//#region src/router/services/locale-path.service.ts
|
|
1788
1304
|
let LocalePathService = class LocalePathService {
|
|
1305
|
+
honoApp;
|
|
1789
1306
|
_config;
|
|
1790
1307
|
_pathDetectionEnabled;
|
|
1791
1308
|
_prefixDefaultLocale;
|
|
@@ -1891,10 +1408,9 @@ let LocalePathService = class LocalePathService {
|
|
|
1891
1408
|
}
|
|
1892
1409
|
};
|
|
1893
1410
|
LocalePathService = __decorate([
|
|
1894
|
-
|
|
1411
|
+
Singleton(),
|
|
1895
1412
|
__decorateParam(0, inject(CONTAINER_TOKEN)),
|
|
1896
|
-
__decorateParam(1, inject(ROUTER_TOKENS.HonoApp))
|
|
1897
|
-
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
1413
|
+
__decorateParam(1, inject(ROUTER_TOKENS.HonoApp))
|
|
1898
1414
|
], LocalePathService);
|
|
1899
1415
|
//#endregion
|
|
1900
1416
|
//#region src/router/services/versioning.service.ts
|
|
@@ -1923,11 +1439,7 @@ let VersioningService = class VersioningService {
|
|
|
1923
1439
|
return [basePath];
|
|
1924
1440
|
}
|
|
1925
1441
|
};
|
|
1926
|
-
VersioningService = __decorate([
|
|
1927
|
-
Transient(),
|
|
1928
|
-
__decorateParam(0, inject(DI_TOKENS.Application)),
|
|
1929
|
-
__decorateMetadata("design:paramtypes", [Object])
|
|
1930
|
-
], VersioningService);
|
|
1442
|
+
VersioningService = __decorate([Singleton(), __decorateParam(0, inject(DI_TOKENS.Application))], VersioningService);
|
|
1931
1443
|
//#endregion
|
|
1932
1444
|
//#region src/router/route-registry.ts
|
|
1933
1445
|
const CONCRETE_HTTP_METHODS = [
|
|
@@ -1941,6 +1453,8 @@ const CONCRETE_HTTP_METHODS = [
|
|
|
1941
1453
|
"trace"
|
|
1942
1454
|
];
|
|
1943
1455
|
let RouteRegistry = class RouteRegistry {
|
|
1456
|
+
versioningService;
|
|
1457
|
+
localePathService;
|
|
1944
1458
|
routes = [];
|
|
1945
1459
|
namedRoutes = /* @__PURE__ */ new Map();
|
|
1946
1460
|
_sortedCache = null;
|
|
@@ -1954,7 +1468,7 @@ let RouteRegistry = class RouteRegistry {
|
|
|
1954
1468
|
* Named routes must have unique names.
|
|
1955
1469
|
*
|
|
1956
1470
|
* @returns Array of expanded RegisteredRoute entries (primary + locale variants)
|
|
1957
|
-
* @throws
|
|
1471
|
+
* @throws RouterError if a named route with the same name already exists
|
|
1958
1472
|
*/
|
|
1959
1473
|
register(input) {
|
|
1960
1474
|
const domainParamNames = input.domainParamNames ?? (input.domain ? extractDomainParamNames(input.domain) : []);
|
|
@@ -1986,7 +1500,7 @@ let RouteRegistry = class RouteRegistry {
|
|
|
1986
1500
|
if (route.name) {
|
|
1987
1501
|
if (this.namedRoutes.has(route.name)) {
|
|
1988
1502
|
const existing = this.namedRoutes.get(route.name);
|
|
1989
|
-
throw new
|
|
1503
|
+
throw new RouterError(`Duplicate route name "${route.name}": already registered by ${existing.controller}.${existing.action}, cannot register ${route.controller}.${route.action}`);
|
|
1990
1504
|
}
|
|
1991
1505
|
this.namedRoutes.set(route.name, route);
|
|
1992
1506
|
}
|
|
@@ -2025,7 +1539,7 @@ let RouteRegistry = class RouteRegistry {
|
|
|
2025
1539
|
}
|
|
2026
1540
|
return cache;
|
|
2027
1541
|
}
|
|
2028
|
-
/** Get all routes sorted by specificity (static > param > wildcard,
|
|
1542
|
+
/** Get all routes sorted by specificity (static > param > wildcard, locale variant before its primary) */
|
|
2029
1543
|
all() {
|
|
2030
1544
|
this._sortedCache ??= sortRoutesBySpecificity(this.routes);
|
|
2031
1545
|
return this._sortedCache;
|
|
@@ -2036,12 +1550,41 @@ let RouteRegistry = class RouteRegistry {
|
|
|
2036
1550
|
}
|
|
2037
1551
|
};
|
|
2038
1552
|
RouteRegistry = __decorate([
|
|
2039
|
-
|
|
1553
|
+
Singleton(),
|
|
2040
1554
|
__decorateParam(0, inject(ROUTER_TOKENS.VersioningService)),
|
|
2041
|
-
__decorateParam(1, inject(ROUTER_TOKENS.LocalePathService))
|
|
2042
|
-
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
1555
|
+
__decorateParam(1, inject(ROUTER_TOKENS.LocalePathService))
|
|
2043
1556
|
], RouteRegistry);
|
|
2044
1557
|
//#endregion
|
|
1558
|
+
//#region src/router/route-url.ts
|
|
1559
|
+
/**
|
|
1560
|
+
* Generate a URL from a named route.
|
|
1561
|
+
*
|
|
1562
|
+
* Keys in `params` matching `:param` placeholders fill the path.
|
|
1563
|
+
* Domain params (`{tenant}`) are also consumed from `params`.
|
|
1564
|
+
* Extra keys become query string parameters.
|
|
1565
|
+
*
|
|
1566
|
+
* Resolves RouteRegistry from the application container via AsyncLocalStorage.
|
|
1567
|
+
* Available after `Application.initialize()` has been called.
|
|
1568
|
+
*
|
|
1569
|
+
* @param name - Named route identifier
|
|
1570
|
+
* @param params - Route params + domain params + extra query params
|
|
1571
|
+
* @returns Generated URL string
|
|
1572
|
+
*
|
|
1573
|
+
* @example
|
|
1574
|
+
* ```typescript
|
|
1575
|
+
* // In a controller (preferred):
|
|
1576
|
+
* ctx.route('users.show', { id: '1' })
|
|
1577
|
+
*
|
|
1578
|
+
* // Outside controllers (standalone function):
|
|
1579
|
+
* import { route } from 'stratal/router'
|
|
1580
|
+
*
|
|
1581
|
+
* route('users.show', { id: '1' })
|
|
1582
|
+
* ```
|
|
1583
|
+
*/
|
|
1584
|
+
function route(name, params, options) {
|
|
1585
|
+
return getContainer().resolve(ROUTER_TOKENS.Uri).route(name, params, options);
|
|
1586
|
+
}
|
|
1587
|
+
//#endregion
|
|
2045
1588
|
//#region src/router/uri.ts
|
|
2046
1589
|
/**
|
|
2047
1590
|
* Encode a value for use as a path parameter.
|
|
@@ -2064,7 +1607,7 @@ function encodePathParam(value) {
|
|
|
2064
1607
|
* @param params - Path params, domain params, and extra query params
|
|
2065
1608
|
* @returns Relative URL string (or absolute with domain prefix if route has a domain pattern)
|
|
2066
1609
|
*
|
|
2067
|
-
* @throws
|
|
1610
|
+
* @throws RouterError if a required path or domain param is missing
|
|
2068
1611
|
*/
|
|
2069
1612
|
function buildRouteUrl(route, name, params) {
|
|
2070
1613
|
const allParams = { ...params };
|
|
@@ -2076,7 +1619,7 @@ function buildRouteUrl(route, name, params) {
|
|
|
2076
1619
|
}
|
|
2077
1620
|
for (const paramName of route.paramNames) {
|
|
2078
1621
|
const value = allParams[paramName];
|
|
2079
|
-
if (value === void 0) throw new
|
|
1622
|
+
if (value === void 0) throw new RouterError(`Missing required route parameter "${paramName}" for route "${name}" (path: ${route.path})`);
|
|
2080
1623
|
url = url.replace(new RegExp(`:${paramName}(\\{[^}]*\\})?`), encodePathParam(value));
|
|
2081
1624
|
consumedKeys.add(paramName);
|
|
2082
1625
|
}
|
|
@@ -2085,7 +1628,7 @@ function buildRouteUrl(route, name, params) {
|
|
|
2085
1628
|
domain = route.domain;
|
|
2086
1629
|
for (const domainParam of route.domainParamNames) {
|
|
2087
1630
|
const value = allParams[domainParam];
|
|
2088
|
-
if (value === void 0) throw new
|
|
1631
|
+
if (value === void 0) throw new RouterError(`Missing required domain parameter "${domainParam}" for route "${name}" (domain: ${route.domain})`);
|
|
2089
1632
|
domain = domain.replace(`{${domainParam}}`, encodeURIComponent(value));
|
|
2090
1633
|
consumedKeys.add(domainParam);
|
|
2091
1634
|
}
|
|
@@ -2099,6 +1642,8 @@ function buildRouteUrl(route, name, params) {
|
|
|
2099
1642
|
return url;
|
|
2100
1643
|
}
|
|
2101
1644
|
let Uri = class Uri {
|
|
1645
|
+
registry;
|
|
1646
|
+
routerContext;
|
|
2102
1647
|
_defaults = {};
|
|
2103
1648
|
trailingSlash;
|
|
2104
1649
|
constructor(registry, routerContext, application) {
|
|
@@ -2141,12 +1686,11 @@ let Uri = class Uri {
|
|
|
2141
1686
|
* @param options - URL generation options
|
|
2142
1687
|
* @returns Generated URL string
|
|
2143
1688
|
*
|
|
2144
|
-
* @throws
|
|
2145
|
-
* @throws MissingRouteParamError if required params missing
|
|
1689
|
+
* @throws RouterError if route name not found or required params missing
|
|
2146
1690
|
*/
|
|
2147
1691
|
route(name, params, options) {
|
|
2148
1692
|
const registeredRoute = this.registry.get(name);
|
|
2149
|
-
if (!registeredRoute) throw new
|
|
1693
|
+
if (!registeredRoute) throw new RouterError(`Route name "${name}" was not found in the registry`);
|
|
2150
1694
|
let url = applyTrailingSlash(buildRouteUrl(registeredRoute, name, {
|
|
2151
1695
|
...this._defaults,
|
|
2152
1696
|
...params
|
|
@@ -2266,52 +1810,12 @@ let Uri = class Uri {
|
|
|
2266
1810
|
}
|
|
2267
1811
|
};
|
|
2268
1812
|
Uri = __decorate([
|
|
2269
|
-
|
|
1813
|
+
Request(),
|
|
2270
1814
|
__decorateParam(0, inject(ROUTER_TOKENS.RouteRegistry)),
|
|
2271
1815
|
__decorateParam(1, inject(ROUTER_TOKENS.RouterContext)),
|
|
2272
|
-
__decorateParam(2, inject(DI_TOKENS.Application))
|
|
2273
|
-
__decorateMetadata("design:paramtypes", [
|
|
2274
|
-
Object,
|
|
2275
|
-
Object,
|
|
2276
|
-
Object
|
|
2277
|
-
])
|
|
1816
|
+
__decorateParam(2, inject(DI_TOKENS.Application))
|
|
2278
1817
|
], Uri);
|
|
2279
1818
|
//#endregion
|
|
2280
|
-
//#region src/router/route-url.ts
|
|
2281
|
-
/**
|
|
2282
|
-
* Generate a URL from a named route.
|
|
2283
|
-
*
|
|
2284
|
-
* Keys in `params` matching `:param` placeholders fill the path.
|
|
2285
|
-
* Domain params (`{tenant}`) are also consumed from `params`.
|
|
2286
|
-
* Extra keys become query string parameters.
|
|
2287
|
-
*
|
|
2288
|
-
* Resolves RouteRegistry from the application container via AsyncLocalStorage.
|
|
2289
|
-
* Available after `Application.initialize()` has been called.
|
|
2290
|
-
*
|
|
2291
|
-
* @param name - Named route identifier
|
|
2292
|
-
* @param params - Route params + domain params + extra query params
|
|
2293
|
-
* @returns Generated URL string
|
|
2294
|
-
*
|
|
2295
|
-
* @example
|
|
2296
|
-
* ```typescript
|
|
2297
|
-
* // In a controller (preferred):
|
|
2298
|
-
* ctx.route('users.show', { id: '1' })
|
|
2299
|
-
*
|
|
2300
|
-
* // Outside controllers (standalone function):
|
|
2301
|
-
* import { route } from 'stratal/router'
|
|
2302
|
-
*
|
|
2303
|
-
* route('users.show', { id: '1' })
|
|
2304
|
-
* ```
|
|
2305
|
-
*/
|
|
2306
|
-
function route(name, params) {
|
|
2307
|
-
const container = getContainer();
|
|
2308
|
-
const registry = container.resolve(ROUTER_TOKENS.RouteRegistry);
|
|
2309
|
-
const application = container.resolve(DI_TOKENS.Application);
|
|
2310
|
-
const registeredRoute = registry.get(name);
|
|
2311
|
-
if (!registeredRoute) throw new RouteNameNotFoundError(name);
|
|
2312
|
-
return applyTrailingSlash(buildRouteUrl(registeredRoute, name, params), application.config.trailingSlash ?? "ignore");
|
|
2313
|
-
}
|
|
2314
|
-
//#endregion
|
|
2315
1819
|
//#region src/router/middleware/verify-signature.middleware.ts
|
|
2316
1820
|
/**
|
|
2317
1821
|
* Middleware that verifies signed URLs.
|
|
@@ -2337,156 +1841,12 @@ var VerifySignatureMiddleware = class {
|
|
|
2337
1841
|
async handle(ctx, next) {
|
|
2338
1842
|
const url = ctx.c.req.url;
|
|
2339
1843
|
const secret = ctx.c.env.APP_SECRET;
|
|
2340
|
-
if (!secret) throw new
|
|
1844
|
+
if (!secret) throw new RouterError("Missing required environment variable \"APP_SECRET\"");
|
|
2341
1845
|
if (!await verifySignedUrl(url, secret)) throw new InvalidSignatureError();
|
|
2342
1846
|
await next();
|
|
2343
1847
|
}
|
|
2344
1848
|
};
|
|
2345
1849
|
//#endregion
|
|
2346
|
-
|
|
2347
|
-
/**
|
|
2348
|
-
* I18n Service
|
|
2349
|
-
*
|
|
2350
|
-
* Request-scoped service for translations.
|
|
2351
|
-
* Injects RouterContext to access request-specific locale.
|
|
2352
|
-
* Uses pre-built CoreContext from MessageLoaderService (singleton) for zero-cost lookups.
|
|
2353
|
-
*/
|
|
2354
|
-
let I18nService = class I18nService {
|
|
2355
|
-
constructor(loader, routerContext) {
|
|
2356
|
-
this.loader = loader;
|
|
2357
|
-
this.routerContext = routerContext;
|
|
2358
|
-
}
|
|
2359
|
-
/**
|
|
2360
|
-
* Translate a message key
|
|
2361
|
-
*
|
|
2362
|
-
* @param key - Message key (e.g., 'common.actions.save')
|
|
2363
|
-
* @param params - Optional parameters for interpolation
|
|
2364
|
-
* @returns Translated string
|
|
2365
|
-
*/
|
|
2366
|
-
t(key, params) {
|
|
2367
|
-
const context = this.loader.getCoreContext(this.getLocale());
|
|
2368
|
-
const result = params !== void 0 ? translate(context, key, params) : translate(context, key);
|
|
2369
|
-
return typeof result === "string" ? result : key;
|
|
2370
|
-
}
|
|
2371
|
-
/**
|
|
2372
|
-
* Get current locale
|
|
2373
|
-
*
|
|
2374
|
-
* @returns Current locale code from RouterContext or default locale
|
|
2375
|
-
*/
|
|
2376
|
-
getLocale() {
|
|
2377
|
-
return this.routerContext?.getLocale() ?? "en";
|
|
2378
|
-
}
|
|
2379
|
-
};
|
|
2380
|
-
I18nService = __decorate([
|
|
2381
|
-
Transient(I18N_TOKENS.I18nService),
|
|
2382
|
-
__decorateParam(0, inject(I18N_TOKENS.MessageLoader)),
|
|
2383
|
-
__decorateParam(1, inject(ROUTER_TOKENS.RouterContext, { isOptional: true })),
|
|
2384
|
-
__decorateMetadata("design:paramtypes", [Object, Object])
|
|
2385
|
-
], I18nService);
|
|
2386
|
-
//#endregion
|
|
2387
|
-
//#region src/i18n/i18n.module.ts
|
|
2388
|
-
/**
|
|
2389
|
-
* I18n Module
|
|
2390
|
-
*
|
|
2391
|
-
* Core infrastructure module for internationalization.
|
|
2392
|
-
* Provides message translation and locale handling.
|
|
2393
|
-
*
|
|
2394
|
-
* - `forRoot()` configures locale settings (call once in root module)
|
|
2395
|
-
* - `registerMessages()` adds translations (call from any module, as many times as needed)
|
|
2396
|
-
*
|
|
2397
|
-
* @example
|
|
2398
|
-
* ```typescript
|
|
2399
|
-
* @Module({
|
|
2400
|
-
* imports: [
|
|
2401
|
-
* I18nModule.forRoot({ defaultLocale: 'en', locales: ['en', 'fr'] }),
|
|
2402
|
-
* I18nModule.registerMessages(appMessages),
|
|
2403
|
-
* ],
|
|
2404
|
-
* })
|
|
2405
|
-
* export class AppModule {}
|
|
2406
|
-
* ```
|
|
2407
|
-
*
|
|
2408
|
-
* @example Package contributing messages
|
|
2409
|
-
* ```typescript
|
|
2410
|
-
* @Module({
|
|
2411
|
-
* imports: [
|
|
2412
|
-
* I18nModule.registerMessages(tenancyMessages),
|
|
2413
|
-
* ],
|
|
2414
|
-
* })
|
|
2415
|
-
* export class TenancyModule {}
|
|
2416
|
-
* ```
|
|
2417
|
-
*/
|
|
2418
|
-
var _I18nModule;
|
|
2419
|
-
setupI18nCompiler();
|
|
2420
|
-
z.config({ customError: backendErrorMap });
|
|
2421
|
-
let I18nModule = _I18nModule = class I18nModule {
|
|
2422
|
-
/**
|
|
2423
|
-
* Configure I18n locale settings
|
|
2424
|
-
*
|
|
2425
|
-
* Call once in the root module. Does not accept messages —
|
|
2426
|
-
* use `registerMessages()` to add translations.
|
|
2427
|
-
*
|
|
2428
|
-
* @param options - Locale configuration (defaultLocale, fallbackLocale, locales)
|
|
2429
|
-
*/
|
|
2430
|
-
static forRoot(options = {}) {
|
|
2431
|
-
return {
|
|
2432
|
-
module: _I18nModule,
|
|
2433
|
-
providers: [{
|
|
2434
|
-
provide: I18N_TOKENS.Options,
|
|
2435
|
-
useValue: options
|
|
2436
|
-
}]
|
|
2437
|
-
};
|
|
2438
|
-
}
|
|
2439
|
-
/**
|
|
2440
|
-
* Register i18n messages
|
|
2441
|
-
*
|
|
2442
|
-
* Can be called from any module, as many times as needed.
|
|
2443
|
-
* Messages are deep-merged in registration order — later calls override earlier ones at leaf level.
|
|
2444
|
-
*
|
|
2445
|
-
* @param messages - Messages keyed by locale code
|
|
2446
|
-
*
|
|
2447
|
-
* @example App-level messages
|
|
2448
|
-
* ```typescript
|
|
2449
|
-
* I18nModule.registerMessages({
|
|
2450
|
-
* en: { common: { hello: 'Hello' }, errors: { notFound: 'Not found' } },
|
|
2451
|
-
* fr: { common: { hello: 'Bonjour' }, errors: { notFound: 'Introuvable' } },
|
|
2452
|
-
* })
|
|
2453
|
-
* ```
|
|
2454
|
-
*
|
|
2455
|
-
* @example Package-level messages
|
|
2456
|
-
* ```typescript
|
|
2457
|
-
* I18nModule.registerMessages({
|
|
2458
|
-
* en: { tenancy: { tenantNotFound: 'Tenant not found' } },
|
|
2459
|
-
* })
|
|
2460
|
-
* ```
|
|
2461
|
-
*/
|
|
2462
|
-
static registerMessages(messages) {
|
|
2463
|
-
MessageRegistry.addMessages(messages);
|
|
2464
|
-
return {
|
|
2465
|
-
module: _I18nModule,
|
|
2466
|
-
providers: []
|
|
2467
|
-
};
|
|
2468
|
-
}
|
|
2469
|
-
configureRoutes(router) {
|
|
2470
|
-
router.use(I18nContextMiddleware);
|
|
2471
|
-
}
|
|
2472
|
-
};
|
|
2473
|
-
I18nModule = _I18nModule = __decorate([Module({ providers: [
|
|
2474
|
-
{
|
|
2475
|
-
provide: I18N_TOKENS.MessageRegistry,
|
|
2476
|
-
useClass: MessageRegistry,
|
|
2477
|
-
scope: Scope.Singleton
|
|
2478
|
-
},
|
|
2479
|
-
{
|
|
2480
|
-
provide: I18N_TOKENS.MessageLoader,
|
|
2481
|
-
useClass: MessageLoaderService,
|
|
2482
|
-
scope: Scope.Singleton
|
|
2483
|
-
},
|
|
2484
|
-
{
|
|
2485
|
-
provide: I18N_TOKENS.I18nService,
|
|
2486
|
-
useClass: I18nService
|
|
2487
|
-
}
|
|
2488
|
-
] })], I18nModule);
|
|
2489
|
-
//#endregion
|
|
2490
|
-
export { OpenAPIModule as A, LocaleNotSupportedError as B, validationErrorResponseSchema as C, createMiddlewareChain as D, getRouteMetadata as E, getMessages as F, I18nContextMiddleware as H, messages as I, buildDetectorOptions as L, MessageRegistry as M, MessageLoaderService as N, createDomainMiddleware as O, getLocales as P, resolveI18nOptions as R, uuidParamSchema as S, getRouteDecoratedMethods as T, OpenAPIConfigService as V, commonErrorSchemas as _, buildRouteUrl as a, paginationQuerySchema as b, LocalePathService as c, extractDomainParamNames as d, extractParamNames as f, toOpenAPIPath as g, sortRoutesBySpecificity as h, Uri as i, OpenAPIService as j, parseDomainPattern as k, HonoApp as l, getPathSpecificityScore as m, VerifySignatureMiddleware as n, RouteRegistry as o, generateConventionRouteName as p, route as r, VersioningService as s, I18nModule as t, RouteRegistrationService as u, errorResponseSchema as v, Route as w, successMessageSchema as x, paginatedResponseSchema as y, TranslationMissingError as z };
|
|
1850
|
+
export { parseDomainPattern as A, uuidParamSchema as C, getRouteMetadata as D, getRouteDecoratedMethods as E, ResponseValidationError as M, SchemaValidationError as N, createMiddlewareChain as O, RouteNotFoundError as P, successMessageSchema as S, Route as T, toOpenAPIPath as _, RouteRegistry as a, paginatedResponseSchema as b, buildDetectorOptions as c, RouteRegistrationService as d, extractDomainParamNames as f, sortRoutesBySpecificity as g, getPathSpecificityScore as h, route as i, InvalidSignatureError as j, createDomainMiddleware as k, resolveI18nOptions as l, generateConventionRouteName as m, Uri as n, VersioningService as o, extractParamNames as p, buildRouteUrl as r, LocalePathService as s, VerifySignatureMiddleware as t, HonoApp as u, commonErrorSchemas as v, validationErrorResponseSchema as w, paginationQuerySchema as x, errorResponseSchema as y };
|
|
2491
1851
|
|
|
2492
|
-
//# sourceMappingURL=
|
|
1852
|
+
//# sourceMappingURL=router-Cy6DjkvP.mjs.map
|