acrylblends 0.6.2 → 0.6.4

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 (316) hide show
  1. package/README.md +5 -1
  2. package/docs/framework/README.md +3 -2
  3. package/docs/framework/UPSTREAM.md +1 -1
  4. package/docs/framework/cordis/acryl-in-a-cordis-app.md +6 -0
  5. package/docs/framework/getting-started/basic.md +1 -0
  6. package/docs/framework/getting-started/desktop.md +41 -0
  7. package/docs/framework/guides/jsx-dom.md +0 -3
  8. package/docs/framework/guides/jsx.md +24 -3
  9. package/docs/framework/helpers/css.md +0 -3
  10. package/docs/framework/helpers/ssg.md +3 -6
  11. package/docs/framework/middleware/builtin/jsx-renderer.md +0 -3
  12. package/docs/framework/upstream.json +3 -3
  13. package/lib/accepts.d.ts +1 -1
  14. package/lib/acryl-base.d.ts +1 -1
  15. package/lib/adapter.d.ts +1 -1
  16. package/lib/{app-BdrVHBlJ.d.ts → app-D8riatvv.d.ts} +1 -1
  17. package/lib/base-BpQy2Rk7.d.ts +783 -0
  18. package/lib/base-ddiVmiE7.js +721 -0
  19. package/lib/basic-auth.d.ts +1 -1
  20. package/lib/bearer-auth.d.ts +1 -1
  21. package/lib/body-limit.d.ts +1 -1
  22. package/lib/cache.d.ts +1 -1
  23. package/lib/cache.js +4 -4
  24. package/lib/{client-BHTr318g.js → client-DDLXwhBo.js} +2 -125
  25. package/lib/client.d.ts +2 -2
  26. package/lib/client.js +2 -1
  27. package/lib/combine.d.ts +1 -1
  28. package/lib/common-D8Z4JRCw.d.ts +46 -0
  29. package/lib/components-0o0CBYNv.js +268 -0
  30. package/lib/components-DdI7-ns7.js +24 -0
  31. package/lib/compress.d.ts +1 -1
  32. package/lib/conninfo.d.ts +2 -2
  33. package/lib/constants-BR9jM9BC.js +9 -0
  34. package/lib/{context-B5Y1lLha.d.ts → context-DS3fYyG-.d.ts} +2 -2
  35. package/lib/context-DxFdY_un.d.ts +250 -0
  36. package/lib/context-storage.d.ts +1 -1
  37. package/lib/{cookie-D9_nQbsM.d.ts → cookie-CCelEqky.d.ts} +1 -1
  38. package/lib/cookie.d.ts +3 -3
  39. package/lib/cors.d.ts +1 -1
  40. package/lib/csrf.d.ts +1 -1
  41. package/lib/css-D2jb7X8b.js +320 -0
  42. package/lib/css.d.ts +82 -0
  43. package/lib/css.js +134 -0
  44. package/lib/dev.d.ts +2 -2
  45. package/lib/etag.d.ts +1 -1
  46. package/lib/factory.d.ts +2 -2
  47. package/lib/hooks-BMw6BAyP.js +762 -0
  48. package/lib/html-SllAe0YT.d.ts +46 -0
  49. package/lib/html.d.ts +1 -1
  50. package/lib/{index-m12zcmph.d.ts → index-Bb7YJKCq.d.ts} +3 -3
  51. package/lib/{index-Kqou8Fjh.d.ts → index-BvFh1Gfx.d.ts} +2 -2
  52. package/lib/index-C850MeBA.d.ts +94 -0
  53. package/lib/{index-DtEoak1i.d.ts → index-CTy4N7ng.d.ts} +2 -2
  54. package/lib/index.d.ts +4 -4
  55. package/lib/ip-restriction.d.ts +2 -2
  56. package/lib/jsx/dom/client.d.ts +30 -0
  57. package/lib/jsx/dom/client.js +49 -0
  58. package/lib/jsx/dom/css.d.ts +84 -0
  59. package/lib/jsx/dom/css.js +2 -0
  60. package/lib/jsx/dom/jsx-dev-runtime.d.ts +3 -0
  61. package/lib/jsx/dom/jsx-dev-runtime.js +2 -0
  62. package/lib/jsx/dom/jsx-runtime.d.ts +3 -0
  63. package/lib/jsx/dom/jsx-runtime.js +2 -0
  64. package/lib/jsx/dom/server.d.ts +105 -0
  65. package/lib/jsx/dom/server.js +37 -0
  66. package/lib/jsx/dom.d.ts +5 -0
  67. package/lib/jsx/dom.js +74 -0
  68. package/lib/jsx/jsx-dev-runtime.d.ts +6 -0
  69. package/lib/jsx/jsx-dev-runtime.js +14 -0
  70. package/lib/jsx/jsx-runtime.d.ts +10 -0
  71. package/lib/jsx/jsx-runtime.js +30 -0
  72. package/lib/jsx/streaming.d.ts +2 -0
  73. package/lib/jsx/streaming.js +2 -0
  74. package/lib/jsx-dev-runtime-B22O-Npk.d.ts +7 -0
  75. package/lib/jsx-dev-runtime-D18Y35TI.js +354 -0
  76. package/lib/jsx-renderer.d.ts +75 -0
  77. package/lib/jsx-renderer.js +99 -0
  78. package/lib/jsx-runtime-BVVgDSdq.d.ts +1 -0
  79. package/lib/jsx.d.ts +3 -0
  80. package/lib/jsx.js +47 -0
  81. package/lib/jwk.d.ts +4 -4
  82. package/lib/{jwt-BA65QhnJ.d.ts → jwt-BARhotDz.d.ts} +1 -1
  83. package/lib/jwt.d.ts +4 -4
  84. package/lib/language.d.ts +1 -1
  85. package/lib/logger.d.ts +1 -1
  86. package/lib/loopback-only.d.ts +1 -1
  87. package/lib/method-not-allowed.d.ts +2 -2
  88. package/lib/method-override.d.ts +2 -2
  89. package/lib/mount.d.ts +1 -1
  90. package/lib/node-server/conninfo.d.ts +1 -1
  91. package/lib/node-server/serve-static.d.ts +1 -1
  92. package/lib/node-server/serve-static.js +1 -1
  93. package/lib/node-server.d.ts +1 -1
  94. package/lib/node-server.js +1 -1
  95. package/lib/powered-by.d.ts +1 -1
  96. package/lib/pretty-json.d.ts +1 -1
  97. package/lib/proxy.d.ts +1 -1
  98. package/lib/quick.d.ts +1 -1
  99. package/lib/request-id.d.ts +1 -1
  100. package/lib/request.d.ts +1 -1
  101. package/lib/route.d.ts +1 -1
  102. package/lib/schema-validator.d.ts +1 -1
  103. package/lib/secure-headers.d.ts +1 -1
  104. package/lib/{serve-static-Dw_m6KxR.js → serve-static-B14MF1Va.js} +2 -0
  105. package/lib/serve-static.d.ts +1 -1
  106. package/lib/ssg-BwjcA-Ge.js +389 -0
  107. package/lib/ssg.d.ts +156 -0
  108. package/lib/ssg.js +2 -0
  109. package/lib/streaming.d.ts +1 -1
  110. package/lib/testing.d.ts +4 -4
  111. package/lib/testing.js +1 -1
  112. package/lib/timeout.d.ts +1 -1
  113. package/lib/timing.d.ts +1 -1
  114. package/lib/tiny.d.ts +1 -1
  115. package/lib/trailing-slash.d.ts +1 -1
  116. package/lib/{types-ZM9gIiKh.d.ts → types-Dv_nV2cv.d.ts} +1 -1
  117. package/lib/{types-D9DEXMjE.d.ts → types-Lqx5BxQF.d.ts} +8 -1
  118. package/lib/{types-Bd29gh2o.d.ts → types-zNxyEpG2.d.ts} +3 -3
  119. package/lib/types.d.ts +1 -1
  120. package/lib/utils/body.d.ts +1 -1
  121. package/lib/utils/cookie.d.ts +1 -1
  122. package/lib/utils/crypto.d.ts +1 -1
  123. package/lib/utils/html.d.ts +1 -45
  124. package/lib/utils/ipaddr.d.ts +1 -1
  125. package/lib/utils/jwt.d.ts +1 -1
  126. package/lib/utils/types.d.ts +2 -2
  127. package/lib/utils-Cx61GFMC.js +125 -0
  128. package/lib/validator.d.ts +2 -2
  129. package/lib/ws.d.ts +1 -1
  130. package/package.json +53 -1
  131. package/plugins/acryl-inspect/upstream.json +1 -1
  132. package/plugins/acryl-node-server/upstream.json +1 -1
  133. package/plugins/acryl-router/src/core/helper/css/common.ts +337 -0
  134. package/plugins/acryl-router/src/core/helper/css/index.ts +262 -0
  135. package/plugins/acryl-router/src/core/helper/ssg/index.ts +14 -0
  136. package/plugins/acryl-router/src/core/helper/ssg/middleware.ts +83 -0
  137. package/plugins/acryl-router/src/core/helper/ssg/plugins.ts +72 -0
  138. package/plugins/acryl-router/src/core/helper/ssg/ssg.ts +471 -0
  139. package/plugins/acryl-router/src/core/helper/ssg/utils.ts +118 -0
  140. package/plugins/acryl-router/src/core/jsx/base.ts +490 -0
  141. package/plugins/acryl-router/src/core/jsx/children.ts +20 -0
  142. package/plugins/acryl-router/src/core/jsx/components.ts +257 -0
  143. package/plugins/acryl-router/src/core/jsx/constants.ts +6 -0
  144. package/plugins/acryl-router/src/core/jsx/context.ts +266 -0
  145. package/plugins/acryl-router/src/core/jsx/dom/client.ts +89 -0
  146. package/plugins/acryl-router/src/core/jsx/dom/components.ts +39 -0
  147. package/plugins/acryl-router/src/core/jsx/dom/context.ts +52 -0
  148. package/plugins/acryl-router/src/core/jsx/dom/css.ts +263 -0
  149. package/plugins/acryl-router/src/core/jsx/dom/hooks/index.ts +91 -0
  150. package/plugins/acryl-router/src/core/jsx/dom/index.ts +170 -0
  151. package/plugins/acryl-router/src/core/jsx/dom/intrinsic-element/components.ts +438 -0
  152. package/plugins/acryl-router/src/core/jsx/dom/jsx-dev-runtime.ts +23 -0
  153. package/plugins/acryl-router/src/core/jsx/dom/jsx-runtime.ts +8 -0
  154. package/plugins/acryl-router/src/core/jsx/dom/render.ts +879 -0
  155. package/plugins/acryl-router/src/core/jsx/dom/server.ts +76 -0
  156. package/plugins/acryl-router/src/core/jsx/dom/utils.ts +7 -0
  157. package/plugins/acryl-router/src/core/jsx/hooks/index.ts +437 -0
  158. package/plugins/acryl-router/src/core/jsx/index.ts +115 -0
  159. package/plugins/acryl-router/src/core/jsx/intrinsic-element/common.ts +23 -0
  160. package/plugins/acryl-router/src/core/jsx/intrinsic-element/components.ts +210 -0
  161. package/plugins/acryl-router/src/core/jsx/intrinsic-elements.ts +938 -0
  162. package/plugins/acryl-router/src/core/jsx/jsx-dev-runtime.ts +26 -0
  163. package/plugins/acryl-router/src/core/jsx/jsx-runtime.ts +51 -0
  164. package/plugins/acryl-router/src/core/jsx/streaming.ts +231 -0
  165. package/plugins/acryl-router/src/core/jsx/types.ts +41 -0
  166. package/plugins/acryl-router/src/core/jsx/utils.ts +202 -0
  167. package/plugins/acryl-router/src/core/middleware/cache/index.ts +4 -4
  168. package/plugins/acryl-router/src/core/middleware/jsx-renderer/index.ts +162 -0
  169. package/plugins/acryl-router/src/core/utils/types.ts +6 -0
  170. package/plugins/acryl-router/src/helpers/index.ts +2 -0
  171. package/plugins/acryl-router/src/middleware/index.ts +1 -0
  172. package/plugins/acryl-router/upstream.json +3 -3
  173. package/plugins/acryl-router-http/upstream.json +1 -1
  174. package/plugins/acryl-state/upstream.json +1 -1
  175. package/plugins/desktop/upstream.json +1 -1
  176. package/plugins/desktop-web/upstream.json +1 -1
  177. package/plugins/extensions/resolve.ts +4 -0
  178. package/plugins/save/plugin.json +1 -1
  179. package/shared/AGENTS.core.md +4 -0
  180. package/templates/agent/tsconfig.json +7 -1
  181. package/templates/todo/upstream.json +1 -1
  182. package/plugins/acryl-inspect/tests/report.spec.ts +0 -69
  183. package/plugins/acryl-inspect/tests/service.spec.ts +0 -121
  184. package/plugins/acryl-node-server/tests/adapter/app.ts +0 -76
  185. package/plugins/acryl-node-server/tests/adapter/assets/.static/plain.txt +0 -1
  186. package/plugins/acryl-node-server/tests/adapter/assets/favicon.ico +0 -0
  187. package/plugins/acryl-node-server/tests/adapter/assets/secret.txt +0 -1
  188. package/plugins/acryl-node-server/tests/adapter/assets/static/acryl.html +0 -1
  189. package/plugins/acryl-node-server/tests/adapter/assets/static/admin/secret.txt +0 -1
  190. package/plugins/acryl-node-server/tests/adapter/assets/static/data.json +0 -5
  191. package/plugins/acryl-node-server/tests/adapter/assets/static/extensionless +0 -1
  192. package/plugins/acryl-node-server/tests/adapter/assets/static/foo..bar.txt +0 -0
  193. package/plugins/acryl-node-server/tests/adapter/assets/static/index.html +0 -1
  194. package/plugins/acryl-node-server/tests/adapter/assets/static/plain.txt +0 -1
  195. package/plugins/acryl-node-server/tests/adapter/assets/static-with-context-path/plain.txt +0 -1
  196. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin +0 -1
  197. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.bin.br +0 -1
  198. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt +0 -1
  199. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.br +0 -1
  200. package/plugins/acryl-node-server/tests/adapter/assets/static-with-precompressed/hello.txt.zst +0 -1
  201. package/plugins/acryl-node-server/tests/adapter/conninfo.test.ts +0 -34
  202. package/plugins/acryl-node-server/tests/adapter/content-length.test.ts +0 -248
  203. package/plugins/acryl-node-server/tests/adapter/early-hints.test.ts +0 -457
  204. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-cert.pem +0 -23
  205. package/plugins/acryl-node-server/tests/adapter/fixtures/keys/agent1-key.pem +0 -27
  206. package/plugins/acryl-node-server/tests/adapter/headers.test.ts +0 -252
  207. package/plugins/acryl-node-server/tests/adapter/helpers/request.ts +0 -190
  208. package/plugins/acryl-node-server/tests/adapter/listener.test.ts +0 -727
  209. package/plugins/acryl-node-server/tests/adapter/request-client-disconnect.test.ts +0 -189
  210. package/plugins/acryl-node-server/tests/adapter/request.test.ts +0 -1230
  211. package/plugins/acryl-node-server/tests/adapter/response.test.ts +0 -285
  212. package/plugins/acryl-node-server/tests/adapter/serve-static.test.ts +0 -849
  213. package/plugins/acryl-node-server/tests/adapter/server-socket.test.ts +0 -790
  214. package/plugins/acryl-node-server/tests/adapter/server.test.ts +0 -1312
  215. package/plugins/acryl-node-server/tests/adapter/setup.ts +0 -16
  216. package/plugins/acryl-node-server/tests/adapter/url.test.ts +0 -76
  217. package/plugins/acryl-node-server/tests/adapter/utils/response.test.ts +0 -23
  218. package/plugins/acryl-node-server/tests/adapter/utils/stream.test.ts +0 -75
  219. package/plugins/acryl-node-server/tests/adapter/utils.test.ts +0 -235
  220. package/plugins/acryl-node-server/tests/adapter/websocket.test.ts +0 -260
  221. package/plugins/acryl-node-server/tests/server.spec.ts +0 -141
  222. package/plugins/acryl-router/src/core/app.test.ts +0 -3833
  223. package/plugins/acryl-router/src/core/client/client.test.ts +0 -2313
  224. package/plugins/acryl-router/src/core/client/types.test.ts +0 -149
  225. package/plugins/acryl-router/src/core/client/utils.test.ts +0 -405
  226. package/plugins/acryl-router/src/core/compose.test.ts +0 -751
  227. package/plugins/acryl-router/src/core/context.test.ts +0 -629
  228. package/plugins/acryl-router/src/core/helper/accepts/accepts.test.ts +0 -344
  229. package/plugins/acryl-router/src/core/helper/adapter/index.test.ts +0 -55
  230. package/plugins/acryl-router/src/core/helper/cookie/index.test.ts +0 -510
  231. package/plugins/acryl-router/src/core/helper/dev/index.test.ts +0 -181
  232. package/plugins/acryl-router/src/core/helper/factory/index.test.ts +0 -434
  233. package/plugins/acryl-router/src/core/helper/html/index.test.ts +0 -78
  234. package/plugins/acryl-router/src/core/helper/proxy/index.test.ts +0 -356
  235. package/plugins/acryl-router/src/core/helper/route/index.test.ts +0 -259
  236. package/plugins/acryl-router/src/core/helper/streaming/stream.test.ts +0 -128
  237. package/plugins/acryl-router/src/core/helper/streaming/text.test.ts +0 -34
  238. package/plugins/acryl-router/src/core/helper/testing/index.test.ts +0 -42
  239. package/plugins/acryl-router/src/core/helper/websocket/index.test.ts +0 -124
  240. package/plugins/acryl-router/src/core/http-exception.test.ts +0 -45
  241. package/plugins/acryl-router/src/core/middleware/basic-auth/index.test.ts +0 -434
  242. package/plugins/acryl-router/src/core/middleware/bearer-auth/index.test.ts +0 -1018
  243. package/plugins/acryl-router/src/core/middleware/body-limit/index.test.ts +0 -273
  244. package/plugins/acryl-router/src/core/middleware/cache/index.test.ts +0 -1211
  245. package/plugins/acryl-router/src/core/middleware/combine/index.test.ts +0 -355
  246. package/plugins/acryl-router/src/core/middleware/compress/index.test.ts +0 -535
  247. package/plugins/acryl-router/src/core/middleware/context-storage/index.test.ts +0 -43
  248. package/plugins/acryl-router/src/core/middleware/cors/index.test.ts +0 -532
  249. package/plugins/acryl-router/src/core/middleware/csrf/index.test.ts +0 -534
  250. package/plugins/acryl-router/src/core/middleware/etag/digest.test.ts +0 -21
  251. package/plugins/acryl-router/src/core/middleware/etag/index.test.ts +0 -503
  252. package/plugins/acryl-router/src/core/middleware/ip-restriction/index.test.ts +0 -217
  253. package/plugins/acryl-router/src/core/middleware/jwk/index.test.ts +0 -1135
  254. package/plugins/acryl-router/src/core/middleware/jwk/keys.test.json +0 -48
  255. package/plugins/acryl-router/src/core/middleware/jwt/index.test.ts +0 -802
  256. package/plugins/acryl-router/src/core/middleware/language/index.test.ts +0 -552
  257. package/plugins/acryl-router/src/core/middleware/logger/index.test.ts +0 -204
  258. package/plugins/acryl-router/src/core/middleware/method-not-allowed/index.test.ts +0 -292
  259. package/plugins/acryl-router/src/core/middleware/method-override/index.test.ts +0 -221
  260. package/plugins/acryl-router/src/core/middleware/mount/index.test.ts +0 -334
  261. package/plugins/acryl-router/src/core/middleware/powered-by/index.test.ts +0 -37
  262. package/plugins/acryl-router/src/core/middleware/pretty-json/index.test.ts +0 -218
  263. package/plugins/acryl-router/src/core/middleware/request-id/index.test.ts +0 -168
  264. package/plugins/acryl-router/src/core/middleware/secure-headers/index.test.ts +0 -671
  265. package/plugins/acryl-router/src/core/middleware/serve-static/index.test.ts +0 -450
  266. package/plugins/acryl-router/src/core/middleware/serve-static/path.test.ts +0 -50
  267. package/plugins/acryl-router/src/core/middleware/timeout/index.test.ts +0 -70
  268. package/plugins/acryl-router/src/core/middleware/timing/index.test.ts +0 -310
  269. package/plugins/acryl-router/src/core/middleware/trailing-slash/index.test.ts +0 -381
  270. package/plugins/acryl-router/src/core/preset/quick.test.ts +0 -42
  271. package/plugins/acryl-router/src/core/preset/tiny.test.ts +0 -42
  272. package/plugins/acryl-router/src/core/request.test.ts +0 -751
  273. package/plugins/acryl-router/src/core/router/common.case.test.ts +0 -1132
  274. package/plugins/acryl-router/src/core/router/linear-router/router.test.ts +0 -80
  275. package/plugins/acryl-router/src/core/router/pattern-router/router.test.ts +0 -46
  276. package/plugins/acryl-router/src/core/router/reg-exp-router/prepared-router.test.ts +0 -154
  277. package/plugins/acryl-router/src/core/router/reg-exp-router/router.test.ts +0 -265
  278. package/plugins/acryl-router/src/core/router/smart-router/router.test.ts +0 -13
  279. package/plugins/acryl-router/src/core/router/trie-router/node.test.ts +0 -896
  280. package/plugins/acryl-router/src/core/router/trie-router/router.test.ts +0 -8
  281. package/plugins/acryl-router/src/core/types.test.ts +0 -4134
  282. package/plugins/acryl-router/src/core/utils/accept.test.ts +0 -299
  283. package/plugins/acryl-router/src/core/utils/basic-auth.test.ts +0 -56
  284. package/plugins/acryl-router/src/core/utils/body.test.ts +0 -496
  285. package/plugins/acryl-router/src/core/utils/buffer.test.ts +0 -147
  286. package/plugins/acryl-router/src/core/utils/color.test.ts +0 -23
  287. package/plugins/acryl-router/src/core/utils/concurrent.test.ts +0 -69
  288. package/plugins/acryl-router/src/core/utils/cookie.test.ts +0 -460
  289. package/plugins/acryl-router/src/core/utils/crypto.test.ts +0 -43
  290. package/plugins/acryl-router/src/core/utils/encode.test.ts +0 -61
  291. package/plugins/acryl-router/src/core/utils/filepath.test.ts +0 -78
  292. package/plugins/acryl-router/src/core/utils/html.test.ts +0 -16
  293. package/plugins/acryl-router/src/core/utils/ipaddr.test.ts +0 -149
  294. package/plugins/acryl-router/src/core/utils/jwt/jwa.test.ts +0 -86
  295. package/plugins/acryl-router/src/core/utils/jwt/jwt.test.ts +0 -1788
  296. package/plugins/acryl-router/src/core/utils/mime.test.ts +0 -64
  297. package/plugins/acryl-router/src/core/utils/stream.test.ts +0 -212
  298. package/plugins/acryl-router/src/core/utils/types.test.ts +0 -295
  299. package/plugins/acryl-router/src/core/utils/url.test.ts +0 -384
  300. package/plugins/acryl-router/src/core/validator/utils.test.ts +0 -82
  301. package/plugins/acryl-router/src/core/validator/validator.test.ts +0 -1488
  302. package/plugins/acryl-router/tests/docs-examples.spec.ts +0 -152
  303. package/plugins/acryl-router/tests/live-install.spec.ts +0 -64
  304. package/plugins/acryl-router/tests/loader.spec.ts +0 -72
  305. package/plugins/acryl-router/tests/loopback-only.spec.ts +0 -80
  306. package/plugins/acryl-router/tests/no-dom/consumer.ts +0 -11
  307. package/plugins/acryl-router/tests/no-dom/tsconfig.json +0 -13
  308. package/plugins/acryl-router/tests/service.spec.ts +0 -426
  309. package/plugins/acryl-router/tests/shadow-state.spec.ts +0 -79
  310. package/plugins/acryl-router-http/tests/adapter.spec.ts +0 -174
  311. package/plugins/acryl-router-http/tests/stream.spec.ts +0 -133
  312. package/plugins/acryl-router-http/tests/surfaces.spec.ts +0 -101
  313. package/plugins/acryl-state/src/react.ts +0 -11
  314. package/plugins/acryl-state/tests/cell.spec.ts +0 -71
  315. package/plugins/acryl-state/tests/react.spec.ts +0 -39
  316. package/plugins/acryl-state/tests/service.spec.ts +0 -132
