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.
Files changed (417) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +325 -0
  3. package/docs/framework/README.md +51 -51
  4. package/docs/framework/UPSTREAM.md +1 -1
  5. package/docs/framework/agents/index.md +24 -0
  6. package/docs/framework/api/acryl.md +259 -0
  7. package/docs/framework/api/context.md +527 -0
  8. package/docs/framework/api/exception.md +80 -0
  9. package/docs/framework/api/index.md +12 -0
  10. package/docs/framework/api/presets.md +65 -0
  11. package/docs/framework/api/request.md +396 -0
  12. package/docs/framework/api/routing.md +303 -0
  13. package/docs/framework/{api-summary.md → api/summary.md} +19 -17
  14. package/docs/framework/concepts/benchmarks.md +26 -0
  15. package/docs/framework/concepts/developer-experience.md +5 -0
  16. package/docs/framework/concepts/middleware.md +21 -0
  17. package/docs/framework/concepts/motivation.md +14 -0
  18. package/docs/framework/concepts/routers.md +63 -0
  19. package/docs/framework/concepts/stacks.md +235 -0
  20. package/docs/framework/concepts/web-standard.md +37 -0
  21. package/docs/framework/{getting-started.md → cordis/acryl-in-a-cordis-app.md} +16 -16
  22. package/docs/framework/{concepts.md → cordis/concepts.md} +2 -2
  23. package/docs/framework/cordis/middleware.md +8 -0
  24. package/docs/framework/{migration-from-0-3.md → cordis/migration-from-0-3.md} +16 -13
  25. package/docs/framework/cordis/migration-from-0-4.md +14 -0
  26. package/docs/framework/{migration-from-dsh-webserver.md → cordis/migration-from-dsh-webserver.md} +13 -7
  27. package/docs/framework/{routing.md → cordis/mounting.md} +5 -108
  28. package/docs/framework/{node-server.md → cordis/node-server.md} +4 -4
  29. package/docs/framework/{surfaces.md → cordis/surfaces.md} +2 -2
  30. package/docs/framework/cordis/transport-and-cancellation.md +57 -0
  31. package/docs/framework/{validation.md → cordis/validation.md} +9 -9
  32. package/docs/framework/getting-started/basic.md +196 -0
  33. package/docs/framework/getting-started/bun.md +221 -0
  34. package/docs/framework/getting-started/nodejs.md +344 -0
  35. package/docs/framework/getting-started/other-runtimes.md +23 -0
  36. package/docs/framework/guides/best-practices.md +231 -0
  37. package/docs/framework/guides/create-acrylblends.md +79 -0
  38. package/docs/framework/guides/examples.md +3 -0
  39. package/docs/framework/guides/faq.md +19 -0
  40. package/docs/framework/guides/helpers.md +33 -0
  41. package/docs/framework/guides/jsx-dom.md +299 -0
  42. package/docs/framework/guides/jsx.md +440 -0
  43. package/docs/framework/guides/middleware.md +253 -0
  44. package/docs/framework/guides/rpc.md +886 -0
  45. package/docs/framework/guides/testing.md +133 -0
  46. package/docs/framework/guides/validation.md +383 -0
  47. package/docs/framework/helpers/accepts.md +60 -0
  48. package/docs/framework/helpers/adapter.md +87 -0
  49. package/docs/framework/helpers/conninfo.md +112 -0
  50. package/docs/framework/helpers/cookie.md +232 -0
  51. package/docs/framework/helpers/css.md +285 -0
  52. package/docs/framework/helpers/dev.md +67 -0
  53. package/docs/framework/helpers/factory.md +180 -0
  54. package/docs/framework/helpers/html.md +123 -0
  55. package/docs/framework/helpers/jwt.md +184 -0
  56. package/docs/framework/helpers/proxy.md +118 -0
  57. package/docs/framework/helpers/route.md +143 -0
  58. package/docs/framework/helpers/ssg.md +393 -0
  59. package/docs/framework/helpers/streaming.md +119 -0
  60. package/docs/framework/helpers/testing.md +101 -0
  61. package/docs/framework/helpers/websocket.md +215 -0
  62. package/docs/framework/middleware/builtin/basic-auth.md +165 -0
  63. package/docs/framework/middleware/builtin/bearer-auth.md +138 -0
  64. package/docs/framework/middleware/builtin/body-limit.md +71 -0
  65. package/docs/framework/middleware/builtin/cache.md +122 -0
  66. package/docs/framework/middleware/builtin/combine.md +94 -0
  67. package/docs/framework/middleware/builtin/compress.md +59 -0
  68. package/docs/framework/middleware/builtin/context-storage.md +78 -0
  69. package/docs/framework/middleware/builtin/cors.md +135 -0
  70. package/docs/framework/middleware/builtin/csrf.md +105 -0
  71. package/docs/framework/middleware/builtin/etag.md +54 -0
  72. package/docs/framework/middleware/builtin/ip-restriction.md +69 -0
  73. package/docs/framework/middleware/builtin/jsx-renderer.md +286 -0
  74. package/docs/framework/middleware/builtin/jwk.md +192 -0
  75. package/docs/framework/middleware/builtin/jwt.md +145 -0
  76. package/docs/framework/middleware/builtin/language.md +232 -0
  77. package/docs/framework/middleware/builtin/logger.md +74 -0
  78. package/docs/framework/middleware/builtin/loopback-only.md +31 -0
  79. package/docs/framework/middleware/builtin/method-not-allowed.md +48 -0
  80. package/docs/framework/middleware/builtin/method-override.md +80 -0
  81. package/docs/framework/middleware/builtin/mount.md +106 -0
  82. package/docs/framework/middleware/builtin/pretty-json.md +53 -0
  83. package/docs/framework/middleware/builtin/request-id.md +94 -0
  84. package/docs/framework/middleware/builtin/secure-headers.md +247 -0
  85. package/docs/framework/middleware/builtin/timeout.md +98 -0
  86. package/docs/framework/middleware/builtin/timing.md +101 -0
  87. package/docs/framework/middleware/builtin/trailing-slash.md +74 -0
  88. package/docs/framework/middleware/third-party.md +4 -0
  89. package/docs/framework/upstream.json +3 -3
  90. package/lib/accepts-XBuZPVRI.js +52 -0
  91. package/lib/accepts.d.ts +33 -0
  92. package/lib/accepts.js +2 -0
  93. package/lib/acryl-base.d.ts +2 -0
  94. package/lib/acryl-base.js +332 -0
  95. package/lib/adapter.d.ts +12 -0
  96. package/lib/adapter.js +37 -0
  97. package/lib/app-BM0rTCp7.js +26 -0
  98. package/lib/app-CmAYW1Al.d.ts +21 -0
  99. package/lib/basic-auth.d.ts +72 -0
  100. package/lib/basic-auth.js +95 -0
  101. package/lib/bearer-auth.d.ts +89 -0
  102. package/lib/bearer-auth.js +94 -0
  103. package/lib/body-limit.d.ts +42 -0
  104. package/lib/body-limit.js +66 -0
  105. package/lib/client-BHTr318g.js +266 -0
  106. package/lib/client.d.ts +3 -0
  107. package/lib/client.js +2 -0
  108. package/lib/combine.d.ts +85 -0
  109. package/lib/combine.js +137 -0
  110. package/lib/compose-BuW2B6PZ.js +50 -0
  111. package/lib/compress.d.ts +38 -0
  112. package/lib/compress.js +79 -0
  113. package/lib/connection-C7xgP1hP.js +24 -0
  114. package/lib/conninfo.d.ts +25 -0
  115. package/lib/conninfo.js +2 -0
  116. package/lib/constants-Dy7ZvN1H.js +4 -0
  117. package/lib/context-Bm7rI-oK.d.ts +1234 -0
  118. package/lib/context-DDO0cfuP.js +365 -0
  119. package/lib/context-storage.d.ts +38 -0
  120. package/lib/context-storage.js +52 -0
  121. package/lib/cookie-ClMaKDQf.d.ts +40 -0
  122. package/lib/cookie.d.ts +24 -0
  123. package/lib/cookie.js +82 -0
  124. package/lib/cors.d.ts +52 -0
  125. package/lib/cors.js +106 -0
  126. package/lib/csrf.d.ts +75 -0
  127. package/lib/csrf.js +101 -0
  128. package/lib/etag.d.ts +40 -0
  129. package/lib/etag.js +135 -0
  130. package/lib/factory.d.ts +35 -0
  131. package/lib/factory.js +30 -0
  132. package/lib/headers-tu2YYN8T.d.ts +11 -0
  133. package/lib/html.d.ts +6 -0
  134. package/lib/html.js +31 -0
  135. package/lib/http-exception.d.ts +57 -0
  136. package/lib/http-exception.js +54 -0
  137. package/lib/http-status-DaAwGAFL.d.ts +35 -0
  138. package/lib/index-B-3F4wt2.d.ts +12 -0
  139. package/lib/index-UTBmM3GX.d.ts +68 -0
  140. package/lib/index-oOClm_Xk.d.ts +45 -0
  141. package/lib/index.d.ts +5 -0
  142. package/lib/index.js +28 -0
  143. package/lib/ip-restriction.d.ts +68 -0
  144. package/lib/ip-restriction.js +166 -0
  145. package/lib/jwk.d.ts +52 -0
  146. package/lib/jwk.js +117 -0
  147. package/lib/jwt-BGJBw5AF.js +403 -0
  148. package/lib/jwt-Dg493Tai.d.ts +51 -0
  149. package/lib/jwt.d.ts +72 -0
  150. package/lib/jwt.js +115 -0
  151. package/lib/language.d.ts +88 -0
  152. package/lib/language.js +198 -0
  153. package/lib/logger.d.ts +22 -0
  154. package/lib/logger.js +54 -0
  155. package/lib/loopback-only.d.ts +45 -0
  156. package/lib/loopback-only.js +90 -0
  157. package/lib/method-not-allowed.d.ts +47 -0
  158. package/lib/method-not-allowed.js +82 -0
  159. package/lib/method-override.d.ts +46 -0
  160. package/lib/method-override.js +103 -0
  161. package/lib/mime-BQOYHl-l.d.ts +72 -0
  162. package/lib/node-server/conninfo.d.ts +11 -0
  163. package/lib/node-server/conninfo.js +19 -0
  164. package/lib/node-server/serve-static.d.ts +19 -0
  165. package/lib/node-server/serve-static.js +2 -0
  166. package/lib/node-server.d.ts +103 -0
  167. package/lib/node-server.js +1325 -0
  168. package/lib/powered-by.d.ts +28 -0
  169. package/lib/powered-by.js +24 -0
  170. package/lib/pretty-json.d.ts +40 -0
  171. package/lib/pretty-json.js +39 -0
  172. package/lib/reg-exp-router-DC1R3qoY.js +363 -0
  173. package/lib/request-id.d.ts +45 -0
  174. package/lib/request-id.js +34 -0
  175. package/lib/request.d.ts +2 -0
  176. package/lib/request.js +323 -0
  177. package/lib/route.d.ts +78 -0
  178. package/lib/route.js +126 -0
  179. package/lib/router/linear-router.d.ts +11 -0
  180. package/lib/router/linear-router.js +96 -0
  181. package/lib/router/pattern-router.d.ts +11 -0
  182. package/lib/router/pattern-router.js +41 -0
  183. package/lib/router/reg-exp-router.d.ts +35 -0
  184. package/lib/router/reg-exp-router.js +2 -0
  185. package/lib/router/smart-router.d.ts +15 -0
  186. package/lib/router/smart-router.js +2 -0
  187. package/lib/router/trie-router.d.ts +11 -0
  188. package/lib/router/trie-router.js +2 -0
  189. package/lib/router-CvUxUTOq.d.ts +99 -0
  190. package/lib/router.d.ts +2 -0
  191. package/lib/router.js +35 -0
  192. package/lib/schema-validator.d.ts +28 -0
  193. package/lib/schema-validator.js +22 -0
  194. package/lib/secure-headers.d.ts +125 -0
  195. package/lib/secure-headers.js +163 -0
  196. package/lib/serve-static-Dw_m6KxR.js +213 -0
  197. package/lib/serve-static.d.ts +31 -0
  198. package/lib/serve-static.js +77 -0
  199. package/lib/smart-router-C5CZ5XSM.js +49 -0
  200. package/lib/stream-CPdqZ0Fp.d.ts +34 -0
  201. package/lib/streaming-DHST3Scg.js +96 -0
  202. package/lib/streaming.d.ts +23 -0
  203. package/lib/streaming.js +2 -0
  204. package/lib/testing.d.ts +10 -0
  205. package/lib/testing.js +17 -0
  206. package/lib/timeout.d.ts +30 -0
  207. package/lib/timeout.js +42 -0
  208. package/lib/timing.d.ts +130 -0
  209. package/lib/timing.js +183 -0
  210. package/lib/trailing-slash.d.ts +91 -0
  211. package/lib/trailing-slash.js +85 -0
  212. package/lib/trie-router-CfFbapzL.js +146 -0
  213. package/lib/types-CDO6I3B0.d.ts +40 -0
  214. package/lib/types-CHesD1KG.d.ts +195 -0
  215. package/lib/types-CwrQjlaM.d.ts +105 -0
  216. package/lib/types-DR95J00T.d.ts +29 -0
  217. package/lib/types.d.ts +2 -0
  218. package/lib/types.js +4 -0
  219. package/lib/utils/accept.d.ts +9 -0
  220. package/lib/utils/accept.js +193 -0
  221. package/lib/utils/basic-auth.d.ts +8 -0
  222. package/lib/utils/basic-auth.js +20 -0
  223. package/lib/utils/body.d.ts +2 -0
  224. package/lib/utils/body.js +94 -0
  225. package/lib/utils/buffer.d.ts +19 -0
  226. package/lib/utils/buffer.js +51 -0
  227. package/lib/utils/color.d.ts +24 -0
  228. package/lib/utils/color.js +37 -0
  229. package/lib/utils/compress.d.ts +11 -0
  230. package/lib/utils/compress.js +11 -0
  231. package/lib/utils/concurrent.d.ts +17 -0
  232. package/lib/utils/concurrent.js +30 -0
  233. package/lib/utils/constants.d.ts +7 -0
  234. package/lib/utils/constants.js +7 -0
  235. package/lib/utils/cookie.d.ts +2 -0
  236. package/lib/utils/cookie.js +125 -0
  237. package/lib/utils/crypto.d.ts +14 -0
  238. package/lib/utils/crypto.js +34 -0
  239. package/lib/utils/encode.d.ts +11 -0
  240. package/lib/utils/encode.js +33 -0
  241. package/lib/utils/filepath.d.ts +14 -0
  242. package/lib/utils/filepath.js +25 -0
  243. package/lib/utils/handler.d.ts +9 -0
  244. package/lib/utils/handler.js +12 -0
  245. package/lib/utils/headers.d.ts +2 -0
  246. package/lib/utils/headers.js +1 -0
  247. package/lib/utils/html.d.ts +46 -0
  248. package/lib/utils/html.js +103 -0
  249. package/lib/utils/http-status.d.ts +2 -0
  250. package/lib/utils/http-status.js +1 -0
  251. package/lib/utils/ipaddr.d.ts +56 -0
  252. package/lib/utils/ipaddr.js +238 -0
  253. package/lib/utils/jwt.d.ts +24 -0
  254. package/lib/utils/jwt.js +2 -0
  255. package/lib/utils/mime.d.ts +2 -0
  256. package/lib/utils/mime.js +77 -0
  257. package/lib/utils/stream.d.ts +2 -0
  258. package/lib/utils/stream.js +88 -0
  259. package/lib/utils/types.d.ts +2 -0
  260. package/lib/utils/types.js +1 -0
  261. package/lib/utils/url.d.ts +46 -0
  262. package/lib/utils/url.js +197 -0
  263. package/lib/utils-dw8lxqjL.js +4 -0
  264. package/lib/validator-D84mq-dO.js +65 -0
  265. package/lib/validator.d.ts +42 -0
  266. package/lib/validator.js +2 -0
  267. package/lib/ws.d.ts +2 -0
  268. package/lib/ws.js +53 -0
  269. package/package.json +312 -14
  270. package/plugins/acryl-inspect/src/service.ts +2 -2
  271. package/plugins/acryl-inspect/tests/service.spec.ts +3 -3
  272. package/plugins/acryl-inspect/upstream.json +2 -2
  273. package/plugins/acryl-node-server/tests/adapter/app.ts +2 -2
  274. package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +1 -1
  275. package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +1 -1
  276. package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +2 -2
  277. package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +4 -4
  278. package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +5 -5
  279. package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +2 -2
  280. package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +20 -20
  281. package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +2 -2
  282. package/plugins/acryl-node-server/tests/adapter/server.test.ts +60 -50
  283. package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +4 -4
  284. package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +9 -9
  285. package/plugins/acryl-node-server/tests/server.spec.ts +6 -6
  286. package/plugins/acryl-node-server/upstream.json +2 -2
  287. package/plugins/acryl-router/src/client.ts +1 -1
  288. package/plugins/acryl-router/src/connection.ts +2 -2
  289. package/plugins/acryl-router/src/core/app-base.ts +29 -29
  290. package/plugins/acryl-router/src/core/app.test.ts +175 -175
  291. package/plugins/acryl-router/src/core/app.ts +8 -8
  292. package/plugins/acryl-router/src/core/client/client.test.ts +76 -76
  293. package/plugins/acryl-router/src/core/client/client.ts +2 -2
  294. package/plugins/acryl-router/src/core/client/fetch-result-please.ts +1 -1
  295. package/plugins/acryl-router/src/core/client/index.ts +1 -1
  296. package/plugins/acryl-router/src/core/client/types.test.ts +6 -6
  297. package/plugins/acryl-router/src/core/client/types.ts +16 -16
  298. package/plugins/acryl-router/src/core/client/utils.test.ts +2 -2
  299. package/plugins/acryl-router/src/core/context.test.ts +4 -4
  300. package/plugins/acryl-router/src/core/context.ts +6 -6
  301. package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +3 -3
  302. package/plugins/acryl-router/src/core/helper/accepts/index.ts +1 -1
  303. package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +6 -6
  304. package/plugins/acryl-router/src/core/helper/adapter/index.ts +1 -1
  305. package/plugins/acryl-router/src/core/helper/conninfo/index.ts +1 -1
  306. package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +8 -8
  307. package/plugins/acryl-router/src/core/helper/cookie/index.ts +1 -1
  308. package/plugins/acryl-router/src/core/helper/factory/index.test.ts +9 -9
  309. package/plugins/acryl-router/src/core/helper/factory/index.ts +10 -10
  310. package/plugins/acryl-router/src/core/helper/html/index.test.ts +4 -4
  311. package/plugins/acryl-router/src/core/helper/html/index.ts +1 -1
  312. package/plugins/acryl-router/src/core/helper/route/index.test.ts +7 -7
  313. package/plugins/acryl-router/src/core/helper/route/index.ts +8 -8
  314. package/plugins/acryl-router/src/core/helper/streaming/index.ts +1 -1
  315. package/plugins/acryl-router/src/core/helper/testing/index.test.ts +6 -6
  316. package/plugins/acryl-router/src/core/helper/testing/index.ts +4 -4
  317. package/plugins/acryl-router/src/core/helper/websocket/index.ts +2 -1
  318. package/plugins/acryl-router/src/core/http-exception.ts +1 -1
  319. package/plugins/acryl-router/src/core/index.ts +9 -9
  320. package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +6 -6
  321. package/plugins/acryl-router/src/core/middleware/basic-auth/index.ts +3 -3
  322. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +5 -5
  323. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.ts +3 -3
  324. package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +6 -6
  325. package/plugins/acryl-router/src/core/middleware/body-limit/index.ts +3 -3
  326. package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +9 -9
  327. package/plugins/acryl-router/src/core/middleware/combine/index.ts +7 -7
  328. package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +9 -9
  329. package/plugins/acryl-router/src/core/middleware/compress/index.ts +3 -3
  330. package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +5 -5
  331. package/plugins/acryl-router/src/core/middleware/context-storage/index.ts +4 -4
  332. package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +7 -7
  333. package/plugins/acryl-router/src/core/middleware/cors/index.ts +3 -3
  334. package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +10 -10
  335. package/plugins/acryl-router/src/core/middleware/csrf/index.ts +3 -3
  336. package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +42 -42
  337. package/plugins/acryl-router/src/core/middleware/etag/index.ts +4 -4
  338. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +4 -4
  339. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.ts +6 -6
  340. package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +16 -16
  341. package/plugins/acryl-router/src/core/middleware/jwk/jwk.ts +7 -6
  342. package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +16 -16
  343. package/plugins/acryl-router/src/core/middleware/jwt/jwt.ts +4 -3
  344. package/plugins/acryl-router/src/core/middleware/language/index.test.ts +3 -3
  345. package/plugins/acryl-router/src/core/middleware/language/language.ts +3 -3
  346. package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +5 -5
  347. package/plugins/acryl-router/src/core/middleware/logger/index.ts +4 -4
  348. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +24 -24
  349. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.ts +8 -8
  350. package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +5 -5
  351. package/plugins/acryl-router/src/core/middleware/method-override/index.ts +6 -6
  352. package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +4 -4
  353. package/plugins/acryl-router/src/core/middleware/powered-by/index.ts +6 -6
  354. package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +30 -30
  355. package/plugins/acryl-router/src/core/middleware/pretty-json/index.ts +4 -4
  356. package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +15 -15
  357. package/plugins/acryl-router/src/core/middleware/request-id/request-id.ts +3 -3
  358. package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +35 -35
  359. package/plugins/acryl-router/src/core/middleware/secure-headers/secure-headers.ts +3 -3
  360. package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +23 -23
  361. package/plugins/acryl-router/src/core/middleware/serve-static/index.ts +1 -1
  362. package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +2 -2
  363. package/plugins/acryl-router/src/core/middleware/timeout/index.ts +3 -3
  364. package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +14 -14
  365. package/plugins/acryl-router/src/core/middleware/timing/timing.ts +3 -3
  366. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +7 -7
  367. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.ts +7 -7
  368. package/plugins/acryl-router/src/core/request.test.ts +42 -42
  369. package/plugins/acryl-router/src/core/request.ts +6 -6
  370. package/plugins/acryl-router/src/core/router/linear-router/index.ts +1 -1
  371. package/plugins/acryl-router/src/core/router/pattern-router/index.ts +1 -1
  372. package/plugins/acryl-router/src/core/router/reg-exp-router/index.ts +1 -1
  373. package/plugins/acryl-router/src/core/router/smart-router/index.ts +1 -1
  374. package/plugins/acryl-router/src/core/router/trie-router/index.ts +1 -1
  375. package/plugins/acryl-router/src/core/types.test.ts +115 -115
  376. package/plugins/acryl-router/src/core/types.ts +72 -72
  377. package/plugins/acryl-router/src/core/utils/body.ts +8 -8
  378. package/plugins/acryl-router/src/core/utils/html.ts +1 -1
  379. package/plugins/acryl-router/src/core/utils/jwt/jws.ts +3 -3
  380. package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +2 -2
  381. package/plugins/acryl-router/src/core/utils/jwt/jwt.ts +3 -3
  382. package/plugins/acryl-router/src/core/utils/jwt/types.ts +1 -1
  383. package/plugins/acryl-router/src/core/utils/types.ts +42 -0
  384. package/plugins/acryl-router/src/core/utils/url.test.ts +2 -2
  385. package/plugins/acryl-router/src/core/validator/index.ts +1 -1
  386. package/plugins/acryl-router/src/core/validator/validator.test.ts +28 -28
  387. package/plugins/acryl-router/src/deprecated.ts +15 -0
  388. package/plugins/acryl-router/src/index.ts +3 -2
  389. package/plugins/acryl-router/src/service.ts +10 -10
  390. package/plugins/acryl-router/tests/docs-examples.spec.ts +11 -11
  391. package/plugins/acryl-router/tests/live-install.spec.ts +2 -2
  392. package/plugins/acryl-router/tests/loader.spec.ts +3 -3
  393. package/plugins/acryl-router/tests/loopback-only.spec.ts +4 -4
  394. package/plugins/acryl-router/tests/no-dom/consumer.ts +11 -0
  395. package/plugins/acryl-router/tests/no-dom/tsconfig.json +13 -0
  396. package/plugins/acryl-router/tests/service.spec.ts +23 -23
  397. package/plugins/acryl-router/upstream.json +3 -3
  398. package/plugins/acryl-router-http/tests/adapter.spec.ts +3 -3
  399. package/plugins/acryl-router-http/tests/surfaces.spec.ts +2 -2
  400. package/plugins/acryl-router-http/upstream.json +2 -2
  401. package/plugins/acryl-state/src/service.ts +2 -2
  402. package/plugins/acryl-state/upstream.json +2 -2
  403. package/plugins/builder/script.ts +2 -2
  404. package/plugins/extensions/resolve.ts +70 -10
  405. package/plugins/openai/prompt.ts +5 -5
  406. package/shared/AGENTS.core.md +16 -9
  407. package/templates/agent/src/routes.ts +2 -2
  408. package/templates/agent/test/model.test.ts +2 -2
  409. package/templates/agent/tsconfig.json +40 -0
  410. package/templates/blank/src/routes.ts +2 -2
  411. package/templates/todo/src/todo.ts +2 -2
  412. package/templates/todo/upstream.json +2 -2
  413. package/docs/framework/context.md +0 -129
  414. package/docs/framework/helpers.md +0 -118
  415. package/docs/framework/middleware.md +0 -154
  416. package/docs/framework/request.md +0 -106
  417. /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.
