stratal 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/bin/cloudflare-workers-loader.mjs +80 -7
- package/dist/bin/cloudflare-workers-loader.mjs.map +1 -1
- package/dist/bin/quarry.mjs +41 -54
- package/dist/bin/quarry.mjs.map +1 -1
- package/dist/cache/index.d.mts +5 -3
- package/dist/cache/index.d.mts.map +1 -1
- package/dist/cache/index.mjs +123 -39
- package/dist/cache/index.mjs.map +1 -1
- package/dist/{cache.service-e34gV6tz.d.mts → cache.service-uElmBtdS.d.mts} +24 -34
- package/dist/cache.service-uElmBtdS.d.mts.map +1 -0
- package/dist/{command-BU4ApTo5.mjs → command-BvmUAPPQ.mjs} +15 -3
- package/dist/command-BvmUAPPQ.mjs.map +1 -0
- package/dist/{command-wXfvHbBZ.d.mts → command-CPhFHjG3.d.mts} +2 -2
- package/dist/command-CPhFHjG3.d.mts.map +1 -0
- package/dist/command-not-found.error-ONAZ2Bpk.mjs +14 -0
- package/dist/command-not-found.error-ONAZ2Bpk.mjs.map +1 -0
- package/dist/config/index.d.mts +3 -3
- package/dist/config/index.d.mts.map +1 -1
- package/dist/config/index.mjs +7 -6
- package/dist/config/index.mjs.map +1 -1
- package/dist/{consumer-registry-DHQtypr1.d.mts → consumer-registry-D3iMTSdy.d.mts} +54 -22
- package/dist/consumer-registry-D3iMTSdy.d.mts.map +1 -0
- package/dist/{container-storage-GpNNz79X.mjs → container-storage-BmOJ4_Na.mjs} +1 -1
- package/dist/{container-storage-GpNNz79X.mjs.map → container-storage-BmOJ4_Na.mjs.map} +1 -1
- package/dist/{controller.decorator-DIUazNU7.mjs → controller.decorator-C5UVeJS3.mjs} +4 -4
- package/dist/{controller.decorator-DIUazNU7.mjs.map → controller.decorator-C5UVeJS3.mjs.map} +1 -1
- package/dist/cron/index.d.mts +79 -4
- package/dist/cron/index.d.mts.map +1 -1
- package/dist/cron/index.mjs +2 -2
- package/dist/cron-job-NesZRk8F.d.mts +58 -0
- package/dist/cron-job-NesZRk8F.d.mts.map +1 -0
- package/dist/{cron-manager-9bpN9bu4.mjs → cron.module-Bgzq5hiT.mjs} +17 -7
- package/dist/cron.module-Bgzq5hiT.mjs.map +1 -0
- package/dist/{decorate-HgTKAYK8.mjs → decorate-CuAoSZvs.mjs} +2 -2
- package/dist/{deep-merge-C8NgcXw4.mjs → deep-merge-ByiAOZ3r.mjs} +1 -1
- package/dist/{deep-merge-C8NgcXw4.mjs.map → deep-merge-ByiAOZ3r.mjs.map} +1 -1
- package/dist/di/index.d.mts +2 -2
- package/dist/di/index.mjs +3 -3
- package/dist/{di-BO1QIb5H.mjs → di-DseMn-z9.mjs} +244 -135
- package/dist/di-DseMn-z9.mjs.map +1 -0
- package/dist/email/index.d.mts +33 -40
- package/dist/email/index.d.mts.map +1 -1
- package/dist/email/index.mjs +456 -41
- package/dist/email/index.mjs.map +1 -1
- package/dist/{en-BPP6h6y5.mjs → en-CDZBMcc1.mjs} +2 -2
- package/dist/{en-BPP6h6y5.mjs.map → en-CDZBMcc1.mjs.map} +1 -1
- package/dist/{env-DKSbuBi5.d.mts → env-ug22bJj7.d.mts} +1 -1
- package/dist/env-ug22bJj7.d.mts.map +1 -0
- package/dist/errors/index.d.mts +1 -1
- package/dist/errors/index.mjs +3 -3
- package/dist/{errors-BBZTnjdq.mjs → errors-mXYxG0XB.mjs} +5 -5
- package/dist/{errors-BBZTnjdq.mjs.map → errors-mXYxG0XB.mjs.map} +1 -1
- package/dist/events/index.d.mts +14 -3
- package/dist/events/index.d.mts.map +1 -1
- package/dist/events/index.mjs +2 -2
- package/dist/{events-D1KdDaiP.mjs → events-BXJGZjpG.mjs} +16 -6
- package/dist/events-BXJGZjpG.mjs.map +1 -0
- package/dist/{exception-context-B4kM-M53.mjs → exception-context-kEoMFwze.mjs} +3 -3
- package/dist/{exception-context-B4kM-M53.mjs.map → exception-context-kEoMFwze.mjs.map} +1 -1
- package/dist/{gateway-context-CFe6a9gz.mjs → gateway-context-TMu_AlJt.mjs} +25 -6
- package/dist/{gateway-context-CFe6a9gz.mjs.map → gateway-context-TMu_AlJt.mjs.map} +1 -1
- 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-Ced-uNIF.mjs → guards-DALPXy3_.mjs} +2 -2
- package/dist/{guards-Ced-uNIF.mjs.map → guards-DALPXy3_.mjs.map} +1 -1
- package/dist/hono-app-CvV3hOfT.mjs +161 -0
- package/dist/hono-app-CvV3hOfT.mjs.map +1 -0
- package/dist/{http-method.decorator-CdjKFJZZ.mjs → http-method.decorator-ByWZb9DO.mjs} +4 -4
- package/dist/{http-method.decorator-CdjKFJZZ.mjs.map → http-method.decorator-ByWZb9DO.mjs.map} +1 -1
- package/dist/i18n/index.d.mts +4 -4
- package/dist/i18n/index.d.mts.map +1 -1
- package/dist/i18n/index.mjs +5 -5
- package/dist/i18n/index.mjs.map +1 -1
- package/dist/i18n/messages/en/index.d.mts +1 -1
- package/dist/i18n/messages/en/index.mjs +1 -1
- package/dist/i18n/utils/index.mjs +1 -1
- package/dist/i18n/validation/index.d.mts +3 -3
- package/dist/i18n/validation/index.mjs +3 -3
- package/dist/{i18n.module-BlXrtAlV.mjs → i18n.module-DRQAZoSZ.mjs} +14 -11
- package/dist/{i18n.module-BlXrtAlV.mjs.map → i18n.module-DRQAZoSZ.mjs.map} +1 -1
- package/dist/{i18n.tokens-hwRpmjRq.mjs → i18n.tokens-CZ_v8oyS.mjs} +1 -1
- package/dist/{i18n.tokens-hwRpmjRq.mjs.map → i18n.tokens-CZ_v8oyS.mjs.map} +1 -1
- package/dist/{index-B4UBK-2T.d.mts → index-0ItCjaqw.d.mts} +1 -1
- package/dist/index-0ItCjaqw.d.mts.map +1 -0
- package/dist/{index-CW1YHSft.d.mts → index-B5JBRcWD.d.mts} +249 -103
- package/dist/index-B5JBRcWD.d.mts.map +1 -0
- package/dist/{index-BtlE9RuO.d.mts → index-BUt92sAE.d.mts} +1 -1
- package/dist/index-BUt92sAE.d.mts.map +1 -0
- package/dist/{index-DEncMcC6.d.mts → index-B_JoEl3V.d.mts} +221 -16
- package/dist/index-B_JoEl3V.d.mts.map +1 -0
- package/dist/{index-Dj5IMwtr.d.mts → index-DtBNIFuP.d.mts} +4 -6
- package/dist/index-DtBNIFuP.d.mts.map +1 -0
- package/dist/{index-KMgSCSM7.d.mts → index-HgOLNruQ.d.mts} +1 -1
- package/dist/{index-KMgSCSM7.d.mts.map → index-HgOLNruQ.d.mts.map} +1 -1
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +3 -2
- package/dist/{is-command-CX5rAfZW.mjs → is-command-CEPO9n8c.mjs} +2 -2
- package/dist/{is-command-CX5rAfZW.mjs.map → is-command-CEPO9n8c.mjs.map} +1 -1
- package/dist/{is-seeder-CYCtELlm.mjs → is-seeder-Gvh_AM71.mjs} +1 -1
- package/dist/{is-seeder-CYCtELlm.mjs.map → is-seeder-Gvh_AM71.mjs.map} +1 -1
- package/dist/lazy-module-loader-Ib383jH_.d.mts +60 -0
- package/dist/lazy-module-loader-Ib383jH_.d.mts.map +1 -0
- package/dist/locale-path.service-D-dHiIPc.mjs +165 -0
- package/dist/locale-path.service-D-dHiIPc.mjs.map +1 -0
- package/dist/locale-url-nZrZxqJP.mjs +44 -0
- package/dist/locale-url-nZrZxqJP.mjs.map +1 -0
- package/dist/locale-url.service-C2EWmGdq.mjs +41 -0
- package/dist/locale-url.service-C2EWmGdq.mjs.map +1 -0
- package/dist/logger/index.d.mts +1 -1
- package/dist/logger/index.mjs +2 -2
- package/dist/logger/index.mjs.map +1 -1
- package/dist/macroable/index.d.mts +2 -2
- package/dist/macroable/index.mjs +1 -1
- package/dist/{macroable-DzlfzT50.mjs → macroable-cvDTFZ_A.mjs} +1 -1
- package/dist/{macroable-DzlfzT50.mjs.map → macroable-cvDTFZ_A.mjs.map} +1 -1
- package/dist/{metadata-BVkc4aUu.mjs → metadata-DzzprcID.mjs} +1 -1
- package/dist/{metadata-BVkc4aUu.mjs.map → metadata-DzzprcID.mjs.map} +1 -1
- package/dist/module/index.d.mts +4 -3
- package/dist/module/index.d.mts.map +1 -1
- package/dist/module/index.mjs +10 -2
- package/dist/module/index.mjs.map +1 -0
- package/dist/{module-xYoHba6B.mjs → module-registry-Dm-pqHd3.mjs} +189 -57
- package/dist/module-registry-Dm-pqHd3.mjs.map +1 -0
- package/dist/module.decorator-CYHY6pG5.mjs +19 -0
- package/dist/module.decorator-CYHY6pG5.mjs.map +1 -0
- package/dist/openapi/index.d.mts +44 -8
- package/dist/openapi/index.d.mts.map +1 -1
- package/dist/openapi/index.mjs +3 -2
- package/dist/{openapi-C6lm0RmV.mjs → openapi-CstuTM8S.mjs} +55 -229
- package/dist/openapi-CstuTM8S.mjs.map +1 -0
- package/dist/openapi-tools.service-BC5EC3R3.mjs +206 -0
- package/dist/openapi-tools.service-BC5EC3R3.mjs.map +1 -0
- package/dist/{openapi.service-CrLlsXAd.d.mts → openapi.service-YhTiJ1bO.d.mts} +3 -3
- package/dist/{openapi.service-CrLlsXAd.d.mts.map → openapi.service-YhTiJ1bO.d.mts.map} +1 -1
- package/dist/quarry/index.d.mts +14 -5
- package/dist/quarry/index.d.mts.map +1 -1
- package/dist/quarry/index.mjs +6 -5
- package/dist/quarry/runner.d.mts +11 -11
- package/dist/quarry/runner.d.mts.map +1 -1
- package/dist/quarry/runner.mjs +192 -22
- package/dist/quarry/runner.mjs.map +1 -1
- package/dist/{quarry-registry-D4hIGScf.d.mts → quarry-registry-CXg0RFXq.d.mts} +4 -4
- package/dist/quarry-registry-CXg0RFXq.d.mts.map +1 -0
- package/dist/{quarry-registry-DkraZNwn.mjs → quarry.module-BuRPGMDm.mjs} +22 -21
- package/dist/quarry.module-BuRPGMDm.mjs.map +1 -0
- package/dist/queue/index.d.mts +3 -3
- package/dist/queue/index.mjs +42 -31
- package/dist/queue/index.mjs.map +1 -1
- package/dist/queue.module-nddvxzCB.mjs +613 -0
- package/dist/queue.module-nddvxzCB.mjs.map +1 -0
- package/dist/queue.tokens-DjHnFmre.mjs +11 -0
- package/dist/queue.tokens-DjHnFmre.mjs.map +1 -0
- package/dist/{r2-storage.provider-Hfm6LdZQ.mjs → r2-storage.provider-DCxQt9dD.mjs} +4 -4
- package/dist/{r2-storage.provider-Hfm6LdZQ.mjs.map → r2-storage.provider-DCxQt9dD.mjs.map} +1 -1
- package/dist/{rate-limit.decorator-D69zdZbp.mjs → rate-limit.decorator-BPAie_p3.mjs} +3 -3
- package/dist/{rate-limit.decorator-D69zdZbp.mjs.map → rate-limit.decorator-BPAie_p3.mjs.map} +1 -1
- package/dist/rate-limiter/index.d.mts +5 -5
- package/dist/rate-limiter/index.d.mts.map +1 -1
- package/dist/rate-limiter/index.mjs +26 -21
- package/dist/rate-limiter/index.mjs.map +1 -1
- package/dist/route-name-DGoBOfPg.mjs +171 -0
- package/dist/route-name-DGoBOfPg.mjs.map +1 -0
- package/dist/route-registration.service-D6vSwiKP.mjs +918 -0
- package/dist/route-registration.service-D6vSwiKP.mjs.map +1 -0
- package/dist/route-registry-CYqLp2Nj.mjs +123 -0
- package/dist/route-registry-CYqLp2Nj.mjs.map +1 -0
- package/dist/router/index.d.mts +2 -2
- package/dist/router/index.mjs +18 -8
- package/dist/router-CWGBD-Bg.mjs +78 -0
- package/dist/router-CWGBD-Bg.mjs.map +1 -0
- package/dist/router-resolver-D4YlPNlm.mjs +88 -0
- package/dist/router-resolver-D4YlPNlm.mjs.map +1 -0
- package/dist/seeder/index.d.mts +14 -4
- package/dist/seeder/index.d.mts.map +1 -1
- package/dist/seeder/index.mjs +5 -3
- package/dist/{seeder-BADTig4n.mjs → seeder-7ubkms-Y.mjs} +7 -56
- package/dist/seeder-7ubkms-Y.mjs.map +1 -0
- package/dist/seeder-registry-CyUmKsJq.mjs +57 -0
- package/dist/seeder-registry-CyUmKsJq.mjs.map +1 -0
- package/dist/seeder.module-CYYwk3Qk.mjs +15 -0
- package/dist/seeder.module-CYYwk3Qk.mjs.map +1 -0
- package/dist/{signed-url-BqUqt5dF.mjs → signed-url-DIU0sK_6.mjs} +1 -1
- package/dist/{signed-url-BqUqt5dF.mjs.map → signed-url-DIU0sK_6.mjs.map} +1 -1
- package/dist/storage/index.d.mts +3 -3
- package/dist/storage/index.d.mts.map +1 -1
- package/dist/storage/index.mjs +2 -2
- package/dist/storage/providers/index.d.mts +2 -2
- package/dist/storage/providers/index.d.mts.map +1 -1
- package/dist/storage/providers/index.mjs +1 -1
- package/dist/{storage-BA3ppVYM.mjs → storage-MDZypIE9.mjs} +12 -11
- package/dist/{storage-BA3ppVYM.mjs.map → storage-MDZypIE9.mjs.map} +1 -1
- package/dist/{storage-provider.interface-DQMtT42e.d.mts → storage-provider.interface-ClUwxz4S.d.mts} +2 -2
- package/dist/storage-provider.interface-ClUwxz4S.d.mts.map +1 -0
- package/dist/storage.error-Dnib4VHc.mjs +8 -0
- package/dist/{storage.error-C6FY037a.mjs.map → storage.error-Dnib4VHc.mjs.map} +1 -1
- package/dist/{stratal-Bdq4IdB3.mjs → stratal-DL9M38_s.mjs} +142 -140
- package/dist/stratal-DL9M38_s.mjs.map +1 -0
- package/dist/{stratal-BsKmvP6J.d.mts → stratal-DwDJPY9N.d.mts} +3 -3
- package/dist/{stratal-BsKmvP6J.d.mts.map → stratal-DwDJPY9N.d.mts.map} +1 -1
- package/dist/tiered-cache.service-Dv3BhxxE.d.mts +79 -0
- package/dist/tiered-cache.service-Dv3BhxxE.d.mts.map +1 -0
- package/dist/trailing-slash-CFyw8nYu.mjs +34 -0
- package/dist/trailing-slash-CFyw8nYu.mjs.map +1 -0
- package/dist/{types-BaeHi67f.d.mts → types-CmV_9xBD.d.mts} +1 -1
- package/dist/types-CmV_9xBD.d.mts.map +1 -0
- package/dist/uri-h7Q8Jug9.mjs +251 -0
- package/dist/uri-h7Q8Jug9.mjs.map +1 -0
- package/dist/{usage-generator-DTqaUMR9.mjs → usage-generator-DAWYasuP.mjs} +4 -4
- package/dist/usage-generator-DAWYasuP.mjs.map +1 -0
- package/dist/{validation-DUzcjb8Q.mjs → validation-CpOjviyT.mjs} +6 -6
- package/dist/{validation-DUzcjb8Q.mjs.map → validation-CpOjviyT.mjs.map} +1 -1
- package/dist/{validation.context-XTysWJ3b.mjs → validation.context-CRvmrhq7.mjs} +3 -3
- package/dist/{validation.context-XTysWJ3b.mjs.map → validation.context-CRvmrhq7.mjs.map} +1 -1
- package/dist/versioning.service-C6aHky8-.mjs +36 -0
- package/dist/versioning.service-C6aHky8-.mjs.map +1 -0
- package/dist/websocket/index.d.mts +11 -2
- package/dist/websocket/index.d.mts.map +1 -1
- package/dist/websocket/index.mjs +1 -1
- package/dist/workers/index.d.mts +2 -2
- package/dist/workers/index.d.mts.map +1 -1
- package/dist/workers/index.mjs +3 -3
- package/dist/workers/index.mjs.map +1 -1
- package/dist/{zod-hMa3rSHV.mjs → zod-eKqqhZ5_.mjs} +2 -2
- package/dist/{zod-hMa3rSHV.mjs.map → zod-eKqqhZ5_.mjs.map} +1 -1
- package/dist/{zod-DvWTfRpI.d.mts → zod-wecrEVAs.d.mts} +8 -3
- package/dist/zod-wecrEVAs.d.mts.map +1 -0
- package/package.json +19 -30
- package/dist/base-email.provider-BWZHIjt8.mjs +0 -42
- package/dist/base-email.provider-BWZHIjt8.mjs.map +0 -1
- package/dist/cache.service-e34gV6tz.d.mts.map +0 -1
- package/dist/cache.tokens-ovi_c52J.mjs +0 -6
- package/dist/cache.tokens-ovi_c52J.mjs.map +0 -1
- package/dist/colors-axmupKdp.mjs +0 -16
- package/dist/colors-axmupKdp.mjs.map +0 -1
- package/dist/command-BU4ApTo5.mjs.map +0 -1
- package/dist/command-wXfvHbBZ.d.mts.map +0 -1
- package/dist/consumer-registry-DHQtypr1.d.mts.map +0 -1
- package/dist/cron-manager-9bpN9bu4.mjs.map +0 -1
- package/dist/cron-manager-CSTIBPcM.d.mts +0 -124
- package/dist/cron-manager-CSTIBPcM.d.mts.map +0 -1
- package/dist/di-BO1QIb5H.mjs.map +0 -1
- package/dist/env-DKSbuBi5.d.mts.map +0 -1
- package/dist/events-D1KdDaiP.mjs.map +0 -1
- package/dist/index-B4UBK-2T.d.mts.map +0 -1
- package/dist/index-BtlE9RuO.d.mts.map +0 -1
- package/dist/index-CW1YHSft.d.mts.map +0 -1
- package/dist/index-DEncMcC6.d.mts.map +0 -1
- package/dist/index-Dj5IMwtr.d.mts.map +0 -1
- package/dist/module-xYoHba6B.mjs.map +0 -1
- package/dist/openapi-C6lm0RmV.mjs.map +0 -1
- package/dist/quarry-registry-D4hIGScf.d.mts.map +0 -1
- package/dist/quarry-registry-DkraZNwn.mjs.map +0 -1
- package/dist/queue.module-DeWJ0tQM.mjs +0 -355
- package/dist/queue.module-DeWJ0tQM.mjs.map +0 -1
- package/dist/resend.provider-Ur6tU7fK.mjs +0 -68
- package/dist/resend.provider-Ur6tU7fK.mjs.map +0 -1
- package/dist/router-Cy6DjkvP.mjs +0 -1852
- package/dist/router-Cy6DjkvP.mjs.map +0 -1
- package/dist/seeder-BADTig4n.mjs.map +0 -1
- package/dist/smtp.provider-C129sNBT.mjs +0 -76
- package/dist/smtp.provider-C129sNBT.mjs.map +0 -1
- package/dist/storage-provider.interface-DQMtT42e.d.mts.map +0 -1
- package/dist/storage.error-C6FY037a.mjs +0 -8
- package/dist/stratal-Bdq4IdB3.mjs.map +0 -1
- package/dist/types-BaeHi67f.d.mts.map +0 -1
- package/dist/usage-generator-DTqaUMR9.mjs.map +0 -1
- package/dist/zod-DvWTfRpI.d.mts.map +0 -1
- /package/dist/{chunk-D1SwGrFN.mjs → chunk-BBjsoOtd.mjs} +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
//#region src/router/utils/path.ts
|
|
2
|
+
/**
|
|
3
|
+
* Path normalization and route ordering utilities.
|
|
4
|
+
*
|
|
5
|
+
* Users always write Hono-style `:param` paths (`:companyId`, `:id`).
|
|
6
|
+
* OpenAPI requires `{param}` style — conversion happens only at registration time.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Convert Hono-style `:param` path segments to OpenAPI-style `{param}`.
|
|
10
|
+
* Strips regex constraints (e.g., `:locale{sw}` → `{locale}`).
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* toOpenAPIPath('/users/:id') // '/users/{id}'
|
|
14
|
+
* toOpenAPIPath('/:companyId/users/:userId') // '/{companyId}/users/{userId}'
|
|
15
|
+
* toOpenAPIPath('/users/:id/posts') // '/users/{id}/posts'
|
|
16
|
+
* toOpenAPIPath('/:locale{en|fr}/users') // '/{locale}/users'
|
|
17
|
+
*/
|
|
18
|
+
function toOpenAPIPath(path) {
|
|
19
|
+
return path.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\{[^}]*\})?/g, "{$1}");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Convert Hono-style `:param` path segments to OpenAPI-style `{param}`,
|
|
23
|
+
* preserving regex constraints.
|
|
24
|
+
*
|
|
25
|
+
* Used for Hono route registration via `app.openapi()`. The non-greedy
|
|
26
|
+
* regex in `@hono/zod-openapi` (`\/{(.+?)}/g`) converts `{param}` back
|
|
27
|
+
* to `:param` while leaving the constraint suffix intact.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* toRoutingOpenAPIPath('/:locale{sw}/users/:id') // '/{locale}{sw}/users/{id}'
|
|
31
|
+
* toRoutingOpenAPIPath('/users/:id') // '/users/{id}'
|
|
32
|
+
*/
|
|
33
|
+
function toRoutingOpenAPIPath(path) {
|
|
34
|
+
return path.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\{[^}]*\})?/g, (_, name, constraint) => constraint ? `{${name}}${constraint}` : `{${name}}`);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compute a packed specificity key for route ordering.
|
|
38
|
+
* Encodes both score and segment count into a single number to avoid object allocation.
|
|
39
|
+
*
|
|
40
|
+
* Lower score = higher priority (registered first in Hono).
|
|
41
|
+
* Scoring: static = 0, `:param{constraint}` = 5, `:param` = 10, wildcard `{.+}` / `{.*}` = 100.
|
|
42
|
+
*
|
|
43
|
+
* Packed as: score * 10000 - segmentCount (negative segment count so more segments = lower key = higher priority)
|
|
44
|
+
*
|
|
45
|
+
* Locale variants score against the path with the leading `/:locale{…}` segment
|
|
46
|
+
* stripped — the variant's score therefore matches its primary, but its larger
|
|
47
|
+
* segment count makes it sort just before the primary. Without this, a primary
|
|
48
|
+
* catch-all (e.g. `/:slug{.+}`) gobbles locale-prefixed URLs because Hono picks
|
|
49
|
+
* whichever matching route was registered first.
|
|
50
|
+
*/
|
|
51
|
+
function getPathSpecificityKey(route) {
|
|
52
|
+
const segmentCount = countSegments(route.path);
|
|
53
|
+
const scoringPath = route.isLocaleVariant ? route.path.replace(/^\/:locale\{[^}]*\}/, "") || "/" : route.path;
|
|
54
|
+
let score = 0;
|
|
55
|
+
let i = 0;
|
|
56
|
+
while (i < scoringPath.length) {
|
|
57
|
+
if (scoringPath.charCodeAt(i) === 47) {
|
|
58
|
+
i++;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
let end = scoringPath.indexOf("/", i);
|
|
62
|
+
if (end === -1) end = scoringPath.length;
|
|
63
|
+
const segment = scoringPath.substring(i, end);
|
|
64
|
+
if (segment.includes("{.+}") || segment.includes("{.*}")) score += 100;
|
|
65
|
+
else if (segment.charCodeAt(0) === 58) score += segment.includes("{") ? 5 : 10;
|
|
66
|
+
i = end;
|
|
67
|
+
}
|
|
68
|
+
return score * 1e4 - segmentCount;
|
|
69
|
+
}
|
|
70
|
+
function countSegments(path) {
|
|
71
|
+
let count = 0;
|
|
72
|
+
let i = 0;
|
|
73
|
+
while (i < path.length) {
|
|
74
|
+
if (path.charCodeAt(i) === 47) {
|
|
75
|
+
i++;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
let end = path.indexOf("/", i);
|
|
79
|
+
if (end === -1) end = path.length;
|
|
80
|
+
count++;
|
|
81
|
+
i = end;
|
|
82
|
+
}
|
|
83
|
+
return count;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Compute a specificity score for route ordering.
|
|
87
|
+
* Lower score = higher priority (registered first in Hono).
|
|
88
|
+
*
|
|
89
|
+
* Scoring: static = 0, `:param{constraint}` = 5, `:param` = 10, wildcard `{.+}` / `{.*}` = 100.
|
|
90
|
+
*/
|
|
91
|
+
function getPathSpecificityScore(path) {
|
|
92
|
+
const segments = path.split("/").filter(Boolean);
|
|
93
|
+
let score = 0;
|
|
94
|
+
for (const segment of segments) if (segment.includes("{.+}") || segment.includes("{.*}")) score += 100;
|
|
95
|
+
else if (segment.startsWith(":") && segment.includes("{")) score += 5;
|
|
96
|
+
else if (segment.startsWith(":")) score += 10;
|
|
97
|
+
return score;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Sort routes by specificity so Hono registers them in the correct order.
|
|
101
|
+
*
|
|
102
|
+
* 1. Static paths before parameterized before wildcards
|
|
103
|
+
* 2. More segments = more specific (tie-breaker)
|
|
104
|
+
* 3. Locale-prefixed variants before their primary (so a locale-prefixed
|
|
105
|
+
* request matches the variant first; a primary catch-all would otherwise
|
|
106
|
+
* swallow the locale prefix into its param)
|
|
107
|
+
*/
|
|
108
|
+
function sortRoutesBySpecificity(routes) {
|
|
109
|
+
const keys = /* @__PURE__ */ new Map();
|
|
110
|
+
for (const route of routes) keys.set(route, getPathSpecificityKey(route));
|
|
111
|
+
const copy = routes.slice();
|
|
112
|
+
copy.sort((a, b) => keys.get(a) - keys.get(b));
|
|
113
|
+
return copy;
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/router/utils/route-name.ts
|
|
117
|
+
/**
|
|
118
|
+
* Route naming utilities.
|
|
119
|
+
*
|
|
120
|
+
* Extracts parameter names from paths and domains,
|
|
121
|
+
* and generates convention-based route names.
|
|
122
|
+
*/
|
|
123
|
+
/**
|
|
124
|
+
* Extract parameter names from a Hono-style path.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* extractParamNames('/users/:id') // ['id']
|
|
128
|
+
* extractParamNames('/:companyId/users/:userId') // ['companyId', 'userId']
|
|
129
|
+
* extractParamNames('/users') // []
|
|
130
|
+
*/
|
|
131
|
+
function extractParamNames(path) {
|
|
132
|
+
if (!path.includes(":")) return [];
|
|
133
|
+
return [...path.matchAll(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)].map((m) => m[1]);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Extract parameter names from a domain pattern.
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* extractDomainParamNames('{tenant}.example.com') // ['tenant']
|
|
140
|
+
* extractDomainParamNames('{region}.{tenant}.example.com') // ['region', 'tenant']
|
|
141
|
+
* extractDomainParamNames('example.com') // []
|
|
142
|
+
*/
|
|
143
|
+
function extractDomainParamNames(domain) {
|
|
144
|
+
if (!domain.includes("{")) return [];
|
|
145
|
+
return [...domain.matchAll(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g)].map((m) => m[1]);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Auto-generate a route name for convention-based `@Route` methods.
|
|
149
|
+
*
|
|
150
|
+
* Strips common prefixes (`/api/`, `/v{N}/`) and parameter segments,
|
|
151
|
+
* then joins remaining static segments with dots and appends the method name.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* generateConventionRouteName('/users', 'index') // 'users.index'
|
|
155
|
+
* generateConventionRouteName('/users', 'show') // 'users.show'
|
|
156
|
+
* generateConventionRouteName('/api/v1/users', 'create') // 'users.create'
|
|
157
|
+
* generateConventionRouteName('/api/v1/users/:userId/notes', 'index') // 'users.notes.index'
|
|
158
|
+
* generateConventionRouteName('/:companyId/users', 'index') // 'users.index'
|
|
159
|
+
* generateConventionRouteName('/users/:userId/notes/:noteId/tags', 'index') // 'users.notes.tags.index'
|
|
160
|
+
*/
|
|
161
|
+
function generateConventionRouteName(basePath, methodName) {
|
|
162
|
+
const parts = basePath.split("/");
|
|
163
|
+
const segments = [];
|
|
164
|
+
for (const s of parts) if (s && s !== "api" && !s.startsWith(":") && !/^v\d+$/.test(s)) segments.push(s);
|
|
165
|
+
if (segments.length === 0) return methodName;
|
|
166
|
+
return `${segments.join(".")}.${methodName}`;
|
|
167
|
+
}
|
|
168
|
+
//#endregion
|
|
169
|
+
export { sortRoutesBySpecificity as a, getPathSpecificityScore as i, extractParamNames as n, toOpenAPIPath as o, generateConventionRouteName as r, toRoutingOpenAPIPath as s, extractDomainParamNames as t };
|
|
170
|
+
|
|
171
|
+
//# sourceMappingURL=route-name-DGoBOfPg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route-name-DGoBOfPg.mjs","names":[],"sources":["../src/router/utils/path.ts","../src/router/utils/route-name.ts"],"sourcesContent":["/**\n * Path normalization and route ordering utilities.\n *\n * Users always write Hono-style `:param` paths (`:companyId`, `:id`).\n * OpenAPI requires `{param}` style — conversion happens only at registration time.\n */\n\n/**\n * Convert Hono-style `:param` path segments to OpenAPI-style `{param}`.\n * Strips regex constraints (e.g., `:locale{sw}` → `{locale}`).\n *\n * @example\n * toOpenAPIPath('/users/:id') // '/users/{id}'\n * toOpenAPIPath('/:companyId/users/:userId') // '/{companyId}/users/{userId}'\n * toOpenAPIPath('/users/:id/posts') // '/users/{id}/posts'\n * toOpenAPIPath('/:locale{en|fr}/users') // '/{locale}/users'\n */\nexport function toOpenAPIPath(path: string): string {\n return path.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)(\\{[^}]*\\})?/g, '{$1}')\n}\n\n/**\n * Convert Hono-style `:param` path segments to OpenAPI-style `{param}`,\n * preserving regex constraints.\n *\n * Used for Hono route registration via `app.openapi()`. The non-greedy\n * regex in `@hono/zod-openapi` (`\\/{(.+?)}/g`) converts `{param}` back\n * to `:param` while leaving the constraint suffix intact.\n *\n * @example\n * toRoutingOpenAPIPath('/:locale{sw}/users/:id') // '/{locale}{sw}/users/{id}'\n * toRoutingOpenAPIPath('/users/:id') // '/users/{id}'\n */\nexport function toRoutingOpenAPIPath(path: string): string {\n return path.replace(\n /:([a-zA-Z_][a-zA-Z0-9_]*)(\\{[^}]*\\})?/g,\n (_, name: string, constraint?: string) => constraint ? `{${name}}${constraint}` : `{${name}}`,\n )\n}\n\n/**\n * Compute a packed specificity key for route ordering.\n * Encodes both score and segment count into a single number to avoid object allocation.\n *\n * Lower score = higher priority (registered first in Hono).\n * Scoring: static = 0, `:param{constraint}` = 5, `:param` = 10, wildcard `{.+}` / `{.*}` = 100.\n *\n * Packed as: score * 10000 - segmentCount (negative segment count so more segments = lower key = higher priority)\n *\n * Locale variants score against the path with the leading `/:locale{…}` segment\n * stripped — the variant's score therefore matches its primary, but its larger\n * segment count makes it sort just before the primary. Without this, a primary\n * catch-all (e.g. `/:slug{.+}`) gobbles locale-prefixed URLs because Hono picks\n * whichever matching route was registered first.\n */\nfunction getPathSpecificityKey(route: { path: string; isLocaleVariant?: boolean }): number {\n const segmentCount = countSegments(route.path)\n const scoringPath = route.isLocaleVariant\n ? (route.path.replace(/^\\/:locale\\{[^}]*\\}/, '') || '/')\n : route.path\n\n let score = 0\n let i = 0\n while (i < scoringPath.length) {\n if (scoringPath.charCodeAt(i) === 47 /* '/' */) { i++; continue }\n\n let end = scoringPath.indexOf('/', i)\n if (end === -1) end = scoringPath.length\n\n const segment = scoringPath.substring(i, end)\n\n if (segment.includes('{.+}') || segment.includes('{.*}')) {\n score += 100\n } else if (segment.charCodeAt(0) === 58 /* ':' */) {\n score += segment.includes('{') ? 5 : 10\n }\n\n i = end\n }\n\n return score * 10000 - segmentCount\n}\n\nfunction countSegments(path: string): number {\n let count = 0\n let i = 0\n while (i < path.length) {\n if (path.charCodeAt(i) === 47 /* '/' */) { i++; continue }\n let end = path.indexOf('/', i)\n if (end === -1) end = path.length\n count++\n i = end\n }\n return count\n}\n\n/**\n * Compute a specificity score for route ordering.\n * Lower score = higher priority (registered first in Hono).\n *\n * Scoring: static = 0, `:param{constraint}` = 5, `:param` = 10, wildcard `{.+}` / `{.*}` = 100.\n */\nexport function getPathSpecificityScore(path: string): number {\n const segments = path.split('/').filter(Boolean)\n let score = 0\n for (const segment of segments) {\n if (segment.includes('{.+}') || segment.includes('{.*}')) {\n score += 100\n } else if (segment.startsWith(':') && segment.includes('{')) {\n score += 5\n } else if (segment.startsWith(':')) {\n score += 10\n }\n }\n return score\n}\n\n/**\n * Sort routes by specificity so Hono registers them in the correct order.\n *\n * 1. Static paths before parameterized before wildcards\n * 2. More segments = more specific (tie-breaker)\n * 3. Locale-prefixed variants before their primary (so a locale-prefixed\n * request matches the variant first; a primary catch-all would otherwise\n * swallow the locale prefix into its param)\n */\nexport function sortRoutesBySpecificity<T extends { path: string; isLocaleVariant?: boolean }>(routes: T[]): T[] {\n // Pre-compute packed specificity keys (avoids object allocation per route)\n const keys = new Map<T, number>()\n for (const route of routes) {\n keys.set(route, getPathSpecificityKey(route))\n }\n\n const copy = routes.slice()\n copy.sort((a, b) => keys.get(a)! - keys.get(b)!)\n return copy\n}\n","/**\n * Route naming utilities.\n *\n * Extracts parameter names from paths and domains,\n * and generates convention-based route names.\n */\n\n/**\n * Extract parameter names from a Hono-style path.\n *\n * @example\n * extractParamNames('/users/:id') // ['id']\n * extractParamNames('/:companyId/users/:userId') // ['companyId', 'userId']\n * extractParamNames('/users') // []\n */\nexport function extractParamNames(path: string): string[] {\n if (!path.includes(':')) return []\n const matches = path.matchAll(/:([a-zA-Z_][a-zA-Z0-9_]*)/g)\n return [...matches].map(m => m[1])\n}\n\n/**\n * Extract parameter names from a domain pattern.\n *\n * @example\n * extractDomainParamNames('{tenant}.example.com') // ['tenant']\n * extractDomainParamNames('{region}.{tenant}.example.com') // ['region', 'tenant']\n * extractDomainParamNames('example.com') // []\n */\nexport function extractDomainParamNames(domain: string): string[] {\n if (!domain.includes('{')) return []\n const matches = domain.matchAll(/\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g)\n return [...matches].map(m => m[1])\n}\n\n/**\n * Auto-generate a route name for convention-based `@Route` methods.\n *\n * Strips common prefixes (`/api/`, `/v{N}/`) and parameter segments,\n * then joins remaining static segments with dots and appends the method name.\n *\n * @example\n * generateConventionRouteName('/users', 'index') // 'users.index'\n * generateConventionRouteName('/users', 'show') // 'users.show'\n * generateConventionRouteName('/api/v1/users', 'create') // 'users.create'\n * generateConventionRouteName('/api/v1/users/:userId/notes', 'index') // 'users.notes.index'\n * generateConventionRouteName('/:companyId/users', 'index') // 'users.index'\n * generateConventionRouteName('/users/:userId/notes/:noteId/tags', 'index') // 'users.notes.tags.index'\n */\nexport function generateConventionRouteName(basePath: string, methodName: string): string {\n // Single-pass: split and filter in one loop (avoids 4 intermediate arrays)\n const parts = basePath.split('/')\n const segments: string[] = []\n for (const s of parts) {\n if (s && s !== 'api' && !s.startsWith(':') && !/^v\\d+$/.test(s)) {\n segments.push(s)\n }\n }\n\n if (segments.length === 0) {\n return methodName\n }\n\n return `${segments.join('.')}.${methodName}`\n}\n"],"mappings":"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"}
|