@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (392) hide show
  1. package/dist/cli/checks/lighthouse.d.ts +26 -0
  2. package/dist/cli/checks/lighthouse.d.ts.map +1 -0
  3. package/dist/cli/checks/lighthouse.js +121 -0
  4. package/dist/cli/checks/lighthouse.js.map +1 -0
  5. package/dist/cli/checks/links.d.ts +12 -0
  6. package/dist/cli/checks/links.d.ts.map +1 -0
  7. package/dist/cli/checks/links.js +89 -0
  8. package/dist/cli/checks/links.js.map +1 -0
  9. package/dist/cli/checks/performance.d.ts +17 -0
  10. package/dist/cli/checks/performance.d.ts.map +1 -0
  11. package/dist/cli/checks/performance.js +61 -0
  12. package/dist/cli/checks/performance.js.map +1 -0
  13. package/dist/cli/commands/check.d.ts +3 -0
  14. package/dist/cli/commands/check.d.ts.map +1 -0
  15. package/dist/cli/commands/check.js +85 -0
  16. package/dist/cli/commands/check.js.map +1 -0
  17. package/dist/cli/create/index.d.ts +11 -1
  18. package/dist/cli/create/index.d.ts.map +1 -1
  19. package/dist/cli/create/index.js +135 -65
  20. package/dist/cli/create/index.js.map +1 -1
  21. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  22. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  23. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  24. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  25. package/dist/cli/index.js +2 -0
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/index.d.ts +3 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/plugin/build-ssg.d.ts +22 -6
  30. package/dist/plugin/build-ssg.d.ts.map +1 -1
  31. package/dist/plugin/build-ssg.js +227 -17
  32. package/dist/plugin/build-ssg.js.map +1 -1
  33. package/dist/plugin/content/parser.d.ts.map +1 -1
  34. package/dist/plugin/content/parser.js +54 -10
  35. package/dist/plugin/content/parser.js.map +1 -1
  36. package/dist/plugin/dev-server.d.ts +4 -1
  37. package/dist/plugin/dev-server.d.ts.map +1 -1
  38. package/dist/plugin/dev-server.js.map +1 -1
  39. package/dist/plugin/dts-generator.d.ts.map +1 -1
  40. package/dist/plugin/dts-generator.js +50 -8
  41. package/dist/plugin/dts-generator.js.map +1 -1
  42. package/dist/plugin/generated-dir.d.ts +2 -0
  43. package/dist/plugin/generated-dir.d.ts.map +1 -1
  44. package/dist/plugin/generated-dir.js +17 -6
  45. package/dist/plugin/generated-dir.js.map +1 -1
  46. package/dist/plugin/html-post-process.d.ts +6 -0
  47. package/dist/plugin/html-post-process.d.ts.map +1 -1
  48. package/dist/plugin/html-post-process.js +24 -0
  49. package/dist/plugin/html-post-process.js.map +1 -1
  50. package/dist/plugin/index.d.ts.map +1 -1
  51. package/dist/plugin/index.js +60 -13
  52. package/dist/plugin/index.js.map +1 -1
  53. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  54. package/dist/plugin/transforms/auto-import.js +7 -0
  55. package/dist/plugin/transforms/auto-import.js.map +1 -1
  56. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  57. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  58. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  59. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  60. package/dist/runtime/app-template.d.ts +1 -1
  61. package/dist/runtime/app-template.d.ts.map +1 -1
  62. package/dist/runtime/app-template.js +206 -36
  63. package/dist/runtime/app-template.js.map +1 -1
  64. package/dist/runtime/composables/index.d.ts +4 -0
  65. package/dist/runtime/composables/index.d.ts.map +1 -1
  66. package/dist/runtime/composables/index.js +2 -0
  67. package/dist/runtime/composables/index.js.map +1 -1
  68. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  69. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  70. package/dist/runtime/composables/use-active-headings.js +112 -0
  71. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  72. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  73. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  74. package/dist/runtime/composables/use-content-page.js +179 -0
  75. package/dist/runtime/composables/use-content-page.js.map +1 -0
  76. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  77. package/dist/runtime/composables/use-content-search.js +1 -5
  78. package/dist/runtime/composables/use-content-search.js.map +1 -1
  79. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  80. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  81. package/dist/runtime/composables/use-fetch.js +112 -43
  82. package/dist/runtime/composables/use-fetch.js.map +1 -1
  83. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  84. package/dist/runtime/composables/use-route.js +39 -11
  85. package/dist/runtime/composables/use-route.js.map +1 -1
  86. package/dist/runtime/content/client.js +2 -2
  87. package/dist/runtime/content/client.js.map +1 -1
  88. package/dist/runtime/entry-server-template.d.ts +16 -1
  89. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  90. package/dist/runtime/entry-server-template.js +120 -13
  91. package/dist/runtime/entry-server-template.js.map +1 -1
  92. package/dist/types/config.d.ts +45 -4
  93. package/dist/types/config.d.ts.map +1 -1
  94. package/dist/types/config.js.map +1 -1
  95. package/dist/types/middleware.d.ts +2 -2
  96. package/dist/types/middleware.d.ts.map +1 -1
  97. package/package.json +22 -19
  98. package/.github/copilot-instructions.md +0 -169
  99. package/.github/workflows/publish.yml +0 -257
  100. package/.nvmrc +0 -1
  101. package/CHANGELOG.md +0 -236
  102. package/CLAUDE.md +0 -113
  103. package/commits.txt +0 -1
  104. package/cypress.config.ts +0 -16
  105. package/docs/authentication.md +0 -285
  106. package/docs/cli.md +0 -324
  107. package/docs/components.md +0 -237
  108. package/docs/composables.md +0 -907
  109. package/docs/configuration.md +0 -696
  110. package/docs/content.md +0 -570
  111. package/docs/data-loading.md +0 -336
  112. package/docs/getting-started.md +0 -237
  113. package/docs/head-management.md +0 -212
  114. package/docs/i18n.md +0 -159
  115. package/docs/layouts.md +0 -224
  116. package/docs/middleware.md +0 -234
  117. package/docs/plugins.md +0 -170
  118. package/docs/rendering-modes.md +0 -377
  119. package/docs/routing.md +0 -485
  120. package/docs/server-api.md +0 -253
  121. package/docs/testing.md +0 -455
  122. package/docs/use-fetch.md +0 -183
  123. package/e2e/cypress/e2e/api.cy.ts +0 -123
  124. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  125. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  126. package/e2e/cypress/e2e/content.cy.ts +0 -425
  127. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  128. package/e2e/cypress/e2e/data.cy.ts +0 -158
  129. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  130. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  131. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  132. package/e2e/cypress/e2e/head.cy.ts +0 -89
  133. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  134. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  135. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  136. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  137. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  138. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  139. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  140. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  141. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  142. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  143. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  144. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  145. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  146. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  147. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  148. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  149. package/e2e/cypress/e2e/session.cy.ts +0 -73
  150. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  151. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  152. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  153. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  154. package/e2e/cypress/support/commands.ts +0 -120
  155. package/e2e/cypress/support/e2e.ts +0 -10
  156. package/e2e/cypress/tsconfig.json +0 -14
  157. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  158. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  159. package/e2e/kitchen-sink/app/error.ts +0 -18
  160. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  161. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  162. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  163. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  164. package/e2e/kitchen-sink/app/loading.ts +0 -9
  165. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  166. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  167. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  168. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  169. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  170. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  171. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  172. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  173. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  174. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  175. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  176. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  177. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  178. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  179. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  180. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  181. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  182. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  183. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  184. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  185. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  186. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  187. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  188. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  189. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  190. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  191. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  192. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  193. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  194. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  195. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  196. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  197. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  198. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  199. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  200. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  201. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  202. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  203. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  204. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  205. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  206. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  207. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  208. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  209. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  210. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  211. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  212. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  213. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  214. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  215. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  216. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  217. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  218. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  219. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  220. package/e2e/kitchen-sink/cer.config.ts +0 -43
  221. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  222. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  223. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  224. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  225. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  226. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  227. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  228. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  229. package/e2e/kitchen-sink/content/index.md +0 -16
  230. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  231. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  232. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  233. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  234. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  235. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  236. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  237. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  238. package/e2e/kitchen-sink/tsconfig.json +0 -3
  239. package/e2e/scripts/clean.mjs +0 -14
  240. package/eslint.config.ts +0 -22
  241. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  242. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  243. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  244. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  245. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  246. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  247. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  248. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  249. package/src/__tests__/index.test.ts +0 -21
  250. package/src/__tests__/plugin/app-template.test.ts +0 -166
  251. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  252. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  253. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  254. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  255. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  256. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  257. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  258. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  259. package/src/__tests__/plugin/content/search.test.ts +0 -119
  260. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  261. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  262. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  263. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  264. package/src/__tests__/plugin/html-post-process.test.ts +0 -146
  265. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  266. package/src/__tests__/plugin/resolve-config.test.ts +0 -233
  267. package/src/__tests__/plugin/scanner.test.ts +0 -186
  268. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  269. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  270. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  271. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  272. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  273. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  274. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  275. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  276. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  277. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  278. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  279. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  280. package/src/__tests__/runtime/app-template.test.ts +0 -208
  281. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  282. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  283. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  284. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  285. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  286. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  287. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  288. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  289. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  290. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  291. package/src/__tests__/runtime/use-content.test.ts +0 -226
  292. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  293. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  294. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  295. package/src/__tests__/runtime/use-head.test.ts +0 -311
  296. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  297. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  298. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  299. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  300. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  301. package/src/__tests__/runtime/use-route.test.ts +0 -156
  302. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  303. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  304. package/src/__tests__/runtime/use-session.test.ts +0 -320
  305. package/src/__tests__/runtime/use-state.test.ts +0 -340
  306. package/src/__tests__/types/config.test.ts +0 -18
  307. package/src/cli/adapters/cloudflare.ts +0 -335
  308. package/src/cli/adapters/netlify.ts +0 -326
  309. package/src/cli/adapters/vercel.ts +0 -311
  310. package/src/cli/commands/adapt.ts +0 -84
  311. package/src/cli/commands/build.ts +0 -165
  312. package/src/cli/commands/dev.ts +0 -125
  313. package/src/cli/commands/generate.ts +0 -91
  314. package/src/cli/commands/preview-isr.ts +0 -172
  315. package/src/cli/commands/preview.ts +0 -523
  316. package/src/cli/create/index.ts +0 -275
  317. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  318. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  319. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  320. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  321. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  322. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  323. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  324. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  325. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  326. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  327. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  328. package/src/cli/index.ts +0 -22
  329. package/src/index.ts +0 -20
  330. package/src/plugin/build-ssg.ts +0 -403
  331. package/src/plugin/build-ssr.ts +0 -134
  332. package/src/plugin/content/emitter.ts +0 -50
  333. package/src/plugin/content/index.ts +0 -233
  334. package/src/plugin/content/parser.ts +0 -259
  335. package/src/plugin/content/path-utils.ts +0 -55
  336. package/src/plugin/content/scanner.ts +0 -26
  337. package/src/plugin/content/search.ts +0 -28
  338. package/src/plugin/dev-server.ts +0 -379
  339. package/src/plugin/dts-generator.ts +0 -273
  340. package/src/plugin/generated-dir.ts +0 -121
  341. package/src/plugin/html-post-process.ts +0 -96
  342. package/src/plugin/index.ts +0 -584
  343. package/src/plugin/path-utils.ts +0 -186
  344. package/src/plugin/scanner.ts +0 -65
  345. package/src/plugin/transforms/auto-import.ts +0 -206
  346. package/src/plugin/transforms/head-inject.ts +0 -161
  347. package/src/plugin/virtual/composables.ts +0 -28
  348. package/src/plugin/virtual/content-components.ts +0 -83
  349. package/src/plugin/virtual/error.ts +0 -34
  350. package/src/plugin/virtual/layouts.ts +0 -41
  351. package/src/plugin/virtual/loading.ts +0 -32
  352. package/src/plugin/virtual/middleware.ts +0 -45
  353. package/src/plugin/virtual/plugins.ts +0 -46
  354. package/src/plugin/virtual/routes.ts +0 -514
  355. package/src/plugin/virtual/server-api.ts +0 -85
  356. package/src/plugin/virtual/server-middleware.ts +0 -44
  357. package/src/runtime/app-template.ts +0 -377
  358. package/src/runtime/composables/define-middleware.ts +0 -17
  359. package/src/runtime/composables/define-server-middleware.ts +0 -18
  360. package/src/runtime/composables/index.ts +0 -27
  361. package/src/runtime/composables/use-auth.ts +0 -125
  362. package/src/runtime/composables/use-content-search.ts +0 -205
  363. package/src/runtime/composables/use-content.ts +0 -146
  364. package/src/runtime/composables/use-cookie.ts +0 -135
  365. package/src/runtime/composables/use-fetch.ts +0 -438
  366. package/src/runtime/composables/use-head.ts +0 -234
  367. package/src/runtime/composables/use-inject.ts +0 -49
  368. package/src/runtime/composables/use-locale.ts +0 -109
  369. package/src/runtime/composables/use-navigate.ts +0 -58
  370. package/src/runtime/composables/use-page-data.ts +0 -93
  371. package/src/runtime/composables/use-route.ts +0 -71
  372. package/src/runtime/composables/use-runtime-config.ts +0 -123
  373. package/src/runtime/composables/use-seo-meta.ts +0 -80
  374. package/src/runtime/composables/use-session.ts +0 -186
  375. package/src/runtime/composables/use-state.ts +0 -92
  376. package/src/runtime/content/client.ts +0 -168
  377. package/src/runtime/entry-client-template.ts +0 -39
  378. package/src/runtime/entry-server-template.ts +0 -493
  379. package/src/runtime/isr-handler.ts +0 -184
  380. package/src/runtime/oauth/handler.ts +0 -407
  381. package/src/runtime/oauth/index.ts +0 -49
  382. package/src/runtime/oauth/providers.ts +0 -38
  383. package/src/types/api.ts +0 -40
  384. package/src/types/config.ts +0 -379
  385. package/src/types/content.ts +0 -66
  386. package/src/types/index.ts +0 -7
  387. package/src/types/middleware.ts +0 -63
  388. package/src/types/page.ts +0 -117
  389. package/src/types/plugin.ts +0 -34
  390. package/tsconfig.build.json +0 -10
  391. package/tsconfig.json +0 -19
  392. package/vitest.config.ts +0 -33
