acrylblends 0.2.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 (335) hide show
  1. package/dist/index.d.ts +22 -16
  2. package/dist/index.js +65 -20
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/acryl-inspect/LICENSE +21 -0
  6. package/plugins/acryl-inspect/plugin.json +12 -0
  7. package/plugins/acryl-inspect/src/index.ts +3 -0
  8. package/plugins/acryl-inspect/src/report.ts +126 -0
  9. package/plugins/acryl-inspect/src/service.ts +68 -0
  10. package/plugins/acryl-inspect/tests/report.spec.ts +63 -0
  11. package/plugins/acryl-inspect/tests/service.spec.ts +121 -0
  12. package/plugins/acryl-inspect/upstream.json +18 -0
  13. package/plugins/acryl-node-server/LICENSE +47 -0
  14. package/plugins/acryl-node-server/plugin.json +13 -0
  15. package/plugins/acryl-node-server/src/adapter/conninfo.ts +23 -0
  16. package/plugins/acryl-node-server/src/adapter/early-hints.ts +55 -0
  17. package/plugins/acryl-node-server/src/adapter/error.ts +11 -0
  18. package/plugins/acryl-node-server/src/adapter/headers.ts +249 -0
  19. package/plugins/acryl-node-server/src/adapter/index.ts +6 -0
  20. package/plugins/acryl-node-server/src/adapter/listener.ts +540 -0
  21. package/plugins/acryl-node-server/src/adapter/request.ts +797 -0
  22. package/plugins/acryl-node-server/src/adapter/response.ts +186 -0
  23. package/plugins/acryl-node-server/src/adapter/serve-static.ts +238 -0
  24. package/plugins/acryl-node-server/src/adapter/server.ts +36 -0
  25. package/plugins/acryl-node-server/src/adapter/types.ts +82 -0
  26. package/plugins/acryl-node-server/src/adapter/url.ts +42 -0
  27. package/plugins/acryl-node-server/src/adapter/utils/response/constants.ts +1 -0
  28. package/plugins/acryl-node-server/src/adapter/utils/response.ts +4 -0
  29. package/plugins/acryl-node-server/src/adapter/utils/stream.ts +88 -0
  30. package/plugins/acryl-node-server/src/adapter/utils.ts +96 -0
  31. package/plugins/acryl-node-server/src/adapter/websocket-types.ts +45 -0
  32. package/plugins/acryl-node-server/src/adapter/websocket.ts +375 -0
  33. package/plugins/acryl-node-server/src/index.ts +107 -0
  34. package/plugins/acryl-node-server/tests/adapter/app.ts +76 -0
  35. package/plugins/acryl-node-server/tests/adapter/assets/.static/plain.txt +1 -0
  36. package/plugins/acryl-node-server/tests/adapter/assets/favicon.ico +0 -0
  37. package/plugins/acryl-node-server/tests/adapter/assets/secret.txt +1 -0
  38. package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +1 -0
  39. package/plugins/acryl-node-server/tests/adapter/assets/static/admin/secret.txt +1 -0
  40. package/plugins/acryl-node-server/tests/adapter/assets/static/data.json +5 -0
  41. package/plugins/acryl-node-server/tests/adapter/assets/static/extensionless +1 -0
  42. package/plugins/acryl-node-server/tests/adapter/assets/static/foo..bar.txt +0 -0
  43. package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +1 -0
  44. package/plugins/acryl-node-server/tests/adapter/assets/static/plain.txt +1 -0
  45. package/plugins/acryl-node-server/tests/adapter/assets/static-with-context-path/plain.txt +1 -0
  46. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin +1 -0
  47. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin.br +1 -0
  48. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt +1 -0
  49. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.br +1 -0
  50. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.zst +1 -0
  51. package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +34 -0
  52. package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +248 -0
  53. package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +457 -0
  54. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-cert.pem +23 -0
  55. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-key.pem +27 -0
  56. package/plugins/acryl-node-server/tests/adapter/headers.test.ts +252 -0
  57. package/plugins/acryl-node-server/tests/adapter/helpers/request.ts +190 -0
  58. package/plugins/acryl-node-server/tests/adapter/listener.test.ts +727 -0
  59. package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +189 -0
  60. package/plugins/acryl-node-server/tests/adapter/request.test.ts +1230 -0
  61. package/plugins/acryl-node-server/tests/adapter/response.test.ts +285 -0
  62. package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +849 -0
  63. package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +790 -0
  64. package/plugins/acryl-node-server/tests/adapter/server.test.ts +1302 -0
  65. package/plugins/acryl-node-server/tests/adapter/setup.ts +16 -0
  66. package/plugins/acryl-node-server/tests/adapter/url.test.ts +76 -0
  67. package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +23 -0
  68. package/plugins/acryl-node-server/tests/adapter/utils/stream.test.ts +75 -0
  69. package/plugins/acryl-node-server/tests/adapter/utils.test.ts +235 -0
  70. package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +260 -0
  71. package/plugins/acryl-node-server/tests/server.spec.ts +141 -0
  72. package/plugins/acryl-node-server/upstream.json +18 -0
  73. package/plugins/acryl-router/LICENSE +47 -0
  74. package/plugins/acryl-router/plugin.json +13 -0
  75. package/plugins/acryl-router/src/client.ts +2 -0
  76. package/plugins/acryl-router/src/connection.ts +42 -0
  77. package/plugins/acryl-router/src/core/app-base.ts +544 -0
  78. package/plugins/acryl-router/src/core/app.test.ts +3833 -0
  79. package/plugins/acryl-router/src/core/app.ts +34 -0
  80. package/plugins/acryl-router/src/core/client/client.test.ts +2313 -0
  81. package/plugins/acryl-router/src/core/client/client.ts +249 -0
  82. package/plugins/acryl-router/src/core/client/fetch-result-please.ts +95 -0
  83. package/plugins/acryl-router/src/core/client/index.ts +17 -0
  84. package/plugins/acryl-router/src/core/client/types.test.ts +149 -0
  85. package/plugins/acryl-router/src/core/client/types.ts +393 -0
  86. package/plugins/acryl-router/src/core/client/utils.test.ts +405 -0
  87. package/plugins/acryl-router/src/core/client/utils.ts +117 -0
  88. package/plugins/acryl-router/src/core/compose.test.ts +751 -0
  89. package/plugins/acryl-router/src/core/compose.ts +73 -0
  90. package/plugins/acryl-router/src/core/context.test.ts +629 -0
  91. package/plugins/acryl-router/src/core/context.ts +781 -0
  92. package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +344 -0
  93. package/plugins/acryl-router/src/core/helper/accepts/accepts.ts +96 -0
  94. package/plugins/acryl-router/src/core/helper/accepts/index.ts +6 -0
  95. package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +55 -0
  96. package/plugins/acryl-router/src/core/helper/adapter/index.ts +90 -0
  97. package/plugins/acryl-router/src/core/helper/conninfo/index.ts +6 -0
  98. package/plugins/acryl-router/src/core/helper/conninfo/types.ts +45 -0
  99. package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +510 -0
  100. package/plugins/acryl-router/src/core/helper/cookie/index.ts +146 -0
  101. package/plugins/acryl-router/src/core/helper/factory/index.test.ts +434 -0
  102. package/plugins/acryl-router/src/core/helper/factory/index.ts +375 -0
  103. package/plugins/acryl-router/src/core/helper/html/index.test.ts +78 -0
  104. package/plugins/acryl-router/src/core/helper/html/index.ts +57 -0
  105. package/plugins/acryl-router/src/core/helper/route/index.test.ts +259 -0
  106. package/plugins/acryl-router/src/core/helper/route/index.ts +144 -0
  107. package/plugins/acryl-router/src/core/helper/streaming/index.ts +9 -0
  108. package/plugins/acryl-router/src/core/helper/streaming/sse.ts +101 -0
  109. package/plugins/acryl-router/src/core/helper/streaming/stream.test.ts +128 -0
  110. package/plugins/acryl-router/src/core/helper/streaming/stream.ts +45 -0
  111. package/plugins/acryl-router/src/core/helper/streaming/text.test.ts +34 -0
  112. package/plugins/acryl-router/src/core/helper/streaming/text.ts +15 -0
  113. package/plugins/acryl-router/src/core/helper/streaming/utils.ts +11 -0
  114. package/plugins/acryl-router/src/core/helper/testing/index.test.ts +42 -0
  115. package/plugins/acryl-router/src/core/helper/testing/index.ts +28 -0
  116. package/plugins/acryl-router/src/core/helper/websocket/index.test.ts +124 -0
  117. package/plugins/acryl-router/src/core/helper/websocket/index.ts +140 -0
  118. package/plugins/acryl-router/src/core/http-exception.test.ts +45 -0
  119. package/plugins/acryl-router/src/core/http-exception.ts +77 -0
  120. package/plugins/acryl-router/src/core/index.ts +53 -0
  121. package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +434 -0
  122. package/plugins/acryl-router/src/core/middleware/basic-auth/index.ts +152 -0
  123. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +1018 -0
  124. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.ts +220 -0
  125. package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +273 -0
  126. package/plugins/acryl-router/src/core/middleware/body-limit/index.ts +110 -0
  127. package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +355 -0
  128. package/plugins/acryl-router/src/core/middleware/combine/index.ts +171 -0
  129. package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +535 -0
  130. package/plugins/acryl-router/src/core/middleware/compress/index.ts +142 -0
  131. package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +43 -0
  132. package/plugins/acryl-router/src/core/middleware/context-storage/index.ts +58 -0
  133. package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +532 -0
  134. package/plugins/acryl-router/src/core/middleware/cors/index.ts +163 -0
  135. package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +534 -0
  136. package/plugins/acryl-router/src/core/middleware/csrf/index.ts +150 -0
  137. package/plugins/acryl-router/src/core/middleware/etag/digest.test.ts +21 -0
  138. package/plugins/acryl-router/src/core/middleware/etag/digest.ts +95 -0
  139. package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +503 -0
  140. package/plugins/acryl-router/src/core/middleware/etag/index.ts +135 -0
  141. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +217 -0
  142. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.ts +278 -0
  143. package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +1135 -0
  144. package/plugins/acryl-router/src/core/middleware/jwk/index.ts +1 -0
  145. package/plugins/acryl-router/src/core/middleware/jwk/jwk.ts +195 -0
  146. package/plugins/acryl-router/src/core/middleware/jwk/keys.test.json +48 -0
  147. package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +802 -0
  148. package/plugins/acryl-router/src/core/middleware/jwt/index.ts +9 -0
  149. package/plugins/acryl-router/src/core/middleware/jwt/jwt.ts +189 -0
  150. package/plugins/acryl-router/src/core/middleware/language/index.test.ts +552 -0
  151. package/plugins/acryl-router/src/core/middleware/language/index.ts +12 -0
  152. package/plugins/acryl-router/src/core/middleware/language/language.ts +314 -0
  153. package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +204 -0
  154. package/plugins/acryl-router/src/core/middleware/logger/index.ts +95 -0
  155. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +292 -0
  156. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.ts +141 -0
  157. package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +221 -0
  158. package/plugins/acryl-router/src/core/middleware/method-override/index.ts +147 -0
  159. package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +37 -0
  160. package/plugins/acryl-router/src/core/middleware/powered-by/index.ts +35 -0
  161. package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +218 -0
  162. package/plugins/acryl-router/src/core/middleware/pretty-json/index.ts +67 -0
  163. package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +168 -0
  164. package/plugins/acryl-router/src/core/middleware/request-id/index.ts +7 -0
  165. package/plugins/acryl-router/src/core/middleware/request-id/request-id.ts +59 -0
  166. package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +671 -0
  167. package/plugins/acryl-router/src/core/middleware/secure-headers/index.ts +8 -0
  168. package/plugins/acryl-router/src/core/middleware/secure-headers/permissions-policy.ts +101 -0
  169. package/plugins/acryl-router/src/core/middleware/secure-headers/secure-headers.ts +340 -0
  170. package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +450 -0
  171. package/plugins/acryl-router/src/core/middleware/serve-static/index.ts +135 -0
  172. package/plugins/acryl-router/src/core/middleware/serve-static/path.test.ts +50 -0
  173. package/plugins/acryl-router/src/core/middleware/serve-static/path.ts +25 -0
  174. package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +70 -0
  175. package/plugins/acryl-router/src/core/middleware/timeout/index.ts +58 -0
  176. package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +310 -0
  177. package/plugins/acryl-router/src/core/middleware/timing/index.ts +8 -0
  178. package/plugins/acryl-router/src/core/middleware/timing/timing.ts +256 -0
  179. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +381 -0
  180. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.ts +156 -0
  181. package/plugins/acryl-router/src/core/request/constants.ts +1 -0
  182. package/plugins/acryl-router/src/core/request.test.ts +751 -0
  183. package/plugins/acryl-router/src/core/request.ts +502 -0
  184. package/plugins/acryl-router/src/core/router/common.case.test.ts +1132 -0
  185. package/plugins/acryl-router/src/core/router/linear-router/index.ts +6 -0
  186. package/plugins/acryl-router/src/core/router/linear-router/router.test.ts +80 -0
  187. package/plugins/acryl-router/src/core/router/linear-router/router.ts +152 -0
  188. package/plugins/acryl-router/src/core/router/pattern-router/index.ts +6 -0
  189. package/plugins/acryl-router/src/core/router/pattern-router/router.test.ts +46 -0
  190. package/plugins/acryl-router/src/core/router/pattern-router/router.ts +54 -0
  191. package/plugins/acryl-router/src/core/router/reg-exp-router/index.ts +7 -0
  192. package/plugins/acryl-router/src/core/router/reg-exp-router/matcher.ts +33 -0
  193. package/plugins/acryl-router/src/core/router/reg-exp-router/node.ts +170 -0
  194. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.test.ts +154 -0
  195. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.ts +165 -0
  196. package/plugins/acryl-router/src/core/router/reg-exp-router/router.test.ts +265 -0
  197. package/plugins/acryl-router/src/core/router/reg-exp-router/router.ts +174 -0
  198. package/plugins/acryl-router/src/core/router/reg-exp-router/trie.ts +84 -0
  199. package/plugins/acryl-router/src/core/router/smart-router/index.ts +6 -0
  200. package/plugins/acryl-router/src/core/router/smart-router/router.test.ts +13 -0
  201. package/plugins/acryl-router/src/core/router/smart-router/router.ts +70 -0
  202. package/plugins/acryl-router/src/core/router/trie-router/index.ts +6 -0
  203. package/plugins/acryl-router/src/core/router/trie-router/node.test.ts +896 -0
  204. package/plugins/acryl-router/src/core/router/trie-router/node.ts +221 -0
  205. package/plugins/acryl-router/src/core/router/trie-router/router.test.ts +8 -0
  206. package/plugins/acryl-router/src/core/router/trie-router/router.ts +18 -0
  207. package/plugins/acryl-router/src/core/router/utils.ts +1 -0
  208. package/plugins/acryl-router/src/core/router.ts +103 -0
  209. package/plugins/acryl-router/src/core/types.test.ts +4134 -0
  210. package/plugins/acryl-router/src/core/types.ts +2782 -0
  211. package/plugins/acryl-router/src/core/utils/accept.test.ts +299 -0
  212. package/plugins/acryl-router/src/core/utils/accept.ts +268 -0
  213. package/plugins/acryl-router/src/core/utils/basic-auth.test.ts +56 -0
  214. package/plugins/acryl-router/src/core/utils/basic-auth.ts +26 -0
  215. package/plugins/acryl-router/src/core/utils/body.test.ts +496 -0
  216. package/plugins/acryl-router/src/core/utils/body.ts +263 -0
  217. package/plugins/acryl-router/src/core/utils/buffer.test.ts +147 -0
  218. package/plugins/acryl-router/src/core/utils/buffer.ts +117 -0
  219. package/plugins/acryl-router/src/core/utils/color.test.ts +23 -0
  220. package/plugins/acryl-router/src/core/utils/color.ts +56 -0
  221. package/plugins/acryl-router/src/core/utils/compress.ts +10 -0
  222. package/plugins/acryl-router/src/core/utils/concurrent.test.ts +69 -0
  223. package/plugins/acryl-router/src/core/utils/concurrent.ts +55 -0
  224. package/plugins/acryl-router/src/core/utils/constants.ts +4 -0
  225. package/plugins/acryl-router/src/core/utils/cookie.test.ts +460 -0
  226. package/plugins/acryl-router/src/core/utils/cookie.ts +281 -0
  227. package/plugins/acryl-router/src/core/utils/crypto.test.ts +43 -0
  228. package/plugins/acryl-router/src/core/utils/crypto.ts +58 -0
  229. package/plugins/acryl-router/src/core/utils/encode.test.ts +61 -0
  230. package/plugins/acryl-router/src/core/utils/encode.ts +34 -0
  231. package/plugins/acryl-router/src/core/utils/filepath.test.ts +78 -0
  232. package/plugins/acryl-router/src/core/utils/filepath.ts +60 -0
  233. package/plugins/acryl-router/src/core/utils/handler.ts +15 -0
  234. package/plugins/acryl-router/src/core/utils/headers.ts +355 -0
  235. package/plugins/acryl-router/src/core/utils/html.test.ts +16 -0
  236. package/plugins/acryl-router/src/core/utils/html.ts +182 -0
  237. package/plugins/acryl-router/src/core/utils/http-status.ts +72 -0
  238. package/plugins/acryl-router/src/core/utils/ipaddr.test.ts +149 -0
  239. package/plugins/acryl-router/src/core/utils/ipaddr.ts +374 -0
  240. package/plugins/acryl-router/src/core/utils/jwt/index.ts +7 -0
  241. package/plugins/acryl-router/src/core/utils/jwt/jwa.test.ts +86 -0
  242. package/plugins/acryl-router/src/core/utils/jwt/jwa.ts +38 -0
  243. package/plugins/acryl-router/src/core/utils/jwt/jws.ts +235 -0
  244. package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +1788 -0
  245. package/plugins/acryl-router/src/core/utils/jwt/jwt.ts +292 -0
  246. package/plugins/acryl-router/src/core/utils/jwt/types.ts +157 -0
  247. package/plugins/acryl-router/src/core/utils/jwt/utf8.ts +7 -0
  248. package/plugins/acryl-router/src/core/utils/mime.test.ts +64 -0
  249. package/plugins/acryl-router/src/core/utils/mime.ts +94 -0
  250. package/plugins/acryl-router/src/core/utils/stream.test.ts +212 -0
  251. package/plugins/acryl-router/src/core/utils/stream.ts +107 -0
  252. package/plugins/acryl-router/src/core/utils/types.test.ts +295 -0
  253. package/plugins/acryl-router/src/core/utils/types.ts +123 -0
  254. package/plugins/acryl-router/src/core/utils/url.test.ts +384 -0
  255. package/plugins/acryl-router/src/core/utils/url.ts +337 -0
  256. package/plugins/acryl-router/src/core/validator/index.ts +8 -0
  257. package/plugins/acryl-router/src/core/validator/utils.test.ts +82 -0
  258. package/plugins/acryl-router/src/core/validator/utils.ts +69 -0
  259. package/plugins/acryl-router/src/core/validator/validator.test.ts +1488 -0
  260. package/plugins/acryl-router/src/core/validator/validator.ts +185 -0
  261. package/plugins/acryl-router/src/helpers/index.ts +13 -0
  262. package/plugins/acryl-router/src/helpers/schema-validator.ts +35 -0
  263. package/plugins/acryl-router/src/index.ts +6 -0
  264. package/plugins/acryl-router/src/middleware/index.ts +25 -0
  265. package/plugins/acryl-router/src/middleware/loopback-only.ts +88 -0
  266. package/plugins/acryl-router/src/service.ts +356 -0
  267. package/plugins/acryl-router/tests/docs-examples.spec.ts +152 -0
  268. package/plugins/acryl-router/tests/live-install.spec.ts +64 -0
  269. package/plugins/acryl-router/tests/loader.spec.ts +72 -0
  270. package/plugins/acryl-router/tests/service.spec.ts +409 -0
  271. package/plugins/acryl-router/tests/shadow-state.spec.ts +79 -0
  272. package/plugins/acryl-router/upstream.json +20 -0
  273. package/plugins/acryl-router-http/LICENSE +21 -0
  274. package/plugins/acryl-router-http/plugin.json +12 -0
  275. package/plugins/acryl-router-http/src/bridge.ts +54 -0
  276. package/plugins/acryl-router-http/src/index.ts +63 -0
  277. package/plugins/acryl-router-http/src/serve.ts +24 -0
  278. package/plugins/acryl-router-http/tests/adapter.spec.ts +174 -0
  279. package/plugins/acryl-router-http/tests/stream.spec.ts +133 -0
  280. package/plugins/acryl-router-http/tests/surfaces.spec.ts +101 -0
  281. package/plugins/acryl-router-http/upstream.json +22 -0
  282. package/plugins/acryl-state/LICENSE +21 -0
  283. package/plugins/acryl-state/NOTICE +30 -0
  284. package/plugins/acryl-state/plugin.json +12 -0
  285. package/plugins/acryl-state/src/cell.ts +67 -0
  286. package/plugins/acryl-state/src/index.ts +3 -0
  287. package/plugins/acryl-state/src/react.ts +11 -0
  288. package/plugins/acryl-state/src/service.ts +119 -0
  289. package/plugins/acryl-state/tests/cell.spec.ts +71 -0
  290. package/plugins/acryl-state/tests/react.spec.ts +39 -0
  291. package/plugins/acryl-state/tests/service.spec.ts +132 -0
  292. package/plugins/acryl-state/upstream.json +22 -0
  293. package/plugins/builder/script.ts +6 -10
  294. package/plugins/extensions/index.ts +20 -3
  295. package/plugins/extensions/resolve.ts +28 -3
  296. package/plugins/openai/prompt.ts +12 -6
  297. package/plugins/tasks/index.ts +14 -0
  298. package/plugins/tsconfig.json +14 -5
  299. package/templates/agent/blend.yaml +5 -7
  300. package/templates/agent/src/app.ts +8 -8
  301. package/templates/agent/src/routes.ts +39 -38
  302. package/templates/agent/template.json +3 -3
  303. package/templates/agent/test/builder.test.ts +22 -14
  304. package/templates/agent/test/model.test.ts +3 -3
  305. package/templates/agent/tsconfig.json +8 -5
  306. package/templates/{app → blank}/blend.yaml +3 -3
  307. package/templates/{app → blank}/src/app.ts +5 -5
  308. package/templates/blank/src/routes.ts +16 -0
  309. package/templates/blank/template.json +1 -0
  310. package/templates/{app → blank}/test/app.test.ts +1 -1
  311. package/templates/{app → blank}/tsconfig.json +2 -4
  312. package/templates/todo/README.md +27 -0
  313. package/templates/todo/blend.yaml +25 -0
  314. package/templates/todo/gitignore +2 -0
  315. package/templates/todo/package.json +23 -0
  316. package/templates/todo/src/app.ts +71 -0
  317. package/templates/todo/src/main.ts +19 -0
  318. package/templates/todo/src/page.ts +28 -0
  319. package/templates/todo/src/todo.ts +123 -0
  320. package/templates/todo/template.json +1 -0
  321. package/templates/todo/test/todo.test.ts +145 -0
  322. package/templates/todo/tsconfig.json +17 -0
  323. package/templates/todo/upstream.json +12 -0
  324. package/plugins/events/index.ts +0 -42
  325. package/plugins/events/plugin.json +0 -9
  326. package/plugins/http/index.ts +0 -64
  327. package/plugins/http/plugin.json +0 -10
  328. package/plugins/server/index.ts +0 -138
  329. package/plugins/server/plugin.json +0 -10
  330. package/templates/app/src/routes.ts +0 -14
  331. package/templates/app/template.json +0 -1
  332. /package/templates/{app → blank}/README.md +0 -0
  333. /package/templates/{app → blank}/gitignore +0 -0
  334. /package/templates/{app → blank}/package.json +0 -0
  335. /package/templates/{app → blank}/src/main.ts +0 -0
