acrylblends 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/dist/index.d.ts +6 -1
  2. package/dist/index.js +28 -3
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/acryl-inspect/plugin.json +2 -1
  6. package/plugins/acryl-inspect/src/report.ts +16 -13
  7. package/plugins/acryl-inspect/src/service.ts +9 -7
  8. package/plugins/acryl-inspect/tests/report.spec.ts +7 -8
  9. package/plugins/acryl-inspect/tests/service.spec.ts +11 -10
  10. package/plugins/acryl-inspect/upstream.json +2 -2
  11. package/plugins/acryl-node-server/LICENSE +26 -0
  12. package/plugins/acryl-node-server/plugin.json +2 -1
  13. package/plugins/acryl-node-server/src/adapter/conninfo.ts +23 -0
  14. package/plugins/acryl-node-server/src/adapter/early-hints.ts +55 -0
  15. package/plugins/acryl-node-server/src/adapter/error.ts +11 -0
  16. package/plugins/acryl-node-server/src/adapter/headers.ts +249 -0
  17. package/plugins/acryl-node-server/src/adapter/index.ts +6 -0
  18. package/plugins/acryl-node-server/src/adapter/listener.ts +540 -0
  19. package/plugins/acryl-node-server/src/adapter/request.ts +797 -0
  20. package/plugins/acryl-node-server/src/adapter/response.ts +186 -0
  21. package/plugins/acryl-node-server/src/adapter/serve-static.ts +238 -0
  22. package/plugins/acryl-node-server/src/adapter/server.ts +36 -0
  23. package/plugins/acryl-node-server/src/adapter/types.ts +82 -0
  24. package/plugins/acryl-node-server/src/adapter/url.ts +42 -0
  25. package/plugins/acryl-node-server/src/adapter/utils/response/constants.ts +1 -0
  26. package/plugins/acryl-node-server/src/adapter/utils/response.ts +4 -0
  27. package/plugins/acryl-node-server/src/adapter/utils/stream.ts +88 -0
  28. package/plugins/acryl-node-server/src/adapter/utils.ts +96 -0
  29. package/plugins/acryl-node-server/src/adapter/websocket-types.ts +45 -0
  30. package/plugins/acryl-node-server/src/adapter/websocket.ts +375 -0
  31. package/plugins/acryl-node-server/src/index.ts +19 -6
  32. package/plugins/acryl-node-server/tests/adapter/app.ts +76 -0
  33. package/plugins/acryl-node-server/tests/adapter/assets/.static/plain.txt +1 -0
  34. package/plugins/acryl-node-server/tests/adapter/assets/favicon.ico +0 -0
  35. package/plugins/acryl-node-server/tests/adapter/assets/secret.txt +1 -0
  36. package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +1 -0
  37. package/plugins/acryl-node-server/tests/adapter/assets/static/admin/secret.txt +1 -0
  38. package/plugins/acryl-node-server/tests/adapter/assets/static/data.json +5 -0
  39. package/plugins/acryl-node-server/tests/adapter/assets/static/extensionless +1 -0
  40. package/plugins/acryl-node-server/tests/adapter/assets/static/foo..bar.txt +0 -0
  41. package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +1 -0
  42. package/plugins/acryl-node-server/tests/adapter/assets/static/plain.txt +1 -0
  43. package/plugins/acryl-node-server/tests/adapter/assets/static-with-context-path/plain.txt +1 -0
  44. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin +1 -0
  45. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin.br +1 -0
  46. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt +1 -0
  47. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.br +1 -0
  48. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.zst +1 -0
  49. package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +34 -0
  50. package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +248 -0
  51. package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +457 -0
  52. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-cert.pem +23 -0
  53. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-key.pem +27 -0
  54. package/plugins/acryl-node-server/tests/adapter/headers.test.ts +252 -0
  55. package/plugins/acryl-node-server/tests/adapter/helpers/request.ts +190 -0
  56. package/plugins/acryl-node-server/tests/adapter/listener.test.ts +727 -0
  57. package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +189 -0
  58. package/plugins/acryl-node-server/tests/adapter/request.test.ts +1230 -0
  59. package/plugins/acryl-node-server/tests/adapter/response.test.ts +285 -0
  60. package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +849 -0
  61. package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +790 -0
  62. package/plugins/acryl-node-server/tests/adapter/server.test.ts +1302 -0
  63. package/plugins/acryl-node-server/tests/adapter/setup.ts +16 -0
  64. package/plugins/acryl-node-server/tests/adapter/url.test.ts +76 -0
  65. package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +23 -0
  66. package/plugins/acryl-node-server/tests/adapter/utils/stream.test.ts +75 -0
  67. package/plugins/acryl-node-server/tests/adapter/utils.test.ts +235 -0
  68. package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +260 -0
  69. package/plugins/acryl-node-server/tests/server.spec.ts +44 -8
  70. package/plugins/acryl-node-server/upstream.json +3 -3
  71. package/plugins/acryl-router/LICENSE +26 -0
  72. package/plugins/acryl-router/plugin.json +2 -1
  73. package/plugins/acryl-router/src/client.ts +2 -0
  74. package/plugins/acryl-router/src/connection.ts +42 -0
  75. package/plugins/acryl-router/src/core/app-base.ts +544 -0
  76. package/plugins/acryl-router/src/core/app.test.ts +3833 -0
  77. package/plugins/acryl-router/src/core/app.ts +34 -0
  78. package/plugins/acryl-router/src/core/client/client.test.ts +2313 -0
  79. package/plugins/acryl-router/src/core/client/client.ts +249 -0
  80. package/plugins/acryl-router/src/core/client/fetch-result-please.ts +95 -0
  81. package/plugins/acryl-router/src/core/client/index.ts +17 -0
  82. package/plugins/acryl-router/src/core/client/types.test.ts +149 -0
  83. package/plugins/acryl-router/src/core/client/types.ts +393 -0
  84. package/plugins/acryl-router/src/core/client/utils.test.ts +405 -0
  85. package/plugins/acryl-router/src/core/client/utils.ts +117 -0
  86. package/plugins/acryl-router/src/core/compose.test.ts +751 -0
  87. package/plugins/acryl-router/src/core/compose.ts +73 -0
  88. package/plugins/acryl-router/src/core/context.test.ts +629 -0
  89. package/plugins/acryl-router/src/core/context.ts +781 -0
  90. package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +344 -0
  91. package/plugins/acryl-router/src/core/helper/accepts/accepts.ts +96 -0
  92. package/plugins/acryl-router/src/core/helper/accepts/index.ts +6 -0
  93. package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +55 -0
  94. package/plugins/acryl-router/src/core/helper/adapter/index.ts +90 -0
  95. package/plugins/acryl-router/src/core/helper/conninfo/index.ts +6 -0
  96. package/plugins/acryl-router/src/core/helper/conninfo/types.ts +45 -0
  97. package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +510 -0
  98. package/plugins/acryl-router/src/core/helper/cookie/index.ts +146 -0
  99. package/plugins/acryl-router/src/core/helper/factory/index.test.ts +434 -0
  100. package/plugins/acryl-router/src/core/helper/factory/index.ts +375 -0
  101. package/plugins/acryl-router/src/core/helper/html/index.test.ts +78 -0
  102. package/plugins/acryl-router/src/core/helper/html/index.ts +57 -0
  103. package/plugins/acryl-router/src/core/helper/route/index.test.ts +259 -0
  104. package/plugins/acryl-router/src/core/helper/route/index.ts +144 -0
  105. package/plugins/acryl-router/src/core/helper/streaming/index.ts +9 -0
  106. package/plugins/acryl-router/src/core/helper/streaming/sse.ts +101 -0
  107. package/plugins/acryl-router/src/core/helper/streaming/stream.test.ts +128 -0
  108. package/plugins/acryl-router/src/core/helper/streaming/stream.ts +45 -0
  109. package/plugins/acryl-router/src/core/helper/streaming/text.test.ts +34 -0
  110. package/plugins/acryl-router/src/core/helper/streaming/text.ts +15 -0
  111. package/plugins/acryl-router/src/core/helper/streaming/utils.ts +11 -0
  112. package/plugins/acryl-router/src/core/helper/testing/index.test.ts +42 -0
  113. package/plugins/acryl-router/src/core/helper/testing/index.ts +28 -0
  114. package/plugins/acryl-router/src/core/helper/websocket/index.test.ts +124 -0
  115. package/plugins/acryl-router/src/core/helper/websocket/index.ts +140 -0
  116. package/plugins/acryl-router/src/core/http-exception.test.ts +45 -0
  117. package/plugins/acryl-router/src/core/http-exception.ts +77 -0
  118. package/plugins/acryl-router/src/core/index.ts +53 -0
  119. package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +434 -0
  120. package/plugins/acryl-router/src/core/middleware/basic-auth/index.ts +152 -0
  121. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +1018 -0
  122. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.ts +220 -0
  123. package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +273 -0
  124. package/plugins/acryl-router/src/core/middleware/body-limit/index.ts +110 -0
  125. package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +355 -0
  126. package/plugins/acryl-router/src/core/middleware/combine/index.ts +171 -0
  127. package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +535 -0
  128. package/plugins/acryl-router/src/core/middleware/compress/index.ts +142 -0
  129. package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +43 -0
  130. package/plugins/acryl-router/src/core/middleware/context-storage/index.ts +58 -0
  131. package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +532 -0
  132. package/plugins/acryl-router/src/core/middleware/cors/index.ts +163 -0
  133. package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +534 -0
  134. package/plugins/acryl-router/src/core/middleware/csrf/index.ts +150 -0
  135. package/plugins/acryl-router/src/core/middleware/etag/digest.test.ts +21 -0
  136. package/plugins/acryl-router/src/core/middleware/etag/digest.ts +95 -0
  137. package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +503 -0
  138. package/plugins/acryl-router/src/core/middleware/etag/index.ts +135 -0
  139. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +217 -0
  140. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.ts +278 -0
  141. package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +1135 -0
  142. package/plugins/acryl-router/src/core/middleware/jwk/index.ts +1 -0
  143. package/plugins/acryl-router/src/core/middleware/jwk/jwk.ts +195 -0
  144. package/plugins/acryl-router/src/core/middleware/jwk/keys.test.json +48 -0
  145. package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +802 -0
  146. package/plugins/acryl-router/src/core/middleware/jwt/index.ts +9 -0
  147. package/plugins/acryl-router/src/core/middleware/jwt/jwt.ts +189 -0
  148. package/plugins/acryl-router/src/core/middleware/language/index.test.ts +552 -0
  149. package/plugins/acryl-router/src/core/middleware/language/index.ts +12 -0
  150. package/plugins/acryl-router/src/core/middleware/language/language.ts +314 -0
  151. package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +204 -0
  152. package/plugins/acryl-router/src/core/middleware/logger/index.ts +95 -0
  153. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +292 -0
  154. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.ts +141 -0
  155. package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +221 -0
  156. package/plugins/acryl-router/src/core/middleware/method-override/index.ts +147 -0
  157. package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +37 -0
  158. package/plugins/acryl-router/src/core/middleware/powered-by/index.ts +35 -0
  159. package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +218 -0
  160. package/plugins/acryl-router/src/core/middleware/pretty-json/index.ts +67 -0
  161. package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +168 -0
  162. package/plugins/acryl-router/src/core/middleware/request-id/index.ts +7 -0
  163. package/plugins/acryl-router/src/core/middleware/request-id/request-id.ts +59 -0
  164. package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +671 -0
  165. package/plugins/acryl-router/src/core/middleware/secure-headers/index.ts +8 -0
  166. package/plugins/acryl-router/src/core/middleware/secure-headers/permissions-policy.ts +101 -0
  167. package/plugins/acryl-router/src/core/middleware/secure-headers/secure-headers.ts +340 -0
  168. package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +450 -0
  169. package/plugins/acryl-router/src/core/middleware/serve-static/index.ts +135 -0
  170. package/plugins/acryl-router/src/core/middleware/serve-static/path.test.ts +50 -0
  171. package/plugins/acryl-router/src/core/middleware/serve-static/path.ts +25 -0
  172. package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +70 -0
  173. package/plugins/acryl-router/src/core/middleware/timeout/index.ts +58 -0
  174. package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +310 -0
  175. package/plugins/acryl-router/src/core/middleware/timing/index.ts +8 -0
  176. package/plugins/acryl-router/src/core/middleware/timing/timing.ts +256 -0
  177. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +381 -0
  178. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.ts +156 -0
  179. package/plugins/acryl-router/src/core/request/constants.ts +1 -0
  180. package/plugins/acryl-router/src/core/request.test.ts +751 -0
  181. package/plugins/acryl-router/src/core/request.ts +502 -0
  182. package/plugins/acryl-router/src/core/router/common.case.test.ts +1132 -0
  183. package/plugins/acryl-router/src/core/router/linear-router/index.ts +6 -0
  184. package/plugins/acryl-router/src/core/router/linear-router/router.test.ts +80 -0
  185. package/plugins/acryl-router/src/core/router/linear-router/router.ts +152 -0
  186. package/plugins/acryl-router/src/core/router/pattern-router/index.ts +6 -0
  187. package/plugins/acryl-router/src/core/router/pattern-router/router.test.ts +46 -0
  188. package/plugins/acryl-router/src/core/router/pattern-router/router.ts +54 -0
  189. package/plugins/acryl-router/src/core/router/reg-exp-router/index.ts +7 -0
  190. package/plugins/acryl-router/src/core/router/reg-exp-router/matcher.ts +33 -0
  191. package/plugins/acryl-router/src/core/router/reg-exp-router/node.ts +170 -0
  192. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.test.ts +154 -0
  193. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.ts +165 -0
  194. package/plugins/acryl-router/src/core/router/reg-exp-router/router.test.ts +265 -0
  195. package/plugins/acryl-router/src/core/router/reg-exp-router/router.ts +174 -0
  196. package/plugins/acryl-router/src/core/router/reg-exp-router/trie.ts +84 -0
  197. package/plugins/acryl-router/src/core/router/smart-router/index.ts +6 -0
  198. package/plugins/acryl-router/src/core/router/smart-router/router.test.ts +13 -0
  199. package/plugins/acryl-router/src/core/router/smart-router/router.ts +70 -0
  200. package/plugins/acryl-router/src/core/router/trie-router/index.ts +6 -0
  201. package/plugins/acryl-router/src/core/router/trie-router/node.test.ts +896 -0
  202. package/plugins/acryl-router/src/core/router/trie-router/node.ts +221 -0
  203. package/plugins/acryl-router/src/core/router/trie-router/router.test.ts +8 -0
  204. package/plugins/acryl-router/src/core/router/trie-router/router.ts +18 -0
  205. package/plugins/acryl-router/src/core/router/utils.ts +1 -0
  206. package/plugins/acryl-router/src/core/router.ts +103 -0
  207. package/plugins/acryl-router/src/core/types.test.ts +4134 -0
  208. package/plugins/acryl-router/src/core/types.ts +2782 -0
  209. package/plugins/acryl-router/src/core/utils/accept.test.ts +299 -0
  210. package/plugins/acryl-router/src/core/utils/accept.ts +268 -0
  211. package/plugins/acryl-router/src/core/utils/basic-auth.test.ts +56 -0
  212. package/plugins/acryl-router/src/core/utils/basic-auth.ts +26 -0
  213. package/plugins/acryl-router/src/core/utils/body.test.ts +496 -0
  214. package/plugins/acryl-router/src/core/utils/body.ts +263 -0
  215. package/plugins/acryl-router/src/core/utils/buffer.test.ts +147 -0
  216. package/plugins/acryl-router/src/core/utils/buffer.ts +117 -0
  217. package/plugins/acryl-router/src/core/utils/color.test.ts +23 -0
  218. package/plugins/acryl-router/src/core/utils/color.ts +56 -0
  219. package/plugins/acryl-router/src/core/utils/compress.ts +10 -0
  220. package/plugins/acryl-router/src/core/utils/concurrent.test.ts +69 -0
  221. package/plugins/acryl-router/src/core/utils/concurrent.ts +55 -0
  222. package/plugins/acryl-router/src/core/utils/constants.ts +4 -0
  223. package/plugins/acryl-router/src/core/utils/cookie.test.ts +460 -0
  224. package/plugins/acryl-router/src/core/utils/cookie.ts +281 -0
  225. package/plugins/acryl-router/src/core/utils/crypto.test.ts +43 -0
  226. package/plugins/acryl-router/src/core/utils/crypto.ts +58 -0
  227. package/plugins/acryl-router/src/core/utils/encode.test.ts +61 -0
  228. package/plugins/acryl-router/src/core/utils/encode.ts +34 -0
  229. package/plugins/acryl-router/src/core/utils/filepath.test.ts +78 -0
  230. package/plugins/acryl-router/src/core/utils/filepath.ts +60 -0
  231. package/plugins/acryl-router/src/core/utils/handler.ts +15 -0
  232. package/plugins/acryl-router/src/core/utils/headers.ts +355 -0
  233. package/plugins/acryl-router/src/core/utils/html.test.ts +16 -0
  234. package/plugins/acryl-router/src/core/utils/html.ts +182 -0
  235. package/plugins/acryl-router/src/core/utils/http-status.ts +72 -0
  236. package/plugins/acryl-router/src/core/utils/ipaddr.test.ts +149 -0
  237. package/plugins/acryl-router/src/core/utils/ipaddr.ts +374 -0
  238. package/plugins/acryl-router/src/core/utils/jwt/index.ts +7 -0
  239. package/plugins/acryl-router/src/core/utils/jwt/jwa.test.ts +86 -0
  240. package/plugins/acryl-router/src/core/utils/jwt/jwa.ts +38 -0
  241. package/plugins/acryl-router/src/core/utils/jwt/jws.ts +235 -0
  242. package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +1788 -0
  243. package/plugins/acryl-router/src/core/utils/jwt/jwt.ts +292 -0
  244. package/plugins/acryl-router/src/core/utils/jwt/types.ts +157 -0
  245. package/plugins/acryl-router/src/core/utils/jwt/utf8.ts +7 -0
  246. package/plugins/acryl-router/src/core/utils/mime.test.ts +64 -0
  247. package/plugins/acryl-router/src/core/utils/mime.ts +94 -0
  248. package/plugins/acryl-router/src/core/utils/stream.test.ts +212 -0
  249. package/plugins/acryl-router/src/core/utils/stream.ts +107 -0
  250. package/plugins/acryl-router/src/core/utils/types.test.ts +295 -0
  251. package/plugins/acryl-router/src/core/utils/types.ts +123 -0
  252. package/plugins/acryl-router/src/core/utils/url.test.ts +384 -0
  253. package/plugins/acryl-router/src/core/utils/url.ts +337 -0
  254. package/plugins/acryl-router/src/core/validator/index.ts +8 -0
  255. package/plugins/acryl-router/src/core/validator/utils.test.ts +82 -0
  256. package/plugins/acryl-router/src/core/validator/utils.ts +69 -0
  257. package/plugins/acryl-router/src/core/validator/validator.test.ts +1488 -0
  258. package/plugins/acryl-router/src/core/validator/validator.ts +185 -0
  259. package/plugins/acryl-router/src/helpers/index.ts +13 -3
  260. package/plugins/acryl-router/src/helpers/schema-validator.ts +35 -0
  261. package/plugins/acryl-router/src/index.ts +6 -6
  262. package/plugins/acryl-router/src/middleware/index.ts +25 -6
  263. package/plugins/acryl-router/src/middleware/loopback-only.ts +19 -13
  264. package/plugins/acryl-router/src/service.ts +256 -64
  265. package/plugins/acryl-router/tests/docs-examples.spec.ts +152 -0
  266. package/plugins/acryl-router/tests/live-install.spec.ts +2 -2
  267. package/plugins/acryl-router/tests/loader.spec.ts +3 -2
  268. package/plugins/acryl-router/tests/service.spec.ts +264 -66
  269. package/plugins/acryl-router/tests/shadow-state.spec.ts +79 -0
  270. package/plugins/acryl-router/upstream.json +2 -2
  271. package/plugins/acryl-router-http/plugin.json +2 -1
  272. package/plugins/acryl-router-http/src/bridge.ts +3 -1
  273. package/plugins/acryl-router-http/tests/adapter.spec.ts +16 -12
  274. package/plugins/acryl-router-http/tests/surfaces.spec.ts +12 -10
  275. package/plugins/acryl-router-http/upstream.json +3 -3
  276. package/plugins/acryl-state/NOTICE +30 -0
  277. package/plugins/acryl-state/plugin.json +1 -1
  278. package/plugins/acryl-state/src/cell.ts +1 -1
  279. package/plugins/acryl-state/src/service.ts +33 -15
  280. package/plugins/acryl-state/upstream.json +6 -4
  281. package/plugins/builder/script.ts +4 -7
  282. package/plugins/extensions/index.ts +2 -2
  283. package/plugins/extensions/resolve.ts +28 -3
  284. package/plugins/openai/prompt.ts +9 -7
  285. package/plugins/tsconfig.json +5 -4
  286. package/templates/agent/src/routes.ts +37 -27
  287. package/templates/agent/test/model.test.ts +2 -1
  288. package/templates/agent/tsconfig.json +8 -5
  289. package/templates/blank/src/routes.ts +6 -4
  290. package/templates/blank/tsconfig.json +2 -4
  291. package/templates/todo/src/page.ts +1 -1
  292. package/templates/todo/src/todo.ts +56 -29
  293. package/templates/todo/tsconfig.json +2 -4
  294. package/templates/todo/upstream.json +2 -2
  295. package/plugins/acryl-router/src/compose.ts +0 -21
  296. package/plugins/acryl-router/src/context.ts +0 -59
  297. package/plugins/acryl-router/src/helpers/read-body.ts +0 -59
  298. package/plugins/acryl-router/src/helpers/sse.ts +0 -83
  299. package/plugins/acryl-router/src/helpers/validate.ts +0 -44
  300. package/plugins/acryl-router/src/http-error.ts +0 -21
  301. package/plugins/acryl-router/src/middleware/body-limit.ts +0 -25
  302. package/plugins/acryl-router/src/middleware/cors.ts +0 -46
  303. package/plugins/acryl-router/src/middleware/logger.ts +0 -21
  304. package/plugins/acryl-router/src/middleware/request-id.ts +0 -24
  305. package/plugins/acryl-router/src/middleware/secure-headers.ts +0 -23
  306. package/plugins/acryl-router/src/pattern.ts +0 -89
  307. package/plugins/acryl-router/src/registrar.ts +0 -90
  308. package/plugins/acryl-router/src/table.ts +0 -156
  309. package/plugins/acryl-router/src/types.ts +0 -73
  310. package/plugins/acryl-router/src/util.ts +0 -23
  311. package/plugins/acryl-router/tests/api.spec.ts +0 -223
  312. package/plugins/acryl-router/tests/conformance.ts +0 -170
  313. package/plugins/acryl-router/tests/helpers.spec.ts +0 -172
  314. package/plugins/acryl-router/tests/middleware.spec.ts +0 -183
  315. package/plugins/acryl-router/tests/table.spec.ts +0 -47
