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
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { I as MiddlewareHandler, _ as Env, t as Context } from "./context-Bm7rI-oK.js";
|
|
2
|
+
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/middleware/bearer-auth/index.d.ts
|
|
4
|
+
type MessageFunction = (c: Context) => string | object | Promise<string | object>;
|
|
5
|
+
type CustomizedErrorResponseOptions = {
|
|
6
|
+
wwwAuthenticateHeader?: string | object | MessageFunction;
|
|
7
|
+
message?: string | object | MessageFunction;
|
|
8
|
+
};
|
|
9
|
+
type BearerAuthOptions<E extends Env = Env> = {
|
|
10
|
+
token: string | string[];
|
|
11
|
+
realm?: string;
|
|
12
|
+
prefix?: string;
|
|
13
|
+
headerName?: string;
|
|
14
|
+
hashFunction?: Function;
|
|
15
|
+
/**
|
|
16
|
+
* @deprecated Use noAuthenticationHeader.message instead
|
|
17
|
+
*/
|
|
18
|
+
noAuthenticationHeaderMessage?: string | object | MessageFunction;
|
|
19
|
+
noAuthenticationHeader?: CustomizedErrorResponseOptions;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Use invalidAuthenticationHeader.message instead
|
|
22
|
+
*/
|
|
23
|
+
invalidAuthenticationHeaderMessage?: string | object | MessageFunction;
|
|
24
|
+
invalidAuthenticationHeader?: CustomizedErrorResponseOptions;
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Use invalidToken.message instead
|
|
27
|
+
*/
|
|
28
|
+
invalidTokenMessage?: string | object | MessageFunction;
|
|
29
|
+
invalidToken?: CustomizedErrorResponseOptions;
|
|
30
|
+
} | {
|
|
31
|
+
realm?: string;
|
|
32
|
+
prefix?: string;
|
|
33
|
+
headerName?: string;
|
|
34
|
+
verifyToken: (token: string, c: Context<E>) => boolean | Promise<boolean>;
|
|
35
|
+
hashFunction?: Function;
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use noAuthenticationHeader.message instead
|
|
38
|
+
*/
|
|
39
|
+
noAuthenticationHeaderMessage?: string | object | MessageFunction;
|
|
40
|
+
noAuthenticationHeader?: CustomizedErrorResponseOptions;
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Use invalidAuthenticationHeader.message instead
|
|
43
|
+
*/
|
|
44
|
+
invalidAuthenticationHeaderMessage?: string | object | MessageFunction;
|
|
45
|
+
invalidAuthenticationHeader?: CustomizedErrorResponseOptions;
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Use invalidToken.message instead
|
|
48
|
+
*/
|
|
49
|
+
invalidTokenMessage?: string | object | MessageFunction;
|
|
50
|
+
invalidToken?: CustomizedErrorResponseOptions;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Bearer Auth Middleware for Acryl.
|
|
54
|
+
*
|
|
55
|
+
*
|
|
56
|
+
* @template E - The environment type.
|
|
57
|
+
* @param {BearerAuthOptions} options - The options for the bearer authentication middleware.
|
|
58
|
+
* @param {string | string[]} [options.token] - The string or array of strings to validate the incoming bearer token against.
|
|
59
|
+
* @param {Function} [options.verifyToken] - The function to verify the token.
|
|
60
|
+
* @param {string} [options.realm=""] - The domain name of the realm, as part of the returned WWW-Authenticate challenge header.
|
|
61
|
+
* @param {string} [options.prefix="Bearer"] - The prefix (or known as `schema`) for the Authorization header value. If set to the empty string, no prefix is expected.
|
|
62
|
+
* @param {string} [options.headerName=Authorization] - The header name.
|
|
63
|
+
* @param {Function} [options.hashFunction] - A function to handle hashing for safe comparison of authentication tokens.
|
|
64
|
+
* @param {string | object | MessageFunction} [options.noAuthenticationHeader.message="Unauthorized"] - The no authentication header message.
|
|
65
|
+
* @param {string | object | MessageFunction} [options.noAuthenticationHeader.wwwAuthenticateHeader="Bearer realm=\"\""] - The response header value for the WWW-Authenticate header when no authentication header is provided.
|
|
66
|
+
* @param {string | object | MessageFunction} [options.invalidAuthenticationHeader.message="Bad Request"] - The invalid authentication header message.
|
|
67
|
+
* @param {string | object | MessageFunction} [options.invalidAuthenticationHeader.wwwAuthenticateHeader="Bearer error=\"invalid_request\""] - The response header value for the WWW-Authenticate header when authentication header is invalid.
|
|
68
|
+
* @param {string | object | MessageFunction} [options.invalidToken.message="Unauthorized"] - The invalid token message.
|
|
69
|
+
* @param {string | object | MessageFunction} [options.invalidToken.wwwAuthenticateHeader="Bearer error=\"invalid_token\""] - The response header value for the WWW-Authenticate header when token is invalid.
|
|
70
|
+
* @returns {MiddlewareHandler<E>} The middleware handler function.
|
|
71
|
+
* @throws {Error} If neither "token" nor "verifyToken" options are provided.
|
|
72
|
+
* @throws {HTTPException} If authentication fails, with 401 status code for missing or invalid token, or 400 status code for invalid request.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const app = new Acryl()
|
|
77
|
+
*
|
|
78
|
+
* const token = process.env.API_TOKEN // never a literal in source
|
|
79
|
+
*
|
|
80
|
+
* app.use('/api/*', bearerAuth({ token }))
|
|
81
|
+
*
|
|
82
|
+
* app.get('/api/page', (c) => {
|
|
83
|
+
* return c.json({ message: 'You are authorized' })
|
|
84
|
+
* })
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
declare const bearerAuth: <E extends Env = Env>(options: BearerAuthOptions<E>) => MiddlewareHandler<E>;
|
|
88
|
+
//#endregion
|
|
89
|
+
export { bearerAuth };
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { HTTPException } from "./http-exception.js";
|
|
2
|
+
import { timingSafeEqual } from "./utils/buffer.js";
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/middleware/bearer-auth/index.ts
|
|
4
|
+
const TOKEN_STRINGS = "[A-Za-z0-9._~+/-]+=*";
|
|
5
|
+
const PREFIX = "Bearer";
|
|
6
|
+
const HEADER = "Authorization";
|
|
7
|
+
/**
|
|
8
|
+
* Bearer Auth Middleware for Acryl.
|
|
9
|
+
*
|
|
10
|
+
*
|
|
11
|
+
* @template E - The environment type.
|
|
12
|
+
* @param {BearerAuthOptions} options - The options for the bearer authentication middleware.
|
|
13
|
+
* @param {string | string[]} [options.token] - The string or array of strings to validate the incoming bearer token against.
|
|
14
|
+
* @param {Function} [options.verifyToken] - The function to verify the token.
|
|
15
|
+
* @param {string} [options.realm=""] - The domain name of the realm, as part of the returned WWW-Authenticate challenge header.
|
|
16
|
+
* @param {string} [options.prefix="Bearer"] - The prefix (or known as `schema`) for the Authorization header value. If set to the empty string, no prefix is expected.
|
|
17
|
+
* @param {string} [options.headerName=Authorization] - The header name.
|
|
18
|
+
* @param {Function} [options.hashFunction] - A function to handle hashing for safe comparison of authentication tokens.
|
|
19
|
+
* @param {string | object | MessageFunction} [options.noAuthenticationHeader.message="Unauthorized"] - The no authentication header message.
|
|
20
|
+
* @param {string | object | MessageFunction} [options.noAuthenticationHeader.wwwAuthenticateHeader="Bearer realm=\"\""] - The response header value for the WWW-Authenticate header when no authentication header is provided.
|
|
21
|
+
* @param {string | object | MessageFunction} [options.invalidAuthenticationHeader.message="Bad Request"] - The invalid authentication header message.
|
|
22
|
+
* @param {string | object | MessageFunction} [options.invalidAuthenticationHeader.wwwAuthenticateHeader="Bearer error=\"invalid_request\""] - The response header value for the WWW-Authenticate header when authentication header is invalid.
|
|
23
|
+
* @param {string | object | MessageFunction} [options.invalidToken.message="Unauthorized"] - The invalid token message.
|
|
24
|
+
* @param {string | object | MessageFunction} [options.invalidToken.wwwAuthenticateHeader="Bearer error=\"invalid_token\""] - The response header value for the WWW-Authenticate header when token is invalid.
|
|
25
|
+
* @returns {MiddlewareHandler<E>} The middleware handler function.
|
|
26
|
+
* @throws {Error} If neither "token" nor "verifyToken" options are provided.
|
|
27
|
+
* @throws {HTTPException} If authentication fails, with 401 status code for missing or invalid token, or 400 status code for invalid request.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const app = new Acryl()
|
|
32
|
+
*
|
|
33
|
+
* const token = process.env.API_TOKEN // never a literal in source
|
|
34
|
+
*
|
|
35
|
+
* app.use('/api/*', bearerAuth({ token }))
|
|
36
|
+
*
|
|
37
|
+
* app.get('/api/page', (c) => {
|
|
38
|
+
* return c.json({ message: 'You are authorized' })
|
|
39
|
+
* })
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
const bearerAuth = (options) => {
|
|
43
|
+
if (!("token" in options || "verifyToken" in options)) throw new Error("bearer auth middleware requires options for \"token\" or \"verifyToken\"");
|
|
44
|
+
if (!options.realm) options.realm = "";
|
|
45
|
+
if (options.prefix === void 0) options.prefix = PREFIX;
|
|
46
|
+
const realm = options.realm?.replace(/"/g, "\\\"");
|
|
47
|
+
const prefix = options.prefix;
|
|
48
|
+
const tokenRegexp = new RegExp(`^${TOKEN_STRINGS}$`);
|
|
49
|
+
const wwwAuthenticatePrefix = prefix === "" ? "" : `${prefix} `;
|
|
50
|
+
const throwHTTPException = async (c, status, wwwAuthenticateHeader, messageOption) => {
|
|
51
|
+
const wwwAuthenticateHeaderValue = typeof wwwAuthenticateHeader === "function" ? await wwwAuthenticateHeader(c) : wwwAuthenticateHeader;
|
|
52
|
+
const headers = { "WWW-Authenticate": typeof wwwAuthenticateHeaderValue === "string" ? wwwAuthenticateHeaderValue : `${wwwAuthenticatePrefix}${Object.entries(wwwAuthenticateHeaderValue).map(([key, value]) => `${key}="${value}"`).join(",")}` };
|
|
53
|
+
const responseMessage = typeof messageOption === "function" ? await messageOption(c) : messageOption;
|
|
54
|
+
throw new HTTPException(status, { res: typeof responseMessage === "string" ? new Response(responseMessage, {
|
|
55
|
+
status,
|
|
56
|
+
headers
|
|
57
|
+
}) : new Response(JSON.stringify(responseMessage), {
|
|
58
|
+
status,
|
|
59
|
+
headers: {
|
|
60
|
+
...headers,
|
|
61
|
+
"content-type": "application/json"
|
|
62
|
+
}
|
|
63
|
+
}) });
|
|
64
|
+
};
|
|
65
|
+
return async function bearerAuth(c, next) {
|
|
66
|
+
const headerToken = c.req.header(options.headerName || HEADER);
|
|
67
|
+
if (!headerToken) await throwHTTPException(c, 401, options.noAuthenticationHeader?.wwwAuthenticateHeader || `${wwwAuthenticatePrefix}realm="${realm}"`, options.noAuthenticationHeader?.message || options.noAuthenticationHeaderMessage || "Unauthorized");
|
|
68
|
+
else {
|
|
69
|
+
let tokenValue;
|
|
70
|
+
if (prefix === "") tokenValue = headerToken;
|
|
71
|
+
else {
|
|
72
|
+
const headerLower = headerToken.toLowerCase();
|
|
73
|
+
const prefixLower = prefix.toLowerCase();
|
|
74
|
+
if (headerLower.startsWith(prefixLower) && headerToken[prefix.length] === " ") tokenValue = headerToken.slice(prefix.length).trimStart();
|
|
75
|
+
}
|
|
76
|
+
if (!tokenValue || !tokenRegexp.test(tokenValue)) await throwHTTPException(c, 400, options.invalidAuthenticationHeader?.wwwAuthenticateHeader || `${wwwAuthenticatePrefix}error="invalid_request"`, options.invalidAuthenticationHeader?.message || options.invalidAuthenticationHeaderMessage || "Bad Request");
|
|
77
|
+
else {
|
|
78
|
+
let equal = false;
|
|
79
|
+
if ("verifyToken" in options) equal = await options.verifyToken(tokenValue, c);
|
|
80
|
+
else if (typeof options.token === "string") equal = await timingSafeEqual(options.token, tokenValue, options.hashFunction);
|
|
81
|
+
else if (Array.isArray(options.token) && options.token.length > 0) {
|
|
82
|
+
for (const token of options.token) if (await timingSafeEqual(token, tokenValue, options.hashFunction)) {
|
|
83
|
+
equal = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (!equal) await throwHTTPException(c, 401, options.invalidToken?.wwwAuthenticateHeader || `${wwwAuthenticatePrefix}error="invalid_token"`, options.invalidToken?.message || options.invalidTokenMessage || "Unauthorized");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
await next();
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
//#endregion
|
|
94
|
+
export { bearerAuth };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-Bm7rI-oK.js";
|
|
2
|
+
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/middleware/body-limit/index.d.ts
|
|
4
|
+
type OnError = (c: Context) => Response | Promise<Response>;
|
|
5
|
+
type BodyLimitOptions = {
|
|
6
|
+
maxSize: number;
|
|
7
|
+
onError?: OnError;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Body Limit Middleware for Acryl.
|
|
11
|
+
*
|
|
12
|
+
*
|
|
13
|
+
* @param {BodyLimitOptions} options - The options for the body limit middleware.
|
|
14
|
+
* @param {number} options.maxSize - The maximum body size allowed.
|
|
15
|
+
* @param {OnError} [options.onError] - The error handler to be invoked if the specified body size is exceeded.
|
|
16
|
+
* @returns {MiddlewareHandler} The middleware handler function.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const app = new Acryl()
|
|
21
|
+
*
|
|
22
|
+
* app.post(
|
|
23
|
+
* '/upload',
|
|
24
|
+
* bodyLimit({
|
|
25
|
+
* maxSize: 50 * 1024, // 50kb
|
|
26
|
+
* onError: (c) => {
|
|
27
|
+
* return c.text('overflow :(', 413)
|
|
28
|
+
* },
|
|
29
|
+
* }),
|
|
30
|
+
* async (c) => {
|
|
31
|
+
* const body = await c.req.parseBody()
|
|
32
|
+
* if (body['file'] instanceof File) {
|
|
33
|
+
* console.log(`Got file sized: ${body['file'].size}`)
|
|
34
|
+
* }
|
|
35
|
+
* return c.text('pass :)')
|
|
36
|
+
* }
|
|
37
|
+
* )
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare const bodyLimit: (options: BodyLimitOptions) => MiddlewareHandler;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { bodyLimit };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { HTTPException } from "./http-exception.js";
|
|
2
|
+
//#region ../../plugins/acryl-router/src/core/middleware/body-limit/index.ts
|
|
3
|
+
const ERROR_MESSAGE = "Payload Too Large";
|
|
4
|
+
/**
|
|
5
|
+
* Body Limit Middleware for Acryl.
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* @param {BodyLimitOptions} options - The options for the body limit middleware.
|
|
9
|
+
* @param {number} options.maxSize - The maximum body size allowed.
|
|
10
|
+
* @param {OnError} [options.onError] - The error handler to be invoked if the specified body size is exceeded.
|
|
11
|
+
* @returns {MiddlewareHandler} The middleware handler function.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const app = new Acryl()
|
|
16
|
+
*
|
|
17
|
+
* app.post(
|
|
18
|
+
* '/upload',
|
|
19
|
+
* bodyLimit({
|
|
20
|
+
* maxSize: 50 * 1024, // 50kb
|
|
21
|
+
* onError: (c) => {
|
|
22
|
+
* return c.text('overflow :(', 413)
|
|
23
|
+
* },
|
|
24
|
+
* }),
|
|
25
|
+
* async (c) => {
|
|
26
|
+
* const body = await c.req.parseBody()
|
|
27
|
+
* if (body['file'] instanceof File) {
|
|
28
|
+
* console.log(`Got file sized: ${body['file'].size}`)
|
|
29
|
+
* }
|
|
30
|
+
* return c.text('pass :)')
|
|
31
|
+
* }
|
|
32
|
+
* )
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
const bodyLimit = (options) => {
|
|
36
|
+
const onError = options.onError || (() => {
|
|
37
|
+
throw new HTTPException(413, { res: new Response(ERROR_MESSAGE, { status: 413 }) });
|
|
38
|
+
});
|
|
39
|
+
const maxSize = options.maxSize;
|
|
40
|
+
return async function bodyLimit(c, next) {
|
|
41
|
+
if (!c.req.raw.body) return next();
|
|
42
|
+
const hasTransferEncoding = c.req.raw.headers.has("transfer-encoding");
|
|
43
|
+
if (c.req.raw.headers.has("content-length") && !hasTransferEncoding) return parseInt(c.req.raw.headers.get("content-length") || "0", 10) > maxSize ? onError(c) : next();
|
|
44
|
+
let size = 0;
|
|
45
|
+
const chunks = [];
|
|
46
|
+
const rawReader = c.req.raw.body.getReader();
|
|
47
|
+
for (;;) {
|
|
48
|
+
const { done, value } = await rawReader.read();
|
|
49
|
+
if (done) break;
|
|
50
|
+
size += value.length;
|
|
51
|
+
if (size > maxSize) return onError(c);
|
|
52
|
+
chunks.push(value);
|
|
53
|
+
}
|
|
54
|
+
const requestInit = {
|
|
55
|
+
body: new ReadableStream({ start(controller) {
|
|
56
|
+
for (const chunk of chunks) controller.enqueue(chunk);
|
|
57
|
+
controller.close();
|
|
58
|
+
} }),
|
|
59
|
+
duplex: "half"
|
|
60
|
+
};
|
|
61
|
+
c.req.raw = new Request(c.req.raw, requestInit);
|
|
62
|
+
return next();
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
//#endregion
|
|
66
|
+
export { bodyLimit };
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { serialize } from "./utils/cookie.js";
|
|
2
|
+
//#region ../../plugins/acryl-router/src/core/client/fetch-result-please.ts
|
|
3
|
+
/**
|
|
4
|
+
* @description This file is a modified version of `fetch-result-please` (`ofetch`), minimalized and adapted to Acryl's custom needs.
|
|
5
|
+
*
|
|
6
|
+
* @link https://www.npmjs.com/package/fetch-result-please
|
|
7
|
+
*/
|
|
8
|
+
const nullBodyResponses = /* @__PURE__ */ new Set([
|
|
9
|
+
101,
|
|
10
|
+
204,
|
|
11
|
+
205,
|
|
12
|
+
304
|
|
13
|
+
]);
|
|
14
|
+
/**
|
|
15
|
+
* Smartly parses and return the consumable result from a fetch `Response`.
|
|
16
|
+
*
|
|
17
|
+
* Throwing a structured error if the response is not `ok`. ({@link DetailedError})
|
|
18
|
+
*/
|
|
19
|
+
async function fetchRP(fetchRes) {
|
|
20
|
+
const _fetchRes = await fetchRes;
|
|
21
|
+
if ((_fetchRes.body || _fetchRes._bodyInit) && !nullBodyResponses.has(_fetchRes.status)) _fetchRes._data = await _fetchRes[detectResponseType(_fetchRes)]();
|
|
22
|
+
if (!_fetchRes.ok) throw new DetailedError(`${_fetchRes.status} ${_fetchRes.statusText}`, {
|
|
23
|
+
statusCode: _fetchRes?.status,
|
|
24
|
+
detail: {
|
|
25
|
+
data: _fetchRes?._data,
|
|
26
|
+
statusText: _fetchRes?.statusText
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return _fetchRes._data;
|
|
30
|
+
}
|
|
31
|
+
var DetailedError = class extends Error {
|
|
32
|
+
/**
|
|
33
|
+
* Additional `message` that will be logged AND returned to client
|
|
34
|
+
*/
|
|
35
|
+
detail;
|
|
36
|
+
/**
|
|
37
|
+
* Additional `code` that will be logged AND returned to client
|
|
38
|
+
*/
|
|
39
|
+
code;
|
|
40
|
+
/**
|
|
41
|
+
* Additional value that will be logged AND NOT returned to client
|
|
42
|
+
*/
|
|
43
|
+
log;
|
|
44
|
+
/**
|
|
45
|
+
* Optionally set the status code to return, in a web server context
|
|
46
|
+
*/
|
|
47
|
+
statusCode;
|
|
48
|
+
constructor(message, options = {}) {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = "DetailedError";
|
|
51
|
+
this.log = options.log;
|
|
52
|
+
this.detail = options.detail;
|
|
53
|
+
this.code = options.code;
|
|
54
|
+
this.statusCode = options.statusCode;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const jsonRegex = /^application\/(?:[\w!#$%&*.^`~-]*\+)?json(?:;.+)?$/i;
|
|
58
|
+
function detectResponseType(response) {
|
|
59
|
+
const _contentType = response.headers.get("content-type");
|
|
60
|
+
if (!_contentType) return "text";
|
|
61
|
+
const contentType = _contentType.split(";").shift();
|
|
62
|
+
if (jsonRegex.test(contentType)) return "json";
|
|
63
|
+
return "text";
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region ../../plugins/acryl-router/src/core/client/utils.ts
|
|
67
|
+
const mergePath = (base, path) => {
|
|
68
|
+
base = base.replace(/\/+$/, "");
|
|
69
|
+
base = base + "/";
|
|
70
|
+
path = path.replace(/^\/+/, "");
|
|
71
|
+
return base + path;
|
|
72
|
+
};
|
|
73
|
+
const replaceUrlParam = (urlString, params) => {
|
|
74
|
+
for (const [k, v] of Object.entries(params)) {
|
|
75
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??(?=/|$)");
|
|
76
|
+
urlString = urlString.replace(reg, () => v ? `/${v}` : "");
|
|
77
|
+
}
|
|
78
|
+
return urlString;
|
|
79
|
+
};
|
|
80
|
+
const buildSearchParams = (query) => {
|
|
81
|
+
const searchParams = new URLSearchParams();
|
|
82
|
+
for (const [k, v] of Object.entries(query)) {
|
|
83
|
+
if (v === void 0) continue;
|
|
84
|
+
if (Array.isArray(v)) for (const v2 of v) {
|
|
85
|
+
if (v2 === void 0) continue;
|
|
86
|
+
searchParams.append(k, v2);
|
|
87
|
+
}
|
|
88
|
+
else searchParams.set(k, v);
|
|
89
|
+
}
|
|
90
|
+
return searchParams;
|
|
91
|
+
};
|
|
92
|
+
const replaceUrlProtocol = (urlString, protocol) => {
|
|
93
|
+
switch (protocol) {
|
|
94
|
+
case "ws": return urlString.replace(/^http/, "ws");
|
|
95
|
+
case "http": return urlString.replace(/^ws/, "http");
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const removeIndexString = (urlString) => {
|
|
99
|
+
if (/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test(urlString)) return urlString.replace(/\/index(?=\?|$)/, "/");
|
|
100
|
+
return urlString.replace(/\/index(?=\?|$)/, "");
|
|
101
|
+
};
|
|
102
|
+
function isObject(item) {
|
|
103
|
+
return typeof item === "object" && item !== null && !Array.isArray(item);
|
|
104
|
+
}
|
|
105
|
+
function deepMerge(target, source) {
|
|
106
|
+
if (!isObject(target) && !isObject(source)) return source;
|
|
107
|
+
const merged = { ...target };
|
|
108
|
+
for (const key in source) {
|
|
109
|
+
const value = source[key];
|
|
110
|
+
if (isObject(merged[key]) && isObject(value)) merged[key] = deepMerge(merged[key], value);
|
|
111
|
+
else merged[key] = value;
|
|
112
|
+
}
|
|
113
|
+
return merged;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Shortcut to get a consumable response from `hc`'s fetch calls (Response), with types inference.
|
|
117
|
+
*
|
|
118
|
+
* Smartly parse the response data, throwing a structured error if the response is not `ok`. ({@link DetailedError})
|
|
119
|
+
*
|
|
120
|
+
* @example const result = await parseResponse(client.posts.$get())
|
|
121
|
+
*/
|
|
122
|
+
async function parseResponse(fetchRes) {
|
|
123
|
+
return fetchRP(fetchRes);
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
//#region ../../plugins/acryl-router/src/core/client/client.ts
|
|
127
|
+
const createProxy = (callback, path) => {
|
|
128
|
+
return new Proxy(() => {}, {
|
|
129
|
+
get(_obj, key) {
|
|
130
|
+
if (typeof key !== "string" || key === "then") return;
|
|
131
|
+
return createProxy(callback, [...path, key]);
|
|
132
|
+
},
|
|
133
|
+
apply(_1, _2, args) {
|
|
134
|
+
return callback({
|
|
135
|
+
path,
|
|
136
|
+
args
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
const appendQueryParams = (url, searchParams) => {
|
|
142
|
+
const queryString = searchParams.toString();
|
|
143
|
+
return queryString ? `${url}?${queryString}` : url;
|
|
144
|
+
};
|
|
145
|
+
var ClientRequestImpl = class {
|
|
146
|
+
url;
|
|
147
|
+
method;
|
|
148
|
+
buildSearchParams;
|
|
149
|
+
queryParams = void 0;
|
|
150
|
+
pathParams = {};
|
|
151
|
+
rBody;
|
|
152
|
+
cType = void 0;
|
|
153
|
+
constructor(url, method, options) {
|
|
154
|
+
this.url = url;
|
|
155
|
+
this.method = method;
|
|
156
|
+
this.buildSearchParams = options.buildSearchParams;
|
|
157
|
+
}
|
|
158
|
+
fetch = async (args, opt) => {
|
|
159
|
+
if (args) {
|
|
160
|
+
if (args.query) this.queryParams = this.buildSearchParams(args.query);
|
|
161
|
+
if (args.form) {
|
|
162
|
+
const form = new FormData();
|
|
163
|
+
for (const [k, v] of Object.entries(args.form)) {
|
|
164
|
+
if (v === void 0) continue;
|
|
165
|
+
if (Array.isArray(v)) for (const v2 of v) {
|
|
166
|
+
if (v2 === void 0) continue;
|
|
167
|
+
form.append(k, v2);
|
|
168
|
+
}
|
|
169
|
+
else form.append(k, v);
|
|
170
|
+
}
|
|
171
|
+
this.rBody = form;
|
|
172
|
+
}
|
|
173
|
+
if (args.json !== void 0) {
|
|
174
|
+
this.rBody = JSON.stringify(args.json);
|
|
175
|
+
this.cType = "application/json";
|
|
176
|
+
}
|
|
177
|
+
if (args.param) this.pathParams = args.param;
|
|
178
|
+
}
|
|
179
|
+
let methodUpperCase = this.method.toUpperCase();
|
|
180
|
+
const headerValues = {
|
|
181
|
+
...args?.header,
|
|
182
|
+
...typeof opt?.headers === "function" ? await opt.headers() : opt?.headers
|
|
183
|
+
};
|
|
184
|
+
if (args?.cookie) {
|
|
185
|
+
const cookies = [];
|
|
186
|
+
for (const [key, value] of Object.entries(args.cookie)) {
|
|
187
|
+
if (value === void 0) continue;
|
|
188
|
+
cookies.push(serialize(key, value));
|
|
189
|
+
}
|
|
190
|
+
if (cookies.length > 0) headerValues["Cookie"] = cookies.join("; ");
|
|
191
|
+
}
|
|
192
|
+
if (this.cType) headerValues["Content-Type"] = this.cType;
|
|
193
|
+
const headers = new Headers();
|
|
194
|
+
for (const [key, value] of Object.entries(headerValues)) if (value !== void 0) headers.set(key, value);
|
|
195
|
+
let url = this.url;
|
|
196
|
+
url = removeIndexString(url);
|
|
197
|
+
url = replaceUrlParam(url, this.pathParams);
|
|
198
|
+
if (this.queryParams) url = appendQueryParams(url, this.queryParams);
|
|
199
|
+
methodUpperCase = this.method.toUpperCase();
|
|
200
|
+
const setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
|
|
201
|
+
return (opt?.fetch || fetch)(url, {
|
|
202
|
+
body: setBody ? this.rBody : void 0,
|
|
203
|
+
method: methodUpperCase,
|
|
204
|
+
headers,
|
|
205
|
+
...opt?.init
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
const hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
210
|
+
const buildSearchParamsOption = options?.buildSearchParams ?? buildSearchParams;
|
|
211
|
+
const parts = [...opts.path];
|
|
212
|
+
const lastParts = parts.slice(-3).reverse();
|
|
213
|
+
if (lastParts[0] === "toString") {
|
|
214
|
+
if (lastParts[1] === "name") return lastParts[2] || "";
|
|
215
|
+
return proxyCallback.toString();
|
|
216
|
+
}
|
|
217
|
+
if (lastParts[0] === "valueOf") {
|
|
218
|
+
if (lastParts[1] === "name") return lastParts[2] || "";
|
|
219
|
+
return proxyCallback;
|
|
220
|
+
}
|
|
221
|
+
let method = "";
|
|
222
|
+
if (/^\$/.test(lastParts[0])) {
|
|
223
|
+
const last = parts.pop();
|
|
224
|
+
if (last) method = last.replace(/^\$/, "");
|
|
225
|
+
}
|
|
226
|
+
const url = mergePath(baseUrl, parts.join("/"));
|
|
227
|
+
if (method === "url" || method === "path") {
|
|
228
|
+
let result = removeIndexString(url);
|
|
229
|
+
if (opts.args[0]) {
|
|
230
|
+
if (opts.args[0].param) result = replaceUrlParam(result, opts.args[0].param);
|
|
231
|
+
if (opts.args[0].query) result = appendQueryParams(result, buildSearchParamsOption(opts.args[0].query));
|
|
232
|
+
}
|
|
233
|
+
if (method === "url") return new URL(result);
|
|
234
|
+
return result.slice(baseUrl.replace(/\/+$/, "").length).replace(/^\/?/, "/");
|
|
235
|
+
}
|
|
236
|
+
if (method === "ws") {
|
|
237
|
+
const normalizedUrl = removeIndexString(url);
|
|
238
|
+
const webSocketUrl = replaceUrlProtocol(opts.args[0]?.param ? replaceUrlParam(normalizedUrl, opts.args[0].param) : normalizedUrl, "ws");
|
|
239
|
+
const targetUrl = new URL(webSocketUrl);
|
|
240
|
+
const queryParams = opts.args[0]?.query;
|
|
241
|
+
if (queryParams) buildSearchParamsOption(queryParams).forEach((value, key) => {
|
|
242
|
+
targetUrl.searchParams.append(key, value);
|
|
243
|
+
});
|
|
244
|
+
const establishWebSocket = (...args) => {
|
|
245
|
+
if (options?.webSocket !== void 0 && typeof options.webSocket === "function") return options.webSocket(...args);
|
|
246
|
+
return new WebSocket(...args);
|
|
247
|
+
};
|
|
248
|
+
return establishWebSocket(targetUrl.toString());
|
|
249
|
+
}
|
|
250
|
+
const req = new ClientRequestImpl(url, method, { buildSearchParams: buildSearchParamsOption });
|
|
251
|
+
if (method) {
|
|
252
|
+
options ??= {};
|
|
253
|
+
const reqOptions = { ...opts.args[1] };
|
|
254
|
+
const baseHeaders = options.headers;
|
|
255
|
+
const reqHeaders = reqOptions.headers;
|
|
256
|
+
if (baseHeaders && reqHeaders) reqOptions.headers = async () => ({
|
|
257
|
+
...typeof baseHeaders === "function" ? await baseHeaders() : baseHeaders,
|
|
258
|
+
...typeof reqHeaders === "function" ? await reqHeaders() : reqHeaders
|
|
259
|
+
});
|
|
260
|
+
const args = deepMerge(options, reqOptions);
|
|
261
|
+
return req.fetch(opts.args[0], args);
|
|
262
|
+
}
|
|
263
|
+
return req;
|
|
264
|
+
}, []);
|
|
265
|
+
//#endregion
|
|
266
|
+
export { parseResponse as n, DetailedError as r, hc as t };
|
package/lib/client.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { a as ClientResponse, c as InferRequestType, i as ClientRequestOptions, l as InferResponseType, o as Fetch, r as ClientRequest, t as ApplyGlobalResponse, u as PickResponseByStatusCode } from "./types-CHesD1KG.js";
|
|
2
|
+
import { n as DetailedError, r as hc, t as parseResponse } from "./index-oOClm_Xk.js";
|
|
3
|
+
export { type ApplyGlobalResponse, type ClientRequest, type ClientRequestOptions, type ClientResponse, DetailedError, type Fetch, type InferRequestType, type InferResponseType, type PickResponseByStatusCode, hc, parseResponse };
|
package/lib/client.js
ADDED
package/lib/combine.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { I as MiddlewareHandler, t as Context } from "./context-Bm7rI-oK.js";
|
|
2
|
+
|
|
3
|
+
//#region ../../plugins/acryl-router/src/core/middleware/combine/index.d.ts
|
|
4
|
+
type Condition = (c: Context) => boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Create a composed middleware that runs the first middleware that returns true.
|
|
7
|
+
*
|
|
8
|
+
* @param middleware - An array of MiddlewareHandler or Condition functions.
|
|
9
|
+
* Middleware is applied in the order it is passed, and if any middleware exits without returning
|
|
10
|
+
* an exception first, subsequent middleware will not be executed.
|
|
11
|
+
* You can also pass a condition function that returns a boolean value. If returns true
|
|
12
|
+
* the evaluation will be halted, and rest of the middleware will not be executed.
|
|
13
|
+
* @returns A composed middleware.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { some } from 'acrylblends/combine'
|
|
18
|
+
* import { bearerAuth } from 'acrylblends/bearer-auth'
|
|
19
|
+
* import { myRateLimit } from '@/rate-limit'
|
|
20
|
+
*
|
|
21
|
+
* // If client has a valid token, then skip rate limiting.
|
|
22
|
+
* // Otherwise, apply rate limiting.
|
|
23
|
+
* app.use('/api/*', some(
|
|
24
|
+
* bearerAuth({ token }),
|
|
25
|
+
* myRateLimit({ limit: 100 }),
|
|
26
|
+
* ));
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
declare const some: (...middleware: (MiddlewareHandler | Condition)[]) => MiddlewareHandler;
|
|
30
|
+
/**
|
|
31
|
+
* Create a composed middleware that runs all middleware and throws an error if any of them fail.
|
|
32
|
+
*
|
|
33
|
+
* @param middleware - An array of MiddlewareHandler or Condition functions.
|
|
34
|
+
* Middleware is applied in the order it is passed, and if any middleware throws an error,
|
|
35
|
+
* subsequent middleware will not be executed.
|
|
36
|
+
* You can also pass a condition function that returns a boolean value. If returns false
|
|
37
|
+
* the evaluation will be halted, and rest of the middleware will not be executed.
|
|
38
|
+
* @returns A composed middleware.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* import { some, every } from 'acrylblends/combine'
|
|
43
|
+
* import { bearerAuth } from 'acrylblends/bearer-auth'
|
|
44
|
+
* import { myCheckLocalNetwork } from '@/check-local-network'
|
|
45
|
+
* import { myRateLimit } from '@/rate-limit'
|
|
46
|
+
*
|
|
47
|
+
* // If client is in local network, then skip authentication and rate limiting.
|
|
48
|
+
* // Otherwise, apply authentication and rate limiting.
|
|
49
|
+
* app.use('/api/*', some(
|
|
50
|
+
* myCheckLocalNetwork(),
|
|
51
|
+
* every(
|
|
52
|
+
* bearerAuth({ token }),
|
|
53
|
+
* myRateLimit({ limit: 100 }),
|
|
54
|
+
* ),
|
|
55
|
+
* ));
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
declare const every: (...middleware: (MiddlewareHandler | Condition)[]) => MiddlewareHandler;
|
|
59
|
+
/**
|
|
60
|
+
* Create a composed middleware that runs all middleware except when the condition is met.
|
|
61
|
+
*
|
|
62
|
+
* @param condition - A string or Condition function.
|
|
63
|
+
* If there are multiple targets to match any of them, they can be passed as an array.
|
|
64
|
+
* If a string is passed, it will be treated as a path pattern to match.
|
|
65
|
+
* If a Condition function is passed, it will be evaluated against the request context.
|
|
66
|
+
* @param middleware - Middleware to run when the condition is not met.
|
|
67
|
+
* Multiple middleware can be passed, and they are applied in the order they are passed.
|
|
68
|
+
* @returns A composed middleware.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { except } from 'acrylblends/combine'
|
|
73
|
+
* import { bearerAuth } from 'acrylblends/bearer-auth'
|
|
74
|
+
*
|
|
75
|
+
* // If client is accessing public API, then skip authentication.
|
|
76
|
+
* // Otherwise, require a valid token.
|
|
77
|
+
* app.use('/api/*', except(
|
|
78
|
+
* '/api/public/*',
|
|
79
|
+
* bearerAuth({ token }),
|
|
80
|
+
* ));
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
declare const except: (condition: string | Condition | (string | Condition)[], ...middleware: MiddlewareHandler[]) => MiddlewareHandler;
|
|
84
|
+
//#endregion
|
|
85
|
+
export { every, except, some };
|