acrylblends 0.4.0 → 0.5.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 (426) hide show
  1. package/LICENSE +73 -0
  2. package/dist/index.js +56 -2
  3. package/dist/index.js.map +1 -1
  4. package/docs/framework/LICENSE +23 -0
  5. package/docs/framework/README.md +63 -0
  6. package/docs/framework/UPSTREAM.md +3 -0
  7. package/docs/framework/agents/index.md +24 -0
  8. package/docs/framework/api/acryl.md +259 -0
  9. package/docs/framework/api/context.md +527 -0
  10. package/docs/framework/api/exception.md +80 -0
  11. package/docs/framework/api/index.md +12 -0
  12. package/docs/framework/api/presets.md +65 -0
  13. package/docs/framework/api/request.md +396 -0
  14. package/docs/framework/api/routing.md +303 -0
  15. package/docs/framework/api/summary.md +140 -0
  16. package/docs/framework/concepts/benchmarks.md +26 -0
  17. package/docs/framework/concepts/developer-experience.md +5 -0
  18. package/docs/framework/concepts/middleware.md +21 -0
  19. package/docs/framework/concepts/motivation.md +14 -0
  20. package/docs/framework/concepts/routers.md +63 -0
  21. package/docs/framework/concepts/stacks.md +235 -0
  22. package/docs/framework/concepts/web-standard.md +37 -0
  23. package/docs/framework/cordis/acryl-in-a-cordis-app.md +146 -0
  24. package/docs/framework/cordis/concepts.md +105 -0
  25. package/docs/framework/cordis/middleware.md +8 -0
  26. package/docs/framework/cordis/migration-from-0-3.md +111 -0
  27. package/docs/framework/cordis/migration-from-0-4.md +14 -0
  28. package/docs/framework/cordis/migration-from-dsh-webserver.md +103 -0
  29. package/docs/framework/cordis/mounting.md +85 -0
  30. package/docs/framework/cordis/node-server.md +75 -0
  31. package/docs/framework/cordis/plugin-lifecycle.md +111 -0
  32. package/docs/framework/cordis/surfaces.md +71 -0
  33. package/docs/framework/cordis/transport-and-cancellation.md +57 -0
  34. package/docs/framework/cordis/validation.md +135 -0
  35. package/docs/framework/getting-started/basic.md +196 -0
  36. package/docs/framework/getting-started/bun.md +221 -0
  37. package/docs/framework/getting-started/nodejs.md +344 -0
  38. package/docs/framework/getting-started/other-runtimes.md +23 -0
  39. package/docs/framework/guides/best-practices.md +231 -0
  40. package/docs/framework/guides/create-acrylblends.md +79 -0
  41. package/docs/framework/guides/examples.md +3 -0
  42. package/docs/framework/guides/faq.md +19 -0
  43. package/docs/framework/guides/helpers.md +33 -0
  44. package/docs/framework/guides/jsx-dom.md +299 -0
  45. package/docs/framework/guides/jsx.md +440 -0
  46. package/docs/framework/guides/middleware.md +253 -0
  47. package/docs/framework/guides/rpc.md +886 -0
  48. package/docs/framework/guides/testing.md +133 -0
  49. package/docs/framework/guides/validation.md +383 -0
  50. package/docs/framework/helpers/accepts.md +60 -0
  51. package/docs/framework/helpers/adapter.md +87 -0
  52. package/docs/framework/helpers/conninfo.md +112 -0
  53. package/docs/framework/helpers/cookie.md +232 -0
  54. package/docs/framework/helpers/css.md +285 -0
  55. package/docs/framework/helpers/dev.md +67 -0
  56. package/docs/framework/helpers/factory.md +180 -0
  57. package/docs/framework/helpers/html.md +123 -0
  58. package/docs/framework/helpers/jwt.md +184 -0
  59. package/docs/framework/helpers/proxy.md +118 -0
  60. package/docs/framework/helpers/route.md +143 -0
  61. package/docs/framework/helpers/ssg.md +393 -0
  62. package/docs/framework/helpers/streaming.md +119 -0
  63. package/docs/framework/helpers/testing.md +101 -0
  64. package/docs/framework/helpers/websocket.md +215 -0
  65. package/docs/framework/middleware/builtin/basic-auth.md +165 -0
  66. package/docs/framework/middleware/builtin/bearer-auth.md +138 -0
  67. package/docs/framework/middleware/builtin/body-limit.md +71 -0
  68. package/docs/framework/middleware/builtin/cache.md +122 -0
  69. package/docs/framework/middleware/builtin/combine.md +94 -0
  70. package/docs/framework/middleware/builtin/compress.md +59 -0
  71. package/docs/framework/middleware/builtin/context-storage.md +78 -0
  72. package/docs/framework/middleware/builtin/cors.md +135 -0
  73. package/docs/framework/middleware/builtin/csrf.md +105 -0
  74. package/docs/framework/middleware/builtin/etag.md +54 -0
  75. package/docs/framework/middleware/builtin/ip-restriction.md +69 -0
  76. package/docs/framework/middleware/builtin/jsx-renderer.md +286 -0
  77. package/docs/framework/middleware/builtin/jwk.md +192 -0
  78. package/docs/framework/middleware/builtin/jwt.md +145 -0
  79. package/docs/framework/middleware/builtin/language.md +232 -0
  80. package/docs/framework/middleware/builtin/logger.md +74 -0
  81. package/docs/framework/middleware/builtin/loopback-only.md +31 -0
  82. package/docs/framework/middleware/builtin/method-not-allowed.md +48 -0
  83. package/docs/framework/middleware/builtin/method-override.md +80 -0
  84. package/docs/framework/middleware/builtin/mount.md +106 -0
  85. package/docs/framework/middleware/builtin/pretty-json.md +53 -0
  86. package/docs/framework/middleware/builtin/request-id.md +94 -0
  87. package/docs/framework/middleware/builtin/secure-headers.md +247 -0
  88. package/docs/framework/middleware/builtin/timeout.md +98 -0
  89. package/docs/framework/middleware/builtin/timing.md +101 -0
  90. package/docs/framework/middleware/builtin/trailing-slash.md +74 -0
  91. package/docs/framework/middleware/third-party.md +4 -0
  92. package/docs/framework/upstream.json +9 -0
  93. package/lib/accepts-XBuZPVRI.js +52 -0
  94. package/lib/accepts.d.ts +33 -0
  95. package/lib/accepts.js +2 -0
  96. package/lib/acryl-base.d.ts +2 -0
  97. package/lib/acryl-base.js +332 -0
  98. package/lib/adapter.d.ts +12 -0
  99. package/lib/adapter.js +37 -0
  100. package/lib/app-BM0rTCp7.js +26 -0
  101. package/lib/app-CmAYW1Al.d.ts +21 -0
  102. package/lib/basic-auth.d.ts +72 -0
  103. package/lib/basic-auth.js +95 -0
  104. package/lib/bearer-auth.d.ts +89 -0
  105. package/lib/bearer-auth.js +94 -0
  106. package/lib/body-limit.d.ts +42 -0
  107. package/lib/body-limit.js +66 -0
  108. package/lib/client-BHTr318g.js +266 -0
  109. package/lib/client.d.ts +3 -0
  110. package/lib/client.js +2 -0
  111. package/lib/combine.d.ts +85 -0
  112. package/lib/combine.js +137 -0
  113. package/lib/compose-BuW2B6PZ.js +50 -0
  114. package/lib/compress.d.ts +38 -0
  115. package/lib/compress.js +79 -0
  116. package/lib/connection-C7xgP1hP.js +24 -0
  117. package/lib/conninfo.d.ts +25 -0
  118. package/lib/conninfo.js +2 -0
  119. package/lib/constants-Dy7ZvN1H.js +4 -0
  120. package/lib/context-Bm7rI-oK.d.ts +1234 -0
  121. package/lib/context-DDO0cfuP.js +365 -0
  122. package/lib/context-storage.d.ts +38 -0
  123. package/lib/context-storage.js +52 -0
  124. package/lib/cookie-ClMaKDQf.d.ts +40 -0
  125. package/lib/cookie.d.ts +24 -0
  126. package/lib/cookie.js +82 -0
  127. package/lib/cors.d.ts +52 -0
  128. package/lib/cors.js +106 -0
  129. package/lib/csrf.d.ts +75 -0
  130. package/lib/csrf.js +101 -0
  131. package/lib/etag.d.ts +40 -0
  132. package/lib/etag.js +135 -0
  133. package/lib/factory.d.ts +35 -0
  134. package/lib/factory.js +30 -0
  135. package/lib/headers-tu2YYN8T.d.ts +11 -0
  136. package/lib/html.d.ts +6 -0
  137. package/lib/html.js +31 -0
  138. package/lib/http-exception.d.ts +57 -0
  139. package/lib/http-exception.js +54 -0
  140. package/lib/http-status-DaAwGAFL.d.ts +35 -0
  141. package/lib/index-B-3F4wt2.d.ts +12 -0
  142. package/lib/index-UTBmM3GX.d.ts +68 -0
  143. package/lib/index-oOClm_Xk.d.ts +45 -0
  144. package/lib/index.d.ts +5 -0
  145. package/lib/index.js +28 -0
  146. package/lib/ip-restriction.d.ts +68 -0
  147. package/lib/ip-restriction.js +166 -0
  148. package/lib/jwk.d.ts +52 -0
  149. package/lib/jwk.js +117 -0
  150. package/lib/jwt-BGJBw5AF.js +403 -0
  151. package/lib/jwt-Dg493Tai.d.ts +51 -0
  152. package/lib/jwt.d.ts +72 -0
  153. package/lib/jwt.js +115 -0
  154. package/lib/language.d.ts +88 -0
  155. package/lib/language.js +198 -0
  156. package/lib/logger.d.ts +22 -0
  157. package/lib/logger.js +54 -0
  158. package/lib/loopback-only.d.ts +45 -0
  159. package/lib/loopback-only.js +90 -0
  160. package/lib/method-not-allowed.d.ts +47 -0
  161. package/lib/method-not-allowed.js +82 -0
  162. package/lib/method-override.d.ts +46 -0
  163. package/lib/method-override.js +103 -0
  164. package/lib/mime-BQOYHl-l.d.ts +72 -0
  165. package/lib/node-server/conninfo.d.ts +11 -0
  166. package/lib/node-server/conninfo.js +19 -0
  167. package/lib/node-server/serve-static.d.ts +19 -0
  168. package/lib/node-server/serve-static.js +2 -0
  169. package/lib/node-server.d.ts +103 -0
  170. package/lib/node-server.js +1325 -0
  171. package/lib/powered-by.d.ts +28 -0
  172. package/lib/powered-by.js +24 -0
  173. package/lib/pretty-json.d.ts +40 -0
  174. package/lib/pretty-json.js +39 -0
  175. package/lib/reg-exp-router-DC1R3qoY.js +363 -0
  176. package/lib/request-id.d.ts +45 -0
  177. package/lib/request-id.js +34 -0
  178. package/lib/request.d.ts +2 -0
  179. package/lib/request.js +323 -0
  180. package/lib/route.d.ts +78 -0
  181. package/lib/route.js +126 -0
  182. package/lib/router/linear-router.d.ts +11 -0
  183. package/lib/router/linear-router.js +96 -0
  184. package/lib/router/pattern-router.d.ts +11 -0
  185. package/lib/router/pattern-router.js +41 -0
  186. package/lib/router/reg-exp-router.d.ts +35 -0
  187. package/lib/router/reg-exp-router.js +2 -0
  188. package/lib/router/smart-router.d.ts +15 -0
  189. package/lib/router/smart-router.js +2 -0
  190. package/lib/router/trie-router.d.ts +11 -0
  191. package/lib/router/trie-router.js +2 -0
  192. package/lib/router-CvUxUTOq.d.ts +99 -0
  193. package/lib/router.d.ts +2 -0
  194. package/lib/router.js +35 -0
  195. package/lib/schema-validator.d.ts +28 -0
  196. package/lib/schema-validator.js +22 -0
  197. package/lib/secure-headers.d.ts +125 -0
  198. package/lib/secure-headers.js +163 -0
  199. package/lib/serve-static-Dw_m6KxR.js +213 -0
  200. package/lib/serve-static.d.ts +31 -0
  201. package/lib/serve-static.js +77 -0
  202. package/lib/smart-router-C5CZ5XSM.js +49 -0
  203. package/lib/stream-CPdqZ0Fp.d.ts +34 -0
  204. package/lib/streaming-DHST3Scg.js +96 -0
  205. package/lib/streaming.d.ts +23 -0
  206. package/lib/streaming.js +2 -0
  207. package/lib/testing.d.ts +10 -0
  208. package/lib/testing.js +17 -0
  209. package/lib/timeout.d.ts +30 -0
  210. package/lib/timeout.js +42 -0
  211. package/lib/timing.d.ts +130 -0
  212. package/lib/timing.js +183 -0
  213. package/lib/trailing-slash.d.ts +91 -0
  214. package/lib/trailing-slash.js +85 -0
  215. package/lib/trie-router-CfFbapzL.js +146 -0
  216. package/lib/types-CDO6I3B0.d.ts +40 -0
  217. package/lib/types-CHesD1KG.d.ts +195 -0
  218. package/lib/types-CwrQjlaM.d.ts +105 -0
  219. package/lib/types-DR95J00T.d.ts +29 -0
  220. package/lib/types.d.ts +2 -0
  221. package/lib/types.js +4 -0
  222. package/lib/utils/accept.d.ts +9 -0
  223. package/lib/utils/accept.js +193 -0
  224. package/lib/utils/basic-auth.d.ts +8 -0
  225. package/lib/utils/basic-auth.js +20 -0
  226. package/lib/utils/body.d.ts +2 -0
  227. package/lib/utils/body.js +94 -0
  228. package/lib/utils/buffer.d.ts +19 -0
  229. package/lib/utils/buffer.js +51 -0
  230. package/lib/utils/color.d.ts +24 -0
  231. package/lib/utils/color.js +37 -0
  232. package/lib/utils/compress.d.ts +11 -0
  233. package/lib/utils/compress.js +11 -0
  234. package/lib/utils/concurrent.d.ts +17 -0
  235. package/lib/utils/concurrent.js +30 -0
  236. package/lib/utils/constants.d.ts +7 -0
  237. package/lib/utils/constants.js +7 -0
  238. package/lib/utils/cookie.d.ts +2 -0
  239. package/lib/utils/cookie.js +125 -0
  240. package/lib/utils/crypto.d.ts +14 -0
  241. package/lib/utils/crypto.js +34 -0
  242. package/lib/utils/encode.d.ts +11 -0
  243. package/lib/utils/encode.js +33 -0
  244. package/lib/utils/filepath.d.ts +14 -0
  245. package/lib/utils/filepath.js +25 -0
  246. package/lib/utils/handler.d.ts +9 -0
  247. package/lib/utils/handler.js +12 -0
  248. package/lib/utils/headers.d.ts +2 -0
  249. package/lib/utils/headers.js +1 -0
  250. package/lib/utils/html.d.ts +46 -0
  251. package/lib/utils/html.js +103 -0
  252. package/lib/utils/http-status.d.ts +2 -0
  253. package/lib/utils/http-status.js +1 -0
  254. package/lib/utils/ipaddr.d.ts +56 -0
  255. package/lib/utils/ipaddr.js +238 -0
  256. package/lib/utils/jwt.d.ts +24 -0
  257. package/lib/utils/jwt.js +2 -0
  258. package/lib/utils/mime.d.ts +2 -0
  259. package/lib/utils/mime.js +77 -0
  260. package/lib/utils/stream.d.ts +2 -0
  261. package/lib/utils/stream.js +88 -0
  262. package/lib/utils/types.d.ts +2 -0
  263. package/lib/utils/types.js +1 -0
  264. package/lib/utils/url.d.ts +46 -0
  265. package/lib/utils/url.js +197 -0
  266. package/lib/utils-dw8lxqjL.js +4 -0
  267. package/lib/validator-D84mq-dO.js +65 -0
  268. package/lib/validator.d.ts +42 -0
  269. package/lib/validator.js +2 -0
  270. package/lib/ws.d.ts +2 -0
  271. package/lib/ws.js +53 -0
  272. package/package.json +315 -15
  273. package/plugins/acryl-inspect/src/report.ts +15 -10
  274. package/plugins/acryl-inspect/src/service.ts +2 -2
  275. package/plugins/acryl-inspect/tests/report.spec.ts +9 -3
  276. package/plugins/acryl-inspect/tests/service.spec.ts +3 -3
  277. package/plugins/acryl-inspect/upstream.json +2 -2
  278. package/plugins/acryl-node-server/tests/adapter/app.ts +2 -2
  279. package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +1 -1
  280. package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +1 -1
  281. package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +2 -2
  282. package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +4 -4
  283. package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +5 -5
  284. package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +2 -2
  285. package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +20 -20
  286. package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +2 -2
  287. package/plugins/acryl-node-server/tests/adapter/server.test.ts +50 -50
  288. package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +4 -4
  289. package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +9 -9
  290. package/plugins/acryl-node-server/tests/server.spec.ts +6 -6
  291. package/plugins/acryl-node-server/upstream.json +2 -2
  292. package/plugins/acryl-router/src/client.ts +1 -1
  293. package/plugins/acryl-router/src/connection.ts +2 -2
  294. package/plugins/acryl-router/src/core/app-base.ts +29 -29
  295. package/plugins/acryl-router/src/core/app.test.ts +175 -175
  296. package/plugins/acryl-router/src/core/app.ts +8 -8
  297. package/plugins/acryl-router/src/core/client/client.test.ts +76 -76
  298. package/plugins/acryl-router/src/core/client/client.ts +2 -2
  299. package/plugins/acryl-router/src/core/client/fetch-result-please.ts +1 -1
  300. package/plugins/acryl-router/src/core/client/index.ts +1 -1
  301. package/plugins/acryl-router/src/core/client/types.test.ts +6 -6
  302. package/plugins/acryl-router/src/core/client/types.ts +16 -16
  303. package/plugins/acryl-router/src/core/client/utils.test.ts +2 -2
  304. package/plugins/acryl-router/src/core/context.test.ts +4 -4
  305. package/plugins/acryl-router/src/core/context.ts +6 -6
  306. package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +3 -3
  307. package/plugins/acryl-router/src/core/helper/accepts/index.ts +1 -1
  308. package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +6 -6
  309. package/plugins/acryl-router/src/core/helper/adapter/index.ts +1 -1
  310. package/plugins/acryl-router/src/core/helper/conninfo/index.ts +1 -1
  311. package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +8 -8
  312. package/plugins/acryl-router/src/core/helper/cookie/index.ts +1 -1
  313. package/plugins/acryl-router/src/core/helper/factory/index.test.ts +9 -9
  314. package/plugins/acryl-router/src/core/helper/factory/index.ts +10 -10
  315. package/plugins/acryl-router/src/core/helper/html/index.test.ts +4 -4
  316. package/plugins/acryl-router/src/core/helper/html/index.ts +1 -1
  317. package/plugins/acryl-router/src/core/helper/route/index.test.ts +7 -7
  318. package/plugins/acryl-router/src/core/helper/route/index.ts +8 -8
  319. package/plugins/acryl-router/src/core/helper/streaming/index.ts +1 -1
  320. package/plugins/acryl-router/src/core/helper/testing/index.test.ts +6 -6
  321. package/plugins/acryl-router/src/core/helper/testing/index.ts +4 -4
  322. package/plugins/acryl-router/src/core/helper/websocket/index.ts +2 -1
  323. package/plugins/acryl-router/src/core/http-exception.ts +1 -1
  324. package/plugins/acryl-router/src/core/index.ts +9 -9
  325. package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +6 -6
  326. package/plugins/acryl-router/src/core/middleware/basic-auth/index.ts +3 -3
  327. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +5 -5
  328. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.ts +3 -3
  329. package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +6 -6
  330. package/plugins/acryl-router/src/core/middleware/body-limit/index.ts +3 -3
  331. package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +9 -9
  332. package/plugins/acryl-router/src/core/middleware/combine/index.ts +7 -7
  333. package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +9 -9
  334. package/plugins/acryl-router/src/core/middleware/compress/index.ts +3 -3
  335. package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +5 -5
  336. package/plugins/acryl-router/src/core/middleware/context-storage/index.ts +4 -4
  337. package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +7 -7
  338. package/plugins/acryl-router/src/core/middleware/cors/index.ts +3 -3
  339. package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +10 -10
  340. package/plugins/acryl-router/src/core/middleware/csrf/index.ts +3 -3
  341. package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +42 -42
  342. package/plugins/acryl-router/src/core/middleware/etag/index.ts +4 -4
  343. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +4 -4
  344. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.ts +6 -6
  345. package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +16 -16
  346. package/plugins/acryl-router/src/core/middleware/jwk/jwk.ts +7 -6
  347. package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +16 -16
  348. package/plugins/acryl-router/src/core/middleware/jwt/jwt.ts +4 -3
  349. package/plugins/acryl-router/src/core/middleware/language/index.test.ts +3 -3
  350. package/plugins/acryl-router/src/core/middleware/language/language.ts +3 -3
  351. package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +5 -5
  352. package/plugins/acryl-router/src/core/middleware/logger/index.ts +4 -4
  353. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +24 -24
  354. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.ts +8 -8
  355. package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +5 -5
  356. package/plugins/acryl-router/src/core/middleware/method-override/index.ts +6 -6
  357. package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +4 -4
  358. package/plugins/acryl-router/src/core/middleware/powered-by/index.ts +6 -6
  359. package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +30 -30
  360. package/plugins/acryl-router/src/core/middleware/pretty-json/index.ts +4 -4
  361. package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +15 -15
  362. package/plugins/acryl-router/src/core/middleware/request-id/request-id.ts +3 -3
  363. package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +35 -35
  364. package/plugins/acryl-router/src/core/middleware/secure-headers/secure-headers.ts +3 -3
  365. package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +23 -23
  366. package/plugins/acryl-router/src/core/middleware/serve-static/index.ts +1 -1
  367. package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +2 -2
  368. package/plugins/acryl-router/src/core/middleware/timeout/index.ts +3 -3
  369. package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +14 -14
  370. package/plugins/acryl-router/src/core/middleware/timing/timing.ts +3 -3
  371. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +7 -7
  372. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.ts +7 -7
  373. package/plugins/acryl-router/src/core/request.test.ts +42 -42
  374. package/plugins/acryl-router/src/core/request.ts +6 -6
  375. package/plugins/acryl-router/src/core/router/linear-router/index.ts +1 -1
  376. package/plugins/acryl-router/src/core/router/pattern-router/index.ts +1 -1
  377. package/plugins/acryl-router/src/core/router/reg-exp-router/index.ts +1 -1
  378. package/plugins/acryl-router/src/core/router/smart-router/index.ts +1 -1
  379. package/plugins/acryl-router/src/core/router/trie-router/index.ts +1 -1
  380. package/plugins/acryl-router/src/core/types.test.ts +115 -115
  381. package/plugins/acryl-router/src/core/types.ts +72 -72
  382. package/plugins/acryl-router/src/core/utils/body.ts +8 -8
  383. package/plugins/acryl-router/src/core/utils/html.ts +1 -1
  384. package/plugins/acryl-router/src/core/utils/jwt/jws.ts +3 -3
  385. package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +2 -2
  386. package/plugins/acryl-router/src/core/utils/jwt/jwt.ts +3 -3
  387. package/plugins/acryl-router/src/core/utils/jwt/types.ts +1 -1
  388. package/plugins/acryl-router/src/core/utils/types.ts +42 -0
  389. package/plugins/acryl-router/src/core/utils/url.test.ts +2 -2
  390. package/plugins/acryl-router/src/core/validator/index.ts +1 -1
  391. package/plugins/acryl-router/src/core/validator/validator.test.ts +28 -28
  392. package/plugins/acryl-router/src/deprecated.ts +15 -0
  393. package/plugins/acryl-router/src/index.ts +3 -2
  394. package/plugins/acryl-router/src/middleware/index.ts +1 -1
  395. package/plugins/acryl-router/src/middleware/loopback-only.ts +34 -1
  396. package/plugins/acryl-router/src/service.ts +19 -13
  397. package/plugins/acryl-router/tests/docs-examples.spec.ts +11 -11
  398. package/plugins/acryl-router/tests/live-install.spec.ts +2 -2
  399. package/plugins/acryl-router/tests/loader.spec.ts +3 -3
  400. package/plugins/acryl-router/tests/loopback-only.spec.ts +80 -0
  401. package/plugins/acryl-router/tests/no-dom/consumer.ts +11 -0
  402. package/plugins/acryl-router/tests/no-dom/tsconfig.json +13 -0
  403. package/plugins/acryl-router/tests/service.spec.ts +39 -22
  404. package/plugins/acryl-router/upstream.json +3 -3
  405. package/plugins/acryl-router-http/tests/adapter.spec.ts +3 -3
  406. package/plugins/acryl-router-http/tests/surfaces.spec.ts +2 -2
  407. package/plugins/acryl-router-http/upstream.json +2 -2
  408. package/plugins/acryl-state/src/service.ts +2 -2
  409. package/plugins/acryl-state/upstream.json +2 -2
  410. package/plugins/builder/script.ts +3 -3
  411. package/plugins/extensions/index.ts +4 -3
  412. package/plugins/extensions/resolve.ts +70 -10
  413. package/plugins/openai/prompt.ts +7 -7
  414. package/shared/AGENTS.core.md +61 -0
  415. package/templates/agent/AGENTS.md +6 -0
  416. package/templates/agent/README.md +2 -2
  417. package/templates/agent/blend.yaml +1 -1
  418. package/templates/agent/src/routes.ts +2 -2
  419. package/templates/agent/test/model.test.ts +2 -2
  420. package/templates/agent/tsconfig.json +40 -0
  421. package/templates/blank/AGENTS.md +5 -0
  422. package/templates/blank/README.md +1 -1
  423. package/templates/blank/src/routes.ts +2 -2
  424. package/templates/todo/AGENTS.md +5 -0
  425. package/templates/todo/src/todo.ts +6 -4
  426. package/templates/todo/upstream.json +2 -2
