acrylblends 0.4.0 → 0.5.0
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/LICENSE +73 -0
- package/dist/index.js +56 -2
- package/dist/index.js.map +1 -1
- package/docs/framework/LICENSE +23 -0
- package/docs/framework/README.md +63 -0
- package/docs/framework/UPSTREAM.md +3 -0
- package/docs/framework/agents/index.md +24 -0
- package/docs/framework/api/acryl.md +259 -0
- package/docs/framework/api/context.md +527 -0
- package/docs/framework/api/exception.md +80 -0
- package/docs/framework/api/index.md +12 -0
- package/docs/framework/api/presets.md +65 -0
- package/docs/framework/api/request.md +396 -0
- package/docs/framework/api/routing.md +303 -0
- package/docs/framework/api/summary.md +140 -0
- package/docs/framework/concepts/benchmarks.md +26 -0
- package/docs/framework/concepts/developer-experience.md +5 -0
- package/docs/framework/concepts/middleware.md +21 -0
- package/docs/framework/concepts/motivation.md +14 -0
- package/docs/framework/concepts/routers.md +63 -0
- package/docs/framework/concepts/stacks.md +235 -0
- package/docs/framework/concepts/web-standard.md +37 -0
- package/docs/framework/cordis/acryl-in-a-cordis-app.md +146 -0
- package/docs/framework/cordis/concepts.md +105 -0
- package/docs/framework/cordis/middleware.md +8 -0
- package/docs/framework/cordis/migration-from-0-3.md +111 -0
- package/docs/framework/cordis/migration-from-0-4.md +14 -0
- package/docs/framework/cordis/migration-from-dsh-webserver.md +103 -0
- package/docs/framework/cordis/mounting.md +85 -0
- package/docs/framework/cordis/node-server.md +75 -0
- package/docs/framework/cordis/plugin-lifecycle.md +111 -0
- package/docs/framework/cordis/surfaces.md +71 -0
- package/docs/framework/cordis/transport-and-cancellation.md +57 -0
- package/docs/framework/cordis/validation.md +135 -0
- package/docs/framework/getting-started/basic.md +196 -0
- package/docs/framework/getting-started/bun.md +221 -0
- package/docs/framework/getting-started/nodejs.md +344 -0
- package/docs/framework/getting-started/other-runtimes.md +23 -0
- package/docs/framework/guides/best-practices.md +231 -0
- package/docs/framework/guides/create-acrylblends.md +79 -0
- package/docs/framework/guides/examples.md +3 -0
- package/docs/framework/guides/faq.md +19 -0
- package/docs/framework/guides/helpers.md +33 -0
- package/docs/framework/guides/jsx-dom.md +299 -0
- package/docs/framework/guides/jsx.md +440 -0
- package/docs/framework/guides/middleware.md +253 -0
- package/docs/framework/guides/rpc.md +886 -0
- package/docs/framework/guides/testing.md +133 -0
- package/docs/framework/guides/validation.md +383 -0
- package/docs/framework/helpers/accepts.md +60 -0
- package/docs/framework/helpers/adapter.md +87 -0
- package/docs/framework/helpers/conninfo.md +112 -0
- package/docs/framework/helpers/cookie.md +232 -0
- package/docs/framework/helpers/css.md +285 -0
- package/docs/framework/helpers/dev.md +67 -0
- package/docs/framework/helpers/factory.md +180 -0
- package/docs/framework/helpers/html.md +123 -0
- package/docs/framework/helpers/jwt.md +184 -0
- package/docs/framework/helpers/proxy.md +118 -0
- package/docs/framework/helpers/route.md +143 -0
- package/docs/framework/helpers/ssg.md +393 -0
- package/docs/framework/helpers/streaming.md +119 -0
- package/docs/framework/helpers/testing.md +101 -0
- package/docs/framework/helpers/websocket.md +215 -0
- package/docs/framework/middleware/builtin/basic-auth.md +165 -0
- package/docs/framework/middleware/builtin/bearer-auth.md +138 -0
- package/docs/framework/middleware/builtin/body-limit.md +71 -0
- package/docs/framework/middleware/builtin/cache.md +122 -0
- package/docs/framework/middleware/builtin/combine.md +94 -0
- package/docs/framework/middleware/builtin/compress.md +59 -0
- package/docs/framework/middleware/builtin/context-storage.md +78 -0
- package/docs/framework/middleware/builtin/cors.md +135 -0
- package/docs/framework/middleware/builtin/csrf.md +105 -0
- package/docs/framework/middleware/builtin/etag.md +54 -0
- package/docs/framework/middleware/builtin/ip-restriction.md +69 -0
- package/docs/framework/middleware/builtin/jsx-renderer.md +286 -0
- package/docs/framework/middleware/builtin/jwk.md +192 -0
- package/docs/framework/middleware/builtin/jwt.md +145 -0
- package/docs/framework/middleware/builtin/language.md +232 -0
- package/docs/framework/middleware/builtin/logger.md +74 -0
- package/docs/framework/middleware/builtin/loopback-only.md +31 -0
- package/docs/framework/middleware/builtin/method-not-allowed.md +48 -0
- package/docs/framework/middleware/builtin/method-override.md +80 -0
- package/docs/framework/middleware/builtin/mount.md +106 -0
- package/docs/framework/middleware/builtin/pretty-json.md +53 -0
- package/docs/framework/middleware/builtin/request-id.md +94 -0
- package/docs/framework/middleware/builtin/secure-headers.md +247 -0
- package/docs/framework/middleware/builtin/timeout.md +98 -0
- package/docs/framework/middleware/builtin/timing.md +101 -0
- package/docs/framework/middleware/builtin/trailing-slash.md +74 -0
- package/docs/framework/middleware/third-party.md +4 -0
- package/docs/framework/upstream.json +9 -0
- package/lib/accepts-XBuZPVRI.js +52 -0
- package/lib/accepts.d.ts +33 -0
- package/lib/accepts.js +2 -0
- package/lib/acryl-base.d.ts +2 -0
- package/lib/acryl-base.js +332 -0
- package/lib/adapter.d.ts +12 -0
- package/lib/adapter.js +37 -0
- package/lib/app-BM0rTCp7.js +26 -0
- package/lib/app-CmAYW1Al.d.ts +21 -0
- package/lib/basic-auth.d.ts +72 -0
- package/lib/basic-auth.js +95 -0
- package/lib/bearer-auth.d.ts +89 -0
- package/lib/bearer-auth.js +94 -0
- package/lib/body-limit.d.ts +42 -0
- package/lib/body-limit.js +66 -0
- package/lib/client-BHTr318g.js +266 -0
- package/lib/client.d.ts +3 -0
- package/lib/client.js +2 -0
- package/lib/combine.d.ts +85 -0
- package/lib/combine.js +137 -0
- package/lib/compose-BuW2B6PZ.js +50 -0
- package/lib/compress.d.ts +38 -0
- package/lib/compress.js +79 -0
- package/lib/connection-C7xgP1hP.js +24 -0
- package/lib/conninfo.d.ts +25 -0
- package/lib/conninfo.js +2 -0
- package/lib/constants-Dy7ZvN1H.js +4 -0
- package/lib/context-Bm7rI-oK.d.ts +1234 -0
- package/lib/context-DDO0cfuP.js +365 -0
- package/lib/context-storage.d.ts +38 -0
- package/lib/context-storage.js +52 -0
- package/lib/cookie-ClMaKDQf.d.ts +40 -0
- package/lib/cookie.d.ts +24 -0
- package/lib/cookie.js +82 -0
- package/lib/cors.d.ts +52 -0
- package/lib/cors.js +106 -0
- package/lib/csrf.d.ts +75 -0
- package/lib/csrf.js +101 -0
- package/lib/etag.d.ts +40 -0
- package/lib/etag.js +135 -0
- package/lib/factory.d.ts +35 -0
- package/lib/factory.js +30 -0
- package/lib/headers-tu2YYN8T.d.ts +11 -0
- package/lib/html.d.ts +6 -0
- package/lib/html.js +31 -0
- package/lib/http-exception.d.ts +57 -0
- package/lib/http-exception.js +54 -0
- package/lib/http-status-DaAwGAFL.d.ts +35 -0
- package/lib/index-B-3F4wt2.d.ts +12 -0
- package/lib/index-UTBmM3GX.d.ts +68 -0
- package/lib/index-oOClm_Xk.d.ts +45 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +28 -0
- package/lib/ip-restriction.d.ts +68 -0
- package/lib/ip-restriction.js +166 -0
- package/lib/jwk.d.ts +52 -0
- package/lib/jwk.js +117 -0
- package/lib/jwt-BGJBw5AF.js +403 -0
- package/lib/jwt-Dg493Tai.d.ts +51 -0
- package/lib/jwt.d.ts +72 -0
- package/lib/jwt.js +115 -0
- package/lib/language.d.ts +88 -0
- package/lib/language.js +198 -0
- package/lib/logger.d.ts +22 -0
- package/lib/logger.js +54 -0
- package/lib/loopback-only.d.ts +45 -0
- package/lib/loopback-only.js +90 -0
- package/lib/method-not-allowed.d.ts +47 -0
- package/lib/method-not-allowed.js +82 -0
- package/lib/method-override.d.ts +46 -0
- package/lib/method-override.js +103 -0
- package/lib/mime-BQOYHl-l.d.ts +72 -0
- package/lib/node-server/conninfo.d.ts +11 -0
- package/lib/node-server/conninfo.js +19 -0
- package/lib/node-server/serve-static.d.ts +19 -0
- package/lib/node-server/serve-static.js +2 -0
- package/lib/node-server.d.ts +103 -0
- package/lib/node-server.js +1325 -0
- package/lib/powered-by.d.ts +28 -0
- package/lib/powered-by.js +24 -0
- package/lib/pretty-json.d.ts +40 -0
- package/lib/pretty-json.js +39 -0
- package/lib/reg-exp-router-DC1R3qoY.js +363 -0
- package/lib/request-id.d.ts +45 -0
- package/lib/request-id.js +34 -0
- package/lib/request.d.ts +2 -0
- package/lib/request.js +323 -0
- package/lib/route.d.ts +78 -0
- package/lib/route.js +126 -0
- package/lib/router/linear-router.d.ts +11 -0
- package/lib/router/linear-router.js +96 -0
- package/lib/router/pattern-router.d.ts +11 -0
- package/lib/router/pattern-router.js +41 -0
- package/lib/router/reg-exp-router.d.ts +35 -0
- package/lib/router/reg-exp-router.js +2 -0
- package/lib/router/smart-router.d.ts +15 -0
- package/lib/router/smart-router.js +2 -0
- package/lib/router/trie-router.d.ts +11 -0
- package/lib/router/trie-router.js +2 -0
- package/lib/router-CvUxUTOq.d.ts +99 -0
- package/lib/router.d.ts +2 -0
- package/lib/router.js +35 -0
- package/lib/schema-validator.d.ts +28 -0
- package/lib/schema-validator.js +22 -0
- package/lib/secure-headers.d.ts +125 -0
- package/lib/secure-headers.js +163 -0
- package/lib/serve-static-Dw_m6KxR.js +213 -0
- package/lib/serve-static.d.ts +31 -0
- package/lib/serve-static.js +77 -0
- package/lib/smart-router-C5CZ5XSM.js +49 -0
- package/lib/stream-CPdqZ0Fp.d.ts +34 -0
- package/lib/streaming-DHST3Scg.js +96 -0
- package/lib/streaming.d.ts +23 -0
- package/lib/streaming.js +2 -0
- package/lib/testing.d.ts +10 -0
- package/lib/testing.js +17 -0
- package/lib/timeout.d.ts +30 -0
- package/lib/timeout.js +42 -0
- package/lib/timing.d.ts +130 -0
- package/lib/timing.js +183 -0
- package/lib/trailing-slash.d.ts +91 -0
- package/lib/trailing-slash.js +85 -0
- package/lib/trie-router-CfFbapzL.js +146 -0
- package/lib/types-CDO6I3B0.d.ts +40 -0
- package/lib/types-CHesD1KG.d.ts +195 -0
- package/lib/types-CwrQjlaM.d.ts +105 -0
- package/lib/types-DR95J00T.d.ts +29 -0
- package/lib/types.d.ts +2 -0
- package/lib/types.js +4 -0
- package/lib/utils/accept.d.ts +9 -0
- package/lib/utils/accept.js +193 -0
- package/lib/utils/basic-auth.d.ts +8 -0
- package/lib/utils/basic-auth.js +20 -0
- package/lib/utils/body.d.ts +2 -0
- package/lib/utils/body.js +94 -0
- package/lib/utils/buffer.d.ts +19 -0
- package/lib/utils/buffer.js +51 -0
- package/lib/utils/color.d.ts +24 -0
- package/lib/utils/color.js +37 -0
- package/lib/utils/compress.d.ts +11 -0
- package/lib/utils/compress.js +11 -0
- package/lib/utils/concurrent.d.ts +17 -0
- package/lib/utils/concurrent.js +30 -0
- package/lib/utils/constants.d.ts +7 -0
- package/lib/utils/constants.js +7 -0
- package/lib/utils/cookie.d.ts +2 -0
- package/lib/utils/cookie.js +125 -0
- package/lib/utils/crypto.d.ts +14 -0
- package/lib/utils/crypto.js +34 -0
- package/lib/utils/encode.d.ts +11 -0
- package/lib/utils/encode.js +33 -0
- package/lib/utils/filepath.d.ts +14 -0
- package/lib/utils/filepath.js +25 -0
- package/lib/utils/handler.d.ts +9 -0
- package/lib/utils/handler.js +12 -0
- package/lib/utils/headers.d.ts +2 -0
- package/lib/utils/headers.js +1 -0
- package/lib/utils/html.d.ts +46 -0
- package/lib/utils/html.js +103 -0
- package/lib/utils/http-status.d.ts +2 -0
- package/lib/utils/http-status.js +1 -0
- package/lib/utils/ipaddr.d.ts +56 -0
- package/lib/utils/ipaddr.js +238 -0
- package/lib/utils/jwt.d.ts +24 -0
- package/lib/utils/jwt.js +2 -0
- package/lib/utils/mime.d.ts +2 -0
- package/lib/utils/mime.js +77 -0
- package/lib/utils/stream.d.ts +2 -0
- package/lib/utils/stream.js +88 -0
- package/lib/utils/types.d.ts +2 -0
- package/lib/utils/types.js +1 -0
- package/lib/utils/url.d.ts +46 -0
- package/lib/utils/url.js +197 -0
- package/lib/utils-dw8lxqjL.js +4 -0
- package/lib/validator-D84mq-dO.js +65 -0
- package/lib/validator.d.ts +42 -0
- package/lib/validator.js +2 -0
- package/lib/ws.d.ts +2 -0
- package/lib/ws.js +53 -0
- package/package.json +315 -15
- package/plugins/acryl-inspect/src/report.ts +15 -10
- package/plugins/acryl-inspect/src/service.ts +2 -2
- package/plugins/acryl-inspect/tests/report.spec.ts +9 -3
- package/plugins/acryl-inspect/tests/service.spec.ts +3 -3
- package/plugins/acryl-inspect/upstream.json +2 -2
- package/plugins/acryl-node-server/tests/adapter/app.ts +2 -2
- package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +1 -1
- package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +1 -1
- package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +2 -2
- package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +4 -4
- package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +5 -5
- package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +2 -2
- package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +20 -20
- package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +2 -2
- package/plugins/acryl-node-server/tests/adapter/server.test.ts +50 -50
- package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +4 -4
- package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +9 -9
- package/plugins/acryl-node-server/tests/server.spec.ts +6 -6
- package/plugins/acryl-node-server/upstream.json +2 -2
- package/plugins/acryl-router/src/client.ts +1 -1
- package/plugins/acryl-router/src/connection.ts +2 -2
- package/plugins/acryl-router/src/core/app-base.ts +29 -29
- package/plugins/acryl-router/src/core/app.test.ts +175 -175
- package/plugins/acryl-router/src/core/app.ts +8 -8
- package/plugins/acryl-router/src/core/client/client.test.ts +76 -76
- package/plugins/acryl-router/src/core/client/client.ts +2 -2
- package/plugins/acryl-router/src/core/client/fetch-result-please.ts +1 -1
- package/plugins/acryl-router/src/core/client/index.ts +1 -1
- package/plugins/acryl-router/src/core/client/types.test.ts +6 -6
- package/plugins/acryl-router/src/core/client/types.ts +16 -16
- package/plugins/acryl-router/src/core/client/utils.test.ts +2 -2
- package/plugins/acryl-router/src/core/context.test.ts +4 -4
- package/plugins/acryl-router/src/core/context.ts +6 -6
- package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +3 -3
- package/plugins/acryl-router/src/core/helper/accepts/index.ts +1 -1
- package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +6 -6
- package/plugins/acryl-router/src/core/helper/adapter/index.ts +1 -1
- package/plugins/acryl-router/src/core/helper/conninfo/index.ts +1 -1
- package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +8 -8
- package/plugins/acryl-router/src/core/helper/cookie/index.ts +1 -1
- package/plugins/acryl-router/src/core/helper/factory/index.test.ts +9 -9
- package/plugins/acryl-router/src/core/helper/factory/index.ts +10 -10
- package/plugins/acryl-router/src/core/helper/html/index.test.ts +4 -4
- package/plugins/acryl-router/src/core/helper/html/index.ts +1 -1
- package/plugins/acryl-router/src/core/helper/route/index.test.ts +7 -7
- package/plugins/acryl-router/src/core/helper/route/index.ts +8 -8
- package/plugins/acryl-router/src/core/helper/streaming/index.ts +1 -1
- package/plugins/acryl-router/src/core/helper/testing/index.test.ts +6 -6
- package/plugins/acryl-router/src/core/helper/testing/index.ts +4 -4
- package/plugins/acryl-router/src/core/helper/websocket/index.ts +2 -1
- package/plugins/acryl-router/src/core/http-exception.ts +1 -1
- package/plugins/acryl-router/src/core/index.ts +9 -9
- package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +6 -6
- package/plugins/acryl-router/src/core/middleware/basic-auth/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +5 -5
- package/plugins/acryl-router/src/core/middleware/bearer-auth/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +6 -6
- package/plugins/acryl-router/src/core/middleware/body-limit/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +9 -9
- package/plugins/acryl-router/src/core/middleware/combine/index.ts +7 -7
- package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +9 -9
- package/plugins/acryl-router/src/core/middleware/compress/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +5 -5
- package/plugins/acryl-router/src/core/middleware/context-storage/index.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +7 -7
- package/plugins/acryl-router/src/core/middleware/cors/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +10 -10
- package/plugins/acryl-router/src/core/middleware/csrf/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +42 -42
- package/plugins/acryl-router/src/core/middleware/etag/index.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/ip-restriction/index.ts +6 -6
- package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +16 -16
- package/plugins/acryl-router/src/core/middleware/jwk/jwk.ts +7 -6
- package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +16 -16
- package/plugins/acryl-router/src/core/middleware/jwt/jwt.ts +4 -3
- package/plugins/acryl-router/src/core/middleware/language/index.test.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/language/language.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +5 -5
- package/plugins/acryl-router/src/core/middleware/logger/index.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +24 -24
- package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.ts +8 -8
- package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +5 -5
- package/plugins/acryl-router/src/core/middleware/method-override/index.ts +6 -6
- package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/powered-by/index.ts +6 -6
- package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +30 -30
- package/plugins/acryl-router/src/core/middleware/pretty-json/index.ts +4 -4
- package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +15 -15
- package/plugins/acryl-router/src/core/middleware/request-id/request-id.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +35 -35
- package/plugins/acryl-router/src/core/middleware/secure-headers/secure-headers.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +23 -23
- package/plugins/acryl-router/src/core/middleware/serve-static/index.ts +1 -1
- package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +2 -2
- package/plugins/acryl-router/src/core/middleware/timeout/index.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +14 -14
- package/plugins/acryl-router/src/core/middleware/timing/timing.ts +3 -3
- package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +7 -7
- package/plugins/acryl-router/src/core/middleware/trailing-slash/index.ts +7 -7
- package/plugins/acryl-router/src/core/request.test.ts +42 -42
- package/plugins/acryl-router/src/core/request.ts +6 -6
- package/plugins/acryl-router/src/core/router/linear-router/index.ts +1 -1
- package/plugins/acryl-router/src/core/router/pattern-router/index.ts +1 -1
- package/plugins/acryl-router/src/core/router/reg-exp-router/index.ts +1 -1
- package/plugins/acryl-router/src/core/router/smart-router/index.ts +1 -1
- package/plugins/acryl-router/src/core/router/trie-router/index.ts +1 -1
- package/plugins/acryl-router/src/core/types.test.ts +115 -115
- package/plugins/acryl-router/src/core/types.ts +72 -72
- package/plugins/acryl-router/src/core/utils/body.ts +8 -8
- package/plugins/acryl-router/src/core/utils/html.ts +1 -1
- package/plugins/acryl-router/src/core/utils/jwt/jws.ts +3 -3
- package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +2 -2
- package/plugins/acryl-router/src/core/utils/jwt/jwt.ts +3 -3
- package/plugins/acryl-router/src/core/utils/jwt/types.ts +1 -1
- package/plugins/acryl-router/src/core/utils/types.ts +42 -0
- package/plugins/acryl-router/src/core/utils/url.test.ts +2 -2
- package/plugins/acryl-router/src/core/validator/index.ts +1 -1
- package/plugins/acryl-router/src/core/validator/validator.test.ts +28 -28
- package/plugins/acryl-router/src/deprecated.ts +15 -0
- package/plugins/acryl-router/src/index.ts +3 -2
- package/plugins/acryl-router/src/middleware/index.ts +1 -1
- package/plugins/acryl-router/src/middleware/loopback-only.ts +34 -1
- package/plugins/acryl-router/src/service.ts +19 -13
- package/plugins/acryl-router/tests/docs-examples.spec.ts +11 -11
- package/plugins/acryl-router/tests/live-install.spec.ts +2 -2
- package/plugins/acryl-router/tests/loader.spec.ts +3 -3
- package/plugins/acryl-router/tests/loopback-only.spec.ts +80 -0
- package/plugins/acryl-router/tests/no-dom/consumer.ts +11 -0
- package/plugins/acryl-router/tests/no-dom/tsconfig.json +13 -0
- package/plugins/acryl-router/tests/service.spec.ts +39 -22
- package/plugins/acryl-router/upstream.json +3 -3
- package/plugins/acryl-router-http/tests/adapter.spec.ts +3 -3
- package/plugins/acryl-router-http/tests/surfaces.spec.ts +2 -2
- package/plugins/acryl-router-http/upstream.json +2 -2
- package/plugins/acryl-state/src/service.ts +2 -2
- package/plugins/acryl-state/upstream.json +2 -2
- package/plugins/builder/script.ts +3 -3
- package/plugins/extensions/index.ts +4 -3
- package/plugins/extensions/resolve.ts +70 -10
- package/plugins/openai/prompt.ts +7 -7
- package/shared/AGENTS.core.md +61 -0
- package/templates/agent/AGENTS.md +6 -0
- package/templates/agent/README.md +2 -2
- package/templates/agent/blend.yaml +1 -1
- package/templates/agent/src/routes.ts +2 -2
- package/templates/agent/test/model.test.ts +2 -2
- package/templates/agent/tsconfig.json +40 -0
- package/templates/blank/AGENTS.md +5 -0
- package/templates/blank/README.md +1 -1
- package/templates/blank/src/routes.ts +2 -2
- package/templates/todo/AGENTS.md +5 -0
- package/templates/todo/src/todo.ts +6 -4
- package/templates/todo/upstream.json +2 -2
package/lib/request.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { HTTPException } from "./http-exception.js";
|
|
2
|
+
import { t as GET_MATCH_RESULT } from "./constants-Dy7ZvN1H.js";
|
|
3
|
+
import { parseBody } from "./utils/body.js";
|
|
4
|
+
import { getQueryParam, getQueryParams, tryDecodeURIComponent } from "./utils/url.js";
|
|
5
|
+
//#region ../../plugins/acryl-router/src/core/request.ts
|
|
6
|
+
var AcrylRequest = class {
|
|
7
|
+
/**
|
|
8
|
+
* `.raw` can get the raw Request object.
|
|
9
|
+
*
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // For Cloudflare Workers
|
|
14
|
+
* app.post('/', async (c) => {
|
|
15
|
+
* const metadata = c.req.raw.cf?.hostMetadata?
|
|
16
|
+
* ...
|
|
17
|
+
* })
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
raw;
|
|
21
|
+
#validatedData;
|
|
22
|
+
#matchResult;
|
|
23
|
+
routeIndex = 0;
|
|
24
|
+
/**
|
|
25
|
+
* `.path` can get the pathname of the request.
|
|
26
|
+
*
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* app.get('/about/me', (c) => {
|
|
31
|
+
* const pathname = c.req.path // `/about/me`
|
|
32
|
+
* })
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
path;
|
|
36
|
+
bodyCache = {};
|
|
37
|
+
constructor(request, path = "/", matchResult = [[]]) {
|
|
38
|
+
this.raw = request;
|
|
39
|
+
this.path = path;
|
|
40
|
+
this.#matchResult = matchResult;
|
|
41
|
+
}
|
|
42
|
+
param(key) {
|
|
43
|
+
return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();
|
|
44
|
+
}
|
|
45
|
+
#getDecodedParam(key) {
|
|
46
|
+
const paramKey = this.#matchResult[0][this.routeIndex]?.[1][key];
|
|
47
|
+
const param = this.#getParamValue(paramKey);
|
|
48
|
+
return param && tryDecodeURIComponent(param);
|
|
49
|
+
}
|
|
50
|
+
#getAllDecodedParams() {
|
|
51
|
+
const decoded = {};
|
|
52
|
+
const keys = Object.keys(this.#matchResult[0][this.routeIndex]?.[1] ?? {});
|
|
53
|
+
for (const key of keys) {
|
|
54
|
+
const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);
|
|
55
|
+
if (value !== void 0) decoded[key] = tryDecodeURIComponent(value);
|
|
56
|
+
}
|
|
57
|
+
return decoded;
|
|
58
|
+
}
|
|
59
|
+
#getParamValue(paramKey) {
|
|
60
|
+
return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;
|
|
61
|
+
}
|
|
62
|
+
query(key) {
|
|
63
|
+
return getQueryParam(this.url, key);
|
|
64
|
+
}
|
|
65
|
+
queries(key) {
|
|
66
|
+
return getQueryParams(this.url, key);
|
|
67
|
+
}
|
|
68
|
+
header(name) {
|
|
69
|
+
if (name) return this.raw.headers.get(name) ?? void 0;
|
|
70
|
+
const headerData = Object.create(null);
|
|
71
|
+
this.raw.headers.forEach((value, key) => {
|
|
72
|
+
headerData[key] = value;
|
|
73
|
+
});
|
|
74
|
+
return headerData;
|
|
75
|
+
}
|
|
76
|
+
async parseBody(options) {
|
|
77
|
+
return parseBody(this, options);
|
|
78
|
+
}
|
|
79
|
+
#cachedBody = (key) => {
|
|
80
|
+
const { bodyCache, raw } = this;
|
|
81
|
+
const cachedBody = bodyCache[key];
|
|
82
|
+
if (cachedBody) return cachedBody;
|
|
83
|
+
for (const anyCachedKey in bodyCache) return bodyCache[anyCachedKey].then((body) => {
|
|
84
|
+
if (anyCachedKey === "json") body = JSON.stringify(body);
|
|
85
|
+
const contentType = anyCachedKey === "formData" ? void 0 : raw.headers.get("content-type");
|
|
86
|
+
return new Response(body, { headers: contentType ? { "Content-Type": contentType } : void 0 })[key]();
|
|
87
|
+
});
|
|
88
|
+
return bodyCache[key] = raw[key]();
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* `.json()` can parse Request body of type `application/json`
|
|
92
|
+
*
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* app.post('/entry', async (c) => {
|
|
97
|
+
* const body = await c.req.json()
|
|
98
|
+
* })
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
json() {
|
|
102
|
+
return this.#cachedBody("text").then((text) => JSON.parse(text));
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* `.text()` can parse Request body of type `text/plain`
|
|
106
|
+
*
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```ts
|
|
110
|
+
* app.post('/entry', async (c) => {
|
|
111
|
+
* const body = await c.req.text()
|
|
112
|
+
* })
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
text() {
|
|
116
|
+
return this.#cachedBody("text");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* `.arrayBuffer()` parse Request body as an `ArrayBuffer`
|
|
120
|
+
*
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```ts
|
|
124
|
+
* app.post('/entry', async (c) => {
|
|
125
|
+
* const body = await c.req.arrayBuffer()
|
|
126
|
+
* })
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
arrayBuffer() {
|
|
130
|
+
return this.#cachedBody("arrayBuffer");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* `.bytes()` parses the request body as a `Uint8Array`.
|
|
134
|
+
*
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```ts
|
|
138
|
+
* app.post('/entry', async (c) => {
|
|
139
|
+
* const body = await c.req.bytes()
|
|
140
|
+
* })
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
bytes() {
|
|
144
|
+
return this.#cachedBody("arrayBuffer").then((buffer) => new Uint8Array(buffer));
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Parses the request body as a `Blob`.
|
|
148
|
+
* @example
|
|
149
|
+
* ```ts
|
|
150
|
+
* app.post('/entry', async (c) => {
|
|
151
|
+
* const body = await c.req.blob();
|
|
152
|
+
* });
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
blob() {
|
|
156
|
+
return this.#cachedBody("blob");
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Parses the request body as `FormData`.
|
|
160
|
+
* @example
|
|
161
|
+
* ```ts
|
|
162
|
+
* app.post('/entry', async (c) => {
|
|
163
|
+
* const body = await c.req.formData();
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
formData() {
|
|
168
|
+
return this.#cachedBody("formData");
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Adds validated data to the request.
|
|
172
|
+
*
|
|
173
|
+
* @param target - The target of the validation.
|
|
174
|
+
* @param data - The validated data to add.
|
|
175
|
+
*/
|
|
176
|
+
addValidatedData(target, data) {
|
|
177
|
+
(this.#validatedData ??= {})[target] = data;
|
|
178
|
+
}
|
|
179
|
+
valid(target) {
|
|
180
|
+
return this.#validatedData?.[target];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* `.url` can get the request url strings.
|
|
184
|
+
*
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```ts
|
|
188
|
+
* app.get('/about/me', (c) => {
|
|
189
|
+
* const url = c.req.url // `http://localhost:8787/about/me`
|
|
190
|
+
* ...
|
|
191
|
+
* })
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
get url() {
|
|
195
|
+
return this.raw.url;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* `.method` can get the method name of the request.
|
|
199
|
+
*
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ```ts
|
|
203
|
+
* app.get('/about/me', (c) => {
|
|
204
|
+
* const method = c.req.method // `GET`
|
|
205
|
+
* })
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
get method() {
|
|
209
|
+
return this.raw.method;
|
|
210
|
+
}
|
|
211
|
+
get [GET_MATCH_RESULT]() {
|
|
212
|
+
return this.#matchResult;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* `.matchedRoutes` can return a matched route in the handler
|
|
216
|
+
*
|
|
217
|
+
* @deprecated
|
|
218
|
+
*
|
|
219
|
+
* Use matchedRoutes helper defined in "acryl-router/route" instead.
|
|
220
|
+
*
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```ts
|
|
224
|
+
* app.use('*', async function logger(c, next) {
|
|
225
|
+
* await next()
|
|
226
|
+
* c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
|
|
227
|
+
* const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
|
|
228
|
+
* console.log(
|
|
229
|
+
* method,
|
|
230
|
+
* ' ',
|
|
231
|
+
* path,
|
|
232
|
+
* ' '.repeat(Math.max(10 - path.length, 0)),
|
|
233
|
+
* name,
|
|
234
|
+
* i === c.req.routeIndex ? '<- respond from here' : ''
|
|
235
|
+
* )
|
|
236
|
+
* })
|
|
237
|
+
* })
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
get matchedRoutes() {
|
|
241
|
+
return this.#matchResult[0].map(([[, route]]) => route);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* `.routePath` can retrieve the path registered within the handler
|
|
245
|
+
*
|
|
246
|
+
* @deprecated
|
|
247
|
+
*
|
|
248
|
+
* Use routePath helper defined in "acryl-router/route" instead.
|
|
249
|
+
*
|
|
250
|
+
*
|
|
251
|
+
* @example
|
|
252
|
+
* ```ts
|
|
253
|
+
* app.get('/posts/:id', (c) => {
|
|
254
|
+
* return c.json({ path: c.req.routePath })
|
|
255
|
+
* })
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
get routePath() {
|
|
259
|
+
return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* Clones a AcrylRequest's underlying raw Request object.
|
|
264
|
+
*
|
|
265
|
+
* This utility handles both consumed and unconsumed request bodies:
|
|
266
|
+
* - If the request body hasn't been consumed, it uses the native `clone()` method
|
|
267
|
+
* - If the request body has been consumed, it reconstructs a new Request using cached body data
|
|
268
|
+
*
|
|
269
|
+
* This is particularly useful when you need to:
|
|
270
|
+
* - Process the same request body multiple times
|
|
271
|
+
* - Pass requests to external services after validation
|
|
272
|
+
*
|
|
273
|
+
* @param req - The AcrylRequest object to clone
|
|
274
|
+
* @returns A Promise that resolves to a new Request object with the same properties
|
|
275
|
+
* @throws {HTTPException} If the request body was consumed directly via `req.raw`
|
|
276
|
+
* without using AcrylRequest methods (e.g., `req.json()`, `req.text()`), making it
|
|
277
|
+
* impossible to reconstruct the body from cache
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* ```ts
|
|
281
|
+
* // Clone after consuming the body (e.g., after validation)
|
|
282
|
+
* app.post('/forward',
|
|
283
|
+
* validator('json', (data) => data),
|
|
284
|
+
* async (c) => {
|
|
285
|
+
* const validated = c.req.valid('json')
|
|
286
|
+
* // Body has been consumed, but cloneRawRequest still works
|
|
287
|
+
* const clonedReq = await cloneRawRequest(c.req)
|
|
288
|
+
* return fetch('http://backend-service.com', clonedReq)
|
|
289
|
+
* }
|
|
290
|
+
* )
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
const cloneRawRequest = async (req) => {
|
|
294
|
+
if (!req.raw.bodyUsed) return req.raw.clone();
|
|
295
|
+
const cacheKey = Object.keys(req.bodyCache)[0];
|
|
296
|
+
if (!cacheKey) throw new HTTPException(500, { message: "Cannot clone request: body was already consumed and not cached. Please use AcrylRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly." });
|
|
297
|
+
let body = await req[cacheKey]();
|
|
298
|
+
const headers = req.header();
|
|
299
|
+
if (cacheKey === "json") {
|
|
300
|
+
body = JSON.stringify(body);
|
|
301
|
+
delete headers["content-length"];
|
|
302
|
+
} else if (body instanceof FormData) {
|
|
303
|
+
delete headers["content-type"];
|
|
304
|
+
delete headers["content-length"];
|
|
305
|
+
}
|
|
306
|
+
const requestInit = {
|
|
307
|
+
body,
|
|
308
|
+
cache: req.raw.cache,
|
|
309
|
+
credentials: req.raw.credentials,
|
|
310
|
+
headers,
|
|
311
|
+
integrity: req.raw.integrity,
|
|
312
|
+
keepalive: req.raw.keepalive,
|
|
313
|
+
method: req.method,
|
|
314
|
+
mode: req.raw.mode,
|
|
315
|
+
redirect: req.raw.redirect,
|
|
316
|
+
referrer: req.raw.referrer,
|
|
317
|
+
referrerPolicy: req.raw.referrerPolicy,
|
|
318
|
+
signal: req.raw.signal
|
|
319
|
+
};
|
|
320
|
+
return new Request(req.url, requestInit);
|
|
321
|
+
};
|
|
322
|
+
//#endregion
|
|
323
|
+
export { AcrylRequest, cloneRawRequest };
|
package/lib/route.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { q as RouterRoute, t as Context } from "./context-Bm7rI-oK.js";
|
|
2
|
+
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/helper/route/index.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Get matched routes in the handler
|
|
6
|
+
*
|
|
7
|
+
* @param {Context} c - The context object
|
|
8
|
+
* @returns An array of matched routes
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { matchedRoutes } from 'acrylblends/route'
|
|
13
|
+
*
|
|
14
|
+
* app.use('*', async function logger(c, next) {
|
|
15
|
+
* await next()
|
|
16
|
+
* matchedRoutes(c).forEach(({ handler, method, path }, i) => {
|
|
17
|
+
* const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
|
|
18
|
+
* console.log(
|
|
19
|
+
* method,
|
|
20
|
+
* ' ',
|
|
21
|
+
* path,
|
|
22
|
+
* ' '.repeat(Math.max(10 - path.length, 0)),
|
|
23
|
+
* name,
|
|
24
|
+
* i === c.req.routeIndex ? '<- respond from here' : ''
|
|
25
|
+
* )
|
|
26
|
+
* })
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
declare const matchedRoutes: (c: Context) => RouterRoute[];
|
|
31
|
+
/**
|
|
32
|
+
* Get the route path registered within the handler
|
|
33
|
+
*
|
|
34
|
+
* @param {Context} c - The context object
|
|
35
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
36
|
+
* @returns The route path registered within the handler
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { routePath } from 'acrylblends/route'
|
|
41
|
+
*
|
|
42
|
+
* app.use('*', (c, next) => {
|
|
43
|
+
* console.log(routePath(c)) // '*'
|
|
44
|
+
* console.log(routePath(c, -1)) // '/posts/:id'
|
|
45
|
+
* return next()
|
|
46
|
+
* })
|
|
47
|
+
*
|
|
48
|
+
* app.get('/posts/:id', (c) => {
|
|
49
|
+
* return c.text(routePath(c)) // '/posts/:id'
|
|
50
|
+
* })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare const routePath: (c: Context, index?: number) => string;
|
|
54
|
+
/**
|
|
55
|
+
* Get the basePath of the as-is route specified by routing.
|
|
56
|
+
*
|
|
57
|
+
* @param {Context} c - The context object
|
|
58
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
59
|
+
* @returns The basePath of the as-is route specified by routing.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { baseRoutePath } from 'acrylblends/route'
|
|
64
|
+
*
|
|
65
|
+
* const app = new Acryl()
|
|
66
|
+
*
|
|
67
|
+
* const subApp = new Acryl()
|
|
68
|
+
* subApp.get('/posts/:id', (c) => {
|
|
69
|
+
* return c.text(baseRoutePath(c)) // '/:sub'
|
|
70
|
+
* })
|
|
71
|
+
*
|
|
72
|
+
* app.route('/:sub', subApp)
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare const baseRoutePath: (c: Context, index?: number) => string;
|
|
76
|
+
declare const basePath: (c: Context, index?: number) => string;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { basePath, baseRoutePath, matchedRoutes, routePath };
|
package/lib/route.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { t as GET_MATCH_RESULT } from "./constants-Dy7ZvN1H.js";
|
|
2
|
+
import { getPattern, splitRoutingPath } from "./utils/url.js";
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/helper/route/index.ts
|
|
4
|
+
/**
|
|
5
|
+
* Get matched routes in the handler
|
|
6
|
+
*
|
|
7
|
+
* @param {Context} c - The context object
|
|
8
|
+
* @returns An array of matched routes
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { matchedRoutes } from 'acrylblends/route'
|
|
13
|
+
*
|
|
14
|
+
* app.use('*', async function logger(c, next) {
|
|
15
|
+
* await next()
|
|
16
|
+
* matchedRoutes(c).forEach(({ handler, method, path }, i) => {
|
|
17
|
+
* const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
|
|
18
|
+
* console.log(
|
|
19
|
+
* method,
|
|
20
|
+
* ' ',
|
|
21
|
+
* path,
|
|
22
|
+
* ' '.repeat(Math.max(10 - path.length, 0)),
|
|
23
|
+
* name,
|
|
24
|
+
* i === c.req.routeIndex ? '<- respond from here' : ''
|
|
25
|
+
* )
|
|
26
|
+
* })
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
const matchedRoutes = (c) => c.req[GET_MATCH_RESULT][0].map(([[, route]]) => route);
|
|
31
|
+
/**
|
|
32
|
+
* Get the route path registered within the handler
|
|
33
|
+
*
|
|
34
|
+
* @param {Context} c - The context object
|
|
35
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
36
|
+
* @returns The route path registered within the handler
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* import { routePath } from 'acrylblends/route'
|
|
41
|
+
*
|
|
42
|
+
* app.use('*', (c, next) => {
|
|
43
|
+
* console.log(routePath(c)) // '*'
|
|
44
|
+
* console.log(routePath(c, -1)) // '/posts/:id'
|
|
45
|
+
* return next()
|
|
46
|
+
* })
|
|
47
|
+
*
|
|
48
|
+
* app.get('/posts/:id', (c) => {
|
|
49
|
+
* return c.text(routePath(c)) // '/posts/:id'
|
|
50
|
+
* })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
const routePath = (c, index) => matchedRoutes(c).at(index ?? c.req.routeIndex)?.path ?? "";
|
|
54
|
+
/**
|
|
55
|
+
* Get the basePath of the as-is route specified by routing.
|
|
56
|
+
*
|
|
57
|
+
* @param {Context} c - The context object
|
|
58
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
59
|
+
* @returns The basePath of the as-is route specified by routing.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { baseRoutePath } from 'acrylblends/route'
|
|
64
|
+
*
|
|
65
|
+
* const app = new Acryl()
|
|
66
|
+
*
|
|
67
|
+
* const subApp = new Acryl()
|
|
68
|
+
* subApp.get('/posts/:id', (c) => {
|
|
69
|
+
* return c.text(baseRoutePath(c)) // '/:sub'
|
|
70
|
+
* })
|
|
71
|
+
*
|
|
72
|
+
* app.route('/:sub', subApp)
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
const baseRoutePath = (c, index) => matchedRoutes(c).at(index ?? c.req.routeIndex)?.basePath ?? "";
|
|
76
|
+
/**
|
|
77
|
+
* Get the basePath with embedded parameters
|
|
78
|
+
*
|
|
79
|
+
* @param {Context} c - The context object
|
|
80
|
+
* @param {number} index - The index of the route from which to retrieve the path, similar to Array.prototype.at(), where a negative number is the index counted from the end of the matching route. Defaults to the current route index.
|
|
81
|
+
* @returns The basePath with embedded parameters.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```ts
|
|
85
|
+
* import { basePath } from 'acrylblends/route'
|
|
86
|
+
*
|
|
87
|
+
* const app = new Acryl()
|
|
88
|
+
*
|
|
89
|
+
* const subApp = new Acryl()
|
|
90
|
+
* subApp.get('/posts/:id', (c) => {
|
|
91
|
+
* return c.text(basePath(c)) // '/requested-sub-app-path'
|
|
92
|
+
* })
|
|
93
|
+
*
|
|
94
|
+
* app.route('/:sub', subApp)
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
const basePathCacheMap = /* @__PURE__ */ new WeakMap();
|
|
98
|
+
const basePath = (c, index) => {
|
|
99
|
+
index ??= c.req.routeIndex;
|
|
100
|
+
const cache = basePathCacheMap.get(c) || [];
|
|
101
|
+
if (typeof cache[index] === "string") return cache[index];
|
|
102
|
+
let result;
|
|
103
|
+
const rp = baseRoutePath(c, index);
|
|
104
|
+
if (!/[:*]/.test(rp)) result = rp;
|
|
105
|
+
else {
|
|
106
|
+
const paths = splitRoutingPath(rp);
|
|
107
|
+
const reqPath = c.req.path;
|
|
108
|
+
let basePathLength = 0;
|
|
109
|
+
for (let i = 0, len = paths.length; i < len; i++) {
|
|
110
|
+
const pattern = getPattern(paths[i], paths[i + 1]);
|
|
111
|
+
if (pattern) {
|
|
112
|
+
const re = pattern[2] === true || pattern === "*" ? /[^\/]+/ : pattern[2];
|
|
113
|
+
const restPath = reqPath.substring(basePathLength + 1);
|
|
114
|
+
const segment = restPath.split("/", 1)[0];
|
|
115
|
+
basePathLength += (restPath.match(re)?.[0] ?? (re.test(segment) ? segment : "")).length;
|
|
116
|
+
} else basePathLength += paths[i].length;
|
|
117
|
+
basePathLength += 1;
|
|
118
|
+
}
|
|
119
|
+
result = reqPath.substring(0, basePathLength);
|
|
120
|
+
}
|
|
121
|
+
cache[index] = result;
|
|
122
|
+
basePathCacheMap.set(c, cache);
|
|
123
|
+
return result;
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
126
|
+
export { basePath, baseRoutePath, matchedRoutes, routePath };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { c as Result, l as Router } from "../router-CvUxUTOq.js";
|
|
2
|
+
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/router/linear-router/router.d.ts
|
|
4
|
+
declare class LinearRouter<T> implements Router<T> {
|
|
5
|
+
#private;
|
|
6
|
+
name: string;
|
|
7
|
+
add(method: string, path: string, handler: T): void;
|
|
8
|
+
match(method: string, path: string): Result<T>;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { LinearRouter };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { checkOptionalParameter } from "../utils/url.js";
|
|
2
|
+
import { UnsupportedPathError } from "../router.js";
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/router/linear-router/router.ts
|
|
4
|
+
const emptyParams = Object.create(null);
|
|
5
|
+
const splitPathRe = /\/(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/[^\/\?]+|(\?)/g;
|
|
6
|
+
const splitByStarRe = /\*/;
|
|
7
|
+
var LinearRouter = class {
|
|
8
|
+
name = "LinearRouter";
|
|
9
|
+
#routes = [];
|
|
10
|
+
add(method, path, handler) {
|
|
11
|
+
for (let i = 0, paths = checkOptionalParameter(path) || [path], len = paths.length; i < len; i++) this.#routes.push([
|
|
12
|
+
method,
|
|
13
|
+
paths[i],
|
|
14
|
+
handler
|
|
15
|
+
]);
|
|
16
|
+
}
|
|
17
|
+
match(method, path) {
|
|
18
|
+
const handlers = [];
|
|
19
|
+
ROUTES_LOOP: for (let i = 0, len = this.#routes.length; i < len; i++) {
|
|
20
|
+
const [routeMethod, routePath, handler] = this.#routes[i];
|
|
21
|
+
if (routeMethod === method || routeMethod === "ALL") {
|
|
22
|
+
if (routePath === "*" || routePath === "/*") {
|
|
23
|
+
handlers.push([handler, emptyParams]);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const hasStar = routePath.indexOf("*") !== -1;
|
|
27
|
+
const hasLabel = routePath.indexOf(":") !== -1;
|
|
28
|
+
if (!hasStar && !hasLabel) {
|
|
29
|
+
if (routePath === path || routePath + "/" === path) handlers.push([handler, emptyParams]);
|
|
30
|
+
} else if (hasStar && !hasLabel) {
|
|
31
|
+
const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42;
|
|
32
|
+
const endsWithSlashStar = routePath.endsWith("/*");
|
|
33
|
+
const parts = (endsWithStar ? routePath.slice(0, endsWithSlashStar ? -2 : -1) : routePath).split(splitByStarRe);
|
|
34
|
+
const lastIndex = parts.length - 1;
|
|
35
|
+
for (let j = 0, pos = 0, len = parts.length; j < len; j++) {
|
|
36
|
+
const part = parts[j];
|
|
37
|
+
if (path.indexOf(part, pos) !== pos) continue ROUTES_LOOP;
|
|
38
|
+
pos += part.length;
|
|
39
|
+
if (j === lastIndex) {
|
|
40
|
+
if (endsWithSlashStar) {
|
|
41
|
+
if (pos !== path.length && path.charCodeAt(pos) !== 47) continue ROUTES_LOOP;
|
|
42
|
+
} else if (!endsWithStar && pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) continue ROUTES_LOOP;
|
|
43
|
+
} else {
|
|
44
|
+
const index = path.indexOf("/", pos);
|
|
45
|
+
if (index === -1) continue ROUTES_LOOP;
|
|
46
|
+
pos = index;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
handlers.push([handler, emptyParams]);
|
|
50
|
+
} else if (hasLabel && !hasStar) {
|
|
51
|
+
const params = Object.create(null);
|
|
52
|
+
const parts = routePath.match(splitPathRe);
|
|
53
|
+
const lastIndex = parts.length - 1;
|
|
54
|
+
for (let j = 0, pos = 0, len = parts.length; j < len; j++) {
|
|
55
|
+
if (pos === -1 || pos >= path.length) continue ROUTES_LOOP;
|
|
56
|
+
const part = parts[j];
|
|
57
|
+
if (part.charCodeAt(1) === 58) {
|
|
58
|
+
if (path.charCodeAt(pos) !== 47) continue ROUTES_LOOP;
|
|
59
|
+
let name = part.slice(2);
|
|
60
|
+
let value;
|
|
61
|
+
if (name.charCodeAt(name.length - 1) === 125) {
|
|
62
|
+
const openBracePos = name.indexOf("{");
|
|
63
|
+
const next = parts[j + 1];
|
|
64
|
+
const lookahead = next && next[1] !== ":" && next[1] !== "*" ? `(?=${next})` : "";
|
|
65
|
+
const pattern = name.slice(openBracePos + 1, -1) + lookahead;
|
|
66
|
+
const restPath = path.slice(pos + 1);
|
|
67
|
+
const match = new RegExp(pattern, "d").exec(restPath);
|
|
68
|
+
if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) continue ROUTES_LOOP;
|
|
69
|
+
name = name.slice(0, openBracePos);
|
|
70
|
+
value = restPath.slice(...match.indices[0]);
|
|
71
|
+
pos += match.indices[0][1] + 1;
|
|
72
|
+
} else {
|
|
73
|
+
let endValuePos = path.indexOf("/", pos + 1);
|
|
74
|
+
if (endValuePos === -1) endValuePos = path.length;
|
|
75
|
+
if (endValuePos === pos + 1) continue ROUTES_LOOP;
|
|
76
|
+
value = path.slice(pos + 1, endValuePos);
|
|
77
|
+
pos = endValuePos;
|
|
78
|
+
}
|
|
79
|
+
params[name] ||= value;
|
|
80
|
+
} else {
|
|
81
|
+
if (path.indexOf(part, pos) !== pos) continue ROUTES_LOOP;
|
|
82
|
+
pos += part.length;
|
|
83
|
+
}
|
|
84
|
+
if (j === lastIndex) {
|
|
85
|
+
if (pos !== path.length && !(pos === path.length - 1 && path.charCodeAt(pos) === 47)) continue ROUTES_LOOP;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
handlers.push([handler, params]);
|
|
89
|
+
} else if (hasLabel && hasStar) throw new UnsupportedPathError();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return [handlers];
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
//#endregion
|
|
96
|
+
export { LinearRouter };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { c as Result, l as Router } from "../router-CvUxUTOq.js";
|
|
2
|
+
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/router/pattern-router/router.d.ts
|
|
4
|
+
declare class PatternRouter<T> implements Router<T> {
|
|
5
|
+
#private;
|
|
6
|
+
name: string;
|
|
7
|
+
add(method: string, path: string, handler: T): void;
|
|
8
|
+
match(method: string, path: string): Result<T>;
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { PatternRouter };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { UnsupportedPathError } from "../router.js";
|
|
2
|
+
//#region ../../plugins/acryl-router/src/core/router/pattern-router/router.ts
|
|
3
|
+
const emptyParams = Object.create(null);
|
|
4
|
+
var PatternRouter = class {
|
|
5
|
+
name = "PatternRouter";
|
|
6
|
+
#routes = [];
|
|
7
|
+
add(method, path, handler) {
|
|
8
|
+
const suffix = path.endsWith("/*") ? "(?:$|/)" : path.endsWith("*") ? "" : "/?$";
|
|
9
|
+
path = path.replace(/\*$/, "");
|
|
10
|
+
if (path.at(-1) === "?") {
|
|
11
|
+
path = path.slice(0, -1);
|
|
12
|
+
this.add(method, path.replace(/\/[^/]+$/, ""), handler);
|
|
13
|
+
}
|
|
14
|
+
const parts = (path.match(/\/?(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/?[^\/\?]+/g) || []).map((part) => {
|
|
15
|
+
const match = part.match(/^\/:([^{]+)(?:{(.*)})?/);
|
|
16
|
+
return match ? `/(?<${match[1]}>${match[2] || "[^/]+"})` : part === "/*" ? "/[^/]+" : part.replace(/[.\\+*[^\]$()]/g, "\\$&");
|
|
17
|
+
});
|
|
18
|
+
try {
|
|
19
|
+
this.#routes.push([
|
|
20
|
+
new RegExp(`^${parts.join("")}${suffix}`),
|
|
21
|
+
method,
|
|
22
|
+
handler
|
|
23
|
+
]);
|
|
24
|
+
} catch {
|
|
25
|
+
throw new UnsupportedPathError();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
match(method, path) {
|
|
29
|
+
const handlers = [];
|
|
30
|
+
for (let i = 0, len = this.#routes.length; i < len; i++) {
|
|
31
|
+
const [pattern, routeMethod, handler] = this.#routes[i];
|
|
32
|
+
if (routeMethod === method || routeMethod === "ALL") {
|
|
33
|
+
const match = pattern.exec(path);
|
|
34
|
+
if (match) handlers.push([handler, match.groups || emptyParams]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return [handlers];
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
|
41
|
+
export { PatternRouter };
|