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,185 @@
1
+ import type { Context } from '../context.ts'
2
+ import { getCookie } from '../helper/cookie/index.ts'
3
+ import { HTTPException } from '../http-exception.ts'
4
+ import type { Env, MiddlewareHandler, TypedResponse, ValidationTargets, FormValue } from '../types.ts'
5
+ import type { BodyData } from '../utils/body.ts'
6
+ import { bufferToFormData } from '../utils/buffer.ts'
7
+ import type { InferInput } from './utils.ts'
8
+
9
+ type ValidationTargetKeysWithBody = 'form' | 'json'
10
+ type ValidationTargetByMethod<M> = M extends 'get' | 'head' // GET and HEAD request must not have a body content.
11
+ ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody>
12
+ : keyof ValidationTargets
13
+
14
+ export type ValidationFunction<
15
+ InputType,
16
+ OutputType,
17
+ E extends Env = {},
18
+ P extends string = string,
19
+ > = (
20
+ value: InputType,
21
+ c: Context<E, P>
22
+ ) => OutputType | TypedResponse | Promise<OutputType> | Promise<TypedResponse>
23
+
24
+ const jsonRegex = /^application\/([a-z-\.]+\+)?json(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i
25
+ const multipartRegex = /^multipart\/form-data(;\s?boundary=[a-zA-Z0-9'"()+_,\-./:=?]+)?$/i
26
+ const urlencodedRegex = /^application\/x-www-form-urlencoded(;\s*[a-zA-Z0-9\-]+\=([^;]+))*$/i
27
+
28
+ export type ExtractValidationResponse<VF> = VF extends (value: any, c: any) => infer R
29
+ ? R extends Promise<infer PR>
30
+ ? PR extends TypedResponse<infer T, infer S, infer F>
31
+ ? TypedResponse<T, S, F>
32
+ : PR extends Response
33
+ ? PR
34
+ : PR extends undefined
35
+ ? never // undefined → never
36
+ : never // anything else → never
37
+ : R extends TypedResponse<infer T, infer S, infer F>
38
+ ? TypedResponse<T, S, F>
39
+ : R extends Response
40
+ ? R
41
+ : R extends undefined
42
+ ? never // undefined → never
43
+ : never // anything else → never
44
+ : never // Can't extract → never
45
+
46
+ export const validator = <
47
+ InputType,
48
+ P extends string,
49
+ M extends string,
50
+ U extends ValidationTargetByMethod<M>,
51
+ P2 extends string = P,
52
+ // Capture the actual validation function as a type
53
+ VF extends (
54
+ value: unknown extends InputType ? ValidationTargets[U] : InputType,
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ c: Context<any, P2>
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ ) => any = (
59
+ value: unknown extends InputType ? ValidationTargets[U] : InputType,
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ c: Context<any, P2>
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ ) => any,
64
+ V extends {
65
+ in: {
66
+ [K in U]: K extends 'json'
67
+ ? unknown extends InputType
68
+ ? ExtractValidatorOutput<VF>
69
+ : InputType
70
+ : InferInput<ExtractValidatorOutput<VF>, K, FormValue>
71
+ }
72
+ out: { [K in U]: ExtractValidatorOutput<VF> }
73
+ } = {
74
+ in: {
75
+ [K in U]: K extends 'json'
76
+ ? unknown extends InputType
77
+ ? ExtractValidatorOutput<VF>
78
+ : InputType
79
+ : InferInput<ExtractValidatorOutput<VF>, K, FormValue>
80
+ }
81
+ out: { [K in U]: ExtractValidatorOutput<VF> }
82
+ },
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ E extends Env = any,
85
+ >(
86
+ target: U,
87
+ validationFunc: VF
88
+ ): MiddlewareHandler<E, P, V, ExtractValidationResponse<VF>> => {
89
+ return async (c, next) => {
90
+ let value = {}
91
+ const contentType = c.req.header('Content-Type')
92
+
93
+ switch (target) {
94
+ case 'json':
95
+ if (!contentType || !jsonRegex.test(contentType)) {
96
+ break
97
+ }
98
+ try {
99
+ value = await c.req.json()
100
+ } catch {
101
+ const message = 'Malformed JSON in request body'
102
+ throw new HTTPException(400, { message })
103
+ }
104
+ break
105
+ case 'form': {
106
+ if (
107
+ !contentType ||
108
+ !(multipartRegex.test(contentType) || urlencodedRegex.test(contentType))
109
+ ) {
110
+ break
111
+ }
112
+
113
+ let formData: FormData
114
+
115
+ if (c.req.bodyCache.formData) {
116
+ formData = await c.req.bodyCache.formData
117
+ } else {
118
+ try {
119
+ const arrayBuffer = await c.req.arrayBuffer()
120
+ formData = await bufferToFormData(arrayBuffer, contentType)
121
+ c.req.bodyCache.formData = formData
122
+ } catch (e) {
123
+ let message = 'Malformed FormData request.'
124
+ message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`
125
+ throw new HTTPException(400, { message })
126
+ }
127
+ }
128
+
129
+ const form: BodyData<{ all: true }> = Object.create(null)
130
+ formData.forEach((value, key) => {
131
+ if (key.endsWith('[]')) {
132
+ ;((form[key] ??= []) as unknown[]).push(value)
133
+ } else if (Array.isArray(form[key])) {
134
+ ;(form[key] as unknown[]).push(value)
135
+ } else if (Object.hasOwn(form, key)) {
136
+ form[key] = [form[key] as string | File, value]
137
+ } else {
138
+ form[key] = value
139
+ }
140
+ })
141
+ value = form
142
+ break
143
+ }
144
+ case 'query':
145
+ value = Object.fromEntries(
146
+ Object.entries(c.req.queries()).map(([k, v]) => {
147
+ return v.length === 1 ? [k, v[0]] : [k, v]
148
+ })
149
+ )
150
+ break
151
+ case 'param':
152
+ value = c.req.param() as Record<string, string>
153
+ break
154
+ case 'header':
155
+ value = c.req.header()
156
+ break
157
+ case 'cookie':
158
+ value = getCookie(c)
159
+ break
160
+ }
161
+
162
+ const res = await validationFunc(value as never, c as never)
163
+
164
+ if (res instanceof Response) {
165
+ return res as ExtractValidationResponse<VF>
166
+ }
167
+
168
+ c.req.addValidatedData(target, res as never)
169
+
170
+ return (await next()) as ExtractValidationResponse<VF>
171
+ }
172
+ }
173
+
174
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
+ export type ExtractValidatorOutput<VF> = VF extends (value: any, c: any) => infer R
176
+ ? R extends Promise<infer PR>
177
+ ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
178
+ PR extends Response | TypedResponse<any, any, any>
179
+ ? never
180
+ : PR
181
+ : // eslint-disable-next-line @typescript-eslint/no-explicit-any
182
+ R extends Response | TypedResponse<any, any, any>
183
+ ? never
184
+ : R
185
+ : never
@@ -1,3 +1,13 @@
1
- export { readBytes, readJson, readText, type ReadBodyOptions } from './read-body.ts'
2
- export { streamSSE, type SseOptions, type SseStream } from './sse.ts'
3
- export { valid, validate, type StandardSchema, type ValidationTarget } from './validate.ts'
1
+ export { getConnInfo, connectionOf } from '../connection.ts'
2
+ export type { AddressType, ConnInfo, GetConnInfo, NetAddrInfo } from '../core/helper/conninfo/index.ts'
3
+ export { accepts } from '../core/helper/accepts/index.ts'
4
+ export { createFactory, createMiddleware, Factory } from '../core/helper/factory/index.ts'
5
+ export { deleteCookie, generateCookie, generateSignedCookie, getCookie, getSignedCookie, setCookie, setSignedCookie } from '../core/helper/cookie/index.ts'
6
+ export { getExtension, getMimeType, mimes, type BaseMime } from '../core/utils/mime.ts'
7
+ export { html, raw } from '../core/helper/html/index.ts'
8
+ export { matchedRoutes, routePath, baseRoutePath, basePath } from '../core/helper/route/index.ts'
9
+ export { testClient } from '../core/helper/testing/index.ts'
10
+ export { stream, streamSSE, streamText, SSEStreamingApi, type SSEMessage } from '../core/helper/streaming/index.ts'
11
+ export { validator, type ValidationFunction } from '../core/validator/index.ts'
12
+ export { schemaValidator, type StandardSchema } from './schema-validator.ts'
13
+ export { createWSMessageEvent, defineWebSocketHelper, WSContext, type SendOptions, type UpgradeWebSocket, type WSContextInit, type WSEvents, type WSMessageReceive, type WSReadyState } from '../core/helper/websocket/index.ts'
@@ -0,0 +1,35 @@
1
+ import type { Env, MiddlewareHandler, ValidationTargets } from '../core/types.ts'
2
+ import { validator } from '../core/validator/index.ts'
3
+
4
+ /** The slice of the Standard Schema interface this needs; Schemastery (what Cordis uses), Zod and Valibot all implement it. */
5
+ export interface StandardSchema<T = unknown> {
6
+ readonly '~standard': {
7
+ validate(value: unknown): StandardResult<T> | Promise<StandardResult<T>>
8
+ }
9
+ }
10
+
11
+ type StandardResult<T> =
12
+ | { readonly value: T, readonly issues?: undefined }
13
+ | { readonly issues: readonly { readonly message: string, readonly path?: readonly unknown[] | undefined }[] }
14
+
15
+ const pathOf = (path: readonly unknown[] | undefined): string =>
16
+ (path ?? []).map(part => String(typeof part === 'object' && part !== null && 'key' in part ? (part as { key: unknown }).key : part)).join('.')
17
+
18
+ /**
19
+ * The core `validator` driven by a Standard Schema. A failure answers 400 with `{ error, issues }`; success makes the parsed value the
20
+ * handler's `c.req.valid(target)`, typed by the schema.
21
+ */
22
+ export function schemaValidator<Target extends keyof ValidationTargets, Out, E extends Env = Env, P extends string = string>(
23
+ target: Target,
24
+ schema: StandardSchema<Out>,
25
+ ): MiddlewareHandler<E, P, { in: { [K in Target]: Out }, out: { [K in Target]: Out } }> {
26
+ const middleware = validator(target, async (value, c) => {
27
+ const result = await schema['~standard'].validate(value)
28
+ if (result.issues !== undefined) {
29
+ return c.json({ error: `invalid ${target}`, issues: result.issues.map(issue => ({ message: issue.message, path: pathOf(issue.path) })) }, 400)
30
+ }
31
+ return result.value
32
+ })
33
+ // The core infers its own input and output types from the function; the schema's output type is the one a handler should see.
34
+ return middleware as unknown as MiddlewareHandler<E, P, { in: { [K in Target]: Out }, out: { [K in Target]: Out } }>
35
+ }
@@ -1,6 +1,6 @@
1
- export { Router, Config, apply, name, type RouterHttpService } from './service.ts'
2
- export { RouteTable, type RouteTableOptions } from './table.ts'
3
- export { compose } from './compose.ts'
4
- export { HttpError } from './http-error.ts'
5
- export type { Registrar, RouteHandlers, UseArguments } from './registrar.ts'
6
- export type { ConnectionInfo, ErrorHandler, NotFoundHandler, ResponseBody, Handler, Method, Middleware, Next, RouteContext, RouteMethod, TrailingSlash } from './types.ts'
1
+ export { Router, Config, apply, name, type MountableApp, type RouterHttpService, type TrailingSlash } from './service.ts'
2
+ export { connectionOf, getConnInfo, type ConnectionInfo, type RouterBindings, type RouterEnv } from './connection.ts'
3
+ export { App, Context } from './core/index.ts'
4
+ export type { AppRequest, ContextRenderer, ContextVariableMap, Env, ErrorHandler, ExecutionContext, Handler, Input, MiddlewareHandler, Next, NotFoundHandler, NotFoundResponse, Schema, ToSchema, TypedResponse, ValidationTargets } from './core/index.ts'
5
+ export { HTTPException } from './core/http-exception.ts'
6
+ export type { ContentfulStatusCode, StatusCode } from './core/utils/http-status.ts'
@@ -1,6 +1,25 @@
1
- export { bodyLimit, BODY_LIMIT_KEY, type BodyLimitOptions } from './body-limit.ts'
2
- export { cors, type CorsOptions } from './cors.ts'
3
- export { logger, type LogSink } from './logger.ts'
4
- export { loopbackAuthority, loopbackOnly, sameOrigin, type LoopbackOptions } from './loopback-only.ts'
5
- export { requestId, type RequestIdOptions } from './request-id.ts'
6
- export { secureHeaders, type SecureHeadersOptions } from './secure-headers.ts'
1
+ export { basicAuth } from '../core/middleware/basic-auth/index.ts'
2
+ export { bearerAuth } from '../core/middleware/bearer-auth/index.ts'
3
+ export { bodyLimit } from '../core/middleware/body-limit/index.ts'
4
+ export { every, except, some } from '../core/middleware/combine/index.ts'
5
+ export { compress } from '../core/middleware/compress/index.ts'
6
+ export { contextStorage, getContext, tryGetContext } from '../core/middleware/context-storage/index.ts'
7
+ export { cors } from '../core/middleware/cors/index.ts'
8
+ export { csrf } from '../core/middleware/csrf/index.ts'
9
+ export { etag } from '../core/middleware/etag/index.ts'
10
+ export { jwk } from '../core/middleware/jwk/index.ts'
11
+ export { AlgorithmTypes, decode, jwt, sign, verify, verifyWithJwks, type JwtVariables } from '../core/middleware/jwt/index.ts'
12
+ export { ipRestriction, type IPRestrictionRule, type IPRestrictionRules } from '../core/middleware/ip-restriction/index.ts'
13
+ export { detectFromCookie, detectFromHeader, detectFromPath, detectFromQuery, languageDetector } from '../core/middleware/language/index.ts'
14
+ export { logger } from '../core/middleware/logger/index.ts'
15
+ export { methodNotAllowed } from '../core/middleware/method-not-allowed/index.ts'
16
+ export { methodOverride } from '../core/middleware/method-override/index.ts'
17
+ export { poweredBy } from '../core/middleware/powered-by/index.ts'
18
+ export { prettyJSON } from '../core/middleware/pretty-json/index.ts'
19
+ export { requestId, type RequestIdVariables } from '../core/middleware/request-id/index.ts'
20
+ export { serveStatic, type ServeStaticOptions } from '../core/middleware/serve-static/index.ts'
21
+ export { NONCE, secureHeaders, type SecureHeadersVariables } from '../core/middleware/secure-headers/index.ts'
22
+ export { timeout } from '../core/middleware/timeout/index.ts'
23
+ export { endTime, setMetric, startTime, timing, wrapTime, type TimingVariables } from '../core/middleware/timing/index.ts'
24
+ export { appendTrailingSlash, trimTrailingSlash } from '../core/middleware/trailing-slash/index.ts'
25
+ export { LOOPBACK_HOSTNAMES, loopbackAuthority, loopbackOnly, sameOrigin, type LoopbackOptions } from './loopback-only.ts'
@@ -1,5 +1,7 @@
1
1
  import { BlockList, isIP } from 'node:net'
2
- import type { Middleware, RouteContext } from '../types.ts'
2
+ import { connectionOf } from '../connection.ts'
3
+ import type { Context } from '../core/context.ts'
4
+ import type { MiddlewareHandler } from '../core/types.ts'
3
5
 
4
6
  export interface LoopbackOptions {
5
7
  /** Hostnames a `Host` header may name. Default: the loopback names `127.0.0.1`, `localhost` and `[::1]`. */
@@ -27,15 +29,15 @@ const SAFE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS'])
27
29
 
28
30
  /**
29
31
  * The authority a loopback request addressed: the `Host` header as a URL, or `undefined` when the request does not come from a loopback peer to the
30
- * real local port, names another host, or is marked cross-site by the browser. The peer and the port come from the transport (`c.connection`), never
32
+ * real local port, names another host, or is marked cross-site by the browser. The peer and the port come from the transport (`connectionOf(c)`), never
31
33
  * from a header; an in-process call has neither and is refused.
32
34
  */
33
35
  export const LOOPBACK_HOSTNAMES: readonly string[] = ['127.0.0.1', 'localhost', '[::1]']
34
36
 
35
- export function loopbackAuthority(c: RouteContext, hostnames: readonly string[] = LOOPBACK_HOSTNAMES): URL | undefined {
36
- const { remoteAddress, localPort } = c.connection
37
- const host = c.req.headers.get('host')
38
- if (remoteAddress === undefined || localPort === undefined || host === null) return undefined
37
+ export function loopbackAuthority(c: Context, hostnames: readonly string[] = LOOPBACK_HOSTNAMES): URL | undefined {
38
+ const { remoteAddress, localPort } = connectionOf(c)
39
+ const host = c.req.header('host')
40
+ if (remoteAddress === undefined || localPort === undefined || host === undefined) return undefined
39
41
  const address = (remoteAddress.replace(/^\[|\]$/gu, '').split('%', 1)[0] ?? '').replace(/^::ffff:/iu, '')
40
42
  const family = isIP(address)
41
43
  if (family === 0 || !loopback.check(address, family === 4 ? 'ipv4' : 'ipv6')) return undefined
@@ -49,15 +51,15 @@ export function loopbackAuthority(c: RouteContext, hostnames: readonly string[]
49
51
  authority.protocol !== 'http:'
50
52
  || Number(authority.port || '80') !== localPort
51
53
  || !hostnames.includes(authority.hostname)
52
- || c.req.headers.get('sec-fetch-site') === 'cross-site'
54
+ || c.req.header('sec-fetch-site') === 'cross-site'
53
55
  ) return undefined
54
56
  return authority
55
57
  }
56
58
 
57
59
  /** Whether a changing request is acceptable by its `Origin`: absent (not a browser cross-origin change) or naming this same authority. `null` and any other origin are not. */
58
- export function sameOrigin(c: RouteContext, authority: URL): boolean {
59
- const origin = c.req.headers.get('origin')
60
- if (origin === null) return true
60
+ export function sameOrigin(c: Context, authority: URL): boolean {
61
+ const origin = c.req.header('origin')
62
+ if (origin === undefined) return true
61
63
  try {
62
64
  const parsed = new URL(origin)
63
65
  return parsed.protocol === 'http:' && parsed.host === authority.host && parsed.pathname === '/'
@@ -67,16 +69,20 @@ export function sameOrigin(c: RouteContext, authority: URL): boolean {
67
69
  }
68
70
 
69
71
  /** Only requests from this machine to this app: loopback peer, the real port, an allowed `Host`, and for mutations a matching `Origin`. Everything else gets a 403. */
70
- export function loopbackOnly(options: LoopbackOptions = {}): Middleware {
72
+ export function loopbackOnly(options: LoopbackOptions = {}): MiddlewareHandler {
71
73
  const mutations = options.mutations ?? 'same-origin'
72
74
  const inProcess = options.inProcess ?? 'deny'
73
75
  return async (c, next) => {
74
- if (inProcess === 'allow' && c.connection.remoteAddress === undefined && c.connection.localPort === undefined) return next()
76
+ const connection = connectionOf(c)
77
+ if (inProcess === 'allow' && connection.remoteAddress === undefined && connection.localPort === undefined) {
78
+ await next()
79
+ return
80
+ }
75
81
  const authority = loopbackAuthority(c, options.hostnames)
76
82
  if (authority === undefined) return c.json({ error: 'request authority rejected' }, 403)
77
83
  if (mutations === 'same-origin' && !SAFE_METHODS.has(c.req.method) && !sameOrigin(c, authority)) {
78
84
  return c.json({ error: 'a change must come from this app\'s own origin' }, 403)
79
85
  }
80
- return next()
86
+ await next()
81
87
  }
82
88
  }