@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,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
- })