acrylblends 0.4.1 → 0.5.1
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/README.md +325 -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} +13 -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 +60 -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
package/LICENSE
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WebBoxes s.r.o.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This package is built from the ACRYL port of Hono v4.13.13 (https://github.com/honojs/hono), used under this license:
|
|
26
|
+
|
|
27
|
+
MIT License
|
|
28
|
+
|
|
29
|
+
Copyright (c) 2021 - present, Yusuke Wada and Hono contributors
|
|
30
|
+
|
|
31
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
32
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
33
|
+
in the Software without restriction, including without limitation the rights
|
|
34
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
35
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
36
|
+
furnished to do so, subject to the following conditions:
|
|
37
|
+
|
|
38
|
+
The above copyright notice and this permission notice shall be included in all
|
|
39
|
+
copies or substantial portions of the Software.
|
|
40
|
+
|
|
41
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
42
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
43
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
44
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
45
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
46
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
47
|
+
SOFTWARE.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
Its node-server entries are built from the ACRYL port of @hono/node-server v2.1.5 (https://github.com/honojs/node-server), used under this license:
|
|
52
|
+
|
|
53
|
+
MIT License
|
|
54
|
+
|
|
55
|
+
Copyright (c) 2022 - present, Yusuke Wada and Hono contributors
|
|
56
|
+
|
|
57
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
58
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
59
|
+
in the Software without restriction, including without limitation the rights
|
|
60
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
61
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
62
|
+
furnished to do so, subject to the following conditions:
|
|
63
|
+
|
|
64
|
+
The above copyright notice and this permission notice shall be included in all
|
|
65
|
+
copies or substantial portions of the Software.
|
|
66
|
+
|
|
67
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
68
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
69
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
70
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
71
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
72
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
73
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/acrylblends/acrylblends/main/docs/assets/acrylblends-logo.png" alt="ACRYLBLENDS" width="120">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">acrylblends</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center"><strong>Acryl, a small web framework on Web Standards, for Node.js.</strong><br>
|
|
8
|
+
One <code>Request</code> in, one <code>Response</code> out: routing, middleware, validation, a typed client and a Node.js server, with no dependencies.</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://github.com/acryldev/acryl/blob/main/docs/framework/README.md">Documentation</a> ·
|
|
12
|
+
<a href="https://github.com/acryldev/acryl/blob/main/docs/framework/getting-started/basic.md">Getting started</a> ·
|
|
13
|
+
<a href="https://github.com/acryldev/acryl/blob/main/docs/framework/api/index.md">API</a> ·
|
|
14
|
+
<a href="https://acrylblends.github.io">acrylblends.github.io</a> ·
|
|
15
|
+
<a href="https://acryl.dev">acryl.dev</a> ·
|
|
16
|
+
<a href="https://github.com/acrylblends/acrylblends">GitHub</a>
|
|
17
|
+
</p>
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { Acryl } from 'acrylblends'
|
|
23
|
+
|
|
24
|
+
const app = new Acryl()
|
|
25
|
+
app.get('/', (c) => c.text('Hello Acryl!'))
|
|
26
|
+
|
|
27
|
+
export default app
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Contents
|
|
31
|
+
|
|
32
|
+
- [Requirements](#requirements)
|
|
33
|
+
- [Quick start](#quick-start)
|
|
34
|
+
- [Start from a template](#start-from-a-template)
|
|
35
|
+
- [A first API](#a-first-api)
|
|
36
|
+
- [Middleware](#middleware)
|
|
37
|
+
- [Validation](#validation)
|
|
38
|
+
- [Typed client](#typed-client)
|
|
39
|
+
- [Testing](#testing)
|
|
40
|
+
- [Serving on Node.js](#serving-on-nodejs)
|
|
41
|
+
- [What is in the package](#what-is-in-the-package)
|
|
42
|
+
- [Upgrading from 0.4](#upgrading-from-04)
|
|
43
|
+
- [The acrylblends command](#the-acrylblends-command)
|
|
44
|
+
- [Links](#links)
|
|
45
|
+
- [License](#license)
|
|
46
|
+
|
|
47
|
+
## Requirements
|
|
48
|
+
|
|
49
|
+
- **Node.js 22.19 or newer.** Node.js is the verified runtime, and it runs `.ts` files directly, so there is no build step.
|
|
50
|
+
- **Bun** runs the same app (`export default app`) and is experimental.
|
|
51
|
+
- `acrylblends` has no dependencies. Its types need only Node's types (`@types/node`), not the DOM library.
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
Create a folder and install the package:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
mkdir my-app && cd my-app
|
|
59
|
+
npm init -y
|
|
60
|
+
npm pkg set type=module
|
|
61
|
+
npm install acrylblends
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Write the app in `index.ts`:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
import { Acryl } from 'acrylblends'
|
|
68
|
+
|
|
69
|
+
const app = new Acryl()
|
|
70
|
+
|
|
71
|
+
app.get('/', (c) => c.text('Hello Acryl!'))
|
|
72
|
+
|
|
73
|
+
export default app
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Serve it on Node.js with the adapter in `server.ts`:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
import { serve } from 'acrylblends/node-server'
|
|
80
|
+
import app from './index.ts'
|
|
81
|
+
|
|
82
|
+
serve({ fetch: app.fetch, port: 3000 }, (info) => {
|
|
83
|
+
console.log(`Listening on http://localhost:${info.port}`)
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Run it and open http://localhost:3000:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
node server.ts
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
For Bun, `bun run index.ts` serves the same `export default app`.
|
|
94
|
+
|
|
95
|
+
## Start from a template
|
|
96
|
+
|
|
97
|
+
`create-acrylblends` creates a ready project with `dev`, `test` and `start` scripts:
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
npm create acrylblends@latest my-app
|
|
101
|
+
cd my-app
|
|
102
|
+
npm install
|
|
103
|
+
npm run dev
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `nodejs` template is a minimal Acryl app. `bun` is the same for Bun (experimental). `acryl-app` is a Cordis app built from plugins,
|
|
107
|
+
with an agent that can extend it while it runs. See the
|
|
108
|
+
[create-acrylblends guide](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/create-acrylblends.md).
|
|
109
|
+
|
|
110
|
+
## A first API
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { Acryl } from 'acrylblends'
|
|
114
|
+
import { HTTPException } from 'acrylblends/http-exception'
|
|
115
|
+
|
|
116
|
+
type Book = { id: string, title: string }
|
|
117
|
+
const books = new Map<string, Book>()
|
|
118
|
+
|
|
119
|
+
const app = new Acryl()
|
|
120
|
+
|
|
121
|
+
app.get('/api/books', (c) => c.json([...books.values()]))
|
|
122
|
+
|
|
123
|
+
app.get('/api/books/:id', (c) => {
|
|
124
|
+
const book = books.get(c.req.param('id'))
|
|
125
|
+
if (book === undefined) throw new HTTPException(404, { message: 'no such book' })
|
|
126
|
+
return c.json(book)
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
app.post('/api/books', async (c) => {
|
|
130
|
+
const { title } = await c.req.json<{ title: string }>()
|
|
131
|
+
const book = { id: crypto.randomUUID(), title }
|
|
132
|
+
books.set(book.id, book)
|
|
133
|
+
return c.json(book, 201)
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
app.notFound((c) => c.json({ error: 'not found' }, 404))
|
|
137
|
+
app.onError((error, c) => error instanceof HTTPException ? error.getResponse() : c.json({ error: 'internal error' }, 500))
|
|
138
|
+
|
|
139
|
+
export default app
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Read more: [Routing](https://github.com/acryldev/acryl/blob/main/docs/framework/api/routing.md),
|
|
143
|
+
[Context](https://github.com/acryldev/acryl/blob/main/docs/framework/api/context.md),
|
|
144
|
+
[Request](https://github.com/acryldev/acryl/blob/main/docs/framework/api/request.md),
|
|
145
|
+
[Exceptions](https://github.com/acryldev/acryl/blob/main/docs/framework/api/exception.md).
|
|
146
|
+
|
|
147
|
+
## Middleware
|
|
148
|
+
|
|
149
|
+
Each built-in middleware has its own subpath:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { Acryl } from 'acrylblends'
|
|
153
|
+
import { cors } from 'acrylblends/cors'
|
|
154
|
+
import { logger } from 'acrylblends/logger'
|
|
155
|
+
import { secureHeaders } from 'acrylblends/secure-headers'
|
|
156
|
+
import { bearerAuth } from 'acrylblends/bearer-auth'
|
|
157
|
+
|
|
158
|
+
const app = new Acryl()
|
|
159
|
+
|
|
160
|
+
app.use(logger())
|
|
161
|
+
app.use(secureHeaders())
|
|
162
|
+
app.use('/api/*', cors())
|
|
163
|
+
app.use('/admin/*', bearerAuth({ token: process.env.ADMIN_TOKEN ?? '' }))
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Built in: `basic-auth`, `bearer-auth`, `body-limit`, `combine`, `compress`, `context-storage`, `cors`, `csrf`, `etag`, `ip-restriction`,
|
|
167
|
+
`jwk`, `jwt`, `language`, `logger`, `method-not-allowed`, `method-override`, `powered-by`, `pretty-json`, `request-id`, `secure-headers`,
|
|
168
|
+
`serve-static`, `timeout`, `timing`, `trailing-slash`, plus ACRYL's `loopback-only`. Each one is documented under
|
|
169
|
+
[Middleware](https://github.com/acryldev/acryl/tree/main/docs/framework/middleware/builtin). To write your own, see the
|
|
170
|
+
[middleware guide](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/middleware.md).
|
|
171
|
+
|
|
172
|
+
## Validation
|
|
173
|
+
|
|
174
|
+
`acrylblends/validator` validates any part of a request: `json`, `form`, `query`, `param`, `header`, `cookie`. The validated value is typed
|
|
175
|
+
in the handler:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { Acryl } from 'acrylblends'
|
|
179
|
+
import { validator } from 'acrylblends/validator'
|
|
180
|
+
|
|
181
|
+
const app = new Acryl()
|
|
182
|
+
|
|
183
|
+
app.post(
|
|
184
|
+
'/api/books',
|
|
185
|
+
validator('json', (value, c) => {
|
|
186
|
+
const title = (value as { title?: unknown }).title
|
|
187
|
+
if (typeof title !== 'string' || title === '') return c.json({ error: 'title is required' }, 400)
|
|
188
|
+
return { title }
|
|
189
|
+
}),
|
|
190
|
+
(c) => c.json({ title: c.req.valid('json').title }, 201),
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`acrylblends/schema-validator` drives the same validator with any [Standard Schema](https://standardschema.dev) library (Zod, Valibot,
|
|
195
|
+
ArkType and others). See the [validation guide](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/validation.md).
|
|
196
|
+
|
|
197
|
+
## Typed client
|
|
198
|
+
|
|
199
|
+
Export the app's type, and `acrylblends/client` calls its routes with typed paths, inputs and answers:
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
// api.ts
|
|
203
|
+
import { Acryl } from 'acrylblends'
|
|
204
|
+
|
|
205
|
+
const app = new Acryl().get('/api/hello', (c) => c.json({ message: 'Hello Acryl!' }))
|
|
206
|
+
export type AppType = typeof app
|
|
207
|
+
export default app
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
// client.ts
|
|
212
|
+
import { hc } from 'acrylblends/client'
|
|
213
|
+
import type { AppType } from './api.ts'
|
|
214
|
+
|
|
215
|
+
const client = hc<AppType>('http://localhost:3000')
|
|
216
|
+
const answer = await client.api.hello.$get()
|
|
217
|
+
console.log((await answer.json()).message)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
See [RPC](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/rpc.md).
|
|
221
|
+
|
|
222
|
+
## Testing
|
|
223
|
+
|
|
224
|
+
`app.request()` answers a request in process, with no server and no port, so tests need nothing else running:
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
import assert from 'node:assert/strict'
|
|
228
|
+
import { test } from 'node:test'
|
|
229
|
+
import app from './index.ts'
|
|
230
|
+
|
|
231
|
+
test('GET / says hello', async () => {
|
|
232
|
+
const response = await app.request('/')
|
|
233
|
+
assert.equal(response.status, 200)
|
|
234
|
+
assert.equal(await response.text(), 'Hello Acryl!')
|
|
235
|
+
})
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Run it with `node --test`. `acrylblends/testing` adds `testClient`, the typed client over `app.request()`. See the
|
|
239
|
+
[testing guide](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/testing.md).
|
|
240
|
+
|
|
241
|
+
## Serving on Node.js
|
|
242
|
+
|
|
243
|
+
`acrylblends/node-server` serves any Acryl app on Node's `http` module (or `http2` and `https` with `createServer`), streams bodies, aborts
|
|
244
|
+
`c.req.raw.signal` when the client goes away, and serves files:
|
|
245
|
+
|
|
246
|
+
```ts
|
|
247
|
+
import { Acryl } from 'acrylblends'
|
|
248
|
+
import { serve } from 'acrylblends/node-server'
|
|
249
|
+
import { serveStatic } from 'acrylblends/node-server/serve-static'
|
|
250
|
+
import { getConnInfo } from 'acrylblends/node-server/conninfo'
|
|
251
|
+
|
|
252
|
+
const app = new Acryl()
|
|
253
|
+
app.use('/static/*', serveStatic({ root: './' }))
|
|
254
|
+
app.get('/ip', (c) => c.text(getConnInfo(c).remote.address ?? 'unknown'))
|
|
255
|
+
|
|
256
|
+
const server = serve({ fetch: app.fetch, port: 3000, hostname: '127.0.0.1' })
|
|
257
|
+
process.on('SIGTERM', () => { server.close() })
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
See [Node.js](https://github.com/acryldev/acryl/blob/main/docs/framework/getting-started/nodejs.md).
|
|
261
|
+
|
|
262
|
+
## What is in the package
|
|
263
|
+
|
|
264
|
+
| Import | What |
|
|
265
|
+
| --- | --- |
|
|
266
|
+
| `acrylblends` | `Acryl`, `Context`, `AcrylRequest`, and the types |
|
|
267
|
+
| `acrylblends/<middleware>` | each built-in middleware, for example `acrylblends/cors` |
|
|
268
|
+
| `acrylblends/validator`, `acrylblends/schema-validator` | request validation |
|
|
269
|
+
| `acrylblends/client`, `acrylblends/testing` | the typed client and its in-process test version |
|
|
270
|
+
| `acrylblends/accepts`, `adapter`, `cookie`, `factory`, `html`, `route`, `streaming`, `ws`, `conninfo` | helpers ([helpers docs](https://github.com/acryldev/acryl/tree/main/docs/framework/helpers)) |
|
|
271
|
+
| `acrylblends/http-exception` | `HTTPException` |
|
|
272
|
+
| `acrylblends/router/*` | the routers: `reg-exp-router`, `smart-router`, `trie-router`, `pattern-router`, `linear-router` ([routers](https://github.com/acryldev/acryl/blob/main/docs/framework/concepts/routers.md)) |
|
|
273
|
+
| `acrylblends/utils/*` | the utilities the framework is built from |
|
|
274
|
+
| `acrylblends/node-server` | `serve`, `createAdaptorServer`, `getRequestListener`; with `node-server/serve-static` and `node-server/conninfo` |
|
|
275
|
+
|
|
276
|
+
Every subpath is listed in the package's `exports`. JSX, SSG, the cache, mount, proxy and dev helpers and other runtimes' adapters are
|
|
277
|
+
being ported. The docs mark them "not yet available" until they ship
|
|
278
|
+
([FAQ](https://github.com/acryldev/acryl/blob/main/docs/framework/guides/faq.md)).
|
|
279
|
+
|
|
280
|
+
To extend the context's typed variables, augment the root module:
|
|
281
|
+
|
|
282
|
+
```ts
|
|
283
|
+
declare module 'acrylblends' {
|
|
284
|
+
interface ContextVariableMap {
|
|
285
|
+
user: string
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Upgrading from 0.4
|
|
291
|
+
|
|
292
|
+
From 0.5 the package's root is the framework. `App` and `AppRequest`, the 0.4 names, still work as deprecated aliases of `Acryl` and
|
|
293
|
+
`AcrylRequest` for one release. The scaffolding API that was the root in 0.4 is now `acrylblends/cli`. See
|
|
294
|
+
[Migration from 0.4](https://github.com/acryldev/acryl/blob/main/docs/framework/cordis/migration-from-0-4.md).
|
|
295
|
+
|
|
296
|
+
## The acrylblends command
|
|
297
|
+
|
|
298
|
+
The package also carries the `acrylblends` command. It scaffolds Cordis apps with ACRYL's plugins as code you own (instance, settings,
|
|
299
|
+
plugins installed while the app runs, an agent that builds plugins, durable tasks, the app as data in `blend.yaml`, a save that refuses
|
|
300
|
+
secrets):
|
|
301
|
+
|
|
302
|
+
```sh
|
|
303
|
+
npx acrylblends init my-app --agent -y
|
|
304
|
+
cd my-app && npm install && npm run dev
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
See the [ACRYLBLENDS documentation](https://github.com/acrylblends/acrylblends/blob/main/docs/README.md) and
|
|
308
|
+
[Acryl in a Cordis app](https://github.com/acryldev/acryl/blob/main/docs/framework/cordis/acryl-in-a-cordis-app.md).
|
|
309
|
+
|
|
310
|
+
## Links
|
|
311
|
+
|
|
312
|
+
| | |
|
|
313
|
+
| --- | --- |
|
|
314
|
+
| Framework documentation | https://github.com/acryldev/acryl/blob/main/docs/framework/README.md |
|
|
315
|
+
| ACRYLBLENDS website | https://acrylblends.github.io |
|
|
316
|
+
| ACRYL website | https://acryl.dev |
|
|
317
|
+
| This package's source and issues | https://github.com/acrylblends/acrylblends ([issues](https://github.com/acrylblends/acrylblends/issues)) |
|
|
318
|
+
| The framework's source | https://github.com/acryldev/acryl (`plugins/acryl-router`, `plugins/acryl-node-server`) |
|
|
319
|
+
| For coding agents | https://github.com/acryldev/acryl/blob/main/docs/framework/agents/index.md |
|
|
320
|
+
| npm | https://www.npmjs.com/package/acrylblends |
|
|
321
|
+
|
|
322
|
+
## License
|
|
323
|
+
|
|
324
|
+
MIT. Copyright (c) 2026 WebBoxes s.r.o. The framework is ported from MIT-licensed open-source projects. Their notices are kept in the
|
|
325
|
+
package's `LICENSE` file.
|
package/docs/framework/README.md
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Acryl
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`acryl-node-server` are ported from a mature MIT web framework with their test suites; the Cordis plugins around them are ACRYL's own.
|
|
3
|
+
Acryl is a small web framework built on Web Standards. You write handlers over the standard `Request` and `Response`, and the same application runs on Node.js (and, experimentally, Bun), and inside a Cordis app as a plugin that an agent can extend while it runs.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
```ts twoslash
|
|
6
|
+
import { Acryl } from 'acrylblends'
|
|
7
|
+
const app = new Acryl()
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
app.get('/', (c) => c.text('Acryl!'))
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
3. **One declared contract per plugin** - what it provides, needs, and registers (routes, commands, tools, slots).
|
|
15
|
-
4. **Every registration is reversible** - unloading a plugin removes what it owns.
|
|
16
|
-
5. **Conventions are explicit and small** - an ordinary feature needs no knowledge of runtime internals.
|
|
11
|
+
export default app
|
|
12
|
+
```
|
|
17
13
|
|
|
18
|
-
##
|
|
14
|
+
## Quick Start
|
|
19
15
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
```sh
|
|
17
|
+
npm create acrylblends@latest my-app
|
|
18
|
+
```
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
Other package managers work the same way: `pnpm create acrylblends@latest`, `yarn create acrylblends`, `bun create acrylblends@latest`.
|
|
21
|
+
The starter asks which template you want (`nodejs`, `bun` (experimental), or `acryl-app`, a Cordis app with an agent). See [Getting started](getting-started/basic.md).
|
|
25
22
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
23
|
+
## What is in the box
|
|
24
|
+
|
|
25
|
+
- **Routing** with several routers behind one API: `RegExpRouter`, `TrieRouter`, `SmartRouter` (the default, which chooses between them), `LinearRouter` and `PatternRouter`.
|
|
26
|
+
See [Routers](concepts/routers.md) and [Routing](api/routing.md).
|
|
27
|
+
- **Web Standards only.** Handlers receive a `Context` over `Request` and return `Response`, with no runtime-specific objects. See [Web Standards](concepts/web-standard.md).
|
|
28
|
+
- **Built-in middleware** for authentication, CORS, CSRF, compression, ETag, logging, request ids, secure headers, timeouts and more.
|
|
29
|
+
See [Built-in middleware](middleware/builtin/basic-auth.md) and [Middleware](concepts/middleware.md).
|
|
30
|
+
- **Helpers** for cookies, streaming and server-sent events, content negotiation, HTML templates, WebSockets and testing. See [Helpers](guides/helpers.md).
|
|
31
|
+
- **Typed routes and a typed client.** Route types flow from the server to `acrylblends/client`. See [RPC](guides/rpc.md).
|
|
32
|
+
- **Validation** with a validator function or any Standard Schema library. See [Validation](guides/validation.md).
|
|
33
|
+
- **A Cordis plugin around it.** A plugin mounts an app with `ctx.router.route`, the mount goes away when the plugin unloads, and a coding agent can write such plugins
|
|
34
|
+
into a running app. See [Acryl in a Cordis app](cordis/acryl-in-a-cordis-app.md) and [Agents](agents/index.md).
|
|
35
|
+
|
|
36
|
+
## Runtimes
|
|
37
|
+
|
|
38
|
+
Verified: Node.js. Bun is experimental. The other runtimes the framework could target are listed on [Other runtimes](getting-started/other-runtimes.md) as not yet verified.
|
|
39
|
+
|
|
40
|
+
## Not yet available
|
|
41
|
+
|
|
42
|
+
Some parts of the documented API surface are not part of the package yet, and their pages say so at the top: the JSX packages, static site generation, the CSS helper, the
|
|
43
|
+
`proxy`, `dev` and `cache` pieces, the `quick` and `tiny` presets and the adapters of the runtimes other than Node.js. They are enabled as they are ported.
|
|
44
|
+
|
|
45
|
+
## Where to read next
|
|
46
|
+
|
|
47
|
+
| I want to | Read |
|
|
50
48
|
| --- | --- |
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
49
|
+
| Run something in five minutes | [Getting started](getting-started/basic.md) |
|
|
50
|
+
| Look up a call | [API](api/index.md), [Routing](api/routing.md), [Context](api/context.md), [Request](api/request.md), [API summary](api/summary.md) |
|
|
51
|
+
| Understand the design | [Concepts](concepts/motivation.md) |
|
|
52
|
+
| Copy a pattern | [Guides](guides/best-practices.md), [Validation](guides/validation.md), [Testing](guides/testing.md) |
|
|
53
|
+
| Use Acryl inside a Cordis app | [Acryl in a Cordis app](cordis/acryl-in-a-cordis-app.md), [Plugin lifecycle](cordis/plugin-lifecycle.md), [Mounting](cordis/mounting.md) |
|
|
54
|
+
| Move from the 0.3 router calls | [Migration from 0.3](cordis/migration-from-0-3.md) |
|
|
55
|
+
| Move from the 0.4 names (`App`) | [Migration from 0.4](cordis/migration-from-0-4.md) |
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
The license of these pages and of the framework source they describe is in [LICENSE](LICENSE).
|
|
58
58
|
|
|
59
|
-
##
|
|
59
|
+
## TypeScript in a Cordis app
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
An app's `tsconfig.json` can extend `acryl-router/tsconfig.app.json` (ES2024 with the DOM types, strict). The DOM types are optional: every
|
|
62
|
+
entry point's types also stand with only `"lib": ["ES2024"]` and `"types": ["node"]`, the setting a Host-only plugin uses so browser globals
|
|
63
|
+
do not typecheck in server code (the router's `tests/no-dom` fixture checks this on every typecheck).
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# Generated copy
|
|
2
2
|
|
|
3
|
-
This folder is a copy of `docs/framework` of acryldev/acryl at commit `
|
|
3
|
+
This folder is a copy of `docs/framework` of acryldev/acryl at commit `5743482e4199ded676a77f594bce15fd4aa0ca2f`, made by `scripts/sync-framework.mjs`. Do not edit it here: change the text in ACRYL and sync again. `pnpm run verify:framework` fails when a page differs from the recorded digest.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Agents
|
|
2
|
+
|
|
3
|
+
A coding agent (Claude Code, Codex, OpenCode, Copilot and others) builds on Acryl best when the documentation is in the folder it works in. A project created with
|
|
4
|
+
`npm create acrylblends@latest` (and one made with `npx acrylblends init`) therefore contains:
|
|
5
|
+
|
|
6
|
+
- `docs/framework/`: these pages. Start at `README.md`; `api/summary.md` is the one-page summary of the API.
|
|
7
|
+
- `AGENTS.md`: where the API is, how a feature is built (an `Acryl` app mounted with `ctx.router.route`, a plugin registered in `src/app.ts` and `blend.yaml`, a state cell),
|
|
8
|
+
the things that surprise people, and what must pass before a task is done (`npm test` and `npm run check`).
|
|
9
|
+
- `CLAUDE.md`: one line, `@AGENTS.md`, so tools that read `CLAUDE.md` read the same guide.
|
|
10
|
+
|
|
11
|
+
## What an agent can do inside a running app
|
|
12
|
+
|
|
13
|
+
The `acryl-app` template (a Cordis app) also lets an agent change the app while it runs:
|
|
14
|
+
|
|
15
|
+
1. The agent writes a plugin into `extensions/<name>/index.ts`. The plugin may import `acrylblends` and the other subpaths by name.
|
|
16
|
+
2. The app installs it as a child plugin, runs its `check(ctx)` with the plugin's own context, and keeps the previous version if the new one fails to start or to pass its check.
|
|
17
|
+
3. A plugin's routes are an `Acryl` app mounted with `ctx.router.route`, so removing the plugin removes its routes.
|
|
18
|
+
|
|
19
|
+
See [Acryl in a Cordis app](../cordis/acryl-in-a-cordis-app.md), [Plugin lifecycle](../cordis/plugin-lifecycle.md) and [Mounting](../cordis/mounting.md).
|
|
20
|
+
|
|
21
|
+
## Checking that an agent can use the docs
|
|
22
|
+
|
|
23
|
+
The repository has a manual gate: it creates a fresh app, starts a headless coding agent inside it with a one-line task (for example "add a /customers/count route with a test"),
|
|
24
|
+
and checks that the app's tests and type-check pass afterwards and that the route answers.
|