@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.25.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.
- package/dist/cli/adapters/netlify.js +4 -2
- package/dist/cli/adapters/netlify.js.map +1 -1
- package/dist/cli/checks/lighthouse.d.ts +26 -0
- package/dist/cli/checks/lighthouse.d.ts.map +1 -0
- package/dist/cli/checks/lighthouse.js +121 -0
- package/dist/cli/checks/lighthouse.js.map +1 -0
- package/dist/cli/checks/links.d.ts +12 -0
- package/dist/cli/checks/links.d.ts.map +1 -0
- package/dist/cli/checks/links.js +89 -0
- package/dist/cli/checks/links.js.map +1 -0
- package/dist/cli/checks/performance.d.ts +17 -0
- package/dist/cli/checks/performance.d.ts.map +1 -0
- package/dist/cli/checks/performance.js +61 -0
- package/dist/cli/checks/performance.js.map +1 -0
- package/dist/cli/commands/check.d.ts +3 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +85 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/preview.d.ts.map +1 -1
- package/dist/cli/commands/preview.js +4 -2
- package/dist/cli/commands/preview.js.map +1 -1
- package/dist/cli/create/index.d.ts +11 -1
- package/dist/cli/create/index.d.ts.map +1 -1
- package/dist/cli/create/index.js +135 -65
- package/dist/cli/create/index.js.map +1 -1
- package/dist/cli/create/templates/spa/package.json.tpl +5 -3
- package/dist/cli/create/templates/ssg/cer.config.ts.tpl +2 -0
- package/dist/cli/create/templates/ssg/package.json.tpl +5 -3
- package/dist/cli/create/templates/ssr/package.json.tpl +5 -3
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin/build-ssg.d.ts +22 -6
- package/dist/plugin/build-ssg.d.ts.map +1 -1
- package/dist/plugin/build-ssg.js +226 -17
- package/dist/plugin/build-ssg.js.map +1 -1
- package/dist/plugin/content/index.d.ts +1 -1
- package/dist/plugin/content/index.d.ts.map +1 -1
- package/dist/plugin/content/index.js +8 -8
- package/dist/plugin/content/index.js.map +1 -1
- package/dist/plugin/content/parser.d.ts +3 -3
- package/dist/plugin/content/parser.d.ts.map +1 -1
- package/dist/plugin/content/parser.js +103 -24
- package/dist/plugin/content/parser.js.map +1 -1
- package/dist/plugin/dev-server.d.ts +4 -1
- package/dist/plugin/dev-server.d.ts.map +1 -1
- package/dist/plugin/dev-server.js.map +1 -1
- package/dist/plugin/dts-generator.d.ts.map +1 -1
- package/dist/plugin/dts-generator.js +50 -8
- package/dist/plugin/dts-generator.js.map +1 -1
- package/dist/plugin/generated-dir.d.ts +2 -0
- package/dist/plugin/generated-dir.d.ts.map +1 -1
- package/dist/plugin/generated-dir.js +17 -6
- package/dist/plugin/generated-dir.js.map +1 -1
- package/dist/plugin/html-post-process.d.ts +7 -0
- package/dist/plugin/html-post-process.d.ts.map +1 -1
- package/dist/plugin/html-post-process.js +26 -0
- package/dist/plugin/html-post-process.js.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +60 -13
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/transforms/auto-import.d.ts.map +1 -1
- package/dist/plugin/transforms/auto-import.js +7 -0
- package/dist/plugin/transforms/auto-import.js.map +1 -1
- package/dist/plugin/transforms/prune-runtime-css.d.ts +8 -0
- package/dist/plugin/transforms/prune-runtime-css.d.ts.map +1 -0
- package/dist/plugin/transforms/prune-runtime-css.js +40 -0
- package/dist/plugin/transforms/prune-runtime-css.js.map +1 -0
- package/dist/runtime/app-template.d.ts +1 -1
- package/dist/runtime/app-template.d.ts.map +1 -1
- package/dist/runtime/app-template.js +206 -36
- package/dist/runtime/app-template.js.map +1 -1
- package/dist/runtime/composables/index.d.ts +4 -0
- package/dist/runtime/composables/index.d.ts.map +1 -1
- package/dist/runtime/composables/index.js +2 -0
- package/dist/runtime/composables/index.js.map +1 -1
- package/dist/runtime/composables/use-active-headings.d.ts +24 -0
- package/dist/runtime/composables/use-active-headings.d.ts.map +1 -0
- package/dist/runtime/composables/use-active-headings.js +112 -0
- package/dist/runtime/composables/use-active-headings.js.map +1 -0
- package/dist/runtime/composables/use-content-page.d.ts +45 -0
- package/dist/runtime/composables/use-content-page.d.ts.map +1 -0
- package/dist/runtime/composables/use-content-page.js +181 -0
- package/dist/runtime/composables/use-content-page.js.map +1 -0
- package/dist/runtime/composables/use-content-search.d.ts.map +1 -1
- package/dist/runtime/composables/use-content-search.js +1 -5
- package/dist/runtime/composables/use-content-search.js.map +1 -1
- package/dist/runtime/composables/use-fetch.d.ts +2 -1
- package/dist/runtime/composables/use-fetch.d.ts.map +1 -1
- package/dist/runtime/composables/use-fetch.js +112 -43
- package/dist/runtime/composables/use-fetch.js.map +1 -1
- package/dist/runtime/composables/use-route.d.ts.map +1 -1
- package/dist/runtime/composables/use-route.js +39 -11
- package/dist/runtime/composables/use-route.js.map +1 -1
- package/dist/runtime/content/client.js +2 -2
- package/dist/runtime/content/client.js.map +1 -1
- package/dist/runtime/entry-server-template.d.ts +16 -1
- package/dist/runtime/entry-server-template.d.ts.map +1 -1
- package/dist/runtime/entry-server-template.js +120 -13
- package/dist/runtime/entry-server-template.js.map +1 -1
- package/dist/types/config.d.ts +45 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.map +1 -1
- package/dist/types/content.d.ts +18 -1
- package/dist/types/content.d.ts.map +1 -1
- package/dist/types/middleware.d.ts +2 -2
- package/dist/types/middleware.d.ts.map +1 -1
- package/package.json +22 -19
- package/.github/copilot-instructions.md +0 -169
- package/.github/workflows/publish.yml +0 -257
- package/.nvmrc +0 -1
- package/CHANGELOG.md +0 -236
- package/CLAUDE.md +0 -113
- package/commits.txt +0 -1
- package/cypress.config.ts +0 -16
- package/docs/authentication.md +0 -285
- package/docs/cli.md +0 -324
- package/docs/components.md +0 -237
- package/docs/composables.md +0 -907
- package/docs/configuration.md +0 -696
- package/docs/content.md +0 -570
- package/docs/data-loading.md +0 -336
- package/docs/getting-started.md +0 -237
- package/docs/head-management.md +0 -212
- package/docs/i18n.md +0 -159
- package/docs/layouts.md +0 -224
- package/docs/middleware.md +0 -234
- package/docs/plugins.md +0 -170
- package/docs/rendering-modes.md +0 -377
- package/docs/routing.md +0 -485
- package/docs/server-api.md +0 -253
- package/docs/testing.md +0 -455
- package/docs/use-fetch.md +0 -183
- package/e2e/cypress/e2e/api.cy.ts +0 -123
- package/e2e/cypress/e2e/async-component.cy.ts +0 -27
- package/e2e/cypress/e2e/component-splitting.cy.ts +0 -50
- package/e2e/cypress/e2e/content.cy.ts +0 -425
- package/e2e/cypress/e2e/cookie.cy.ts +0 -85
- package/e2e/cypress/e2e/data.cy.ts +0 -158
- package/e2e/cypress/e2e/error-boundary.cy.ts +0 -88
- package/e2e/cypress/e2e/fouc.cy.ts +0 -254
- package/e2e/cypress/e2e/group-meta.cy.ts +0 -36
- package/e2e/cypress/e2e/head.cy.ts +0 -89
- package/e2e/cypress/e2e/i18n.cy.ts +0 -79
- package/e2e/cypress/e2e/interactive.cy.ts +0 -137
- package/e2e/cypress/e2e/isr-nested-runtime.cy.ts +0 -102
- package/e2e/cypress/e2e/jit-css-custom-colors.cy.ts +0 -43
- package/e2e/cypress/e2e/middleware-chain.cy.ts +0 -89
- package/e2e/cypress/e2e/middleware-status.cy.ts +0 -30
- package/e2e/cypress/e2e/middleware.cy.ts +0 -45
- package/e2e/cypress/e2e/navigate.cy.ts +0 -39
- package/e2e/cypress/e2e/observability.cy.ts +0 -77
- package/e2e/cypress/e2e/per-route-error.cy.ts +0 -42
- package/e2e/cypress/e2e/per-route-render.cy.ts +0 -70
- package/e2e/cypress/e2e/preview-hardening.cy.ts +0 -88
- package/e2e/cypress/e2e/routes.cy.ts +0 -128
- package/e2e/cypress/e2e/seo-meta.cy.ts +0 -108
- package/e2e/cypress/e2e/server-middleware.cy.ts +0 -46
- package/e2e/cypress/e2e/session-rotation.cy.ts +0 -25
- package/e2e/cypress/e2e/session.cy.ts +0 -73
- package/e2e/cypress/e2e/ssr-render-error.cy.ts +0 -68
- package/e2e/cypress/e2e/synthetic-404.cy.ts +0 -45
- package/e2e/cypress/e2e/use-page-data.cy.ts +0 -122
- package/e2e/cypress/e2e/use-state.cy.ts +0 -138
- package/e2e/cypress/support/commands.ts +0 -120
- package/e2e/cypress/support/e2e.ts +0 -10
- package/e2e/cypress/tsconfig.json +0 -14
- package/e2e/kitchen-sink/app/components/ks-badge.ts +0 -8
- package/e2e/kitchen-sink/app/composables/useKsCounter.ts +0 -9
- package/e2e/kitchen-sink/app/error.ts +0 -18
- package/e2e/kitchen-sink/app/layouts/admin.ts +0 -13
- package/e2e/kitchen-sink/app/layouts/default.ts +0 -25
- package/e2e/kitchen-sink/app/layouts/group.ts +0 -9
- package/e2e/kitchen-sink/app/layouts/minimal.ts +0 -7
- package/e2e/kitchen-sink/app/loading.ts +0 -9
- package/e2e/kitchen-sink/app/middleware/auth.ts +0 -9
- package/e2e/kitchen-sink/app/middleware/custom-log.ts +0 -4
- package/e2e/kitchen-sink/app/middleware/group-auth.ts +0 -7
- package/e2e/kitchen-sink/app/middleware/logger.ts +0 -14
- package/e2e/kitchen-sink/app/pages/(auth)/login.ts +0 -13
- package/e2e/kitchen-sink/app/pages/(auth)/protected.ts +0 -16
- package/e2e/kitchen-sink/app/pages/404.ts +0 -9
- package/e2e/kitchen-sink/app/pages/about.ts +0 -17
- package/e2e/kitchen-sink/app/pages/admin/_layout.ts +0 -1
- package/e2e/kitchen-sink/app/pages/admin/dashboard.ts +0 -11
- package/e2e/kitchen-sink/app/pages/async-component-error-test.ts +0 -18
- package/e2e/kitchen-sink/app/pages/async-component-test.ts +0 -18
- package/e2e/kitchen-sink/app/pages/blog/[slug].ts +0 -59
- package/e2e/kitchen-sink/app/pages/blog/index.ts +0 -51
- package/e2e/kitchen-sink/app/pages/content-blog.ts +0 -37
- package/e2e/kitchen-sink/app/pages/content-doc.ts +0 -42
- package/e2e/kitchen-sink/app/pages/content-fallback.ts +0 -36
- package/e2e/kitchen-sink/app/pages/content-guides.ts +0 -35
- package/e2e/kitchen-sink/app/pages/content-index.ts +0 -39
- package/e2e/kitchen-sink/app/pages/content-search.ts +0 -36
- package/e2e/kitchen-sink/app/pages/cookie-test.ts +0 -22
- package/e2e/kitchen-sink/app/pages/counter.ts +0 -17
- package/e2e/kitchen-sink/app/pages/group-auth-blocked.ts +0 -9
- package/e2e/kitchen-sink/app/pages/group-meta-test/_layout.ts +0 -6
- package/e2e/kitchen-sink/app/pages/group-meta-test/custom-mw.ts +0 -14
- package/e2e/kitchen-sink/app/pages/group-meta-test/page.ts +0 -9
- package/e2e/kitchen-sink/app/pages/group-meta-test/protected.ts +0 -8
- package/e2e/kitchen-sink/app/pages/head.ts +0 -20
- package/e2e/kitchen-sink/app/pages/i18n-test.ts +0 -14
- package/e2e/kitchen-sink/app/pages/index.ts +0 -27
- package/e2e/kitchen-sink/app/pages/isr-test.ts +0 -17
- package/e2e/kitchen-sink/app/pages/items/[id].ts +0 -20
- package/e2e/kitchen-sink/app/pages/jit-css-custom-colors-test.ts +0 -14
- package/e2e/kitchen-sink/app/pages/loader-error-test.ts +0 -13
- package/e2e/kitchen-sink/app/pages/loader-props-test.ts +0 -19
- package/e2e/kitchen-sink/app/pages/loader-response-error-test.ts +0 -13
- package/e2e/kitchen-sink/app/pages/middleware-chain-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/middleware-status-test.ts +0 -9
- package/e2e/kitchen-sink/app/pages/navigate-test.ts +0 -16
- package/e2e/kitchen-sink/app/pages/observability-test.ts +0 -25
- package/e2e/kitchen-sink/app/pages/per-route-error-test.error.ts +0 -13
- package/e2e/kitchen-sink/app/pages/per-route-error-test.ts +0 -15
- package/e2e/kitchen-sink/app/pages/plugin-dsd-test.ts +0 -10
- package/e2e/kitchen-sink/app/pages/render-error-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/render-server-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/render-spa-test.ts +0 -12
- package/e2e/kitchen-sink/app/pages/route-info.ts +0 -14
- package/e2e/kitchen-sink/app/pages/seo-test.ts +0 -23
- package/e2e/kitchen-sink/app/pages/session-rotation-test.ts +0 -25
- package/e2e/kitchen-sink/app/pages/use-state-test.ts +0 -37
- package/e2e/kitchen-sink/app/plugins/01.setup.ts +0 -7
- package/e2e/kitchen-sink/app/plugins/02.ks-plugin-components.ts +0 -27
- package/e2e/kitchen-sink/cer-auto-imports.d.ts +0 -51
- package/e2e/kitchen-sink/cer-env.d.ts +0 -35
- package/e2e/kitchen-sink/cer-tsconfig.json +0 -30
- package/e2e/kitchen-sink/cer.config.ts +0 -43
- package/e2e/kitchen-sink/content/01.guides/01.index.md +0 -8
- package/e2e/kitchen-sink/content/01.guides/02.intro.md +0 -8
- package/e2e/kitchen-sink/content/01.guides/10.advanced.md +0 -8
- package/e2e/kitchen-sink/content/blog/2026-04-01-hello.md +0 -26
- package/e2e/kitchen-sink/content/blog/2026-04-02-draft.md +0 -10
- package/e2e/kitchen-sink/content/blog/index.md +0 -8
- package/e2e/kitchen-sink/content/blog/no-frontmatter.md +0 -7
- package/e2e/kitchen-sink/content/docs/getting-started.md +0 -48
- package/e2e/kitchen-sink/content/index.md +0 -16
- package/e2e/kitchen-sink/server/api/echo.ts +0 -12
- package/e2e/kitchen-sink/server/api/health.ts +0 -3
- package/e2e/kitchen-sink/server/api/posts/[slug].ts +0 -11
- package/e2e/kitchen-sink/server/api/posts/index.ts +0 -5
- package/e2e/kitchen-sink/server/api/session.ts +0 -23
- package/e2e/kitchen-sink/server/data/posts.ts +0 -21
- package/e2e/kitchen-sink/server/middleware/01-headers.ts +0 -6
- package/e2e/kitchen-sink/server/middleware/02-status-test.ts +0 -10
- package/e2e/kitchen-sink/tsconfig.json +0 -3
- package/e2e/scripts/clean.mjs +0 -14
- package/eslint.config.ts +0 -22
- package/src/__tests__/cli/adapters/cloudflare-worker.integration.test.ts +0 -132
- package/src/__tests__/cli/adapters/cloudflare.test.ts +0 -332
- package/src/__tests__/cli/adapters/netlify-bridge.integration.test.ts +0 -139
- package/src/__tests__/cli/adapters/netlify.test.ts +0 -286
- package/src/__tests__/cli/adapters/vercel-launcher.integration.test.ts +0 -129
- package/src/__tests__/cli/adapters/vercel.test.ts +0 -263
- package/src/__tests__/cli/preview-hardening.test.ts +0 -265
- package/src/__tests__/cli/preview-isr.test.ts +0 -320
- package/src/__tests__/index.test.ts +0 -21
- package/src/__tests__/plugin/app-template.test.ts +0 -166
- package/src/__tests__/plugin/build-ssg-render.test.ts +0 -155
- package/src/__tests__/plugin/build-ssg.test.ts +0 -598
- package/src/__tests__/plugin/build-ssr.test.ts +0 -192
- package/src/__tests__/plugin/cer-app-plugin.test.ts +0 -552
- package/src/__tests__/plugin/content/emitter.test.ts +0 -117
- package/src/__tests__/plugin/content/loader.test.ts +0 -154
- package/src/__tests__/plugin/content/parser.test.ts +0 -381
- package/src/__tests__/plugin/content/path-utils.test.ts +0 -69
- package/src/__tests__/plugin/content/search.test.ts +0 -119
- package/src/__tests__/plugin/dev-server.test.ts +0 -813
- package/src/__tests__/plugin/dts-generator.test.ts +0 -394
- package/src/__tests__/plugin/entry-server-template.test.ts +0 -385
- package/src/__tests__/plugin/generated-dir.test.ts +0 -144
- package/src/__tests__/plugin/html-post-process.test.ts +0 -146
- package/src/__tests__/plugin/path-utils.test.ts +0 -411
- package/src/__tests__/plugin/resolve-config.test.ts +0 -233
- package/src/__tests__/plugin/scanner.test.ts +0 -186
- package/src/__tests__/plugin/transforms/auto-import.test.ts +0 -510
- package/src/__tests__/plugin/transforms/head-inject.test.ts +0 -178
- package/src/__tests__/plugin/virtual/composables.test.ts +0 -57
- package/src/__tests__/plugin/virtual/content-components.test.ts +0 -66
- package/src/__tests__/plugin/virtual/error.test.ts +0 -71
- package/src/__tests__/plugin/virtual/layouts.test.ts +0 -70
- package/src/__tests__/plugin/virtual/loading.test.ts +0 -72
- package/src/__tests__/plugin/virtual/middleware.test.ts +0 -83
- package/src/__tests__/plugin/virtual/plugins.test.ts +0 -129
- package/src/__tests__/plugin/virtual/routes.test.ts +0 -884
- package/src/__tests__/plugin/virtual/server-api.test.ts +0 -164
- package/src/__tests__/plugin/virtual/server-middleware.test.ts +0 -102
- package/src/__tests__/runtime/app-template.test.ts +0 -208
- package/src/__tests__/runtime/define-middleware.test.ts +0 -64
- package/src/__tests__/runtime/define-server-middleware.test.ts +0 -54
- package/src/__tests__/runtime/entry-client-template.test.ts +0 -61
- package/src/__tests__/runtime/isr-handler.test.ts +0 -338
- package/src/__tests__/runtime/oauth/handler.test.ts +0 -358
- package/src/__tests__/runtime/oauth/providers.test.ts +0 -47
- package/src/__tests__/runtime/oauth-index.test.ts +0 -43
- package/src/__tests__/runtime/use-auth.test.ts +0 -169
- package/src/__tests__/runtime/use-content-search-composable.test.ts +0 -405
- package/src/__tests__/runtime/use-content-search.test.ts +0 -163
- package/src/__tests__/runtime/use-content.test.ts +0 -226
- package/src/__tests__/runtime/use-cookie.test.ts +0 -277
- package/src/__tests__/runtime/use-fetch-component.test.ts +0 -214
- package/src/__tests__/runtime/use-fetch.test.ts +0 -377
- package/src/__tests__/runtime/use-head.test.ts +0 -311
- package/src/__tests__/runtime/use-inject-client.test.ts +0 -67
- package/src/__tests__/runtime/use-inject.test.ts +0 -66
- package/src/__tests__/runtime/use-locale.test.ts +0 -152
- package/src/__tests__/runtime/use-navigate.test.ts +0 -121
- package/src/__tests__/runtime/use-page-data.test.ts +0 -298
- package/src/__tests__/runtime/use-route.test.ts +0 -156
- package/src/__tests__/runtime/use-runtime-config.test.ts +0 -182
- package/src/__tests__/runtime/use-seo-meta.test.ts +0 -109
- package/src/__tests__/runtime/use-session.test.ts +0 -320
- package/src/__tests__/runtime/use-state.test.ts +0 -340
- package/src/__tests__/types/config.test.ts +0 -18
- package/src/cli/adapters/cloudflare.ts +0 -335
- package/src/cli/adapters/netlify.ts +0 -326
- package/src/cli/adapters/vercel.ts +0 -311
- package/src/cli/commands/adapt.ts +0 -84
- package/src/cli/commands/build.ts +0 -165
- package/src/cli/commands/dev.ts +0 -125
- package/src/cli/commands/generate.ts +0 -91
- package/src/cli/commands/preview-isr.ts +0 -172
- package/src/cli/commands/preview.ts +0 -523
- package/src/cli/create/index.ts +0 -275
- package/src/cli/create/templates/shared/.gitignore.tpl +0 -25
- package/src/cli/create/templates/shared/app/layouts/default.ts.tpl +0 -15
- package/src/cli/create/templates/shared/app/pages/index.ts.tpl +0 -8
- package/src/cli/create/templates/shared/index.html.tpl +0 -12
- package/src/cli/create/templates/shared/tsconfig.json.tpl +0 -6
- package/src/cli/create/templates/spa/cer.config.ts.tpl +0 -6
- package/src/cli/create/templates/spa/package.json.tpl +0 -18
- package/src/cli/create/templates/ssg/cer.config.ts.tpl +0 -10
- package/src/cli/create/templates/ssg/package.json.tpl +0 -19
- package/src/cli/create/templates/ssr/cer.config.ts.tpl +0 -6
- package/src/cli/create/templates/ssr/package.json.tpl +0 -18
- package/src/cli/index.ts +0 -22
- package/src/index.ts +0 -20
- package/src/plugin/build-ssg.ts +0 -403
- package/src/plugin/build-ssr.ts +0 -134
- package/src/plugin/content/emitter.ts +0 -50
- package/src/plugin/content/index.ts +0 -233
- package/src/plugin/content/parser.ts +0 -259
- package/src/plugin/content/path-utils.ts +0 -55
- package/src/plugin/content/scanner.ts +0 -26
- package/src/plugin/content/search.ts +0 -28
- package/src/plugin/dev-server.ts +0 -379
- package/src/plugin/dts-generator.ts +0 -273
- package/src/plugin/generated-dir.ts +0 -121
- package/src/plugin/html-post-process.ts +0 -96
- package/src/plugin/index.ts +0 -584
- package/src/plugin/path-utils.ts +0 -186
- package/src/plugin/scanner.ts +0 -65
- package/src/plugin/transforms/auto-import.ts +0 -206
- package/src/plugin/transforms/head-inject.ts +0 -161
- package/src/plugin/virtual/composables.ts +0 -28
- package/src/plugin/virtual/content-components.ts +0 -83
- package/src/plugin/virtual/error.ts +0 -34
- package/src/plugin/virtual/layouts.ts +0 -41
- package/src/plugin/virtual/loading.ts +0 -32
- package/src/plugin/virtual/middleware.ts +0 -45
- package/src/plugin/virtual/plugins.ts +0 -46
- package/src/plugin/virtual/routes.ts +0 -514
- package/src/plugin/virtual/server-api.ts +0 -85
- package/src/plugin/virtual/server-middleware.ts +0 -44
- package/src/runtime/app-template.ts +0 -377
- package/src/runtime/composables/define-middleware.ts +0 -17
- package/src/runtime/composables/define-server-middleware.ts +0 -18
- package/src/runtime/composables/index.ts +0 -27
- package/src/runtime/composables/use-auth.ts +0 -125
- package/src/runtime/composables/use-content-search.ts +0 -205
- package/src/runtime/composables/use-content.ts +0 -146
- package/src/runtime/composables/use-cookie.ts +0 -135
- package/src/runtime/composables/use-fetch.ts +0 -438
- package/src/runtime/composables/use-head.ts +0 -234
- package/src/runtime/composables/use-inject.ts +0 -49
- package/src/runtime/composables/use-locale.ts +0 -109
- package/src/runtime/composables/use-navigate.ts +0 -58
- package/src/runtime/composables/use-page-data.ts +0 -93
- package/src/runtime/composables/use-route.ts +0 -71
- package/src/runtime/composables/use-runtime-config.ts +0 -123
- package/src/runtime/composables/use-seo-meta.ts +0 -80
- package/src/runtime/composables/use-session.ts +0 -186
- package/src/runtime/composables/use-state.ts +0 -92
- package/src/runtime/content/client.ts +0 -168
- package/src/runtime/entry-client-template.ts +0 -39
- package/src/runtime/entry-server-template.ts +0 -493
- package/src/runtime/isr-handler.ts +0 -184
- package/src/runtime/oauth/handler.ts +0 -407
- package/src/runtime/oauth/index.ts +0 -49
- package/src/runtime/oauth/providers.ts +0 -38
- package/src/types/api.ts +0 -40
- package/src/types/config.ts +0 -379
- package/src/types/content.ts +0 -66
- package/src/types/index.ts +0 -7
- package/src/types/middleware.ts +0 -63
- package/src/types/page.ts +0 -117
- package/src/types/plugin.ts +0 -34
- package/tsconfig.build.json +0 -10
- package/tsconfig.json +0 -19
- 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
|
-
})
|