@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
|
@@ -1,552 +0,0 @@
|
|
|
1
|
-
import { vi, describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
-
|
|
3
|
-
vi.mock('@jasonshimmy/custom-elements-runtime/vite-plugin', () => ({
|
|
4
|
-
cerPlugin: vi.fn().mockReturnValue([{ name: 'cer-runtime-plugin' }]),
|
|
5
|
-
cerComponentImports: vi.fn().mockReturnValue({ name: 'cer-component-imports' }),
|
|
6
|
-
}))
|
|
7
|
-
vi.mock('node:fs', async (importOriginal) => {
|
|
8
|
-
const actual = await importOriginal<typeof import('node:fs')>()
|
|
9
|
-
return { ...actual, existsSync: vi.fn().mockReturnValue(true), readFileSync: vi.fn().mockReturnValue('') }
|
|
10
|
-
})
|
|
11
|
-
vi.mock('../../plugin/dev-server.js', () => ({
|
|
12
|
-
configureCerDevServer: vi.fn().mockResolvedValue(undefined),
|
|
13
|
-
}))
|
|
14
|
-
vi.mock('../../plugin/scanner.js', () => ({
|
|
15
|
-
createWatcher: vi.fn().mockReturnValue({ on: vi.fn(), close: vi.fn() }),
|
|
16
|
-
scanDirectory: vi.fn().mockResolvedValue([]),
|
|
17
|
-
}))
|
|
18
|
-
vi.mock('../../plugin/dts-generator.js', () => ({
|
|
19
|
-
scanComposableExports: vi.fn().mockResolvedValue(new Map()),
|
|
20
|
-
writeAutoImportDts: vi.fn().mockResolvedValue(undefined),
|
|
21
|
-
writeTsconfigPaths: vi.fn(),
|
|
22
|
-
}))
|
|
23
|
-
vi.mock('../../plugin/generated-dir.js', () => ({
|
|
24
|
-
writeGeneratedDir: vi.fn(),
|
|
25
|
-
getGeneratedDir: vi.fn().mockReturnValue('/project/.cer'),
|
|
26
|
-
GENERATED_DIR_NAME: '.cer',
|
|
27
|
-
}))
|
|
28
|
-
vi.mock('../../plugin/virtual/routes.js', () => ({ generateRoutesCode: vi.fn().mockResolvedValue('// routes') }))
|
|
29
|
-
vi.mock('../../plugin/virtual/layouts.js', () => ({ generateLayoutsCode: vi.fn().mockResolvedValue('// layouts') }))
|
|
30
|
-
vi.mock('../../plugin/virtual/composables.js', () => ({ generateComposablesCode: vi.fn().mockResolvedValue('// composables') }))
|
|
31
|
-
vi.mock('../../plugin/virtual/plugins.js', () => ({ generatePluginsCode: vi.fn().mockResolvedValue('// plugins') }))
|
|
32
|
-
vi.mock('../../plugin/virtual/middleware.js', () => ({ generateMiddlewareCode: vi.fn().mockResolvedValue('// middleware') }))
|
|
33
|
-
vi.mock('../../plugin/virtual/server-api.js', () => ({ generateServerApiCode: vi.fn().mockResolvedValue('// server-api') }))
|
|
34
|
-
vi.mock('../../plugin/virtual/server-middleware.js', () => ({ generateServerMiddlewareCode: vi.fn().mockResolvedValue('// server-middleware') }))
|
|
35
|
-
vi.mock('../../plugin/virtual/loading.js', () => ({ generateLoadingCode: vi.fn().mockResolvedValue('// loading') }))
|
|
36
|
-
vi.mock('../../plugin/virtual/error.js', () => ({ generateErrorCode: vi.fn().mockResolvedValue('// error') }))
|
|
37
|
-
vi.mock('../../plugin/virtual/content-components.js', () => ({ generateContentComponentsCode: vi.fn().mockResolvedValue('// content-components') }))
|
|
38
|
-
vi.mock('../../plugin/transforms/auto-import.js', () => ({ autoImportTransform: vi.fn().mockReturnValue(null) }))
|
|
39
|
-
|
|
40
|
-
import { cerApp } from '../../plugin/index.js'
|
|
41
|
-
import { generateAppEntryTemplate } from '../../runtime/app-template.js'
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
type TestPlugin = {
|
|
45
|
-
name: string
|
|
46
|
-
config: (viteConfig: Record<string, unknown>, env: Record<string, unknown>) => unknown
|
|
47
|
-
configResolved: (resolved: Record<string, unknown>) => void
|
|
48
|
-
resolveId: (id: string) => string | undefined
|
|
49
|
-
load: (id: string, options?: { ssr?: boolean }) => Promise<string | null>
|
|
50
|
-
transform: (code: string, id: string) => unknown
|
|
51
|
-
transformIndexHtml: (html: string) => string
|
|
52
|
-
buildStart: () => Promise<void>
|
|
53
|
-
configureServer: (server: unknown) => Promise<void>
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Helper to get the cerAppPlugin (first plugin in the returned array)
|
|
57
|
-
function getCerPlugin(userConfig = {}): TestPlugin {
|
|
58
|
-
return cerApp(userConfig)[0] as unknown as TestPlugin
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Minimal resolved config that mirrors what Vite passes to configResolved
|
|
62
|
-
const FAKE_RESOLVED = { root: '/project' }
|
|
63
|
-
|
|
64
|
-
describe('cerApp()', () => {
|
|
65
|
-
it('returns an array of plugins', () => {
|
|
66
|
-
const plugins = cerApp()
|
|
67
|
-
expect(Array.isArray(plugins)).toBe(true)
|
|
68
|
-
expect(plugins.length).toBeGreaterThan(0)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it('first plugin is named @jasonshimmy/vite-plugin-cer-app', () => {
|
|
72
|
-
const plugin = getCerPlugin()
|
|
73
|
-
expect(plugin.name).toBe('@jasonshimmy/vite-plugin-cer-app')
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('includes cerComponentImports plugin when autoImports.components is unset', () => {
|
|
77
|
-
const plugins = cerApp()
|
|
78
|
-
const names = plugins.map((p) => (p as { name: string }).name)
|
|
79
|
-
expect(names).toContain('cer-component-imports')
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it('includes cerComponentImports plugin when autoImports.components is true', () => {
|
|
83
|
-
const plugins = cerApp({ autoImports: { components: true } })
|
|
84
|
-
const names = plugins.map((p) => (p as { name: string }).name)
|
|
85
|
-
expect(names).toContain('cer-component-imports')
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('excludes cerComponentImports plugin when autoImports.components is false', () => {
|
|
89
|
-
const plugins = cerApp({ autoImports: { components: false } })
|
|
90
|
-
const names = plugins.map((p) => (p as { name: string }).name)
|
|
91
|
-
expect(names).not.toContain('cer-component-imports')
|
|
92
|
-
})
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
describe('cerApp plugin — config hook', () => {
|
|
96
|
-
it('returns build.target: esnext', () => {
|
|
97
|
-
const plugin = getCerPlugin()
|
|
98
|
-
const result = plugin.config({ root: '/project' }, { command: 'build', mode: 'production' }) as Record<string, unknown>
|
|
99
|
-
expect((result.build as Record<string, unknown>).target).toBe('esnext')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('config hook resolves the root', () => {
|
|
103
|
-
const plugin = getCerPlugin()
|
|
104
|
-
const result = plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
105
|
-
expect(result).toBeDefined()
|
|
106
|
-
})
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
describe('cerApp plugin — configResolved hook', () => {
|
|
110
|
-
it('does not throw when called', () => {
|
|
111
|
-
const plugin = getCerPlugin()
|
|
112
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
113
|
-
expect(() => plugin.configResolved(FAKE_RESOLVED)).not.toThrow()
|
|
114
|
-
})
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
describe('cerApp plugin — resolveId hook', () => {
|
|
118
|
-
beforeEach(() => {
|
|
119
|
-
const plugin = getCerPlugin()
|
|
120
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
121
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('resolves virtual:cer-routes to \\0virtual:cer-routes', () => {
|
|
125
|
-
const plugin = getCerPlugin()
|
|
126
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
127
|
-
expect(plugin.resolveId('virtual:cer-routes')).toBe('\0virtual:cer-routes')
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('resolves virtual:cer-layouts', () => {
|
|
131
|
-
const plugin = getCerPlugin()
|
|
132
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
133
|
-
expect(plugin.resolveId('virtual:cer-layouts')).toBe('\0virtual:cer-layouts')
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it('resolves virtual:cer-plugins', () => {
|
|
137
|
-
const plugin = getCerPlugin()
|
|
138
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
139
|
-
expect(plugin.resolveId('virtual:cer-plugins')).toBe('\0virtual:cer-plugins')
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('resolves virtual:cer-server-api', () => {
|
|
143
|
-
const plugin = getCerPlugin()
|
|
144
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
145
|
-
expect(plugin.resolveId('virtual:cer-server-api')).toBe('\0virtual:cer-server-api')
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('resolves virtual:cer-loading', () => {
|
|
149
|
-
const plugin = getCerPlugin()
|
|
150
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
151
|
-
expect(plugin.resolveId('virtual:cer-loading')).toBe('\0virtual:cer-loading')
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
it('resolves virtual:cer-error', () => {
|
|
155
|
-
const plugin = getCerPlugin()
|
|
156
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
157
|
-
expect(plugin.resolveId('virtual:cer-error')).toBe('\0virtual:cer-error')
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
it('resolves /@cer/app.ts to \\0cer-app-entry (virtual module)', () => {
|
|
161
|
-
const plugin = getCerPlugin()
|
|
162
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
163
|
-
expect(plugin.resolveId('/@cer/app.ts')).toBe('\0cer-app-entry')
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
it('does not resolve /.cer/app.ts (old URL, rewritten by transformIndexHtml)', () => {
|
|
167
|
-
const plugin = getCerPlugin()
|
|
168
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
169
|
-
expect(plugin.resolveId('/.cer/app.ts')).toBeUndefined()
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
it('returns undefined for unknown ids', () => {
|
|
173
|
-
const plugin = getCerPlugin()
|
|
174
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
175
|
-
expect(plugin.resolveId('some-unknown-id')).toBeUndefined()
|
|
176
|
-
})
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
describe('cerApp plugin — load hook', () => {
|
|
180
|
-
it('loads \\0cer-app-entry with generated app entry content', async () => {
|
|
181
|
-
const plugin = getCerPlugin()
|
|
182
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
183
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
184
|
-
const result = await plugin.load('\0cer-app-entry')
|
|
185
|
-
expect(result).toBe(generateAppEntryTemplate())
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
it('returns null for unknown resolved ids', async () => {
|
|
189
|
-
const plugin = getCerPlugin()
|
|
190
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
191
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
192
|
-
const result = await plugin.load('\0unknown-module')
|
|
193
|
-
expect(result).toBeNull()
|
|
194
|
-
})
|
|
195
|
-
|
|
196
|
-
it('loads virtual:cer-routes module code', async () => {
|
|
197
|
-
const plugin = getCerPlugin()
|
|
198
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
199
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
200
|
-
const result = await plugin.load('\0virtual:cer-routes')
|
|
201
|
-
expect(result).toBe('// routes')
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
it('loads virtual:cer-layouts module code', async () => {
|
|
205
|
-
const plugin = getCerPlugin()
|
|
206
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
207
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
208
|
-
const result = await plugin.load('\0virtual:cer-layouts')
|
|
209
|
-
expect(result).toBe('// layouts')
|
|
210
|
-
})
|
|
211
|
-
|
|
212
|
-
it('loads virtual:cer-loading module code', async () => {
|
|
213
|
-
const plugin = getCerPlugin()
|
|
214
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
215
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
216
|
-
const result = await plugin.load('\0virtual:cer-loading')
|
|
217
|
-
expect(result).toBe('// loading')
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
it('loads virtual:cer-error module code', async () => {
|
|
221
|
-
const plugin = getCerPlugin()
|
|
222
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
223
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
224
|
-
const result = await plugin.load('\0virtual:cer-error')
|
|
225
|
-
expect(result).toBe('// error')
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
it('returns cached code on repeated load calls', async () => {
|
|
229
|
-
const { generateRoutesCode } = await import('../../plugin/virtual/routes.js')
|
|
230
|
-
vi.mocked(generateRoutesCode).mockClear()
|
|
231
|
-
|
|
232
|
-
// Use a SINGLE plugin instance so the module cache persists across calls
|
|
233
|
-
const plugin = getCerPlugin()
|
|
234
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
235
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
236
|
-
|
|
237
|
-
const first = await plugin.load('\0virtual:cer-routes')
|
|
238
|
-
const second = await plugin.load('\0virtual:cer-routes')
|
|
239
|
-
|
|
240
|
-
expect(first).toBe(second)
|
|
241
|
-
// generateRoutesCode should only be called once (cache hit on second call)
|
|
242
|
-
expect(generateRoutesCode).toHaveBeenCalledTimes(1)
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it('loads virtual:cer-app-config and exports appConfig', async () => {
|
|
246
|
-
const plugin = getCerPlugin({ mode: 'ssg' })
|
|
247
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
248
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
249
|
-
const result = await plugin.load('\0virtual:cer-app-config') as string
|
|
250
|
-
expect(result).toContain('appConfig')
|
|
251
|
-
expect(result).toContain('ssg')
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
it('excludes _runtimePrivateDefaults from the client bundle', async () => {
|
|
255
|
-
const plugin = getCerPlugin({ runtimeConfig: { private: { dbUrl: '', secretKey: '' } } })
|
|
256
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
257
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
258
|
-
// Client load (ssr: false / omitted)
|
|
259
|
-
const clientResult = await plugin.load('\0virtual:cer-app-config') as string
|
|
260
|
-
expect(clientResult).not.toContain('_runtimePrivateDefaults')
|
|
261
|
-
expect(clientResult).not.toContain('dbUrl')
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
it('includes _runtimePrivateDefaults in the SSR bundle', async () => {
|
|
265
|
-
const plugin = getCerPlugin({ runtimeConfig: { private: { dbUrl: '', secretKey: '' } } })
|
|
266
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
267
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
268
|
-
// SSR load (ssr: true)
|
|
269
|
-
const ssrResult = await plugin.load('\0virtual:cer-app-config', { ssr: true }) as string
|
|
270
|
-
expect(ssrResult).toContain('_runtimePrivateDefaults')
|
|
271
|
-
expect(ssrResult).toContain('dbUrl')
|
|
272
|
-
})
|
|
273
|
-
|
|
274
|
-
it('caches SSR and client virtual:cer-app-config separately', async () => {
|
|
275
|
-
const plugin = getCerPlugin({ runtimeConfig: { private: { token: '' } } })
|
|
276
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
277
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
278
|
-
const client = await plugin.load('\0virtual:cer-app-config') as string
|
|
279
|
-
const ssr = await plugin.load('\0virtual:cer-app-config', { ssr: true }) as string
|
|
280
|
-
expect(client).not.toContain('_runtimePrivateDefaults')
|
|
281
|
-
expect(ssr).toContain('_runtimePrivateDefaults')
|
|
282
|
-
})
|
|
283
|
-
})
|
|
284
|
-
|
|
285
|
-
describe('cerApp plugin — transform hook', () => {
|
|
286
|
-
it('returns null for virtual module ids', async () => {
|
|
287
|
-
const plugin = getCerPlugin()
|
|
288
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
289
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
290
|
-
const result = plugin.transform('// code', '\0virtual:cer-routes')
|
|
291
|
-
expect(result).toBeNull()
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
it('calls autoImportTransform for regular files', async () => {
|
|
295
|
-
const { autoImportTransform } = await import('../../plugin/transforms/auto-import.js')
|
|
296
|
-
const plugin = getCerPlugin()
|
|
297
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
298
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
299
|
-
|
|
300
|
-
plugin.transform('const x = 1', '/project/app/pages/index.ts')
|
|
301
|
-
expect(autoImportTransform).toHaveBeenCalled()
|
|
302
|
-
})
|
|
303
|
-
|
|
304
|
-
it('returns null when autoImportTransform returns null', async () => {
|
|
305
|
-
const plugin = getCerPlugin()
|
|
306
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
307
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
308
|
-
const result = plugin.transform('const x = 1', '/project/app/pages/index.ts')
|
|
309
|
-
expect(result).toBeNull()
|
|
310
|
-
})
|
|
311
|
-
|
|
312
|
-
it('returns { code, map } when autoImportTransform returns a string', async () => {
|
|
313
|
-
const { autoImportTransform } = await import('../../plugin/transforms/auto-import.js')
|
|
314
|
-
vi.mocked(autoImportTransform).mockReturnValueOnce('transformed code')
|
|
315
|
-
const plugin = getCerPlugin()
|
|
316
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
317
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
318
|
-
const result = plugin.transform('const x = 1', '/project/app/pages/index.ts') as { code: string; map: null }
|
|
319
|
-
expect(result).toEqual({ code: 'transformed code', map: null })
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
it('returns null when autoImports.runtime is false', async () => {
|
|
323
|
-
const plugin = getCerPlugin({ autoImports: { runtime: false } })
|
|
324
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
325
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
326
|
-
const result = plugin.transform('const x = 1', '/project/app/pages/index.ts')
|
|
327
|
-
expect(result).toBeNull()
|
|
328
|
-
})
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
describe('cerApp plugin — transformIndexHtml hook', () => {
|
|
332
|
-
it('rewrites /.cer/app.ts src to /@cer/app.ts', () => {
|
|
333
|
-
const plugin = getCerPlugin()
|
|
334
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
335
|
-
const input = '<script type="module" src="/.cer/app.ts"></script>'
|
|
336
|
-
const output = plugin.transformIndexHtml(input)
|
|
337
|
-
expect(output).toContain('src="/@cer/app.ts"')
|
|
338
|
-
expect(output).not.toContain('src="/.cer/app.ts"')
|
|
339
|
-
})
|
|
340
|
-
|
|
341
|
-
it('leaves html unchanged when /.cer/app.ts is not present', () => {
|
|
342
|
-
const plugin = getCerPlugin()
|
|
343
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
344
|
-
const input = '<script type="module" src="/@cer/app.ts"></script>'
|
|
345
|
-
expect(plugin.transformIndexHtml(input)).toBe(input)
|
|
346
|
-
})
|
|
347
|
-
})
|
|
348
|
-
|
|
349
|
-
describe('cerApp plugin — configResolved hook', () => {
|
|
350
|
-
it('calls writeGeneratedDir during configResolved', async () => {
|
|
351
|
-
const { writeGeneratedDir } = await import('../../plugin/generated-dir.js')
|
|
352
|
-
vi.mocked(writeGeneratedDir).mockClear()
|
|
353
|
-
const plugin = getCerPlugin()
|
|
354
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
355
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
356
|
-
expect(writeGeneratedDir).toHaveBeenCalledTimes(1)
|
|
357
|
-
})
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
describe('cerApp plugin — buildStart hook', () => {
|
|
361
|
-
it('calls writeGeneratedDir on build start', async () => {
|
|
362
|
-
const { writeGeneratedDir } = await import('../../plugin/generated-dir.js')
|
|
363
|
-
vi.mocked(writeGeneratedDir).mockClear()
|
|
364
|
-
const plugin = getCerPlugin()
|
|
365
|
-
plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
|
|
366
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
367
|
-
await plugin.buildStart()
|
|
368
|
-
// writeGeneratedDir is called once in configResolved and once in buildStart
|
|
369
|
-
expect(writeGeneratedDir).toHaveBeenCalledTimes(2)
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
it('calls scanComposableExports on build start', async () => {
|
|
373
|
-
const { scanComposableExports } = await import('../../plugin/dts-generator.js')
|
|
374
|
-
vi.mocked(scanComposableExports).mockClear()
|
|
375
|
-
const plugin = getCerPlugin()
|
|
376
|
-
plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
|
|
377
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
378
|
-
await plugin.buildStart()
|
|
379
|
-
expect(scanComposableExports).toHaveBeenCalledTimes(1)
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
it('calls writeAutoImportDts on build start', async () => {
|
|
383
|
-
const { writeAutoImportDts } = await import('../../plugin/dts-generator.js')
|
|
384
|
-
vi.mocked(writeAutoImportDts).mockClear()
|
|
385
|
-
const plugin = getCerPlugin()
|
|
386
|
-
plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
|
|
387
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
388
|
-
await plugin.buildStart()
|
|
389
|
-
expect(writeAutoImportDts).toHaveBeenCalledTimes(1)
|
|
390
|
-
})
|
|
391
|
-
|
|
392
|
-
it('calls writeTsconfigPaths on build start', async () => {
|
|
393
|
-
const { writeTsconfigPaths } = await import('../../plugin/dts-generator.js')
|
|
394
|
-
vi.mocked(writeTsconfigPaths).mockClear()
|
|
395
|
-
const plugin = getCerPlugin()
|
|
396
|
-
plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
|
|
397
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
398
|
-
await plugin.buildStart()
|
|
399
|
-
expect(writeTsconfigPaths).toHaveBeenCalledTimes(1)
|
|
400
|
-
})
|
|
401
|
-
|
|
402
|
-
it('warms virtual:cer-app-config cache under :client key so load() hits it', async () => {
|
|
403
|
-
// After buildStart(), a subsequent client load (ssr: false) should be served
|
|
404
|
-
// from cache (generateAppConfigModule is not a public mock, so we verify by
|
|
405
|
-
// ensuring the load hook returns a non-null result without triggering the
|
|
406
|
-
// real generator — which is mocked at module level to a fixed string '// mock'
|
|
407
|
-
// for other modules; appConfig is not mocked, so it generates real code).
|
|
408
|
-
const plugin = getCerPlugin({ runtimeConfig: { private: { token: '' } } })
|
|
409
|
-
plugin.config({ root: '/project' }, { command: 'build', mode: 'production' })
|
|
410
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
411
|
-
await plugin.buildStart()
|
|
412
|
-
|
|
413
|
-
// Client load should return a result that does NOT include _runtimePrivateDefaults
|
|
414
|
-
const result = await plugin.load('\0virtual:cer-app-config') as string
|
|
415
|
-
expect(result).not.toContain('_runtimePrivateDefaults')
|
|
416
|
-
|
|
417
|
-
// SSR load (different cache key) should include _runtimePrivateDefaults
|
|
418
|
-
const ssrResult = await plugin.load('\0virtual:cer-app-config', { ssr: true }) as string
|
|
419
|
-
expect(ssrResult).toContain('_runtimePrivateDefaults')
|
|
420
|
-
})
|
|
421
|
-
})
|
|
422
|
-
|
|
423
|
-
describe('cerApp plugin — configureServer hook', () => {
|
|
424
|
-
it('calls writeGeneratedDir on server configure', async () => {
|
|
425
|
-
const { writeGeneratedDir } = await import('../../plugin/generated-dir.js')
|
|
426
|
-
vi.mocked(writeGeneratedDir).mockClear()
|
|
427
|
-
const plugin = getCerPlugin()
|
|
428
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
429
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
430
|
-
const mockServer = {
|
|
431
|
-
watcher: { on: vi.fn() },
|
|
432
|
-
moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
|
|
433
|
-
ws: { send: vi.fn() },
|
|
434
|
-
middlewares: { use: vi.fn() },
|
|
435
|
-
}
|
|
436
|
-
await plugin.configureServer(mockServer)
|
|
437
|
-
// configResolved calls it once, configureServer calls it again
|
|
438
|
-
expect(writeGeneratedDir).toHaveBeenCalledTimes(2)
|
|
439
|
-
})
|
|
440
|
-
|
|
441
|
-
it('calls scanComposableExports on server configure', async () => {
|
|
442
|
-
const { scanComposableExports } = await import('../../plugin/dts-generator.js')
|
|
443
|
-
vi.mocked(scanComposableExports).mockClear()
|
|
444
|
-
const plugin = getCerPlugin()
|
|
445
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
446
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
447
|
-
|
|
448
|
-
const mockServer = {
|
|
449
|
-
watcher: { on: vi.fn() },
|
|
450
|
-
moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
|
|
451
|
-
ws: { send: vi.fn() },
|
|
452
|
-
}
|
|
453
|
-
await plugin.configureServer(mockServer)
|
|
454
|
-
expect(scanComposableExports).toHaveBeenCalled()
|
|
455
|
-
})
|
|
456
|
-
|
|
457
|
-
it('calls configureCerDevServer on server configure', async () => {
|
|
458
|
-
const { configureCerDevServer } = await import('../../plugin/dev-server.js')
|
|
459
|
-
vi.mocked(configureCerDevServer).mockClear()
|
|
460
|
-
const plugin = getCerPlugin()
|
|
461
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
462
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
463
|
-
|
|
464
|
-
const mockServer = {
|
|
465
|
-
watcher: { on: vi.fn() },
|
|
466
|
-
moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
|
|
467
|
-
ws: { send: vi.fn() },
|
|
468
|
-
}
|
|
469
|
-
await plugin.configureServer(mockServer)
|
|
470
|
-
expect(configureCerDevServer).toHaveBeenCalled()
|
|
471
|
-
})
|
|
472
|
-
|
|
473
|
-
it('invokes the file-change watcher callback on add event', async () => {
|
|
474
|
-
const { createWatcher } = await import('../../plugin/scanner.js')
|
|
475
|
-
const { scanComposableExports } = await import('../../plugin/dts-generator.js')
|
|
476
|
-
vi.mocked(scanComposableExports).mockClear()
|
|
477
|
-
|
|
478
|
-
let capturedCallback: ((event: string, file: string) => void) | null = null
|
|
479
|
-
vi.mocked(createWatcher).mockImplementationOnce((_watcher, _dirs, cb) => {
|
|
480
|
-
capturedCallback = cb
|
|
481
|
-
return { on: vi.fn(), close: vi.fn() } as unknown as ReturnType<typeof createWatcher>
|
|
482
|
-
})
|
|
483
|
-
|
|
484
|
-
const plugin = getCerPlugin()
|
|
485
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
486
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
487
|
-
|
|
488
|
-
const mockServer = {
|
|
489
|
-
watcher: { on: vi.fn() },
|
|
490
|
-
moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
|
|
491
|
-
ws: { send: vi.fn() },
|
|
492
|
-
}
|
|
493
|
-
await plugin.configureServer(mockServer)
|
|
494
|
-
|
|
495
|
-
// Simulate an 'add' event on a pages file — covers getDirtyVirtualIds and watcher callback
|
|
496
|
-
await capturedCallback!('add', '/project/app/pages/new-page.ts')
|
|
497
|
-
expect((mockServer.ws.send as ReturnType<typeof vi.fn>)).toHaveBeenCalledWith({ type: 'full-reload' })
|
|
498
|
-
})
|
|
499
|
-
|
|
500
|
-
it('re-scans composables when a composable file is added', async () => {
|
|
501
|
-
const { createWatcher } = await import('../../plugin/scanner.js')
|
|
502
|
-
const { scanComposableExports } = await import('../../plugin/dts-generator.js')
|
|
503
|
-
vi.mocked(scanComposableExports).mockClear()
|
|
504
|
-
|
|
505
|
-
let capturedCallback: ((event: string, file: string) => void) | null = null
|
|
506
|
-
vi.mocked(createWatcher).mockImplementationOnce((_watcher, _dirs, cb) => {
|
|
507
|
-
capturedCallback = cb
|
|
508
|
-
return { on: vi.fn(), close: vi.fn() } as unknown as ReturnType<typeof createWatcher>
|
|
509
|
-
})
|
|
510
|
-
|
|
511
|
-
const plugin = getCerPlugin()
|
|
512
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
513
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
514
|
-
|
|
515
|
-
const mockServer = {
|
|
516
|
-
watcher: { on: vi.fn() },
|
|
517
|
-
moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
|
|
518
|
-
ws: { send: vi.fn() },
|
|
519
|
-
}
|
|
520
|
-
await plugin.configureServer(mockServer)
|
|
521
|
-
|
|
522
|
-
const callsBeforeEvent = vi.mocked(scanComposableExports).mock.calls.length
|
|
523
|
-
await capturedCallback!('add', '/project/app/composables/use-new.ts')
|
|
524
|
-
expect(vi.mocked(scanComposableExports).mock.calls.length).toBeGreaterThan(callsBeforeEvent)
|
|
525
|
-
})
|
|
526
|
-
|
|
527
|
-
it('does not trigger HMR on non-add/unlink events', async () => {
|
|
528
|
-
const { createWatcher } = await import('../../plugin/scanner.js')
|
|
529
|
-
|
|
530
|
-
let capturedCallback: ((event: string, file: string) => void) | null = null
|
|
531
|
-
vi.mocked(createWatcher).mockImplementationOnce((_watcher, _dirs, cb) => {
|
|
532
|
-
capturedCallback = cb
|
|
533
|
-
return { on: vi.fn(), close: vi.fn() } as unknown as ReturnType<typeof createWatcher>
|
|
534
|
-
})
|
|
535
|
-
|
|
536
|
-
const plugin = getCerPlugin()
|
|
537
|
-
plugin.config({ root: '/project' }, { command: 'serve', mode: 'development' })
|
|
538
|
-
plugin.configResolved(FAKE_RESOLVED)
|
|
539
|
-
|
|
540
|
-
const wsSend = vi.fn()
|
|
541
|
-
const mockServer = {
|
|
542
|
-
watcher: { on: vi.fn() },
|
|
543
|
-
moduleGraph: { getModuleById: vi.fn().mockReturnValue(null), invalidateModule: vi.fn() },
|
|
544
|
-
ws: { send: wsSend },
|
|
545
|
-
}
|
|
546
|
-
await plugin.configureServer(mockServer)
|
|
547
|
-
wsSend.mockClear()
|
|
548
|
-
|
|
549
|
-
await capturedCallback!('change', '/project/app/pages/index.ts')
|
|
550
|
-
expect(wsSend).not.toHaveBeenCalled()
|
|
551
|
-
})
|
|
552
|
-
})
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
import { contentPathToFile, emitContentFiles } from '../../../plugin/content/emitter.js'
|
|
3
|
-
import { mkdtempSync, readFileSync, existsSync } from 'node:fs'
|
|
4
|
-
import { tmpdir } from 'node:os'
|
|
5
|
-
import { join } from 'pathe'
|
|
6
|
-
import type { ContentItem } from '../../../types/content.js'
|
|
7
|
-
|
|
8
|
-
// ─── contentPathToFile ────────────────────────────────────────────────────────
|
|
9
|
-
|
|
10
|
-
describe('contentPathToFile', () => {
|
|
11
|
-
it('maps / to index.json', () => {
|
|
12
|
-
expect(contentPathToFile('/')).toBe('index.json')
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
it('maps /about to about.json', () => {
|
|
16
|
-
expect(contentPathToFile('/about')).toBe('about.json')
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('maps /blog/hello to blog/hello.json', () => {
|
|
20
|
-
expect(contentPathToFile('/blog/hello')).toBe('blog/hello.json')
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('maps /blog to blog.json', () => {
|
|
24
|
-
expect(contentPathToFile('/blog')).toBe('blog.json')
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('maps /docs/getting-started to docs/getting-started.json', () => {
|
|
28
|
-
expect(contentPathToFile('/docs/getting-started')).toBe('docs/getting-started.json')
|
|
29
|
-
})
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
// ─── emitContentFiles ─────────────────────────────────────────────────────────
|
|
33
|
-
|
|
34
|
-
describe('emitContentFiles', () => {
|
|
35
|
-
const items: ContentItem[] = [
|
|
36
|
-
{
|
|
37
|
-
_path: '/',
|
|
38
|
-
_file: 'index.md',
|
|
39
|
-
_type: 'markdown',
|
|
40
|
-
title: 'Home',
|
|
41
|
-
description: 'Welcome',
|
|
42
|
-
body: '<h1>Home</h1>',
|
|
43
|
-
toc: [],
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
_path: '/blog/hello',
|
|
47
|
-
_file: 'blog/hello.md',
|
|
48
|
-
_type: 'markdown',
|
|
49
|
-
title: 'Hello',
|
|
50
|
-
description: 'First post',
|
|
51
|
-
date: '2026-04-03',
|
|
52
|
-
draft: false,
|
|
53
|
-
body: '<h1>Hello</h1>',
|
|
54
|
-
toc: [{ depth: 1, id: 'hello', text: 'Hello' }],
|
|
55
|
-
excerpt: '<p>Intro</p>',
|
|
56
|
-
},
|
|
57
|
-
]
|
|
58
|
-
|
|
59
|
-
it('writes manifest.json with lean ContentMeta (no body/toc/excerpt/_file)', () => {
|
|
60
|
-
const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
|
|
61
|
-
emitContentFiles(items, outDir, '{}')
|
|
62
|
-
const manifest = JSON.parse(readFileSync(join(outDir, '_content/manifest.json'), 'utf-8'))
|
|
63
|
-
expect(Array.isArray(manifest)).toBe(true)
|
|
64
|
-
expect(manifest).toHaveLength(2)
|
|
65
|
-
const root = manifest.find((m: { _path: string }) => m._path === '/')
|
|
66
|
-
expect(root.title).toBe('Home')
|
|
67
|
-
expect('body' in root).toBe(false)
|
|
68
|
-
expect('toc' in root).toBe(false)
|
|
69
|
-
expect('excerpt' in root).toBe(false)
|
|
70
|
-
expect('_file' in root).toBe(false)
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('writes search-index.json with provided content', () => {
|
|
74
|
-
const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
|
|
75
|
-
emitContentFiles(items, outDir, '{"test":true}')
|
|
76
|
-
const idx = JSON.parse(readFileSync(join(outDir, '_content/search-index.json'), 'utf-8'))
|
|
77
|
-
expect(idx).toEqual({ test: true })
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
it('writes root document to _content/index.json', () => {
|
|
81
|
-
const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
|
|
82
|
-
emitContentFiles(items, outDir, '{}')
|
|
83
|
-
expect(existsSync(join(outDir, '_content/index.json'))).toBe(true)
|
|
84
|
-
const doc = JSON.parse(readFileSync(join(outDir, '_content/index.json'), 'utf-8'))
|
|
85
|
-
expect(doc._path).toBe('/')
|
|
86
|
-
expect(doc.body).toBe('<h1>Home</h1>')
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('writes nested document to correct subdirectory', () => {
|
|
90
|
-
const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
|
|
91
|
-
emitContentFiles(items, outDir, '{}')
|
|
92
|
-
const docPath = join(outDir, '_content/blog/hello.json')
|
|
93
|
-
expect(existsSync(docPath)).toBe(true)
|
|
94
|
-
const doc = JSON.parse(readFileSync(docPath, 'utf-8'))
|
|
95
|
-
expect(doc._path).toBe('/blog/hello')
|
|
96
|
-
expect(doc.toc).toEqual([{ depth: 1, id: 'hello', text: 'Hello' }])
|
|
97
|
-
expect(doc.excerpt).toBe('<p>Intro</p>')
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
it('coexisting blog.json and blog/ dir is allowed', () => {
|
|
101
|
-
const items2: ContentItem[] = [
|
|
102
|
-
...items,
|
|
103
|
-
{
|
|
104
|
-
_path: '/blog',
|
|
105
|
-
_file: 'blog/index.md',
|
|
106
|
-
_type: 'markdown',
|
|
107
|
-
title: 'Blog',
|
|
108
|
-
body: '<p>Blog</p>',
|
|
109
|
-
toc: [],
|
|
110
|
-
},
|
|
111
|
-
]
|
|
112
|
-
const outDir = mkdtempSync(join(tmpdir(), 'cer-emitter-'))
|
|
113
|
-
emitContentFiles(items2, outDir, '{}')
|
|
114
|
-
expect(existsSync(join(outDir, '_content/blog.json'))).toBe(true)
|
|
115
|
-
expect(existsSync(join(outDir, '_content/blog/hello.json'))).toBe(true)
|
|
116
|
-
})
|
|
117
|
-
})
|