@jasonshimmy/vite-plugin-cer-app 0.23.1 → 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 (397) 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/commands/preview.d.ts.map +1 -1
  18. package/dist/cli/commands/preview.js +37 -4
  19. package/dist/cli/commands/preview.js.map +1 -1
  20. package/dist/cli/create/index.d.ts +11 -1
  21. package/dist/cli/create/index.d.ts.map +1 -1
  22. package/dist/cli/create/index.js +135 -65
  23. package/dist/cli/create/index.js.map +1 -1
  24. package/dist/cli/create/templates/spa/package.json.tpl +5 -3
  25. package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
  26. package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
  27. package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
  28. package/dist/cli/index.js +2 -0
  29. package/dist/cli/index.js.map +1 -1
  30. package/dist/index.d.ts +3 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/plugin/build-ssg.d.ts +22 -4
  33. package/dist/plugin/build-ssg.d.ts.map +1 -1
  34. package/dist/plugin/build-ssg.js +273 -13
  35. package/dist/plugin/build-ssg.js.map +1 -1
  36. package/dist/plugin/content/parser.d.ts.map +1 -1
  37. package/dist/plugin/content/parser.js +54 -10
  38. package/dist/plugin/content/parser.js.map +1 -1
  39. package/dist/plugin/dev-server.d.ts +6 -1
  40. package/dist/plugin/dev-server.d.ts.map +1 -1
  41. package/dist/plugin/dev-server.js.map +1 -1
  42. package/dist/plugin/dts-generator.d.ts.map +1 -1
  43. package/dist/plugin/dts-generator.js +50 -8
  44. package/dist/plugin/dts-generator.js.map +1 -1
  45. package/dist/plugin/generated-dir.d.ts +2 -0
  46. package/dist/plugin/generated-dir.d.ts.map +1 -1
  47. package/dist/plugin/generated-dir.js +17 -6
  48. package/dist/plugin/generated-dir.js.map +1 -1
  49. package/dist/plugin/html-post-process.d.ts +35 -0
  50. package/dist/plugin/html-post-process.d.ts.map +1 -0
  51. package/dist/plugin/html-post-process.js +112 -0
  52. package/dist/plugin/html-post-process.js.map +1 -0
  53. package/dist/plugin/index.d.ts +9 -0
  54. package/dist/plugin/index.d.ts.map +1 -1
  55. package/dist/plugin/index.js +89 -14
  56. package/dist/plugin/index.js.map +1 -1
  57. package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
  58. package/dist/plugin/transforms/auto-import.js +7 -0
  59. package/dist/plugin/transforms/auto-import.js.map +1 -1
  60. package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
  61. package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
  62. package/dist/plugin/transforms/prune-runtime-css.js +40 -0
  63. package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
  64. package/dist/runtime/app-template.d.ts +1 -4
  65. package/dist/runtime/app-template.d.ts.map +1 -1
  66. package/dist/runtime/app-template.js +211 -40
  67. package/dist/runtime/app-template.js.map +1 -1
  68. package/dist/runtime/composables/index.d.ts +4 -0
  69. package/dist/runtime/composables/index.d.ts.map +1 -1
  70. package/dist/runtime/composables/index.js +2 -0
  71. package/dist/runtime/composables/index.js.map +1 -1
  72. package/dist/runtime/composables/use-active-headings.d.ts +24 -0
  73. package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
  74. package/dist/runtime/composables/use-active-headings.js +112 -0
  75. package/dist/runtime/composables/use-active-headings.js.map +1 -0
  76. package/dist/runtime/composables/use-content-page.d.ts +45 -0
  77. package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
  78. package/dist/runtime/composables/use-content-page.js +179 -0
  79. package/dist/runtime/composables/use-content-page.js.map +1 -0
  80. package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
  81. package/dist/runtime/composables/use-content-search.js +1 -5
  82. package/dist/runtime/composables/use-content-search.js.map +1 -1
  83. package/dist/runtime/composables/use-fetch.d.ts +2 -1
  84. package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
  85. package/dist/runtime/composables/use-fetch.js +112 -43
  86. package/dist/runtime/composables/use-fetch.js.map +1 -1
  87. package/dist/runtime/composables/use-head.d.ts.map +1 -1
  88. package/dist/runtime/composables/use-head.js +30 -6
  89. package/dist/runtime/composables/use-head.js.map +1 -1
  90. package/dist/runtime/composables/use-route.d.ts.map +1 -1
  91. package/dist/runtime/composables/use-route.js +39 -11
  92. package/dist/runtime/composables/use-route.js.map +1 -1
  93. package/dist/runtime/content/client.js +2 -2
  94. package/dist/runtime/content/client.js.map +1 -1
  95. package/dist/runtime/entry-server-template.d.ts +16 -1
  96. package/dist/runtime/entry-server-template.d.ts.map +1 -1
  97. package/dist/runtime/entry-server-template.js +120 -13
  98. package/dist/runtime/entry-server-template.js.map +1 -1
  99. package/dist/types/config.d.ts +53 -4
  100. package/dist/types/config.d.ts.map +1 -1
  101. package/dist/types/config.js.map +1 -1
  102. package/dist/types/middleware.d.ts +2 -2
  103. package/dist/types/middleware.d.ts.map +1 -1
  104. package/package.json +22 -19
  105. package/.github/copilot-instructions.md +0 -169
  106. package/.github/workflows/publish.yml +0 -257
  107. package/.nvmrc +0 -1
  108. package/CHANGELOG.md +0 -232
  109. package/CLAUDE.md +0 -113
  110. package/commits.txt +0 -1
  111. package/cypress.config.ts +0 -16
  112. package/docs/authentication.md +0 -285
  113. package/docs/cli.md +0 -324
  114. package/docs/components.md +0 -237
  115. package/docs/composables.md +0 -907
  116. package/docs/configuration.md +0 -667
  117. package/docs/content.md +0 -570
  118. package/docs/data-loading.md +0 -336
  119. package/docs/getting-started.md +0 -237
  120. package/docs/head-management.md +0 -212
  121. package/docs/i18n.md +0 -159
  122. package/docs/layouts.md +0 -224
  123. package/docs/middleware.md +0 -234
  124. package/docs/plugins.md +0 -170
  125. package/docs/rendering-modes.md +0 -377
  126. package/docs/routing.md +0 -485
  127. package/docs/server-api.md +0 -253
  128. package/docs/testing.md +0 -455
  129. package/docs/use-fetch.md +0 -183
  130. package/e2e/cypress/e2e/api.cy.ts +0 -123
  131. package/e2e/cypress/e2e/async-component.cy.ts +0 -27
  132. package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
  133. package/e2e/cypress/e2e/content.cy.ts +0 -425
  134. package/e2e/cypress/e2e/cookie.cy.ts +0 -85
  135. package/e2e/cypress/e2e/data.cy.ts +0 -158
  136. package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
  137. package/e2e/cypress/e2e/fouc.cy.ts +0 -254
  138. package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
  139. package/e2e/cypress/e2e/head.cy.ts +0 -89
  140. package/e2e/cypress/e2e/i18n.cy.ts +0 -79
  141. package/e2e/cypress/e2e/interactive.cy.ts +0 -137
  142. package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
  143. package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
  144. package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
  145. package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
  146. package/e2e/cypress/e2e/middleware.cy.ts +0 -45
  147. package/e2e/cypress/e2e/navigate.cy.ts +0 -39
  148. package/e2e/cypress/e2e/observability.cy.ts +0 -77
  149. package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
  150. package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
  151. package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
  152. package/e2e/cypress/e2e/routes.cy.ts +0 -128
  153. package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
  154. package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
  155. package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
  156. package/e2e/cypress/e2e/session.cy.ts +0 -73
  157. package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
  158. package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
  159. package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
  160. package/e2e/cypress/e2e/use-state.cy.ts +0 -138
  161. package/e2e/cypress/support/commands.ts +0 -120
  162. package/e2e/cypress/support/e2e.ts +0 -10
  163. package/e2e/cypress/tsconfig.json +0 -14
  164. package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
  165. package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
  166. package/e2e/kitchen-sink/app/error.ts +0 -18
  167. package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
  168. package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
  169. package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
  170. package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
  171. package/e2e/kitchen-sink/app/loading.ts +0 -9
  172. package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
  173. package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
  174. package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
  175. package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
  176. package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
  177. package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
  178. package/e2e/kitchen-sink/app/pages/404.ts +0 -9
  179. package/e2e/kitchen-sink/app/pages/about.ts +0 -17
  180. package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
  181. package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
  182. package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
  183. package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
  184. package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
  185. package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
  186. package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
  187. package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
  188. package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
  189. package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
  190. package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
  191. package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
  192. package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
  193. package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
  194. package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
  195. package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
  196. package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
  197. package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
  198. package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
  199. package/e2e/kitchen-sink/app/pages/head.ts +0 -20
  200. package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
  201. package/e2e/kitchen-sink/app/pages/index.ts +0 -27
  202. package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
  203. package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
  204. package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
  205. package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
  206. package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
  207. package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
  208. package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
  209. package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
  210. package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
  211. package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
  212. package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
  213. package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
  214. package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
  215. package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
  216. package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
  217. package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
  218. package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
  219. package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
  220. package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
  221. package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
  222. package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
  223. package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
  224. package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
  225. package/e2e/kitchen-sink/cer-env.d.ts +0 -35
  226. package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
  227. package/e2e/kitchen-sink/cer.config.ts +0 -43
  228. package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
  229. package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
  230. package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
  231. package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
  232. package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
  233. package/e2e/kitchen-sink/content/blog/index.md +0 -8
  234. package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
  235. package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
  236. package/e2e/kitchen-sink/content/index.md +0 -16
  237. package/e2e/kitchen-sink/server/api/echo.ts +0 -12
  238. package/e2e/kitchen-sink/server/api/health.ts +0 -3
  239. package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
  240. package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
  241. package/e2e/kitchen-sink/server/api/session.ts +0 -23
  242. package/e2e/kitchen-sink/server/data/posts.ts +0 -21
  243. package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
  244. package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
  245. package/e2e/kitchen-sink/tsconfig.json +0 -3
  246. package/e2e/scripts/clean.mjs +0 -14
  247. package/eslint.config.ts +0 -22
  248. package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
  249. package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
  250. package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
  251. package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
  252. package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
  253. package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
  254. package/src/__tests__/cli/preview-hardening.test.ts +0 -265
  255. package/src/__tests__/cli/preview-isr.test.ts +0 -320
  256. package/src/__tests__/index.test.ts +0 -21
  257. package/src/__tests__/plugin/app-template.test.ts +0 -112
  258. package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
  259. package/src/__tests__/plugin/build-ssg.test.ts +0 -598
  260. package/src/__tests__/plugin/build-ssr.test.ts +0 -192
  261. package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
  262. package/src/__tests__/plugin/content/emitter.test.ts +0 -117
  263. package/src/__tests__/plugin/content/loader.test.ts +0 -154
  264. package/src/__tests__/plugin/content/parser.test.ts +0 -381
  265. package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
  266. package/src/__tests__/plugin/content/search.test.ts +0 -119
  267. package/src/__tests__/plugin/dev-server.test.ts +0 -813
  268. package/src/__tests__/plugin/dts-generator.test.ts +0 -394
  269. package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
  270. package/src/__tests__/plugin/generated-dir.test.ts +0 -144
  271. package/src/__tests__/plugin/path-utils.test.ts +0 -411
  272. package/src/__tests__/plugin/resolve-config.test.ts +0 -200
  273. package/src/__tests__/plugin/scanner.test.ts +0 -186
  274. package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
  275. package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
  276. package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
  277. package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
  278. package/src/__tests__/plugin/virtual/error.test.ts +0 -71
  279. package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
  280. package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
  281. package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
  282. package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
  283. package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
  284. package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
  285. package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
  286. package/src/__tests__/runtime/app-template.test.ts +0 -198
  287. package/src/__tests__/runtime/define-middleware.test.ts +0 -64
  288. package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
  289. package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
  290. package/src/__tests__/runtime/isr-handler.test.ts +0 -338
  291. package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
  292. package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
  293. package/src/__tests__/runtime/oauth-index.test.ts +0 -43
  294. package/src/__tests__/runtime/use-auth.test.ts +0 -169
  295. package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
  296. package/src/__tests__/runtime/use-content-search.test.ts +0 -163
  297. package/src/__tests__/runtime/use-content.test.ts +0 -226
  298. package/src/__tests__/runtime/use-cookie.test.ts +0 -277
  299. package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
  300. package/src/__tests__/runtime/use-fetch.test.ts +0 -377
  301. package/src/__tests__/runtime/use-head.test.ts +0 -266
  302. package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
  303. package/src/__tests__/runtime/use-inject.test.ts +0 -66
  304. package/src/__tests__/runtime/use-locale.test.ts +0 -152
  305. package/src/__tests__/runtime/use-navigate.test.ts +0 -121
  306. package/src/__tests__/runtime/use-page-data.test.ts +0 -298
  307. package/src/__tests__/runtime/use-route.test.ts +0 -156
  308. package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
  309. package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
  310. package/src/__tests__/runtime/use-session.test.ts +0 -320
  311. package/src/__tests__/runtime/use-state.test.ts +0 -340
  312. package/src/__tests__/types/config.test.ts +0 -18
  313. package/src/cli/adapters/cloudflare.ts +0 -335
  314. package/src/cli/adapters/netlify.ts +0 -326
  315. package/src/cli/adapters/vercel.ts +0 -311
  316. package/src/cli/commands/adapt.ts +0 -84
  317. package/src/cli/commands/build.ts +0 -165
  318. package/src/cli/commands/dev.ts +0 -125
  319. package/src/cli/commands/generate.ts +0 -91
  320. package/src/cli/commands/preview-isr.ts +0 -172
  321. package/src/cli/commands/preview.ts +0 -489
  322. package/src/cli/create/index.ts +0 -275
  323. package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
  324. package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
  325. package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
  326. package/src/cli/create/templates/shared/index.html.tpl +0 -12
  327. package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
  328. package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
  329. package/src/cli/create/templates/spa/package.json.tpl +0 -18
  330. package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
  331. package/src/cli/create/templates/ssg/package.json.tpl +0 -19
  332. package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
  333. package/src/cli/create/templates/ssr/package.json.tpl +0 -18
  334. package/src/cli/index.ts +0 -22
  335. package/src/index.ts +0 -20
  336. package/src/plugin/build-ssg.ts +0 -336
  337. package/src/plugin/build-ssr.ts +0 -134
  338. package/src/plugin/content/emitter.ts +0 -50
  339. package/src/plugin/content/index.ts +0 -233
  340. package/src/plugin/content/parser.ts +0 -259
  341. package/src/plugin/content/path-utils.ts +0 -55
  342. package/src/plugin/content/scanner.ts +0 -26
  343. package/src/plugin/content/search.ts +0 -28
  344. package/src/plugin/dev-server.ts +0 -377
  345. package/src/plugin/dts-generator.ts +0 -273
  346. package/src/plugin/generated-dir.ts +0 -121
  347. package/src/plugin/index.ts +0 -553
  348. package/src/plugin/path-utils.ts +0 -186
  349. package/src/plugin/scanner.ts +0 -65
  350. package/src/plugin/transforms/auto-import.ts +0 -206
  351. package/src/plugin/transforms/head-inject.ts +0 -161
  352. package/src/plugin/virtual/composables.ts +0 -28
  353. package/src/plugin/virtual/content-components.ts +0 -83
  354. package/src/plugin/virtual/error.ts +0 -34
  355. package/src/plugin/virtual/layouts.ts +0 -41
  356. package/src/plugin/virtual/loading.ts +0 -32
  357. package/src/plugin/virtual/middleware.ts +0 -45
  358. package/src/plugin/virtual/plugins.ts +0 -46
  359. package/src/plugin/virtual/routes.ts +0 -514
  360. package/src/plugin/virtual/server-api.ts +0 -85
  361. package/src/plugin/virtual/server-middleware.ts +0 -44
  362. package/src/runtime/app-template.ts +0 -380
  363. package/src/runtime/composables/define-middleware.ts +0 -17
  364. package/src/runtime/composables/define-server-middleware.ts +0 -18
  365. package/src/runtime/composables/index.ts +0 -27
  366. package/src/runtime/composables/use-auth.ts +0 -125
  367. package/src/runtime/composables/use-content-search.ts +0 -205
  368. package/src/runtime/composables/use-content.ts +0 -146
  369. package/src/runtime/composables/use-cookie.ts +0 -135
  370. package/src/runtime/composables/use-fetch.ts +0 -438
  371. package/src/runtime/composables/use-head.ts +0 -212
  372. package/src/runtime/composables/use-inject.ts +0 -49
  373. package/src/runtime/composables/use-locale.ts +0 -109
  374. package/src/runtime/composables/use-navigate.ts +0 -58
  375. package/src/runtime/composables/use-page-data.ts +0 -93
  376. package/src/runtime/composables/use-route.ts +0 -71
  377. package/src/runtime/composables/use-runtime-config.ts +0 -123
  378. package/src/runtime/composables/use-seo-meta.ts +0 -80
  379. package/src/runtime/composables/use-session.ts +0 -186
  380. package/src/runtime/composables/use-state.ts +0 -92
  381. package/src/runtime/content/client.ts +0 -168
  382. package/src/runtime/entry-client-template.ts +0 -39
  383. package/src/runtime/entry-server-template.ts +0 -493
  384. package/src/runtime/isr-handler.ts +0 -184
  385. package/src/runtime/oauth/handler.ts +0 -407
  386. package/src/runtime/oauth/index.ts +0 -49
  387. package/src/runtime/oauth/providers.ts +0 -38
  388. package/src/types/api.ts +0 -40
  389. package/src/types/config.ts +0 -371
  390. package/src/types/content.ts +0 -66
  391. package/src/types/index.ts +0 -7
  392. package/src/types/middleware.ts +0 -63
  393. package/src/types/page.ts +0 -117
  394. package/src/types/plugin.ts +0 -34
  395. package/tsconfig.build.json +0 -10
  396. package/tsconfig.json +0 -19
  397. package/vitest.config.ts +0 -33
