acrylblends 1.0.3 → 1.0.5

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 (256) hide show
  1. package/docs/framework/agents/index.md +6 -4
  2. package/docs/framework/workshop/README.md +3 -3
  3. package/docs/framework/workshop/facilitator.md +1 -0
  4. package/lib/accept-CNNHu4Cf.js +193 -0
  5. package/lib/{accepts-XBuZPVRI.js → accepts-Btq83xPd.js} +1 -1
  6. package/lib/accepts.js +1 -1
  7. package/lib/acryl-base.js +1 -331
  8. package/lib/adapter-CaZ6FZUU.js +37 -0
  9. package/lib/adapter.js +1 -36
  10. package/lib/{app-BM0rTCp7.js → app-CQcGWjrk.js} +4 -4
  11. package/lib/app-base-CpRMZL4v.js +332 -0
  12. package/lib/{audit-BXnYsLge.d.ts → audit-D5z9uwOP.d.ts} +14 -1
  13. package/lib/{base-NSN_SNv-.js → base-D_6kfOr-.js} +1 -1
  14. package/lib/basic-auth-C0HTRpXh.js +20 -0
  15. package/lib/basic-auth-DFLflXNe.js +95 -0
  16. package/lib/basic-auth.js +1 -94
  17. package/lib/bearer-auth-Cwxt-vgS.js +94 -0
  18. package/lib/bearer-auth.js +1 -93
  19. package/lib/body-D7f4e7w_.js +94 -0
  20. package/lib/body-limit-WmIjWRLt.js +66 -0
  21. package/lib/body-limit.js +1 -65
  22. package/lib/buffer-CkEOJCcY.js +51 -0
  23. package/lib/bun.js +3 -3
  24. package/lib/cache-B0bHH7s5.js +169 -0
  25. package/lib/cache.js +1 -168
  26. package/lib/{client-DDLXwhBo.js → client-BrMFnMEd.js} +1 -1
  27. package/lib/{client-modules-CLvWOjbd.js → client-modules-drj4mjhj.js} +4 -4
  28. package/lib/client.js +1 -1
  29. package/lib/color-COa3DplO.js +37 -0
  30. package/lib/combine-TWuGdcbC.js +137 -0
  31. package/lib/combine.js +1 -136
  32. package/lib/{components-cEW3ovK0.js → components-B2ka9Ax1.js} +4 -4
  33. package/lib/{components-JXVm45kK.js → components-PVXwaOaC.js} +2 -2
  34. package/lib/compress-BzWqsHF1.js +79 -0
  35. package/lib/compress-C-9vK4B2.d.ts +11 -0
  36. package/lib/compress-DCyrrQ5D.js +11 -0
  37. package/lib/compress.d.ts +1 -1
  38. package/lib/compress.js +2 -78
  39. package/lib/concurrent-DrF3d2c-.js +30 -0
  40. package/lib/conninfo-BCROmdnf.d.ts +11 -0
  41. package/lib/conninfo-CWJwieh4.js +19 -0
  42. package/lib/constants-CBSEudrb.js +7 -0
  43. package/lib/{context-DDO0cfuP.js → context-CkOh7Ygv.js} +2 -2
  44. package/lib/context-storage-iuPoI_CR.js +52 -0
  45. package/lib/context-storage.js +1 -51
  46. package/lib/cookie-B1LlkzOe.js +125 -0
  47. package/lib/cookie-BHIduy2T.js +82 -0
  48. package/lib/cookie.js +1 -81
  49. package/lib/cordis/db-sqlite.d.ts +1 -1
  50. package/lib/cordis/door.d.ts +17 -3
  51. package/lib/cordis/door.js +123 -16
  52. package/lib/cordis/inspect.js +4 -4
  53. package/lib/cordis/kv-db.d.ts +1 -1
  54. package/lib/cordis/kv-db.js +1 -1
  55. package/lib/cordis/kv-json.d.ts +1 -1
  56. package/lib/cordis/kv-json.js +1 -1
  57. package/lib/cordis/node-server.d.ts +1 -1
  58. package/lib/cordis/node-server.js +3 -116
  59. package/lib/cordis/router-http.d.ts +1 -1
  60. package/lib/cordis/router-http.js +2 -2
  61. package/lib/cordis/router.d.ts +1 -1
  62. package/lib/cordis/router.js +4 -4
  63. package/lib/cordis/state.js +7 -7
  64. package/lib/{core-CaY8XDZ6.js → core-BOu1jYua.js} +1 -1
  65. package/lib/cors-CbAQ-8qU.js +106 -0
  66. package/lib/cors.js +1 -105
  67. package/lib/crypto-iVP-N-tS.js +34 -0
  68. package/lib/csrf-DqqOZtgy.js +101 -0
  69. package/lib/csrf.js +1 -100
  70. package/lib/css-C5CPVMvM.js +134 -0
  71. package/lib/css.js +2 -133
  72. package/lib/db/sqlite.d.ts +1 -25
  73. package/lib/dev-CLgu-JRe.js +50 -0
  74. package/lib/dev.js +1 -49
  75. package/lib/dom-YjND9Jt3.js +74 -0
  76. package/lib/door/host.d.ts +2 -2
  77. package/lib/door/host.js +1 -1
  78. package/lib/door/page.d.ts +12 -1
  79. package/lib/door/page.js +22 -1
  80. package/lib/door/protocol.d.ts +2 -2
  81. package/lib/door/protocol.js +2 -197
  82. package/lib/encode-BhbNLrjp.js +33 -0
  83. package/lib/factory-CLdSf-xS.js +30 -0
  84. package/lib/factory.js +1 -29
  85. package/lib/handler-C0wZ0KwO.js +12 -0
  86. package/lib/helpers-BEjcdbgw.js +5 -0
  87. package/lib/{hooks-w72iLeFR.js → hooks-CfC07ri0.js} +1 -1
  88. package/lib/html-CgNa89xw.js +31 -0
  89. package/lib/html-DGExBFNg.js +103 -0
  90. package/lib/html.d.ts +2 -5
  91. package/lib/html.js +2 -30
  92. package/lib/http-exception-MjWkT89V.js +54 -0
  93. package/lib/http-exception.js +1 -53
  94. package/lib/{index-D4nVR3wu.d.ts → index-DMOtA-NJ.d.ts} +7 -1
  95. package/lib/index-dAzQsJG9.d.ts +6 -0
  96. package/lib/index.js +3 -3
  97. package/lib/ip-restriction-jKtKCRM_.js +166 -0
  98. package/lib/ip-restriction.js +1 -165
  99. package/lib/ipaddr-DCoIo528.js +238 -0
  100. package/lib/jsx/dom/client.js +1 -1
  101. package/lib/jsx/dom/jsx-dev-runtime.js +1 -1
  102. package/lib/jsx/dom/jsx-runtime.js +2 -1
  103. package/lib/jsx/dom/server.js +3 -3
  104. package/lib/jsx/dom.js +5 -73
  105. package/lib/jsx/jsx-dev-runtime.d.ts +2 -5
  106. package/lib/jsx/jsx-dev-runtime.js +2 -13
  107. package/lib/jsx/jsx-runtime.d.ts +2 -2
  108. package/lib/jsx/jsx-runtime.js +4 -4
  109. package/lib/jsx/streaming.js +1 -1
  110. package/lib/jsx-CUQgttxU.js +47 -0
  111. package/lib/jsx-dev-runtime-B4WTyq8r.js +14 -0
  112. package/lib/{jsx-dev-runtime-CWLRA2F3.js → jsx-dev-runtime-BLfA-EhI.js} +2 -2
  113. package/lib/jsx-dev-runtime-CGt4kNYr.d.ts +6 -0
  114. package/lib/jsx-renderer-CfifM4hT.js +99 -0
  115. package/lib/jsx-renderer.js +1 -98
  116. package/lib/jsx-runtime-COCRWBJ9.js +2 -0
  117. package/lib/jsx.js +5 -46
  118. package/lib/{jwk-LkzeoaU8.js → jwk-CDPpYQpD.js} +3 -3
  119. package/lib/jwk.js +1 -1
  120. package/lib/{jwt-BGJBw5AF.js → jwt-BXoIA2fQ.js} +2 -2
  121. package/lib/{jwt-CskdhEW9.js → jwt-lyS4Q3mT.js} +3 -3
  122. package/lib/jwt.js +2 -2
  123. package/lib/kv/db.d.ts +1 -10
  124. package/lib/kv/db.js +1 -56
  125. package/lib/kv/json.d.ts +1 -9
  126. package/lib/kv/json.js +1 -223
  127. package/lib/{language-D9a4zqvn.js → language-DeGRtLJt.js} +2 -2
  128. package/lib/language.js +1 -1
  129. package/lib/{linear-router-C3FPib6h.js → linear-router-CmZn_JLV.js} +2 -2
  130. package/lib/logger-Ckxu8diz.js +54 -0
  131. package/lib/logger.js +1 -53
  132. package/lib/loopback-only-BbasoF7R.js +90 -0
  133. package/lib/loopback-only.js +1 -89
  134. package/lib/method-not-allowed-TO2_hnfl.js +82 -0
  135. package/lib/method-not-allowed.js +1 -81
  136. package/lib/method-override-DnZKfJbV.js +103 -0
  137. package/lib/method-override.js +1 -102
  138. package/lib/middleware-BfG_fp8P.js +12 -0
  139. package/lib/mime-BnScXkQn.js +77 -0
  140. package/lib/mount-QkK_3NtJ.js +67 -0
  141. package/lib/mount.js +1 -66
  142. package/lib/node-server/conninfo.d.ts +1 -10
  143. package/lib/node-server/conninfo.js +1 -18
  144. package/lib/node-server/register.js +25 -2
  145. package/lib/node-server/serve-static.d.ts +1 -17
  146. package/lib/node-server/serve-static.js +1 -1
  147. package/lib/node-server.d.ts +2 -2
  148. package/lib/node-server.js +4 -4
  149. package/lib/open-BqK4D2Wn.d.ts +11 -0
  150. package/lib/open-But9E2rL.js +57 -0
  151. package/lib/open-CULVJgOc.d.ts +12 -0
  152. package/lib/open-Dp4sxspc.js +224 -0
  153. package/lib/open-T7kgbO2O.d.ts +27 -0
  154. package/lib/{pattern-router-HZxjDGEQ.js → pattern-router-CJBecJBd.js} +1 -1
  155. package/lib/powered-by-CXQNjNIX.js +24 -0
  156. package/lib/powered-by.js +1 -23
  157. package/lib/pretty-json-CeC1yvYt.js +39 -0
  158. package/lib/pretty-json.js +1 -38
  159. package/lib/{protocol-BizVt4J6.d.ts → protocol-C37gPePD.d.ts} +9 -2
  160. package/lib/protocol-Dt0AZBOz.js +213 -0
  161. package/lib/proxy-C2w_mH7k.js +121 -0
  162. package/lib/proxy.js +1 -120
  163. package/lib/quick.js +4 -4
  164. package/lib/{reg-exp-router-DC1R3qoY.js → reg-exp-router-C_WV84eV.js} +2 -2
  165. package/lib/request-DvMgGtlW.js +323 -0
  166. package/lib/request.js +1 -322
  167. package/lib/route-D8m-a2I1.js +126 -0
  168. package/lib/route.js +1 -125
  169. package/lib/router/linear-router.js +1 -1
  170. package/lib/router/pattern-router.js +1 -1
  171. package/lib/router/reg-exp-router.js +1 -1
  172. package/lib/router/smart-router.js +1 -1
  173. package/lib/router/trie-router.js +1 -1
  174. package/lib/router-Be_o6nFu.js +35 -0
  175. package/lib/router.js +1 -34
  176. package/lib/schema-validator-EK3cUUCt.js +22 -0
  177. package/lib/schema-validator.js +1 -21
  178. package/lib/{secure-headers-mP3j6Hm6.js → secure-headers-C5ZOcXqk.js} +1 -1
  179. package/lib/secure-headers.js +1 -1
  180. package/lib/serve-static-B7sqnftW.d.ts +18 -0
  181. package/lib/{serve-static-3uo_9rjF.js → serve-static-C1Nkj_xB.js} +2 -2
  182. package/lib/{serve-static-Cp5adzGo.js → serve-static-EiJf1zkO.js} +4 -4
  183. package/lib/serve-static.js +1 -1
  184. package/lib/{smart-router-C5CZ5XSM.js → smart-router-BjxkDQCE.js} +1 -1
  185. package/lib/{snapshot-text-DmE0YfeZ.js → snapshot-text-Bbx43mN0.js} +57 -9
  186. package/lib/{src-2Z4mJg0x.js → src-BTBm4OPD.js} +22 -6
  187. package/lib/src-LX0E4ec4.js +117 -0
  188. package/lib/{ssg-BwjcA-Ge.js → ssg-BEl7MHqg.js} +5 -5
  189. package/lib/ssg.js +1 -1
  190. package/lib/stream-CzM_SHkq.js +88 -0
  191. package/lib/{streaming-DHST3Scg.js → streaming-BlDaph8U.js} +3 -3
  192. package/lib/streaming.js +1 -1
  193. package/lib/{test-websocket-D8WWqE5G.js → test-websocket-BLeEvybj.js} +2 -2
  194. package/lib/testing-BQx5T_UX.js +17 -0
  195. package/lib/testing.js +1 -16
  196. package/lib/timeout-FeqZ9A-0.js +42 -0
  197. package/lib/timeout.js +1 -41
  198. package/lib/tiny.js +2 -2
  199. package/lib/trailing-slash-DwTx-1sk.js +85 -0
  200. package/lib/trailing-slash.js +1 -84
  201. package/lib/{trie-router-CfFbapzL.js → trie-router-JydLKUa2.js} +2 -2
  202. package/lib/url-BPh4d6j-.js +197 -0
  203. package/lib/utils/accept.js +1 -192
  204. package/lib/utils/basic-auth.js +1 -19
  205. package/lib/utils/body.js +1 -93
  206. package/lib/utils/buffer.js +1 -50
  207. package/lib/utils/color.js +1 -36
  208. package/lib/utils/compress.d.ts +1 -10
  209. package/lib/utils/compress.js +1 -10
  210. package/lib/utils/concurrent.js +1 -29
  211. package/lib/utils/constants.js +1 -6
  212. package/lib/utils/cookie.js +1 -124
  213. package/lib/utils/crypto.js +1 -33
  214. package/lib/utils/encode.js +1 -32
  215. package/lib/utils/handler.js +1 -11
  216. package/lib/utils/html.js +1 -102
  217. package/lib/utils/ipaddr.js +1 -237
  218. package/lib/utils/jwt.js +1 -1
  219. package/lib/utils/mime.js +1 -76
  220. package/lib/utils/stream.js +1 -87
  221. package/lib/utils/url.js +1 -196
  222. package/lib/{validator-D84mq-dO.js → validator-Btiyt5VJ.js} +3 -3
  223. package/lib/validator.js +1 -1
  224. package/lib/websocket-DsyBIKVA.js +56 -0
  225. package/lib/ws.js +1 -55
  226. package/package.json +1 -1
  227. package/plugins/acryl-door/src/cli/acryl.ts +5 -3
  228. package/plugins/acryl-door/src/host/channel.ts +36 -0
  229. package/plugins/acryl-door/src/host/chat-tools.ts +2 -0
  230. package/plugins/acryl-door/src/host/door.ts +44 -5
  231. package/plugins/acryl-door/src/host/shim.ts +23 -0
  232. package/plugins/acryl-door/src/host/verbs.ts +4 -3
  233. package/plugins/acryl-door/src/index.ts +39 -3
  234. package/plugins/acryl-door/src/page/driver/driver.ts +22 -1
  235. package/plugins/acryl-door/src/page/protocol.ts +13 -2
  236. package/plugins/acryl-node-server/src/register.ts +29 -2
  237. package/plugins/acryl-router/src/service.ts +19 -1
  238. package/plugins/agent/model.ts +6 -1
  239. package/plugins/agent/tools.ts +12 -2
  240. package/plugins/agent-panel/client/describe.ts +44 -0
  241. package/plugins/agent-panel/client/main.ts +67 -35
  242. package/plugins/agent-panel/index.ts +137 -35
  243. package/plugins/desktop/attach.ts +72 -0
  244. package/plugins/desktop/main.ts +17 -4
  245. package/plugins/extensions/index.ts +3 -4
  246. package/plugins/extensions/stage.ts +33 -5
  247. package/plugins/openai/index.ts +1 -1
  248. package/shared/DEFAULTS.md +4 -0
  249. package/templates/agent/AGENTS.md +2 -0
  250. package/templates/agent/blend.yaml +4 -1
  251. package/templates/agent/src/app.ts +2 -0
  252. package/templates/agent/src/routes.ts +1 -1
  253. package/templates/agent/template.json +1 -0
  254. package/templates/agent/test/builder.test.ts +26 -21
  255. package/lib/helpers-CvTauQT5.js +0 -5
  256. package/lib/middleware-CPQ8himN.js +0 -12