@@ -1,63 +1,63 @@
1
- # ACRYL Framework
1
+ # Acryl
2
2
 
3
- Status: 0.4.0 (spec 047, `specs/047-framework-port/plan.md`). The application core in `acryl-router` and the Node adapter in
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
- The ACRYL Framework is the small, readable layer on top of Cordis that turns "a bunch of DSH packages" into building an agentic app. You
7
- write an ordinary `App` (routes, a `Context`, middleware with `next()`, validators and helpers on Web-standard `Request` and `Response`),
8
- and a Cordis plugin mounts it with `ctx.router.route(path, app)`.
5
+ ```ts twoslash
6
+ import { Acryl } from 'acrylblends'
7
+ const app = new Acryl()
9
8
 
10
- ## The five rules
9
+ app.get('/', (c) => c.text('Acryl!'))
11
10
 
12
- 1. **Everything extensible is a Cordis plugin.**
13
- 2. **One application, several surfaces** - share capabilities and contracts, not necessarily the transport.
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
- ## What it gives you
14
+ ## Quick Start
19
15
 
20
- One handler, every surface. A plugin writes a handler once; Web and Desktop reach it over HTTP (Desktop's window talks to the app's own
21
- loopback server), the terminal UI and tests call it in process with `ctx.router.request(path)`, and a standalone process serves it with
22
- `acryl-node-server`. The universal entry point is `ctx.router.fetch(request)`.
16
+ ```sh
17
+ npm create acrylblends@latest my-app
18
+ ```
23
19
 
24
- ## Documentation map
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
- | Topic | Page |
27
- | --- | --- |
28
- | First application | [Getting started](./getting-started.md) |
29
- | Every everyday call on one page | [API summary](./api-summary.md) |
30
- | Framework model | [Core concepts](./concepts.md) |
31
- | Routes and mounting | [Routing and mounting](./routing.md) |
32
- | Handler context | [Context](./context.md) |
33
- | Reading requests | [Request](./request.md) |
34
- | Cross-cutting behavior, and the built-in list | [Middleware](./middleware.md) |
35
- | Input checking | [Validation](./validation.md) |
36
- | Streaming, cookies, testing and the rest | [Helpers](./helpers.md) |
37
- | Serving without the ACRYL Host | [Node server](./node-server.md) |
38
- | Cordis ownership and service state | [Plugin lifecycle and disposal](./plugin-lifecycle.md) |
39
- | The application surfaces | [Surfaces and adapters](./surfaces.md) |
40
- | Leaving the DSH server | [Migration from the DSH webServer](./migration-from-dsh-webserver.md) |
41
- | Moving from 0.3 | [Migration from 0.3](./migration-from-0-3.md) |
42
-
43
- [ACRYL Blends](https://acrylblends.github.io/) is the product-facing guide for building and publishing complete applications. The
44
- framework pages here are the API and integration reference behind those guides. The mirrored developer documentation is published at
45
- [acryl.dev/docs](https://acryl.dev/docs).
46
-
47
- ## The packages
48
-
49
- | Package | What it is |
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
- | `acryl-router` | `App` and the whole application API; the Cordis `router` service that composes the mounted apps; `acryl-router/middleware`, `acryl-router/helpers`, `acryl-router/client` |
52
- | `acryl-router-http` | inside the ACRYL Host: `ctx.routerHttp.mount(prefix)` serves a prefix of the router on the Host's web server |
53
- | `acryl-node-server` | without the Host: one `node:http` server for the whole router, `ctx.nodeServer.url`, and `serveStatic` |
54
- | `acryl-state` | observable cells shared by every surface, with read-only HTTP and SSE routes and `useCell` for React |
55
- | `acryl-inspect` | what each plugin requires, provides and mounts, read from the running system |
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
- An app's `tsconfig.json` can extend `acryl-router/tsconfig.app.json` (ES2024 with the DOM types, strict).
57
+ The license of these pages and of the framework source they describe is in [LICENSE](LICENSE).
58
58
 
59
- ## Why this exists
59
+ ## TypeScript in a Cordis app
60
60
 
61
- DSH changes fast and stays one optional agent inside ACRYL. Cordis is the lifecycle ACRYL keeps across Web (browser), Desktop (Electron)
62
- and the terminal UI. HTTP used to go through DSH's `webServer` - a `node:http` route table with no middleware and no Web-standard
63
- `Request`/`Response` - which the terminal UI cannot reuse. The framework removes that coupling.
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 `64e7c9d2e787f74b2da82492644fbbb46a601074`, 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.
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.