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,896 +0,0 @@
1
- import { Node } from './node.ts'
2
-
3
- describe('Root Node', () => {
4
- const node = new Node()
5
- node.insert('get', '/', 'get root')
6
- it('get /', () => {
7
- const [res] = node.search('get', '/')
8
- expect(res).not.toBeNull()
9
- expect(res[0][0]).toEqual('get root')
10
- expect(node.search('get', '/hello')[0].length).toBe(0)
11
- })
12
- })
13
-
14
- describe('Root Node is not defined', () => {
15
- const node = new Node()
16
- node.insert('get', '/hello', 'get hello')
17
- it('get /', () => {
18
- expect(node.search('get', '/')[0]).toEqual([])
19
- })
20
- })
21
-
22
- describe('Get with *', () => {
23
- const node = new Node()
24
- node.insert('get', '*', 'get all')
25
- it('get /', () => {
26
- expect(node.search('get', '/')[0].length).toBe(1)
27
- expect(node.search('get', '/hello')[0].length).toBe(1)
28
- })
29
- })
30
-
31
- describe('Get with * including JS reserved words', () => {
32
- const node = new Node()
33
- node.insert('get', '*', 'get all')
34
- it('get /', () => {
35
- expect(node.search('get', '/hello/constructor')[0].length).toBe(1)
36
- expect(node.search('get', '/hello/__proto__')[0].length).toBe(1)
37
- })
38
- })
39
-
40
- describe('Get with a suffix wildcard', () => {
41
- const node = new Node()
42
- node.insert('get', '/assets*', 'assets')
43
-
44
- it.each(['/assets', '/assets-v2', '/assets/app.js'])('matches %s', (path) => {
45
- expect(node.search('get', path)[0]).toEqual([['assets', {}]])
46
- })
47
-
48
- it('does not match a shorter prefix', () => {
49
- expect(node.search('get', '/asset')[0]).toEqual([])
50
- })
51
-
52
- it('treats regular expression characters in the prefix literally', () => {
53
- const node = new Node()
54
- node.insert('get', '/file.+*', 'file')
55
- expect(node.search('get', '/file.+js')[0]).toEqual([['file', {}]])
56
- expect(node.search('get', '/fileZZjs')[0]).toEqual([])
57
- })
58
-
59
- it('registers the pattern when its child already exists', () => {
60
- const node = new Node()
61
- node.insert('get', '/assets*/x', 'literal')
62
- node.insert('get', '/assets*', 'assets')
63
- expect(node.search('get', '/assets/app.js')[0]).toEqual([['assets', {}]])
64
- })
65
- })
66
-
67
- describe('Basic Usage', () => {
68
- const node = new Node()
69
- node.insert('get', '/hello', 'get hello')
70
- node.insert('post', '/hello', 'post hello')
71
- node.insert('get', '/hello/foo', 'get hello foo')
72
-
73
- it('get, post /hello', () => {
74
- expect(node.search('get', '/')[0].length).toBe(0)
75
- expect(node.search('post', '/')[0].length).toBe(0)
76
-
77
- expect(node.search('get', '/hello')[0][0][0]).toEqual('get hello')
78
- expect(node.search('post', '/hello')[0][0][0]).toEqual('post hello')
79
- expect(node.search('put', '/hello')[0].length).toBe(0)
80
- })
81
- it('get /nothing', () => {
82
- expect(node.search('get', '/nothing')[0].length).toBe(0)
83
- })
84
- it('/hello/foo, /hello/bar', () => {
85
- expect(node.search('get', '/hello/foo')[0][0][0]).toEqual('get hello foo')
86
- expect(node.search('post', '/hello/foo')[0].length).toBe(0)
87
- expect(node.search('get', '/hello/bar')[0].length).toBe(0)
88
- })
89
- it('/hello/foo/bar', () => {
90
- expect(node.search('get', '/hello/foo/bar')[0].length).toBe(0)
91
- })
92
- })
93
-
94
- describe('Name path', () => {
95
- const node = new Node()
96
- node.insert('get', '/entry/:id', 'get entry')
97
- node.insert('get', '/entry/:id/comment/:comment_id', 'get comment')
98
- node.insert('get', '/map/:location/events', 'get events')
99
- node.insert('get', '/about/:name/address/map', 'get address')
100
-
101
- it('get /entry/123', () => {
102
- const [res] = node.search('get', '/entry/123')
103
- expect(res.length).toBe(1)
104
- expect(res[0][0]).toEqual('get entry')
105
- expect(res[0][1]).not.toBeNull()
106
- expect(res[0][1]['id']).toBe('123')
107
- expect(res[0][1]['id']).not.toBe('1234')
108
- })
109
-
110
- it('get /entry/456/comment', () => {
111
- const [res] = node.search('get', '/entry/456/comment')
112
- expect(res.length).toBe(0)
113
- })
114
-
115
- it('get /entry/789/comment/123', () => {
116
- const [res] = node.search('get', '/entry/789/comment/123')
117
- expect(res.length).toBe(1)
118
- expect(res[0][0]).toEqual('get comment')
119
- expect(res[0][1]['id']).toBe('789')
120
- expect(res[0][1]['comment_id']).toBe('123')
121
- })
122
-
123
- it('get /map/:location/events', () => {
124
- const [res] = node.search('get', '/map/yokohama/events')
125
- expect(res.length).toBe(1)
126
- expect(res[0][0]).toEqual('get events')
127
- expect(res[0][1]['location']).toBe('yokohama')
128
- })
129
-
130
- it('get /about/:name/address/map', () => {
131
- const [res] = node.search('get', '/about/foo/address/map')
132
- expect(res.length).toBe(1)
133
- expect(res[0][0]).toEqual('get address')
134
- expect(res[0][1]['name']).toBe('foo')
135
- })
136
-
137
- it('Should not return a previous param value', () => {
138
- const node = new Node()
139
- node.insert('delete', '/resource/:id', 'resource')
140
- const [resA] = node.search('delete', '/resource/a')
141
- const [resB] = node.search('delete', '/resource/b')
142
- expect(resA).not.toBeNull()
143
- expect(resA.length).toBe(1)
144
- expect(resA[0][0]).toEqual('resource')
145
- expect(resA[0][1]).toEqual({ id: 'a' })
146
- expect(resB).not.toBeNull()
147
- expect(resB.length).toBe(1)
148
- expect(resB[0][0]).toEqual('resource')
149
- expect(resB[0][1]).toEqual({ id: 'b' })
150
- })
151
-
152
- it('Should return a sorted values', () => {
153
- const node = new Node()
154
- node.insert('get', '/resource/a', 'A')
155
- node.insert('get', '/resource/*', 'Star')
156
- const [res] = node.search('get', '/resource/a')
157
- expect(res).not.toBeNull()
158
- expect(res.length).toBe(2)
159
- expect(res[0][0]).toEqual('A')
160
- expect(res[1][0]).toEqual('Star')
161
- })
162
- })
163
-
164
- describe('Name path - Multiple route', () => {
165
- const node = new Node()
166
-
167
- node.insert('get', '/:type/:id', 'common')
168
- node.insert('get', '/posts/:id', 'specialized')
169
-
170
- it('get /posts/123', () => {
171
- const [res] = node.search('get', '/posts/123')
172
- expect(res.length).toBe(2)
173
- expect(res[0][0]).toEqual('common')
174
- expect(res[0][1]['id']).toBe('123')
175
- expect(res[1][0]).toEqual('specialized')
176
- expect(res[1][1]['id']).toBe('123')
177
- })
178
- })
179
-
180
- describe('Param prefix', () => {
181
- const node = new Node()
182
-
183
- node.insert('get', '/:foo', 'onepart')
184
- node.insert('get', '/:bar/:baz', 'twopart')
185
-
186
- it('get /hello', () => {
187
- const [res] = node.search('get', '/hello')
188
- expect(res.length).toBe(1)
189
- expect(res[0][0]).toEqual('onepart')
190
- expect(res[0][1]['foo']).toBe('hello')
191
- })
192
-
193
- it('get /hello/world', () => {
194
- const [res] = node.search('get', '/hello/world')
195
- expect(res.length).toBe(1)
196
- expect(res[0][0]).toEqual('twopart')
197
- expect(res[0][1]['bar']).toBe('hello')
198
- expect(res[0][1]['baz']).toBe('world')
199
- })
200
- })
201
-
202
- describe('Named params and a wildcard', () => {
203
- const node = new Node()
204
-
205
- node.insert('get', '/:id/*', 'onepart')
206
-
207
- it('get /', () => {
208
- const [res] = node.search('get', '/')
209
- expect(res.length).toBe(0)
210
- })
211
-
212
- it('get /foo', () => {
213
- const [res] = node.search('get', '/foo')
214
- expect(res.length).toBe(1)
215
- expect(res[0][0]).toEqual('onepart')
216
- expect(res[0][1]['id']).toEqual('foo')
217
- })
218
-
219
- it('get /foo/bar', () => {
220
- const [res] = node.search('get', '/foo/bar')
221
- expect(res.length).toBe(1)
222
- expect(res[0][0]).toEqual('onepart')
223
- expect(res[0][1]['id']).toEqual('foo')
224
- })
225
- })
226
-
227
- describe('Wildcard', () => {
228
- const node = new Node()
229
- node.insert('get', '/wildcard-abc/*/wildcard-efg', 'wildcard')
230
- it('/wildcard-abc/xxxxxx/wildcard-efg', () => {
231
- const [res] = node.search('get', '/wildcard-abc/xxxxxx/wildcard-efg')
232
- expect(res.length).toBe(1)
233
- expect(res[0][0]).toEqual('wildcard')
234
- })
235
- node.insert('get', '/wildcard-abc/*/wildcard-efg/hijk', 'wildcard')
236
- it('/wildcard-abc/xxxxxx/wildcard-efg/hijk', () => {
237
- const [res] = node.search('get', '/wildcard-abc/xxxxxx/wildcard-efg/hijk')
238
- expect(res.length).toBe(1)
239
- expect(res[0][0]).toEqual('wildcard')
240
- })
241
- })
242
-
243
- describe('Regexp', () => {
244
- const node = new Node()
245
- node.insert('get', '/regex-abc/:id{[0-9]+}/comment/:comment_id{[a-z]+}', 'regexp')
246
- it('/regexp-abc/123/comment/abc', () => {
247
- const [res] = node.search('get', '/regex-abc/123/comment/abc')
248
- expect(res.length).toBe(1)
249
- expect(res[0][0]).toEqual('regexp')
250
- expect(res[0][1]['id']).toBe('123')
251
- expect(res[0][1]['comment_id']).toBe('abc')
252
- })
253
- it('/regexp-abc/abc', () => {
254
- const [res] = node.search('get', '/regex-abc/abc')
255
- expect(res.length).toBe(0)
256
- })
257
- it('/regexp-abc/123/comment/123', () => {
258
- const [res] = node.search('get', '/regex-abc/123/comment/123')
259
- expect(res.length).toBe(0)
260
- })
261
- })
262
-
263
- describe('All', () => {
264
- const node = new Node()
265
- node.insert('ALL', '/all-methods', 'all methods') // ALL
266
- it('/all-methods', () => {
267
- let [res] = node.search('get', '/all-methods')
268
- expect(res.length).toBe(1)
269
- expect(res[0][0]).toEqual('all methods')
270
- ;[res] = node.search('put', '/all-methods')
271
- expect(res.length).toBe(1)
272
- expect(res[0][0]).toEqual('all methods')
273
- })
274
- })
275
-
276
- describe('Special Wildcard', () => {
277
- const node = new Node()
278
- node.insert('ALL', '*', 'match all')
279
-
280
- it('/foo', () => {
281
- const [res] = node.search('get', '/foo')
282
- expect(res.length).toBe(1)
283
- expect(res[0][0]).toEqual('match all')
284
- })
285
- it('/hello', () => {
286
- const [res] = node.search('get', '/hello')
287
- expect(res.length).toBe(1)
288
- expect(res[0][0]).toEqual('match all')
289
- })
290
- it('/hello/foo', () => {
291
- const [res] = node.search('get', '/hello/foo')
292
- expect(res.length).toBe(1)
293
- expect(res[0][0]).toEqual('match all')
294
- })
295
- })
296
-
297
- describe('Special Wildcard deeply', () => {
298
- const node = new Node()
299
- node.insert('ALL', '/hello/*', 'match hello')
300
- it('/hello', () => {
301
- const [res] = node.search('get', '/hello')
302
- expect(res.length).toBe(1)
303
- expect(res[0][0]).toEqual('match hello')
304
- })
305
- it('/hello/foo', () => {
306
- const [res] = node.search('get', '/hello/foo')
307
- expect(res.length).toBe(1)
308
- expect(res[0][0]).toEqual('match hello')
309
- })
310
- })
311
-
312
- describe('Default with wildcard', () => {
313
- const node = new Node()
314
- node.insert('ALL', '/api/*', 'fallback')
315
- node.insert('ALL', '/api/abc', 'match api')
316
- it('/api/abc', () => {
317
- const [res] = node.search('get', '/api/abc')
318
- expect(res.length).toBe(2)
319
- expect(res[0][0]).toEqual('fallback')
320
- expect(res[1][0]).toEqual('match api')
321
- })
322
- it('/api/def', () => {
323
- const [res] = node.search('get', '/api/def')
324
- expect(res.length).toBe(1)
325
- expect(res[0][0]).toEqual('fallback')
326
- })
327
- })
328
-
329
- describe('Multi match', () => {
330
- describe('Basic', () => {
331
- const node = new Node()
332
- node.insert('get', '*', 'GET *')
333
- node.insert('get', '/abc/*', 'GET /abc/*')
334
- node.insert('get', '/abc/*/edf', 'GET /abc/*/edf')
335
- node.insert('get', '/abc/edf', 'GET /abc/edf')
336
- node.insert('get', '/abc/*/ghi/jkl', 'GET /abc/*/ghi/jkl')
337
- it('get /abc/edf', () => {
338
- const [res] = node.search('get', '/abc/edf')
339
- expect(res.length).toBe(3)
340
- expect(res[0][0]).toEqual('GET *')
341
- expect(res[1][0]).toEqual('GET /abc/*')
342
- expect(res[2][0]).toEqual('GET /abc/edf')
343
- })
344
- it('get /abc/xxx/edf', () => {
345
- const [res] = node.search('get', '/abc/xxx/edf')
346
- expect(res.length).toBe(3)
347
- expect(res[0][0]).toEqual('GET *')
348
- expect(res[1][0]).toEqual('GET /abc/*')
349
- expect(res[2][0]).toEqual('GET /abc/*/edf')
350
- })
351
- it('get /', () => {
352
- const [res] = node.search('get', '/')
353
- expect(res.length).toBe(1)
354
- expect(res[0][0]).toEqual('GET *')
355
- })
356
- it('post /', () => {
357
- const [res] = node.search('post', '/')
358
- expect(res.length).toBe(0)
359
- })
360
- it('get /abc/edf/ghi', () => {
361
- const [res] = node.search('get', '/abc/edf/ghi')
362
- expect(res.length).toBe(2)
363
- expect(res[0][0]).toEqual('GET *')
364
- expect(res[1][0]).toEqual('GET /abc/*')
365
- })
366
- })
367
- describe('Blog', () => {
368
- const node = new Node()
369
- node.insert('get', '*', 'middleware a') // 0.1
370
- node.insert('ALL', '*', 'middleware b') // 0.2 <===
371
- node.insert('get', '/entry', 'get entries') // 1.3
372
- node.insert('post', '/entry/*', 'middleware c') // 1.4 <===
373
- node.insert('post', '/entry', 'post entry') // 1.5 <===
374
- node.insert('get', '/entry/:id', 'get entry') // 2.6
375
- node.insert('get', '/entry/:id/comment/:comment_id', 'get comment') // 4.7
376
- it('get /entry/123', async () => {
377
- const [res] = node.search('get', '/entry/123')
378
- expect(res.length).toBe(3)
379
- expect(res[0][0]).toEqual('middleware a')
380
- expect(res[0][1]['id']).toBe(undefined)
381
- expect(res[1][0]).toEqual('middleware b')
382
- expect(res[1][1]['id']).toBe(undefined)
383
- expect(res[2][0]).toEqual('get entry')
384
- expect(res[2][1]['id']).toBe('123')
385
- })
386
- it('get /entry/123/comment/456', async () => {
387
- const [res] = node.search('get', '/entry/123/comment/456')
388
- expect(res.length).toBe(3)
389
- expect(res[0][0]).toEqual('middleware a')
390
- expect(res[0][1]['id']).toBe(undefined)
391
- expect(res[0][1]['comment_id']).toBe(undefined)
392
- expect(res[1][0]).toEqual('middleware b')
393
- expect(res[1][1]['id']).toBe(undefined)
394
- expect(res[1][1]['comment_id']).toBe(undefined)
395
- expect(res[2][0]).toEqual('get comment')
396
- expect(res[2][1]['id']).toBe('123')
397
- expect(res[2][1]['comment_id']).toBe('456')
398
- })
399
- it('post /entry', async () => {
400
- const [res] = node.search('post', '/entry')
401
- expect(res.length).toBe(3)
402
- expect(res[0][0]).toEqual('middleware b')
403
- expect(res[1][0]).toEqual('middleware c')
404
- expect(res[2][0]).toEqual('post entry')
405
- })
406
- it('delete /entry', async () => {
407
- const [res] = node.search('delete', '/entry')
408
- expect(res.length).toBe(1)
409
- expect(res[0][0]).toEqual('middleware b')
410
- })
411
- })
412
- describe('ALL', () => {
413
- const node = new Node()
414
- node.insert('ALL', '*', 'ALL *')
415
- node.insert('ALL', '/abc/*', 'ALL /abc/*')
416
- node.insert('ALL', '/abc/*/def', 'ALL /abc/*/def')
417
- it('get /', () => {
418
- const [res] = node.search('get', '/')
419
- expect(res.length).toBe(1)
420
- expect(res[0][0]).toEqual('ALL *')
421
- })
422
- it('post /abc', () => {
423
- const [res] = node.search('post', '/abc')
424
- expect(res.length).toBe(2)
425
- expect(res[0][0]).toEqual('ALL *')
426
- expect(res[1][0]).toEqual('ALL /abc/*')
427
- })
428
- it('delete /abc/xxx/def', () => {
429
- const [res] = node.search('post', '/abc/xxx/def')
430
- expect(res.length).toBe(3)
431
- expect(res[0][0]).toEqual('ALL *')
432
- expect(res[1][0]).toEqual('ALL /abc/*')
433
- expect(res[2][0]).toEqual('ALL /abc/*/def')
434
- })
435
- })
436
- describe('Regexp', () => {
437
- const node = new Node()
438
- node.insert('get', '/regex-abc/:id{[0-9]+}/*', 'middleware a')
439
- node.insert('get', '/regex-abc/:id{[0-9]+}/def', 'regexp')
440
- it('/regex-abc/123/def', () => {
441
- const [res] = node.search('get', '/regex-abc/123/def')
442
- expect(res.length).toBe(2)
443
- expect(res[0][0]).toEqual('middleware a')
444
- expect(res[0][1]['id']).toBe('123')
445
- expect(res[1][0]).toEqual('regexp')
446
- expect(res[1][1]['id']).toBe('123')
447
- })
448
- it('/regex-abc/123/ghi', () => {
449
- const [res] = node.search('get', '/regex-abc/123/ghi')
450
- expect(res.length).toBe(1)
451
- expect(res[0][0]).toEqual('middleware a')
452
- expect(res[0][1]['id']).toBe('123')
453
- })
454
- it('/regex-abc/123', () => {
455
- const [res] = node.search('get', '/regex-abc/123')
456
- expect(res.length).toBe(1)
457
- expect(res[0][0]).toEqual('middleware a')
458
- expect(res[0][1]['id']).toBe('123')
459
- })
460
- })
461
- describe('Trailing slash', () => {
462
- const node = new Node()
463
- node.insert('get', '/book', 'GET /book')
464
- node.insert('get', '/book/:id', 'GET /book/:id')
465
- it('get /book', () => {
466
- const [res] = node.search('get', '/book')
467
- expect(res.length).toBe(1)
468
- })
469
- it('get /book/', () => {
470
- const [res] = node.search('get', '/book/')
471
- expect(res.length).toBe(0)
472
- })
473
- })
474
- describe('Same path', () => {
475
- const node = new Node()
476
- node.insert('get', '/hey', 'Middleware A')
477
- node.insert('get', '/hey', 'Middleware B')
478
- it('get /hey', () => {
479
- const [res] = node.search('get', '/hey')
480
- expect(res.length).toBe(2)
481
- expect(res[0][0]).toEqual('Middleware A')
482
- expect(res[1][0]).toEqual('Middleware B')
483
- })
484
- })
485
- describe('Including slashes', () => {
486
- const node = new Node()
487
- node.insert('get', '/js/:filename{[a-z0-9/]+.js}', 'any file')
488
- node.insert('get', '/js/main.js', 'main.js')
489
- it('get /js/main.js', () => {
490
- const [res] = node.search('get', '/js/main.js')
491
- expect(res.length).toBe(2)
492
- expect(res[0][0]).toEqual('any file')
493
- expect(res[0][1]).toEqual({ filename: 'main.js' })
494
- expect(res[1][0]).toEqual('main.js')
495
- expect(res[1][1]).toEqual({})
496
- })
497
- it('get /js/chunk/123.js', () => {
498
- const [res] = node.search('get', '/js/chunk/123.js')
499
- expect(res.length).toBe(1)
500
- expect(res[0][0]).toEqual('any file')
501
- expect(res[0][1]).toEqual({ filename: 'chunk/123.js' })
502
- })
503
- it('get /js/chunk/nest/123.js', () => {
504
- const [res] = node.search('get', '/js/chunk/nest/123.js')
505
- expect(res.length).toBe(1)
506
- expect(res[0][0]).toEqual('any file')
507
- expect(res[0][1]).toEqual({ filename: 'chunk/nest/123.js' })
508
- })
509
- })
510
- describe('REST API', () => {
511
- const node = new Node()
512
- node.insert('get', '/users/:username{[a-z]+}', 'profile')
513
- node.insert('get', '/users/:username{[a-z]+}/posts', 'posts')
514
- it('get /users/acryl', () => {
515
- const [res] = node.search('get', '/users/acryl')
516
- expect(res.length).toBe(1)
517
- expect(res[0][0]).toEqual('profile')
518
- })
519
- it('get /users/acryl/posts', () => {
520
- const [res] = node.search('get', '/users/acryl/posts')
521
- expect(res.length).toBe(1)
522
- expect(res[0][0]).toEqual('posts')
523
- })
524
- })
525
- })
526
-
527
- describe('Duplicate param name', () => {
528
- it('self', () => {
529
- const node = new Node()
530
- node.insert('get', '/:id/:id', 'foo')
531
- const [res] = node.search('get', '/123/456')
532
- expect(res.length).toBe(1)
533
- expect(res[0][0]).toBe('foo')
534
- expect(res[0][1]['id']).toBe('123')
535
- })
536
-
537
- it('self with trailing static', () => {
538
- const node = new Node()
539
- node.insert('get', '/:id/:id/x', 'foo')
540
- const [res] = node.search('get', '/123/456/x')
541
- expect(res.length).toBe(1)
542
- expect(res[0][0]).toBe('foo')
543
- expect(res[0][1]['id']).toBe('123')
544
- })
545
-
546
- it('self three times', () => {
547
- const node = new Node()
548
- node.insert('get', '/:id/:id/:id', 'foo')
549
- const [res] = node.search('get', '/1/2/3')
550
- expect(res.length).toBe(1)
551
- expect(res[0][0]).toBe('foo')
552
- expect(res[0][1]['id']).toBe('1')
553
- })
554
-
555
- it('self with regexp matcher', () => {
556
- const node = new Node()
557
- node.insert('get', '/:id/:id{[0-9]+}', 'foo')
558
- const [res] = node.search('get', '/abc/123')
559
- expect(res.length).toBe(1)
560
- expect(res[0][0]).toBe('foo')
561
- expect(res[0][1]['id']).toBe('abc')
562
- })
563
-
564
- describe('parent', () => {
565
- const node = new Node()
566
- node.insert('get', '/:id/:action', 'foo')
567
- node.insert('get', '/posts/:id', 'bar')
568
- node.insert('get', '/posts/:id/comments/:comment_id', 'comment')
569
-
570
- it('get /123/action', () => {
571
- const [res] = node.search('get', '/123/action')
572
- expect(res.length).toBe(1)
573
- expect(res[0][0]).toBe('foo')
574
- expect(res[0][1]).toEqual({ id: '123', action: 'action' })
575
- })
576
- })
577
-
578
- it('get /posts/456 for comments', () => {
579
- const node = new Node()
580
- node.insert('get', '/posts/:id/comments/:comment_id', 'comment')
581
- const [res] = node.search('get', '/posts/abc/comments/edf')
582
- expect(res.length).toBe(1)
583
- expect(res[0][0]).toBe('comment')
584
- expect(res[0][1]).toEqual({ id: 'abc', comment_id: 'edf' })
585
- })
586
-
587
- describe('child', () => {
588
- const node = new Node()
589
- node.insert('get', '/posts/:id', 'foo')
590
- node.insert('get', '/:id/:action', 'bar')
591
- it('get /posts/action', () => {
592
- const [res] = node.search('get', '/posts/action')
593
- expect(res.length).toBe(2)
594
- expect(res[0][0]).toBe('foo')
595
- expect(res[0][1]).toEqual({ id: 'action' })
596
- expect(res[1][0]).toBe('bar')
597
- expect(res[1][1]).toEqual({ id: 'posts', action: 'action' })
598
- })
599
- })
600
-
601
- describe('regular expression', () => {
602
- const node = new Node()
603
- node.insert('get', '/:id/:action{create|update}', 'foo')
604
- node.insert('get', '/:id/:action{delete}', 'bar')
605
- it('get /123/create', () => {
606
- const [res] = node.search('get', '/123/create')
607
- expect(res.length).toBe(1)
608
- expect(res[0][0]).toBe('foo')
609
- expect(res[0][1]).toEqual({ id: '123', action: 'create' })
610
- })
611
- it('get /123/delete', () => {
612
- const [res] = node.search('get', '/123/delete')
613
- expect(res.length).toBe(1)
614
- expect(res[0][0]).toBe('bar')
615
- expect(res[0][1]).toEqual({ id: '123', action: 'delete' })
616
- })
617
- })
618
- })
619
-
620
- describe('Sort Order', () => {
621
- describe('Basic', () => {
622
- const node = new Node()
623
- node.insert('get', '*', 'a')
624
- node.insert('get', '/page', '/page')
625
- node.insert('get', '/:slug', '/:slug')
626
-
627
- it('get /page', () => {
628
- const [res] = node.search('get', '/page')
629
- expect(res.length).toBe(3)
630
- expect(res[0][0]).toEqual('a')
631
- expect(res[1][0]).toEqual('/page')
632
- expect(res[2][0]).toEqual('/:slug')
633
- })
634
- })
635
-
636
- describe('With Named path', () => {
637
- const node = new Node()
638
- node.insert('get', '*', 'a')
639
- node.insert('get', '/posts/:id', '/posts/:id')
640
- node.insert('get', '/:type/:id', '/:type/:id')
641
-
642
- it('get /posts/123', () => {
643
- const [res] = node.search('get', '/posts/123')
644
- expect(res.length).toBe(3)
645
- expect(res[0][0]).toEqual('a')
646
- expect(res[1][0]).toEqual('/posts/:id')
647
- expect(res[2][0]).toEqual('/:type/:id')
648
- })
649
- })
650
-
651
- describe('With Wildcards', () => {
652
- const node = new Node()
653
- node.insert('get', '/api/*', '1st')
654
- node.insert('get', '/api/*', '2nd')
655
- node.insert('get', '/api/posts/:id', '3rd')
656
- node.insert('get', '/api/*', '4th')
657
-
658
- it('get /api/posts/123', () => {
659
- const [res] = node.search('get', '/api/posts/123')
660
- expect(res.length).toBe(4)
661
- expect(res[0][0]).toEqual('1st')
662
- expect(res[1][0]).toEqual('2nd')
663
- expect(res[2][0]).toEqual('3rd')
664
- expect(res[3][0]).toEqual('4th')
665
- })
666
- })
667
-
668
- describe('With special Wildcard', () => {
669
- const node = new Node()
670
- node.insert('get', '/posts', '/posts') // 1.1
671
- node.insert('get', '/posts/*', '/posts/*') // 1.2
672
- node.insert('get', '/posts/:id', '/posts/:id') // 2.3
673
-
674
- it('get /posts', () => {
675
- const [res] = node.search('get', '/posts')
676
- expect(res.length).toBe(2)
677
- expect(res[0][0]).toEqual('/posts')
678
- expect(res[1][0]).toEqual('/posts/*')
679
- })
680
- })
681
-
682
- describe('Complex', () => {
683
- const node = new Node()
684
- node.insert('get', '/api', 'a') // not match
685
- node.insert('get', '/api/*', 'b') // match
686
- node.insert('get', '/api/:type', 'c') // not match
687
- node.insert('get', '/api/:type/:id', 'd') // match
688
- node.insert('get', '/api/posts/:id', 'e') // match
689
- node.insert('get', '/api/posts/123', 'f') // match
690
- node.insert('get', '/*/*/:id', 'g') // match
691
- node.insert('get', '/api/posts/*/comment', 'h') // not match
692
- node.insert('get', '*', 'i') // match
693
- node.insert('get', '*', 'j') // match
694
-
695
- it('get /api/posts/123', () => {
696
- const [res] = node.search('get', '/api/posts/123')
697
- expect(res.length).toBe(7)
698
- expect(res[0][0]).toEqual('b')
699
- expect(res[1][0]).toEqual('d')
700
- expect(res[2][0]).toEqual('e')
701
- expect(res[3][0]).toEqual('f')
702
- expect(res[4][0]).toEqual('g')
703
- expect(res[5][0]).toEqual('i')
704
- expect(res[6][0]).toEqual('j')
705
- })
706
- })
707
-
708
- describe('Multi match', () => {
709
- const node = new Node()
710
- node.insert('get', '*', 'GET *') // 0.1
711
- node.insert('get', '/abc/*', 'GET /abc/*') // 1.2
712
- node.insert('get', '/abc/edf', 'GET /abc/edf') // 2.3
713
- node.insert('get', '/abc/*/ghi/jkl', 'GET /abc/*/ghi/jkl') // 4.4
714
- it('get /abc/edf', () => {
715
- const [res] = node.search('get', '/abc/edf')
716
- expect(res.length).toBe(3)
717
- expect(res[0][0]).toEqual('GET *')
718
- expect(res[1][0]).toEqual('GET /abc/*')
719
- expect(res[2][0]).toEqual('GET /abc/edf')
720
- })
721
- })
722
-
723
- describe('Multi match', () => {
724
- const node = new Node()
725
-
726
- node.insert('get', '/api/*', 'a') // 2.1 for /api/entry
727
- node.insert('get', '/api/entry', 'entry') // 2.2
728
- node.insert('ALL', '/api/*', 'b') // 2.3 for /api/entry
729
-
730
- it('get /api/entry', async () => {
731
- const [res] = node.search('get', '/api/entry')
732
- expect(res.length).toBe(3)
733
- expect(res[0][0]).toEqual('a')
734
- expect(res[1][0]).toEqual('entry')
735
- expect(res[2][0]).toEqual('b')
736
- })
737
- })
738
-
739
- describe('fallback', () => {
740
- describe('Blog - failed', () => {
741
- const node = new Node()
742
- node.insert('post', '/entry', 'post entry') // 1.1
743
- node.insert('post', '/entry/*', 'fallback') // 1.2
744
- node.insert('get', '/entry/:id', 'get entry') // 2.3
745
- it('post /entry', async () => {
746
- const [res] = node.search('post', '/entry')
747
- expect(res.length).toBe(2)
748
- expect(res[0][0]).toEqual('post entry')
749
- expect(res[1][0]).toEqual('fallback')
750
- })
751
- })
752
- })
753
- describe('page', () => {
754
- const node = new Node()
755
- node.insert('get', '/page', 'page') // 1.1
756
- node.insert('ALL', '/*', 'fallback') // 1.2
757
- it('get /page', async () => {
758
- const [res] = node.search('get', '/page')
759
- expect(res.length).toBe(2)
760
- expect(res[0][0]).toEqual('page')
761
- expect(res[1][0]).toEqual('fallback')
762
- })
763
- })
764
- })
765
-
766
- describe('star', () => {
767
- const node = new Node()
768
- node.insert('get', '/', '/')
769
- node.insert('get', '/*', '/*')
770
- node.insert('get', '*', '*')
771
-
772
- node.insert('get', '/x', '/x')
773
- node.insert('get', '/x/*', '/x/*')
774
-
775
- it('top', async () => {
776
- const [res] = node.search('get', '/')
777
- expect(res.length).toBe(3)
778
- expect(res[0][0]).toEqual('/')
779
- expect(res[1][0]).toEqual('/*')
780
- expect(res[2][0]).toEqual('*')
781
- })
782
-
783
- it('Under a certain path', async () => {
784
- const [res] = node.search('get', '/x')
785
- expect(res.length).toBe(4)
786
- expect(res[0][0]).toEqual('/*')
787
- expect(res[1][0]).toEqual('*')
788
- expect(res[2][0]).toEqual('/x')
789
- expect(res[3][0]).toEqual('/x/*')
790
- })
791
- })
792
-
793
- describe('Routing order With named parameters', () => {
794
- const node = new Node()
795
- node.insert('get', '/book/a', 'no-slug')
796
- node.insert('get', '/book/:slug', 'slug')
797
- node.insert('get', '/book/b', 'no-slug-b')
798
- it('/book/a', () => {
799
- const [res] = node.search('get', '/book/a')
800
- expect(res).not.toBeNull()
801
- expect(res.length).toBe(2)
802
- expect(res[0][0]).toEqual('no-slug')
803
- expect(res[0][1]).toEqual({})
804
- expect(res[1][0]).toEqual('slug')
805
- expect(res[1][1]).toEqual({ slug: 'a' })
806
- })
807
- it('/book/foo', () => {
808
- const [res] = node.search('get', '/book/foo')
809
- expect(res).not.toBeNull()
810
- expect(res.length).toBe(1)
811
- expect(res[0][0]).toEqual('slug')
812
- expect(res[0][1]).toEqual({ slug: 'foo' })
813
- expect(res[0][1]['slug']).toBe('foo')
814
- })
815
- it('/book/b', () => {
816
- const [res] = node.search('get', '/book/b')
817
- expect(res).not.toBeNull()
818
- expect(res.length).toBe(2)
819
- expect(res[0][0]).toEqual('slug')
820
- expect(res[0][1]).toEqual({ slug: 'b' })
821
- expect(res[1][0]).toEqual('no-slug-b')
822
- expect(res[1][1]).toEqual({})
823
- })
824
- })
825
-
826
- describe('The same name is used for path params', () => {
827
- describe('Basic', () => {
828
- const node = new Node()
829
- node.insert('get', '/:a/:b/:c', 'abc')
830
- node.insert('get', '/:a/:b/:c/:d', 'abcd')
831
- it('/1/2/3', () => {
832
- const [res] = node.search('get', '/1/2/3')
833
- expect(res).not.toBeNull()
834
- expect(res.length).toBe(1)
835
- expect(res[0][0]).toEqual('abc')
836
- expect(res[0][1]).toEqual({ a: '1', b: '2', c: '3' })
837
- })
838
- })
839
-
840
- describe('Complex', () => {
841
- const node = new Node()
842
- node.insert('get', '/:a', 'a')
843
- node.insert('get', '/:b/:a', 'ba')
844
- it('/about/me', () => {
845
- const [res] = node.search('get', '/about/me')
846
- expect(res).not.toBeNull()
847
- expect(res.length).toBe(1)
848
- expect(res[0][0]).toEqual('ba')
849
- expect(res[0][1]).toEqual({ b: 'about', a: 'me' })
850
- })
851
- })
852
-
853
- describe('Complex with tails', () => {
854
- const node = new Node()
855
- node.insert('get', '/:id/:id2/comments', 'a')
856
- node.insert('get', '/posts/:id/comments', 'b')
857
- it('/posts/123/comments', () => {
858
- const [res] = node.search('get', '/posts/123/comments')
859
- expect(res).not.toBeNull()
860
- expect(res.length).toBe(2)
861
- expect(res[0][0]).toEqual('a')
862
- expect(res[0][1]).toEqual({ id: 'posts', id2: '123' })
863
- expect(res[1][0]).toEqual('b')
864
- expect(res[1][1]).toEqual({ id: '123' })
865
- })
866
- })
867
- })
868
-
869
- describe('Pattern spanning multiple parts', () => {
870
- describe('followed by a wildcard', () => {
871
- const node = new Node()
872
- node.insert('get', '/:file{.*}/*', 'file')
873
-
874
- it('should return the handler once per matching part count', () => {
875
- for (const path of ['/a', '/a/b', '/a/b/c', '/a/b/c/d']) {
876
- const [res] = node.search('get', path)
877
- expect(res.length).toBe(1)
878
- expect(res[0][0]).toEqual('file')
879
- }
880
- })
881
- })
882
-
883
- describe('followed by a static part', () => {
884
- const node = new Node()
885
- node.insert('get', '/:dirs{.+}/file.html', 'file.html')
886
-
887
- it('should match however many parts the pattern spans', () => {
888
- for (const dirs of ['foo', 'foo/bar', 'foo/bar/baz', 'a/b/c/d']) {
889
- const [res] = node.search('get', `/${dirs}/file.html`)
890
- expect(res.length).toBe(1)
891
- expect(res[0][0]).toEqual('file.html')
892
- expect(res[0][1]).toEqual({ dirs })
893
- }
894
- })
895
- })
896
- })