@@ -35,18 +35,20 @@ See [Acryl in a Cordis app](../cordis/acryl-in-a-cordis-app.md), [Plugin lifecyc
35
35
 
36
36
  ## The agent panel and the terminals
37
37
 
38
- The panel is a chat button on every page of the running app, and `driver-pty` adds real terminals to it. Both are **development only** (see [what runs in production](../guides/production.md)). They need the rows of the `agent` template (`agent` and `extensions`, with the `model`, `tools` and `memory` the agent brings), so start from that template:
38
+ The panel is a chat button on every page of the running app. **A new app from the `agent` template has it** (`npm create acrylblends@latest my-app agent`), and `driver-pty` adds real terminals to it. Both are **development only** (see [what runs in production](../guides/production.md)).
39
39
 
40
40
  ```sh
41
41
  npm create acrylblends@latest my-app agent
42
42
  cd my-app
43
43
  npm install
44
- npx acrylblends add agent-panel driver-pty
44
+ npm run dev # the panel is the button at the corner of the page
45
+ npx acrylblends add driver-pty # optional: real terminals (pty:claude, pty:codex, pty:pi) in the panel
45
46
  npm install
46
- npm run dev
47
47
  ```
48
48
 
49
- - `add` puts the `agent-panel` row (and `driver-pty`'s after it) in `blend.yaml` before the `routes` row and registers both in `src/app.ts`. On an app without the `agent` and `extensions` rows, such as `blank`, it refuses before it copies anything and says which rows are missing.
49
+ - The panel needs the `agent` and `extensions` rows, which only the `agent` template has: `add agent-panel` on an app without them (a `blank` app) refuses before it copies anything and says which rows are missing, and on an `agent` app it says the panel is already there. An agent-template app made before 1.0.5 gets it with `npx acrylblends add agent-panel`.
50
+ - `add driver-pty` puts the driver's row after the panel's in `blend.yaml` and registers it in `src/app.ts`.
51
+ - A **run belongs to the app, not to the page**: when the page reloads (the door reloads it after a plugin change) the panel shows the question and the events so far and follows the run to its end; **Stop** is the only thing that cancels it.
50
52
  - **The panel's coding agents are yours.** `claude`, `codex` and `pi` run on the machine that runs the app, in the app folder, with the login of the person who started it: `claude` and `codex` use their own signed-in sessions, and `pi` is offered when `DEEPSEEK_API_KEY` is set or `pi` has stored a DeepSeek login (`~/.pi/agent/auth.json`, read from the `HOME` of the process that runs the app: an app started under another `HOME` does not see the login, and the panel then lists `pty:pi` but no chat `pi`). A program that is not installed, or is not logged in, is not offered; nothing is shared between machines, and a workshop laptop needs its own login. The panel's own `agent` (the offline scripted one) needs none.
51
53
  - `pi` has to be an executable on the `PATH`; a shell function that wraps the binary is fine as long as the binary itself is found by `which pi`.
52
54
  - `driver-pty` brings `node-pty`, which ships prebuilt binaries for macOS, Windows and Linux. npm 11 and pnpm warn that its install script was not run (they ask you to approve dependency install scripts); you can ignore the warning. If no `pty:` terminal is offered and the app prints why at start, approve and rebuild: `npm approve-scripts node-pty`, then `npm rebuild node-pty` (pnpm: `pnpm approve-builds`).
@@ -182,8 +182,8 @@ Then `inject: ['router', 'kv', 'db']` with `import type {} from '../plugins/acry
182
182
  `await ctx.db.run('INSERT INTO visits (at) VALUES (?)', new Date().toISOString())` before the reply. The database is `my-hero/.acrylblends/data.sqlite`,
183
183
  and the migrations run at start, in order.
184
184
 
185
- **Stuck?** `migrations "migrations" is relative, but this app has no file base URL` means the folder was named in `blend.yaml`; move it into
186
- `src/app.ts` as above. "no such table" means the file is not in `migrations/` at the app root.
185
+ **Stuck?** `migrations "migrations" is relative, but this app has no file base URL` means the app has `acrylblends` older than 1.0.3, where a relative path in `blend.yaml` was not read
186
+ from the app folder; move it into `src/app.ts` as above, or update (`npx acrylblends@latest upgrade`). "no such table" means the file is not in `migrations/` at the app root.
187
187
 
188
188
  ## 5. A desktop window (7 minutes)
189
189
 
@@ -280,7 +280,7 @@ few minutes; the panel shows each step, and has a stop button. Open `/board` whe
280
280
  A terminal agent works too: choose `pty:codex` (or `pty:claude`, `pty:pi`) for its normal interactive session inside the app folder, where it can use
281
281
  the door (`.acryl/bin/acryl`) to look at the page it built.
282
282
 
283
- **Stuck?** The panel uses your own agent account: `codex login` (or `claude`) in a terminal first. If `npm install` warns that npm blocked
283
+ **Stuck?** The panel uses your own agent account: `codex login` (or `claude`) in a terminal first. Your own agent settings travel with it: skills or hooks of your own can make it stop and ask for approval instead of acting, so write the task as "do it now, without asking for approval", or start the agent from a clean configuration (a fresh `CODEX_HOME`, or no personal skills). If `npm install` warns that npm blocked
284
284
  `node-pty`'s install script, ignore it: prebuilt binaries ship. Only if the panel lists no `pty:` terminal, run `npm approve-scripts node-pty` and
285
285
  `npm rebuild node-pty` (the `add` output says the same).
286
286
 
@@ -54,6 +54,7 @@ what the optional column is for, and the handout names the same choices so nobod
54
54
 
55
55
  These are the defects found by the walk. They are known; say so rather than letting people think they broke something.
56
56
 
57
+ - **An agent with its own settings acts differently.** Skills, hooks and instructions in a person's own Codex or Claude configuration travel into the panel's run: on the owner's laptop Codex stopped to "present a design for approval" instead of building. Word every task for the agent as "do it now, without asking for approval", and for a demo machine start the agent from a clean configuration (a fresh `CODEX_HOME`, no personal skills).
57
58
  - **The data step is the slow one.** Wiring `kv` then `db` by hand is about ten minutes of edits for a newcomer (two rows, two registry lines, two
58
59
  type imports, the migrations folder). It is the block the handout names optional, and the one to help with first.
59
60
  - **A relative migrations path in `blend.yaml` fails.** `migrations: migrations` in the row stops the app with "this app has no file base URL to
@@ -0,0 +1,193 @@
1
+ //#region ../../plugins/acryl-router/src/core/utils/accept.ts
2
+ const isWhitespace = (char) => char === 32 || char === 9 || char === 10 || char === 13;
3
+ const consumeWhitespace = (acceptHeader, startIndex) => {
4
+ while (startIndex < acceptHeader.length) {
5
+ if (!isWhitespace(acceptHeader.charCodeAt(startIndex))) break;
6
+ startIndex++;
7
+ }
8
+ return startIndex;
9
+ };
10
+ const ignoreTrailingWhitespace = (acceptHeader, startIndex) => {
11
+ while (startIndex > 0) {
12
+ if (!isWhitespace(acceptHeader.charCodeAt(startIndex - 1))) break;
13
+ startIndex--;
14
+ }
15
+ return startIndex;
16
+ };
17
+ const skipInvalidParam = (acceptHeader, startIndex) => {
18
+ while (startIndex < acceptHeader.length) {
19
+ const char = acceptHeader.charCodeAt(startIndex);
20
+ if (char === 59) return [startIndex + 1, true];
21
+ if (char === 44) return [startIndex + 1, false];
22
+ startIndex++;
23
+ }
24
+ return [startIndex, false];
25
+ };
26
+ const skipInvalidAcceptValue = (acceptHeader, startIndex) => {
27
+ let i = startIndex;
28
+ let inQuotes = false;
29
+ while (i < acceptHeader.length) {
30
+ const char = acceptHeader.charCodeAt(i);
31
+ if (inQuotes && char === 92) i++;
32
+ else if (char === 34) inQuotes = !inQuotes;
33
+ else if (!inQuotes && char === 44) return i + 1;
34
+ i++;
35
+ }
36
+ return i;
37
+ };
38
+ const getNextParam = (acceptHeader, startIndex) => {
39
+ startIndex = consumeWhitespace(acceptHeader, startIndex);
40
+ let i = startIndex;
41
+ let key;
42
+ let value;
43
+ let hasNext = false;
44
+ while (i < acceptHeader.length) {
45
+ const char = acceptHeader.charCodeAt(i);
46
+ if (char === 61) {
47
+ key = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
48
+ i++;
49
+ break;
50
+ }
51
+ if (char === 59) return [
52
+ i + 1,
53
+ void 0,
54
+ void 0,
55
+ true
56
+ ];
57
+ if (char === 44) return [
58
+ i + 1,
59
+ void 0,
60
+ void 0,
61
+ false
62
+ ];
63
+ i++;
64
+ }
65
+ if (key === void 0) return [
66
+ i,
67
+ void 0,
68
+ void 0,
69
+ false
70
+ ];
71
+ i = consumeWhitespace(acceptHeader, i);
72
+ if (acceptHeader.charCodeAt(i) === 61) {
73
+ const skipResult = skipInvalidParam(acceptHeader, i + 1);
74
+ return [
75
+ skipResult[0],
76
+ key,
77
+ void 0,
78
+ skipResult[1]
79
+ ];
80
+ }
81
+ let inQuotes = false;
82
+ const paramStartIndex = i;
83
+ while (i < acceptHeader.length) {
84
+ const char = acceptHeader.charCodeAt(i);
85
+ if (inQuotes && char === 92) i++;
86
+ else if (char === 34) {
87
+ if (inQuotes) {
88
+ let nextIndex = consumeWhitespace(acceptHeader, i + 1);
89
+ const nextChar = acceptHeader.charCodeAt(nextIndex);
90
+ if (nextIndex < acceptHeader.length && !(nextChar === 59 || nextChar === 44)) {
91
+ const skipResult = skipInvalidParam(acceptHeader, nextIndex);
92
+ return [
93
+ skipResult[0],
94
+ key,
95
+ void 0,
96
+ skipResult[1]
97
+ ];
98
+ }
99
+ value = acceptHeader.slice(paramStartIndex + 1, i);
100
+ if (value.includes("\\")) value = value.replace(/\\(.)/g, "$1");
101
+ if (nextChar === 44) return [
102
+ nextIndex + 1,
103
+ key,
104
+ value,
105
+ false
106
+ ];
107
+ if (nextChar === 59) {
108
+ hasNext = true;
109
+ nextIndex++;
110
+ }
111
+ i = nextIndex;
112
+ break;
113
+ }
114
+ inQuotes = true;
115
+ } else if (!inQuotes && (char === 59 || char === 44)) {
116
+ value = acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i));
117
+ if (char === 59) hasNext = true;
118
+ i++;
119
+ break;
120
+ }
121
+ i++;
122
+ }
123
+ return [
124
+ i,
125
+ key,
126
+ value ?? acceptHeader.slice(paramStartIndex, ignoreTrailingWhitespace(acceptHeader, i)),
127
+ hasNext
128
+ ];
129
+ };
130
+ const getNextAcceptValue = (acceptHeader, startIndex) => {
131
+ const accept = {
132
+ type: "",
133
+ params: Object.create(null),
134
+ q: 1
135
+ };
136
+ startIndex = consumeWhitespace(acceptHeader, startIndex);
137
+ let i = startIndex;
138
+ while (i < acceptHeader.length) {
139
+ const char = acceptHeader.charCodeAt(i);
140
+ if (char === 59 || char === 44) {
141
+ accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, i));
142
+ i++;
143
+ if (char === 44) return [i, accept.type ? accept : void 0];
144
+ if (!accept.type) return [skipInvalidAcceptValue(acceptHeader, i), void 0];
145
+ break;
146
+ }
147
+ i++;
148
+ }
149
+ if (!accept.type) {
150
+ accept.type = acceptHeader.slice(startIndex, ignoreTrailingWhitespace(acceptHeader, acceptHeader.length));
151
+ return [acceptHeader.length, accept.type ? accept : void 0];
152
+ }
153
+ let param;
154
+ let value;
155
+ let hasNext;
156
+ while (i < acceptHeader.length) {
157
+ [i, param, value, hasNext] = getNextParam(acceptHeader, i);
158
+ if (param && value) accept.params[param] = value;
159
+ if (!hasNext) break;
160
+ }
161
+ return [i, accept];
162
+ };
163
+ const parseAccept = (acceptHeader) => {
164
+ if (!acceptHeader) return [];
165
+ const values = [];
166
+ let i = 0;
167
+ let accept;
168
+ let requiresSort = false;
169
+ let lastAccept;
170
+ while (i < acceptHeader.length) {
171
+ [i, accept] = getNextAcceptValue(acceptHeader, i);
172
+ if (accept) {
173
+ accept.q = parseQuality(accept.params.q ?? accept.params.Q);
174
+ values.push(accept);
175
+ if (lastAccept && lastAccept.q < accept.q) requiresSort = true;
176
+ lastAccept = accept;
177
+ }
178
+ }
179
+ if (requiresSort) values.sort((a, b) => b.q - a.q);
180
+ return values;
181
+ };
182
+ const parseQuality = (qVal) => {
183
+ if (qVal === void 0) return 1;
184
+ if (qVal === "") return 1;
185
+ if (qVal === "NaN") return 0;
186
+ const num = Number(qVal);
187
+ if (Number.isNaN(num)) return 1;
188
+ if (num < 0) return 0;
189
+ if (num > 1) return 1;
190
+ return num;
191
+ };
192
+ //#endregion
193
+ export { parseAccept as t };
@@ -1,4 +1,4 @@
1
- import { parseAccept } from "./utils/accept.js";
1
+ import { t as parseAccept } from "./accept-CNNHu4Cf.js";
2
2
  //#region ../../plugins/acryl-router/src/core/helper/accepts/accepts.ts
3
3
  const matchType = (acceptType, supportedType) => {
4
4
  const accept = acceptType.toLowerCase();
package/lib/accepts.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as accepts } from "./accepts-XBuZPVRI.js";
1
+ import { t as accepts } from "./accepts-Btq83xPd.js";
2
2
  export { accepts };
package/lib/acryl-base.js CHANGED
@@ -1,332 +1,2 @@
1
- import { t as compose } from "./compose-BuW2B6PZ.js";
2
- import { getPath, getPathNoStrict, mergePath } from "./utils/url.js";
3
- import { t as Context } from "./context-DDO0cfuP.js";
4
- import { METHODS } from "./router.js";
5
- import { COMPOSED_HANDLER } from "./utils/constants.js";
6
- //#region ../../plugins/acryl-router/src/core/app-base.ts
7
- /**
8
- * @module
9
- * This module is the base module for the Acryl object.
10
- */
11
- const notFoundHandler = (c) => {
12
- return c.text("404 Not Found", 404);
13
- };
14
- const errorHandler = (err, c) => {
15
- if ("getResponse" in err) {
16
- const res = err.getResponse();
17
- return c.newResponse(res.body, res);
18
- }
19
- console.error(err);
20
- return c.text("Internal Server Error", 500);
21
- };
22
- var Acryl = class Acryl {
23
- get;
24
- post;
25
- put;
26
- delete;
27
- options;
28
- patch;
29
- query;
30
- all;
31
- on;
32
- use;
33
- router;
34
- getPath;
35
- _basePath = "/";
36
- #path = "/";
37
- routes = [];
38
- constructor(options = {}) {
39
- [...METHODS, "all"].forEach((method) => {
40
- this[method] = (args1, ...args) => {
41
- const methodName = method.toUpperCase();
42
- if (typeof args1 === "string") this.#path = args1;
43
- else this.#addRoute(methodName, this.#path, args1);
44
- args.forEach((handler) => {
45
- this.#addRoute(methodName, this.#path, handler);
46
- });
47
- return this;
48
- };
49
- });
50
- this.on = (method, path, ...handlers) => {
51
- for (const p of [path].flat()) {
52
- this.#path = p;
53
- for (const m of [method].flat()) {
54
- const methodName = m.toUpperCase();
55
- for (const handler of handlers) this.#addRoute(methodName, this.#path, handler);
56
- }
57
- }
58
- return this;
59
- };
60
- this.use = (arg1, ...handlers) => {
61
- if (typeof arg1 === "string") this.#path = arg1;
62
- else {
63
- this.#path = "*";
64
- handlers.unshift(arg1);
65
- }
66
- handlers.forEach((handler) => {
67
- this.#addRoute("ALL", this.#path, handler);
68
- });
69
- return this;
70
- };
71
- const { strict, ...optionsWithoutStrict } = options;
72
- Object.assign(this, optionsWithoutStrict);
73
- this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;
74
- }
75
- #clone() {
76
- const clone = new Acryl({
77
- router: this.router,
78
- getPath: this.getPath
79
- });
80
- clone.errorHandler = this.errorHandler;
81
- clone.#notFoundHandler = this.#notFoundHandler;
82
- clone.routes = this.routes;
83
- return clone;
84
- }
85
- #notFoundHandler = notFoundHandler;
86
- errorHandler = errorHandler;
87
- /**
88
- * `.route()` allows grouping other Acryl instance in routes.
89
- *
90
- *
91
- * @param {string} path - base Path
92
- * @param {Acryl} app - other Acryl instance
93
- * @returns {Acryl} routed Acryl instance
94
- *
95
- * @example
96
- * ```ts
97
- * const app = new Acryl()
98
- * const app2 = new Acryl()
99
- *
100
- * app2.get("/user", (c) => c.text("user"))
101
- * app.route("/api", app2) // GET /api/user
102
- * ```
103
- */
104
- route(path, app) {
105
- const subApp = this.basePath(path);
106
- app.routes.map((r) => {
107
- let handler;
108
- if (app.errorHandler === errorHandler) handler = r.handler;
109
- else {
110
- handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;
111
- handler[COMPOSED_HANDLER] = r.handler;
112
- }
113
- subApp.#addRoute(r.method, r.path, handler, r.basePath);
114
- });
115
- return this;
116
- }
117
- /**
118
- * `.basePath()` allows base paths to be specified.
119
- *
120
- *
121
- * @param {string} path - base Path
122
- * @returns {Acryl} changed Acryl instance
123
- *
124
- * @example
125
- * ```ts
126
- * const api = new Acryl().basePath('/api')
127
- * ```
128
- */
129
- basePath(path) {
130
- const subApp = this.#clone();
131
- subApp._basePath = mergePath(this._basePath, path);
132
- return subApp;
133
- }
134
- /**
135
- * `.onError()` handles an error and returns a customized Response.
136
- *
137
- *
138
- * @param {ErrorHandler} handler - request Handler for error
139
- * @returns {Acryl} changed Acryl instance
140
- *
141
- * @example
142
- * ```ts
143
- * app.onError((err, c) => {
144
- * console.error(`${err}`)
145
- * return c.text('Custom Error Message', 500)
146
- * })
147
- * ```
148
- */
149
- onError = (handler) => {
150
- this.errorHandler = handler;
151
- return this;
152
- };
153
- /**
154
- * `.notFound()` allows you to customize a Not Found Response.
155
- *
156
- *
157
- * @param {NotFoundHandler} handler - request handler for not-found
158
- * @returns {Acryl} changed Acryl instance
159
- *
160
- * @example
161
- * ```ts
162
- * app.notFound((c) => {
163
- * return c.text('Custom 404 Message', 404)
164
- * })
165
- * ```
166
- */
167
- notFound = (handler) => {
168
- this.#notFoundHandler = handler;
169
- return this;
170
- };
171
- /**
172
- * `.mount()` allows you to mount applications built with other frameworks into your Acryl application.
173
- *
174
- * @deprecated Use `mount()` from `acryl-router/mount` instead. `.mount()` will be removed in v5.
175
- *
176
- *
177
- * @param {string} path - base Path
178
- * @param {Function} applicationHandler - other Request Handler
179
- * @param {MountOptions} [options] - options of `.mount()`
180
- * @returns {Acryl} mounted Acryl instance
181
- *
182
- * @example
183
- * ```ts
184
- * import { Router as IttyRouter } from 'itty-router'
185
- * import { Acryl } from 'acrylblends'
186
- * // Create itty-router application
187
- * const ittyRouter = IttyRouter()
188
- * // GET /itty-router/hello
189
- * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))
190
- *
191
- * const app = new Acryl()
192
- * app.mount('/itty-router', ittyRouter.handle)
193
- * ```
194
- *
195
- * @example
196
- * ```ts
197
- * const app = new Acryl()
198
- * // Send the request to another application without modification.
199
- * app.mount('/app', anotherApp, {
200
- * replaceRequest: (req) => req,
201
- * })
202
- * ```
203
- */
204
- mount(path, applicationHandler, options) {
205
- let replaceRequest;
206
- let optionHandler;
207
- if (options) if (typeof options === "function") optionHandler = options;
208
- else {
209
- optionHandler = options.optionHandler;
210
- if (options.replaceRequest === false) replaceRequest = (request) => request;
211
- else replaceRequest = options.replaceRequest;
212
- }
213
- const getOptions = optionHandler ? (c) => {
214
- const options = optionHandler(c);
215
- return Array.isArray(options) ? options : [options];
216
- } : (c) => {
217
- let executionContext = void 0;
218
- try {
219
- executionContext = c.executionCtx;
220
- } catch {}
221
- return [c.env, executionContext];
222
- };
223
- replaceRequest ||= (() => {
224
- const mergedPath = mergePath(this._basePath, path);
225
- const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
226
- return (request) => {
227
- const url = new URL(request.url);
228
- url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
229
- return new Request(url, request);
230
- };
231
- })();
232
- const handler = async (c, next) => {
233
- const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));
234
- if (res) return res;
235
- await next();
236
- };
237
- this.#addRoute("ALL", mergePath(path, "*"), handler);
238
- return this;
239
- }
240
- #addRoute(method, path, handler, baseRoutePath) {
241
- path = mergePath(this._basePath, path);
242
- const r = {
243
- basePath: baseRoutePath !== void 0 ? mergePath(this._basePath, baseRoutePath) : this._basePath,
244
- path,
245
- method,
246
- handler
247
- };
248
- this.router.add(method, path, [handler, r]);
249
- this.routes.push(r);
250
- }
251
- #handleError(err, c) {
252
- if (err instanceof Error) return this.errorHandler(err, c);
253
- throw err;
254
- }
255
- #dispatch(request, executionCtx, env, method) {
256
- if (method === "HEAD") return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, "GET")))();
257
- const path = this.getPath(request, { env });
258
- const matchResult = this.router.match(method, path);
259
- const c = new Context(request, {
260
- path,
261
- matchResult,
262
- env,
263
- executionCtx,
264
- notFoundHandler: this.#notFoundHandler
265
- });
266
- if (matchResult[0].length === 1) {
267
- let res;
268
- try {
269
- res = matchResult[0][0][0][0](c, async () => {
270
- c.res = await this.#notFoundHandler(c);
271
- });
272
- } catch (err) {
273
- return this.#handleError(err, c);
274
- }
275
- return res instanceof Promise ? res.then((resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);
276
- }
277
- const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);
278
- return (async () => {
279
- try {
280
- const context = await composed(c);
281
- if (!context.finalized) throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");
282
- return context.res;
283
- } catch (err) {
284
- return this.#handleError(err, c);
285
- }
286
- })();
287
- }
288
- /**
289
- * `.fetch()` will be entry point of your app.
290
- *
291
- *
292
- * @param {Request} request - request Object of request
293
- * @param {Env} env - env Object
294
- * @param {ExecutionContext} executionCtx - context of execution
295
- * @returns {Response | Promise<Response>} response of request
296
- *
297
- */
298
- fetch = (request, ...rest) => {
299
- return this.#dispatch(request, rest[1], rest[0], request.method);
300
- };
301
- /**
302
- * `.request()` is a useful method for testing.
303
- * You can pass a URL or pathname to send a GET request.
304
- * app will return a Response object.
305
- * ```ts
306
- * test('GET /hello is ok', async () => {
307
- * const res = await app.request('/hello')
308
- * expect(res.status).toBe(200)
309
- * })
310
- * ```
311
- */
312
- request = (input, requestInit, Env, executionCtx) => {
313
- if (input instanceof Request) return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);
314
- input = input.toString();
315
- return this.fetch(new Request(/^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`, requestInit), Env, executionCtx);
316
- };
317
- /**
318
- * `.fire()` automatically adds a global fetch event listener.
319
- * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.
320
- * @deprecated
321
- * ACRYL ships no service-worker adapter: mount the app with `ctx.router.route(path, app)` and serve it through an ACRYL adapter instead.
322
- * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
323
- * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/
324
- */
325
- fire = () => {
326
- addEventListener("fetch", (event) => {
327
- event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));
328
- });
329
- };
330
- };
331
- //#endregion
1
+ import { t as Acryl } from "./app-base-CpRMZL4v.js";
332
2
  export { Acryl as AcrylBase };