@@ -1,88 +0,0 @@
1
- /**
2
- * Tests for the error boundary.
3
- *
4
- * SSR: when a page loader throws, the server renders `page-error` (from app/error.ts)
5
- * instead of crashing, and returns the correct HTTP status code.
6
- *
7
- * Client-side: when navigating to a page whose loader throws, currentError is set
8
- * and the error boundary component is displayed.
9
- */
10
-
11
- const mode = Cypress.env('mode') as 'spa' | 'ssr' | 'ssg'
12
-
13
- // Client-side loader error boundary — works in all modes via client-side navigation
14
- describe('Client-side error boundary — loader throws during navigation', () => {
15
- it('shows the error boundary after navigating to a page whose loader throws', () => {
16
- cy.visit('/')
17
- // Navigate via the router so the client-side loader runs (not a hard page load)
18
- cy.window().then((win) => {
19
- // @ts-expect-error cerRouter is a private global
20
- win.__cerRouter?.push('/loader-error-test')
21
- })
22
- cy.get('[data-cy=error-boundary]', { timeout: 5000 }).should('exist')
23
- })
24
-
25
- it('error message contains the loader error text after client-side navigation', () => {
26
- cy.visit('/')
27
- cy.window().then((win) => {
28
- // @ts-expect-error cerRouter is a private global
29
- win.__cerRouter?.push('/loader-error-test')
30
- })
31
- cy.get('[data-cy=error-message]', { timeout: 5000 }).should('contain', 'Loader intentionally failed')
32
- })
33
- })
34
-
35
- // SSR loader error boundary — only meaningful when a server render happens
36
- if (mode === 'ssr') {
37
- describe('SSR error boundary — loader throws', () => {
38
- it('returns the status code from the thrown error (503)', () => {
39
- cy.request({ url: '/loader-error-test', failOnStatusCode: false }).then((response) => {
40
- expect(response.status).to.eq(503)
41
- })
42
- })
43
-
44
- it('renders page-error element in the server response', () => {
45
- cy.request({ url: '/loader-error-test', failOnStatusCode: false }).then((response) => {
46
- expect(response.body).to.include('page-error')
47
- })
48
- })
49
-
50
- it('does not render the normal page heading when loader throws', () => {
51
- cy.request({ url: '/loader-error-test', failOnStatusCode: false }).then((response) => {
52
- expect(response.body).not.to.include('loader-error-heading')
53
- })
54
- })
55
-
56
- it('shows the error boundary UI in the browser', () => {
57
- cy.visit('/loader-error-test', { failOnStatusCode: false })
58
- cy.get('[data-cy=error-boundary]').should('exist')
59
- cy.get('[data-cy=error-heading]').should('contain', '503')
60
- cy.get('[data-cy=error-message]').should('contain', 'Loader intentionally failed')
61
- })
62
-
63
- it('exposes a retry button that calls resetError()', () => {
64
- cy.visit('/loader-error-test', { failOnStatusCode: false })
65
- cy.get('[data-cy=error-retry]').should('exist')
66
- })
67
- })
68
-
69
- describe('SSR error boundary — loader throws a Response object', () => {
70
- it('reads the numeric .status from the thrown Response (405)', () => {
71
- cy.request({ url: '/loader-response-error-test', failOnStatusCode: false }).then((response) => {
72
- expect(response.status).to.eq(405)
73
- })
74
- })
75
-
76
- it('renders page-error element in the server response for a thrown Response', () => {
77
- cy.request({ url: '/loader-response-error-test', failOnStatusCode: false }).then((response) => {
78
- expect(response.body).to.include('page-error')
79
- })
80
- })
81
-
82
- it('does not render the normal page heading when a Response is thrown', () => {
83
- cy.request({ url: '/loader-response-error-test', failOnStatusCode: false }).then((response) => {
84
- expect(response.body).not.to.include('loader-response-error-heading')
85
- })
86
- })
87
- })
88
- }
@@ -1,254 +0,0 @@
1
- /**
2
- * Declarative Shadow DOM (DSD) correctness tests.
3
- *
4
- * For SSR and SSG modes, validates that the server-rendered HTML:
5
- * 1. Contains <template shadowrootmode="open"> elements (value must be "open")
6
- * 2. Each shadow template has its own embedded <style> (JIT CSS not stripped to <head>)
7
- * 3. Shadow DOM styles are NOT hoisted to <head> (which would break encapsulation)
8
- * 4. Shadow templates contain the actual rendered component content
9
- * 5. More complex routes produce more shadow templates than simple routes
10
- * 6. The loading indicator is NOT present in the initial HTML
11
- * 7. The DSD polyfill is present and positioned after </cer-layout-view>
12
- * 8. After JS hydration, custom elements have live, accessible shadow roots
13
- * 9. Hydration does not duplicate or destroy the pre-rendered shadow content
14
- */
15
-
16
- const mode = Cypress.env('mode') as 'spa' | 'ssr' | 'ssg'
17
-
18
- // All pre-renderable routes
19
- const ALL_ROUTES = [
20
- '/',
21
- '/about',
22
- '/counter',
23
- '/head',
24
- '/blog',
25
- '/blog/first-post',
26
- '/blog/second-post',
27
- '/items/1',
28
- '/items/2',
29
- '/login',
30
- '/plugin-dsd-test',
31
- ]
32
-
33
- if (mode === 'spa') {
34
- describe('DSD (skipped in SPA mode)', () => {
35
- it('SPA mode has no server-side rendering — DSD tests are SSR/SSG only', () => {
36
- cy.log('DSD tests are skipped in SPA mode')
37
- })
38
- })
39
- } else {
40
- // ─── Structure: every route has well-formed DSD ───────────────────────────
41
-
42
- describe('DSD structure — all routes', () => {
43
- ALL_ROUTES.forEach((path) => {
44
- it(`${path} has valid DSD structure`, () => {
45
- cy.assertDSDStructure(path)
46
- })
47
- })
48
- })
49
-
50
- // ─── Content: shadow templates contain the actual rendered content ─────────
51
-
52
- describe('DSD content — shadow templates contain rendered output', () => {
53
- it('home (/): layout nav and page heading are inside shadow templates', () => {
54
- // layout-default renders site-nav; page-index renders the home heading
55
- cy.assertDSDContains('/', 'data-cy="site-nav"')
56
- cy.assertDSDContains('/', 'data-cy="home-heading"')
57
- cy.assertDSDContains('/', 'Kitchen Sink')
58
- })
59
-
60
- it('home (/): ks-badge content is inside a shadow template', () => {
61
- cy.assertDSDContains('/', 'data-cy="ks-badge"')
62
- })
63
-
64
- it('about (/about): page heading is inside a shadow template', () => {
65
- cy.assertDSDContains('/about', 'data-cy="about-heading"')
66
- cy.assertDSDContains('/about', 'About')
67
- })
68
-
69
- it('counter (/counter): heading and initial count 0 are inside shadow templates', () => {
70
- cy.assertDSDContains('/counter', 'data-cy="counter-heading"')
71
- cy.assertDSDContains('/counter', 'Counter')
72
- cy.assertDSDContains('/counter', 'data-cy="count"')
73
- })
74
-
75
- it('blog (/blog): blog heading is inside a shadow template', () => {
76
- cy.assertDSDContains('/blog', 'data-cy="blog-heading"')
77
- })
78
-
79
- it('blog detail (/blog/first-post): post title is inside a shadow template', () => {
80
- cy.assertDSDContains('/blog/first-post', 'First Post')
81
- })
82
- })
83
-
84
- // ─── Template depth: complex routes have more templates than simple ones ───
85
-
86
- describe('DSD template count — complexity reflects component tree', () => {
87
- it('home (/) has more shadow templates than about (/about)', () => {
88
- cy.request('/').then((homeResp) => {
89
- cy.request('/about').then((aboutResp) => {
90
- const homeTemplates = [
91
- ...homeResp.body.matchAll(/<template shadowrootmode="open"/g),
92
- ].length
93
- const aboutTemplates = [
94
- ...aboutResp.body.matchAll(/<template shadowrootmode="open"/g),
95
- ].length
96
-
97
- expect(
98
- homeTemplates,
99
- 'home page (default layout + page-index + ks-badge) should have more templates than about',
100
- ).to.be.greaterThan(aboutTemplates)
101
- })
102
- })
103
- })
104
-
105
- it('each route has at least 2 shadow templates (layout + page)', () => {
106
- ALL_ROUTES.forEach((path) => {
107
- cy.request(path).then((resp) => {
108
- const count = [...resp.body.matchAll(/<template shadowrootmode="open"/g)].length
109
- expect(count, `${path}: should have at least 2 shadow templates`).to.be.at.least(2)
110
- })
111
- })
112
- })
113
- })
114
-
115
- // ─── Plugin-registered components get DSD ────────────────────────────────
116
- //
117
- // Regression test for the "dual-instance registry" bug:
118
- // When @jasonshimmy/custom-elements-runtime was in ssr.noExternal, the bundler
119
- // inlined a separate copy of the runtime's component Map. Plugin files (treated
120
- // as external) resolved the CER runtime from node_modules at runtime — a
121
- // different Map instance. Components registered by plugins never appeared in
122
- // the SSR renderer's registry, so renderToStreamWithJITCSSDSD emitted bare
123
- // <custom-element> stubs with no DSD → FOUC when the browser upgraded them.
124
- // The fix: keep @jasonshimmy/custom-elements-runtime external so all code
125
- // (server bundle + plugin packages) shares one node_modules instance.
126
-
127
- describe('Plugin-registered components — DSD in SSR/SSG', () => {
128
- it('ks-plugin-card (registered via plugin, not auto-scanned) has a shadow template', () => {
129
- cy.request('/plugin-dsd-test').then((resp) => {
130
- const html: string = resp.body
131
- expect(html, 'ks-plugin-card must appear in rendered HTML').to.include('ks-plugin-card')
132
- // The component must have a shadow root template — not a bare stub
133
- const pluginCardIdx = html.indexOf('ks-plugin-card')
134
- const templateAfterCard = html.indexOf('<template shadowrootmode="open"', pluginCardIdx)
135
- const nextTagClose = html.indexOf('</ks-plugin-card>', pluginCardIdx)
136
- expect(templateAfterCard, 'ks-plugin-card must contain a <template shadowrootmode> (DSD)').to.be.greaterThan(-1)
137
- expect(templateAfterCard, 'shadow template must appear before </ks-plugin-card>').to.be.lessThan(nextTagClose)
138
- })
139
- })
140
-
141
- it('ks-plugin-card DSD contains the card CSS style', () => {
142
- cy.request('/plugin-dsd-test').then((resp) => {
143
- cy.assertDSDContains('/plugin-dsd-test', '.card')
144
- })
145
- })
146
-
147
- it('ks-plugin-card has a live shadow root after hydration', () => {
148
- // ks-plugin-card lives inside page-plugin-dsd-test's shadow root.
149
- // page-plugin-dsd-test is light DOM of layout-default (slotted), so
150
- // document.querySelector() can find it directly.
151
- cy.visit('/plugin-dsd-test')
152
- cy.get('[data-cy="plugin-dsd-test-page"]').should('exist')
153
- cy.window().then((win) => {
154
- const page = win.document.querySelector('page-plugin-dsd-test')
155
- expect(page, 'page-plugin-dsd-test must exist').to.not.be.null
156
- const card = page?.shadowRoot?.querySelector('ks-plugin-card')
157
- expect(card, 'ks-plugin-card must exist inside page-plugin-dsd-test shadow root').to.not.be.null
158
- expect((card as Element & { shadowRoot: ShadowRoot | null }).shadowRoot,
159
- 'ks-plugin-card must have a live shadow root after hydration').to.not.be.null
160
- })
161
- })
162
-
163
- it('ks-plugin-card slot content is accessible after hydration', () => {
164
- cy.visit('/plugin-dsd-test')
165
- cy.get('[data-cy="plugin-card-content"]').should('have.text', 'Card content from plugin component')
166
- })
167
- })
168
-
169
- // ─── DSD polyfill ─────────────────────────────────────────────────────────
170
-
171
- describe('DSD polyfill', () => {
172
- it('polyfill script is present in the home page HTML', () => {
173
- cy.request('/').then((resp) => {
174
- // The polyfill inlines a function that calls attachShadow on existing templates
175
- expect(resp.body, 'DSD polyfill should be present in server HTML').to.include(
176
- 'attachShadow',
177
- )
178
- })
179
- })
180
-
181
- it('polyfill is placed after </cer-layout-view> so it runs outside shadow light DOM', () => {
182
- cy.request('/').then((resp) => {
183
- const html: string = resp.body
184
- const clvEnd = html.lastIndexOf('</cer-layout-view>')
185
- const polyfillIdx = html.indexOf('attachShadow')
186
- expect(clvEnd, 'cer-layout-view closing tag must exist').to.be.greaterThan(-1)
187
- expect(polyfillIdx, 'DSD polyfill must exist').to.be.greaterThan(-1)
188
- expect(polyfillIdx, 'DSD polyfill must come AFTER </cer-layout-view>').to.be.greaterThan(
189
- clvEnd,
190
- )
191
- })
192
- })
193
- })
194
-
195
- // ─── Loading indicator ────────────────────────────────────────────────────
196
-
197
- describe('loading indicator absent from initial HTML', () => {
198
- it('home page: loading indicator is not in the server-rendered HTML', () => {
199
- cy.request('/').then((resp) => {
200
- expect(resp.body).not.to.include('page-loading')
201
- expect(resp.body).not.to.include('data-cy="loading-indicator"')
202
- })
203
- })
204
- })
205
-
206
- // ─── Hydration: shadow roots are live after JS boots ──────────────────────
207
-
208
- describe('DSD hydration — shadow roots live after JS', () => {
209
- it('layout-default has a live shadow root after hydration on home (/)', () => {
210
- cy.visit('/')
211
- cy.get('layout-default').should('exist')
212
- cy.assertShadowRootLive('layout-default')
213
- })
214
-
215
- it('page-index has a live shadow root after hydration on home (/)', () => {
216
- cy.visit('/')
217
- cy.get('page-index', { includeShadowDom: true }).should('exist')
218
- cy.assertShadowRootLive('page-index')
219
- })
220
-
221
- it('layout-minimal has a live shadow root after hydration on about (/about)', () => {
222
- cy.visit('/about')
223
- cy.get('layout-minimal').should('exist')
224
- cy.assertShadowRootLive('layout-minimal')
225
- })
226
-
227
- it('page-about has a live shadow root after hydration on about (/about)', () => {
228
- cy.visit('/about')
229
- cy.assertShadowRootLive('page-about')
230
- })
231
-
232
- it('page-counter has a live shadow root after hydration on counter (/counter)', () => {
233
- cy.visit('/counter')
234
- cy.assertShadowRootLive('page-counter')
235
- })
236
-
237
- it('shadow root content survives hydration — home heading still readable', () => {
238
- cy.visit('/')
239
- // Content set by DSD pre-render should still be accessible in the live shadow root
240
- cy.get('[data-cy="home-heading"]').should('have.text', 'Kitchen Sink')
241
- })
242
-
243
- it('shadow root content survives hydration — site-nav still rendered', () => {
244
- cy.visit('/')
245
- cy.get('[data-cy="site-nav"]').should('exist')
246
- cy.get('[data-cy="nav-home"]').should('exist')
247
- })
248
-
249
- it('shadow root content survives hydration — counter shows initial count 0', () => {
250
- cy.visit('/counter')
251
- cy.get('[data-cy="count"]').should('have.text', '0')
252
- })
253
- })
254
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * P2-1: _layout.ts group meta inheritance.
3
- *
4
- * Verifies that middleware and layout declared in a directory's _layout.ts
5
- * are inherited by all pages in that directory, with page-level declarations
6
- * taking precedence.
7
- */
8
-
9
- describe('Group meta from _layout.ts (P2-1)', () => {
10
- context('middleware inheritance', () => {
11
- it('applies group middleware from _layout.ts to pages in the directory', () => {
12
- // The group-meta-test/protected.ts page is in a directory with auth middleware
13
- // declared in _layout.ts — visiting without auth should trigger the middleware
14
- cy.visit('/group-meta-test/protected', { failOnStatusCode: false })
15
- // The auth middleware redirects or renders a guard indicator
16
- cy.get('[data-cy=group-auth-guard]', { timeout: 5000 }).should('exist')
17
- })
18
-
19
- it('page-level middleware overrides group middleware', () => {
20
- // The group-meta-test/custom-mw.ts overrides group middleware with its own
21
- cy.visit('/group-meta-test/custom-mw', { failOnStatusCode: false })
22
- cy.get('[data-cy=custom-mw-marker]', { timeout: 5000 }).should('exist')
23
- })
24
- })
25
-
26
- context('layout inheritance', () => {
27
- it('pages in a group directory use the layout declared in _layout.ts', () => {
28
- // Use the page that overrides the blocking group middleware so this
29
- // assertion isolates layout inheritance from the redirect behavior.
30
- cy.visit('/group-meta-test/custom-mw')
31
- cy.get('[data-cy=custom-mw-marker]', { timeout: 5000 }).should('exist')
32
- // The group layout still wraps the page.
33
- cy.get('[data-cy=group-layout]', { timeout: 5000 }).should('exist')
34
- })
35
- })
36
- })
@@ -1,89 +0,0 @@
1
- /**
2
- * useHead() tests — verifies document title and meta tags are set correctly.
3
- *
4
- * In SSR/SSG: tags should be in the initial HTML (server-side injection).
5
- * In all modes: tags should be set after client-side hydration.
6
- */
7
-
8
- const mode = Cypress.env('mode') as 'spa' | 'ssr' | 'ssg'
9
-
10
- describe('useHead() — document title', () => {
11
- it('sets title to "Home — Kitchen Sink" on home page', () => {
12
- cy.visit('/')
13
- cy.title().should('eq', 'Home — Kitchen Sink')
14
- })
15
-
16
- it('sets title to "About — Kitchen Sink" on about page', () => {
17
- cy.visit('/about')
18
- cy.title().should('eq', 'About — Kitchen Sink')
19
- })
20
-
21
- it('sets title to "Head Test — Kitchen Sink" on head page', () => {
22
- cy.visit('/head')
23
- cy.title().should('eq', 'Head Test — Kitchen Sink')
24
- })
25
-
26
- it('sets title to "Blog — Kitchen Sink" on blog list page', () => {
27
- cy.visit('/blog')
28
- cy.title().should('eq', 'Blog — Kitchen Sink')
29
- })
30
-
31
- it('updates title when navigating between pages', () => {
32
- cy.visit('/')
33
- cy.title().should('eq', 'Home — Kitchen Sink')
34
- cy.get('[data-cy=nav-about]').first().click({ force: true })
35
- cy.title().should('eq', 'About — Kitchen Sink')
36
- cy.get('[data-cy=about-back]').first().click({ force: true })
37
- cy.title().should('eq', 'Home — Kitchen Sink')
38
- })
39
- })
40
-
41
- describe('useHead() — meta tags', () => {
42
- it('sets meta description on home page', () => {
43
- cy.visit('/')
44
- cy.get('meta[name="description"]').should('have.attr', 'content', 'Kitchen sink test app.')
45
- })
46
-
47
- it('sets meta description on about page', () => {
48
- cy.visit('/about')
49
- cy.get('meta[name="description"]').should('have.attr', 'content', 'About the kitchen sink test app.')
50
- })
51
-
52
- it('sets meta description on head test page', () => {
53
- cy.visit('/head')
54
- cy.get('meta[name="description"]').should('have.attr', 'content', 'A test page for useHead().')
55
- })
56
-
57
- it('sets og:title meta on head test page', () => {
58
- cy.visit('/head')
59
- cy.get('meta[property="og:title"]').should('have.attr', 'content', 'Head Test')
60
- })
61
- })
62
-
63
- if (mode !== 'spa') {
64
- describe('useHead() — server-side injection (SSR/SSG)', () => {
65
- it('home page title is in the initial HTML', () => {
66
- cy.request('/').then((response) => {
67
- expect(response.body).to.include('<title>Home — Kitchen Sink</title>')
68
- })
69
- })
70
-
71
- it('about page title is in the initial HTML', () => {
72
- cy.request('/about').then((response) => {
73
- expect(response.body).to.include('<title>About — Kitchen Sink</title>')
74
- })
75
- })
76
-
77
- it('head test page title is in the initial HTML', () => {
78
- cy.request('/head').then((response) => {
79
- expect(response.body).to.include('<title>Head Test — Kitchen Sink</title>')
80
- })
81
- })
82
-
83
- it('meta description is in the initial HTML for home', () => {
84
- cy.request('/').then((response) => {
85
- expect(response.body).to.include('Kitchen sink test app.')
86
- })
87
- })
88
- })
89
- }
@@ -1,79 +0,0 @@
1
- /**
2
- * E2E tests for i18n routing and useLocale() composable.
3
- *
4
- * The kitchen-sink is configured with:
5
- * locales: ['en', 'fr'], defaultLocale: 'en', strategy: 'prefix_except_default'
6
- *
7
- * This means:
8
- * /i18n-test → renders in default locale (en)
9
- * /fr/i18n-test → renders in locale (fr)
10
- */
11
-
12
- describe('i18n routing — useLocale()', () => {
13
- context('default locale (unprefixed path)', () => {
14
- it('renders the i18n-test page at /i18n-test', () => {
15
- cy.visit('/i18n-test')
16
- cy.get('[data-cy=i18n-heading]').should('contain', 'i18n Test Page')
17
- })
18
-
19
- it('reports "en" as the current locale on /i18n-test', () => {
20
- cy.visit('/i18n-test')
21
- cy.get('[data-cy=current-locale]').should('have.text', 'en')
22
- })
23
-
24
- it('reports "en" as the defaultLocale', () => {
25
- cy.visit('/i18n-test')
26
- cy.get('[data-cy=default-locale]').should('have.text', 'en')
27
- })
28
-
29
- it('reports all configured locales', () => {
30
- cy.visit('/i18n-test')
31
- cy.get('[data-cy=locales]').should('have.text', 'en,fr')
32
- })
33
-
34
- it('switchLocalePath("fr") produces /fr/i18n-test', () => {
35
- cy.visit('/i18n-test')
36
- cy.get('[data-cy=switch-to-fr]').should('have.attr', 'href', '/fr/i18n-test')
37
- })
38
-
39
- it('switchLocalePath("en") on the default locale keeps the unprefixed path', () => {
40
- cy.visit('/i18n-test')
41
- cy.get('[data-cy=switch-to-en]').should('have.attr', 'href', '/i18n-test')
42
- })
43
- })
44
-
45
- context('non-default locale (fr-prefixed path)', () => {
46
- it('renders the i18n-test page at /fr/i18n-test', () => {
47
- cy.visit('/fr/i18n-test')
48
- cy.get('[data-cy=i18n-heading]').should('contain', 'i18n Test Page')
49
- })
50
-
51
- it('reports "fr" as the current locale on /fr/i18n-test', () => {
52
- cy.visit('/fr/i18n-test')
53
- cy.get('[data-cy=current-locale]').should('have.text', 'fr')
54
- })
55
-
56
- it('switchLocalePath("en") from /fr/i18n-test produces /i18n-test', () => {
57
- cy.visit('/fr/i18n-test')
58
- cy.get('[data-cy=switch-to-en]').should('have.attr', 'href', '/i18n-test')
59
- })
60
-
61
- it('switchLocalePath("fr") on the fr-locale keeps the fr prefix', () => {
62
- cy.visit('/fr/i18n-test')
63
- cy.get('[data-cy=switch-to-fr]').should('have.attr', 'href', '/fr/i18n-test')
64
- })
65
-
66
- it('clicking the switch-to-en link navigates to the default-locale path', () => {
67
- cy.visit('/fr/i18n-test')
68
- cy.get('[data-cy=switch-to-en]').click({ force: true })
69
- cy.url().should('include', '/i18n-test')
70
- cy.url().should('not.include', '/fr/')
71
- })
72
-
73
- it('clicking the switch-to-fr link from /i18n-test navigates to /fr/i18n-test', () => {
74
- cy.visit('/i18n-test')
75
- cy.get('[data-cy=switch-to-fr]').click({ force: true })
76
- cy.url().should('include', '/fr/i18n-test')
77
- })
78
- })
79
- })