@@ -0,0 +1,502 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { HTTPException } from './http-exception.ts'
3
+ import { GET_MATCH_RESULT } from './request/constants.ts'
4
+ import type { Result } from './router.ts'
5
+ import type {
6
+ Input,
7
+ InputToDataByTarget,
8
+ ParamKeyToRecord,
9
+ ParamKeys,
10
+ RemoveQuestion,
11
+ RouterRoute,
12
+ ValidationTargets,
13
+ } from './types.ts'
14
+ import { parseBody } from './utils/body.ts'
15
+ import type { BodyData, ParseBodyOptions } from './utils/body.ts'
16
+ import type { CustomHeader, RequestHeader } from './utils/headers.ts'
17
+ import type { Simplify, UnionToIntersection } from './utils/types.ts'
18
+ import { getQueryParam, getQueryParams, tryDecodeURIComponent } from './utils/url.ts'
19
+
20
+ type Body = {
21
+ json: any
22
+ text: string
23
+ arrayBuffer: ArrayBuffer
24
+ blob: Blob
25
+ formData: FormData
26
+ }
27
+ type BodyCache = Partial<Body>
28
+
29
+ type OptionalRequestInitProperties = 'window' | 'priority'
30
+ type RequiredRequestInit = Required<Omit<RequestInit, OptionalRequestInitProperties>> & {
31
+ [Key in OptionalRequestInitProperties]?: RequestInit[Key]
32
+ }
33
+
34
+ export class AppRequest<P extends string = '/', I extends Input['out'] = {}> {
35
+ /**
36
+ * `.raw` can get the raw Request object.
37
+ *
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * // For Cloudflare Workers
42
+ * app.post('/', async (c) => {
43
+ * const metadata = c.req.raw.cf?.hostMetadata?
44
+ * ...
45
+ * })
46
+ * ```
47
+ */
48
+ raw: Request
49
+
50
+ #validatedData: { [K in keyof ValidationTargets]?: {} } | undefined // Short name of validatedData
51
+ #matchResult: Result<[unknown, RouterRoute]>
52
+ routeIndex: number = 0
53
+ /**
54
+ * `.path` can get the pathname of the request.
55
+ *
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * app.get('/about/me', (c) => {
60
+ * const pathname = c.req.path // `/about/me`
61
+ * })
62
+ * ```
63
+ */
64
+ path: string
65
+ bodyCache: BodyCache = {}
66
+
67
+ constructor(
68
+ request: Request,
69
+ path: string = '/',
70
+ matchResult: Result<[unknown, RouterRoute]> = [[]]
71
+ ) {
72
+ this.raw = request
73
+ this.path = path
74
+ this.#matchResult = matchResult
75
+ }
76
+
77
+ /**
78
+ * `.req.param()` gets the path parameters.
79
+ *
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * const name = c.req.param('name')
84
+ * // or all parameters at once
85
+ * const { id, comment_id } = c.req.param()
86
+ * ```
87
+ */
88
+ param<P2 extends ParamKeys<P> = ParamKeys<P>>(
89
+ key: string extends P ? never : P2 extends `${infer _}?` ? never : P2
90
+ ): string
91
+ param<P2 extends RemoveQuestion<ParamKeys<P>> = RemoveQuestion<ParamKeys<P>>>(
92
+ key: P2
93
+ ): string | undefined
94
+ param(key: string): string | undefined
95
+ param<P2 extends string = P>(): Simplify<UnionToIntersection<ParamKeyToRecord<ParamKeys<P2>>>>
96
+ param(key?: string): unknown {
97
+ return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams()
98
+ }
99
+
100
+ #getDecodedParam(key: string): string | undefined {
101
+ const paramKey = this.#matchResult[0][this.routeIndex]?.[1][key]
102
+ const param = this.#getParamValue(paramKey)
103
+ return param && tryDecodeURIComponent(param)
104
+ }
105
+
106
+ #getAllDecodedParams(): Record<string, string> {
107
+ const decoded: Record<string, string> = {}
108
+
109
+ const keys = Object.keys(this.#matchResult[0][this.routeIndex]?.[1] ?? {})
110
+ for (const key of keys) {
111
+ const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key])
112
+ if (value !== undefined) {
113
+ decoded[key] = tryDecodeURIComponent(value)
114
+ }
115
+ }
116
+
117
+ return decoded
118
+ }
119
+
120
+ #getParamValue(paramKey: any): string | undefined {
121
+ return this.#matchResult[1] ? this.#matchResult[1][paramKey as any] : paramKey
122
+ }
123
+
124
+ /**
125
+ * `.query()` can get querystring parameters.
126
+ *
127
+ *
128
+ * @example
129
+ * ```ts
130
+ * // Query params
131
+ * app.get('/search', (c) => {
132
+ * const query = c.req.query('q')
133
+ * })
134
+ *
135
+ * // Get all params at once
136
+ * app.get('/search', (c) => {
137
+ * const { q, limit, offset } = c.req.query()
138
+ * })
139
+ * ```
140
+ */
141
+ query(key: string): string | undefined
142
+ query(): Record<string, string>
143
+ query(key?: string) {
144
+ return getQueryParam(this.url, key)
145
+ }
146
+
147
+ /**
148
+ * `.queries()` can get multiple querystring parameter values, e.g. /search?tags=A&tags=B
149
+ *
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * app.get('/search', (c) => {
154
+ * // tags will be string[]
155
+ * const tags = c.req.queries('tags')
156
+ * })
157
+ * ```
158
+ */
159
+ queries(key: string): string[] | undefined
160
+ queries(): Record<string, string[]>
161
+ queries(key?: string) {
162
+ return getQueryParams(this.url, key)
163
+ }
164
+
165
+ /**
166
+ * `.header()` can get the request header value.
167
+ *
168
+ *
169
+ * @example
170
+ * ```ts
171
+ * app.get('/', (c) => {
172
+ * const userAgent = c.req.header('User-Agent')
173
+ * })
174
+ * ```
175
+ */
176
+ header(name: RequestHeader): string | undefined
177
+ header(name: string): string | undefined
178
+ header(): Record<RequestHeader | (string & CustomHeader), string>
179
+ header(name?: string) {
180
+ if (name) {
181
+ return this.raw.headers.get(name) ?? undefined
182
+ }
183
+
184
+ const headerData: Record<string, string | undefined> = Object.create(null)
185
+ this.raw.headers.forEach((value, key) => {
186
+ headerData[key] = value
187
+ })
188
+ return headerData
189
+ }
190
+
191
+ /**
192
+ * `.parseBody()` can parse Request body of type `multipart/form-data` or `application/x-www-form-urlencoded`
193
+ *
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * app.post('/entry', async (c) => {
198
+ * const body = await c.req.parseBody()
199
+ * })
200
+ * ```
201
+ */
202
+ async parseBody<Options extends Partial<ParseBodyOptions>, T extends BodyData<Options>>(
203
+ options?: Options
204
+ ): Promise<T>
205
+ async parseBody<T extends BodyData>(options?: Partial<ParseBodyOptions>): Promise<T>
206
+ async parseBody(options?: Partial<ParseBodyOptions>) {
207
+ return parseBody(this, options)
208
+ }
209
+
210
+ #cachedBody = (key: keyof Body) => {
211
+ const { bodyCache, raw } = this
212
+ const cachedBody = bodyCache[key]
213
+
214
+ if (cachedBody) {
215
+ return cachedBody
216
+ }
217
+
218
+ for (const anyCachedKey in bodyCache) {
219
+ return (bodyCache[anyCachedKey as keyof Body] as Promise<BodyInit>).then((body) => {
220
+ if (anyCachedKey === 'json') {
221
+ body = JSON.stringify(body)
222
+ }
223
+ // Rebuilding the body through a bare `Response` loses the request's media
224
+ // type, so a representation that needs it (e.g. `formData()`) can no longer
225
+ // be produced even though the bytes are still available. Carry the original
226
+ // `Content-Type` over, except for `FormData`, where `Response` must generate
227
+ // a fresh multipart boundary of its own.
228
+ const contentType =
229
+ anyCachedKey === 'formData' ? undefined : raw.headers.get('content-type')
230
+ return new Response(body, {
231
+ headers: contentType ? { 'Content-Type': contentType } : undefined,
232
+ })[key]()
233
+ })
234
+ }
235
+
236
+ return (bodyCache[key] = raw[key]())
237
+ }
238
+
239
+ /**
240
+ * `.json()` can parse Request body of type `application/json`
241
+ *
242
+ *
243
+ * @example
244
+ * ```ts
245
+ * app.post('/entry', async (c) => {
246
+ * const body = await c.req.json()
247
+ * })
248
+ * ```
249
+ */
250
+ json<T = any>(): Promise<T> {
251
+ return this.#cachedBody('text').then((text: string) => JSON.parse(text))
252
+ }
253
+
254
+ /**
255
+ * `.text()` can parse Request body of type `text/plain`
256
+ *
257
+ *
258
+ * @example
259
+ * ```ts
260
+ * app.post('/entry', async (c) => {
261
+ * const body = await c.req.text()
262
+ * })
263
+ * ```
264
+ */
265
+ text(): Promise<string> {
266
+ return this.#cachedBody('text')
267
+ }
268
+
269
+ /**
270
+ * `.arrayBuffer()` parse Request body as an `ArrayBuffer`
271
+ *
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * app.post('/entry', async (c) => {
276
+ * const body = await c.req.arrayBuffer()
277
+ * })
278
+ * ```
279
+ */
280
+ arrayBuffer(): Promise<ArrayBuffer> {
281
+ return this.#cachedBody('arrayBuffer')
282
+ }
283
+
284
+ /**
285
+ * `.bytes()` parses the request body as a `Uint8Array`.
286
+ *
287
+ *
288
+ * @example
289
+ * ```ts
290
+ * app.post('/entry', async (c) => {
291
+ * const body = await c.req.bytes()
292
+ * })
293
+ * ```
294
+ */
295
+ bytes(): Promise<Uint8Array> {
296
+ return this.#cachedBody('arrayBuffer').then((buffer: ArrayBuffer) => new Uint8Array(buffer))
297
+ }
298
+
299
+ /**
300
+ * Parses the request body as a `Blob`.
301
+ * @example
302
+ * ```ts
303
+ * app.post('/entry', async (c) => {
304
+ * const body = await c.req.blob();
305
+ * });
306
+ * ```
307
+ */
308
+ blob(): Promise<Blob> {
309
+ return this.#cachedBody('blob')
310
+ }
311
+
312
+ /**
313
+ * Parses the request body as `FormData`.
314
+ * @example
315
+ * ```ts
316
+ * app.post('/entry', async (c) => {
317
+ * const body = await c.req.formData();
318
+ * });
319
+ * ```
320
+ */
321
+ formData(): Promise<FormData> {
322
+ return this.#cachedBody('formData')
323
+ }
324
+
325
+ /**
326
+ * Adds validated data to the request.
327
+ *
328
+ * @param target - The target of the validation.
329
+ * @param data - The validated data to add.
330
+ */
331
+ addValidatedData(target: keyof ValidationTargets, data: {}) {
332
+ ;(this.#validatedData ??= {})[target] = data
333
+ }
334
+
335
+ /**
336
+ * Gets validated data from the request.
337
+ *
338
+ * @param target - The target of the validation.
339
+ * @returns The validated data.
340
+ *
341
+ */
342
+ valid<T extends keyof I & keyof ValidationTargets>(target: T): InputToDataByTarget<I, T>
343
+ valid(target: keyof ValidationTargets) {
344
+ return this.#validatedData?.[target] as unknown
345
+ }
346
+
347
+ /**
348
+ * `.url` can get the request url strings.
349
+ *
350
+ *
351
+ * @example
352
+ * ```ts
353
+ * app.get('/about/me', (c) => {
354
+ * const url = c.req.url // `http://localhost:8787/about/me`
355
+ * ...
356
+ * })
357
+ * ```
358
+ */
359
+ get url(): string {
360
+ return this.raw.url
361
+ }
362
+
363
+ /**
364
+ * `.method` can get the method name of the request.
365
+ *
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * app.get('/about/me', (c) => {
370
+ * const method = c.req.method // `GET`
371
+ * })
372
+ * ```
373
+ */
374
+ get method(): string {
375
+ return this.raw.method
376
+ }
377
+
378
+ get [GET_MATCH_RESULT](): Result<[unknown, RouterRoute]> {
379
+ return this.#matchResult
380
+ }
381
+
382
+ /**
383
+ * `.matchedRoutes` can return a matched route in the handler
384
+ *
385
+ * @deprecated
386
+ *
387
+ * Use matchedRoutes helper defined in "acryl-router/route" instead.
388
+ *
389
+ *
390
+ * @example
391
+ * ```ts
392
+ * app.use('*', async function logger(c, next) {
393
+ * await next()
394
+ * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {
395
+ * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')
396
+ * console.log(
397
+ * method,
398
+ * ' ',
399
+ * path,
400
+ * ' '.repeat(Math.max(10 - path.length, 0)),
401
+ * name,
402
+ * i === c.req.routeIndex ? '<- respond from here' : ''
403
+ * )
404
+ * })
405
+ * })
406
+ * ```
407
+ */
408
+ get matchedRoutes(): RouterRoute[] {
409
+ return this.#matchResult[0].map(([[, route]]) => route)
410
+ }
411
+
412
+ /**
413
+ * `.routePath` can retrieve the path registered within the handler
414
+ *
415
+ * @deprecated
416
+ *
417
+ * Use routePath helper defined in "acryl-router/route" instead.
418
+ *
419
+ *
420
+ * @example
421
+ * ```ts
422
+ * app.get('/posts/:id', (c) => {
423
+ * return c.json({ path: c.req.routePath })
424
+ * })
425
+ * ```
426
+ */
427
+ get routePath(): string {
428
+ return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path
429
+ }
430
+ }
431
+
432
+ /**
433
+ * Clones a AppRequest's underlying raw Request object.
434
+ *
435
+ * This utility handles both consumed and unconsumed request bodies:
436
+ * - If the request body hasn't been consumed, it uses the native `clone()` method
437
+ * - If the request body has been consumed, it reconstructs a new Request using cached body data
438
+ *
439
+ * This is particularly useful when you need to:
440
+ * - Process the same request body multiple times
441
+ * - Pass requests to external services after validation
442
+ *
443
+ * @param req - The AppRequest object to clone
444
+ * @returns A Promise that resolves to a new Request object with the same properties
445
+ * @throws {HTTPException} If the request body was consumed directly via `req.raw`
446
+ * without using AppRequest methods (e.g., `req.json()`, `req.text()`), making it
447
+ * impossible to reconstruct the body from cache
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * // Clone after consuming the body (e.g., after validation)
452
+ * app.post('/forward',
453
+ * validator('json', (data) => data),
454
+ * async (c) => {
455
+ * const validated = c.req.valid('json')
456
+ * // Body has been consumed, but cloneRawRequest still works
457
+ * const clonedReq = await cloneRawRequest(c.req)
458
+ * return fetch('http://backend-service.com', clonedReq)
459
+ * }
460
+ * )
461
+ * ```
462
+ */
463
+ export const cloneRawRequest = async (req: AppRequest): Promise<Request> => {
464
+ if (!req.raw.bodyUsed) {
465
+ return req.raw.clone()
466
+ }
467
+
468
+ const cacheKey = (Object.keys(req.bodyCache) as Array<keyof Body>)[0]
469
+ if (!cacheKey) {
470
+ throw new HTTPException(500, {
471
+ message:
472
+ 'Cannot clone request: body was already consumed and not cached. Please use AppRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly.',
473
+ })
474
+ }
475
+
476
+ let body: BodyInit = await req[cacheKey]()
477
+ const headers = req.header()
478
+ if (cacheKey === 'json') {
479
+ body = JSON.stringify(body)
480
+ delete headers['content-length']
481
+ } else if (body instanceof FormData) {
482
+ delete headers['content-type']
483
+ delete headers['content-length']
484
+ }
485
+
486
+ const requestInit: RequiredRequestInit = {
487
+ body,
488
+ cache: req.raw.cache,
489
+ credentials: req.raw.credentials,
490
+ headers,
491
+ integrity: req.raw.integrity,
492
+ keepalive: req.raw.keepalive,
493
+ method: req.method,
494
+ mode: req.raw.mode,
495
+ redirect: req.raw.redirect,
496
+ referrer: req.raw.referrer,
497
+ referrerPolicy: req.raw.referrerPolicy,
498
+ signal: req.raw.signal,
499
+ }
500
+
501
+ return new Request(req.url, requestInit)
502
+ }