@@ -1,1132 +0,0 @@
1
- import type { RunnerTestSuite } from 'vitest'
2
- import type { ParamIndexMap, Params, Router } from '../router.ts'
3
-
4
- const getSuiteHierarchy = (suite?: RunnerTestSuite) => {
5
- const res: RunnerTestSuite[] = []
6
- let s: RunnerTestSuite | undefined = suite
7
- while (s) {
8
- res.unshift(s)
9
- s = s.suite
10
- }
11
- return res
12
- }
13
-
14
- export const runTest = ({
15
- skip = [],
16
- newRouter,
17
- }: {
18
- skip?: {
19
- reason: string
20
- tests: string[]
21
- }[]
22
- newRouter: <T>() => Router<T>
23
- }) => {
24
- describe('Common', () => {
25
- type Match = (method: string, path: string) => { handler: string; params: Params }[]
26
- let router: Router<string>
27
- let match: Match
28
-
29
- beforeEach(({ task, skip: skipTask }) => {
30
- const suites = getSuiteHierarchy(task.suite)
31
- const name = [...suites.slice(2).map((s) => s.name), task.name].join(' > ')
32
- const isSkip = skip.find((s) => s.tests.includes(name))
33
- if (isSkip) {
34
- console.log(`Skip: ${isSkip.reason}`)
35
- skipTask()
36
- return
37
- }
38
-
39
- router = newRouter()
40
- match = (method: string, path: string) => {
41
- const [matchRes, stash] = router.match(method, path)
42
- const res = matchRes.map((r) =>
43
- stash
44
- ? {
45
- handler: r[0],
46
- params: Object.keys(r[1]).reduce(
47
- (acc, key) => {
48
- acc[key] = stash[(r[1] as ParamIndexMap)[key]]
49
- return acc
50
- },
51
- Object.create(null) as Params
52
- ),
53
- }
54
- : { handler: r[0], params: r[1] as Params }
55
- )
56
- return res
57
- }
58
- })
59
-
60
- describe('Basic Usage', () => {
61
- beforeEach(() => {
62
- router.add('GET', '/hello', 'get hello')
63
- router.add('POST', '/hello', 'post hello')
64
- router.add('PURGE', '/hello', 'purge hello')
65
- })
66
-
67
- it('GET, post hello', async () => {
68
- let res = match('GET', '/hello')
69
- expect(res.length).toBe(1)
70
- expect(res[0].handler).toEqual('get hello')
71
- res = match('POST', '/hello')
72
- expect(res.length).toBe(1)
73
- expect(res[0].handler).toEqual('post hello')
74
- res = match('PURGE', '/hello')
75
- expect(res.length).toBe(1)
76
- expect(res[0].handler).toEqual('purge hello')
77
- res = match('PUT', '/hello')
78
- expect(res.length).toBe(0)
79
- res = match('GET', '/')
80
- expect(res.length).toBe(0)
81
- })
82
- })
83
-
84
- describe('Reserved words', () => {
85
- it('Reserved words and named parameter', async () => {
86
- router.add('GET', '/entry/:constructor', 'get entry')
87
- const res = match('GET', '/entry/123')
88
- expect(res.length).toBe(1)
89
- expect(res[0].handler).toEqual('get entry')
90
- expect(res[0].params['constructor']).toBe('123')
91
- })
92
-
93
- it('Reserved words and wildcard', async () => {
94
- router.add('GET', '/wild/*/card', 'get wildcard')
95
- const res = match('GET', '/wild/constructor/card')
96
- expect(res.length).toBe(1)
97
- expect(res[0].handler).toEqual('get wildcard')
98
- })
99
-
100
- it('Reserved words and optional named parameter', async () => {
101
- router.add('GET', '/api/animals/:constructor?', 'animals')
102
- const res = match('GET', '/api/animals')
103
- expect(res.length).toBe(1)
104
- expect(res[0].handler).toEqual('animals')
105
- expect(res[0].params['constructor']).toBeUndefined()
106
- })
107
- })
108
-
109
- describe('Complex', () => {
110
- it('Named Param', async () => {
111
- router.add('GET', '/entry/:id', 'get entry')
112
- let res = match('GET', '/entry/123')
113
-
114
- expect(res.length).toBe(1)
115
- expect(res[0].handler).toEqual('get entry')
116
- expect(res[0].params['id']).toBe('123')
117
-
118
- res = match('GET', '/entry-123')
119
- expect(res.length).toBe(0)
120
- })
121
-
122
- it('Wildcard', async () => {
123
- router.add('GET', '/wild/*/card', 'get wildcard')
124
- const res = match('GET', '/wild/xxx/card')
125
- expect(res.length).toBe(1)
126
- expect(res[0].handler).toEqual('get wildcard')
127
- })
128
-
129
- it('Default', async () => {
130
- router.add('GET', '/api/abc', 'get api')
131
- router.add('GET', '/api/*', 'fallback')
132
- let res = match('GET', '/api/abc')
133
- expect(res.length).toBe(2)
134
- expect(res[0].handler).toEqual('get api')
135
- expect(res[1].handler).toEqual('fallback')
136
- res = match('GET', '/api/def')
137
- expect(res.length).toBe(1)
138
- expect(res[0].handler).toEqual('fallback')
139
- })
140
-
141
- it('Regexp', async () => {
142
- router.add('GET', '/post/:date{[0-9]+}/:title{[a-z]+}', 'get post')
143
- let res = match('GET', '/post/20210101/hello')
144
- expect(res.length).toBe(1)
145
- expect(res[0].handler).toEqual('get post')
146
- expect(res[0].params['date']).toBe('20210101')
147
- expect(res[0].params['title']).toBe('hello')
148
- res = match('GET', '/post/onetwothree')
149
- expect(res.length).toBe(0)
150
- res = match('GET', '/post/123/123')
151
- expect(res.length).toBe(0)
152
- })
153
-
154
- it('Parameter with {.*} regexp', () => {
155
- router.add('GET', '/files/:name{.*}', 'file')
156
- let res = match('GET', '/files')
157
- expect(res.length).toBe(0)
158
-
159
- res = match('GET', '/files/a')
160
- expect(res.length).toBe(1)
161
- expect(res[0].handler).toEqual('file')
162
- expect(res[0].params['name']).toEqual('a')
163
-
164
- res = match('GET', '/files/a/b')
165
- expect(res.length).toBe(1)
166
- expect(res[0].handler).toEqual('file')
167
- expect(res[0].params['name']).toEqual('a/b')
168
-
169
- res = match('GET', '/files/')
170
- expect(res.length).toBe(1)
171
- expect(res[0].handler).toEqual('file')
172
- })
173
-
174
- it('/*', async () => {
175
- router.add('GET', '/api/*', 'auth middleware')
176
- router.add('GET', '/api', 'top')
177
- router.add('GET', '/api/posts', 'posts')
178
- router.add('GET', '/api/*', 'fallback')
179
-
180
- let res = match('GET', '/api')
181
- expect(res.length).toBe(3)
182
- expect(res[0].handler).toEqual('auth middleware')
183
- expect(res[1].handler).toEqual('top')
184
- expect(res[2].handler).toEqual('fallback')
185
- res = match('GET', '/api/posts')
186
- expect(res.length).toBe(3)
187
- expect(res[0].handler).toEqual('auth middleware')
188
- expect(res[1].handler).toEqual('posts')
189
- expect(res[2].handler).toEqual('fallback')
190
- })
191
- })
192
-
193
- describe('Registration order', () => {
194
- it('middleware -> handler', async () => {
195
- router.add('GET', '*', 'bar')
196
- router.add('GET', '/:type/:action', 'foo')
197
- const res = match('GET', '/posts/123')
198
- expect(res.length).toBe(2)
199
- expect(res[0].handler).toEqual('bar')
200
- expect(res[1].handler).toEqual('foo')
201
- })
202
-
203
- it('handler -> fallback', async () => {
204
- router.add('GET', '/:type/:action', 'foo')
205
- router.add('GET', '*', 'fallback')
206
- const res = match('GET', '/posts/123')
207
- expect(res.length).toBe(2)
208
- expect(res[0].handler).toEqual('foo')
209
- expect(res[1].handler).toEqual('fallback')
210
- })
211
- })
212
-
213
- describe('Multi match', () => {
214
- describe('Blog', () => {
215
- beforeEach(() => {
216
- router.add('ALL', '*', 'middleware a')
217
- router.add('GET', '*', 'middleware b')
218
- router.add('GET', '/entry', 'get entries')
219
- router.add('POST', '/entry/*', 'middleware c')
220
- router.add('POST', '/entry', 'post entry')
221
- router.add('GET', '/entry/:id', 'get entry')
222
- router.add('GET', '/entry/:id/comment/:comment_id', 'get comment')
223
- })
224
-
225
- it('GET /', async () => {
226
- const res = match('GET', '/')
227
- expect(res.length).toBe(2)
228
- expect(res[0].handler).toEqual('middleware a')
229
- expect(res[1].handler).toEqual('middleware b')
230
- })
231
- it('GET /entry/123', async () => {
232
- const res = match('GET', '/entry/123')
233
- expect(res.length).toBe(3)
234
- expect(res[0].handler).toEqual('middleware a')
235
- expect(res[0].params['id']).toBe(undefined)
236
- expect(res[1].handler).toEqual('middleware b')
237
- expect(res[1].params['id']).toBe(undefined)
238
- expect(res[2].handler).toEqual('get entry')
239
- expect(res[2].params['id']).toBe('123')
240
- })
241
- it('GET /entry/123/comment/456', async () => {
242
- const res = match('GET', '/entry/123/comment/456')
243
- expect(res.length).toBe(3)
244
- expect(res[0].handler).toEqual('middleware a')
245
- expect(res[0].params['id']).toBe(undefined)
246
- expect(res[0].params['comment_id']).toBe(undefined)
247
- expect(res[1].handler).toEqual('middleware b')
248
- expect(res[1].params['id']).toBe(undefined)
249
- expect(res[1].params['comment_id']).toBe(undefined)
250
- expect(res[2].handler).toEqual('get comment')
251
- expect(res[2].params['id']).toBe('123')
252
- expect(res[2].params['comment_id']).toBe('456')
253
- })
254
- it('POST /entry', async () => {
255
- const res = match('POST', '/entry')
256
- expect(res.length).toBe(3)
257
- expect(res[0].handler).toEqual('middleware a')
258
- expect(res[1].handler).toEqual('middleware c')
259
- expect(res[2].handler).toEqual('post entry')
260
- })
261
- it('DELETE /entry', async () => {
262
- const res = match('DELETE', '/entry')
263
- expect(res.length).toBe(1)
264
- expect(res[0].handler).toEqual('middleware a')
265
- })
266
- })
267
-
268
- describe('`params` per a handler', () => {
269
- beforeEach(() => {
270
- router.add('ALL', '*', 'middleware a')
271
- router.add('GET', '/entry/:id/*', 'middleware b')
272
- router.add('GET', '/entry/:id/:action', 'action')
273
- })
274
-
275
- it('GET /entry/123/show', async () => {
276
- const res = match('GET', '/entry/123/show')
277
- expect(res.length).toBe(3)
278
- expect(res[0].handler).toEqual('middleware a')
279
- expect(res[0].params['id']).toBe(undefined)
280
- expect(res[0].params['action']).toBe(undefined)
281
- expect(res[1].handler).toEqual('middleware b')
282
- expect(res[1].params['id']).toBe('123')
283
- expect(res[1].params['comment_id']).toBe(undefined)
284
- expect(res[2].handler).toEqual('action')
285
- expect(res[2].params['id']).toBe('123')
286
- expect(res[2].params['action']).toBe('show')
287
- })
288
- })
289
-
290
- it('hierarchy', () => {
291
- router.add('GET', '/posts/:id/comments/:comment_id', 'foo')
292
- router.add('GET', '/posts/:id', 'bar')
293
- expect(() => {
294
- router.match('GET', '/')
295
- }).not.toThrow()
296
- })
297
- })
298
-
299
- describe('Duplicate param name', () => {
300
- it('self', () => {
301
- router.add('GET', '/:id/:id', 'foo')
302
- const res = match('GET', '/123/456')
303
- expect(res.length).toBe(1)
304
- expect(res[0].handler).toEqual('foo')
305
- expect(res[0].params['id']).toBe('123')
306
- })
307
-
308
- it('self with trailing static', () => {
309
- router.add('GET', '/:id/:id/x', 'foo')
310
- const res = match('GET', '/123/456/x')
311
- expect(res.length).toBe(1)
312
- expect(res[0].handler).toEqual('foo')
313
- expect(res[0].params['id']).toBe('123')
314
- })
315
-
316
- it('self three times', () => {
317
- router.add('GET', '/:id/:id/:id', 'foo')
318
- const res = match('GET', '/1/2/3')
319
- expect(res.length).toBe(1)
320
- expect(res[0].handler).toEqual('foo')
321
- expect(res[0].params['id']).toBe('1')
322
- })
323
-
324
- it('parent', () => {
325
- router.add('GET', '/:id/:action', 'foo')
326
- router.add('GET', '/posts/:id', 'bar')
327
- const res = match('GET', '/posts/get')
328
- expect(res.length).toBe(2)
329
- expect(res[0].handler).toEqual('foo')
330
- expect(res[0].params['id']).toBe('posts')
331
- expect(res[0].params['action']).toBe('get')
332
- expect(res[1].handler).toEqual('bar')
333
- expect(res[1].params['id']).toBe('get')
334
- })
335
-
336
- it('child', () => {
337
- router.add('GET', '/posts/:id', 'foo')
338
- router.add('GET', '/:id/:action', 'bar')
339
- const res = match('GET', '/posts/get')
340
- expect(res.length).toBe(2)
341
- expect(res[0].handler).toEqual('foo')
342
- expect(res[0].params['id']).toBe('get')
343
- expect(res[1].handler).toEqual('bar')
344
- expect(res[1].params['id']).toBe('posts')
345
- expect(res[1].params['action']).toBe('get')
346
- })
347
- })
348
-
349
- describe('page', () => {
350
- it('GET /page', async () => {
351
- router.add('GET', '/page', 'page')
352
- router.add('ALL', '*', 'fallback') // or '*'
353
-
354
- const res = match('GET', '/page')
355
- expect(res.length).toBe(2)
356
- expect(res[0].handler).toEqual('page')
357
- expect(res[1].handler).toEqual('fallback')
358
- })
359
- })
360
-
361
- describe('star', () => {
362
- beforeEach(() => {
363
- router.add('GET', '/', '/')
364
- router.add('GET', '/*', '/*')
365
- router.add('GET', '*', '*')
366
-
367
- router.add('GET', '/x', '/x')
368
- router.add('GET', '/x/*', '/x/*')
369
- })
370
-
371
- it('top', async () => {
372
- const res = match('GET', '/')
373
- expect(res.length).toBe(3)
374
- expect(res[0].handler).toEqual('/')
375
- expect(res[1].handler).toEqual('/*')
376
- expect(res[2].handler).toEqual('*')
377
- })
378
-
379
- it('Under a certain path', async () => {
380
- const res = match('GET', '/x')
381
- expect(res.length).toBe(4)
382
- expect(res[0].handler).toEqual('/*')
383
- expect(res[1].handler).toEqual('*')
384
- expect(res[2].handler).toEqual('/x')
385
- expect(res[3].handler).toEqual('/x/*')
386
- })
387
- })
388
-
389
- describe('Suffix wildcard', () => {
390
- beforeEach(() => {
391
- router.add('GET', '/assets*', 'assets')
392
- })
393
-
394
- it('GET /assets', async () => {
395
- const res = match('GET', '/assets')
396
- expect(res.length).toBe(1)
397
- expect(res[0].handler).toEqual('assets')
398
- })
399
-
400
- it('GET /assets-v2', async () => {
401
- const res = match('GET', '/assets-v2')
402
- expect(res.length).toBe(1)
403
- expect(res[0].handler).toEqual('assets')
404
- })
405
-
406
- it('GET /assets/app.js', async () => {
407
- const res = match('GET', '/assets/app.js')
408
- expect(res.length).toBe(1)
409
- expect(res[0].handler).toEqual('assets')
410
- })
411
-
412
- it('GET /asset', async () => {
413
- const res = match('GET', '/asset')
414
- expect(res.length).toBe(0)
415
- })
416
-
417
- it.each([
418
- ['/assets*', '/assets/app.js'],
419
- ['/assets/app.js', '/assets*'],
420
- ])('associates %s before %s', async (first, second) => {
421
- router.add('POST', first, first)
422
- router.add('POST', second, second)
423
- const res = match('POST', '/assets/app.js')
424
- expect(res.map(({ handler }) => handler)).toEqual([first, second])
425
- })
426
- })
427
-
428
- describe('Trailing wildcard', () => {
429
- beforeEach(() => {
430
- router.add('GET', '/path/*', 'path')
431
- })
432
-
433
- it('GET /path', async () => {
434
- const res = match('GET', '/path')
435
- expect(res.length).toBe(1)
436
- expect(res[0].handler).toEqual('path')
437
- })
438
-
439
- it('GET /path/to/file', async () => {
440
- const res = match('GET', '/path/to/file')
441
- expect(res.length).toBe(1)
442
- expect(res[0].handler).toEqual('path')
443
- })
444
-
445
- it('GET /pathfoo', async () => {
446
- const res = match('GET', '/pathfoo')
447
- expect(res.length).toBe(0)
448
- })
449
- })
450
-
451
- describe('Trailing wildcard after a label', () => {
452
- beforeEach(() => {
453
- router.add('GET', '/:name/*', 'middleware')
454
- router.add('GET', '/:id', 'handler')
455
- })
456
-
457
- it('GET /abc', async () => {
458
- const res = match('GET', '/abc')
459
- expect(res.length).toBe(2)
460
- expect(res[0]).toEqual({ handler: 'middleware', params: { name: 'abc' } })
461
- expect(res[1]).toEqual({ handler: 'handler', params: { id: 'abc' } })
462
- })
463
-
464
- it('GET /abc/sub', async () => {
465
- const res = match('GET', '/abc/sub')
466
- expect(res).toEqual([{ handler: 'middleware', params: { name: 'abc' } }])
467
- })
468
- })
469
-
470
- describe('Trailing wildcard after a pattern label', () => {
471
- beforeEach(() => {
472
- router.add('GET', '/:name{[a-z]+}/*', 'middleware')
473
- router.add('GET', '/:id{[a-z]+}', 'handler')
474
- })
475
-
476
- it('GET /abc', async () => {
477
- const res = match('GET', '/abc')
478
- expect(res.length).toBe(2)
479
- expect(res[0]).toEqual({ handler: 'middleware', params: { name: 'abc' } })
480
- expect(res[1]).toEqual({ handler: 'handler', params: { id: 'abc' } })
481
- })
482
-
483
- it('GET /reverse/abc in reverse registration order', async () => {
484
- router = newRouter()
485
- router.add('GET', '/reverse/:id{[a-z]+}', 'handler')
486
- router.add('GET', '/reverse/:name{[a-z]+}/*', 'middleware')
487
- const res = match('GET', '/reverse/abc')
488
- expect(res.map(({ handler }) => handler)).toEqual(['handler', 'middleware'])
489
- })
490
-
491
- it('POST /all/abc with ALL middleware', async () => {
492
- router = newRouter()
493
- router.add('ALL', '/all/:name{[a-z]+}/*', 'middleware')
494
- router.add('POST', '/all/:id{[a-z]+}', 'handler')
495
- const res = match('POST', '/all/abc')
496
- expect(res.map(({ handler }) => handler)).toEqual(['middleware', 'handler'])
497
- })
498
-
499
- it('GET /posts/2024/comments with nested braces', async () => {
500
- router = newRouter()
501
- router.add('GET', '/posts/:year{[0-9]{4}}/*', 'middleware')
502
- router.add('GET', '/posts/:yr{[0-9]{4}}/comments', 'handler')
503
- const res = match('GET', '/posts/2024/comments')
504
- expect(res).toEqual([
505
- { handler: 'middleware', params: { year: '2024' } },
506
- { handler: 'handler', params: { yr: '2024' } },
507
- ])
508
- })
509
-
510
- it('GET /files/foo/detail with regexp meta characters', async () => {
511
- router = newRouter()
512
- router.add('GET', '/files/:kind{(?:foo|bar)}/*', 'middleware')
513
- router.add('GET', '/files/:type{(?:foo|bar)}/detail', 'handler')
514
- const res = match('GET', '/files/foo/detail')
515
- expect(res).toEqual([
516
- { handler: 'middleware', params: { kind: 'foo' } },
517
- { handler: 'handler', params: { type: 'foo' } },
518
- ])
519
- })
520
-
521
- it('GET /user/123/profile with the default pattern', async () => {
522
- router = newRouter()
523
- router.add('GET', '/user/:userId{[^/]+}/*', 'middleware')
524
- router.add('GET', '/user/:id/profile', 'handler')
525
- const res = match('GET', '/user/123/profile')
526
- expect(res).toEqual([
527
- { handler: 'middleware', params: { userId: '123' } },
528
- { handler: 'handler', params: { id: '123' } },
529
- ])
530
- })
531
-
532
- it('GET /user/123/profile with the default pattern in reverse registration order', async () => {
533
- router = newRouter()
534
- router.add('GET', '/user/:id/profile', 'handler')
535
- router.add('GET', '/user/:userId{[^/]+}/*', 'middleware')
536
- const res = match('GET', '/user/123/profile')
537
- expect(res).toEqual([
538
- { handler: 'handler', params: { id: '123' } },
539
- { handler: 'middleware', params: { userId: '123' } },
540
- ])
541
- })
542
- })
543
-
544
- describe('Trailing wildcard after a middle wildcard', () => {
545
- beforeEach(() => {
546
- router.add('GET', '/a/*/b/*', 'b')
547
- })
548
-
549
- it('GET /a/x/b', async () => {
550
- const res = match('GET', '/a/x/b')
551
- expect(res.length).toBe(1)
552
- expect(res[0].handler).toEqual('b')
553
- })
554
-
555
- it('GET /a/x/b/c', async () => {
556
- const res = match('GET', '/a/x/b/c')
557
- expect(res.length).toBe(1)
558
- expect(res[0].handler).toEqual('b')
559
- })
560
-
561
- it('GET /a/x/bz', async () => {
562
- const res = match('GET', '/a/x/bz')
563
- expect(res.length).toBe(0)
564
- })
565
- })
566
-
567
- describe('Optional route', () => {
568
- beforeEach(() => {
569
- router.add('GET', '/api/animals/:type?', 'animals')
570
- router.add('GET', '/v1/:version?/:platform?', 'result')
571
- })
572
-
573
- it('GET /api/animals/dog', async () => {
574
- const res = match('GET', '/api/animals/dog')
575
- expect(res.length).toBe(1)
576
- expect(res[0].handler).toEqual('animals')
577
- expect(res[0].params['type']).toBe('dog')
578
- })
579
- it('GET /api/animals', async () => {
580
- const res = match('GET', '/api/animals')
581
- expect(res.length).toBe(1)
582
- expect(res[0].handler).toEqual('animals')
583
- expect(res[0].params['type']).toBeUndefined()
584
- })
585
- it('GET /v1/123/abc', () => {
586
- const res = match('GET', '/v1/123/abc')
587
- expect(res.length).toBe(1)
588
- expect(res[0].handler).toEqual('result')
589
- expect(res[0].params['version']).toBe('123')
590
- expect(res[0].params['platform']).toBe('abc')
591
- })
592
- it('GET /v1/123', () => {
593
- const res = match('GET', '/v1/123')
594
- expect(res.length).toBe(1)
595
- expect(res[0].handler).toEqual('result')
596
- expect(res[0].params['version']).toBe('123')
597
- expect(res[0].params['platform']).toBeUndefined()
598
- })
599
- it('GET /v1', () => {
600
- const res = match('GET', '/v1')
601
- expect(res.length).toBe(1)
602
- expect(res[0].handler).toEqual('result')
603
- expect(res[0].params['version']).toBeUndefined()
604
- expect(res[0].params['platform']).toBeUndefined()
605
- })
606
- })
607
-
608
- describe('All', () => {
609
- beforeEach(() => {
610
- router.add('GET', '/hello', 'get hello')
611
- router.add('ALL', '/all', 'get all')
612
- })
613
-
614
- it('GET, all hello', async () => {
615
- const res = match('GET', '/all')
616
- expect(res.length).toBe(1)
617
- })
618
- })
619
-
620
- describe('long prefix, then star', () => {
621
- describe('GET only', () => {
622
- beforeEach(() => {
623
- router.add('GET', '/long/prefix/*', 'long-prefix')
624
- router.add('GET', '/long/*', 'long')
625
- router.add('GET', '*', 'star1')
626
- router.add('GET', '*', 'star2')
627
- })
628
-
629
- it('GET /', () => {
630
- const res = match('GET', '/')
631
- expect(res.length).toBe(2)
632
- expect(res[0].handler).toEqual('star1')
633
- expect(res[1].handler).toEqual('star2')
634
- })
635
-
636
- it('GET /long/prefix', () => {
637
- const res = match('GET', '/long/prefix')
638
- expect(res.length).toBe(4)
639
- expect(res[0].handler).toEqual('long-prefix')
640
- expect(res[1].handler).toEqual('long')
641
- expect(res[2].handler).toEqual('star1')
642
- expect(res[3].handler).toEqual('star2')
643
- })
644
-
645
- it('GET /long/prefix/test', () => {
646
- const res = match('GET', '/long/prefix/test')
647
- expect(res.length).toBe(4)
648
- expect(res[0].handler).toEqual('long-prefix')
649
- expect(res[1].handler).toEqual('long')
650
- expect(res[2].handler).toEqual('star1')
651
- expect(res[3].handler).toEqual('star2')
652
- })
653
- })
654
-
655
- describe('ALL and GET', () => {
656
- beforeEach(() => {
657
- router.add('ALL', '/long/prefix/*', 'long-prefix')
658
- router.add('ALL', '/long/*', 'long')
659
- router.add('GET', '*', 'star1')
660
- router.add('GET', '*', 'star2')
661
- })
662
-
663
- it('GET /', () => {
664
- const res = match('GET', '/')
665
- expect(res.length).toBe(2)
666
- expect(res[0].handler).toEqual('star1')
667
- expect(res[1].handler).toEqual('star2')
668
- })
669
-
670
- it('GET /long/prefix', () => {
671
- const res = match('GET', '/long/prefix')
672
- expect(res.length).toBe(4)
673
- expect(res[0].handler).toEqual('long-prefix')
674
- expect(res[1].handler).toEqual('long')
675
- expect(res[2].handler).toEqual('star1')
676
- expect(res[3].handler).toEqual('star2')
677
- })
678
-
679
- it('GET /long/prefix/test', () => {
680
- const res = match('GET', '/long/prefix/test')
681
- expect(res.length).toBe(4)
682
- expect(res[0].handler).toEqual('long-prefix')
683
- expect(res[1].handler).toEqual('long')
684
- expect(res[2].handler).toEqual('star1')
685
- expect(res[3].handler).toEqual('star2')
686
- })
687
- })
688
- })
689
-
690
- describe('Including slashes', () => {
691
- beforeEach(() => {
692
- router.add('GET', '/js/:filename{[a-z0-9/]+.js}', 'any file')
693
- })
694
-
695
- it('GET /js/main.js', () => {
696
- router.add('GET', '/js/main.js', 'main.js')
697
-
698
- const res = match('GET', '/js/main.js')
699
- expect(res.length).toBe(2)
700
- expect(res[0].handler).toEqual('any file')
701
- expect(res[0].params['filename']).toEqual('main.js')
702
- expect(res[1].handler).toEqual('main.js')
703
- expect(res[1].params['filename']).toEqual(undefined)
704
- })
705
-
706
- it('GET /js/chunk/123.js', () => {
707
- const res = match('GET', '/js/chunk/123.js')
708
- expect(res.length).toBe(1)
709
- expect(res[0].handler).toEqual('any file')
710
- expect(res[0].params['filename']).toEqual('chunk/123.js')
711
- })
712
-
713
- it('GET /js/chunk/nest/123.js', () => {
714
- const res = match('GET', '/js/chunk/nest/123.js')
715
- expect(res.length).toBe(1)
716
- expect(res[0].handler).toEqual('any file')
717
- expect(res[0].params['filename']).toEqual('chunk/nest/123.js')
718
- })
719
- })
720
-
721
- describe('Capture simple multiple directories', () => {
722
- beforeEach(() => {
723
- router.add('GET', '/:dirs{.+}/file.html', 'file.html')
724
- })
725
-
726
- it('GET /foo/bar/file.html', () => {
727
- const res = match('GET', '/foo/bar/file.html')
728
- expect(res.length).toBe(1)
729
- expect(res[0].handler).toEqual('file.html')
730
- expect(res[0].params['dirs']).toEqual('foo/bar')
731
- })
732
-
733
- it('GET /foo/bar/baz/file.html', () => {
734
- const res = match('GET', '/foo/bar/baz/file.html')
735
- expect(res.length).toBe(1)
736
- expect(res[0].handler).toEqual('file.html')
737
- expect(res[0].params['dirs']).toEqual('foo/bar/baz')
738
- })
739
-
740
- it('GET /a/b/c/d/file.html', () => {
741
- const res = match('GET', '/a/b/c/d/file.html')
742
- expect(res.length).toBe(1)
743
- expect(res[0].handler).toEqual('file.html')
744
- expect(res[0].params['dirs']).toEqual('a/b/c/d')
745
- })
746
- })
747
-
748
- describe('Capture regex pattern has trailing wildcard', () => {
749
- beforeEach(() => {
750
- router.add('GET', '/:dir{[a-z]+}/*/file.html', 'file.html')
751
- })
752
-
753
- it('GET /foo/bar/file.html', () => {
754
- const res = match('GET', '/foo/bar/file.html')
755
- expect(res.length).toBe(1)
756
- expect(res[0].handler).toEqual('file.html')
757
- expect(res[0].params['dir']).toEqual('foo')
758
- })
759
- })
760
-
761
- describe('Capture regex param with trailing wildcard on empty remainder', () => {
762
- beforeEach(() => {
763
- router.add('GET', '/:id{[0-9]+}/*', 'regexp')
764
- })
765
-
766
- it('GET /123', () => {
767
- const res = match('GET', '/123')
768
- expect(res.length).toBe(1)
769
- expect(res[0].handler).toEqual('regexp')
770
- expect(res[0].params['id']).toBe('123')
771
- })
772
- })
773
-
774
- describe('Capture regex param with trailing wildcard and sibling route', () => {
775
- beforeEach(() => {
776
- router.add('GET', '/regex-abc/:id{[0-9]+}/*', 'middleware')
777
- router.add('GET', '/regex-abc/:id{[0-9]+}/def', 'regexp')
778
- })
779
-
780
- it('GET /regex-abc/123/ghi', () => {
781
- const res = match('GET', '/regex-abc/123/ghi')
782
- expect(res.length).toBe(1)
783
- expect(res[0].handler).toEqual('middleware')
784
- expect(res[0].params['id']).toBe('123')
785
- })
786
- })
787
-
788
- describe('Capture complex multiple directories', () => {
789
- beforeEach(() => {
790
- router.add('GET', '/:first{.+}/middle-a/:reference?', '1')
791
- router.add('GET', '/:first{.+}/middle-b/end-c/:uuid', '2')
792
- router.add('GET', '/:first{.+}/middle-b/:digest', '3')
793
- })
794
-
795
- it('GET /part1/middle-b/latest', () => {
796
- const res = match('GET', '/part1/middle-b/latest')
797
- expect(res.length).toBe(1)
798
- expect(res[0].handler).toEqual('3')
799
- expect(res[0].params['first']).toEqual('part1')
800
- expect(res[0].params['digest']).toEqual('latest')
801
- })
802
-
803
- it('GET /part1/middle-b/end-c/latest', () => {
804
- const res = match('GET', '/part1/middle-b/end-c/latest')
805
- expect(res.length).toBe(1)
806
- expect(res[0].handler).toEqual('2')
807
- expect(res[0].params['first']).toEqual('part1')
808
- expect(res[0].params['uuid']).toEqual('latest')
809
- })
810
- })
811
-
812
- describe('Capture multiple directories and optional', () => {
813
- beforeEach(() => {
814
- router.add('GET', '/:prefix{.+}/contents/:id?', 'contents')
815
- })
816
-
817
- it('GET /foo/bar/contents', () => {
818
- const res = match('GET', '/foo/bar/contents')
819
- expect(res.length).toBe(1)
820
- expect(res[0].handler).toEqual('contents')
821
- expect(res[0].params['prefix']).toEqual('foo/bar')
822
- expect(res[0].params['id']).toEqual(undefined)
823
- })
824
-
825
- it('GET /foo/bar/contents/123', () => {
826
- const res = match('GET', '/foo/bar/contents/123')
827
- expect(res.length).toBe(1)
828
- expect(res[0].handler).toEqual('contents')
829
- expect(res[0].params['prefix']).toEqual('foo/bar')
830
- expect(res[0].params['id']).toEqual('123')
831
- })
832
- })
833
-
834
- describe('non ascii characters', () => {
835
- beforeEach(() => {
836
- router.add('ALL', '/$/*', 'middleware $')
837
- router.add('GET', '/$/:name', 'get $ name')
838
- router.add('ALL', '/()/*', 'middleware ()')
839
- router.add('GET', '/()/:name', 'get () name')
840
- })
841
-
842
- it('GET /$/acryl', () => {
843
- const res = match('GET', '/$/acryl')
844
- expect(res.length).toBe(2)
845
- expect(res[0].handler).toEqual('middleware $')
846
- expect(res[0].params).toEqual({})
847
- expect(res[1].handler).toEqual('get $ name')
848
- expect(res[1].params['name']).toEqual('acryl')
849
- })
850
-
851
- it('GET /()/acryl', () => {
852
- const res = match('GET', '/()/acryl')
853
- expect(res.length).toBe(2)
854
- expect(res[0].handler).toEqual('middleware ()')
855
- expect(res[0].params).toEqual({})
856
- expect(res[1].handler).toEqual('get () name')
857
- expect(res[1].params['name']).toEqual('acryl')
858
- })
859
- })
860
-
861
- describe('REST API', () => {
862
- beforeEach(() => {
863
- router.add('GET', '/users/:username{[a-z]+}', 'profile')
864
- router.add('GET', '/users/:username{[a-z]+}/posts', 'posts')
865
- })
866
-
867
- it('GET /users/acryl', () => {
868
- const res = match('GET', '/users/acryl')
869
- expect(res.length).toBe(1)
870
- expect(res[0].handler).toEqual('profile')
871
- })
872
-
873
- it('GET /users/acryl/posts', () => {
874
- const res = match('GET', '/users/acryl/posts')
875
- expect(res.length).toBe(1)
876
- expect(res[0].handler).toEqual('posts')
877
- })
878
- })
879
-
880
- describe('Trailing slash', () => {
881
- beforeEach(() => {
882
- router.add('GET', '/book', 'GET /book')
883
- router.add('GET', '/book/:id', 'GET /book/:id')
884
- })
885
-
886
- it('GET /book', () => {
887
- const res = match('GET', '/book')
888
- expect(res.length).toBe(1)
889
- expect(res[0].handler).toEqual('GET /book')
890
- })
891
- it('GET /book/', () => {
892
- const res = match('GET', '/book/')
893
- expect(res.length).toBe(0)
894
- })
895
- })
896
-
897
- describe('Empty path segment', () => {
898
- beforeEach(() => {
899
- router.add('GET', '/u/:id/posts', 'posts')
900
- })
901
-
902
- it('GET /u/42/posts', () => {
903
- const res = match('GET', '/u/42/posts')
904
- expect(res.length).toBe(1)
905
- expect(res[0].params['id']).toBe('42')
906
- })
907
-
908
- it('GET /u//posts does not match with an empty param', () => {
909
- const res = match('GET', '/u//posts')
910
- expect(res.length).toBe(0)
911
- })
912
- })
913
-
914
- describe('Same path', () => {
915
- beforeEach(() => {
916
- router.add('GET', '/hey', 'Middleware A')
917
- router.add('GET', '/hey', 'Middleware B')
918
- })
919
-
920
- it('GET /hey', () => {
921
- const res = match('GET', '/hey')
922
- expect(res.length).toBe(2)
923
- expect(res[0].handler).toEqual('Middleware A')
924
- expect(res[1].handler).toEqual('Middleware B')
925
- })
926
- })
927
-
928
- describe('Routing with a hostname', () => {
929
- beforeEach(() => {
930
- router.add('GET', 'www1.example.com/hello', 'www1')
931
- router.add('GET', 'www2.example.com/hello', 'www2')
932
- })
933
- it('GET www1.example.com/hello', () => {
934
- const res = match('GET', 'www1.example.com/hello')
935
- expect(res.length).toBe(1)
936
- expect(res[0].handler).toEqual('www1')
937
- })
938
- it('GET www2.example.com/hello', () => {
939
- const res = match('GET', 'www2.example.com/hello')
940
- expect(res.length).toBe(1)
941
- expect(res[0].handler).toEqual('www2')
942
- })
943
- it('GET /hello', () => {
944
- const res = match('GET', '/hello')
945
- expect(res.length).toBe(0)
946
- })
947
- })
948
-
949
- describe('static routes of ALL and GET', () => {
950
- beforeEach(() => {
951
- router.add('ALL', '/foo', 'foo')
952
- router.add('GET', '/bar', 'bar')
953
- })
954
-
955
- it('get /foo', () => {
956
- const res = match('GET', '/foo')
957
- expect(res[0].handler).toEqual('foo')
958
- })
959
- })
960
-
961
- describe('ALL and Star', () => {
962
- beforeEach(() => {
963
- router.add('ALL', '/x', '/x')
964
- router.add('GET', '*', 'star')
965
- })
966
-
967
- it('Should return /x and star', async () => {
968
- const res = match('GET', '/x')
969
- expect(res.length).toBe(2)
970
- expect(res[0].handler).toEqual('/x')
971
- expect(res[1].handler).toEqual('star')
972
- })
973
- })
974
-
975
- describe('GET star, ALL static, GET star...', () => {
976
- beforeEach(() => {
977
- router.add('GET', '*', 'star1')
978
- router.add('ALL', '/x', '/x')
979
- router.add('GET', '*', 'star2')
980
- router.add('GET', '*', 'star3')
981
- })
982
-
983
- it('Should return /x and star', async () => {
984
- const res = match('GET', '/x')
985
- expect(res.length).toBe(4)
986
- expect(res[0].handler).toEqual('star1')
987
- expect(res[1].handler).toEqual('/x')
988
- expect(res[2].handler).toEqual('star2')
989
- expect(res[3].handler).toEqual('star3')
990
- })
991
- })
992
- describe('GET star, GET static, ALL star...', () => {
993
- beforeEach(() => {
994
- router.add('GET', '/y/*', 'star1')
995
- router.add('GET', '/y/a', 'a')
996
- router.add('ALL', '/y/b/*', 'star2')
997
- router.add('GET', '/y/b/bar', 'bar')
998
- })
999
-
1000
- it('Should return star1, star2, and bar', async () => {
1001
- const res = match('GET', '/y/b/bar')
1002
- expect(res.length).toBe(3)
1003
- expect(res[0].handler).toEqual('star1')
1004
- expect(res[1].handler).toEqual('star2')
1005
- expect(res[2].handler).toEqual('bar')
1006
- })
1007
- })
1008
-
1009
- describe('ALL star, ALL star, GET static, ALL star...', () => {
1010
- beforeEach(() => {
1011
- router.add('ALL', '*', 'wildcard')
1012
- router.add('ALL', '/a/*', 'star1')
1013
- router.add('GET', '/a/foo', 'foo')
1014
- router.add('ALL', '/b/*', 'star2')
1015
- router.add('GET', '/b/bar', 'bar')
1016
- })
1017
-
1018
- it('Should return wildcard, star2 and bar', async () => {
1019
- const res = match('GET', '/b/bar')
1020
- expect(res.length).toBe(3)
1021
- expect(res[0].handler).toEqual('wildcard')
1022
- expect(res[1].handler).toEqual('star2')
1023
- expect(res[2].handler).toEqual('bar')
1024
- })
1025
- })
1026
-
1027
- describe('Capture Group', () => {
1028
- describe('Simple capturing group', () => {
1029
- beforeEach(() => {
1030
- router.add('get', '/foo/:capture{(bar|baz)}', 'ok')
1031
- })
1032
-
1033
- it('GET /foo/bar', () => {
1034
- const res = match('get', '/foo/bar')
1035
- expect(res.length).toBe(1)
1036
- expect(res[0].handler).toBe('ok')
1037
- expect(res[0].params['capture']).toBe('bar')
1038
- })
1039
-
1040
- it('GET /foo/baz', () => {
1041
- const res = match('get', '/foo/baz')
1042
- expect(res.length).toBe(1)
1043
- expect(res[0].handler).toBe('ok')
1044
- expect(res[0].params['capture']).toBe('baz')
1045
- })
1046
-
1047
- it('GET /foo/qux', () => {
1048
- const res = match('get', '/foo/qux')
1049
- expect(res.length).toBe(0)
1050
- })
1051
- })
1052
-
1053
- describe('Non-capturing group', () => {
1054
- beforeEach(() => {
1055
- router.add('get', '/foo/:capture{(?:bar|baz)}', 'ok')
1056
- })
1057
-
1058
- it('GET /foo/bar', () => {
1059
- const res = match('get', '/foo/bar')
1060
- expect(res.length).toBe(1)
1061
- expect(res[0].handler).toBe('ok')
1062
- expect(res[0].params['capture']).toBe('bar')
1063
- })
1064
-
1065
- it('GET /foo/baz', () => {
1066
- const res = match('get', '/foo/baz')
1067
- expect(res.length).toBe(1)
1068
- expect(res[0].handler).toBe('ok')
1069
- expect(res[0].params['capture']).toBe('baz')
1070
- })
1071
-
1072
- it('GET /foo/qux', () => {
1073
- const res = match('get', '/foo/qux')
1074
- expect(res.length).toBe(0)
1075
- })
1076
- })
1077
-
1078
- describe('Non-capturing group with prefix', () => {
1079
- beforeEach(() => {
1080
- router.add('get', '/foo/:capture{ba(?:r|z)}', 'ok')
1081
- })
1082
-
1083
- it('GET /foo/bar', () => {
1084
- const res = match('get', '/foo/bar')
1085
- expect(res.length).toBe(1)
1086
- expect(res[0].handler).toBe('ok')
1087
- expect(res[0].params['capture']).toBe('bar')
1088
- })
1089
-
1090
- it('GET /foo/baz', () => {
1091
- const res = match('get', '/foo/baz')
1092
- expect(res.length).toBe(1)
1093
- expect(res[0].handler).toBe('ok')
1094
- expect(res[0].params['capture']).toBe('baz')
1095
- })
1096
-
1097
- it('GET /foo/qux', () => {
1098
- const res = match('get', '/foo/qux')
1099
- expect(res.length).toBe(0)
1100
- })
1101
- })
1102
-
1103
- describe('Complex capturing group', () => {
1104
- it('GET request', () => {
1105
- router.add('get', '/foo/:capture{ba(r|z)}', 'ok')
1106
-
1107
- const res = match('get', '/foo/bar')
1108
- expect(res.length).toBe(1)
1109
- expect(res[0].handler).toBe('ok')
1110
- })
1111
- })
1112
- })
1113
-
1114
- describe('Unknown method', () => {
1115
- beforeEach(() => {
1116
- router.add('GET', '/', 'index')
1117
- router.add('ALL', '/all', 'all')
1118
- })
1119
-
1120
- it('UNKNOWN_METHOD /', () => {
1121
- const res = match('UNKNOWN_METHOD', '/')
1122
- expect(res.length).toBe(0)
1123
- })
1124
-
1125
- it('UNKNOWN_METHOD /all', () => {
1126
- const res = match('UNKNOWN_METHOD', '/all')
1127
- expect(res.length).toBe(1)
1128
- expect(res[0].handler).toBe('all')
1129
- })
1130
- })
1131
- })
1132
- }