@@ -0,0 +1,781 @@
1
+ import { AppRequest } from './request.ts'
2
+ import type { Result } from './router.ts'
3
+ import type {
4
+ Env,
5
+ FetchEventLike,
6
+ H,
7
+ Input,
8
+ NotFoundHandler,
9
+ RouterRoute,
10
+ TypedResponse,
11
+ } from './types.ts'
12
+ import type { ResponseHeader } from './utils/headers.ts'
13
+ import { HtmlEscapedCallbackPhase, resolveCallback } from './utils/html.ts'
14
+ import type { ContentfulStatusCode, RedirectStatusCode, StatusCode } from './utils/http-status.ts'
15
+ import type { BaseMime } from './utils/mime.ts'
16
+ import type { InvalidJSONValue, IsAny, JSONParsed, JSONValue } from './utils/types.ts'
17
+
18
+ type HeaderRecord =
19
+ | Record<'Content-Type', BaseMime>
20
+ | Record<ResponseHeader, string | string[]>
21
+ | Record<string, string | string[]>
22
+
23
+ /**
24
+ * Data type can be a string, ArrayBuffer, Blob, Uint8Array (buffer), or ReadableStream.
25
+ */
26
+ export type Data = string | ArrayBuffer | Blob | ReadableStream | Uint8Array<ArrayBuffer>
27
+
28
+ /**
29
+ * Interface for the execution context in a web worker or similar environment.
30
+ */
31
+ export interface ExecutionContext {
32
+ /**
33
+ * Extends the lifetime of the event callback until the promise is settled.
34
+ *
35
+ * @param promise - A promise to wait for.
36
+ */
37
+ waitUntil(promise: Promise<unknown>): void
38
+ /**
39
+ * Allows the event to be passed through to subsequent event listeners.
40
+ */
41
+ passThroughOnException(): void
42
+ /**
43
+ * For compatibility with Wrangler 4.x.
44
+ */
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ props: any
47
+ /**
48
+ * For compatibility with Wrangler 4.x.
49
+ */
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ exports?: any
52
+ }
53
+
54
+ /**
55
+ * Interface for context variable mapping.
56
+ */
57
+ export interface ContextVariableMap {}
58
+
59
+ /**
60
+ * Interface for context renderer.
61
+ */
62
+ export interface ContextRenderer {}
63
+
64
+ /**
65
+ * Interface representing a renderer for content.
66
+ *
67
+ * @interface DefaultRenderer
68
+ * @param {string | Promise<string>} content - The content to be rendered, which can be either a string or a Promise resolving to a string.
69
+ * @returns {Response | Promise<Response>} - The response after rendering the content, which can be either a Response or a Promise resolving to a Response.
70
+ */
71
+ interface DefaultRenderer {
72
+ (content: string | Promise<string>): Response | Promise<Response>
73
+ }
74
+
75
+ /**
76
+ * Renderer type which can either be a ContextRenderer or DefaultRenderer.
77
+ */
78
+ export type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer
79
+
80
+ /**
81
+ * Extracts the props for the renderer.
82
+ */
83
+ export type PropsForRenderer = [...Required<Parameters<Renderer>>] extends [unknown, infer Props]
84
+ ? Props
85
+ : unknown
86
+
87
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
88
+ export type Layout<T = Record<string, any>> = (props: T) => any
89
+
90
+ /**
91
+ * Interface for getting context variables.
92
+ *
93
+ * @template E - Environment type.
94
+ */
95
+ interface Get<E extends Env> {
96
+ <Key extends keyof E['Variables']>(key: Key): E['Variables'][Key]
97
+ <Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key]
98
+ }
99
+
100
+ /**
101
+ * Interface for setting context variables.
102
+ *
103
+ * @template E - Environment type.
104
+ */
105
+ interface Set<E extends Env> {
106
+ <Key extends keyof E['Variables']>(key: Key, value: E['Variables'][Key]): void
107
+ <Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void
108
+ }
109
+
110
+ /**
111
+ * Interface for creating a new response.
112
+ */
113
+ interface NewResponse {
114
+ (data: Data | null, status?: StatusCode, headers?: HeaderRecord): Response
115
+ (data: Data | null, init?: ResponseOrInit): Response
116
+ }
117
+
118
+ /**
119
+ * Interface for responding with a body.
120
+ */
121
+ interface BodyRespond {
122
+ // if we return content, only allow the status codes that allow for returning the body
123
+ <T extends Data, U extends ContentfulStatusCode>(
124
+ data: T,
125
+ status?: U,
126
+ headers?: HeaderRecord
127
+ ): Response & TypedResponse<T, U, 'body'>
128
+ <T extends Data, U extends ContentfulStatusCode>(
129
+ data: T,
130
+ init?: ResponseOrInit<U>
131
+ ): Response & TypedResponse<T, U, 'body'>
132
+ <T extends null, U extends StatusCode>(
133
+ data: T,
134
+ status?: U,
135
+ headers?: HeaderRecord
136
+ ): Response & TypedResponse<null, U, 'body'>
137
+ <T extends null, U extends StatusCode>(
138
+ data: T,
139
+ init?: ResponseOrInit<U>
140
+ ): Response & TypedResponse<null, U, 'body'>
141
+ }
142
+
143
+ /**
144
+ * Interface for responding with text.
145
+ *
146
+ * @interface TextRespond
147
+ * @template T - The type of the text content.
148
+ * @template U - The type of the status code.
149
+ *
150
+ * @param {T} text - The text content to be included in the response.
151
+ * @param {U} [status] - An optional status code for the response.
152
+ * @param {HeaderRecord} [headers] - An optional record of headers to include in the response.
153
+ *
154
+ * @returns {Response & TypedResponse<T, U, 'text'>} - The response after rendering the text content, typed with the provided text and status code types.
155
+ */
156
+ interface TextRespond {
157
+ <T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(
158
+ text: T,
159
+ status?: U,
160
+ headers?: HeaderRecord
161
+ ): Response & TypedResponse<T, U, 'text'>
162
+ <T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(
163
+ text: T,
164
+ init?: ResponseOrInit<U>
165
+ ): Response & TypedResponse<T, U, 'text'>
166
+ }
167
+
168
+ /**
169
+ * Interface for responding with JSON.
170
+ *
171
+ * @interface JSONRespond
172
+ * @template T - The type of the JSON value or simplified unknown type.
173
+ * @template U - The type of the status code.
174
+ *
175
+ * @param {T} object - The JSON object to be included in the response.
176
+ * @param {U} [status] - An optional status code for the response.
177
+ * @param {HeaderRecord} [headers] - An optional record of headers to include in the response.
178
+ *
179
+ * @returns {JSONRespondReturn<T, U>} - The response after rendering the JSON object, typed with the provided object and status code types.
180
+ */
181
+ interface JSONRespond {
182
+ <
183
+ T extends JSONValue | {} | InvalidJSONValue,
184
+ U extends ContentfulStatusCode = ContentfulStatusCode,
185
+ >(
186
+ object: T,
187
+ status?: U,
188
+ headers?: HeaderRecord
189
+ ): JSONRespondReturn<T, U>
190
+ <
191
+ T extends JSONValue | {} | InvalidJSONValue,
192
+ U extends ContentfulStatusCode = ContentfulStatusCode,
193
+ >(
194
+ object: T,
195
+ init?: ResponseOrInit<U>
196
+ ): JSONRespondReturn<T, U>
197
+ }
198
+
199
+ /**
200
+ * @template T - The type of the JSON value or simplified unknown type.
201
+ * @template U - The type of the status code.
202
+ *
203
+ * @returns {Response & TypedResponse<JSONParsed<T>, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types.
204
+ */
205
+ type JSONRespondReturn<
206
+ T extends JSONValue | {} | InvalidJSONValue,
207
+ U extends ContentfulStatusCode,
208
+ > = Response & TypedResponse<JSONParsed<T>, U, 'json'>
209
+
210
+ /**
211
+ * Interface representing a function that responds with HTML content.
212
+ *
213
+ * @param html - The HTML content to respond with, which can be a string or a Promise that resolves to a string.
214
+ * @param status - (Optional) The HTTP status code for the response.
215
+ * @param headers - (Optional) A record of headers to include in the response.
216
+ * @param init - (Optional) The response initialization object.
217
+ *
218
+ * @returns A Response object or a Promise that resolves to a Response object.
219
+ */
220
+ interface HTMLRespond {
221
+ <T extends string | Promise<string>>(
222
+ html: T,
223
+ status?: ContentfulStatusCode,
224
+ headers?: HeaderRecord
225
+ ): T extends string ? Response : Promise<Response>
226
+ <T extends string | Promise<string>>(
227
+ html: T,
228
+ init?: ResponseOrInit<ContentfulStatusCode>
229
+ ): T extends string ? Response : Promise<Response>
230
+ }
231
+
232
+ /**
233
+ * Options for configuring the context.
234
+ *
235
+ * @template E - Environment type.
236
+ */
237
+ type ContextOptions<E extends Env> = {
238
+ /**
239
+ * Bindings for the environment.
240
+ */
241
+ env: E['Bindings']
242
+ /**
243
+ * Execution context for the request.
244
+ */
245
+ executionCtx?: FetchEventLike | ExecutionContext | undefined
246
+ /**
247
+ * Handler for not found responses.
248
+ */
249
+ notFoundHandler?: NotFoundHandler<E>
250
+ matchResult?: Result<[H, RouterRoute]>
251
+ path?: string
252
+ }
253
+
254
+ interface SetHeadersOptions {
255
+ append?: boolean
256
+ }
257
+
258
+ interface SetHeaders {
259
+ (name: 'Content-Type', value?: BaseMime, options?: SetHeadersOptions): void
260
+ (name: ResponseHeader, value?: string, options?: SetHeadersOptions): void
261
+ (name: string, value?: string, options?: SetHeadersOptions): void
262
+ }
263
+
264
+ type ResponseHeadersInit =
265
+ | [string, string][]
266
+ | Record<'Content-Type', BaseMime>
267
+ | Record<ResponseHeader, string>
268
+ | Record<string, string>
269
+ | Headers
270
+
271
+ interface ResponseInit<T extends StatusCode = StatusCode> {
272
+ headers?: ResponseHeadersInit
273
+ status?: T
274
+ statusText?: string
275
+ }
276
+
277
+ type ResponseOrInit<T extends StatusCode = StatusCode> = ResponseInit<T> | Response
278
+
279
+ export const TEXT_PLAIN = 'text/plain; charset=UTF-8'
280
+
281
+ const setDefaultContentType = (contentType: string, headers?: HeaderRecord): HeaderRecord => {
282
+ return {
283
+ 'Content-Type': contentType,
284
+ ...headers,
285
+ }
286
+ }
287
+
288
+ const createResponseInstance = (
289
+ body?: BodyInit | null | undefined,
290
+ init?: globalThis.ResponseInit
291
+ ): Response => new Response(body, init)
292
+
293
+ export class Context<
294
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
295
+ E extends Env = any,
296
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
297
+ P extends string = any,
298
+ I extends Input = {},
299
+ > {
300
+ #rawRequest: Request
301
+ #req: AppRequest<P, I['out']> | undefined
302
+ /**
303
+ * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
304
+ *
305
+ *
306
+ * @example
307
+ * ```ts
308
+ * // Environment object for Cloudflare Workers
309
+ * app.get('*', async c => {
310
+ * const counter = c.env.COUNTER
311
+ * })
312
+ * ```
313
+ */
314
+ env: E['Bindings'] = {}
315
+ #var: Map<unknown, unknown> | undefined
316
+ finalized: boolean = false
317
+ /**
318
+ * `.error` can get the error object from the middleware if the Handler throws an error.
319
+ *
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * app.use('*', async (c, next) => {
324
+ * await next()
325
+ * if (c.error) {
326
+ * // do something...
327
+ * }
328
+ * })
329
+ * ```
330
+ */
331
+ error: Error | undefined
332
+
333
+ #status: StatusCode | undefined
334
+ #executionCtx: FetchEventLike | ExecutionContext | undefined
335
+ #res: Response | undefined
336
+ #layout: Layout<PropsForRenderer & { Layout: Layout }> | undefined
337
+ #renderer: Renderer | undefined
338
+ #notFoundHandler: NotFoundHandler<E> | undefined
339
+ #preparedHeaders: Headers | undefined
340
+
341
+ #matchResult: Result<[H, RouterRoute]> | undefined
342
+ #path: string | undefined
343
+
344
+ /**
345
+ * Creates an instance of the Context class.
346
+ *
347
+ * @param req - The Request object.
348
+ * @param options - Optional configuration options for the context.
349
+ */
350
+ constructor(req: Request, options?: ContextOptions<E>) {
351
+ this.#rawRequest = req
352
+ if (options) {
353
+ this.#executionCtx = options.executionCtx
354
+ this.env = options.env
355
+ this.#notFoundHandler = options.notFoundHandler
356
+ this.#path = options.path
357
+ this.#matchResult = options.matchResult
358
+ }
359
+ }
360
+
361
+ /**
362
+ * `.req` is the instance of {@link AppRequest}.
363
+ */
364
+ get req(): AppRequest<P, I['out']> {
365
+ this.#req ??= new AppRequest(this.#rawRequest, this.#path, this.#matchResult)
366
+ return this.#req
367
+ }
368
+
369
+ /**
370
+ * The FetchEvent associated with the current request.
371
+ *
372
+ * @throws Will throw an error if the context does not have a FetchEvent.
373
+ */
374
+ get event(): FetchEventLike {
375
+ if (this.#executionCtx && 'respondWith' in this.#executionCtx) {
376
+ return this.#executionCtx
377
+ } else {
378
+ throw Error('This context has no FetchEvent')
379
+ }
380
+ }
381
+
382
+ /**
383
+ * The ExecutionContext associated with the current request.
384
+ *
385
+ * @throws Will throw an error if the context does not have an ExecutionContext.
386
+ */
387
+ get executionCtx(): ExecutionContext {
388
+ if (this.#executionCtx) {
389
+ return this.#executionCtx as ExecutionContext
390
+ } else {
391
+ throw Error('This context has no ExecutionContext')
392
+ }
393
+ }
394
+
395
+ /**
396
+ * The Response object for the current request.
397
+ */
398
+ get res(): Response {
399
+ return (this.#res ||= createResponseInstance(null, {
400
+ headers: (this.#preparedHeaders ??= new Headers()),
401
+ }))
402
+ }
403
+
404
+ /**
405
+ * Sets the Response object for the current request.
406
+ *
407
+ * @param _res - The Response object to set.
408
+ */
409
+ set res(_res: Response | undefined) {
410
+ if (this.#res && _res) {
411
+ _res = createResponseInstance(_res.body, _res)
412
+ for (const [k, v] of this.#res.headers.entries()) {
413
+ if (k === 'content-type') {
414
+ continue
415
+ }
416
+ if (k === 'set-cookie') {
417
+ const cookies = this.#res.headers.getSetCookie()
418
+ _res.headers.delete('set-cookie')
419
+ for (const cookie of cookies) {
420
+ _res.headers.append('set-cookie', cookie)
421
+ }
422
+ } else {
423
+ _res.headers.set(k, v)
424
+ }
425
+ }
426
+ }
427
+ this.#res = _res
428
+ this.finalized = true
429
+ }
430
+
431
+ /**
432
+ * `.render()` can create a response within a layout.
433
+ *
434
+ *
435
+ * @example
436
+ * ```ts
437
+ * app.get('/', (c) => {
438
+ * return c.render('Hello!')
439
+ * })
440
+ * ```
441
+ */
442
+ render: Renderer = (...args) => {
443
+ this.#renderer ??= (content: string | Promise<string>) => this.html(content)
444
+ return this.#renderer(...args)
445
+ }
446
+
447
+ /**
448
+ * Sets the layout for the response.
449
+ *
450
+ * @param layout - The layout to set.
451
+ * @returns The layout function.
452
+ */
453
+ setLayout = (
454
+ layout: Layout<PropsForRenderer & { Layout: Layout }>
455
+ ): Layout<
456
+ PropsForRenderer & {
457
+ Layout: Layout
458
+ }
459
+ > => (this.#layout = layout)
460
+
461
+ /**
462
+ * Gets the current layout for the response.
463
+ *
464
+ * @returns The current layout function.
465
+ */
466
+ getLayout = (): Layout<PropsForRenderer & { Layout: Layout }> | undefined => this.#layout
467
+
468
+ /**
469
+ * `.setRenderer()` can set the layout in the custom middleware.
470
+ *
471
+ *
472
+ * @example
473
+ * ```tsx
474
+ * app.use('*', async (c, next) => {
475
+ * c.setRenderer((content) => {
476
+ * return c.html(
477
+ * <html>
478
+ * <body>
479
+ * <p>{content}</p>
480
+ * </body>
481
+ * </html>
482
+ * )
483
+ * })
484
+ * await next()
485
+ * })
486
+ * ```
487
+ */
488
+ setRenderer = (renderer: Renderer): void => {
489
+ this.#renderer = renderer
490
+ }
491
+
492
+ /**
493
+ * `.header()` can set headers.
494
+ *
495
+ *
496
+ * @example
497
+ * ```ts
498
+ * app.get('/welcome', (c) => {
499
+ * // Set headers
500
+ * c.header('X-Message', 'Hello!')
501
+ * c.header('Content-Type', 'text/plain')
502
+ *
503
+ * // Append multiple headers using the append option (e.g. Vary)
504
+ * c.header('Vary', 'Accept-Encoding', { append: true })
505
+ * c.header('Vary', 'User-Agent', { append: true })
506
+ *
507
+ * return c.body('Thank you for coming')
508
+ * })
509
+ * ```
510
+ */
511
+ header: SetHeaders = (name, value, options): void => {
512
+ if (this.finalized) {
513
+ this.#res = createResponseInstance((this.#res as Response).body, this.#res)
514
+ }
515
+ const headers = this.#res ? this.#res.headers : (this.#preparedHeaders ??= new Headers())
516
+ if (value === undefined) {
517
+ headers.delete(name)
518
+ } else if (options?.append) {
519
+ headers.append(name, value)
520
+ } else {
521
+ headers.set(name, value)
522
+ }
523
+ }
524
+
525
+ status = (status: StatusCode): void => {
526
+ this.#status = status
527
+ }
528
+
529
+ /**
530
+ * `.set()` can set the value specified by the key.
531
+ *
532
+ *
533
+ * @example
534
+ * ```ts
535
+ * app.use('*', async (c, next) => {
536
+ * c.set('message', 'App is hot!!')
537
+ * await next()
538
+ * })
539
+ * ```
540
+ */
541
+ set: Set<
542
+ IsAny<E> extends true
543
+ ? {
544
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
545
+ Variables: ContextVariableMap & Record<PropertyKey, any>
546
+ }
547
+ : E
548
+ > = (key: PropertyKey, value: unknown) => {
549
+ this.#var ??= new Map()
550
+ this.#var.set(key, value)
551
+ }
552
+
553
+ /**
554
+ * `.get()` can use the value specified by the key.
555
+ *
556
+ *
557
+ * @example
558
+ * ```ts
559
+ * app.get('/', (c) => {
560
+ * const message = c.get('message')
561
+ * return c.text(`The message is "${message}"`)
562
+ * })
563
+ * ```
564
+ */
565
+ get: Get<
566
+ IsAny<E> extends true
567
+ ? {
568
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
569
+ Variables: ContextVariableMap & Record<PropertyKey, any>
570
+ }
571
+ : E
572
+ > = (key: PropertyKey) => {
573
+ return this.#var ? this.#var.get(key) : undefined
574
+ }
575
+
576
+ /**
577
+ * `.var` can access the value of a variable.
578
+ *
579
+ *
580
+ * @example
581
+ * ```ts
582
+ * const result = c.var.client.oneMethod()
583
+ * ```
584
+ */
585
+ // c.var.propName is a read-only
586
+ get var(): Readonly<
587
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
588
+ ContextVariableMap & (IsAny<E['Variables']> extends true ? Record<string, any> : E['Variables'])
589
+ > {
590
+ if (!this.#var) {
591
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
592
+ return {} as any
593
+ }
594
+ return Object.fromEntries(this.#var)
595
+ }
596
+
597
+ #newResponse(
598
+ data: Data | null,
599
+ arg?: StatusCode | ResponseOrInit,
600
+ headers?: HeaderRecord
601
+ ): Response {
602
+ let responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders
603
+
604
+ if (typeof arg === 'object' && arg.headers) {
605
+ responseHeaders ??= new Headers()
606
+ for (const [key, value] of new Headers(arg.headers)) {
607
+ if (key === 'set-cookie') {
608
+ responseHeaders.append(key, value)
609
+ } else {
610
+ responseHeaders.set(key, value)
611
+ }
612
+ }
613
+ }
614
+
615
+ if (headers) {
616
+ if (!responseHeaders) {
617
+ let count = 0
618
+ for (const k in headers) {
619
+ if (++count > 1 || typeof headers[k as keyof HeaderRecord] !== 'string') {
620
+ responseHeaders = new Headers()
621
+ break
622
+ }
623
+ }
624
+ }
625
+ if (responseHeaders) {
626
+ for (const k in headers) {
627
+ const v = headers[k as keyof HeaderRecord]
628
+ if (typeof v === 'string') {
629
+ responseHeaders.set(k, v)
630
+ } else {
631
+ responseHeaders.delete(k)
632
+ for (const v2 of v) {
633
+ responseHeaders.append(k, v2)
634
+ }
635
+ }
636
+ }
637
+ }
638
+ }
639
+
640
+ const status = typeof arg === 'number' ? arg : (arg?.status ?? this.#status)
641
+ return createResponseInstance(data, {
642
+ status,
643
+ headers: responseHeaders ?? (headers as Record<string, string> | undefined),
644
+ })
645
+ }
646
+
647
+ newResponse: NewResponse = (...args) => this.#newResponse(...(args as Parameters<NewResponse>))
648
+
649
+ /**
650
+ * `.body()` can return the HTTP response.
651
+ * You can set headers with `.header()` and set HTTP status code with `.status`.
652
+ * This can also be set in `.text()`, `.json()` and so on.
653
+ *
654
+ *
655
+ * @example
656
+ * ```ts
657
+ * app.get('/welcome', (c) => {
658
+ * // Set headers
659
+ * c.header('X-Message', 'Hello!')
660
+ * c.header('Content-Type', 'text/plain')
661
+ * // Set HTTP status code
662
+ * c.status(201)
663
+ *
664
+ * // Return the response body
665
+ * return c.body('Thank you for coming')
666
+ * })
667
+ * ```
668
+ */
669
+ body: BodyRespond = (
670
+ data: Data | null,
671
+ arg?: StatusCode | RequestInit,
672
+ headers?: HeaderRecord
673
+ ): ReturnType<BodyRespond> => this.#newResponse(data, arg, headers) as ReturnType<BodyRespond>
674
+
675
+ /**
676
+ * `.text()` can render text as `Content-Type:text/plain`.
677
+ *
678
+ *
679
+ * @example
680
+ * ```ts
681
+ * app.get('/say', (c) => {
682
+ * return c.text('Hello!')
683
+ * })
684
+ * ```
685
+ */
686
+ text: TextRespond = (
687
+ text: string,
688
+ arg?: ContentfulStatusCode | ResponseOrInit,
689
+ headers?: HeaderRecord
690
+ ): ReturnType<TextRespond> => {
691
+ return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized
692
+ ? (new Response(text) as ReturnType<TextRespond>)
693
+ : (this.#newResponse(
694
+ text,
695
+ arg,
696
+ setDefaultContentType(TEXT_PLAIN, headers)
697
+ ) as ReturnType<TextRespond>)
698
+ }
699
+
700
+ /**
701
+ * `.json()` can render JSON as `Content-Type:application/json`.
702
+ *
703
+ *
704
+ * @example
705
+ * ```ts
706
+ * app.get('/api', (c) => {
707
+ * return c.json({ message: 'Hello!' })
708
+ * })
709
+ * ```
710
+ */
711
+ json: JSONRespond = <
712
+ T extends JSONValue | {} | InvalidJSONValue,
713
+ U extends ContentfulStatusCode = ContentfulStatusCode,
714
+ >(
715
+ object: T,
716
+ arg?: U | ResponseOrInit<U>,
717
+ headers?: HeaderRecord
718
+ ): JSONRespondReturn<T, U> => {
719
+ return this.#newResponse(
720
+ JSON.stringify(object),
721
+ arg,
722
+ setDefaultContentType('application/json', headers)
723
+ ) /* eslint-disable @typescript-eslint/no-explicit-any */ as any
724
+ }
725
+
726
+ html: HTMLRespond = (
727
+ html: string | Promise<string>,
728
+ arg?: ContentfulStatusCode | ResponseOrInit<ContentfulStatusCode>,
729
+ headers?: HeaderRecord
730
+ ): Response | Promise<Response> => {
731
+ const res = (html: string) =>
732
+ this.#newResponse(html, arg, setDefaultContentType('text/html; charset=UTF-8', headers))
733
+ return typeof html === 'object'
734
+ ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res)
735
+ : res(html)
736
+ }
737
+
738
+ /**
739
+ * `.redirect()` can Redirect, default status code is 302.
740
+ *
741
+ *
742
+ * @example
743
+ * ```ts
744
+ * app.get('/redirect', (c) => {
745
+ * return c.redirect('/')
746
+ * })
747
+ * app.get('/redirect-permanently', (c) => {
748
+ * return c.redirect('/', 301)
749
+ * })
750
+ * ```
751
+ */
752
+ redirect = <T extends RedirectStatusCode = 302>(
753
+ location: string | URL,
754
+ status?: T
755
+ ): Response & TypedResponse<undefined, T, 'redirect'> => {
756
+ const locationString = String(location)
757
+ this.header(
758
+ 'Location',
759
+ // Multibytes should be encoded
760
+ // eslint-disable-next-line no-control-regex
761
+ !/[^\x00-\xFF]/.test(locationString) ? locationString : encodeURI(locationString)
762
+ )
763
+ return this.newResponse(null, status ?? 302) as any
764
+ }
765
+
766
+ /**
767
+ * `.notFound()` can return the Not Found Response.
768
+ *
769
+ *
770
+ * @example
771
+ * ```ts
772
+ * app.get('/notfound', (c) => {
773
+ * return c.notFound()
774
+ * })
775
+ * ```
776
+ */
777
+ notFound = (): ReturnType<NotFoundHandler> => {
778
+ this.#notFoundHandler ??= () => createResponseInstance()
779
+ return this.#notFoundHandler(this)
780
+ }
781
+ }