@jasonshimmy/vite-plugin-cer-app 0.23.1 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +37 -4
- 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 +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin/build-ssg.d.ts +22 -4
- package/dist/plugin/build-ssg.d.ts.map +1 -1
- package/dist/plugin/build-ssg.js +273 -13
- package/dist/plugin/build-ssg.js.map +1 -1
- package/dist/plugin/content/parser.d.ts.map +1 -1
- package/dist/plugin/content/parser.js +54 -10
- package/dist/plugin/content/parser.js.map +1 -1
- package/dist/plugin/dev-server.d.ts +6 -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 +35 -0
- package/dist/plugin/html-post-process.d.ts.map +1 -0
- package/dist/plugin/html-post-process.js +112 -0
- package/dist/plugin/html-post-process.js.map +1 -0
- package/dist/plugin/index.d.ts +9 -0
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +89 -14
- 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 -4
- package/dist/runtime/app-template.d.ts.map +1 -1
- package/dist/runtime/app-template.js +211 -40
- 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 +179 -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-head.d.ts.map +1 -1
- package/dist/runtime/composables/use-head.js +30 -6
- package/dist/runtime/composables/use-head.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 +53 -4
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js.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 -232
- 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 -667
- 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 -112
- 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/path-utils.test.ts +0 -411
- package/src/__tests__/plugin/resolve-config.test.ts +0 -200
- 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 -198
- 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 -266
- 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 -489
- 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 -336
- 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 -377
- package/src/plugin/dts-generator.ts +0 -273
- package/src/plugin/generated-dir.ts +0 -121
- package/src/plugin/index.ts +0 -553
- 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 -380
- 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 -212
- 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 -371
- 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
package/docs/authentication.md
DELETED
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
# Authentication
|
|
2
|
-
|
|
3
|
-
The framework includes a built-in OAuth 2.0 authentication system. Enabling it auto-generates three API routes and provides `useAuth()` for reading the current user anywhere in your app.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Setup
|
|
8
|
-
|
|
9
|
-
Install the providers you need in `cer.config.ts`:
|
|
10
|
-
|
|
11
|
-
```ts
|
|
12
|
-
// cer.config.ts
|
|
13
|
-
import { defineConfig } from '@jasonshimmy/vite-plugin-cer-app'
|
|
14
|
-
|
|
15
|
-
export default defineConfig({
|
|
16
|
-
auth: {
|
|
17
|
-
providers: {
|
|
18
|
-
github: {
|
|
19
|
-
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
20
|
-
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
21
|
-
},
|
|
22
|
-
google: {
|
|
23
|
-
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
24
|
-
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
redirectAfterLogin: '/dashboard',
|
|
28
|
-
redirectAfterLogout: '/',
|
|
29
|
-
sessionKey: 'auth', // optional — defaults to 'auth'
|
|
30
|
-
},
|
|
31
|
-
})
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
Configure the OAuth callback URL in your provider's developer console:
|
|
35
|
-
|
|
36
|
-
```
|
|
37
|
-
https://yourdomain.com/api/auth/callback/github
|
|
38
|
-
https://yourdomain.com/api/auth/callback/google
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## Generated routes
|
|
44
|
-
|
|
45
|
-
When `auth` is configured, the framework automatically registers:
|
|
46
|
-
|
|
47
|
-
| Route | Description |
|
|
48
|
-
|---|---|
|
|
49
|
-
| `GET /api/auth/:provider` | Initiates the OAuth flow — redirects the browser to the provider's authorization page |
|
|
50
|
-
| `GET /api/auth/callback/:provider` | Handles the OAuth callback — exchanges the code for tokens, fetches the user profile, writes the auth session cookie, and redirects to `redirectAfterLogin` |
|
|
51
|
-
| `GET /api/auth/logout` | Clears the auth session cookie and redirects to `redirectAfterLogout` |
|
|
52
|
-
|
|
53
|
-
### OAuth error handling
|
|
54
|
-
|
|
55
|
-
All network calls in the callback route (token exchange and user-info fetch) are wrapped in try/catch. If a provider is unreachable or returns an unexpected response, the handler responds with HTTP 502 and a plain-text diagnostic message rather than crashing the server:
|
|
56
|
-
|
|
57
|
-
| Failure | Status | Response body |
|
|
58
|
-
|---|---|---|
|
|
59
|
-
| Token exchange network error | 502 | `[cer-app] OAuth token exchange request failed` |
|
|
60
|
-
| Token exchange non-OK HTTP status | 502 | `[cer-app] OAuth token exchange returned non-OK status` |
|
|
61
|
-
| Token exchange invalid JSON | 502 | `[cer-app] OAuth token exchange returned invalid JSON` |
|
|
62
|
-
| User-info network error | 502 | `[cer-app] OAuth user-info request failed` |
|
|
63
|
-
| User-info non-OK HTTP status | 502 | `[cer-app] OAuth user-info returned non-OK status` |
|
|
64
|
-
| User-info invalid JSON | 502 | `[cer-app] OAuth user-info returned invalid JSON` |
|
|
65
|
-
| Unknown provider | 404 | `[cer-app] Unknown OAuth provider: <name>` |
|
|
66
|
-
| Missing state / code param | 400 | `[cer-app] OAuth callback missing code or state parameter` |
|
|
67
|
-
| State mismatch (CSRF) | 400 | `[cer-app] OAuth state mismatch — possible CSRF attempt` |
|
|
68
|
-
|
|
69
|
-
These responses are intentionally terse — they are server-to-server error messages, not end-user UI. To show a branded error page when OAuth fails, redirect in a top-level error boundary or handle the 502 at your reverse proxy / CDN layer.
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## `useAuth(sessionKey?)`
|
|
74
|
-
|
|
75
|
-
`useAuth()` reads the authenticated user and provides helpers for login and logout. The optional `sessionKey` parameter specifies which session cookie to read (defaults to the value of `auth.sessionKey` in `cer.config.ts`, which itself defaults to `'auth'`). It works isomorphically:
|
|
76
|
-
|
|
77
|
-
- **Server (SSR/SSG)** — reads the auth session from the per-request `AsyncLocalStorage` context (populated by the entry-server handler before rendering).
|
|
78
|
-
- **Client** — reads from `globalThis.__CER_AUTH_USER__` (injected into the HTML by the server and captured by the client entry before the app boots).
|
|
79
|
-
|
|
80
|
-
```ts
|
|
81
|
-
// app/pages/profile.ts
|
|
82
|
-
component('page-profile', () => {
|
|
83
|
-
const { user, loggedIn, login, logout } = useAuth()
|
|
84
|
-
|
|
85
|
-
return html`
|
|
86
|
-
${loggedIn
|
|
87
|
-
? html`
|
|
88
|
-
<p>Hello, ${user?.name}</p>
|
|
89
|
-
<img src="${user?.avatar}" alt="avatar" />
|
|
90
|
-
<button @click="${logout}">Log out</button>
|
|
91
|
-
`
|
|
92
|
-
: html`
|
|
93
|
-
<button @click="${() => login('github')}">Log in with GitHub</button>
|
|
94
|
-
<button @click="${() => login('google')}">Log in with Google</button>
|
|
95
|
-
`
|
|
96
|
-
}
|
|
97
|
-
`
|
|
98
|
-
})
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### `AuthComposable`
|
|
102
|
-
|
|
103
|
-
| Member | Type | Description |
|
|
104
|
-
|---|---|---|
|
|
105
|
-
| `user` | `AuthUser \| null` | The authenticated user, or `null` if not logged in |
|
|
106
|
-
| `loggedIn` | `boolean` | `true` when a user is authenticated |
|
|
107
|
-
| `login(provider)` | `void` | Redirects to `/api/auth/:provider` to start the OAuth flow (client only) |
|
|
108
|
-
| `logout()` | `void` (client) / `Promise<void>` (server) | Client: assigns `window.location.href` to `/api/auth/logout` (synchronous, no promise). Server: clears the auth session cookie directly and returns a promise. |
|
|
109
|
-
|
|
110
|
-
### `AuthUser`
|
|
111
|
-
|
|
112
|
-
| Field | Type | Description |
|
|
113
|
-
|---|---|---|
|
|
114
|
-
| `provider` | `string` | OAuth provider name, e.g. `'github'`, `'google'`, `'discord'` |
|
|
115
|
-
| `id` | `string` | Provider-issued user ID |
|
|
116
|
-
| `name` | `string?` | Display name |
|
|
117
|
-
| `email` | `string?` | Email address |
|
|
118
|
-
| `avatar` | `string?` | Profile picture URL |
|
|
119
|
-
| `[key: string]` | `unknown` | Any additional fields from `mapUser` or the default normalisation |
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Protecting routes with middleware
|
|
124
|
-
|
|
125
|
-
Use `useAuth()` inside a middleware to guard protected pages:
|
|
126
|
-
|
|
127
|
-
```ts
|
|
128
|
-
// app/middleware/require-auth.ts
|
|
129
|
-
export default defineMiddleware(() => {
|
|
130
|
-
const { loggedIn } = useAuth()
|
|
131
|
-
if (!loggedIn) return '/login'
|
|
132
|
-
})
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
Attach it to a page via `meta.middleware`:
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
// app/pages/dashboard.ts
|
|
139
|
-
component('page-dashboard', () => {
|
|
140
|
-
const { user } = useAuth()
|
|
141
|
-
return html`<h1>Welcome, ${user?.name}</h1>`
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
export const meta = { middleware: ['require-auth'] }
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## Built-in providers
|
|
150
|
-
|
|
151
|
-
Three providers are pre-configured. Supply only `clientId` and `clientSecret`:
|
|
152
|
-
|
|
153
|
-
| Provider | Scopes | PKCE |
|
|
154
|
-
|---|---|---|
|
|
155
|
-
| `google` | `openid email profile` | ✅ S256 |
|
|
156
|
-
| `github` | `read:user user:email` | ❌ not supported |
|
|
157
|
-
| `discord` | `identify email` | ✅ S256 |
|
|
158
|
-
|
|
159
|
-
Override scopes per provider:
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
github: {
|
|
163
|
-
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
164
|
-
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
165
|
-
scope: ['read:user', 'repo'], // add repo access
|
|
166
|
-
},
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
---
|
|
170
|
-
|
|
171
|
-
## Custom providers
|
|
172
|
-
|
|
173
|
-
Supply all three endpoint URLs for providers not built in:
|
|
174
|
-
|
|
175
|
-
```ts
|
|
176
|
-
export default defineConfig({
|
|
177
|
-
auth: {
|
|
178
|
-
providers: {
|
|
179
|
-
myProvider: {
|
|
180
|
-
clientId: process.env.MY_CLIENT_ID!,
|
|
181
|
-
clientSecret: process.env.MY_CLIENT_SECRET!,
|
|
182
|
-
authorizationUrl: 'https://auth.example.com/oauth/authorize',
|
|
183
|
-
tokenUrl: 'https://auth.example.com/oauth/token',
|
|
184
|
-
userInfoUrl: 'https://auth.example.com/oauth/userinfo',
|
|
185
|
-
scope: ['profile', 'email'],
|
|
186
|
-
},
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
})
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## Customising the user shape
|
|
195
|
-
|
|
196
|
-
By default the framework normalises the provider's profile to `{ provider, id, name, email, avatar }`. Use `mapUser` to store additional or differently-shaped data in the session:
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
github: {
|
|
200
|
-
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
201
|
-
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
202
|
-
mapUser: (profile, tokens) => ({
|
|
203
|
-
provider: 'github',
|
|
204
|
-
id: String(profile.id),
|
|
205
|
-
name: String(profile.name ?? profile.login),
|
|
206
|
-
email: String(profile.email ?? ''),
|
|
207
|
-
avatar: String(profile.avatar_url ?? ''),
|
|
208
|
-
login: String(profile.login), // extra field
|
|
209
|
-
accessToken: tokens.accessToken,
|
|
210
|
-
}),
|
|
211
|
-
},
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
The object returned by `mapUser` becomes `useAuth().user` on both server and client.
|
|
215
|
-
|
|
216
|
-
---
|
|
217
|
-
|
|
218
|
-
## `auth.sessionKey`
|
|
219
|
-
|
|
220
|
-
The auth session is stored in a signed `httpOnly` cookie. `sessionKey` sets the cookie name (default `'auth'`). It must not collide with other `useSession()` names in your app.
|
|
221
|
-
|
|
222
|
-
Reading the session key explicitly is only needed if you call `useSession` manually for auth data:
|
|
223
|
-
|
|
224
|
-
```ts
|
|
225
|
-
const session = useSession({ name: 'auth' })
|
|
226
|
-
const user = await session.get<AuthUser>()
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
`useAuth()` reads this automatically — prefer `useAuth()` over reading the session directly.
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## Security
|
|
234
|
-
|
|
235
|
-
- **PKCE (S256)** is used for all providers that support it (Google, Discord). The code verifier is stored in a short-lived `_oauth_pkce` session cookie (10-minute TTL) and cleared after the callback.
|
|
236
|
-
- **State parameter** — a 16-byte random value is generated per flow and verified in the callback, preventing CSRF.
|
|
237
|
-
- **Client secrets** never appear in the client bundle. The auth handler is only imported by the server-side virtual module.
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## `defineOAuthProvider(config)`
|
|
242
|
-
|
|
243
|
-
A type-safe helper for declaring providers in `cer.config.ts`. It is an identity function — it returns the config unchanged and exists purely so TypeScript infers the correct type for each field.
|
|
244
|
-
|
|
245
|
-
Built-in providers (`google`, `github`, `discord`) only require `clientId` and `clientSecret`. Any endpoint URL or scope can be overridden. For a fully custom provider, all three endpoint URLs are required.
|
|
246
|
-
|
|
247
|
-
```ts
|
|
248
|
-
// cer.config.ts
|
|
249
|
-
import { defineConfig } from '@jasonshimmy/vite-plugin-cer-app'
|
|
250
|
-
import { defineOAuthProvider } from '@jasonshimmy/vite-plugin-cer-app/oauth'
|
|
251
|
-
|
|
252
|
-
export default defineConfig({
|
|
253
|
-
auth: {
|
|
254
|
-
providers: {
|
|
255
|
-
github: defineOAuthProvider({
|
|
256
|
-
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
257
|
-
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
258
|
-
scope: ['read:user', 'user:email'], // override default scopes
|
|
259
|
-
}),
|
|
260
|
-
myProvider: defineOAuthProvider({
|
|
261
|
-
clientId: process.env.MY_CLIENT_ID!,
|
|
262
|
-
clientSecret: process.env.MY_CLIENT_SECRET!,
|
|
263
|
-
authorizationUrl: 'https://auth.example.com/authorize',
|
|
264
|
-
tokenUrl: 'https://auth.example.com/token',
|
|
265
|
-
userInfoUrl: 'https://auth.example.com/userinfo',
|
|
266
|
-
}),
|
|
267
|
-
},
|
|
268
|
-
},
|
|
269
|
-
})
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
Using `defineOAuthProvider` is optional — a plain object literal is also accepted. The helper exists only for TypeScript inference convenience.
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## TypeScript
|
|
277
|
-
|
|
278
|
-
```ts
|
|
279
|
-
import { useAuth } from '@jasonshimmy/vite-plugin-cer-app/composables'
|
|
280
|
-
import { defineOAuthProvider } from '@jasonshimmy/vite-plugin-cer-app/oauth'
|
|
281
|
-
import type { AuthUser, AuthComposable } from '@jasonshimmy/vite-plugin-cer-app/composables'
|
|
282
|
-
import type { AuthConfig, OAuthProviderConfig } from '@jasonshimmy/vite-plugin-cer-app/types'
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
`useAuth` is auto-imported in `app/pages/`, `app/layouts/`, `app/components/`, `app/middleware/`, and `app/composables/`. No import statement is needed in those directories.
|
package/docs/cli.md
DELETED
|
@@ -1,324 +0,0 @@
|
|
|
1
|
-
# CLI Reference
|
|
2
|
-
|
|
3
|
-
The framework provides two CLI programs:
|
|
4
|
-
|
|
5
|
-
- **`cer-app`** — dev server, build, preview, and generate commands
|
|
6
|
-
- **`create-cer-app`** — project scaffolding
|
|
7
|
-
|
|
8
|
-
Both are available after installing `@jasonshimmy/vite-plugin-cer-app` as a dev dependency, or globally:
|
|
9
|
-
|
|
10
|
-
```sh
|
|
11
|
-
npm install -g @jasonshimmy/vite-plugin-cer-app
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## `cer-app`
|
|
17
|
-
|
|
18
|
-
### `cer-app dev`
|
|
19
|
-
|
|
20
|
-
Starts the Vite development server. Reads `cer.config.ts` from the current directory.
|
|
21
|
-
|
|
22
|
-
```sh
|
|
23
|
-
cer-app dev [options]
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
| Option | Default | Description |
|
|
27
|
-
|---|---|---|
|
|
28
|
-
| `-p, --port <port>` | `3000` | Port to listen on |
|
|
29
|
-
| `--host <host>` | `localhost` | Host to bind to |
|
|
30
|
-
| `--root <root>` | `process.cwd()` | Project root directory |
|
|
31
|
-
|
|
32
|
-
**Examples:**
|
|
33
|
-
|
|
34
|
-
```sh
|
|
35
|
-
cer-app dev
|
|
36
|
-
cer-app dev --port 4000
|
|
37
|
-
cer-app dev --host 0.0.0.0 --port 8080
|
|
38
|
-
cer-app dev --root ./packages/my-app
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
**Behavior:**
|
|
42
|
-
|
|
43
|
-
- Loads and transpiles `cer.config.ts` (or `cer.config.js`)
|
|
44
|
-
- Starts the Vite dev server with `cerApp()` plugins applied
|
|
45
|
-
- In SSR mode: intercepts HTML requests and renders server-side
|
|
46
|
-
- In SPA mode: standard Vite HMR
|
|
47
|
-
- Watches `app/` and `server/` directories; full-reloads when pages or components are added/removed
|
|
48
|
-
- Responds to `SIGTERM` and `SIGINT` with graceful shutdown
|
|
49
|
-
|
|
50
|
-
---
|
|
51
|
-
|
|
52
|
-
### `cer-app build`
|
|
53
|
-
|
|
54
|
-
Builds the application for production.
|
|
55
|
-
|
|
56
|
-
```sh
|
|
57
|
-
cer-app build [options]
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
| Option | Default | Description |
|
|
61
|
-
|---|---|---|
|
|
62
|
-
| `--root <root>` | `process.cwd()` | Project root directory |
|
|
63
|
-
| `--mode <mode>` | From `cer.config.ts` | Override rendering mode: `spa`, `ssr`, or `ssg` |
|
|
64
|
-
|
|
65
|
-
**Examples:**
|
|
66
|
-
|
|
67
|
-
```sh
|
|
68
|
-
cer-app build
|
|
69
|
-
cer-app build --mode ssr
|
|
70
|
-
cer-app build --mode ssg
|
|
71
|
-
cer-app build --root ./packages/my-app
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Per-mode behavior:**
|
|
75
|
-
|
|
76
|
-
| Mode | Actions |
|
|
77
|
-
|---|---|
|
|
78
|
-
| `spa` | Standard `vite build` to `dist/` |
|
|
79
|
-
| `ssr` | Dual build: client bundle to `dist/client/`, server bundle to `dist/server/server.js` |
|
|
80
|
-
| `ssg` | Dual build + enumerate routes + render all paths to `dist/<path>/index.html` |
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
### `cer-app preview`
|
|
85
|
-
|
|
86
|
-
Serves the production build locally.
|
|
87
|
-
|
|
88
|
-
```sh
|
|
89
|
-
cer-app preview [options]
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
| Option | Default | Description |
|
|
93
|
-
|---|---|---|
|
|
94
|
-
| `-p, --port <port>` | `4173` | Port to listen on |
|
|
95
|
-
| `--host <host>` | `localhost` | Host to bind to |
|
|
96
|
-
| `--root <root>` | `process.cwd()` | Project root directory |
|
|
97
|
-
| `--ssr` | Auto-detected | Load `dist/server/server.js` as the request handler |
|
|
98
|
-
|
|
99
|
-
**Examples:**
|
|
100
|
-
|
|
101
|
-
```sh
|
|
102
|
-
cer-app preview # SPA/SSG static file server
|
|
103
|
-
cer-app preview --ssr # SSR server using dist/server/server.js
|
|
104
|
-
cer-app preview --port 8080
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
**Behavior:**
|
|
108
|
-
|
|
109
|
-
- If `dist/server/server.js` exists (or `--ssr` is passed), starts an SSR preview server
|
|
110
|
-
- Static assets from `dist/client/` are served first; HTML requests fall through to the SSR handler
|
|
111
|
-
- Otherwise, starts a static file server with SPA fallback (serves `index.html` for unknown paths)
|
|
112
|
-
- Returns 404 for paths not found in `dist/` (static mode only)
|
|
113
|
-
- **Path traversal protection:** all file requests are validated against the `dist/` root — requests attempting to escape it (e.g. `GET /../../../../etc/passwd`) receive a `400` response
|
|
114
|
-
- **Security headers:** every response includes `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, and `Referrer-Policy: strict-origin-when-cross-origin`
|
|
115
|
-
- **Smart Cache-Control:** Vite content-hashes assets placed in `/assets/` — these are served with `Cache-Control: public, max-age=31536000, immutable`. All other files (HTML, etc.) use `Cache-Control: no-cache` so browsers always revalidate
|
|
116
|
-
- **Graceful shutdown:** on `SIGTERM` or `SIGINT`, the server stops accepting new connections and waits for in-flight requests to finish before exiting. A 10-second timeout triggers a forced exit if connections do not drain
|
|
117
|
-
- **Request timeouts:** `headersTimeout` (10 s) aborts connections that stall while sending headers; `requestTimeout` (30 s) limits the total time allowed per request/response cycle, protecting against slow-client attacks
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
### `cer-app generate`
|
|
122
|
-
|
|
123
|
-
Runs the SSG build pipeline. Alias for `cer-app build --mode ssg`.
|
|
124
|
-
|
|
125
|
-
```sh
|
|
126
|
-
cer-app generate [options]
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
| Option | Default | Description |
|
|
130
|
-
|---|---|---|
|
|
131
|
-
| `--root <root>` | `process.cwd()` | Project root directory |
|
|
132
|
-
|
|
133
|
-
**Example:**
|
|
134
|
-
|
|
135
|
-
```sh
|
|
136
|
-
cer-app generate
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
**Output:**
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
dist/
|
|
143
|
-
index.html
|
|
144
|
-
about/index.html
|
|
145
|
-
blog/
|
|
146
|
-
hello-world/index.html
|
|
147
|
-
ssg-manifest.json
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
---
|
|
151
|
-
|
|
152
|
-
### `cer-app adapt`
|
|
153
|
-
|
|
154
|
-
Adapts the production build for a deployment platform.
|
|
155
|
-
|
|
156
|
-
Run this after `cer-app build` to produce the platform-specific output alongside `dist/`.
|
|
157
|
-
You can also configure `adapter` in `cer.config.ts` so the adapter runs automatically at the end of every build.
|
|
158
|
-
|
|
159
|
-
```sh
|
|
160
|
-
cer-app adapt [options]
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
| Option | Default | Description |
|
|
164
|
-
|---|---|---|
|
|
165
|
-
| `--platform <platform>` | *(required)* | Target platform: `vercel`, `netlify`, or `cloudflare` |
|
|
166
|
-
| `--root <root>` | `process.cwd()` | Project root directory |
|
|
167
|
-
|
|
168
|
-
**Examples:**
|
|
169
|
-
|
|
170
|
-
```sh
|
|
171
|
-
cer-app adapt --platform vercel
|
|
172
|
-
cer-app adapt --platform netlify
|
|
173
|
-
cer-app adapt --platform cloudflare
|
|
174
|
-
cer-app adapt --platform vercel --root ./packages/my-app
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
**Vercel behavior (`--platform vercel`):**
|
|
178
|
-
|
|
179
|
-
- Writes `.vercel/output/` following the [Vercel Build Output API v3](https://vercel.com/docs/build-output-api/v3).
|
|
180
|
-
- SSR builds: creates a Node.js Serverless Function at `.vercel/output/functions/index.func/` that routes `/api/*` to the exported API handlers and passes everything else to the SSR handler. Content-hashed assets are copied to `.vercel/output/static/` for CDN delivery.
|
|
181
|
-
- SPA/SSG builds: copies static files to `.vercel/output/static/` with a SPA fallback route.
|
|
182
|
-
- Deploy with `vercel deploy --prebuilt`.
|
|
183
|
-
|
|
184
|
-
**Netlify behavior (`--platform netlify`):**
|
|
185
|
-
|
|
186
|
-
- Writes `netlify/functions/ssr.mjs` — a Netlify Functions v2 bridge that converts the Web `Request`/`Response` API to the Node.js-style handler used by the server bundle. Handles `/api/*` routing inline.
|
|
187
|
-
- Copies content-hashed assets to `.netlify/publish/` (no `index.html` — HTML is served by the function).
|
|
188
|
-
- Writes `netlify.toml` with the publish directory, `Cache-Control` headers for assets, and a catch-all redirect to the SSR function.
|
|
189
|
-
- SPA/SSG builds: writes `netlify.toml` only (no function needed).
|
|
190
|
-
- SSR responses are streamed via the Web Streams `TransformStream` API — HTML chunks are forwarded to the client as they are written rather than waiting for the full page to render.
|
|
191
|
-
- Deploy with `netlify deploy`.
|
|
192
|
-
|
|
193
|
-
**Cloudflare behavior (`--platform cloudflare`):**
|
|
194
|
-
|
|
195
|
-
- Writes `dist/_worker.js` — a Cloudflare Pages [Advanced Mode](https://developers.cloudflare.com/pages/functions/advanced-mode/) worker. The client HTML template is inlined in the worker as a string constant so `node:fs` is never needed at runtime.
|
|
196
|
-
- Requires the `nodejs_compat` compatibility flag (written automatically into `wrangler.toml`) for `AsyncLocalStorage` and `node:stream` support.
|
|
197
|
-
- Copies content-hashed assets to `dist/` alongside the worker. Cloudflare Pages CDN serves matched static files first; all other requests fall through to `_worker.js`.
|
|
198
|
-
- SPA/SSG builds: no worker generated — Cloudflare Pages serves `dist/` as a static site.
|
|
199
|
-
- SSR responses are streamed via the Web Streams `TransformStream` API — HTML chunks are forwarded to the client as they are written rather than waiting for the full page to render.
|
|
200
|
-
- Deploy with `wrangler pages deploy dist`.
|
|
201
|
-
|
|
202
|
-
**Auto-run via `cer.config.ts`:**
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
// cer.config.ts — built-in adapter
|
|
206
|
-
export default defineConfig({
|
|
207
|
-
mode: 'ssr',
|
|
208
|
-
adapter: 'vercel', // 'vercel' | 'netlify' | 'cloudflare'
|
|
209
|
-
})
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
```ts
|
|
213
|
-
// cer.config.ts — custom adapter (Railway, Fly.io, bare Node.js, Docker, …)
|
|
214
|
-
export default defineConfig({
|
|
215
|
-
mode: 'ssr',
|
|
216
|
-
adapter: async (root) => {
|
|
217
|
-
const { cp, mkdir } = await import('node:fs/promises')
|
|
218
|
-
await mkdir(`${root}/deploy`, { recursive: true })
|
|
219
|
-
await cp(`${root}/dist`, `${root}/deploy/dist`, { recursive: true })
|
|
220
|
-
},
|
|
221
|
-
})
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
Pass `--platform custom` to `cer-app adapt` to run a function adapter without re-building:
|
|
225
|
-
|
|
226
|
-
```sh
|
|
227
|
-
cer-app adapt --platform custom
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
See [`adapter` in configuration.md](./configuration.md#adapter) for the full options reference.
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## `create-cer-app`
|
|
235
|
-
|
|
236
|
-
Scaffolds a new project from a template.
|
|
237
|
-
|
|
238
|
-
> **Note:** Because the scaffolder is bundled inside `@jasonshimmy/vite-plugin-cer-app` rather than published as a standalone `create-cer-app` package, you must use the `--package` flag with `npx`:
|
|
239
|
-
>
|
|
240
|
-
> ```sh
|
|
241
|
-
> npx --package @jasonshimmy/vite-plugin-cer-app create-cer-app [project-name] [options]
|
|
242
|
-
> ```
|
|
243
|
-
|
|
244
|
-
| Argument / Option | Description |
|
|
245
|
-
|---|---|
|
|
246
|
-
| `[project-name]` | Name of the project (also used as the output directory) |
|
|
247
|
-
| `--mode <mode>` | Rendering mode: `spa`, `ssr`, or `ssg` (skips interactive prompt) |
|
|
248
|
-
| `--dir <dir>` | Output directory (defaults to `project-name`) |
|
|
249
|
-
|
|
250
|
-
**Examples:**
|
|
251
|
-
|
|
252
|
-
```sh
|
|
253
|
-
npx --package @jasonshimmy/vite-plugin-cer-app create-cer-app # interactive prompts
|
|
254
|
-
npx --package @jasonshimmy/vite-plugin-cer-app create-cer-app my-app # prompts for mode
|
|
255
|
-
npx --package @jasonshimmy/vite-plugin-cer-app create-cer-app my-app --mode ssr # no prompts
|
|
256
|
-
npx --package @jasonshimmy/vite-plugin-cer-app create-cer-app my-blog --mode ssg --dir ./sites/blog
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
**Scaffolded files (all modes):**
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
my-app/
|
|
263
|
-
app/
|
|
264
|
-
app.ts ← framework bootstrap (router, plugins, layout shell)
|
|
265
|
-
pages/index.ts
|
|
266
|
-
layouts/default.ts
|
|
267
|
-
index.html
|
|
268
|
-
cer.config.ts
|
|
269
|
-
package.json
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
**Per-mode differences:**
|
|
273
|
-
|
|
274
|
-
| Mode | `cer.config.ts` | `package.json` scripts |
|
|
275
|
-
|---|---|---|
|
|
276
|
-
| SPA | `mode: 'spa'` | `dev`, `build`, `preview` |
|
|
277
|
-
| SSR | `mode: 'ssr'` | `dev`, `build`, `preview --ssr` |
|
|
278
|
-
| SSG | `mode: 'ssg'`, `ssg.routes: 'auto'` | `dev`, `build`, `preview`, `generate` |
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
## Config file loading
|
|
283
|
-
|
|
284
|
-
Both `cer-app dev` and `cer-app build` load `cer.config.ts` by:
|
|
285
|
-
|
|
286
|
-
1. Bundling it with Vite into a temporary `.mjs` file in `node_modules/.cer-app-cache/`
|
|
287
|
-
2. Dynamically importing the result
|
|
288
|
-
|
|
289
|
-
This allows TypeScript syntax in `cer.config.ts` with full type checking. The cached bundle is regenerated on every CLI invocation.
|
|
290
|
-
|
|
291
|
-
If no `cer.config.ts` or `cer.config.js` is found, defaults are used and a warning is printed.
|
|
292
|
-
|
|
293
|
-
---
|
|
294
|
-
|
|
295
|
-
## Using with `npm run`
|
|
296
|
-
|
|
297
|
-
After scaffolding, scripts are already set up in `package.json`:
|
|
298
|
-
|
|
299
|
-
```json
|
|
300
|
-
{
|
|
301
|
-
"scripts": {
|
|
302
|
-
"dev": "cer-app dev",
|
|
303
|
-
"build": "cer-app build",
|
|
304
|
-
"preview": "cer-app preview",
|
|
305
|
-
"generate": "cer-app generate"
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
```sh
|
|
311
|
-
npm run dev
|
|
312
|
-
npm run build
|
|
313
|
-
npm run preview
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Using with `npx` (no global install)
|
|
319
|
-
|
|
320
|
-
```sh
|
|
321
|
-
npx cer-app dev
|
|
322
|
-
npx cer-app build
|
|
323
|
-
npx --package @jasonshimmy/vite-plugin-cer-app create-cer-app my-app
|
|
324
|
-
```
|