acrylblends 0.4.1 → 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/docs/framework/README.md +51 -51
- package/docs/framework/UPSTREAM.md +1 -1
- 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 → api/summary.md} +19 -17
- 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/{getting-started.md → cordis/acryl-in-a-cordis-app.md} +16 -16
- package/docs/framework/{concepts.md → cordis/concepts.md} +2 -2
- package/docs/framework/cordis/middleware.md +8 -0
- package/docs/framework/{migration-from-0-3.md → cordis/migration-from-0-3.md} +16 -13
- package/docs/framework/cordis/migration-from-0-4.md +14 -0
- package/docs/framework/{migration-from-dsh-webserver.md → cordis/migration-from-dsh-webserver.md} +7 -7
- package/docs/framework/{routing.md → cordis/mounting.md} +5 -108
- package/docs/framework/{node-server.md → cordis/node-server.md} +4 -4
- package/docs/framework/{surfaces.md → cordis/surfaces.md} +2 -2
- package/docs/framework/cordis/transport-and-cancellation.md +57 -0
- package/docs/framework/{validation.md → cordis/validation.md} +9 -9
- 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 +3 -3
- 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 +312 -14
- package/plugins/acryl-inspect/src/service.ts +2 -2
- 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/service.ts +10 -10
- 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 +4 -4
- 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 +23 -23
- 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 +2 -2
- package/plugins/extensions/resolve.ts +70 -10
- package/plugins/openai/prompt.ts +5 -5
- package/shared/AGENTS.core.md +16 -9
- 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/src/routes.ts +2 -2
- package/templates/todo/src/todo.ts +2 -2
- package/templates/todo/upstream.json +2 -2
- package/docs/framework/context.md +0 -129
- package/docs/framework/helpers.md +0 -118
- package/docs/framework/middleware.md +0 -154
- package/docs/framework/request.md +0 -106
- /package/docs/framework/{plugin-lifecycle.md → cordis/plugin-lifecycle.md} +0 -0
|
@@ -9,7 +9,7 @@ import { decodeBase64 } from '../encode.ts'
|
|
|
9
9
|
import type { SignatureAlgorithm } from './jwa.ts'
|
|
10
10
|
import { CryptoKeyUsage, JwtAlgorithmNotImplemented } from './types.ts'
|
|
11
11
|
import { utf8Encoder } from './utf8.ts'
|
|
12
|
-
import type { BufferSource } from '../types.ts'
|
|
12
|
+
import type { BufferSource, CryptoKey, JsonWebKey } from '../types.ts'
|
|
13
13
|
|
|
14
14
|
type KeyImporterAlgorithm = Parameters<typeof crypto.subtle.importKey>[2]
|
|
15
15
|
type KeyAlgorithm =
|
|
@@ -21,11 +21,11 @@ type KeyAlgorithm =
|
|
|
21
21
|
|
|
22
22
|
// Extending the JsonWebKey interface to include the "kid" property.
|
|
23
23
|
// https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.4
|
|
24
|
-
export interface
|
|
24
|
+
export interface AcrylJsonWebKey extends JsonWebKey {
|
|
25
25
|
kid?: string
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export type SignatureKey = string |
|
|
28
|
+
export type SignatureKey = string | AcrylJsonWebKey | CryptoKey
|
|
29
29
|
|
|
30
30
|
export async function signing(
|
|
31
31
|
privateKey: SignatureKey,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { vi } from 'vitest'
|
|
3
3
|
import { encodeBase64, encodeBase64Url } from '../encode.ts'
|
|
4
4
|
import { AlgorithmTypes } from './jwa.ts'
|
|
5
|
-
import type {
|
|
5
|
+
import type { AcrylJsonWebKey } from './jws.ts'
|
|
6
6
|
import { signing } from './jws.ts'
|
|
7
7
|
import * as JWT from './jwt.ts'
|
|
8
8
|
import { verifyWithJwks } from './jwt.ts'
|
|
@@ -1475,7 +1475,7 @@ describe('verifyWithJwks algorithm whitelist', () => {
|
|
|
1475
1475
|
|
|
1476
1476
|
describe('verifyWithJwks key handling', () => {
|
|
1477
1477
|
it('Should not mutate provided keys when JWKS is fetched repeatedly', async () => {
|
|
1478
|
-
const localKeys:
|
|
1478
|
+
const localKeys: AcrylJsonWebKey[] = [
|
|
1479
1479
|
{
|
|
1480
1480
|
kty: 'RSA',
|
|
1481
1481
|
kid: 'local-key',
|
|
@@ -8,7 +8,7 @@ import { decodeBase64Url, encodeBase64Url } from '../encode.ts'
|
|
|
8
8
|
import { AlgorithmTypes } from './jwa.ts'
|
|
9
9
|
import type { AsymmetricAlgorithm, SignatureAlgorithm, SymmetricAlgorithm } from './jwa.ts'
|
|
10
10
|
import { signing, verifying } from './jws.ts'
|
|
11
|
-
import type {
|
|
11
|
+
import type { AcrylJsonWebKey, SignatureKey } from './jws.ts'
|
|
12
12
|
import {
|
|
13
13
|
JwtAlgorithmMismatch,
|
|
14
14
|
JwtAlgorithmNotAllowed,
|
|
@@ -198,7 +198,7 @@ const symmetricAlgorithms: SymmetricAlgorithm[] = [
|
|
|
198
198
|
export const verifyWithJwks = async (
|
|
199
199
|
token: string,
|
|
200
200
|
options: {
|
|
201
|
-
keys?:
|
|
201
|
+
keys?: AcrylJsonWebKey[]
|
|
202
202
|
jwks_uri?: string
|
|
203
203
|
verification?: VerifyOptions
|
|
204
204
|
allowedAlgorithms: readonly AsymmetricAlgorithm[]
|
|
@@ -241,7 +241,7 @@ export const verifyWithJwks = async (
|
|
|
241
241
|
throw new Error('invalid JWKS response. "keys" field is not an array')
|
|
242
242
|
}
|
|
243
243
|
verifyKeys ??= []
|
|
244
|
-
verifyKeys.push(...(data.keys as
|
|
244
|
+
verifyKeys.push(...(data.keys as AcrylJsonWebKey[]))
|
|
245
245
|
} else if (!verifyKeys) {
|
|
246
246
|
throw new Error('verifyWithJwks requires options for either "keys" or "jwks_uri" or both')
|
|
247
247
|
}
|
|
@@ -121,3 +121,45 @@ export type StringLiteralUnion<T> = T | (string & Record<never, never>)
|
|
|
121
121
|
|
|
122
122
|
/** Bytes a Web Crypto call accepts; declared here so the public types do not need the DOM library. */
|
|
123
123
|
export type BufferSource = ArrayBufferView<ArrayBuffer> | ArrayBuffer
|
|
124
|
+
|
|
125
|
+
/** A Web Crypto key, named from the runtime's own `crypto` so the public types do not need the DOM library. */
|
|
126
|
+
export type CryptoKey = Awaited<ReturnType<typeof crypto.subtle.importKey>>
|
|
127
|
+
|
|
128
|
+
/** How a WebSocket hands binary data to `onmessage`; declared here so the public types do not need the DOM library. */
|
|
129
|
+
export type BinaryType = 'arraybuffer' | 'blob'
|
|
130
|
+
|
|
131
|
+
/** The members of a WebSocket `message` event the helpers hand out (the Web `MessageEvent`, whose Node global is not generic); declared here so the public types do not need the DOM library. */
|
|
132
|
+
export interface MessageEvent<T = unknown> extends Event {
|
|
133
|
+
readonly data: T
|
|
134
|
+
readonly lastEventId: string
|
|
135
|
+
readonly origin: string
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** The members of a WebSocket `close` event the helpers hand out (the Web `CloseEvent`, which Node has no global type for); declared here so the public types do not need the DOM library. */
|
|
139
|
+
export interface CloseEvent extends Event {
|
|
140
|
+
readonly code: number
|
|
141
|
+
readonly reason: string
|
|
142
|
+
readonly wasClean: boolean
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** A JSON Web Key (RFC 7517), the same members as the Web Crypto dictionary; declared here so the public types do not need the DOM library. */
|
|
146
|
+
export interface JsonWebKey {
|
|
147
|
+
alg?: string
|
|
148
|
+
crv?: string
|
|
149
|
+
d?: string
|
|
150
|
+
dp?: string
|
|
151
|
+
dq?: string
|
|
152
|
+
e?: string
|
|
153
|
+
ext?: boolean
|
|
154
|
+
k?: string
|
|
155
|
+
key_ops?: string[]
|
|
156
|
+
kty?: string
|
|
157
|
+
n?: string
|
|
158
|
+
oth?: { d?: string; r?: string; t?: string }[]
|
|
159
|
+
p?: string
|
|
160
|
+
q?: string
|
|
161
|
+
qi?: string
|
|
162
|
+
use?: string
|
|
163
|
+
x?: string
|
|
164
|
+
y?: string
|
|
165
|
+
}
|
|
@@ -270,7 +270,7 @@ describe('url', () => {
|
|
|
270
270
|
)
|
|
271
271
|
expect(getQueryParam('http://example.com/?safe=1#&admin=true')).toEqual({ safe: '1' })
|
|
272
272
|
expect(getQueryParam('http://example.com/?name=hey&age=20&tall=170', 'age')).toBe('20')
|
|
273
|
-
expect(getQueryParam('http://example.com/?
|
|
273
|
+
expect(getQueryParam('http://example.com/?Acryl+is=a+web+framework', 'Acryl is')).toBe(
|
|
274
274
|
'a web framework'
|
|
275
275
|
)
|
|
276
276
|
expect(getQueryParam('http://example.com/?name=%E0%A4%A', 'name')).toBe('%E0%A4%A')
|
|
@@ -330,7 +330,7 @@ describe('url', () => {
|
|
|
330
330
|
expect(
|
|
331
331
|
getQueryParams('http://example.com/?name=hey&age=20&tall=170&name=foo&age=30', 'age')
|
|
332
332
|
).toEqual(['20', '30'])
|
|
333
|
-
expect(getQueryParams('http://example.com/?
|
|
333
|
+
expect(getQueryParams('http://example.com/?Acryl+is=a+web+framework', 'Acryl is')).toEqual([
|
|
334
334
|
'a web framework',
|
|
335
335
|
])
|
|
336
336
|
expect(getQueryParams('http://example.com/?name=%E0%A4%A', 'name')).toEqual(['%E0%A4%A'])
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
import * as z from 'zod'
|
|
3
3
|
import type { Context } from '../context.ts'
|
|
4
|
-
import {
|
|
4
|
+
import { Acryl } from '../app.ts'
|
|
5
5
|
import { HTTPException } from '../http-exception.ts'
|
|
6
6
|
import { cloneRawRequest } from '../request.ts'
|
|
7
7
|
import type {
|
|
@@ -61,7 +61,7 @@ const zodValidator = <
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
describe('Basic', () => {
|
|
64
|
-
const app = new
|
|
64
|
+
const app = new Acryl()
|
|
65
65
|
|
|
66
66
|
const route = app.get(
|
|
67
67
|
'/search',
|
|
@@ -124,7 +124,7 @@ const onErrorHandler: ErrorHandler = (e, c) => {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
describe('JSON', () => {
|
|
127
|
-
const app = new
|
|
127
|
+
const app = new Acryl()
|
|
128
128
|
app.post(
|
|
129
129
|
'/post',
|
|
130
130
|
validator('json', (value) => value),
|
|
@@ -230,7 +230,7 @@ describe('JSON', () => {
|
|
|
230
230
|
})
|
|
231
231
|
|
|
232
232
|
describe('Malformed JSON', () => {
|
|
233
|
-
const app = new
|
|
233
|
+
const app = new Acryl()
|
|
234
234
|
app.post(
|
|
235
235
|
'/post',
|
|
236
236
|
validator('json', (value) => value),
|
|
@@ -254,7 +254,7 @@ describe('Malformed JSON', () => {
|
|
|
254
254
|
})
|
|
255
255
|
|
|
256
256
|
describe('FormData', () => {
|
|
257
|
-
const app = new
|
|
257
|
+
const app = new Acryl()
|
|
258
258
|
app.post(
|
|
259
259
|
'/post',
|
|
260
260
|
validator('form', (value) => value),
|
|
@@ -373,7 +373,7 @@ describe('FormData', () => {
|
|
|
373
373
|
})
|
|
374
374
|
|
|
375
375
|
describe('Malformed FormData request', () => {
|
|
376
|
-
const app = new
|
|
376
|
+
const app = new Acryl()
|
|
377
377
|
app.post(
|
|
378
378
|
'/post',
|
|
379
379
|
validator('form', (value) => value),
|
|
@@ -399,7 +399,7 @@ describe('Malformed FormData request', () => {
|
|
|
399
399
|
})
|
|
400
400
|
|
|
401
401
|
describe('JSON and FormData', () => {
|
|
402
|
-
const app = new
|
|
402
|
+
const app = new Acryl()
|
|
403
403
|
app.post(
|
|
404
404
|
'/',
|
|
405
405
|
validator('json', (value) => value),
|
|
@@ -442,7 +442,7 @@ describe('JSON and FormData', () => {
|
|
|
442
442
|
|
|
443
443
|
describe('Cached contents', () => {
|
|
444
444
|
describe('json', () => {
|
|
445
|
-
const app = new
|
|
445
|
+
const app = new Acryl()
|
|
446
446
|
const bodyTypes = ['json', 'text', 'arrayBuffer', 'blob']
|
|
447
447
|
|
|
448
448
|
for (const type of bodyTypes) {
|
|
@@ -483,7 +483,7 @@ describe('Cached contents', () => {
|
|
|
483
483
|
})
|
|
484
484
|
|
|
485
485
|
describe('Cached content', () => {
|
|
486
|
-
const app = new
|
|
486
|
+
const app = new Acryl()
|
|
487
487
|
const bodyTypes = ['formData', 'text', 'arrayBuffer', 'blob']
|
|
488
488
|
|
|
489
489
|
for (const type of bodyTypes) {
|
|
@@ -523,7 +523,7 @@ describe('Cached contents', () => {
|
|
|
523
523
|
})
|
|
524
524
|
|
|
525
525
|
describe('Validator middleware with a custom validation function', () => {
|
|
526
|
-
const app = new
|
|
526
|
+
const app = new Acryl()
|
|
527
527
|
|
|
528
528
|
const validationFunction: ValidationFunction<{ id: string }, { id: number }> = (v) => {
|
|
529
529
|
return {
|
|
@@ -595,7 +595,7 @@ describe('Validator middleware with a custom validation function', () => {
|
|
|
595
595
|
})
|
|
596
596
|
|
|
597
597
|
describe('Validator middleware with Zod validates JSON', () => {
|
|
598
|
-
const app = new
|
|
598
|
+
const app = new Acryl()
|
|
599
599
|
|
|
600
600
|
const schema = z.object({
|
|
601
601
|
id: z.number(),
|
|
@@ -688,7 +688,7 @@ describe('Validator middleware with Zod validates JSON', () => {
|
|
|
688
688
|
})
|
|
689
689
|
|
|
690
690
|
describe('Validator middleware with Zod validates Form data', () => {
|
|
691
|
-
const app = new
|
|
691
|
+
const app = new Acryl()
|
|
692
692
|
|
|
693
693
|
const schema = z.object({
|
|
694
694
|
id: z.string(),
|
|
@@ -728,7 +728,7 @@ describe('Validator middleware with Zod validates Form data', () => {
|
|
|
728
728
|
})
|
|
729
729
|
|
|
730
730
|
describe('Validator middleware with Zod validates query params', () => {
|
|
731
|
-
const app = new
|
|
731
|
+
const app = new Acryl()
|
|
732
732
|
|
|
733
733
|
const schema = z.object({
|
|
734
734
|
page: z
|
|
@@ -767,7 +767,7 @@ describe('Validator middleware with Zod validates query params', () => {
|
|
|
767
767
|
})
|
|
768
768
|
|
|
769
769
|
describe('Validator middleware with Zod validates param', () => {
|
|
770
|
-
const app = new
|
|
770
|
+
const app = new Acryl()
|
|
771
771
|
|
|
772
772
|
const schema = z.object({
|
|
773
773
|
id: z
|
|
@@ -804,7 +804,7 @@ describe('Validator middleware with Zod validates param', () => {
|
|
|
804
804
|
})
|
|
805
805
|
|
|
806
806
|
describe('Validator middleware with Zod validates header values', () => {
|
|
807
|
-
const app = new
|
|
807
|
+
const app = new Acryl()
|
|
808
808
|
|
|
809
809
|
const schema = z.object({
|
|
810
810
|
'x-request-id': z.string().uuid(),
|
|
@@ -842,7 +842,7 @@ describe('Validator middleware with Zod validates header values', () => {
|
|
|
842
842
|
})
|
|
843
843
|
|
|
844
844
|
describe('Validator middleware with Zod validates cookies', () => {
|
|
845
|
-
const app = new
|
|
845
|
+
const app = new Acryl()
|
|
846
846
|
|
|
847
847
|
const schema = z.object({
|
|
848
848
|
debug: z.enum(['0', '1']),
|
|
@@ -879,7 +879,7 @@ describe('Validator middleware with Zod validates cookies', () => {
|
|
|
879
879
|
})
|
|
880
880
|
|
|
881
881
|
describe('Validator middleware with Zod multiple validators', () => {
|
|
882
|
-
const app = new
|
|
882
|
+
const app = new Acryl<{ Variables: { id: number } }>()
|
|
883
883
|
const route = app.post(
|
|
884
884
|
'/posts',
|
|
885
885
|
zodValidator(
|
|
@@ -977,7 +977,7 @@ describe('Validator middleware with Zod multiple validators', () => {
|
|
|
977
977
|
})
|
|
978
978
|
|
|
979
979
|
it('With path parameters', () => {
|
|
980
|
-
const app = new
|
|
980
|
+
const app = new Acryl()
|
|
981
981
|
|
|
982
982
|
const route = app.put(
|
|
983
983
|
'/posts/:id',
|
|
@@ -1020,7 +1020,7 @@ it('With path parameters', () => {
|
|
|
1020
1020
|
})
|
|
1021
1021
|
|
|
1022
1022
|
it('`on`', () => {
|
|
1023
|
-
const app = new
|
|
1023
|
+
const app = new Acryl()
|
|
1024
1024
|
|
|
1025
1025
|
const route = app.on(
|
|
1026
1026
|
'PURGE',
|
|
@@ -1068,7 +1068,7 @@ it('`on`', () => {
|
|
|
1068
1068
|
})
|
|
1069
1069
|
|
|
1070
1070
|
it('`app.on`', () => {
|
|
1071
|
-
const app = new
|
|
1071
|
+
const app = new Acryl()
|
|
1072
1072
|
|
|
1073
1073
|
const route = app
|
|
1074
1074
|
.get(
|
|
@@ -1112,7 +1112,7 @@ it('`app.on`', () => {
|
|
|
1112
1112
|
|
|
1113
1113
|
describe('Clone Request object', () => {
|
|
1114
1114
|
describe('json', () => {
|
|
1115
|
-
const app = new
|
|
1115
|
+
const app = new Acryl()
|
|
1116
1116
|
app.post(
|
|
1117
1117
|
'/',
|
|
1118
1118
|
validator('json', () => {
|
|
@@ -1147,7 +1147,7 @@ describe('Clone Request object', () => {
|
|
|
1147
1147
|
})
|
|
1148
1148
|
|
|
1149
1149
|
describe('form', () => {
|
|
1150
|
-
const app = new
|
|
1150
|
+
const app = new Acryl()
|
|
1151
1151
|
app.post(
|
|
1152
1152
|
'/',
|
|
1153
1153
|
validator('form', () => {
|
|
@@ -1212,7 +1212,7 @@ describe('Clone Request object', () => {
|
|
|
1212
1212
|
})
|
|
1213
1213
|
|
|
1214
1214
|
describe('Async validator function', () => {
|
|
1215
|
-
const app = new
|
|
1215
|
+
const app = new Acryl()
|
|
1216
1216
|
|
|
1217
1217
|
app.get(
|
|
1218
1218
|
'/posts',
|
|
@@ -1243,7 +1243,7 @@ describe('Validator with using Zod directly', () => {
|
|
|
1243
1243
|
age: z.number(),
|
|
1244
1244
|
type: z.enum(['a']),
|
|
1245
1245
|
})
|
|
1246
|
-
const app = new
|
|
1246
|
+
const app = new Acryl()
|
|
1247
1247
|
|
|
1248
1248
|
const route = app.post(
|
|
1249
1249
|
'/posts',
|
|
@@ -1308,7 +1308,7 @@ describe('Validator with using Zod directly', () => {
|
|
|
1308
1308
|
|
|
1309
1309
|
describe('Transform', () => {
|
|
1310
1310
|
it('Should be number when the type is transformed', () => {
|
|
1311
|
-
const route = new
|
|
1311
|
+
const route = new Acryl().get(
|
|
1312
1312
|
'/',
|
|
1313
1313
|
validator('query', async () => {
|
|
1314
1314
|
return {
|
|
@@ -1347,7 +1347,7 @@ describe('Transform', () => {
|
|
|
1347
1347
|
})
|
|
1348
1348
|
|
|
1349
1349
|
it('Should be number and union when the type is transformed', () => {
|
|
1350
|
-
const app = new
|
|
1350
|
+
const app = new Acryl()
|
|
1351
1351
|
const route = app.get(
|
|
1352
1352
|
'/',
|
|
1353
1353
|
validator('query', () => {
|
|
@@ -1400,7 +1400,7 @@ describe('Transform', () => {
|
|
|
1400
1400
|
|
|
1401
1401
|
describe('Raw Request cloning after validation', () => {
|
|
1402
1402
|
it('Should allow the `cloneRawRequest` util to clone the request object after validation', async () => {
|
|
1403
|
-
const app = new
|
|
1403
|
+
const app = new Acryl()
|
|
1404
1404
|
|
|
1405
1405
|
app.post(
|
|
1406
1406
|
'/json-validation',
|
|
@@ -1469,7 +1469,7 @@ describe('Raw Request cloning after validation', () => {
|
|
|
1469
1469
|
|
|
1470
1470
|
describe('Form validator prototype pollution prevention', () => {
|
|
1471
1471
|
it('should store __proto__ as data and not misdetect inherited keys', async () => {
|
|
1472
|
-
const app = new
|
|
1472
|
+
const app = new Acryl()
|
|
1473
1473
|
app.post(
|
|
1474
1474
|
'/form',
|
|
1475
1475
|
validator('form', (value) => value),
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The 0.4 names, kept for one release so code written against them keeps working: `App` is now `Acryl` and `AppRequest` is now `AcrylRequest`,
|
|
3
|
+
* the upstream names with the project renamed. Not part of the ported core; both the plugin's root and the public package's root export these.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Acryl } from './core/app.ts'
|
|
7
|
+
import type { AcrylRequest } from './core/request.ts'
|
|
8
|
+
import type { BlankEnv, BlankSchema, Env, Input, Schema } from './core/types.ts'
|
|
9
|
+
|
|
10
|
+
/** @deprecated Use `Acryl` (`new Acryl()`); `App` is the 0.4 name and goes away in the next release. */
|
|
11
|
+
export const App = Acryl
|
|
12
|
+
/** @deprecated Use `Acryl`; `App` is the 0.4 name and goes away in the next release. */
|
|
13
|
+
export type App<E extends Env = BlankEnv, S extends Schema = BlankSchema, BasePath extends string = '/'> = Acryl<E, S, BasePath>
|
|
14
|
+
/** @deprecated Use `AcrylRequest`; `AppRequest` is the 0.4 name and goes away in the next release. */
|
|
15
|
+
export type AppRequest<P extends string = '/', I extends Input['out'] = {}> = AcrylRequest<P, I>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { Router, Config, apply, name, type MountableApp, type RouterHttpService, type TrailingSlash } from './service.ts'
|
|
2
2
|
export { connectionOf, getConnInfo, type ConnectionInfo, type RouterBindings, type RouterEnv } from './connection.ts'
|
|
3
|
-
export {
|
|
4
|
-
export
|
|
3
|
+
export { Acryl, Context } from './core/index.ts'
|
|
4
|
+
export { App, type AppRequest } from './deprecated.ts'
|
|
5
|
+
export type { AcrylRequest, ContextRenderer, ContextVariableMap, Env, ErrorHandler, ExecutionContext, Handler, Input, MiddlewareHandler, Next, NotFoundHandler, NotFoundResponse, Schema, ToSchema, TypedResponse, ValidationTargets } from './core/index.ts'
|
|
5
6
|
export { HTTPException } from './core/http-exception.ts'
|
|
6
7
|
export type { ContentfulStatusCode, StatusCode } from './core/utils/http-status.ts'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The ACRYL router service (`ctx.router`): plugin-owned `
|
|
2
|
+
* The ACRYL router service (`ctx.router`): plugin-owned `Acryl` mounts on Web-standard Request and Response.
|
|
3
3
|
*
|
|
4
|
-
* A plugin builds an ordinary `
|
|
4
|
+
* A plugin builds an ordinary `Acryl` and mounts it with `ctx.router.route(path, app)` from its own context, so the mount disappears when that
|
|
5
5
|
* plugin unloads. `fetch(request)` runs a request in process: Web and Desktop serve it behind HTTP through an adapter, the terminal UI calls
|
|
6
6
|
* it directly, so one handler serves every surface without opening a socket. Disposal refuses new requests, aborts in-flight ones, ends any
|
|
7
7
|
* response body still streaming and waits for all of it to settle.
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { Context, Service } from '@deepseek-ai/cordis'
|
|
11
11
|
import z from '@deepseek-ai/schemastery'
|
|
12
12
|
import type { ConnectionInfo, RouterBindings } from './connection.ts'
|
|
13
|
-
import {
|
|
13
|
+
import { Acryl } from './core/app.ts'
|
|
14
14
|
import type { ExecutionContext } from './core/context.ts'
|
|
15
15
|
import { HTTPException } from './core/http-exception.ts'
|
|
16
16
|
import { TrieRouter } from './core/router/trie-router/index.ts'
|
|
@@ -54,9 +54,9 @@ declare module '@deepseek-ai/cordis' {
|
|
|
54
54
|
/** Stable Cordis plugin name, equal to the package name and the Loader row id. */
|
|
55
55
|
export const name = 'acryl-router'
|
|
56
56
|
|
|
57
|
-
// Any `
|
|
57
|
+
// Any `Acryl`, whatever its Env and schema; the router only reads its routes.
|
|
58
58
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
-
export type MountableApp =
|
|
59
|
+
export type MountableApp = Acryl<any, any, any>
|
|
60
60
|
|
|
61
61
|
interface Mount {
|
|
62
62
|
readonly path: string
|
|
@@ -68,7 +68,7 @@ interface RouterState {
|
|
|
68
68
|
errorHandler: ErrorHandler | undefined
|
|
69
69
|
notFoundHandler: NotFoundHandler | undefined
|
|
70
70
|
/** The app composed from the live mounts; dropped on every change and composed again by the next request. */
|
|
71
|
-
composed:
|
|
71
|
+
composed: Acryl | undefined
|
|
72
72
|
closing: boolean
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -161,8 +161,8 @@ export class Router extends Service {
|
|
|
161
161
|
* mount's code a request is in. The core's `app.route` runs first so a sub-app's own `onError` still applies to its routes.
|
|
162
162
|
*/
|
|
163
163
|
private snapshot(path: string, app: MountableApp): Mount {
|
|
164
|
-
const copy = new
|
|
165
|
-
const tagged = new
|
|
164
|
+
const copy = new Acryl().route('/', app)
|
|
165
|
+
const tagged = new Acryl()
|
|
166
166
|
const mount: Mount = { path, app: tagged }
|
|
167
167
|
for (const route of copy.routes) {
|
|
168
168
|
const inner = route.handler
|
|
@@ -291,12 +291,12 @@ export class Router extends Service {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
private app():
|
|
294
|
+
private app(): Acryl {
|
|
295
295
|
if (this.state.composed !== undefined) return this.state.composed
|
|
296
296
|
// The trie router, because the composed app is rebuilt after every mount change: the default matcher compiles one regular expression
|
|
297
297
|
// over all routes on its first request, which grows faster than the route count (measured: 22 ms at 1000 routes, 163 ms at 2000),
|
|
298
298
|
// while the trie rebuilds in about 1 ms per 1000 routes and matches as fast (scripts/bench-remount.mjs).
|
|
299
|
-
const root = new
|
|
299
|
+
const root = new Acryl({ strict: this.strict, router: new TrieRouter() })
|
|
300
300
|
for (const mount of this.state.mounts) root.route(mount.path, mount.app)
|
|
301
301
|
root.onError(this.state.errorHandler ?? this.logError)
|
|
302
302
|
if (this.state.notFoundHandler !== undefined) root.notFound(this.state.notFoundHandler)
|
|
@@ -6,7 +6,7 @@ import { Context } from '@deepseek-ai/cordis'
|
|
|
6
6
|
import z from '@deepseek-ai/schemastery'
|
|
7
7
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
8
8
|
import { createMiddleware, schemaValidator, testClient } from '../src/helpers/index.ts'
|
|
9
|
-
import {
|
|
9
|
+
import { Acryl, HTTPException, apply, name } from '../src/index.ts'
|
|
10
10
|
import { methodNotAllowed } from '../src/middleware/index.ts'
|
|
11
11
|
|
|
12
12
|
const contexts: Context[] = []
|
|
@@ -30,7 +30,7 @@ describe('getting-started.md', () => {
|
|
|
30
30
|
name: 'todo',
|
|
31
31
|
inject: ['router'],
|
|
32
32
|
apply(inner) {
|
|
33
|
-
const app = new
|
|
33
|
+
const app = new Acryl()
|
|
34
34
|
.get('/', c => c.json({ ok: true }))
|
|
35
35
|
.get('/todos/:id', c => c.json({ id: c.req.param('id') }))
|
|
36
36
|
inner.router.route('/todo', app)
|
|
@@ -45,7 +45,7 @@ describe('getting-started.md', () => {
|
|
|
45
45
|
|
|
46
46
|
describe('routing.md', () => {
|
|
47
47
|
it('serves the routes an app had at the mount, not ones added later', async () => {
|
|
48
|
-
const app = new
|
|
48
|
+
const app = new Acryl().get('/a', c => c.text('a'))
|
|
49
49
|
const ctx = await withPlugin({ name: 'late', inject: ['router'], apply(inner) { inner.router.route('/x', app) } })
|
|
50
50
|
app.get('/b', c => c.text('b'))
|
|
51
51
|
expect((await ctx.router.request('/x/a')).status).toBe(200)
|
|
@@ -53,9 +53,9 @@ describe('routing.md', () => {
|
|
|
53
53
|
})
|
|
54
54
|
|
|
55
55
|
it('answers a wrong method with 404, or 405 and Allow with methodNotAllowed', async () => {
|
|
56
|
-
const plain = new
|
|
56
|
+
const plain = new Acryl().get('/item', c => c.text('item'))
|
|
57
57
|
expect((await plain.request('/item', { method: 'POST' })).status).toBe(404)
|
|
58
|
-
const strict = new
|
|
58
|
+
const strict = new Acryl()
|
|
59
59
|
strict.use(methodNotAllowed({ app: strict })).get('/item', c => c.text('item'))
|
|
60
60
|
const response = await strict.request('/item', { method: 'POST' })
|
|
61
61
|
expect(response.status).toBe(405)
|
|
@@ -69,7 +69,7 @@ describe('routing.md', () => {
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
it('uses a mounted app\'s onError for its routes', async () => {
|
|
72
|
-
const app = new
|
|
72
|
+
const app = new Acryl().get('/boom', () => { throw new Error('boom') })
|
|
73
73
|
app.onError((_error, c) => c.json({ error: 'internal_error' }, 500))
|
|
74
74
|
const ctx = await withPlugin({ name: 'errors', inject: ['router'], apply(inner) { inner.router.route('/', app) } })
|
|
75
75
|
expect(await (await ctx.router.request('/boom')).json()).toEqual({ error: 'internal_error' })
|
|
@@ -82,14 +82,14 @@ describe('context.md and middleware.md', () => {
|
|
|
82
82
|
c.set('user', { name: 'ada' })
|
|
83
83
|
await next()
|
|
84
84
|
})
|
|
85
|
-
const app = new
|
|
85
|
+
const app = new Acryl().use(withUser).get('/me', c => c.json(c.var.user))
|
|
86
86
|
expect(await (await app.request('/me')).json()).toEqual({ name: 'ada' })
|
|
87
87
|
})
|
|
88
88
|
|
|
89
89
|
it('never throws from next(): the error is already a response and is left in c.error', async () => {
|
|
90
90
|
let caught = false
|
|
91
91
|
let seen: unknown
|
|
92
|
-
const app = new
|
|
92
|
+
const app = new Acryl()
|
|
93
93
|
.use(async (c, next) => {
|
|
94
94
|
try {
|
|
95
95
|
await next()
|
|
@@ -105,7 +105,7 @@ describe('context.md and middleware.md', () => {
|
|
|
105
105
|
})
|
|
106
106
|
|
|
107
107
|
it('turns an HTTPException into its own response', async () => {
|
|
108
|
-
const app = new
|
|
108
|
+
const app = new Acryl().get('/', () => { throw new HTTPException(403, { message: 'not yours' }) })
|
|
109
109
|
const response = await app.request('/')
|
|
110
110
|
expect(response.status).toBe(403)
|
|
111
111
|
expect(await response.text()).toBe('not yours')
|
|
@@ -117,7 +117,7 @@ describe('validation.md', () => {
|
|
|
117
117
|
title: z.string().required(),
|
|
118
118
|
done: z.boolean().default(false),
|
|
119
119
|
})
|
|
120
|
-
const app = new
|
|
120
|
+
const app = new Acryl().post('/todos', schemaValidator('json', NewTodo), c => c.json({ todo: c.req.valid('json') }, 201))
|
|
121
121
|
const post = (body: string, type?: string): Promise<Response> =>
|
|
122
122
|
Promise.resolve(app.request('/todos', { method: 'POST', body, headers: type === undefined ? {} : { 'content-type': type } }))
|
|
123
123
|
|
|
@@ -144,7 +144,7 @@ describe('validation.md', () => {
|
|
|
144
144
|
|
|
145
145
|
describe('helpers.md', () => {
|
|
146
146
|
it('calls a chained app through the typed test client', async () => {
|
|
147
|
-
const app = new
|
|
147
|
+
const app = new Acryl().get('/search', c => c.json({ query: c.req.query('q') }))
|
|
148
148
|
const client = testClient(app)
|
|
149
149
|
const response = await client.search.$get({ query: { q: 'cordis' } })
|
|
150
150
|
expect(await response.json()).toEqual({ query: 'cordis' })
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Context, Service } from '@deepseek-ai/cordis'
|
|
9
9
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
10
|
-
import {
|
|
10
|
+
import { Acryl, apply, name } from '../src/index.ts'
|
|
11
11
|
|
|
12
12
|
const contexts: Context[] = []
|
|
13
13
|
const settle = (): Promise<void> => new Promise(resolve => setTimeout(resolve, 0))
|
|
@@ -46,7 +46,7 @@ const extension = (): object => ({
|
|
|
46
46
|
name: 'live-ext',
|
|
47
47
|
inject: ['router'],
|
|
48
48
|
apply(ctx: Context): void {
|
|
49
|
-
ctx.router.route('/', new
|
|
49
|
+
ctx.router.route('/', new Acryl().get('/live', c => c.json({ ok: true })))
|
|
50
50
|
},
|
|
51
51
|
})
|
|
52
52
|
|
|
@@ -11,7 +11,7 @@ import { join } from 'node:path'
|
|
|
11
11
|
import { Context, type FiberState } from '@deepseek-ai/cordis'
|
|
12
12
|
import { Loader } from '@deepseek-ai/cordis-plugin-loader'
|
|
13
13
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
14
|
-
import {
|
|
14
|
+
import { Acryl } from '../src/index.ts'
|
|
15
15
|
|
|
16
16
|
const ACTIVE = 2 as FiberState.ACTIVE
|
|
17
17
|
const DISPOSED = 4 as FiberState.DISPOSED
|
|
@@ -46,7 +46,7 @@ describe('acryl-router through a real Loader', () => {
|
|
|
46
46
|
it('activates from the built entry and serves a request in process', async () => {
|
|
47
47
|
const { ctx, entryId } = await mount()
|
|
48
48
|
expect(entryOf(ctx, entryId).fiber?.state).toBe(ACTIVE)
|
|
49
|
-
ctx.router.route('/', new
|
|
49
|
+
ctx.router.route('/', new Acryl().get('/ping', c => c.json({ ok: true })))
|
|
50
50
|
const response = await ctx.router.fetch(new Request('http://acryl.test/ping'))
|
|
51
51
|
expect(await response.json()).toEqual({ ok: true })
|
|
52
52
|
})
|
|
@@ -66,7 +66,7 @@ describe('acryl-router through a real Loader', () => {
|
|
|
66
66
|
expect(ctx.router).not.toBe(first)
|
|
67
67
|
expect(ctx.router.size).toBe(0)
|
|
68
68
|
expect((await first.fetch(new Request('http://acryl.test/x'))).status).toBe(503)
|
|
69
|
-
ctx.router.route('/', new
|
|
69
|
+
ctx.router.route('/', new Acryl().get('/again', c => c.text('ok')))
|
|
70
70
|
expect(await (await ctx.router.fetch(new Request('http://acryl.test/again'))).text()).toBe('ok')
|
|
71
71
|
})
|
|
72
72
|
})
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { describe, expect, it } from 'vitest'
|
|
7
|
-
import {
|
|
7
|
+
import { Acryl, type ConnectionInfo } from '../src/index.ts'
|
|
8
8
|
import { loopbackOnly, type LoopbackOptions } from '../src/middleware/index.ts'
|
|
9
9
|
|
|
10
10
|
const PORT = 43_120
|
|
11
11
|
const SELF = `http://127.0.0.1:${String(PORT)}`
|
|
12
12
|
const LOCAL: ConnectionInfo = { remoteAddress: '127.0.0.1', localPort: PORT }
|
|
13
13
|
|
|
14
|
-
function guarded(options: LoopbackOptions = {}):
|
|
15
|
-
return new
|
|
14
|
+
function guarded(options: LoopbackOptions = {}): Acryl {
|
|
15
|
+
return new Acryl().use(loopbackOnly(options)).get('/x', c => c.text('read')).post('/x', c => c.text('changed'))
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
async function status(
|
|
19
|
-
app:
|
|
19
|
+
app: Acryl,
|
|
20
20
|
method: string,
|
|
21
21
|
headers: Record<string, string>,
|
|
22
22
|
connection: ConnectionInfo = LOCAL,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Host-only consumer: Node types and no DOM library. Typechecking this against the built `lib/types` proves every public entry point's
|
|
3
|
+
* declarations stand without the DOM library, which a server plugin should not need to load.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type * as Router from '../../src/index.ts'
|
|
7
|
+
import type * as Client from '../../src/client.ts'
|
|
8
|
+
import type * as Helpers from '../../src/helpers/index.ts'
|
|
9
|
+
import type * as Middleware from '../../src/middleware/index.ts'
|
|
10
|
+
|
|
11
|
+
export type Entries = [typeof Router, typeof Client, typeof Helpers, typeof Middleware]
|