@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,377 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generates the `.cer/app.ts` framework client entry point.
|
|
3
|
-
*
|
|
4
|
-
* Always written to `.cer/app.ts` on every dev/build so consumers
|
|
5
|
-
* automatically receive the latest bootstrap code on plugin update.
|
|
6
|
-
* This file is gitignored and should never be edited directly.
|
|
7
|
-
*/
|
|
8
|
-
export function generateAppEntryTemplate(): string {
|
|
9
|
-
return `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app — do not edit.
|
|
10
|
-
// Regenerated automatically on every dev server start and build.
|
|
11
|
-
|
|
12
|
-
import '@jasonshimmy/custom-elements-runtime/css'
|
|
13
|
-
import 'virtual:cer-jit-css'
|
|
14
|
-
// virtual:cer-jit-init must run before virtual:cer-layouts and virtual:cer-plugins
|
|
15
|
-
// so JIT CSS is enabled before those modules upgrade custom elements via
|
|
16
|
-
// customElements.define(). Static imports execute depth-first in module order,
|
|
17
|
-
// so placing this import here guarantees enableJITCSS() fires first.
|
|
18
|
-
import 'virtual:cer-jit-init'
|
|
19
|
-
import 'virtual:cer-content-components'
|
|
20
|
-
import routes from 'virtual:cer-routes'
|
|
21
|
-
import layouts from 'virtual:cer-layouts'
|
|
22
|
-
import plugins from 'virtual:cer-plugins'
|
|
23
|
-
import { hasLoading, loadingTag } from 'virtual:cer-loading'
|
|
24
|
-
import { hasError, errorTag } from 'virtual:cer-error'
|
|
25
|
-
import { runtimeConfig } from 'virtual:cer-app-config'
|
|
26
|
-
import {
|
|
27
|
-
component,
|
|
28
|
-
ref,
|
|
29
|
-
provide,
|
|
30
|
-
setDevMode,
|
|
31
|
-
useOnConnected,
|
|
32
|
-
useOnDisconnected,
|
|
33
|
-
registerBuiltinComponents,
|
|
34
|
-
} from '@jasonshimmy/custom-elements-runtime'
|
|
35
|
-
import { initRouter } from '@jasonshimmy/custom-elements-runtime/router'
|
|
36
|
-
import { initRuntimeConfig } from '@jasonshimmy/vite-plugin-cer-app/composables'
|
|
37
|
-
|
|
38
|
-
const _cerProcess = (globalThis).process
|
|
39
|
-
const _cerNodeEnv = _cerProcess?.env?.NODE_ENV ?? _cerProcess?.env?.MODE
|
|
40
|
-
const _cerRuntimeDev =
|
|
41
|
-
typeof _cerNodeEnv === 'string'
|
|
42
|
-
? _cerNodeEnv !== 'production'
|
|
43
|
-
: typeof import.meta.env?.DEV === 'boolean'
|
|
44
|
-
? import.meta.env.DEV
|
|
45
|
-
: typeof import.meta.env?.PROD === 'boolean'
|
|
46
|
-
? !import.meta.env.PROD
|
|
47
|
-
: typeof import.meta.env?.MODE === 'string'
|
|
48
|
-
? import.meta.env.MODE !== 'production'
|
|
49
|
-
: false
|
|
50
|
-
;(globalThis).__CE_RUNTIME_DEV__ = _cerRuntimeDev
|
|
51
|
-
|
|
52
|
-
registerBuiltinComponents()
|
|
53
|
-
setDevMode(_cerRuntimeDev)
|
|
54
|
-
initRuntimeConfig(runtimeConfig)
|
|
55
|
-
|
|
56
|
-
const router = initRouter({ routes })
|
|
57
|
-
|
|
58
|
-
// Expose the router globally so useRoute() and navigateTo() can access it
|
|
59
|
-
// from any composable without circular imports.
|
|
60
|
-
;(globalThis).__cerRouter = router
|
|
61
|
-
|
|
62
|
-
// ─── Page loader state ───────────────────────────────────────────────────────
|
|
63
|
-
|
|
64
|
-
// Holds the pre-loaded page tag and loader-derived attrs for the current route.
|
|
65
|
-
// Set by _loadPageForPath before every navigation so cer-layout-view can render
|
|
66
|
-
// the page element directly with the correct attributes (enabling useProps()).
|
|
67
|
-
let _currentPageTag = null
|
|
68
|
-
let _currentPageAttrs = {}
|
|
69
|
-
// The pathname this tag was loaded for — used to detect router-internal
|
|
70
|
-
// redirects (e.g. middleware returning '/login') so cer-layout-view falls
|
|
71
|
-
// back to <router-view> when the current route differs from what was pre-loaded.
|
|
72
|
-
let _currentPagePath = null
|
|
73
|
-
|
|
74
|
-
function _toLoaderAttrs(data) {
|
|
75
|
-
if (data === undefined || data === null || typeof data !== 'object') return {}
|
|
76
|
-
return Object.fromEntries(
|
|
77
|
-
Object.entries(data).filter(([, v]) => v !== null && v !== undefined && typeof v !== 'object' && typeof v !== 'function')
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Pre-loads the page module for \`path\`, calls its loader if present, and
|
|
82
|
-
// stores the results so cer-layout-view can pass them as element attributes.
|
|
83
|
-
async function _loadPageForPath(path, options = {}) {
|
|
84
|
-
try {
|
|
85
|
-
const url = new URL(path, 'http://x')
|
|
86
|
-
const query = Object.fromEntries(url.searchParams)
|
|
87
|
-
const { runLoader = true, initialData } = options ?? {}
|
|
88
|
-
const matched = router.matchRoute(url.pathname)
|
|
89
|
-
const route = matched?.route
|
|
90
|
-
if (!route?.load) {
|
|
91
|
-
_currentPageTag = null
|
|
92
|
-
_currentPageAttrs = {}
|
|
93
|
-
_currentPagePath = url.pathname
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
const mod = await route.load()
|
|
97
|
-
_currentPageTag = mod.default ?? null
|
|
98
|
-
_currentPagePath = url.pathname
|
|
99
|
-
const params = matched.params ?? {}
|
|
100
|
-
let loaderAttrs = { ...params }
|
|
101
|
-
let loaderData = initialData
|
|
102
|
-
if (typeof mod.loader === 'function' && runLoader) {
|
|
103
|
-
try {
|
|
104
|
-
const data = await mod.loader({ params, query })
|
|
105
|
-
if (data !== undefined && data !== null) {
|
|
106
|
-
loaderData = data
|
|
107
|
-
// Make loader data available via usePageData() for this navigation.
|
|
108
|
-
;(globalThis).__CER_DATA__ = data
|
|
109
|
-
}
|
|
110
|
-
} catch (err) {
|
|
111
|
-
// Loader errors are surfaced through currentError so the error boundary
|
|
112
|
-
// (app/error.ts) can display a meaningful message — consistent with how
|
|
113
|
-
// the server-side handler behaves when a loader throws.
|
|
114
|
-
currentError.value = err instanceof Error ? err.message : String(err)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
// For the very first hydration pass in SSR/SSG we already have the server's
|
|
118
|
-
// loader payload in globalThis.__CER_DATA__ / window.__CER_DATA__. Reuse it
|
|
119
|
-
// instead of re-running the loader on the client, then derive primitive attrs
|
|
120
|
-
// from that payload so useProps() stays consistent with usePageData().
|
|
121
|
-
loaderAttrs = { ...loaderAttrs, ..._toLoaderAttrs(loaderData) }
|
|
122
|
-
_currentPageAttrs = loaderAttrs
|
|
123
|
-
} catch {
|
|
124
|
-
_currentPageTag = null
|
|
125
|
-
_currentPageAttrs = {}
|
|
126
|
-
_currentPagePath = null
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// ─── Navigation state ────────────────────────────────────────────────────────
|
|
131
|
-
|
|
132
|
-
const isNavigating = ref(false)
|
|
133
|
-
const currentError = ref(null)
|
|
134
|
-
|
|
135
|
-
const resetError = () => {
|
|
136
|
-
currentError.value = null
|
|
137
|
-
void router.replace(router.getCurrent().path)
|
|
138
|
-
}
|
|
139
|
-
;(globalThis).resetError = resetError
|
|
140
|
-
|
|
141
|
-
const _push = router.push.bind(router)
|
|
142
|
-
const _replace = router.replace.bind(router)
|
|
143
|
-
|
|
144
|
-
router.push = async (path) => {
|
|
145
|
-
isNavigating.value = true
|
|
146
|
-
currentError.value = null
|
|
147
|
-
try {
|
|
148
|
-
// Clear stale loader data from the previous route before loading the new one.
|
|
149
|
-
// If the new route has no loader, __CER_DATA__ stays undefined so usePageData()
|
|
150
|
-
// correctly returns null instead of leaking the previous page's data.
|
|
151
|
-
delete (globalThis).__CER_DATA__
|
|
152
|
-
await _loadPageForPath(path)
|
|
153
|
-
await _push(path)
|
|
154
|
-
} catch (err) {
|
|
155
|
-
currentError.value = err instanceof Error ? err.message : String(err)
|
|
156
|
-
} finally {
|
|
157
|
-
isNavigating.value = false
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
router.replace = async (path) => {
|
|
162
|
-
isNavigating.value = true
|
|
163
|
-
currentError.value = null
|
|
164
|
-
try {
|
|
165
|
-
// Clear stale loader data from the previous route before loading the new one.
|
|
166
|
-
delete (globalThis).__CER_DATA__
|
|
167
|
-
await _loadPageForPath(path)
|
|
168
|
-
await _replace(path)
|
|
169
|
-
} catch (err) {
|
|
170
|
-
currentError.value = err instanceof Error ? err.message : String(err)
|
|
171
|
-
} finally {
|
|
172
|
-
isNavigating.value = false
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// ─── Plugins ─────────────────────────────────────────────────────────────────
|
|
177
|
-
|
|
178
|
-
// Collect plugin-provided values so cer-layout-view can forward them into
|
|
179
|
-
// the component context tree via the real provide() hook (which inject() walks).
|
|
180
|
-
// Declared BEFORE component('cer-layout-view') to avoid a temporal dead zone
|
|
181
|
-
// ReferenceError: customElements.define() upgrades existing DOM elements
|
|
182
|
-
// synchronously, calling the render function immediately.
|
|
183
|
-
const _pluginProvides = new Map()
|
|
184
|
-
// Expose plugin provides globally so page components can read them synchronously
|
|
185
|
-
// regardless of render order.
|
|
186
|
-
;(globalThis).__cerPluginProvides = _pluginProvides
|
|
187
|
-
|
|
188
|
-
// ─── <cer-layout-view> ───────────────────────────────────────────────────────
|
|
189
|
-
|
|
190
|
-
// True until the initial page module has loaded and _replace has been called.
|
|
191
|
-
// While true, cer-layout-view renders a <slot> so the SSR/SSG pre-rendered
|
|
192
|
-
// light-DOM content stays visible and no FOUC occurs during the hydration gap.
|
|
193
|
-
// Declared here (before component()) because customElements.define() upgrades
|
|
194
|
-
// existing DOM elements synchronously, so the render function reads this ref
|
|
195
|
-
// on the very first call — before _doHydrate has a chance to run.
|
|
196
|
-
const _cerHydrating = ref(true)
|
|
197
|
-
|
|
198
|
-
component('cer-layout-view', () => {
|
|
199
|
-
// Forward plugin-provided values into the component context so inject() in
|
|
200
|
-
// any descendant component can resolve them by walking up the DOM tree.
|
|
201
|
-
for (const [key, value] of _pluginProvides) {
|
|
202
|
-
provide(key, value)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const current = ref(router.getCurrent())
|
|
206
|
-
let unsub
|
|
207
|
-
let _sawInitialRouteState = false
|
|
208
|
-
|
|
209
|
-
useOnConnected(() => {
|
|
210
|
-
// store.subscribe() synchronously pushes the current route once on
|
|
211
|
-
// subscription. That initial callback is not a real navigation and must not
|
|
212
|
-
// tear down the SSR slot before _doHydrate has pre-loaded the page.
|
|
213
|
-
// Subsequent callbacks may be real navigations, but initRouter() also fires
|
|
214
|
-
// a queueMicrotask(() => navigate(...)) to run guards on the entry URL.
|
|
215
|
-
// That startup microtask resolves during the await route.load() gap —
|
|
216
|
-
// before _currentPageTag is set — so we must not drop the slot until the
|
|
217
|
-
// page module has actually been loaded (_currentPageTag !== null).
|
|
218
|
-
// The explicit _cerHydrating.value = false in _doHydrate() fires after
|
|
219
|
-
// _loadPageForPath completes and is the authoritative hydration trigger.
|
|
220
|
-
unsub = router.subscribe((s) => {
|
|
221
|
-
const _isInitialSubscribePush = !_sawInitialRouteState
|
|
222
|
-
_sawInitialRouteState = true
|
|
223
|
-
if (_isInitialSubscribePush) {
|
|
224
|
-
current.value = s
|
|
225
|
-
return
|
|
226
|
-
}
|
|
227
|
-
if (_cerHydrating.value && _currentPageTag !== null) _cerHydrating.value = false
|
|
228
|
-
current.value = s
|
|
229
|
-
})
|
|
230
|
-
})
|
|
231
|
-
useOnDisconnected(() => { unsub?.(); unsub = undefined })
|
|
232
|
-
|
|
233
|
-
// While the initial page module is being loaded, keep the SSR/SSG
|
|
234
|
-
// pre-rendered light-DOM content visible by forwarding it through a <slot>.
|
|
235
|
-
// This prevents the intermediate blank state that occurs when the shadow DOM
|
|
236
|
-
// renders layout-default with an empty <router-view> before the page chunk
|
|
237
|
-
// has arrived. In SPA mode (no pre-rendered content) the slot is empty, which
|
|
238
|
-
// is no worse than the current router-view behaviour.
|
|
239
|
-
if (_cerHydrating.value) {
|
|
240
|
-
return { tag: 'slot', props: {}, children: [] }
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const matched = router.matchRoute(current.value.path)
|
|
244
|
-
const routeMeta = matched?.route?.meta
|
|
245
|
-
|
|
246
|
-
if (currentError.value !== null) {
|
|
247
|
-
const routeErrorTag = routeMeta?.errorTag ?? null
|
|
248
|
-
const effectiveErrorTag = routeErrorTag ?? (hasError ? errorTag : null)
|
|
249
|
-
if (effectiveErrorTag) {
|
|
250
|
-
return { tag: effectiveErrorTag, props: { attrs: { error: String(currentError.value) } }, children: [] }
|
|
251
|
-
}
|
|
252
|
-
return { tag: 'div', props: { attrs: { style: 'padding:2rem;font-family:monospace' } }, children: String(currentError.value) }
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
if (isNavigating.value && hasLoading && loadingTag) {
|
|
256
|
-
return { tag: loadingTag, props: {}, children: [] }
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Render the page component directly when a pre-loaded tag is available AND
|
|
260
|
-
// the loaded path matches the current route. The path guard detects
|
|
261
|
-
// router-internal redirects (e.g. middleware returning '/login'): when the
|
|
262
|
-
// router redirects to a different path, _currentPagePath won't match
|
|
263
|
-
// current.value.path and we fall back to <router-view> so the correct page
|
|
264
|
-
// is rendered without stale pre-loaded state.
|
|
265
|
-
const _useDirectRender = _currentPageTag && _currentPagePath === current.value.path
|
|
266
|
-
const pageVnode = _useDirectRender
|
|
267
|
-
? { tag: _currentPageTag, props: { attrs: _currentPageAttrs }, children: [] }
|
|
268
|
-
: { tag: 'router-view', props: {}, children: [] }
|
|
269
|
-
|
|
270
|
-
// Support nested layout chains: meta.layoutChain = ['default', 'admin']
|
|
271
|
-
// renders <layout-default><layout-admin><page/></layout-admin></layout-default>
|
|
272
|
-
const chain = routeMeta?.layoutChain
|
|
273
|
-
? routeMeta.layoutChain
|
|
274
|
-
: [routeMeta?.layout ?? 'default']
|
|
275
|
-
|
|
276
|
-
// Build nested vnodes from innermost to outermost.
|
|
277
|
-
let vnode = pageVnode
|
|
278
|
-
for (let i = chain.length - 1; i >= 0; i--) {
|
|
279
|
-
const tag = layouts[chain[i]]
|
|
280
|
-
if (tag) vnode = { tag, props: {}, children: [vnode] }
|
|
281
|
-
}
|
|
282
|
-
return vnode
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
for (const plugin of plugins) {
|
|
286
|
-
if (plugin && typeof plugin.setup === 'function') {
|
|
287
|
-
await plugin.setup({
|
|
288
|
-
router,
|
|
289
|
-
provide: (key, value) => { _pluginProvides.set(key, value) },
|
|
290
|
-
config: {},
|
|
291
|
-
})
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// ─── Pre-load initial route + hydration strategy ─────────────────────────────
|
|
296
|
-
// Download the current page's route chunk AFTER plugins run so that
|
|
297
|
-
// cer-layout-view's first render (which calls provide()) completes before
|
|
298
|
-
// page components are defined and their renders are scheduled. This ensures
|
|
299
|
-
// inject() in child components can find values stored by provide().
|
|
300
|
-
//
|
|
301
|
-
// meta.hydrate controls WHEN the initial page activates:
|
|
302
|
-
// 'load' — immediately (default)
|
|
303
|
-
// 'idle' — deferred until requestIdleCallback (browser idle)
|
|
304
|
-
// 'visible' — deferred until cer-layout-view enters the viewport
|
|
305
|
-
// 'none' — never: SSR HTML stays as-is, no JS activation
|
|
306
|
-
|
|
307
|
-
if (typeof window !== 'undefined') {
|
|
308
|
-
const _initMatch = router.matchRoute(window.location.pathname)
|
|
309
|
-
const _hydrateStrategy = _initMatch?.route?.meta?.hydrate ?? 'load'
|
|
310
|
-
|
|
311
|
-
if (_hydrateStrategy === 'none') {
|
|
312
|
-
// Static HTML only — leave SSR output untouched, clean up data immediately.
|
|
313
|
-
delete (globalThis).__CER_DATA__
|
|
314
|
-
} else {
|
|
315
|
-
const _doHydrate = async () => {
|
|
316
|
-
const _initPath = window.location.pathname + window.location.search + window.location.hash
|
|
317
|
-
const _hasInitialLoaderData = Object.prototype.hasOwnProperty.call(globalThis, '__CER_DATA__')
|
|
318
|
-
// Pre-load the page module and run the loader so cer-layout-view renders
|
|
319
|
-
// the page tag directly with loader attrs (enables useProps() on hydration).
|
|
320
|
-
await _loadPageForPath(
|
|
321
|
-
_initPath,
|
|
322
|
-
_hasInitialLoaderData
|
|
323
|
-
? { runLoader: false, initialData: (globalThis).__CER_DATA__ }
|
|
324
|
-
: undefined,
|
|
325
|
-
)
|
|
326
|
-
// Only activate the initial route if the URL hasn't changed while we were
|
|
327
|
-
// loading the module asynchronously (e.g. a test or plugin navigated away
|
|
328
|
-
// before _doHydrate finished). Calling _replace with a stale path would
|
|
329
|
-
// override any navigation that happened during the async gap.
|
|
330
|
-
const _currentPath = window.location.pathname + window.location.search + window.location.hash
|
|
331
|
-
// Drop the hydration slot cover unconditionally: the page module is loaded
|
|
332
|
-
// and cer-layout-view must switch from the <slot> to live rendering whether
|
|
333
|
-
// or not a redirect changed the path during loading.
|
|
334
|
-
_cerHydrating.value = false
|
|
335
|
-
if (_currentPath === _initPath) {
|
|
336
|
-
// Use the original (unwrapped) replace so isNavigating stays false during
|
|
337
|
-
// the initial paint — the loading component must not flash over pre-rendered content.
|
|
338
|
-
await _replace(_initPath)
|
|
339
|
-
}
|
|
340
|
-
// The client entry marks the already-rendered entry URL so generated
|
|
341
|
-
// route middleware can skip the browser router's startup replay once.
|
|
342
|
-
// Clear any leftover flag after the first hydrated route commits so later
|
|
343
|
-
// navigations always run middleware normally.
|
|
344
|
-
queueMicrotask(() => { delete (globalThis).__CER_HYDRATION_ENTRY__ })
|
|
345
|
-
// Keep the initial route's SSR data available after hydration.
|
|
346
|
-
// Browser engines do not all upgrade and re-render custom elements with
|
|
347
|
-
// identical timing, so deleting __CER_DATA__ here can cause a later
|
|
348
|
-
// hydration render to fall back to the client-only path. The next real
|
|
349
|
-
// router.push/router.replace clears __CER_DATA__ before loading the new
|
|
350
|
-
// route, so stale page data still does not leak across navigations.
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
if (_hydrateStrategy === 'idle') {
|
|
354
|
-
// Defer until the browser has finished higher-priority work.
|
|
355
|
-
if (typeof requestIdleCallback !== 'undefined') {
|
|
356
|
-
requestIdleCallback(() => { void _doHydrate() })
|
|
357
|
-
} else {
|
|
358
|
-
// Safari / older environments fallback.
|
|
359
|
-
setTimeout(() => { void _doHydrate() }, 1)
|
|
360
|
-
}
|
|
361
|
-
} else if (_hydrateStrategy === 'visible') {
|
|
362
|
-
// Defer until cer-layout-view (or body as fallback) enters the viewport.
|
|
363
|
-
const _el = document.querySelector('cer-layout-view') ?? document.body
|
|
364
|
-
const _io = new IntersectionObserver(([entry]) => {
|
|
365
|
-
if (entry.isIntersecting) { _io.disconnect(); void _doHydrate() }
|
|
366
|
-
})
|
|
367
|
-
_io.observe(_el)
|
|
368
|
-
} else {
|
|
369
|
-
// 'load' — hydrate immediately (default behaviour).
|
|
370
|
-
await _doHydrate()
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
export { router }
|
|
376
|
-
`
|
|
377
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { MiddlewareFn } from '../../types/middleware.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Identity helper that gives TypeScript the correct `MiddlewareFn` type
|
|
5
|
-
* without any runtime cost.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* // app/middleware/auth.ts
|
|
9
|
-
* export default defineMiddleware(async (to, from) => {
|
|
10
|
-
* const isLoggedIn = checkSession()
|
|
11
|
-
* if (!isLoggedIn) return '/login' // redirect
|
|
12
|
-
* return true // allow
|
|
13
|
-
* })
|
|
14
|
-
*/
|
|
15
|
-
export function defineMiddleware(fn: MiddlewareFn): MiddlewareFn {
|
|
16
|
-
return fn
|
|
17
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ServerMiddleware } from '../../types/middleware.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Identity helper that gives `ServerMiddleware` functions full TypeScript
|
|
5
|
-
* types without any runtime cost. Usage:
|
|
6
|
-
*
|
|
7
|
-
* ```ts
|
|
8
|
-
* // server/middleware/auth.ts
|
|
9
|
-
* export default defineServerMiddleware(async (req, res, next) => {
|
|
10
|
-
* const session = await useSession().get()
|
|
11
|
-
* if (!session) { res.statusCode = 401; res.end('Unauthorized'); return }
|
|
12
|
-
* next()
|
|
13
|
-
* })
|
|
14
|
-
* ```
|
|
15
|
-
*/
|
|
16
|
-
export function defineServerMiddleware(fn: ServerMiddleware): ServerMiddleware {
|
|
17
|
-
return fn
|
|
18
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export { useHead, beginHeadCollection, endHeadCollection, serializeHeadTags } from './use-head.js'
|
|
2
|
-
export type { HeadInput } from './use-head.js'
|
|
3
|
-
export { usePageData } from './use-page-data.js'
|
|
4
|
-
export { useInject } from './use-inject.js'
|
|
5
|
-
export { useRuntimeConfig, initRuntimeConfig, resolvePrivateConfig } from './use-runtime-config.js'
|
|
6
|
-
export type { RuntimeConfigResult, RuntimeConfigPublic, RuntimeConfigPrivate } from './use-runtime-config.js'
|
|
7
|
-
export { defineMiddleware } from './define-middleware.js'
|
|
8
|
-
export { defineServerMiddleware } from './define-server-middleware.js'
|
|
9
|
-
export { useSeoMeta } from './use-seo-meta.js'
|
|
10
|
-
export type { SeoMetaInput } from './use-seo-meta.js'
|
|
11
|
-
export { useCookie } from './use-cookie.js'
|
|
12
|
-
export type { CookieOptions, CookieRef } from './use-cookie.js'
|
|
13
|
-
export { useSession } from './use-session.js'
|
|
14
|
-
export type { SessionOptions, SessionComposable } from './use-session.js'
|
|
15
|
-
export { useAuth } from './use-auth.js'
|
|
16
|
-
export type { AuthUser, AuthComposable } from './use-auth.js'
|
|
17
|
-
export { useFetch } from './use-fetch.js'
|
|
18
|
-
export type { UseFetchOptions, UseFetchReturn, UseFetchResult, UseFetchReactiveReturn } from './use-fetch.js'
|
|
19
|
-
export { useRoute } from './use-route.js'
|
|
20
|
-
export type { RouteInfo } from './use-route.js'
|
|
21
|
-
export { navigateTo } from './use-navigate.js'
|
|
22
|
-
export { useState } from './use-state.js'
|
|
23
|
-
export { useLocale } from './use-locale.js'
|
|
24
|
-
export type { LocaleComposable } from './use-locale.js'
|
|
25
|
-
export { queryContent, QueryBuilder } from './use-content.js'
|
|
26
|
-
export { useContentSearch } from './use-content-search.js'
|
|
27
|
-
export type { UseContentSearchReturn } from './use-content-search.js'
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { useSession } from './use-session.js'
|
|
2
|
-
|
|
3
|
-
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Normalised user profile stored in the auth session after a successful OAuth login.
|
|
7
|
-
* The `provider`, `id`, and at least one of `name`/`email` fields are populated by the built-in
|
|
8
|
-
* provider normalisers. Additional fields from `mapUser()` are merged in.
|
|
9
|
-
*/
|
|
10
|
-
export interface AuthUser {
|
|
11
|
-
provider: string
|
|
12
|
-
id: string
|
|
13
|
-
name?: string
|
|
14
|
-
email?: string
|
|
15
|
-
avatar?: string
|
|
16
|
-
[key: string]: unknown
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/** Return value of `useAuth()`. Exposes the current user and helpers for login/logout. */
|
|
20
|
-
export interface AuthComposable {
|
|
21
|
-
/** The currently authenticated user, or `null` if not logged in. */
|
|
22
|
-
readonly user: AuthUser | null
|
|
23
|
-
/** `true` when a user is authenticated. */
|
|
24
|
-
readonly loggedIn: boolean
|
|
25
|
-
/**
|
|
26
|
-
* Initiates an OAuth login flow by redirecting to `/api/auth/:provider`.
|
|
27
|
-
* Only meaningful on the client — calling this on the server is a no-op.
|
|
28
|
-
*/
|
|
29
|
-
login(provider: string): void
|
|
30
|
-
/**
|
|
31
|
-
* Logs out the current user.
|
|
32
|
-
*
|
|
33
|
-
* - **Server context** (inside a loader / middleware): clears the auth
|
|
34
|
-
* session cookie immediately via `useSession().clear()`.
|
|
35
|
-
* - **Client context**: redirects to `/api/auth/logout` which clears the
|
|
36
|
-
* cookie server-side and redirects to `redirectAfterLogout`.
|
|
37
|
-
*/
|
|
38
|
-
logout(): Promise<void>
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// ─── Composable ───────────────────────────────────────────────────────────────
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Returns the currently authenticated user and helpers for login/logout.
|
|
45
|
-
*
|
|
46
|
-
* Works isomorphically:
|
|
47
|
-
* - **Server render pass** — reads from `globalThis.__CER_AUTH_STORE__`
|
|
48
|
-
* (AsyncLocalStorage populated by the entry-server handler before rendering).
|
|
49
|
-
* - **Client hydration** — reads from `globalThis.__CER_AUTH_USER__` (injected
|
|
50
|
-
* as `window.__CER_AUTH_USER__` by the entry-server and captured by the
|
|
51
|
-
* client entry before the app boots).
|
|
52
|
-
*
|
|
53
|
-
* @param sessionKey - Session cookie name; must match `auth.sessionKey` in
|
|
54
|
-
* `cer.config.ts` (defaults to `'auth'`).
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* // app/pages/profile.ts
|
|
59
|
-
* component('page-profile', () => {
|
|
60
|
-
* const { user, loggedIn, logout } = useAuth()
|
|
61
|
-
*
|
|
62
|
-
* if (!loggedIn) {
|
|
63
|
-
* // Redirect to login
|
|
64
|
-
* useHead({ title: 'Login required' })
|
|
65
|
-
* }
|
|
66
|
-
* })
|
|
67
|
-
* ```
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* ```ts
|
|
71
|
-
* // app/middleware/require-auth.ts
|
|
72
|
-
* export default defineMiddleware((to) => {
|
|
73
|
-
* const { loggedIn } = useAuth()
|
|
74
|
-
* if (!loggedIn) return '/login'
|
|
75
|
-
* return true
|
|
76
|
-
* })
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export function useAuth(sessionKey = 'auth'): AuthComposable {
|
|
80
|
-
const g = globalThis as Record<string, unknown>
|
|
81
|
-
|
|
82
|
-
// Server: read from the per-request AsyncLocalStorage context.
|
|
83
|
-
// __CER_AUTH_STORE__ is only present in Node.js (tree-shaken on client).
|
|
84
|
-
const authStore = g['__CER_AUTH_STORE__'] as { getStore(): unknown } | undefined
|
|
85
|
-
let user: AuthUser | null = null
|
|
86
|
-
|
|
87
|
-
if (authStore) {
|
|
88
|
-
user = (authStore.getStore() as AuthUser | null) ?? null
|
|
89
|
-
} else {
|
|
90
|
-
// Client: read from the global hydrated by the client entry.
|
|
91
|
-
user = (g['__CER_AUTH_USER__'] as AuthUser | null) ?? null
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return {
|
|
95
|
-
get user() {
|
|
96
|
-
return user
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
get loggedIn() {
|
|
100
|
-
return user !== null
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
login(provider: string) {
|
|
104
|
-
if (typeof window !== 'undefined') {
|
|
105
|
-
window.location.href = `/api/auth/${provider}`
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
async logout() {
|
|
110
|
-
if (typeof window !== 'undefined') {
|
|
111
|
-
// Client: let the server clear the cookie via the logout route.
|
|
112
|
-
window.location.href = '/api/auth/logout'
|
|
113
|
-
} else {
|
|
114
|
-
// Server context: clear the session cookie directly.
|
|
115
|
-
const session = useSession({ name: sessionKey })
|
|
116
|
-
await session.clear()
|
|
117
|
-
// Also clear the local user reference so the current render sees null.
|
|
118
|
-
user = null
|
|
119
|
-
// Clear the ALS store value so concurrent requests are unaffected.
|
|
120
|
-
const store = (g['__CER_AUTH_STORE__'] as { enterWith(v: unknown): void } | undefined)
|
|
121
|
-
if (store) store.enterWith(null)
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
}
|
|
125
|
-
}
|