@@ -0,0 +1,37 @@
1
+ //#region ../../plugins/acryl-router/src/core/helper/adapter/index.ts
2
+ const env = (c, runtime) => {
3
+ const globalEnv = globalThis?.process?.env;
4
+ runtime ??= getRuntimeKey();
5
+ return {
6
+ bun: () => globalEnv,
7
+ node: () => globalEnv,
8
+ "edge-light": () => globalEnv,
9
+ deno: () => {
10
+ return Deno.env.toObject();
11
+ },
12
+ workerd: () => c.env,
13
+ fastly: () => ({}),
14
+ other: () => ({})
15
+ }[runtime]();
16
+ };
17
+ const knownUserAgents = {
18
+ deno: "Deno",
19
+ bun: "Bun",
20
+ workerd: "Cloudflare-Workers",
21
+ node: "Node.js"
22
+ };
23
+ const getRuntimeKey = () => {
24
+ const global = globalThis;
25
+ if (typeof navigator !== "undefined" && typeof navigator.userAgent === "string") {
26
+ for (const [runtimeKey, userAgent] of Object.entries(knownUserAgents)) if (checkUserAgentEquals(userAgent)) return runtimeKey;
27
+ }
28
+ if (typeof global?.EdgeRuntime === "string") return "edge-light";
29
+ if (global?.fastly !== void 0) return "fastly";
30
+ if (global?.process?.release?.name === "node") return "node";
31
+ return "other";
32
+ };
33
+ const checkUserAgentEquals = (platform) => {
34
+ return navigator.userAgent.startsWith(platform);
35
+ };
36
+ //#endregion
37
+ export { knownUserAgents as i, env as n, getRuntimeKey as r, checkUserAgentEquals as t };
package/lib/adapter.js CHANGED
@@ -1,37 +1,2 @@
1
- //#region ../../plugins/acryl-router/src/core/helper/adapter/index.ts
2
- const env = (c, runtime) => {
3
- const globalEnv = globalThis?.process?.env;
4
- runtime ??= getRuntimeKey();
5
- return {
6
- bun: () => globalEnv,
7
- node: () => globalEnv,
8
- "edge-light": () => globalEnv,
9
- deno: () => {
10
- return Deno.env.toObject();
11
- },
12
- workerd: () => c.env,
13
- fastly: () => ({}),
14
- other: () => ({})
15
- }[runtime]();
16
- };
17
- const knownUserAgents = {
18
- deno: "Deno",
19
- bun: "Bun",
20
- workerd: "Cloudflare-Workers",
21
- node: "Node.js"
22
- };
23
- const getRuntimeKey = () => {
24
- const global = globalThis;
25
- if (typeof navigator !== "undefined" && typeof navigator.userAgent === "string") {
26
- for (const [runtimeKey, userAgent] of Object.entries(knownUserAgents)) if (checkUserAgentEquals(userAgent)) return runtimeKey;
27
- }
28
- if (typeof global?.EdgeRuntime === "string") return "edge-light";
29
- if (global?.fastly !== void 0) return "fastly";
30
- if (global?.process?.release?.name === "node") return "node";
31
- return "other";
32
- };
33
- const checkUserAgentEquals = (platform) => {
34
- return navigator.userAgent.startsWith(platform);
35
- };
36
- //#endregion
1
+ import { i as knownUserAgents, n as env, r as getRuntimeKey, t as checkUserAgentEquals } from "./adapter-CaZ6FZUU.js";
37
2
  export { checkUserAgentEquals, env, getRuntimeKey, knownUserAgents };
@@ -1,7 +1,7 @@
1
- import { AcrylBase as Acryl$1 } from "./acryl-base.js";
2
- import { i as RegExpRouter } from "./reg-exp-router-DC1R3qoY.js";
3
- import { t as SmartRouter } from "./smart-router-C5CZ5XSM.js";
4
- import { t as TrieRouter } from "./trie-router-CfFbapzL.js";
1
+ import { t as Acryl$1 } from "./app-base-CpRMZL4v.js";
2
+ import { i as RegExpRouter } from "./reg-exp-router-C_WV84eV.js";
3
+ import { t as SmartRouter } from "./smart-router-BjxkDQCE.js";
4
+ import { t as TrieRouter } from "./trie-router-JydLKUa2.js";
5
5
  //#region ../../plugins/acryl-router/src/core/app.ts
6
6
  /**
7
7
  * The Acryl class extends the functionality of the AcrylBase class.