package/lib/cors.js ADDED
@@ -0,0 +1,106 @@
1
+ //#region ../../plugins/acryl-router/src/core/middleware/cors/index.ts
2
+ /**
3
+ * CORS Middleware for Acryl.
4
+ *
5
+ *
6
+ * @param {CORSOptions} [options] - The options for the CORS middleware.
7
+ * @param {string | string[] | ((origin: string, c: Context) => Promise<string | undefined | null> | string | undefined | null)} [options.origin='*'] - The value of "Access-Control-Allow-Origin" CORS header.
8
+ * @param {string[] | ((origin: string, c: Context) => Promise<string[]> | string[])} [options.allowMethods=['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH', 'QUERY']] - The value of "Access-Control-Allow-Methods" CORS header.
9
+ * @param {string[]} [options.allowHeaders=[]] - The value of "Access-Control-Allow-Headers" CORS header.
10
+ * @param {number} [options.maxAge] - The value of "Access-Control-Max-Age" CORS header.
11
+ * @param {boolean} [options.credentials] - The value of "Access-Control-Allow-Credentials" CORS header.
12
+ * @param {string[]} [options.exposeHeaders=[]] - The value of "Access-Control-Expose-Headers" CORS header.
13
+ * @returns {MiddlewareHandler} The middleware handler function.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const app = new Acryl()
18
+ *
19
+ * app.use('/api/*', cors())
20
+ * app.use(
21
+ * '/api2/*',
22
+ * cors({
23
+ * origin: 'http://example.com',
24
+ * allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
25
+ * allowMethods: ['POST', 'GET', 'OPTIONS'],
26
+ * exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
27
+ * maxAge: 600,
28
+ * credentials: true,
29
+ * })
30
+ * )
31
+ *
32
+ * app.all('/api/abc', (c) => {
33
+ * return c.json({ success: true })
34
+ * })
35
+ * app.all('/api2/abc', (c) => {
36
+ * return c.json({ success: true })
37
+ * })
38
+ * ```
39
+ */
40
+ const cors = (options) => {
41
+ const opts = {
42
+ origin: "*",
43
+ allowMethods: [
44
+ "GET",
45
+ "HEAD",
46
+ "PUT",
47
+ "POST",
48
+ "DELETE",
49
+ "PATCH",
50
+ "QUERY"
51
+ ],
52
+ allowHeaders: [],
53
+ exposeHeaders: [],
54
+ ...options
55
+ };
56
+ const exposeHeadersStr = opts.exposeHeaders?.length ? opts.exposeHeaders.join(",") : void 0;
57
+ const allowHeadersStr = opts.allowHeaders?.length ? opts.allowHeaders.join(",") : void 0;
58
+ const findAllowOrigin = ((optsOrigin) => {
59
+ if (typeof optsOrigin === "string") if (optsOrigin === "*") return () => optsOrigin;
60
+ else return (origin) => optsOrigin === origin ? origin : null;
61
+ else if (typeof optsOrigin === "function") return optsOrigin;
62
+ else return (origin) => optsOrigin.includes(origin) ? origin : null;
63
+ })(opts.origin);
64
+ const findAllowMethods = ((optsAllowMethods) => {
65
+ if (typeof optsAllowMethods === "function") return async (origin, c) => (await optsAllowMethods(origin, c)).join(",");
66
+ else if (Array.isArray(optsAllowMethods)) {
67
+ const methodsStr = optsAllowMethods.join(",");
68
+ return () => methodsStr;
69
+ } else return () => "";
70
+ })(opts.allowMethods);
71
+ return async function cors(c, next) {
72
+ function set(key, value) {
73
+ c.res.headers.set(key, value);
74
+ }
75
+ const allowOrigin = await findAllowOrigin(c.req.header("origin") || "", c);
76
+ if (allowOrigin) set("Access-Control-Allow-Origin", allowOrigin);
77
+ if (opts.credentials) set("Access-Control-Allow-Credentials", "true");
78
+ if (exposeHeadersStr) set("Access-Control-Expose-Headers", exposeHeadersStr);
79
+ if (c.req.method === "OPTIONS") {
80
+ if (opts.origin !== "*") c.res.headers.append("Vary", "Origin");
81
+ if (opts.maxAge != null) set("Access-Control-Max-Age", opts.maxAge.toString());
82
+ const allowMethods = await findAllowMethods(c.req.header("origin") || "", c);
83
+ if (allowMethods) set("Access-Control-Allow-Methods", allowMethods);
84
+ let headersStr = allowHeadersStr;
85
+ if (!headersStr) {
86
+ const requestHeaders = c.req.header("Access-Control-Request-Headers");
87
+ if (requestHeaders) headersStr = requestHeaders.split(",").map((h) => h.trim()).join(",");
88
+ }
89
+ if (headersStr) {
90
+ set("Access-Control-Allow-Headers", headersStr);
91
+ c.res.headers.append("Vary", "Access-Control-Request-Headers");
92
+ }
93
+ c.res.headers.delete("Content-Length");
94
+ c.res.headers.delete("Content-Type");
95
+ return new Response(null, {
96
+ headers: c.res.headers,
97
+ status: 204,
98
+ statusText: "No Content"
99
+ });
100
+ }
101
+ await next();
102
+ if (opts.origin !== "*") c.header("Vary", "Origin", { append: true });
103
+ };
104
+ };
105
+ //#endregion
106
+ export { cors };
package/lib/csrf.d.ts ADDED
@@ -0,0 +1,75 @@
1
+ import { I as MiddlewareHandler, t as Context } from "./context-Bm7rI-oK.js";
2
+
3
+ //#region ../../plugins/acryl-router/src/core/middleware/csrf/index.d.ts
4
+ type IsAllowedOriginHandler = (origin: string, context: Context) => boolean | Promise<boolean>;
5
+ declare const secFetchSiteValues: readonly ["same-origin", "same-site", "none", "cross-site"];
6
+ type SecFetchSite = (typeof secFetchSiteValues)[number];
7
+ type IsAllowedSecFetchSiteHandler = (secFetchSite: SecFetchSite, context: Context) => boolean | Promise<boolean>;
8
+ interface CSRFOptions {
9
+ origin?: string | string[] | IsAllowedOriginHandler;
10
+ secFetchSite?: SecFetchSite | SecFetchSite[] | IsAllowedSecFetchSiteHandler;
11
+ }
12
+ /**
13
+ * CSRF Protection Middleware for Acryl.
14
+ *
15
+ * Protects against Cross-Site Request Forgery attacks by validating request origins
16
+ * and sec-fetch-site headers. The request is allowed if either validation passes.
17
+ *
18
+ *
19
+ * @param {CSRFOptions} [options] - The options for the CSRF protection middleware.
20
+ * @param {string|string[]|(origin: string, context: Context) => boolean} [options.origin] -
21
+ * Allowed origins for requests.
22
+ * - string: Single allowed origin (e.g., 'https://example.com')
23
+ * - string[]: Multiple allowed origins
24
+ * - function: Custom validation logic
25
+ * - Default: Only same origin as the request URL
26
+ * @param {string|string[]|(secFetchSite: string, context: Context) => boolean} [options.secFetchSite] -
27
+ * Sec-Fetch-Site header validation. Standard values include 'same-origin', 'same-site', 'cross-site', 'none'.
28
+ * - string: Single allowed value (e.g., 'same-origin')
29
+ * - string[]: Multiple allowed values (e.g., ['same-origin', 'same-site'])
30
+ * - function: Custom validation with access to context
31
+ * - Default: Only allows 'same-origin'
32
+ * @returns {MiddlewareHandler} The middleware handler function.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const app = new Acryl()
37
+ *
38
+ * // Default: both origin and sec-fetch-site validation
39
+ * app.use('*', csrf())
40
+ *
41
+ * // Allow specific origins
42
+ * app.use('*', csrf({ origin: 'https://example.com' }))
43
+ * app.use('*', csrf({ origin: ['https://app.com', 'https://api.com'] }))
44
+ *
45
+ * // Allow specific sec-fetch-site values
46
+ * app.use('*', csrf({ secFetchSite: 'same-origin' }))
47
+ * app.use('*', csrf({ secFetchSite: ['same-origin', 'same-site'] }))
48
+ *
49
+ * // Dynamic sec-fetch-site validation
50
+ * app.use('*', csrf({
51
+ * secFetchSite: (secFetchSite, c) => {
52
+ * // Always allow same-origin
53
+ * if (secFetchSite === 'same-origin') return true
54
+ * // Allow cross-site for webhook endpoints
55
+ * if (secFetchSite === 'cross-site' && c.req.path.startsWith('/webhook/')) {
56
+ * return true
57
+ * }
58
+ * return false
59
+ * }
60
+ * }))
61
+ *
62
+ * // Dynamic origin validation
63
+ * app.use('*', csrf({
64
+ * origin: (origin, c) => {
65
+ * // Allow same origin
66
+ * if (origin === new URL(c.req.url).origin) return true
67
+ * // Allow specific trusted domains
68
+ * return ['https://app.example.com', 'https://admin.example.com'].includes(origin)
69
+ * }
70
+ * }))
71
+ * ```
72
+ */
73
+ declare const csrf: (options?: CSRFOptions) => MiddlewareHandler;
74
+ //#endregion
75
+ export { csrf };
package/lib/csrf.js ADDED
@@ -0,0 +1,101 @@
1
+ import { HTTPException } from "./http-exception.js";
2
+ //#region ../../plugins/acryl-router/src/core/middleware/csrf/index.ts
3
+ const secFetchSiteValues = [
4
+ "same-origin",
5
+ "same-site",
6
+ "none",
7
+ "cross-site"
8
+ ];
9
+ const isSecFetchSite = (value) => secFetchSiteValues.includes(value);
10
+ const isSafeMethodRe = /^(GET|HEAD|OPTIONS)$/;
11
+ const isRequestedByFormElementRe = /^\b(application\/x-www-form-urlencoded|multipart\/form-data|text\/plain)\b/i;
12
+ /**
13
+ * CSRF Protection Middleware for Acryl.
14
+ *
15
+ * Protects against Cross-Site Request Forgery attacks by validating request origins
16
+ * and sec-fetch-site headers. The request is allowed if either validation passes.
17
+ *
18
+ *
19
+ * @param {CSRFOptions} [options] - The options for the CSRF protection middleware.
20
+ * @param {string|string[]|(origin: string, context: Context) => boolean} [options.origin] -
21
+ * Allowed origins for requests.
22
+ * - string: Single allowed origin (e.g., 'https://example.com')
23
+ * - string[]: Multiple allowed origins
24
+ * - function: Custom validation logic
25
+ * - Default: Only same origin as the request URL
26
+ * @param {string|string[]|(secFetchSite: string, context: Context) => boolean} [options.secFetchSite] -
27
+ * Sec-Fetch-Site header validation. Standard values include 'same-origin', 'same-site', 'cross-site', 'none'.
28
+ * - string: Single allowed value (e.g., 'same-origin')
29
+ * - string[]: Multiple allowed values (e.g., ['same-origin', 'same-site'])
30
+ * - function: Custom validation with access to context
31
+ * - Default: Only allows 'same-origin'
32
+ * @returns {MiddlewareHandler} The middleware handler function.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const app = new Acryl()
37
+ *
38
+ * // Default: both origin and sec-fetch-site validation
39
+ * app.use('*', csrf())
40
+ *
41
+ * // Allow specific origins
42
+ * app.use('*', csrf({ origin: 'https://example.com' }))
43
+ * app.use('*', csrf({ origin: ['https://app.com', 'https://api.com'] }))
44
+ *
45
+ * // Allow specific sec-fetch-site values
46
+ * app.use('*', csrf({ secFetchSite: 'same-origin' }))
47
+ * app.use('*', csrf({ secFetchSite: ['same-origin', 'same-site'] }))
48
+ *
49
+ * // Dynamic sec-fetch-site validation
50
+ * app.use('*', csrf({
51
+ * secFetchSite: (secFetchSite, c) => {
52
+ * // Always allow same-origin
53
+ * if (secFetchSite === 'same-origin') return true
54
+ * // Allow cross-site for webhook endpoints
55
+ * if (secFetchSite === 'cross-site' && c.req.path.startsWith('/webhook/')) {
56
+ * return true
57
+ * }
58
+ * return false
59
+ * }
60
+ * }))
61
+ *
62
+ * // Dynamic origin validation
63
+ * app.use('*', csrf({
64
+ * origin: (origin, c) => {
65
+ * // Allow same origin
66
+ * if (origin === new URL(c.req.url).origin) return true
67
+ * // Allow specific trusted domains
68
+ * return ['https://app.example.com', 'https://admin.example.com'].includes(origin)
69
+ * }
70
+ * }))
71
+ * ```
72
+ */
73
+ const csrf = (options) => {
74
+ const originHandler = ((optsOrigin) => {
75
+ if (!optsOrigin) return (origin, c) => origin === new URL(c.req.url).origin;
76
+ else if (typeof optsOrigin === "string") return (origin) => origin === optsOrigin;
77
+ else if (typeof optsOrigin === "function") return optsOrigin;
78
+ else return (origin) => optsOrigin.includes(origin);
79
+ })(options?.origin);
80
+ const isAllowedOrigin = async (origin, c) => {
81
+ if (origin === void 0) return false;
82
+ return await originHandler(origin, c);
83
+ };
84
+ const secFetchSiteHandler = ((optsSecFetchSite) => {
85
+ if (!optsSecFetchSite) return (secFetchSite) => secFetchSite === "same-origin";
86
+ else if (typeof optsSecFetchSite === "string") return (secFetchSite) => secFetchSite === optsSecFetchSite;
87
+ else if (typeof optsSecFetchSite === "function") return optsSecFetchSite;
88
+ else return (secFetchSite) => optsSecFetchSite.includes(secFetchSite);
89
+ })(options?.secFetchSite);
90
+ const isAllowedSecFetchSite = async (secFetchSite, c) => {
91
+ if (secFetchSite === void 0) return false;
92
+ if (!isSecFetchSite(secFetchSite)) return false;
93
+ return await secFetchSiteHandler(secFetchSite, c);
94
+ };
95
+ return async function csrf(c, next) {
96
+ if (!isSafeMethodRe.test(c.req.method) && isRequestedByFormElementRe.test(c.req.header("content-type") || "text/plain") && !await isAllowedSecFetchSite(c.req.header("sec-fetch-site"), c) && !await isAllowedOrigin(c.req.header("origin"), c)) throw new HTTPException(403, { res: new Response("Forbidden", { status: 403 }) });
97
+ await next();
98
+ };
99
+ };
100
+ //#endregion
101
+ export { csrf };
package/lib/etag.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { I as MiddlewareHandler } from "./context-Bm7rI-oK.js";
2
+
3
+ //#region ../../plugins/acryl-router/src/core/middleware/etag/index.d.ts
4
+ type ETagOptions = {
5
+ retainedHeaders?: string[];
6
+ weak?: boolean;
7
+ generateDigest?: (body: Uint8Array<ArrayBuffer>) => ArrayBuffer | Promise<ArrayBuffer>;
8
+ };
9
+ /**
10
+ * Default headers to pass through on 304 responses. From the spec:
11
+ * > The response must not contain a body and must include the headers that
12
+ * > would have been sent in an equivalent 200 OK response: Cache-Control,
13
+ * > Content-Location, Date, ETag, Expires, and Vary.
14
+ */
15
+ declare const RETAINED_304_HEADERS: string[];
16
+ /**
17
+ * ETag Middleware for Acryl.
18
+ *
19
+ *
20
+ * @param {ETagOptions} [options] - The options for the ETag middleware.
21
+ * @param {boolean} [options.weak=false] - Define using or not using a weak validation. If true is set, then `W/` is added to the prefix of the value.
22
+ * @param {string[]} [options.retainedHeaders=RETAINED_304_HEADERS] - The headers that you want to retain in the 304 Response.
23
+ * @param {function(Uint8Array): ArrayBuffer | Promise<ArrayBuffer>} [options.generateDigest] -
24
+ * A custom digest generation function. By default, it uses 'SHA-1'
25
+ * This function is called with the response body as a `Uint8Array` and should return a hash as an `ArrayBuffer` or a Promise of one.
26
+ * @returns {MiddlewareHandler} The middleware handler function.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const app = new Acryl()
31
+ *
32
+ * app.use('/etag/*', etag())
33
+ * app.get('/etag/abc', (c) => {
34
+ * return c.text('Acryl is hot')
35
+ * })
36
+ * ```
37
+ */
38
+ declare const etag: (options?: ETagOptions) => MiddlewareHandler;
39
+ //#endregion
40
+ export { RETAINED_304_HEADERS, etag };
package/lib/etag.js ADDED
@@ -0,0 +1,135 @@
1
+ //#region ../../plugins/acryl-router/src/core/middleware/etag/digest.ts
2
+ const mergeBuffers = (buffer1, buffer2) => {
3
+ if (!buffer1) return buffer2;
4
+ const merged = new Uint8Array(new ArrayBuffer(buffer1.byteLength + buffer2.byteLength));
5
+ merged.set(new Uint8Array(buffer1), 0);
6
+ merged.set(buffer2, buffer1.byteLength);
7
+ return merged;
8
+ };
9
+ const CHUNK_SIZE = 256 * 1024;
10
+ const generateDigest = async (stream, generator) => {
11
+ if (!stream) return null;
12
+ let result = void 0;
13
+ let chunk;
14
+ let chunkLength = 0;
15
+ const digest = async (body) => {
16
+ result = await generator(mergeBuffers(result, body));
17
+ };
18
+ const reader = stream.getReader();
19
+ for (;;) {
20
+ const { value, done } = await reader.read();
21
+ if (done) break;
22
+ let offset = 0;
23
+ while (offset < value.byteLength) {
24
+ const remaining = value.byteLength - offset;
25
+ if (chunkLength === 0 && remaining >= CHUNK_SIZE) {
26
+ await digest(value.subarray(offset, offset + CHUNK_SIZE));
27
+ offset += CHUNK_SIZE;
28
+ continue;
29
+ }
30
+ const requiredLength = chunkLength + remaining;
31
+ if (requiredLength < CHUNK_SIZE) {
32
+ if (!chunk) chunk = value.slice(offset);
33
+ else {
34
+ if (chunk.byteLength < requiredLength) {
35
+ const nextChunk = new Uint8Array(new ArrayBuffer(Math.min(CHUNK_SIZE, Math.max(requiredLength, chunk.byteLength * 2))));
36
+ nextChunk.set(chunk.subarray(0, chunkLength));
37
+ chunk = nextChunk;
38
+ }
39
+ chunk.set(value.subarray(offset), chunkLength);
40
+ }
41
+ chunkLength = requiredLength;
42
+ break;
43
+ }
44
+ const length = CHUNK_SIZE - chunkLength;
45
+ if (chunk?.byteLength !== CHUNK_SIZE) {
46
+ const nextChunk = new Uint8Array(/* @__PURE__ */ new ArrayBuffer(CHUNK_SIZE));
47
+ if (chunk) nextChunk.set(chunk.subarray(0, chunkLength));
48
+ chunk = nextChunk;
49
+ }
50
+ chunk.set(value.subarray(offset, offset + length), chunkLength);
51
+ await digest(chunk);
52
+ chunkLength = 0;
53
+ offset += length;
54
+ }
55
+ }
56
+ if (chunk && chunkLength > 0) await digest(chunk.subarray(0, chunkLength));
57
+ if (!result) return null;
58
+ return Array.prototype.map.call(new Uint8Array(result), (x) => x.toString(16).padStart(2, "0")).join("");
59
+ };
60
+ //#endregion
61
+ //#region ../../plugins/acryl-router/src/core/middleware/etag/index.ts
62
+ /**
63
+ * Default headers to pass through on 304 responses. From the spec:
64
+ * > The response must not contain a body and must include the headers that
65
+ * > would have been sent in an equivalent 200 OK response: Cache-Control,
66
+ * > Content-Location, Date, ETag, Expires, and Vary.
67
+ */
68
+ const RETAINED_304_HEADERS = [
69
+ "cache-control",
70
+ "content-location",
71
+ "date",
72
+ "etag",
73
+ "expires",
74
+ "vary"
75
+ ];
76
+ const stripWeak = (tag) => tag.replace(/^W\//, "");
77
+ function etagMatches(etag, ifNoneMatch) {
78
+ return ifNoneMatch != null && ifNoneMatch.split(",").some((t) => stripWeak(t.trim()) === stripWeak(etag));
79
+ }
80
+ function initializeGenerator(generator) {
81
+ if (!generator) {
82
+ if (crypto && crypto.subtle) generator = (body) => crypto.subtle.digest({ name: "SHA-1" }, body);
83
+ }
84
+ return generator;
85
+ }
86
+ /**
87
+ * ETag Middleware for Acryl.
88
+ *
89
+ *
90
+ * @param {ETagOptions} [options] - The options for the ETag middleware.
91
+ * @param {boolean} [options.weak=false] - Define using or not using a weak validation. If true is set, then `W/` is added to the prefix of the value.
92
+ * @param {string[]} [options.retainedHeaders=RETAINED_304_HEADERS] - The headers that you want to retain in the 304 Response.
93
+ * @param {function(Uint8Array): ArrayBuffer | Promise<ArrayBuffer>} [options.generateDigest] -
94
+ * A custom digest generation function. By default, it uses 'SHA-1'
95
+ * This function is called with the response body as a `Uint8Array` and should return a hash as an `ArrayBuffer` or a Promise of one.
96
+ * @returns {MiddlewareHandler} The middleware handler function.
97
+ *
98
+ * @example
99
+ * ```ts
100
+ * const app = new Acryl()
101
+ *
102
+ * app.use('/etag/*', etag())
103
+ * app.get('/etag/abc', (c) => {
104
+ * return c.text('Acryl is hot')
105
+ * })
106
+ * ```
107
+ */
108
+ const etag = (options) => {
109
+ const retainedHeaders = new Set((options?.retainedHeaders ?? RETAINED_304_HEADERS).map((header) => header.toLowerCase()));
110
+ const weak = options?.weak ?? false;
111
+ const generator = initializeGenerator(options?.generateDigest);
112
+ return async function etag(c, next) {
113
+ const ifNoneMatch = c.req.header("If-None-Match") ?? null;
114
+ await next();
115
+ if (!(c.req.method === "GET" || c.req.method === "HEAD" || c.req.method === "QUERY") || !c.res.ok) return;
116
+ const res = c.res;
117
+ let etag = res.headers.get("ETag");
118
+ if (!etag) {
119
+ if (!generator) return;
120
+ const hash = await generateDigest(res.clone().body, generator);
121
+ if (hash === null) return;
122
+ etag = weak ? `W/"${hash}"` : `"${hash}"`;
123
+ }
124
+ if (ifNoneMatch === "*" || etagMatches(etag, ifNoneMatch)) {
125
+ c.res = new Response(null, {
126
+ status: 304,
127
+ statusText: "Not Modified",
128
+ headers: { ETag: etag }
129
+ });
130
+ for (const key of Array.from(c.res.headers.keys())) if (!retainedHeaders.has(key.toLowerCase())) c.res.headers.delete(key);
131
+ } else c.res.headers.set("ETag", etag);
132
+ };
133
+ };
134
+ //#endregion
135
+ export { RETAINED_304_HEADERS, etag };
@@ -0,0 +1,35 @@
1
+ import { A as Input, I as MiddlewareHandler, M as IntersectNonAnyTypes, T as H, _ as Env, et as AcrylOptions, k as HandlerResponse } from "./context-Bm7rI-oK.js";
2
+ import { t as Acryl } from "./app-CmAYW1Al.js";
3
+
4
+ //#region ../../plugins/acryl-router/src/core/helper/factory/index.d.ts
5
+ type InitApp<E extends Env = Env> = (app: Acryl<E>) => void;
6
+ interface CreateHandlersInterface<E extends Env, P extends string> {
7
+ <I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E>(handler1: H<E2, P, I, R>): [H<E2, P, I, R>];
8
+ <I extends Input = {}, I2 extends Input = I, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>): [H<E2, P, I, R>, H<E3, P, I2, R2>];
9
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>];
10
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>, H<E5, P, I4, R4>];
11
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, R5 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>, handler5: H<E6, P, I5, R5>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>, H<E5, P, I4, R4>, H<E6, P, I5, R5>];
12
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, R5 extends HandlerResponse<any> = any, R6 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>, handler5: H<E6, P, I5, R5>, handler6: H<E7, P, I6, R6>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>, H<E5, P, I4, R4>, H<E6, P, I5, R5>, H<E7, P, I6, R6>];
13
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, R5 extends HandlerResponse<any> = any, R6 extends HandlerResponse<any> = any, R7 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>, handler5: H<E6, P, I5, R5>, handler6: H<E7, P, I6, R6>, handler7: H<E8, P, I7, R7>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>, H<E5, P, I4, R4>, H<E6, P, I5, R5>, H<E7, P, I6, R6>, H<E8, P, I7, R7>];
14
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, R5 extends HandlerResponse<any> = any, R6 extends HandlerResponse<any> = any, R7 extends HandlerResponse<any> = any, R8 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>, handler5: H<E6, P, I5, R5>, handler6: H<E7, P, I6, R6>, handler7: H<E8, P, I7, R7>, handler8: H<E9, P, I8, R8>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>, H<E5, P, I4, R4>, H<E6, P, I5, R5>, H<E7, P, I6, R6>, H<E8, P, I7, R7>, H<E9, P, I8, R8>];
15
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, R5 extends HandlerResponse<any> = any, R6 extends HandlerResponse<any> = any, R7 extends HandlerResponse<any> = any, R8 extends HandlerResponse<any> = any, R9 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>, handler5: H<E6, P, I5, R5>, handler6: H<E7, P, I6, R6>, handler7: H<E8, P, I7, R7>, handler8: H<E9, P, I8, R8>, handler9: H<E10, P, I9, R9>): [H<E2, P, I, R>, H<E3, P, I2, R>, H<E4, P, I3, R>, H<E5, P, I4, R>, H<E6, P, I5, R>, H<E7, P, I6, R>, H<E8, P, I7, R>, H<E9, P, I8, R>, H<E10, P, I9, R>];
16
+ <I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, R extends HandlerResponse<any> = any, R2 extends HandlerResponse<any> = any, R3 extends HandlerResponse<any> = any, R4 extends HandlerResponse<any> = any, R5 extends HandlerResponse<any> = any, R6 extends HandlerResponse<any> = any, R7 extends HandlerResponse<any> = any, R8 extends HandlerResponse<any> = any, R9 extends HandlerResponse<any> = any, R10 extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[E, E2]>, E4 extends Env = IntersectNonAnyTypes<[E, E2, E3]>, E5 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4]>, E6 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5]>, E7 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6]>, E8 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7]>, E9 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8]>, E10 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9]>, E11 extends Env = IntersectNonAnyTypes<[E, E2, E3, E4, E5, E6, E7, E8, E9, E10]>>(handler1: H<E2, P, I, R>, handler2: H<E3, P, I2, R2>, handler3: H<E4, P, I3, R3>, handler4: H<E5, P, I4, R4>, handler5: H<E6, P, I5, R5>, handler6: H<E7, P, I6, R6>, handler7: H<E8, P, I7, R7>, handler8: H<E9, P, I8, R8>, handler9: H<E10, P, I9, R9>, handler10: H<E11, P, I10, R10>): [H<E2, P, I, R>, H<E3, P, I2, R2>, H<E4, P, I3, R3>, H<E5, P, I4, R4>, H<E6, P, I5, R5>, H<E7, P, I6, R6>, H<E8, P, I7, R7>, H<E9, P, I8, R8>, H<E10, P, I9, R9>, H<E11, P, I10, R10>];
17
+ }
18
+ declare class Factory<E extends Env = Env, P extends string = string> {
19
+ #private;
20
+ private initApp?;
21
+ constructor(init?: {
22
+ initApp?: InitApp<E>;
23
+ defaultAppOptions?: AcrylOptions<E>;
24
+ });
25
+ createApp: (options?: AcrylOptions<E>) => Acryl<E>;
26
+ createMiddleware: <I extends Input = {}, R extends HandlerResponse<any> | void = void>(middleware: MiddlewareHandler<E, P, I, R extends void ? Response : R>) => MiddlewareHandler<E, P, I, R extends void ? Response : R>;
27
+ createHandlers: CreateHandlersInterface<E, P>;
28
+ }
29
+ declare const createFactory: <E extends Env = Env, P extends string = string>(init?: {
30
+ initApp?: InitApp<E>;
31
+ defaultAppOptions?: AcrylOptions<E>;
32
+ }) => Factory<E, P>;
33
+ declare const createMiddleware: <E extends Env = any, P extends string = string, I extends Input = {}, R extends HandlerResponse<any> | void = void>(middleware: MiddlewareHandler<E, P, I, R extends void ? Response : R>) => MiddlewareHandler<E, P, I, R extends void ? Response : R>;
34
+ //#endregion
35
+ export { CreateHandlersInterface, Factory, createFactory, createMiddleware };
package/lib/factory.js ADDED
@@ -0,0 +1,30 @@
1
+ import { t as Acryl } from "./app-BM0rTCp7.js";
2
+ //#region ../../plugins/acryl-router/src/core/helper/factory/index.ts
3
+ /**
4
+ * @module
5
+ * Factory Helper for Acryl.
6
+ */
7
+ var Factory = class {
8
+ initApp;
9
+ #defaultAppOptions;
10
+ constructor(init) {
11
+ this.initApp = init?.initApp;
12
+ this.#defaultAppOptions = init?.defaultAppOptions;
13
+ }
14
+ createApp = (options) => {
15
+ const app = new Acryl(options && this.#defaultAppOptions ? {
16
+ ...this.#defaultAppOptions,
17
+ ...options
18
+ } : options ?? this.#defaultAppOptions);
19
+ if (this.initApp) this.initApp(app);
20
+ return app;
21
+ };
22
+ createMiddleware = (middleware) => middleware;
23
+ createHandlers = (...handlers) => {
24
+ return handlers.filter((handler) => handler !== void 0);
25
+ };
26
+ };
27
+ const createFactory = (init) => new Factory(init);
28
+ const createMiddleware = (middleware) => middleware;
29
+ //#endregion
30
+ export { Factory, createFactory, createMiddleware };
@@ -0,0 +1,11 @@
1
+ //#region ../../plugins/acryl-router/src/core/utils/headers.d.ts
2
+ /**
3
+ * @module
4
+ * HTTP Headers utility.
5
+ */
6
+ type RequestHeader = 'A-IM' | 'Accept' | 'Accept-Additions' | 'Accept-CH' | 'Accept-Charset' | 'Accept-Datetime' | 'Accept-Encoding' | 'Accept-Features' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Query' | 'Accept-Ranges' | 'Accept-Signature' | 'Access-Control' | 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Access-Control-Request-Headers' | 'Access-Control-Request-Method' | 'Activate-Storage-Access' | 'Age' | 'Allow' | 'ALPN' | 'Alt-Svc' | 'Alt-Used' | 'Alternates' | 'AMP-Cache-Transform' | 'Apply-To-Redirect-Ref' | 'Authentication-Control' | 'Authentication-Info' | 'Authorization' | 'Available-Dictionary' | 'C-Ext' | 'C-Man' | 'C-Opt' | 'C-PEP' | 'C-PEP-Info' | 'Cache-Control' | 'Cache-Group-Invalidation' | 'Cache-Groups' | 'Cache-Status' | 'Cal-Managed-ID' | 'CalDAV-Timezones' | 'Capsule-Protocol' | 'CDN-Cache-Control' | 'CDN-Loop' | 'Cert-Not-After' | 'Cert-Not-Before' | 'Clear-Site-Data' | 'Client-Cert' | 'Client-Cert-Chain' | 'Close' | 'CMCD-Object' | 'CMCD-Request' | 'CMCD-Session' | 'CMCD-Status' | 'CMSD-Dynamic' | 'CMSD-Static' | 'Concealed-Auth-Export' | 'Configuration-Context' | 'Connection' | 'Content-Base' | 'Content-Digest' | 'Content-Disposition' | 'Content-Encoding' | 'Content-ID' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-MD5' | 'Content-Range' | 'Content-Script-Type' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Style-Type' | 'Content-Type' | 'Content-Version' | 'Cookie' | 'Cookie2' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Embedder-Policy-Report-Only' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Opener-Policy-Report-Only' | 'Cross-Origin-Resource-Policy' | 'CTA-Common-Access-Token' | 'DASL' | 'Date' | 'DAV' | 'Default-Style' | 'Delta-Base' | 'Deprecation' | 'Depth' | 'Derived-From' | 'Destination' | 'Detached-JWS' | 'Differential-ID' | 'Dictionary-ID' | 'Digest' | 'DPoP' | 'DPoP-Nonce' | 'Early-Data' | 'EDIINT-Features' | 'ETag' | 'Expect' | 'Expect-CT' | 'Expires' | 'Ext' | 'Forwarded' | 'From' | 'GetProfile' | 'Hobareg' | 'Host' | 'HTTP2-Settings' | 'If' | 'If-Match' | 'If-Modified-Since' | 'If-None-Match' | 'If-Range' | 'If-Schedule-Tag-Match' | 'If-Unmodified-Since' | 'IM' | 'Include-Referred-Token-Binding-ID' | 'Incremental' | 'Isolation' | 'Keep-Alive' | 'Label' | 'Last-Event-ID' | 'Last-Modified' | 'Link' | 'Link-Template' | 'Location' | 'Lock-Token' | 'Man' | 'Max-Forwards' | 'Memento-Datetime' | 'Meter' | 'Method-Check' | 'Method-Check-Expires' | 'MIME-Version' | 'Negotiate' | 'NEL' | 'OData-EntityId' | 'OData-Isolation' | 'OData-MaxVersion' | 'OData-Version' | 'Opt' | 'Optional-WWW-Authenticate' | 'Ordering-Type' | 'Origin' | 'Origin-Agent-Cluster' | 'OSCORE' | 'OSLC-Core-Version' | 'Overwrite' | 'P3P' | 'PEP' | 'PEP-Info' | 'Permissions-Policy' | 'PICS-Label' | 'Ping-From' | 'Ping-To' | 'Position' | 'Pragma' | 'Prefer' | 'Preference-Applied' | 'Priority' | 'ProfileObject' | 'Protocol' | 'Protocol-Info' | 'Protocol-Query' | 'Protocol-Request' | 'Proxy-Authenticate' | 'Proxy-Authentication-Info' | 'Proxy-Authorization' | 'Proxy-Features' | 'Proxy-Instruction' | 'Proxy-Status' | 'Public' | 'Public-Key-Pins' | 'Public-Key-Pins-Report-Only' | 'Range' | 'Redirect-Ref' | 'Referer' | 'Referer-Root' | 'Referrer-Policy' | 'Refresh' | 'Repeatability-Client-ID' | 'Repeatability-First-Sent' | 'Repeatability-Request-ID' | 'Repeatability-Result' | 'Replay-Nonce' | 'Reporting-Endpoints' | 'Repr-Digest' | 'Retry-After' | 'Safe' | 'Schedule-Reply' | 'Schedule-Tag' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-Storage-Access' | 'Sec-Fetch-User' | 'Sec-GPC' | 'Sec-Purpose' | 'Sec-Token-Binding' | 'Sec-WebSocket-Accept' | 'Sec-WebSocket-Extensions' | 'Sec-WebSocket-Key' | 'Sec-WebSocket-Protocol' | 'Sec-WebSocket-Version' | 'Security-Scheme' | 'Server' | 'Server-Timing' | 'Set-Cookie' | 'Set-Cookie2' | 'Set-Txn' | 'SetProfile' | 'Signature' | 'Signature-Input' | 'SLUG' | 'SoapAction' | 'Status-URI' | 'Strict-Transport-Security' | 'Sunset' | 'Surrogate-Capability' | 'Surrogate-Control' | 'TCN' | 'TE' | 'Timeout' | 'Timing-Allow-Origin' | 'Topic' | 'Traceparent' | 'Tracestate' | 'Trailer' | 'Transfer-Encoding' | 'TTL' | 'Unencoded-Digest' | 'Upgrade' | 'Urgency' | 'URI' | 'Use-As-Dictionary' | 'User-Agent' | 'Variant-Vary' | 'Vary' | 'Via' | 'Want-Content-Digest' | 'Want-Digest' | 'Want-Repr-Digest' | 'Want-Unencoded-Digest' | 'Warning' | 'WWW-Authenticate' | 'X-Content-Type-Options' | 'X-Frame-Options';
7
+ type ResponseHeader = 'Accept-Query' | 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Activate-Storage-Access' | 'Age' | 'Allow' | 'Cache-Control' | 'Cache-Group-Invalidation' | 'Cache-Groups' | 'Clear-Site-Data' | 'Content-Disposition' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Range' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Type' | 'Cookie' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Resource-Policy' | 'Date' | 'ETag' | 'Expires' | 'Incremental' | 'Last-Modified' | 'Location' | 'Permissions-Policy' | 'Pragma' | 'Retry-After' | 'Save-Data' | 'Sec-CH-Prefers-Color-Scheme' | 'Sec-CH-Prefers-Reduced-Motion' | 'Sec-CH-UA' | 'Sec-CH-UA-Arch' | 'Sec-CH-UA-Bitness' | 'Sec-CH-UA-Form-Factor' | 'Sec-CH-UA-Full-Version' | 'Sec-CH-UA-Full-Version-List' | 'Sec-CH-UA-Mobile' | 'Sec-CH-UA-Model' | 'Sec-CH-UA-Platform' | 'Sec-CH-UA-Platform-Version' | 'Sec-CH-UA-WoW64' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-User' | 'Sec-GPC' | 'Server' | 'Server-Timing' | 'Service-Worker-Navigation-Preload' | 'Set-Cookie' | 'Set-Txn' | 'Strict-Transport-Security' | 'Timing-Allow-Origin' | 'Trailer' | 'Transfer-Encoding' | 'Unencoded-Digest' | 'Upgrade' | 'Vary' | 'Want-Unencoded-Digest' | 'Warning' | 'WWW-Authenticate' | 'X-Content-Type-Options' | 'X-DNS-Prefetch-Control' | 'X-Frame-Options' | 'X-Permitted-Cross-Domain-Policies' | 'X-Powered-By' | 'X-Robots-Tag' | 'X-XSS-Protection';
8
+ type AcceptHeader = 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Ranges';
9
+ type CustomHeader = string & {};
10
+ //#endregion
11
+ export { ResponseHeader as i, CustomHeader as n, RequestHeader as r, AcceptHeader as t };
package/lib/html.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { HtmlEscapedString, raw } from "./utils/html.js";
2
+
3
+ //#region ../../plugins/acryl-router/src/core/helper/html/index.d.ts
4
+ declare const html: (strings: TemplateStringsArray, ...values: unknown[]) => HtmlEscapedString | Promise<HtmlEscapedString>;
5
+ //#endregion
6
+ export { html, raw };
package/lib/html.js ADDED
@@ -0,0 +1,31 @@
1
+ import { escapeToBuffer, raw, resolveCallbackSync, stringBufferToString } from "./utils/html.js";
2
+ //#region ../../plugins/acryl-router/src/core/helper/html/index.ts
3
+ /**
4
+ * @module
5
+ * html Helper for Acryl.
6
+ */
7
+ const html = (strings, ...values) => {
8
+ const buffer = [""];
9
+ for (let i = 0, len = strings.length - 1; i < len; i++) {
10
+ buffer[0] += strings[i];
11
+ const children = Array.isArray(values[i]) ? values[i].flat(Infinity) : [values[i]];
12
+ for (let i = 0, len = children.length; i < len; i++) {
13
+ const child = children[i];
14
+ if (typeof child === "string") escapeToBuffer(child, buffer);
15
+ else if (typeof child === "number") buffer[0] += child;
16
+ else if (typeof child === "boolean" || child === null || child === void 0) continue;
17
+ else if (typeof child === "object" && child.isEscaped) if (child.callbacks) buffer.unshift("", child);
18
+ else {
19
+ const tmp = child.toString();
20
+ if (tmp instanceof Promise) buffer.unshift("", tmp);
21
+ else buffer[0] += tmp;
22
+ }
23
+ else if (child instanceof Promise) buffer.unshift("", child);
24
+ else escapeToBuffer(child.toString(), buffer);
25
+ }
26
+ }
27
+ buffer[0] += strings.at(-1);
28
+ return buffer.length === 1 ? "callbacks" in buffer ? raw(resolveCallbackSync(raw(buffer[0], buffer.callbacks))) : raw(buffer[0]) : stringBufferToString(buffer, buffer.callbacks);
29
+ };
30
+ //#endregion
31
+ export { html, raw };