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,6 @@
1
+ /**
2
+ * @module
3
+ * LinearRouter for App.
4
+ */
5
+
6
+ export { LinearRouter } from './router.ts'
@@ -0,0 +1,80 @@
1
+ import { UnsupportedPathError } from '../../router.ts'
2
+ import { runTest } from '../common.case.test.ts'
3
+ import { LinearRouter } from './router.ts'
4
+
5
+ describe('LinearRouter', () => {
6
+ runTest({
7
+ skip: [
8
+ {
9
+ reason: 'UnsupportedPath',
10
+ tests: [
11
+ 'Multi match > `params` per a handler > GET /entry/123/show',
12
+ 'Capture regex pattern has trailing wildcard > GET /foo/bar/file.html',
13
+ 'Capture regex param with trailing wildcard on empty remainder > GET /123',
14
+ 'Capture regex param with trailing wildcard and sibling route > GET /regex-abc/123/ghi',
15
+ 'Trailing wildcard after a label > GET /abc',
16
+ 'Trailing wildcard after a label > GET /abc/sub',
17
+ 'Trailing wildcard after a pattern label > GET /abc',
18
+ 'Trailing wildcard after a pattern label > GET /reverse/abc in reverse registration order',
19
+ 'Trailing wildcard after a pattern label > POST /all/abc with ALL middleware',
20
+ 'Trailing wildcard after a pattern label > GET /posts/2024/comments with nested braces',
21
+ 'Trailing wildcard after a pattern label > GET /files/foo/detail with regexp meta characters',
22
+ 'Trailing wildcard after a pattern label > GET /user/123/profile with the default pattern',
23
+ 'Trailing wildcard after a pattern label > GET /user/123/profile with the default pattern in reverse registration order',
24
+ 'Complex > Parameter with {.*} regexp',
25
+ ],
26
+ },
27
+ {
28
+ reason: 'LinearRouter allows trailing slashes',
29
+ tests: ['Trailing slash > GET /book/'],
30
+ },
31
+ ],
32
+ newRouter: () => new LinearRouter(),
33
+ })
34
+
35
+ describe('Multi match', () => {
36
+ describe('`params` per a handler', () => {
37
+ const router = new LinearRouter<string>()
38
+
39
+ beforeEach(() => {
40
+ router.add('ALL', '*', 'middleware a')
41
+ router.add('GET', '/entry/:id/*', 'middleware b')
42
+ router.add('GET', '/entry/:id/:action', 'action')
43
+ })
44
+
45
+ it('GET /entry/123/show', () => {
46
+ expect(() => {
47
+ router.match('GET', '/entry/123/show')
48
+ }).toThrowError(UnsupportedPathError)
49
+ })
50
+ })
51
+ })
52
+
53
+ describe('Trailing slash', () => {
54
+ const router = new LinearRouter<string>()
55
+
56
+ beforeEach(() => {
57
+ router.add('GET', '/book', 'GET /book')
58
+ router.add('GET', '/book/:id', 'GET /book/:id')
59
+ })
60
+
61
+ it('GET /book/', () => {
62
+ const [res] = router.match('GET', '/book/')
63
+ expect(res.length).toBe(1)
64
+ expect(res[0][0]).toBe('GET /book')
65
+ })
66
+ })
67
+
68
+ describe('Skip part', () => {
69
+ const router = new LinearRouter<string>()
70
+
71
+ beforeEach(() => {
72
+ router.add('GET', '/products/:id{d+}', 'GET /products/:id{d+}')
73
+ })
74
+
75
+ it('GET /products/list', () => {
76
+ const [res] = router.match('GET', '/products/list')
77
+ expect(res.length).toBe(0)
78
+ })
79
+ })
80
+ })
@@ -0,0 +1,152 @@
1
+ import type { Params, Result, Router } from '../../router.ts'
2
+ import { METHOD_NAME_ALL, UnsupportedPathError } from '../../router.ts'
3
+ import { checkOptionalParameter } from '../../utils/url.ts'
4
+
5
+ type RegExpMatchArrayWithIndices = RegExpMatchArray & { indices: [number, number][] }
6
+
7
+ const emptyParams = Object.create(null)
8
+
9
+ const splitPathRe = /\/(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/[^\/\?]+|(\?)/g
10
+ const splitByStarRe = /\*/
11
+ export class LinearRouter<T> implements Router<T> {
12
+ name: string = 'LinearRouter'
13
+ #routes: [string, string, T][] = []
14
+
15
+ add(method: string, path: string, handler: T) {
16
+ for (
17
+ let i = 0, paths = checkOptionalParameter(path) || [path], len = paths.length;
18
+ i < len;
19
+ i++
20
+ ) {
21
+ this.#routes.push([method, paths[i], handler])
22
+ }
23
+ }
24
+
25
+ match(method: string, path: string): Result<T> {
26
+ const handlers: [T, Params][] = []
27
+ ROUTES_LOOP: for (let i = 0, len = this.#routes.length; i < len; i++) {
28
+ const [routeMethod, routePath, handler] = this.#routes[i]
29
+ if (routeMethod === method || routeMethod === METHOD_NAME_ALL) {
30
+ if (routePath === '*' || routePath === '/*') {
31
+ handlers.push([handler, emptyParams])
32
+ continue
33
+ }
34
+
35
+ const hasStar = routePath.indexOf('*') !== -1
36
+ const hasLabel = routePath.indexOf(':') !== -1
37
+ if (!hasStar && !hasLabel) {
38
+ if (routePath === path || routePath + '/' === path) {
39
+ handlers.push([handler, emptyParams])
40
+ }
41
+ } else if (hasStar && !hasLabel) {
42
+ const endsWithStar = routePath.charCodeAt(routePath.length - 1) === 42
43
+ const endsWithSlashStar = routePath.endsWith('/*')
44
+ const parts = (
45
+ endsWithStar ? routePath.slice(0, endsWithSlashStar ? -2 : -1) : routePath
46
+ ).split(splitByStarRe)
47
+
48
+ const lastIndex = parts.length - 1
49
+ for (let j = 0, pos = 0, len = parts.length; j < len; j++) {
50
+ const part = parts[j]
51
+ const index = path.indexOf(part, pos)
52
+ if (index !== pos) {
53
+ continue ROUTES_LOOP
54
+ }
55
+ pos += part.length
56
+ if (j === lastIndex) {
57
+ if (endsWithSlashStar) {
58
+ if (pos !== path.length && path.charCodeAt(pos) !== 47) {
59
+ continue ROUTES_LOOP
60
+ }
61
+ } else if (
62
+ !endsWithStar &&
63
+ pos !== path.length &&
64
+ !(pos === path.length - 1 && path.charCodeAt(pos) === 47)
65
+ ) {
66
+ continue ROUTES_LOOP
67
+ }
68
+ } else {
69
+ const index = path.indexOf('/', pos)
70
+ if (index === -1) {
71
+ continue ROUTES_LOOP
72
+ }
73
+ pos = index
74
+ }
75
+ }
76
+ handlers.push([handler, emptyParams])
77
+ } else if (hasLabel && !hasStar) {
78
+ const params: Record<string, string> = Object.create(null)
79
+ const parts = routePath.match(splitPathRe) as string[]
80
+
81
+ const lastIndex = parts.length - 1
82
+ for (let j = 0, pos = 0, len = parts.length; j < len; j++) {
83
+ if (pos === -1 || pos >= path.length) {
84
+ continue ROUTES_LOOP
85
+ }
86
+
87
+ const part = parts[j]
88
+ if (part.charCodeAt(1) === 58) {
89
+ if (path.charCodeAt(pos) !== 47) {
90
+ continue ROUTES_LOOP
91
+ }
92
+
93
+ // /:label
94
+ let name = part.slice(2)
95
+ let value
96
+
97
+ if (name.charCodeAt(name.length - 1) === 125) {
98
+ // :label{pattern}
99
+ const openBracePos = name.indexOf('{')
100
+ const next = parts[j + 1]
101
+ const lookahead = next && next[1] !== ':' && next[1] !== '*' ? `(?=${next})` : ''
102
+ const pattern = name.slice(openBracePos + 1, -1) + lookahead
103
+ const restPath = path.slice(pos + 1)
104
+ const match = new RegExp(pattern, 'd').exec(restPath) as RegExpMatchArrayWithIndices
105
+ if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
106
+ continue ROUTES_LOOP
107
+ }
108
+ name = name.slice(0, openBracePos)
109
+ value = restPath.slice(...match.indices[0])
110
+ pos += match.indices[0][1] + 1
111
+ } else {
112
+ let endValuePos = path.indexOf('/', pos + 1)
113
+ if (endValuePos === -1) {
114
+ endValuePos = path.length
115
+ }
116
+ if (endValuePos === pos + 1) {
117
+ // an empty segment, as in `/u/` or `/u//posts`
118
+ continue ROUTES_LOOP
119
+ }
120
+ value = path.slice(pos + 1, endValuePos)
121
+ pos = endValuePos
122
+ }
123
+
124
+ params[name] ||= value as string
125
+ } else {
126
+ const index = path.indexOf(part, pos)
127
+ if (index !== pos) {
128
+ continue ROUTES_LOOP
129
+ }
130
+ pos += part.length
131
+ }
132
+
133
+ if (j === lastIndex) {
134
+ if (
135
+ pos !== path.length &&
136
+ !(pos === path.length - 1 && path.charCodeAt(pos) === 47)
137
+ ) {
138
+ continue ROUTES_LOOP
139
+ }
140
+ }
141
+ }
142
+
143
+ handlers.push([handler, params])
144
+ } else if (hasLabel && hasStar) {
145
+ throw new UnsupportedPathError()
146
+ }
147
+ }
148
+ }
149
+
150
+ return [handlers]
151
+ }
152
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @module
3
+ * PatternRouter for App.
4
+ */
5
+
6
+ export { PatternRouter } from './router.ts'
@@ -0,0 +1,46 @@
1
+ import { UnsupportedPathError } from '../../router.ts'
2
+ import { runTest } from '../common.case.test.ts'
3
+ import { PatternRouter } from './router.ts'
4
+
5
+ describe('Pattern', () => {
6
+ runTest({
7
+ skip: [
8
+ {
9
+ reason: 'UnsupportedPath',
10
+ tests: [
11
+ 'Duplicate param name > self',
12
+ 'Duplicate param name > self with trailing static',
13
+ 'Duplicate param name > self three times',
14
+ ],
15
+ },
16
+ {
17
+ reason: 'PatternRouter allows trailing slashes',
18
+ tests: ['Trailing slash > GET /book/'],
19
+ },
20
+ ],
21
+ newRouter: () => new PatternRouter(),
22
+ })
23
+
24
+ describe('Duplicate param name', () => {
25
+ it('self', () => {
26
+ const router = new PatternRouter<string>()
27
+ expect(() => {
28
+ router.add('GET', '/:id/:id', 'foo')
29
+ }).toThrowError(UnsupportedPathError)
30
+ })
31
+ })
32
+ describe('Trailing slash', () => {
33
+ const router = new PatternRouter<string>()
34
+
35
+ beforeEach(() => {
36
+ router.add('GET', '/book', 'GET /book')
37
+ router.add('GET', '/book/:id', 'GET /book/:id')
38
+ })
39
+
40
+ it('GET /book/', () => {
41
+ const [res] = router.match('GET', '/book/')
42
+ expect(res.length).toBe(1)
43
+ expect(res[0][0]).toBe('GET /book')
44
+ })
45
+ })
46
+ })
@@ -0,0 +1,54 @@
1
+ import type { Params, Result, Router } from '../../router.ts'
2
+ import { METHOD_NAME_ALL, UnsupportedPathError } from '../../router.ts'
3
+
4
+ type Route<T> = [RegExp, string, T] // [pattern, method, handler]
5
+
6
+ const emptyParams = Object.create(null)
7
+
8
+ export class PatternRouter<T> implements Router<T> {
9
+ name: string = 'PatternRouter'
10
+ #routes: Route<T>[] = []
11
+
12
+ add(method: string, path: string, handler: T) {
13
+ const suffix = path.endsWith('/*') ? '(?:$|/)' : path.endsWith('*') ? '' : '/?$'
14
+ path = path.replace(/\*$/, '')
15
+ if (path.at(-1) === '?') {
16
+ path = path.slice(0, -1)
17
+ this.add(method, path.replace(/\/[^/]+$/, ''), handler)
18
+ }
19
+
20
+ const parts = (path.match(/\/?(:\w+(?:{(?:(?:{[\d,]+})|[^}])+})?)|\/?[^\/\?]+/g) || []).map(
21
+ (part) => {
22
+ const match = part.match(/^\/:([^{]+)(?:{(.*)})?/)
23
+ return match
24
+ ? `/(?<${match[1]}>${match[2] || '[^/]+'})`
25
+ : part === '/*'
26
+ ? '/[^/]+'
27
+ : part.replace(/[.\\+*[^\]$()]/g, '\\$&')
28
+ }
29
+ )
30
+
31
+ try {
32
+ this.#routes.push([new RegExp(`^${parts.join('')}${suffix}`), method, handler])
33
+ } catch {
34
+ throw new UnsupportedPathError()
35
+ }
36
+ }
37
+
38
+ match(method: string, path: string): Result<T> {
39
+ const handlers: [T, Params][] = []
40
+
41
+ for (let i = 0, len = this.#routes.length; i < len; i++) {
42
+ const [pattern, routeMethod, handler] = this.#routes[i]
43
+
44
+ if (routeMethod === method || routeMethod === METHOD_NAME_ALL) {
45
+ const match = pattern.exec(path)
46
+ if (match) {
47
+ handlers.push([handler, match.groups || emptyParams])
48
+ }
49
+ }
50
+ }
51
+
52
+ return [handlers]
53
+ }
54
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @module
3
+ * RegExpRouter for App.
4
+ */
5
+
6
+ export { RegExpRouter } from './router.ts'
7
+ export { PreparedRegExpRouter, buildInitParams, serializeInitParams } from './prepared-router.ts'
@@ -0,0 +1,33 @@
1
+ import type { ParamIndexMap, Result, Router } from '../../router.ts'
2
+ import { METHOD_NAME_ALL } from '../../router.ts'
3
+
4
+ export type HandlerData<T> = [T, ParamIndexMap][]
5
+ export type StaticMap<T> = Record<string, Result<T>>
6
+ export type Matcher<T> = [RegExp, HandlerData<T>[], StaticMap<T>]
7
+ export type MatcherMap<T> = Record<string, Matcher<T> | null>
8
+
9
+ export const emptyParam: string[] = []
10
+ export function match<R extends Router<T>, T>(this: R, method: string, path: string): Result<T> {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ const matchers: MatcherMap<T> = (this as any).buildAllMatchers()
13
+
14
+ const match = ((method, path) => {
15
+ const matcher = (matchers[method] || matchers[METHOD_NAME_ALL]) as Matcher<T>
16
+
17
+ const staticMatch = matcher[2][path]
18
+ if (staticMatch) {
19
+ return staticMatch
20
+ }
21
+
22
+ const match = path.match(matcher[0])
23
+ if (!match) {
24
+ return [[], emptyParam]
25
+ }
26
+
27
+ const index = match.indexOf('', 1)
28
+ return [matcher[1][index], match]
29
+ }) as Router<T>['match']
30
+
31
+ this.match = match
32
+ return match(method, path)
33
+ }
@@ -0,0 +1,170 @@
1
+ import { createNullObject } from '../utils.ts'
2
+
3
+ export const LABEL_REG_EXP_STR = '[^/]+'
4
+ export const ONLY_WILDCARD_REG_EXP_STR = '.*'
5
+ export const TAIL_WILDCARD_REG_EXP_STR = '(?:|/.*)'
6
+ export const PATH_ERROR = Symbol()
7
+
8
+ export type ParamAssocArray = [string, number][]
9
+ export interface Context {
10
+ varIndex: number
11
+ }
12
+
13
+ const regExpMetaChars = new Set('.\\+*[^]$()')
14
+
15
+ /**
16
+ * Sort order:
17
+ * 1. literal
18
+ * 2. special pattern (e.g. :label{[0-9]+})
19
+ * 3. common label pattern (e.g. :label)
20
+ * 4. wildcard
21
+ */
22
+ function compareKey(a: string, b: string): number {
23
+ if (a.length === 1) {
24
+ return b.length === 1 ? (a < b ? -1 : 1) : -1
25
+ }
26
+ if (b.length === 1) {
27
+ return 1
28
+ }
29
+
30
+ // wildcard: the only wildcard (.*) precedes the tail wildcard
31
+ if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {
32
+ return b === TAIL_WILDCARD_REG_EXP_STR ? -1 : 1
33
+ } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {
34
+ return -1
35
+ }
36
+
37
+ // label
38
+ if (a === LABEL_REG_EXP_STR) {
39
+ return 1
40
+ } else if (b === LABEL_REG_EXP_STR) {
41
+ return -1
42
+ }
43
+
44
+ return a.length === b.length ? (a < b ? -1 : 1) : b.length - a.length
45
+ }
46
+
47
+ export class Node {
48
+ // handler index of a dynamic path, or -1 for a static path terminal
49
+ #index?: number
50
+ #varIndex?: number
51
+ #children: Record<string, Node> = createNullObject()
52
+
53
+ insert(
54
+ tokens: readonly string[],
55
+ index: number,
56
+ paramMap: ParamAssocArray,
57
+ context: Context,
58
+ isStatic: boolean
59
+ ): void {
60
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
61
+ let node: Node = this
62
+ for (let i = 0, len = tokens.length; i < len; i++) {
63
+ const token = tokens[i]
64
+ const pattern =
65
+ token.length === 1
66
+ ? token === '*'
67
+ ? i === len - 1
68
+ ? ['', '', ONLY_WILDCARD_REG_EXP_STR] // '*' matches to all the trailing paths
69
+ : ['', '', LABEL_REG_EXP_STR]
70
+ : null
71
+ : token === '/*'
72
+ ? ['', '', TAIL_WILDCARD_REG_EXP_STR] // '/path/to/*' is /\/path\/to(?:|/.*)$
73
+ : token.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/)
74
+
75
+ let nextNode: Node
76
+ if (pattern) {
77
+ const name = pattern[1]
78
+ let regexpStr = pattern[2] || LABEL_REG_EXP_STR
79
+ if (name && pattern[2]) {
80
+ if (regexpStr === '.*') {
81
+ throw PATH_ERROR
82
+ }
83
+ regexpStr = regexpStr.replace(/^\((?!\?:)(?=[^)]+\)$)/, '(?:') // (a|b) => (?:a|b)
84
+ if (/\((?!\?:)/.test(regexpStr)) {
85
+ // prefix(?:a|b) is allowed, but prefix(a|b) is not
86
+ throw PATH_ERROR
87
+ }
88
+ if (regexpStr.length === 1 && regExpMetaChars.has(regexpStr)) {
89
+ // a single-char pattern like :x{.} is ambiguous with a literal character
90
+ throw PATH_ERROR
91
+ }
92
+ }
93
+
94
+ nextNode = node.#children[regexpStr]
95
+ if (!nextNode) {
96
+ if (regexpStr !== ONLY_WILDCARD_REG_EXP_STR && regexpStr !== TAIL_WILDCARD_REG_EXP_STR) {
97
+ for (const k in node.#children) {
98
+ if (
99
+ // a single-char pattern coexists with single-char literals as a literal does
100
+ (regexpStr.length > 1 || k.length > 1) &&
101
+ k !== ONLY_WILDCARD_REG_EXP_STR &&
102
+ k !== TAIL_WILDCARD_REG_EXP_STR
103
+ ) {
104
+ throw PATH_ERROR
105
+ }
106
+ }
107
+ }
108
+ nextNode = node.#children[regexpStr] = new Node()
109
+ }
110
+ if (name !== '') {
111
+ nextNode.#varIndex ??= context.varIndex++
112
+ paramMap.push([name, nextNode.#varIndex])
113
+ }
114
+ } else {
115
+ nextNode = node.#children[token]
116
+ if (!nextNode) {
117
+ for (const k in node.#children) {
118
+ if (
119
+ k.length > 1 &&
120
+ k !== ONLY_WILDCARD_REG_EXP_STR &&
121
+ k !== TAIL_WILDCARD_REG_EXP_STR
122
+ ) {
123
+ throw PATH_ERROR
124
+ }
125
+ }
126
+ nextNode = node.#children[token] = new Node()
127
+ }
128
+ }
129
+
130
+ node = nextNode
131
+ }
132
+
133
+ if (node.#index !== undefined) {
134
+ throw PATH_ERROR
135
+ }
136
+ node.#index = isStatic ? -1 : index
137
+ }
138
+
139
+ buildRegExpStr(): string {
140
+ const childKeys = Object.keys(this.#children).sort(compareKey)
141
+
142
+ const strList = childKeys
143
+ .map((k) => {
144
+ const c = this.#children[k]
145
+ const childStr = c.buildRegExpStr()
146
+ // an empty childStr means a static-only branch, which is handled by staticMap
147
+ return childStr === ''
148
+ ? ''
149
+ : (typeof c.#varIndex === 'number'
150
+ ? `(${k})@${c.#varIndex}`
151
+ : regExpMetaChars.has(k)
152
+ ? `\\${k}`
153
+ : k) + childStr
154
+ })
155
+ .filter(Boolean)
156
+
157
+ if (typeof this.#index === 'number' && this.#index !== -1) {
158
+ strList.unshift(`#${this.#index}`)
159
+ }
160
+
161
+ if (strList.length === 0) {
162
+ return ''
163
+ }
164
+ if (strList.length === 1) {
165
+ return strList[0]
166
+ }
167
+
168
+ return '(?:' + strList.join('|') + ')'
169
+ }
170
+ }