@jasonshimmy/vite-plugin-cer-app 0.23.2 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/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 -6
- package/dist/plugin/build-ssg.d.ts.map +1 -1
- package/dist/plugin/build-ssg.js +227 -17
- 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 +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 +6 -0
- package/dist/plugin/html-post-process.d.ts.map +1 -1
- package/dist/plugin/html-post-process.js +24 -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 +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-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/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
package/src/plugin/dev-server.ts
DELETED
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
import type { ViteDevServer } from 'vite'
|
|
2
|
-
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
3
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
4
|
-
import { resolve } from 'node:path'
|
|
5
|
-
import { join } from 'pathe'
|
|
6
|
-
import { getGeneratedDir } from './generated-dir.js'
|
|
7
|
-
|
|
8
|
-
export interface ResolvedCerConfig {
|
|
9
|
-
mode: 'spa' | 'ssr' | 'ssg'
|
|
10
|
-
srcDir: string
|
|
11
|
-
root: string
|
|
12
|
-
/** Canonical site origin (no trailing slash). Null when not configured. */
|
|
13
|
-
siteUrl: string | null
|
|
14
|
-
contentDir: string
|
|
15
|
-
pagesDir: string
|
|
16
|
-
layoutsDir: string
|
|
17
|
-
componentsDir: string
|
|
18
|
-
composablesDir: string
|
|
19
|
-
pluginsDir: string
|
|
20
|
-
middlewareDir: string
|
|
21
|
-
serverApiDir: string
|
|
22
|
-
serverMiddlewareDir: string
|
|
23
|
-
port: number
|
|
24
|
-
ssg: { routes: 'auto' | string[]; concurrency: number; fallback: boolean }
|
|
25
|
-
router: { base?: string; scrollToFragment?: boolean | object }
|
|
26
|
-
jitCss: { content: string[]; extendedColors: boolean; customColors?: Record<string, Record<string, string>> }
|
|
27
|
-
autoImports: { components: boolean; composables: boolean; directives: boolean; runtime: boolean }
|
|
28
|
-
runtimeConfig: { public: Record<string, unknown>; private: import('../types/config.js').RuntimePrivateConfig }
|
|
29
|
-
auth: import('../types/config.js').AuthConfig | null
|
|
30
|
-
i18n: { locales: string[]; defaultLocale: string; strategy: 'prefix' | 'prefix_except_default' | 'no_prefix' } | null
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Reads the raw body from an IncomingMessage as a Buffer.
|
|
35
|
-
*/
|
|
36
|
-
function readBody(req: IncomingMessage): Promise<Buffer> {
|
|
37
|
-
return new Promise((resolve, reject) => {
|
|
38
|
-
const chunks: Buffer[] = []
|
|
39
|
-
req.on('data', (chunk: Buffer) => chunks.push(chunk))
|
|
40
|
-
req.on('end', () => resolve(Buffer.concat(chunks)))
|
|
41
|
-
req.on('error', reject)
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Parses the request body for JSON content types.
|
|
47
|
-
* Attaches the parsed body (or raw buffer) to `(req as any).body`.
|
|
48
|
-
*/
|
|
49
|
-
async function parseBody(req: IncomingMessage): Promise<unknown> {
|
|
50
|
-
const contentType = req.headers['content-type'] ?? ''
|
|
51
|
-
const method = req.method?.toUpperCase() ?? 'GET'
|
|
52
|
-
|
|
53
|
-
if (!['POST', 'PUT', 'PATCH'].includes(method)) {
|
|
54
|
-
return undefined
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const buf = await readBody(req)
|
|
58
|
-
|
|
59
|
-
if (contentType.includes('application/json')) {
|
|
60
|
-
try {
|
|
61
|
-
return JSON.parse(buf.toString('utf-8'))
|
|
62
|
-
} catch {
|
|
63
|
-
return undefined
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return buf
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Extracts route params from a path pattern.
|
|
72
|
-
* e.g. pattern="/api/users/:id", path="/api/users/42" -> { id: "42" }
|
|
73
|
-
*/
|
|
74
|
-
function matchApiPath(
|
|
75
|
-
pattern: string,
|
|
76
|
-
urlPath: string,
|
|
77
|
-
): Record<string, string> | null {
|
|
78
|
-
const patternParts = pattern.split('/')
|
|
79
|
-
const urlParts = urlPath.split('?')[0].split('/')
|
|
80
|
-
|
|
81
|
-
if (patternParts.length !== urlParts.length) return null
|
|
82
|
-
|
|
83
|
-
const params: Record<string, string> = {}
|
|
84
|
-
for (let i = 0; i < patternParts.length; i++) {
|
|
85
|
-
const p = patternParts[i]
|
|
86
|
-
const u = urlParts[i]
|
|
87
|
-
if (p.startsWith(':')) {
|
|
88
|
-
params[p.slice(1)] = decodeURIComponent(u)
|
|
89
|
-
} else if (p !== u) {
|
|
90
|
-
return null
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return params
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Parses URL query string into a plain object.
|
|
99
|
-
*/
|
|
100
|
-
function parseQuery(url: string): Record<string, string> {
|
|
101
|
-
const qIndex = url.indexOf('?')
|
|
102
|
-
if (qIndex === -1) return {}
|
|
103
|
-
const qs = url.slice(qIndex + 1)
|
|
104
|
-
const result: Record<string, string> = {}
|
|
105
|
-
for (const part of qs.split('&')) {
|
|
106
|
-
if (!part) continue
|
|
107
|
-
const eqIdx = part.indexOf('=')
|
|
108
|
-
if (eqIdx === -1) {
|
|
109
|
-
result[decodeURIComponent(part)] = ''
|
|
110
|
-
} else {
|
|
111
|
-
result[decodeURIComponent(part.slice(0, eqIdx))] = decodeURIComponent(
|
|
112
|
-
part.slice(eqIdx + 1),
|
|
113
|
-
)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
return result
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Tests whether a route path pattern matches a URL path.
|
|
121
|
-
* Mirrors the logic in preview-isr.ts#matchRoutePattern — kept local to
|
|
122
|
-
* avoid a plugin→CLI dependency.
|
|
123
|
-
*/
|
|
124
|
-
function _matchDevRoute(pattern: string, urlPath: string): boolean {
|
|
125
|
-
const norm = (s: string) => s.replace(/\/+$/, '') || '/'
|
|
126
|
-
if (norm(pattern) === norm(urlPath)) return true
|
|
127
|
-
const regexStr =
|
|
128
|
-
'^' +
|
|
129
|
-
norm(pattern)
|
|
130
|
-
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
|
|
131
|
-
.replace(/:[^/]+\*/g, '.*')
|
|
132
|
-
.replace(/:[^/]+/g, '[^/]+') +
|
|
133
|
-
'$'
|
|
134
|
-
return new RegExp(regexStr).test(norm(urlPath))
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
function _isHtmlRequest(url: string, acceptHeader: string | string[] | undefined): boolean {
|
|
138
|
-
const accept = Array.isArray(acceptHeader) ? acceptHeader.join(',') : (acceptHeader ?? '')
|
|
139
|
-
if (url.startsWith('/api/') || url.startsWith('/@')) return false
|
|
140
|
-
return (
|
|
141
|
-
accept.includes('text/html') ||
|
|
142
|
-
url === '/' ||
|
|
143
|
-
url === '/index.html' ||
|
|
144
|
-
!url.includes('.')
|
|
145
|
-
)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function _serveSpaShell(
|
|
149
|
-
server: ViteDevServer,
|
|
150
|
-
config: ResolvedCerConfig,
|
|
151
|
-
url: string,
|
|
152
|
-
res: ServerResponse,
|
|
153
|
-
): Promise<boolean> {
|
|
154
|
-
const userHtml = resolve(config.root, 'index.html')
|
|
155
|
-
const cerHtml = join(getGeneratedDir(config.root), 'index.html')
|
|
156
|
-
const shellPath = existsSync(userHtml) ? userHtml : cerHtml
|
|
157
|
-
if (!existsSync(shellPath)) return false
|
|
158
|
-
|
|
159
|
-
const rawHtml = readFileSync(shellPath, 'utf-8')
|
|
160
|
-
const transformed = await server.transformIndexHtml(url, rawHtml)
|
|
161
|
-
res.setHeader('Content-Type', 'text/html; charset=utf-8')
|
|
162
|
-
res.statusCode = 200
|
|
163
|
-
res.end(transformed)
|
|
164
|
-
return true
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Configures the Vite dev server with:
|
|
169
|
-
* 1. API route handlers from server/api/
|
|
170
|
-
* 2. Server middleware from server/middleware/
|
|
171
|
-
* 3. SSR HTML rendering (when mode is 'ssr')
|
|
172
|
-
*/
|
|
173
|
-
export function configureCerDevServer(
|
|
174
|
-
server: ViteDevServer,
|
|
175
|
-
config: ResolvedCerConfig,
|
|
176
|
-
): void {
|
|
177
|
-
server.middlewares.use(async (req: IncomingMessage, res: ServerResponse, next: () => void) => {
|
|
178
|
-
const url = req.url ?? '/'
|
|
179
|
-
const method = req.method?.toUpperCase() ?? 'GET'
|
|
180
|
-
const acceptsHtml = _isHtmlRequest(url, req.headers['accept'])
|
|
181
|
-
|
|
182
|
-
// 1. Server middleware from server/middleware/ runs first (CORS, auth, logging, etc.)
|
|
183
|
-
try {
|
|
184
|
-
const smMod = await server.ssrLoadModule('virtual:cer-server-middleware')
|
|
185
|
-
const serverMiddleware = (smMod.serverMiddleware ?? smMod.default ?? []) as Array<{
|
|
186
|
-
name: string
|
|
187
|
-
handler: (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => void | Promise<void>
|
|
188
|
-
}>
|
|
189
|
-
|
|
190
|
-
for (const { handler } of serverMiddleware) {
|
|
191
|
-
if (typeof handler !== 'function') continue
|
|
192
|
-
let calledNext = false
|
|
193
|
-
try {
|
|
194
|
-
await new Promise<void>((resolve, reject) => {
|
|
195
|
-
Promise.resolve(handler(req, res, (err?: unknown) => {
|
|
196
|
-
if (err) reject(err)
|
|
197
|
-
else { calledNext = true; resolve() }
|
|
198
|
-
})).then(() => { if (!calledNext) resolve() }).catch(reject)
|
|
199
|
-
})
|
|
200
|
-
} catch {
|
|
201
|
-
if (!res.writableEnded) { res.statusCode = 500; res.end('Internal Server Error') }
|
|
202
|
-
return
|
|
203
|
-
}
|
|
204
|
-
if (res.writableEnded || !calledNext) return
|
|
205
|
-
}
|
|
206
|
-
} catch {
|
|
207
|
-
// middleware module not ready — continue
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// 2. API route handlers from server/api/
|
|
211
|
-
try {
|
|
212
|
-
const mod = await server.ssrLoadModule('virtual:cer-server-api')
|
|
213
|
-
const apiRoutes: Array<{ path: string; handlers: Record<string, unknown> }> =
|
|
214
|
-
mod.apiRoutes ?? mod.default?.apiRoutes ?? []
|
|
215
|
-
|
|
216
|
-
for (const route of apiRoutes) {
|
|
217
|
-
const params = matchApiPath(route.path, url.split('?')[0])
|
|
218
|
-
if (params === null) continue
|
|
219
|
-
|
|
220
|
-
const query = parseQuery(url)
|
|
221
|
-
const body = await parseBody(req)
|
|
222
|
-
|
|
223
|
-
// Augment request
|
|
224
|
-
const augmentedReq = req as IncomingMessage & {
|
|
225
|
-
params: Record<string, string>
|
|
226
|
-
query: Record<string, string>
|
|
227
|
-
body: unknown
|
|
228
|
-
}
|
|
229
|
-
augmentedReq.params = params
|
|
230
|
-
augmentedReq.query = query
|
|
231
|
-
augmentedReq.body = body
|
|
232
|
-
|
|
233
|
-
// Augment response with json() and status() helpers
|
|
234
|
-
const augmentedRes = res as ServerResponse & {
|
|
235
|
-
json(data: unknown): void
|
|
236
|
-
status(code: number): typeof augmentedRes
|
|
237
|
-
_statusCode?: number
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
augmentedRes.json = function (data: unknown) {
|
|
241
|
-
const json = JSON.stringify(data)
|
|
242
|
-
this.setHeader('Content-Type', 'application/json')
|
|
243
|
-
this.end(json)
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
augmentedRes.status = function (code: number) {
|
|
247
|
-
this.statusCode = code
|
|
248
|
-
return this
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// Try to find a handler for the HTTP method. Exports may be GET/POST (uppercase)
|
|
252
|
-
// or get/post (lowercase); try both plus a 'default' fallback.
|
|
253
|
-
type RouteHandlerFn = (req: typeof augmentedReq, res: typeof augmentedRes) => void | Promise<void>
|
|
254
|
-
const handlerKey = method.toLowerCase()
|
|
255
|
-
const handler =
|
|
256
|
-
(route.handlers[handlerKey] as RouteHandlerFn | undefined) ??
|
|
257
|
-
(route.handlers[method.toUpperCase()] as RouteHandlerFn | undefined) ??
|
|
258
|
-
(route.handlers['default'] as RouteHandlerFn | undefined)
|
|
259
|
-
|
|
260
|
-
if (typeof handler === 'function') {
|
|
261
|
-
try {
|
|
262
|
-
await handler(augmentedReq, augmentedRes)
|
|
263
|
-
} catch (err) {
|
|
264
|
-
server.ssrFixStacktrace(err as Error)
|
|
265
|
-
console.error(`[cer-app] API handler error at ${route.path}:`, err)
|
|
266
|
-
res.statusCode = 500
|
|
267
|
-
res.setHeader('Content-Type', 'application/json')
|
|
268
|
-
res.end(JSON.stringify({ error: 'Internal Server Error' }))
|
|
269
|
-
}
|
|
270
|
-
return
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
} catch {
|
|
274
|
-
// virtual:cer-server-api not yet ready or empty — continue
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// 3. SPA mode: answer client-routed HTML navigations with the shell directly
|
|
278
|
-
// so Vite's history fallback never emits an intermediate 404 for valid app routes.
|
|
279
|
-
if (config.mode === 'spa' && (method === 'GET' || method === 'HEAD') && acceptsHtml) {
|
|
280
|
-
if (await _serveSpaShell(server, config, url, res)) {
|
|
281
|
-
return
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// 4. SSR/SSG mode: intercept HTML requests and server-render them.
|
|
286
|
-
// Both 'ssr' and 'ssg' modes run loaders on the server so usePageData()
|
|
287
|
-
// returns real data during dev — matching production behaviour.
|
|
288
|
-
// 'spa' mode never runs server loaders, so it falls through to the client bundle.
|
|
289
|
-
if (config.mode === 'ssr' || config.mode === 'ssg') {
|
|
290
|
-
if (acceptsHtml) {
|
|
291
|
-
// Check per-route render mode — skip SSR for 'spa' routes.
|
|
292
|
-
const urlPathOnly = url.split('?')[0]
|
|
293
|
-
try {
|
|
294
|
-
const routesMod = await server.ssrLoadModule('virtual:cer-routes')
|
|
295
|
-
const pageRoutes = Array.isArray(routesMod.default) ? routesMod.default as Array<{ path: string; meta?: Record<string, unknown> }> : []
|
|
296
|
-
for (const route of pageRoutes) {
|
|
297
|
-
if (_matchDevRoute(route.path, urlPathOnly)) {
|
|
298
|
-
if (route.meta?.render === 'spa') {
|
|
299
|
-
// In SSR/SSG dev mode, a route with render:'spa' should be served as
|
|
300
|
-
// the SPA shell (no server rendering). Serve .cer/index.html so the
|
|
301
|
-
// client bundle boots and handles the route client-side.
|
|
302
|
-
if (await _serveSpaShell(server, config, url, res)) {
|
|
303
|
-
return
|
|
304
|
-
}
|
|
305
|
-
next()
|
|
306
|
-
return
|
|
307
|
-
}
|
|
308
|
-
break
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
} catch { /* module not ready — continue to SSR */ }
|
|
312
|
-
try {
|
|
313
|
-
// Load the SSR entry module from .cer/entry-server.ts (written by
|
|
314
|
-
// writeGeneratedDir). The production build uses a virtual plugin for
|
|
315
|
-
// the same template; the dev server needs a real file on disk.
|
|
316
|
-
const ssrEntry = await server.ssrLoadModule(
|
|
317
|
-
join(getGeneratedDir(config.root), 'entry-server.ts'),
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
const handler =
|
|
321
|
-
ssrEntry.handler ?? ssrEntry.default?.handler
|
|
322
|
-
|
|
323
|
-
if (typeof handler === 'function') {
|
|
324
|
-
// In dev mode _clientTemplate inside entry-server.ts is null because
|
|
325
|
-
// the dist/client/index.html path doesn't exist. Set the global that
|
|
326
|
-
// the handler reads per-request so the SSR response includes the
|
|
327
|
-
// Vite client scripts (/@vite/client, HMR, module imports for app.ts).
|
|
328
|
-
const _userIndexPath = resolve(config.root, 'index.html')
|
|
329
|
-
const _genIndexPath = join(getGeneratedDir(config.root), 'index.html')
|
|
330
|
-
const _rawHtml = existsSync(_userIndexPath)
|
|
331
|
-
? readFileSync(_userIndexPath, 'utf-8')
|
|
332
|
-
: existsSync(_genIndexPath)
|
|
333
|
-
? readFileSync(_genIndexPath, 'utf-8')
|
|
334
|
-
: null
|
|
335
|
-
if (_rawHtml) {
|
|
336
|
-
;(globalThis as Record<string, unknown>).__CER_CLIENT_TEMPLATE__ =
|
|
337
|
-
await server.transformIndexHtml(url, _rawHtml)
|
|
338
|
-
}
|
|
339
|
-
try {
|
|
340
|
-
await handler(req, res)
|
|
341
|
-
} finally {
|
|
342
|
-
;(globalThis as Record<string, unknown>).__CER_CLIENT_TEMPLATE__ = undefined
|
|
343
|
-
}
|
|
344
|
-
return
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// Fallback: render using template + ssrEntry render function
|
|
348
|
-
const renderFn = ssrEntry.render ?? ssrEntry.default?.render
|
|
349
|
-
|
|
350
|
-
if (typeof renderFn === 'function') {
|
|
351
|
-
const template = await server.transformIndexHtml(
|
|
352
|
-
url,
|
|
353
|
-
`<!DOCTYPE html><html><head></head><body><div id="app"></div></body></html>`,
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
const result = await renderFn({ url, req })
|
|
357
|
-
const rendered = template.replace(
|
|
358
|
-
'<div id="app"></div>',
|
|
359
|
-
`<div id="app">${result.html ?? ''}</div>`,
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
res.setHeader('Content-Type', 'text/html; charset=utf-8')
|
|
363
|
-
res.end(rendered)
|
|
364
|
-
return
|
|
365
|
-
}
|
|
366
|
-
} catch (err) {
|
|
367
|
-
server.ssrFixStacktrace(err as Error)
|
|
368
|
-
console.error('[cer-app] SSR render error:', err)
|
|
369
|
-
res.statusCode = 500
|
|
370
|
-
res.setHeader('Content-Type', 'text/plain')
|
|
371
|
-
res.end('SSR Error: ' + String(err))
|
|
372
|
-
return
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
next()
|
|
378
|
-
})
|
|
379
|
-
}
|
|
@@ -1,273 +0,0 @@
|
|
|
1
|
-
import { writeFileSync, mkdirSync, existsSync } from 'node:fs'
|
|
2
|
-
import { readFileSync } from 'node:fs'
|
|
3
|
-
import { join, relative } from 'pathe'
|
|
4
|
-
import { scanDirectory } from './scanner.js'
|
|
5
|
-
import { GENERATED_DIR_NAME } from './generated-dir.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Writes `.cer/tsconfig.json` containing path aliases for the `~/` prefix
|
|
9
|
-
* plus include/exclude entries so the consumer's `tsconfig.json` only needs:
|
|
10
|
-
* { "extends": "./.cer/tsconfig.json" }
|
|
11
|
-
*/
|
|
12
|
-
export function writeTsconfigPaths(root: string, srcDir: string): void {
|
|
13
|
-
const cerDir = join(root, GENERATED_DIR_NAME)
|
|
14
|
-
if (!existsSync(cerDir)) {
|
|
15
|
-
mkdirSync(cerDir, { recursive: true })
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// Paths are relative to .cer/ inside the project root, so prefix with ../
|
|
19
|
-
const srcRel = '../' + relative(root, srcDir).replace(/\\/g, '/')
|
|
20
|
-
const paths: Record<string, string[]> = {
|
|
21
|
-
'~/*': [`${srcRel}/*`],
|
|
22
|
-
'~/pages/*': [`${srcRel}/pages/*`],
|
|
23
|
-
'~/layouts/*': [`${srcRel}/layouts/*`],
|
|
24
|
-
'~/components/*': [`${srcRel}/components/*`],
|
|
25
|
-
'~/composables/*': [`${srcRel}/composables/*`],
|
|
26
|
-
'~/plugins/*': [`${srcRel}/plugins/*`],
|
|
27
|
-
'~/middleware/*': [`${srcRel}/middleware/*`],
|
|
28
|
-
'~/assets/*': [`${srcRel}/assets/*`],
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const tsconfig = {
|
|
32
|
-
compilerOptions: { paths },
|
|
33
|
-
include: [
|
|
34
|
-
'../app/**/*.ts',
|
|
35
|
-
'../server/**/*.ts',
|
|
36
|
-
'./**/*.ts',
|
|
37
|
-
'./**/*.d.ts',
|
|
38
|
-
],
|
|
39
|
-
exclude: ['../node_modules', '../dist'],
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const content = JSON.stringify(tsconfig, null, 2) + '\n'
|
|
43
|
-
const tsconfigPath = join(cerDir, 'tsconfig.json')
|
|
44
|
-
// Skip write when content is unchanged to avoid triggering Vite's tsconfig
|
|
45
|
-
// watcher, which would cause an unnecessary server restart on every dev start.
|
|
46
|
-
try {
|
|
47
|
-
if (existsSync(tsconfigPath) && readFileSync(tsconfigPath, 'utf-8') === content) return
|
|
48
|
-
} catch { /* proceed to write */ }
|
|
49
|
-
writeFileSync(tsconfigPath, content, 'utf-8')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const RUNTIME_GLOBALS = [
|
|
53
|
-
'component',
|
|
54
|
-
'html',
|
|
55
|
-
'css',
|
|
56
|
-
'ref',
|
|
57
|
-
'computed',
|
|
58
|
-
'watch',
|
|
59
|
-
'watchEffect',
|
|
60
|
-
'useProps',
|
|
61
|
-
'useEmit',
|
|
62
|
-
'useOnConnected',
|
|
63
|
-
'useOnDisconnected',
|
|
64
|
-
'useOnAttributeChanged',
|
|
65
|
-
'useOnError',
|
|
66
|
-
'useStyle',
|
|
67
|
-
'useDesignTokens',
|
|
68
|
-
'useGlobalStyle',
|
|
69
|
-
'useExpose',
|
|
70
|
-
'useSlots',
|
|
71
|
-
'provide',
|
|
72
|
-
'inject',
|
|
73
|
-
'createComposable',
|
|
74
|
-
'nextTick',
|
|
75
|
-
'defineModel',
|
|
76
|
-
'getCurrentComponentContext',
|
|
77
|
-
'isReactiveState',
|
|
78
|
-
'unsafeHTML',
|
|
79
|
-
'decodeEntities',
|
|
80
|
-
'useTeleport',
|
|
81
|
-
]
|
|
82
|
-
|
|
83
|
-
const DIRECTIVE_GLOBALS = ['when', 'each', 'match', 'anchorBlock']
|
|
84
|
-
|
|
85
|
-
const FRAMEWORK_GLOBALS = ['useHead', 'usePageData', 'useInject', 'useRuntimeConfig', 'defineMiddleware', 'defineServerMiddleware', 'useSeoMeta', 'useCookie', 'useSession', 'useAuth', 'useFetch', 'useRoute', 'navigateTo', 'useState', 'useLocale', 'queryContent', 'useContentSearch']
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Scans a composables directory and returns a map of export name → file path.
|
|
89
|
-
* Uses a simple regex to find exported identifiers.
|
|
90
|
-
*/
|
|
91
|
-
export async function scanComposableExports(composablesDir: string): Promise<Map<string, string>> {
|
|
92
|
-
const result = new Map<string, string>()
|
|
93
|
-
if (!existsSync(composablesDir)) return result
|
|
94
|
-
|
|
95
|
-
const files = await scanDirectory('**/*.ts', composablesDir)
|
|
96
|
-
const exportPattern = /export\s+(?:async\s+)?(?:function|const|let|var|class)\s+(\w+)/g
|
|
97
|
-
|
|
98
|
-
for (const file of files) {
|
|
99
|
-
const code = readFileSync(file, 'utf-8')
|
|
100
|
-
exportPattern.lastIndex = 0
|
|
101
|
-
let match
|
|
102
|
-
while ((match = exportPattern.exec(code)) !== null) {
|
|
103
|
-
result.set(match[1], file)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return result
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Generates the content of `cer-auto-imports.d.ts`.
|
|
112
|
-
* @param root - project root (where the .d.ts file will be written)
|
|
113
|
-
*/
|
|
114
|
-
export async function generateAutoImportDts(
|
|
115
|
-
root: string,
|
|
116
|
-
composablesDir: string,
|
|
117
|
-
composableExports?: Map<string, string>,
|
|
118
|
-
): Promise<string> {
|
|
119
|
-
const exports = composableExports ?? await scanComposableExports(composablesDir)
|
|
120
|
-
|
|
121
|
-
const lines: string[] = [
|
|
122
|
-
'// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app',
|
|
123
|
-
'// Do not edit — regenerated automatically on dev server start and build.',
|
|
124
|
-
'',
|
|
125
|
-
'export {}',
|
|
126
|
-
'',
|
|
127
|
-
'declare global {',
|
|
128
|
-
]
|
|
129
|
-
|
|
130
|
-
for (const name of RUNTIME_GLOBALS) {
|
|
131
|
-
lines.push(` const ${name}: typeof import('@jasonshimmy/custom-elements-runtime')['${name}']`)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
lines.push('')
|
|
135
|
-
|
|
136
|
-
for (const name of DIRECTIVE_GLOBALS) {
|
|
137
|
-
lines.push(` const ${name}: typeof import('@jasonshimmy/custom-elements-runtime/directives')['${name}']`)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
lines.push('')
|
|
141
|
-
|
|
142
|
-
for (const name of FRAMEWORK_GLOBALS) {
|
|
143
|
-
lines.push(` const ${name}: typeof import('@jasonshimmy/vite-plugin-cer-app/composables')['${name}']`)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (exports.size > 0) {
|
|
147
|
-
lines.push('')
|
|
148
|
-
for (const [name, filePath] of exports) {
|
|
149
|
-
// Use a path relative to .cer/ (one level up from root) so the .d.ts resolves correctly
|
|
150
|
-
const rel = '../' + relative(root, filePath).replace(/\.ts$/, '')
|
|
151
|
-
lines.push(` const ${name}: typeof import('${rel}')['${name}']`)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
lines.push('')
|
|
156
|
-
lines.push(' // Content layer types')
|
|
157
|
-
lines.push(` type ContentMeta = import('@jasonshimmy/vite-plugin-cer-app').ContentMeta`)
|
|
158
|
-
lines.push(` type ContentItem = import('@jasonshimmy/vite-plugin-cer-app').ContentItem`)
|
|
159
|
-
lines.push(` type ContentHeading = import('@jasonshimmy/vite-plugin-cer-app').ContentHeading`)
|
|
160
|
-
lines.push(` type ContentSearchResult = import('@jasonshimmy/vite-plugin-cer-app').ContentSearchResult`)
|
|
161
|
-
lines.push('')
|
|
162
|
-
lines.push(' // SSR loader data injected as window.__CER_DATA__ by the server.')
|
|
163
|
-
lines.push(' // Consumed once by usePageData() during client hydration.')
|
|
164
|
-
lines.push(' // eslint-disable-next-line @typescript-eslint/no-explicit-any')
|
|
165
|
-
lines.push(' var __CER_DATA__: any')
|
|
166
|
-
lines.push(' // SSR useState() values injected as window.__CER_STATE_INIT__ by the server.')
|
|
167
|
-
lines.push(' // Pre-populates the client useState() Map on first use.')
|
|
168
|
-
lines.push(' // eslint-disable-next-line @typescript-eslint/no-explicit-any')
|
|
169
|
-
lines.push(' var __CER_STATE_INIT__: any')
|
|
170
|
-
lines.push(' // App config injected by virtual:cer-app-config at app bootstrap.')
|
|
171
|
-
lines.push(' // eslint-disable-next-line @typescript-eslint/no-explicit-any')
|
|
172
|
-
lines.push(' var __CER_APP_CONFIG__: any')
|
|
173
|
-
lines.push('}')
|
|
174
|
-
lines.push('')
|
|
175
|
-
|
|
176
|
-
return lines.join('\n')
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Generates the content of `cer-env.d.ts` — a script (non-module) file
|
|
181
|
-
* containing ambient `declare module` declarations for all virtual modules.
|
|
182
|
-
* Must NOT contain `export {}` or any top-level imports/exports.
|
|
183
|
-
*/
|
|
184
|
-
export async function generateVirtualModuleDts(
|
|
185
|
-
root: string,
|
|
186
|
-
composablesDir: string,
|
|
187
|
-
composableExports?: Map<string, string>,
|
|
188
|
-
): Promise<string> {
|
|
189
|
-
const exports = composableExports ?? await scanComposableExports(composablesDir)
|
|
190
|
-
|
|
191
|
-
const lines: string[] = [
|
|
192
|
-
'// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app',
|
|
193
|
-
'// Do not edit — regenerated automatically on dev server start and build.',
|
|
194
|
-
'',
|
|
195
|
-
`declare module 'virtual:cer-routes' {`,
|
|
196
|
-
` import type { Route } from '@jasonshimmy/custom-elements-runtime/router'`,
|
|
197
|
-
` const routes: Route[]`,
|
|
198
|
-
` export default routes`,
|
|
199
|
-
`}`,
|
|
200
|
-
'',
|
|
201
|
-
`declare module 'virtual:cer-layouts' {}`,
|
|
202
|
-
'',
|
|
203
|
-
`declare module 'virtual:cer-plugins' {`,
|
|
204
|
-
` import type { AppPlugin } from '@jasonshimmy/vite-plugin-cer-app/types'`,
|
|
205
|
-
` const plugins: AppPlugin[]`,
|
|
206
|
-
` export default plugins`,
|
|
207
|
-
`}`,
|
|
208
|
-
'',
|
|
209
|
-
`declare module 'virtual:cer-composables' {`,
|
|
210
|
-
]
|
|
211
|
-
|
|
212
|
-
for (const [name, filePath] of exports) {
|
|
213
|
-
const rel = '../' + relative(root, filePath).replace(/\.ts$/, '')
|
|
214
|
-
lines.push(` export { ${name} } from '${rel}'`)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
lines.push(`}`)
|
|
218
|
-
lines.push('')
|
|
219
|
-
lines.push(`declare module 'virtual:cer-middleware' {`)
|
|
220
|
-
lines.push(` const middleware: Record<string, Function>`)
|
|
221
|
-
lines.push(` export { middleware }`)
|
|
222
|
-
lines.push(`}`)
|
|
223
|
-
lines.push('')
|
|
224
|
-
lines.push(`declare module 'virtual:cer-server-middleware' {`)
|
|
225
|
-
lines.push(` import type { ServerMiddleware } from '@jasonshimmy/vite-plugin-cer-app/types'`)
|
|
226
|
-
lines.push(` export const serverMiddleware: Array<{ name: string; handler: ServerMiddleware }>`)
|
|
227
|
-
lines.push(` export default serverMiddleware`)
|
|
228
|
-
lines.push(`}`)
|
|
229
|
-
lines.push('')
|
|
230
|
-
lines.push(`declare module 'virtual:cer-loading' {`)
|
|
231
|
-
lines.push(` export const hasLoading: boolean`)
|
|
232
|
-
lines.push(` export const loadingTag: string | null`)
|
|
233
|
-
lines.push(`}`)
|
|
234
|
-
lines.push('')
|
|
235
|
-
lines.push(`declare module 'virtual:cer-error' {`)
|
|
236
|
-
lines.push(` export const hasError: boolean`)
|
|
237
|
-
lines.push(` export const errorTag: string | null`)
|
|
238
|
-
lines.push(`}`)
|
|
239
|
-
lines.push('')
|
|
240
|
-
lines.push(`declare module 'virtual:cer-app-config' {`)
|
|
241
|
-
lines.push(` import type { RuntimePublicConfig, RuntimePrivateConfig } from '@jasonshimmy/vite-plugin-cer-app/types'`)
|
|
242
|
-
lines.push(` export const appConfig: { mode: string; router: Record<string, unknown>; ssg: Record<string, unknown> }`)
|
|
243
|
-
lines.push(` export const runtimeConfig: { public: RuntimePublicConfig }`)
|
|
244
|
-
lines.push(` /** Server-only — present only in the SSR bundle. Always \`undefined\` in the client bundle. */`)
|
|
245
|
-
lines.push(` export const _runtimePrivateDefaults: RuntimePrivateConfig | undefined`)
|
|
246
|
-
lines.push(` /** Cookie/session key for the auth session. Derived from the app name. */`)
|
|
247
|
-
lines.push(` export const _authSessionKey: string`)
|
|
248
|
-
lines.push(` export default appConfig`)
|
|
249
|
-
lines.push(`}`)
|
|
250
|
-
lines.push('')
|
|
251
|
-
|
|
252
|
-
return lines.join('\n')
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* Writes `auto-imports.d.ts` and `env.d.ts` to `.cer/` inside the project root.
|
|
257
|
-
*/
|
|
258
|
-
export async function writeAutoImportDts(
|
|
259
|
-
root: string,
|
|
260
|
-
composablesDir: string,
|
|
261
|
-
composableExports?: Map<string, string>,
|
|
262
|
-
): Promise<void> {
|
|
263
|
-
const cerDir = join(root, GENERATED_DIR_NAME)
|
|
264
|
-
if (!existsSync(cerDir)) {
|
|
265
|
-
mkdirSync(cerDir, { recursive: true })
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const scanned = composableExports ?? await scanComposableExports(composablesDir)
|
|
269
|
-
const autoImportsContent = await generateAutoImportDts(root, composablesDir, scanned)
|
|
270
|
-
const envContent = await generateVirtualModuleDts(root, composablesDir, scanned)
|
|
271
|
-
writeFileSync(join(cerDir, 'auto-imports.d.ts'), autoImportsContent, 'utf-8')
|
|
272
|
-
writeFileSync(join(cerDir, 'env.d.ts'), envContent, 'utf-8')
|
|
273
|
-
}
|