@@ -1,121 +0,0 @@
1
- /**
2
- * navigateTo() tests.
3
- *
4
- * Covers:
5
- * - Server path: sends a 302 redirect via the req/res store
6
- * - Client path: delegates to __cerRouter.push
7
- * - Fallback: sets window.location.href
8
- */
9
-
10
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
11
- import { navigateTo } from '../../runtime/composables/use-navigate.js'
12
-
13
- const g = globalThis as Record<string, unknown>
14
-
15
- function makeReqStore(res: Record<string, unknown>) {
16
- const { AsyncLocalStorage } = require('node:async_hooks')
17
- const store = new AsyncLocalStorage()
18
- store.enterWith({ req: {}, res })
19
- return store
20
- }
21
-
22
- // ─── Server path ──────────────────────────────────────────────────────────────
23
-
24
- describe('navigateTo() — server path (__CER_REQ_STORE__)', () => {
25
- let _orig: unknown
26
-
27
- beforeEach(() => {
28
- _orig = g['__CER_REQ_STORE__']
29
- delete g['__cerRouter']
30
- })
31
-
32
- afterEach(() => {
33
- g['__CER_REQ_STORE__'] = _orig
34
- })
35
-
36
- it('sets statusCode 302 and Location header on the response', () => {
37
- const res = {
38
- statusCode: 200,
39
- writableEnded: false,
40
- setHeader: vi.fn(),
41
- end: vi.fn(),
42
- }
43
- g['__CER_REQ_STORE__'] = makeReqStore(res)
44
-
45
- navigateTo('/dashboard')
46
-
47
- expect(res.statusCode).toBe(302)
48
- expect(res.setHeader).toHaveBeenCalledWith('Location', '/dashboard')
49
- expect(res.end).toHaveBeenCalled()
50
- })
51
-
52
- it('does not redirect when response is already ended', () => {
53
- const res = {
54
- statusCode: 200,
55
- writableEnded: true,
56
- setHeader: vi.fn(),
57
- end: vi.fn(),
58
- }
59
- g['__CER_REQ_STORE__'] = makeReqStore(res)
60
-
61
- navigateTo('/dashboard')
62
-
63
- expect(res.setHeader).not.toHaveBeenCalled()
64
- expect(res.end).not.toHaveBeenCalled()
65
- })
66
- })
67
-
68
- // ─── Client path ──────────────────────────────────────────────────────────────
69
-
70
- describe('navigateTo() — client path (__cerRouter)', () => {
71
- beforeEach(() => {
72
- delete g['__CER_REQ_STORE__']
73
- })
74
-
75
- afterEach(() => {
76
- delete g['__cerRouter']
77
- })
78
-
79
- it('calls router.push with the given path', async () => {
80
- const push = vi.fn(async () => {})
81
- g['__cerRouter'] = { push }
82
-
83
- await navigateTo('/home')
84
-
85
- expect(push).toHaveBeenCalledWith('/home')
86
- })
87
-
88
- it('returns the promise from router.push', () => {
89
- const push = vi.fn(async () => {})
90
- g['__cerRouter'] = { push }
91
-
92
- const result = navigateTo('/settings')
93
- expect(result).toBeInstanceOf(Promise)
94
- })
95
- })
96
-
97
- // ─── Fallback ─────────────────────────────────────────────────────────────────
98
-
99
- describe('navigateTo() — window.location fallback', () => {
100
- beforeEach(() => {
101
- delete g['__CER_REQ_STORE__']
102
- delete g['__cerRouter']
103
- })
104
-
105
- afterEach(() => {
106
- if ('window' in g) delete (g as { window?: unknown })['window']
107
- })
108
-
109
- it('sets window.location.href when no router is available', () => {
110
- let redirectedTo = ''
111
- ;(g as Record<string, unknown>)['window'] = {
112
- location: {
113
- get href() { return redirectedTo },
114
- set href(v: string) { redirectedTo = v },
115
- },
116
- }
117
-
118
- navigateTo('/login')
119
- expect(redirectedTo).toBe('/login')
120
- })
121
- })
@@ -1,298 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
2
- import { AsyncLocalStorage } from 'node:async_hooks'
3
-
4
- // --- Module-level mock for @jasonshimmy/custom-elements-runtime ---
5
- // usePageData imports getCurrentComponentContext from the runtime. We mock the
6
- // module so unit tests can control which context (if any) is "active".
7
- let _mockContext: Record<string, unknown> | null = null
8
-
9
- vi.mock('@jasonshimmy/custom-elements-runtime', () => ({
10
- getCurrentComponentContext: () => _mockContext,
11
- }))
12
-
13
- import { usePageData } from '../../runtime/composables/use-page-data.js'
14
-
15
- describe('usePageData', () => {
16
- beforeEach(() => {
17
- // Clean up global state between tests
18
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
19
- delete (globalThis as Record<string, unknown>)['__CER_DATA_STORE__']
20
- })
21
-
22
- afterEach(() => {
23
- delete (globalThis as Record<string, unknown>)['__CER_DATA_STORE__']
24
- })
25
-
26
- it('returns null when no SSR data is present', () => {
27
- expect(usePageData()).toBeNull()
28
- })
29
-
30
- it('returns the data when __CER_DATA__ is set on globalThis', () => {
31
- const data = { id: '1', name: 'Laptop', price: 999 }
32
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = data
33
- expect(usePageData()).toEqual(data)
34
- })
35
-
36
- it('does NOT clear __CER_DATA__ on read (cleared by app.ts after router.replace)', () => {
37
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { title: 'Hello' }
38
- usePageData()
39
- expect((globalThis as Record<string, unknown>)['__CER_DATA__']).toEqual({ title: 'Hello' })
40
- })
41
-
42
- it('returns the same data on subsequent calls (not consumed on first read)', () => {
43
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { title: 'Hello' }
44
- usePageData()
45
- expect(usePageData()).toEqual({ title: 'Hello' })
46
- })
47
-
48
- it('is generic and preserves the typed shape', () => {
49
- interface Post { slug: string; title: string }
50
- const post: Post = { slug: 'hello', title: 'Hello World' }
51
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = post
52
- const result = usePageData<Post>()
53
- expect(result?.slug).toBe('hello')
54
- expect(result?.title).toBe('Hello World')
55
- })
56
-
57
- it('returns null when __CER_DATA__ is explicitly null', () => {
58
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = null
59
- expect(usePageData()).toBeNull()
60
- })
61
- })
62
-
63
- describe('usePageData — AsyncLocalStorage (server-side)', () => {
64
- let store: AsyncLocalStorage<unknown>
65
-
66
- beforeEach(() => {
67
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
68
- store = new AsyncLocalStorage()
69
- ;(globalThis as Record<string, unknown>)['__CER_DATA_STORE__'] = store
70
- })
71
-
72
- afterEach(() => {
73
- delete (globalThis as Record<string, unknown>)['__CER_DATA_STORE__']
74
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
75
- })
76
-
77
- it('reads data from the ALS store when available', () => {
78
- const data = { title: 'SSR Post', body: 'Hello from ALS' }
79
- store.run(data, () => {
80
- expect(usePageData()).toEqual(data)
81
- })
82
- })
83
-
84
- it('returns null when ALS store is empty (null)', () => {
85
- store.run(null, () => {
86
- expect(usePageData()).toBeNull()
87
- })
88
- })
89
-
90
- it('prefers ALS store over globalThis.__CER_DATA__', () => {
91
- const alsData = { source: 'als' }
92
- const globalData = { source: 'global' }
93
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = globalData
94
- store.run(alsData, () => {
95
- expect(usePageData()).toEqual(alsData)
96
- })
97
- })
98
-
99
- it('does NOT delete __CER_DATA__ when returning ALS data', () => {
100
- const globalData = { source: 'global' }
101
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = globalData
102
- store.run({ source: 'als' }, () => {
103
- usePageData()
104
- })
105
- // global data should still be present — ALS path doesn't consume it
106
- expect((globalThis as Record<string, unknown>)['__CER_DATA__']).toEqual(globalData)
107
- })
108
-
109
- it('falls back to __CER_DATA__ when ALS store has no value outside run()', () => {
110
- // Outside any store.run() context, getStore() returns undefined
111
- const data = { fallback: true }
112
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = data
113
- // store is set but we're outside a run() context → getStore() === undefined
114
- expect(usePageData()).toEqual(data)
115
- })
116
-
117
- it('returns null when both ALS and __CER_DATA__ are absent', () => {
118
- store.run(null, () => {
119
- expect(usePageData()).toBeNull()
120
- })
121
- })
122
-
123
- it('is safe to call multiple times inside same ALS context', () => {
124
- const data = { count: 42 }
125
- store.run(data, () => {
126
- expect(usePageData()).toEqual(data)
127
- // ALS data is NOT consumed on read, so a second call still returns it
128
- expect(usePageData()).toEqual(data)
129
- })
130
- })
131
- })
132
-
133
- // ─── Component context caching ─────────────────────────────────────────────
134
- //
135
- // usePageData() caches the result on the component context (via Object.defineProperty)
136
- // so that re-renders of the same element instance return the same value even after
137
- // __CER_DATA__ is deleted by the post-hydration queueMicrotask cleanup.
138
- //
139
- // Background: renderFn passed to component() IS the render function — it runs on
140
- // every re-render, not just once as a setup phase. Without caching, calling
141
- // usePageData() on the second render after __CER_DATA__ is deleted returns null,
142
- // which flips `ssrData ? 'ssr' : 'client'` guards and re-triggers client fetches.
143
-
144
- describe('usePageData — component context caching', () => {
145
- const _PAGE_DATA_KEY = '_cerPageData'
146
-
147
- beforeEach(() => {
148
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
149
- delete (globalThis as Record<string, unknown>)['__CER_DATA_STORE__']
150
- _mockContext = null
151
- })
152
-
153
- afterEach(() => {
154
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
155
- _mockContext = null
156
- })
157
-
158
- it('returns null and does not cache when context is null (no render in progress)', () => {
159
- _mockContext = null
160
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { value: 42 }
161
- const result = usePageData()
162
- expect(result).toEqual({ value: 42 })
163
- // No context to cache on — nothing to assert, just no crash
164
- })
165
-
166
- it('caches the result on the component context using Object.defineProperty', () => {
167
- const ctx: Record<string, unknown> = {}
168
- _mockContext = ctx
169
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { value: 42 }
170
-
171
- usePageData()
172
-
173
- // Should be defined on ctx via Object.defineProperty (non-enumerable)
174
- expect(Object.prototype.hasOwnProperty.call(ctx, _PAGE_DATA_KEY)).toBe(true)
175
- expect(ctx[_PAGE_DATA_KEY]).toEqual({ value: 42 })
176
- })
177
-
178
- it('cached property is non-enumerable (does not appear in Object.keys)', () => {
179
- const ctx: Record<string, unknown> = {}
180
- _mockContext = ctx
181
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { value: 42 }
182
-
183
- usePageData()
184
-
185
- expect(Object.keys(ctx)).not.toContain(_PAGE_DATA_KEY)
186
- })
187
-
188
- it('cached property is non-writable (reactive proxy set-trap cannot overwrite it)', () => {
189
- const ctx: Record<string, unknown> = {}
190
- _mockContext = ctx
191
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { value: 42 }
192
-
193
- usePageData()
194
-
195
- // Attempting to overwrite a writable:false property silently fails in non-strict mode
196
- // and throws in strict mode. Verify the value doesn't change.
197
- try { ctx[_PAGE_DATA_KEY] = { value: 999 } } catch { /* strict mode */ }
198
- expect(ctx[_PAGE_DATA_KEY]).toEqual({ value: 42 })
199
- })
200
-
201
- it('returns cached value on second call even after __CER_DATA__ is deleted', () => {
202
- const ctx: Record<string, unknown> = {}
203
- _mockContext = ctx
204
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { value: 42 }
205
-
206
- // First call (simulates initial render while __CER_DATA__ is present)
207
- const first = usePageData()
208
- expect(first).toEqual({ value: 42 })
209
-
210
- // Simulate post-hydration cleanup: queueMicrotask(() => delete __CER_DATA__)
211
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
212
-
213
- // Second call (simulates re-render after cleanup) — must return cached value
214
- const second = usePageData()
215
- expect(second).toEqual({ value: 42 })
216
- })
217
-
218
- it('caches null result so repeated calls with no data do not re-read the deleted global', () => {
219
- const ctx: Record<string, unknown> = {}
220
- _mockContext = ctx
221
- // No __CER_DATA__ — returns null and caches null
222
-
223
- const first = usePageData()
224
- expect(first).toBeNull()
225
-
226
- // Set __CER_DATA__ AFTER first call — second call should return cached null
227
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { value: 99 }
228
- const second = usePageData()
229
- expect(second).toBeNull()
230
- })
231
-
232
- it('each component element instance has its own independent cache', () => {
233
- const ctxA: Record<string, unknown> = {}
234
- const ctxB: Record<string, unknown> = {}
235
-
236
- // First component: has SSR data
237
- _mockContext = ctxA
238
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { page: 'home' }
239
- const resultA = usePageData()
240
- expect(resultA).toEqual({ page: 'home' })
241
-
242
- // Simulate navigation: delete home data, set blog data
243
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
244
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { page: 'blog' }
245
-
246
- // Second component (different element, different context)
247
- _mockContext = ctxB
248
- const resultB = usePageData()
249
- expect(resultB).toEqual({ page: 'blog' })
250
-
251
- // First component re-rendered — still returns its cached value
252
- _mockContext = ctxA
253
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
254
- const resultA2 = usePageData()
255
- expect(resultA2).toEqual({ page: 'home' }) // cached, not stale blog data
256
- })
257
-
258
- it('ALS path takes precedence over context cache (server-side always uses ALS)', () => {
259
- const store = new AsyncLocalStorage<unknown>()
260
- ;(globalThis as Record<string, unknown>)['__CER_DATA_STORE__'] = store
261
-
262
- const ctx: Record<string, unknown> = {}
263
- // Pre-seed a stale client cache on the context
264
- Object.defineProperty(ctx, _PAGE_DATA_KEY, { value: { stale: true }, writable: false, configurable: true, enumerable: false })
265
- _mockContext = ctx
266
-
267
- const alsData = { fresh: true }
268
- store.run(alsData, () => {
269
- const result = usePageData()
270
- // ALS wins — context cache is not consulted for server-side renders
271
- expect(result).toEqual(alsData)
272
- })
273
-
274
- delete (globalThis as Record<string, unknown>)['__CER_DATA_STORE__']
275
- })
276
-
277
- it('context cache survives across multiple renderFn() invocations (re-render stability)', () => {
278
- const ctx: Record<string, unknown> = {}
279
- _mockContext = ctx
280
- ;(globalThis as Record<string, unknown>)['__CER_DATA__'] = { title: 'My Page' }
281
-
282
- // Simulate 5 re-renders (e.g. reactive state updates)
283
- for (let i = 0; i < 5; i++) {
284
- const result = usePageData<{ title: string }>()
285
- expect(result?.title).toBe('My Page')
286
- }
287
-
288
- // Delete __CER_DATA__ (post-hydration cleanup)
289
- delete (globalThis as Record<string, unknown>)['__CER_DATA__']
290
-
291
- // 5 more re-renders post-cleanup
292
- for (let i = 0; i < 5; i++) {
293
- const result = usePageData<{ title: string }>()
294
- expect(result?.title).toBe('My Page')
295
- }
296
- })
297
- })
298
-
@@ -1,156 +0,0 @@
1
- /**
2
- * useRoute() composable tests.
3
- *
4
- * Covers:
5
- * - Server path: reads from __CER_ROUTE_STORE__ AsyncLocalStorage
6
- * - Client path: reads from globalThis.__cerRouter
7
- * - Fallback: returns default route when neither is present
8
- */
9
-
10
- import { describe, it, expect, beforeEach, afterEach } from 'vitest'
11
- import { useRoute } from '../../runtime/composables/use-route.js'
12
-
13
- const g = globalThis as Record<string, unknown>
14
-
15
- function makeRouteStore(info: unknown) {
16
- const { AsyncLocalStorage } = require('node:async_hooks')
17
- const store = new AsyncLocalStorage()
18
- store.enterWith(info)
19
- return store
20
- }
21
-
22
- // ─── Server path ──────────────────────────────────────────────────────────────
23
-
24
- describe('useRoute() — server path (__CER_ROUTE_STORE__)', () => {
25
- let _orig: unknown
26
-
27
- beforeEach(() => {
28
- _orig = g['__CER_ROUTE_STORE__']
29
- })
30
-
31
- afterEach(() => {
32
- g['__CER_ROUTE_STORE__'] = _orig
33
- delete g['__cerRouter']
34
- })
35
-
36
- it('returns route info from the ALS store', () => {
37
- const info = { path: '/posts/42', params: { id: '42' }, query: {}, meta: { title: 'Post' } }
38
- g['__CER_ROUTE_STORE__'] = makeRouteStore(info)
39
-
40
- const route = useRoute()
41
- expect(route.path).toBe('/posts/42')
42
- expect(route.params).toEqual({ id: '42' })
43
- expect(route.meta).toEqual({ title: 'Post' })
44
- })
45
-
46
- it('falls through to client router when routeStore.getStore() returns null', () => {
47
- // Store is present but no active context (getStore returns null)
48
- const { AsyncLocalStorage } = require('node:async_hooks')
49
- const emptyStore = new AsyncLocalStorage()
50
- g['__CER_ROUTE_STORE__'] = emptyStore
51
- // Provide a client router so we get a real result instead of the fallback
52
- g['__cerRouter'] = {
53
- getCurrent: () => ({ path: '/client-path', query: {} }),
54
- matchRoute: () => ({ route: { meta: null }, params: {} }),
55
- }
56
-
57
- const route = useRoute()
58
- expect(route.path).toBe('/client-path')
59
- })
60
-
61
- it('returns query params from route info', () => {
62
- const info = { path: '/search', params: {}, query: { q: 'hello' }, meta: null }
63
- g['__CER_ROUTE_STORE__'] = makeRouteStore(info)
64
-
65
- const route = useRoute()
66
- expect(route.query).toEqual({ q: 'hello' })
67
- })
68
-
69
- it('returns null meta when not set', () => {
70
- g['__CER_ROUTE_STORE__'] = makeRouteStore({ path: '/', params: {}, query: {}, meta: null })
71
-
72
- const { meta } = useRoute()
73
- expect(meta).toBeNull()
74
- })
75
- })
76
-
77
- // ─── Client path ──────────────────────────────────────────────────────────────
78
-
79
- describe('useRoute() — client path (__cerRouter)', () => {
80
- beforeEach(() => {
81
- delete g['__CER_ROUTE_STORE__']
82
- })
83
-
84
- afterEach(() => {
85
- delete g['__cerRouter']
86
- })
87
-
88
- it('reads from the global router on the client', () => {
89
- g['__cerRouter'] = {
90
- getCurrent: () => ({ path: '/about', query: { ref: 'nav' } }),
91
- matchRoute: () => ({ route: { meta: { title: 'About' } }, params: {} }),
92
- }
93
-
94
- const route = useRoute()
95
- expect(route.path).toBe('/about')
96
- expect(route.query).toEqual({ ref: 'nav' })
97
- expect(route.meta).toEqual({ title: 'About' })
98
- })
99
-
100
- it('defaults query to {} when getCurrent() omits the query property', () => {
101
- g['__cerRouter'] = {
102
- getCurrent: () => ({ path: '/home' }),
103
- matchRoute: () => ({ route: { meta: null }, params: {} }),
104
- }
105
-
106
- const route = useRoute()
107
- expect(route.query).toEqual({})
108
- })
109
-
110
- it('extracts params from matched route', () => {
111
- g['__cerRouter'] = {
112
- getCurrent: () => ({ path: '/posts/7', query: {} }),
113
- matchRoute: () => ({ route: { meta: null }, params: { id: '7' } }),
114
- }
115
-
116
- const { params } = useRoute()
117
- expect(params).toEqual({ id: '7' })
118
- })
119
-
120
- it('returns null meta when route has none', () => {
121
- g['__cerRouter'] = {
122
- getCurrent: () => ({ path: '/', query: {} }),
123
- matchRoute: () => ({ route: { meta: null }, params: {} }),
124
- }
125
-
126
- expect(useRoute().meta).toBeNull()
127
- })
128
-
129
- it('handles unmatched route gracefully', () => {
130
- g['__cerRouter'] = {
131
- getCurrent: () => ({ path: '/unknown', query: {} }),
132
- matchRoute: () => null,
133
- }
134
-
135
- const route = useRoute()
136
- expect(route.params).toEqual({})
137
- expect(route.meta).toBeNull()
138
- })
139
- })
140
-
141
- // ─── Fallback ─────────────────────────────────────────────────────────────────
142
-
143
- describe('useRoute() — fallback (no store, no router)', () => {
144
- beforeEach(() => {
145
- delete g['__CER_ROUTE_STORE__']
146
- delete g['__cerRouter']
147
- })
148
-
149
- it('returns a default route object', () => {
150
- const route = useRoute()
151
- expect(route.path).toBe('/')
152
- expect(route.params).toEqual({})
153
- expect(route.query).toEqual({})
154
- expect(route.meta).toBeNull()
155
- })
156
- })