@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/path-utils.ts
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { basename, relative } from 'pathe'
|
|
2
|
-
|
|
3
|
-
export interface RouteEntry {
|
|
4
|
-
filePath: string
|
|
5
|
-
routePath: string
|
|
6
|
-
tagName: string
|
|
7
|
-
isDynamic: boolean
|
|
8
|
-
isCatchAll: boolean
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Converts a file path to a route path.
|
|
13
|
-
* e.g. app/pages/blog/[slug].ts -> /blog/:slug
|
|
14
|
-
*/
|
|
15
|
-
export function fileToRoutePath(filePath: string, pagesRoot: string): string {
|
|
16
|
-
// Get path relative to pagesRoot, strip extension
|
|
17
|
-
let rel = relative(pagesRoot, filePath)
|
|
18
|
-
rel = rel.replace(/\.[jt]s$/, '')
|
|
19
|
-
|
|
20
|
-
// Split into segments
|
|
21
|
-
const segments = rel.split('/')
|
|
22
|
-
|
|
23
|
-
const transformed: string[] = []
|
|
24
|
-
for (const seg of segments) {
|
|
25
|
-
// Strip route groups: (groupName)
|
|
26
|
-
if (/^\(.*\)$/.test(seg)) {
|
|
27
|
-
continue
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// index becomes empty string (handled by parent)
|
|
31
|
-
if (seg === 'index') {
|
|
32
|
-
continue
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// [...rest] -> :rest* (named splat so the param is accessible in components)
|
|
36
|
-
const catchAllMatch = seg.match(/^\[\.\.\.(.+)\]$/)
|
|
37
|
-
if (catchAllMatch) {
|
|
38
|
-
transformed.push(`:${catchAllMatch[1]}*`)
|
|
39
|
-
continue
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// [param] -> :param
|
|
43
|
-
const dynamicMatch = seg.match(/^\[(.+)\]$/)
|
|
44
|
-
if (dynamicMatch) {
|
|
45
|
-
transformed.push(`:${dynamicMatch[1]}`)
|
|
46
|
-
continue
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
transformed.push(seg)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const path = '/' + transformed.join('/')
|
|
53
|
-
// Normalize double slashes
|
|
54
|
-
return path.replace(/\/+/g, '/')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Converts a file path to a kebab-case custom element tag name.
|
|
59
|
-
* e.g. app/pages/blog/[slug].ts -> page-blog-slug
|
|
60
|
-
*/
|
|
61
|
-
export function fileToTagName(filePath: string, pagesRoot: string): string {
|
|
62
|
-
let rel = relative(pagesRoot, filePath)
|
|
63
|
-
rel = rel.replace(/\.[jt]s$/, '')
|
|
64
|
-
|
|
65
|
-
// Strip route groups
|
|
66
|
-
const segments = rel.split('/').filter((seg) => !/^\(.*\)$/.test(seg))
|
|
67
|
-
|
|
68
|
-
// Mirror fileToRoutePath: strip 'index' segments unless it's the only segment
|
|
69
|
-
// e.g. blog/index.ts -> page-blog (not page-blog-index), index.ts -> page-index
|
|
70
|
-
const tagSegments = segments
|
|
71
|
-
.map((seg) => seg.replace(/\[/g, '').replace(/\]/g, '').replace(/\./g, ''))
|
|
72
|
-
.filter((seg, _, arr) => !(seg === 'index' && arr.length > 1))
|
|
73
|
-
|
|
74
|
-
// Prefix with 'page-'
|
|
75
|
-
const name = 'page-' + tagSegments.join('-')
|
|
76
|
-
// Collapse multiple dashes and convert to lowercase
|
|
77
|
-
return name
|
|
78
|
-
.toLowerCase()
|
|
79
|
-
.replace(/-+/g, '-')
|
|
80
|
-
.replace(/^-|-$/g, '')
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Converts a layout file path to a kebab-case custom element tag name.
|
|
85
|
-
* e.g. app/layouts/default.ts -> layout-default
|
|
86
|
-
*/
|
|
87
|
-
export function fileToLayoutTagName(filePath: string, layoutsRoot: string): string {
|
|
88
|
-
let rel = relative(layoutsRoot, filePath)
|
|
89
|
-
rel = rel.replace(/\.[jt]s$/, '')
|
|
90
|
-
|
|
91
|
-
const segments = rel.split('/')
|
|
92
|
-
const name = 'layout-' + segments.join('-')
|
|
93
|
-
return name
|
|
94
|
-
.toLowerCase()
|
|
95
|
-
.replace(/-+/g, '-')
|
|
96
|
-
.replace(/^-|-$/g, '')
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Sorts routes: static first, then dynamic, then catch-all.
|
|
101
|
-
*/
|
|
102
|
-
export function sortRoutes(routes: RouteEntry[]): RouteEntry[] {
|
|
103
|
-
return [...routes].sort((a, b) => {
|
|
104
|
-
// Catch-all always last
|
|
105
|
-
if (a.isCatchAll && !b.isCatchAll) return 1
|
|
106
|
-
if (!a.isCatchAll && b.isCatchAll) return -1
|
|
107
|
-
|
|
108
|
-
// Dynamic after static
|
|
109
|
-
if (a.isDynamic && !b.isDynamic) return 1
|
|
110
|
-
if (!a.isDynamic && b.isDynamic) return -1
|
|
111
|
-
|
|
112
|
-
// Alphabetical among same type
|
|
113
|
-
return a.routePath.localeCompare(b.routePath)
|
|
114
|
-
})
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Determines if a route path contains dynamic segments.
|
|
119
|
-
*/
|
|
120
|
-
export function isRouteDynamic(routePath: string): boolean {
|
|
121
|
-
return routePath.includes(':')
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Determines if a route path is a catch-all.
|
|
126
|
-
*/
|
|
127
|
-
export function isRouteCatchAll(routePath: string): boolean {
|
|
128
|
-
return routePath.includes('*')
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Builds a full RouteEntry from a file path.
|
|
133
|
-
*/
|
|
134
|
-
export function buildRouteEntry(filePath: string, pagesRoot: string): RouteEntry {
|
|
135
|
-
const routePath = fileToRoutePath(filePath, pagesRoot)
|
|
136
|
-
const tagName = fileToTagName(filePath, pagesRoot)
|
|
137
|
-
return {
|
|
138
|
-
filePath,
|
|
139
|
-
routePath,
|
|
140
|
-
tagName,
|
|
141
|
-
isDynamic: isRouteDynamic(routePath),
|
|
142
|
-
isCatchAll: isRouteCatchAll(routePath),
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Returns the layout name (key) from a layout file path.
|
|
148
|
-
* e.g. app/layouts/default.ts -> 'default'
|
|
149
|
-
*/
|
|
150
|
-
export function fileToLayoutName(filePath: string, layoutsRoot: string): string {
|
|
151
|
-
let rel = relative(layoutsRoot, filePath)
|
|
152
|
-
rel = rel.replace(/\.[jt]s$/, '')
|
|
153
|
-
return rel.replace(/\//g, '-').toLowerCase()
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Returns a safe JS identifier for a file path (for import aliases).
|
|
158
|
-
*/
|
|
159
|
-
export function fileToImportAlias(filePath: string, prefix: string = '_m'): string {
|
|
160
|
-
const base = basename(filePath).replace(/\.[jt]s$/, '')
|
|
161
|
-
const safe = base
|
|
162
|
-
.replace(/[^a-zA-Z0-9_]/g, '_')
|
|
163
|
-
.replace(/^(\d)/, '_$1')
|
|
164
|
-
return `${prefix}_${safe}`
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Returns the numeric sort prefix from a filename (e.g. "01.store.ts" -> 1).
|
|
169
|
-
* Returns Infinity if no numeric prefix.
|
|
170
|
-
*/
|
|
171
|
-
export function extractPluginOrder(fileName: string): number {
|
|
172
|
-
const match = basename(fileName).match(/^(\d+)\./)
|
|
173
|
-
return match ? parseInt(match[1], 10) : Infinity
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Sorts plugin files by leading numeric prefix then alphabetically.
|
|
178
|
-
*/
|
|
179
|
-
export function sortPluginFiles(files: string[]): string[] {
|
|
180
|
-
return [...files].sort((a, b) => {
|
|
181
|
-
const aOrder = extractPluginOrder(a)
|
|
182
|
-
const bOrder = extractPluginOrder(b)
|
|
183
|
-
if (aOrder !== bOrder) return aOrder - bOrder
|
|
184
|
-
return a.localeCompare(b)
|
|
185
|
-
})
|
|
186
|
-
}
|
package/src/plugin/scanner.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import fg from 'fast-glob'
|
|
2
|
-
import type { FSWatcher } from 'vite'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Scans a directory for files matching the given glob pattern.
|
|
6
|
-
* Returns absolute file paths sorted alphabetically.
|
|
7
|
-
*/
|
|
8
|
-
export async function scanDirectory(pattern: string, cwd: string): Promise<string[]> {
|
|
9
|
-
const files = await fg(pattern, {
|
|
10
|
-
cwd,
|
|
11
|
-
absolute: true,
|
|
12
|
-
onlyFiles: true,
|
|
13
|
-
ignore: ['**/node_modules/**', '**/.git/**'],
|
|
14
|
-
})
|
|
15
|
-
return files.sort()
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a file watcher for the given directories using Vite's built-in watcher.
|
|
20
|
-
* Calls `onChange(event, absoluteFilePath)` on add/unlink events.
|
|
21
|
-
*
|
|
22
|
-
* @param watcher - The FSWatcher from Vite's dev server (server.watcher)
|
|
23
|
-
* @param dirs - Absolute directory paths to watch
|
|
24
|
-
* @param onChange - Callback invoked with event type and absolute file path
|
|
25
|
-
* @returns A cleanup function that removes the listeners
|
|
26
|
-
*/
|
|
27
|
-
export function createWatcher(
|
|
28
|
-
watcher: FSWatcher,
|
|
29
|
-
dirs: string[],
|
|
30
|
-
onChange: (event: string, file: string) => void,
|
|
31
|
-
): () => void {
|
|
32
|
-
// Add directories to Vite's watcher
|
|
33
|
-
for (const dir of dirs) {
|
|
34
|
-
watcher.add(dir)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const handleAdd = (file: string) => {
|
|
38
|
-
if (dirs.some((dir) => file.startsWith(dir))) {
|
|
39
|
-
onChange('add', file)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const handleUnlink = (file: string) => {
|
|
44
|
-
if (dirs.some((dir) => file.startsWith(dir))) {
|
|
45
|
-
onChange('unlink', file)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const handleChange = (file: string) => {
|
|
50
|
-
if (dirs.some((dir) => file.startsWith(dir))) {
|
|
51
|
-
onChange('change', file)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
watcher.on('add', handleAdd)
|
|
56
|
-
watcher.on('unlink', handleUnlink)
|
|
57
|
-
watcher.on('change', handleChange)
|
|
58
|
-
|
|
59
|
-
// Return cleanup function
|
|
60
|
-
return () => {
|
|
61
|
-
watcher.off('add', handleAdd)
|
|
62
|
-
watcher.off('unlink', handleUnlink)
|
|
63
|
-
watcher.off('change', handleChange)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
import MagicString from 'magic-string'
|
|
2
|
-
import { normalize } from 'pathe'
|
|
3
|
-
|
|
4
|
-
export interface AutoImportOptions {
|
|
5
|
-
srcDir: string
|
|
6
|
-
/** Absolute path to server/middleware/ directory */
|
|
7
|
-
serverMiddlewareDir?: string
|
|
8
|
-
/** Map of composable export name → absolute file path */
|
|
9
|
-
composableExports?: Map<string, string>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// P1-5: Per-identifier import maps. Only the identifiers actually referenced in
|
|
13
|
-
// a file are injected — this eliminates the full-group injection that prevented
|
|
14
|
-
// tree-shaking when a page used only one framework composable.
|
|
15
|
-
|
|
16
|
-
/** Maps each runtime identifier to its source module. All from the main runtime package. */
|
|
17
|
-
const RUNTIME_MAP: Record<string, string> = {
|
|
18
|
-
component: '@jasonshimmy/custom-elements-runtime',
|
|
19
|
-
defineAsyncComponent: '@jasonshimmy/custom-elements-runtime',
|
|
20
|
-
html: '@jasonshimmy/custom-elements-runtime',
|
|
21
|
-
css: '@jasonshimmy/custom-elements-runtime',
|
|
22
|
-
ref: '@jasonshimmy/custom-elements-runtime',
|
|
23
|
-
computed: '@jasonshimmy/custom-elements-runtime',
|
|
24
|
-
watch: '@jasonshimmy/custom-elements-runtime',
|
|
25
|
-
watchEffect: '@jasonshimmy/custom-elements-runtime',
|
|
26
|
-
useProps: '@jasonshimmy/custom-elements-runtime',
|
|
27
|
-
useEmit: '@jasonshimmy/custom-elements-runtime',
|
|
28
|
-
useOnConnected: '@jasonshimmy/custom-elements-runtime',
|
|
29
|
-
useOnDisconnected: '@jasonshimmy/custom-elements-runtime',
|
|
30
|
-
useOnAttributeChanged: '@jasonshimmy/custom-elements-runtime',
|
|
31
|
-
useOnError: '@jasonshimmy/custom-elements-runtime',
|
|
32
|
-
useStyle: '@jasonshimmy/custom-elements-runtime',
|
|
33
|
-
useDesignTokens: '@jasonshimmy/custom-elements-runtime',
|
|
34
|
-
useGlobalStyle: '@jasonshimmy/custom-elements-runtime',
|
|
35
|
-
useExpose: '@jasonshimmy/custom-elements-runtime',
|
|
36
|
-
useSlots: '@jasonshimmy/custom-elements-runtime',
|
|
37
|
-
provide: '@jasonshimmy/custom-elements-runtime',
|
|
38
|
-
inject: '@jasonshimmy/custom-elements-runtime',
|
|
39
|
-
createComposable: '@jasonshimmy/custom-elements-runtime',
|
|
40
|
-
nextTick: '@jasonshimmy/custom-elements-runtime',
|
|
41
|
-
defineModel: '@jasonshimmy/custom-elements-runtime',
|
|
42
|
-
getCurrentComponentContext: '@jasonshimmy/custom-elements-runtime',
|
|
43
|
-
isReactiveState: '@jasonshimmy/custom-elements-runtime',
|
|
44
|
-
unsafeHTML: '@jasonshimmy/custom-elements-runtime',
|
|
45
|
-
decodeEntities: '@jasonshimmy/custom-elements-runtime',
|
|
46
|
-
useTeleport: '@jasonshimmy/custom-elements-runtime',
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Maps each directive identifier to its source module (directives sub-path). */
|
|
50
|
-
const DIRECTIVE_MAP: Record<string, string> = {
|
|
51
|
-
when: '@jasonshimmy/custom-elements-runtime/directives',
|
|
52
|
-
each: '@jasonshimmy/custom-elements-runtime/directives',
|
|
53
|
-
match: '@jasonshimmy/custom-elements-runtime/directives',
|
|
54
|
-
anchorBlock: '@jasonshimmy/custom-elements-runtime/directives',
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** Maps each framework composable to its source module. */
|
|
58
|
-
const FRAMEWORK_MAP: Record<string, string> = {
|
|
59
|
-
useHead: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
60
|
-
usePageData: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
61
|
-
useInject: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
62
|
-
useRuntimeConfig: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
63
|
-
defineMiddleware: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
64
|
-
defineServerMiddleware: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
65
|
-
useSeoMeta: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
66
|
-
useCookie: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
67
|
-
useSession: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
68
|
-
useAuth: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
69
|
-
useFetch: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
70
|
-
useRoute: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
71
|
-
navigateTo: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
72
|
-
useState: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
73
|
-
useLocale: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
74
|
-
queryContent: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
75
|
-
useContentSearch: '@jasonshimmy/vite-plugin-cer-app/composables',
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// All identifier maps — processed in order. Earlier maps take precedence for
|
|
79
|
-
// the "already imported from this module" duplicate check.
|
|
80
|
-
const ALL_MAPS = [RUNTIME_MAP, DIRECTIVE_MAP, FRAMEWORK_MAP]
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Returns true if the file already manually imports from the given source module.
|
|
84
|
-
* When true, we skip auto-injecting identifiers from that module to avoid duplicates.
|
|
85
|
-
*/
|
|
86
|
-
function isAlreadyImported(code: string, sourceModule: string): boolean {
|
|
87
|
-
return (
|
|
88
|
-
code.includes(`from '${sourceModule}'`) ||
|
|
89
|
-
code.includes(`from "${sourceModule}"`)
|
|
90
|
-
)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Builds minimal import statements containing only the identifiers actually
|
|
95
|
-
* referenced in the file. Groups identifiers by source module. Skips modules
|
|
96
|
-
* that the file already imports from manually.
|
|
97
|
-
*
|
|
98
|
-
* Returns an array of import statement strings (one per source module used).
|
|
99
|
-
*/
|
|
100
|
-
function buildMinimalImportStatements(code: string, maps: Record<string, string>[]): string[] {
|
|
101
|
-
// Group identifier → source module, collecting only used ones.
|
|
102
|
-
const grouped = new Map<string, string[]>()
|
|
103
|
-
|
|
104
|
-
for (const map of maps) {
|
|
105
|
-
for (const [identifier, sourceModule] of Object.entries(map)) {
|
|
106
|
-
// Skip if the file already imports from this module.
|
|
107
|
-
if (isAlreadyImported(code, sourceModule)) continue
|
|
108
|
-
// Skip if identifier not referenced in the file.
|
|
109
|
-
const pattern = new RegExp(`\\b${identifier}\\b`)
|
|
110
|
-
if (!pattern.test(code)) continue
|
|
111
|
-
|
|
112
|
-
const existing = grouped.get(sourceModule) ?? []
|
|
113
|
-
existing.push(identifier)
|
|
114
|
-
grouped.set(sourceModule, existing)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return Array.from(grouped.entries()).map(
|
|
119
|
-
([mod, ids]) => `import { ${ids.join(', ')} } from '${mod}';`,
|
|
120
|
-
)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Auto-import transform: injects runtime and directive imports at the top of
|
|
125
|
-
* files inside app/pages/, app/layouts/, or app/components/ if those
|
|
126
|
-
* identifiers are not already imported.
|
|
127
|
-
*
|
|
128
|
-
* Returns the transformed code string, or null if no injection was needed.
|
|
129
|
-
*/
|
|
130
|
-
export function autoImportTransform(
|
|
131
|
-
code: string,
|
|
132
|
-
id: string,
|
|
133
|
-
opts: AutoImportOptions,
|
|
134
|
-
): string | null {
|
|
135
|
-
const normalizedId = normalize(id)
|
|
136
|
-
const srcDir = normalize(opts.srcDir)
|
|
137
|
-
|
|
138
|
-
// Transform files inside app/pages/, app/layouts/, app/components/, app/middleware/
|
|
139
|
-
// AND special convention files directly in app/ (loading.ts, error.ts, etc.)
|
|
140
|
-
const isSubDir =
|
|
141
|
-
normalizedId.startsWith(srcDir + '/pages/') ||
|
|
142
|
-
normalizedId.startsWith(srcDir + '/layouts/') ||
|
|
143
|
-
normalizedId.startsWith(srcDir + '/components/') ||
|
|
144
|
-
normalizedId.startsWith(srcDir + '/middleware/') ||
|
|
145
|
-
normalizedId.startsWith(srcDir + '/composables/')
|
|
146
|
-
// Files directly in srcDir root (e.g. app/loading.ts, app/error.ts)
|
|
147
|
-
const isRootConventionFile =
|
|
148
|
-
normalizedId.startsWith(srcDir + '/') &&
|
|
149
|
-
!normalizedId.slice(srcDir.length + 1).includes('/')
|
|
150
|
-
// server/middleware/ files also get framework auto-imports
|
|
151
|
-
const serverMiddlewareDir = opts.serverMiddlewareDir ? normalize(opts.serverMiddlewareDir) : null
|
|
152
|
-
const isServerMiddleware = serverMiddlewareDir != null && normalizedId.startsWith(serverMiddlewareDir + '/')
|
|
153
|
-
const isTargetDir = isSubDir || isRootConventionFile || isServerMiddleware
|
|
154
|
-
|
|
155
|
-
if (!isTargetDir) return null
|
|
156
|
-
|
|
157
|
-
// Skip virtual modules and non-ts files
|
|
158
|
-
if (id.startsWith('\0') || (!id.endsWith('.ts') && !id.endsWith('.js'))) return null
|
|
159
|
-
|
|
160
|
-
// Skip virtual:cer-composables injection for files inside app/composables/ to
|
|
161
|
-
// avoid circular imports (the virtual module re-exports from all composable files).
|
|
162
|
-
const isComposablesDir = normalizedId.startsWith(srcDir + '/composables/')
|
|
163
|
-
const composableImport = isComposablesDir ? null : buildComposableImport(code, opts.composableExports)
|
|
164
|
-
|
|
165
|
-
// Build per-identifier import statements from all maps.
|
|
166
|
-
const importLines = buildMinimalImportStatements(code, ALL_MAPS)
|
|
167
|
-
|
|
168
|
-
if (importLines.length === 0 && !composableImport) return null
|
|
169
|
-
|
|
170
|
-
const ms = new MagicString(code)
|
|
171
|
-
const injectLines: string[] = [...importLines]
|
|
172
|
-
|
|
173
|
-
if (composableImport) {
|
|
174
|
-
injectLines.push(composableImport)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
ms.prepend(injectLines.join('\n') + '\n')
|
|
178
|
-
|
|
179
|
-
return ms.toString()
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Builds an import statement for any composable names used in the file
|
|
184
|
-
* that are not already imported.
|
|
185
|
-
* Returns null if no injection is needed.
|
|
186
|
-
*/
|
|
187
|
-
function buildComposableImport(code: string, composableExports?: Map<string, string>): string | null {
|
|
188
|
-
if (!composableExports || composableExports.size === 0) return null
|
|
189
|
-
|
|
190
|
-
// Skip if already importing from virtual:cer-composables
|
|
191
|
-
if (code.includes("from 'virtual:cer-composables'") || code.includes('from "virtual:cer-composables"')) {
|
|
192
|
-
return null
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const needed: string[] = []
|
|
196
|
-
for (const name of composableExports.keys()) {
|
|
197
|
-
const pattern = new RegExp(`\\b${name}\\b`)
|
|
198
|
-
if (pattern.test(code)) {
|
|
199
|
-
needed.push(name)
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
if (needed.length === 0) return null
|
|
204
|
-
|
|
205
|
-
return `import { ${needed.join(', ')} } from 'virtual:cer-composables';`
|
|
206
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
export interface HeadTag {
|
|
2
|
-
tag: string
|
|
3
|
-
attrs?: Record<string, string>
|
|
4
|
-
innerHTML?: string
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export interface HeadInput {
|
|
8
|
-
title?: string
|
|
9
|
-
meta?: Array<Record<string, string>>
|
|
10
|
-
link?: Array<Record<string, string>>
|
|
11
|
-
script?: Array<Record<string, string>>
|
|
12
|
-
style?: Array<Record<string, string>>
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Inserts stringified head tags before the closing </head> tag.
|
|
17
|
-
* If no </head> is found, prepends to the document.
|
|
18
|
-
*/
|
|
19
|
-
export function injectHead(html: string, headTags: HeadTag[]): string {
|
|
20
|
-
if (headTags.length === 0) return html
|
|
21
|
-
|
|
22
|
-
const serialized = headTags.map(serializeTag).join('\n')
|
|
23
|
-
|
|
24
|
-
const closeHeadIdx = html.indexOf('</head>')
|
|
25
|
-
if (closeHeadIdx !== -1) {
|
|
26
|
-
return html.slice(0, closeHeadIdx) + serialized + '\n' + html.slice(closeHeadIdx)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// No </head> found: prepend
|
|
30
|
-
return serialized + '\n' + html
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Serializes a single HeadTag to an HTML string.
|
|
35
|
-
*/
|
|
36
|
-
function serializeTag(tag: HeadTag): string {
|
|
37
|
-
const attrs = tag.attrs
|
|
38
|
-
? Object.entries(tag.attrs)
|
|
39
|
-
.map(([k, v]) => (v === '' ? k : `${k}="${escapeAttr(v)}"`))
|
|
40
|
-
.join(' ')
|
|
41
|
-
: ''
|
|
42
|
-
|
|
43
|
-
const openTag = attrs ? `<${tag.tag} ${attrs}>` : `<${tag.tag}>`
|
|
44
|
-
|
|
45
|
-
if (tag.innerHTML !== undefined) {
|
|
46
|
-
return `${openTag}${tag.innerHTML}</${tag.tag}>`
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Self-closing for void elements
|
|
50
|
-
const voidTags = new Set(['meta', 'link', 'base', 'br', 'hr', 'img', 'input'])
|
|
51
|
-
if (voidTags.has(tag.tag)) {
|
|
52
|
-
return attrs ? `<${tag.tag} ${attrs}>` : `<${tag.tag}>`
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return `${openTag}</${tag.tag}>`
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function escapeAttr(value: string): string {
|
|
59
|
-
return value.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>')
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* HeadCollector gathers HeadInput objects during SSR and serializes them
|
|
64
|
-
* to an HTML string for injection into the document head.
|
|
65
|
-
*/
|
|
66
|
-
export class HeadCollector {
|
|
67
|
-
private readonly _collected: HeadInput[] = []
|
|
68
|
-
|
|
69
|
-
collect(tags: HeadInput): void {
|
|
70
|
-
this._collected.push(tags)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
serialize(): string {
|
|
74
|
-
const tags = headInputToTags(this._collected)
|
|
75
|
-
return tags.map(serializeTag).join('\n')
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
reset(): void {
|
|
79
|
-
this._collected.length = 0
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
getCollected(): HeadInput[] {
|
|
83
|
-
return [...this._collected]
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Converts an array of HeadInput objects to a flat array of HeadTags.
|
|
89
|
-
* Later entries override earlier ones for title; meta/link/script/style are merged.
|
|
90
|
-
*/
|
|
91
|
-
function headInputToTags(inputs: HeadInput[]): HeadTag[] {
|
|
92
|
-
const tags: HeadTag[] = []
|
|
93
|
-
|
|
94
|
-
// Collect title — last one wins
|
|
95
|
-
let title: string | undefined
|
|
96
|
-
for (const input of inputs) {
|
|
97
|
-
if (input.title !== undefined) {
|
|
98
|
-
title = input.title
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (title !== undefined) {
|
|
102
|
-
tags.push({ tag: 'title', innerHTML: escapeHtml(title) })
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Collect meta tags (deduplicate by name/property)
|
|
106
|
-
const metaMap = new Map<string, Record<string, string>>()
|
|
107
|
-
for (const input of inputs) {
|
|
108
|
-
if (input.meta) {
|
|
109
|
-
for (const meta of input.meta) {
|
|
110
|
-
const key = meta.name ?? meta.property ?? meta.charset ?? JSON.stringify(meta)
|
|
111
|
-
metaMap.set(key, meta)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
for (const attrs of metaMap.values()) {
|
|
116
|
-
tags.push({ tag: 'meta', attrs })
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Collect link tags (deduplicate by rel+href)
|
|
120
|
-
const linkMap = new Map<string, Record<string, string>>()
|
|
121
|
-
for (const input of inputs) {
|
|
122
|
-
if (input.link) {
|
|
123
|
-
for (const link of input.link) {
|
|
124
|
-
const key = `${link.rel ?? ''}:${link.href ?? ''}`
|
|
125
|
-
linkMap.set(key, link)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
for (const attrs of linkMap.values()) {
|
|
130
|
-
tags.push({ tag: 'link', attrs })
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// Collect script tags
|
|
134
|
-
for (const input of inputs) {
|
|
135
|
-
if (input.script) {
|
|
136
|
-
for (const script of input.script) {
|
|
137
|
-
const { innerHTML, ...attrs } = script as Record<string, string>
|
|
138
|
-
tags.push({ tag: 'script', attrs, innerHTML })
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Collect style tags
|
|
144
|
-
for (const input of inputs) {
|
|
145
|
-
if (input.style) {
|
|
146
|
-
for (const style of input.style) {
|
|
147
|
-
const { innerHTML, ...attrs } = style as Record<string, string>
|
|
148
|
-
tags.push({ tag: 'style', attrs, innerHTML })
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return tags
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function escapeHtml(str: string): string {
|
|
157
|
-
return str
|
|
158
|
-
.replace(/&/g, '&')
|
|
159
|
-
.replace(/</g, '<')
|
|
160
|
-
.replace(/>/g, '>')
|
|
161
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs'
|
|
2
|
-
import { scanDirectory } from '../scanner.js'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Generates the virtual:cer-composables module code.
|
|
6
|
-
* Scans app/composables/ and re-exports all composable functions.
|
|
7
|
-
*/
|
|
8
|
-
export async function generateComposablesCode(composablesDir: string): Promise<string> {
|
|
9
|
-
if (!existsSync(composablesDir)) {
|
|
10
|
-
return `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\n// No composables directory found\n`
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const files = await scanDirectory('**/*.ts', composablesDir)
|
|
14
|
-
|
|
15
|
-
if (files.length === 0) {
|
|
16
|
-
return `// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app\n// No composables found\n`
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const lines: string[] = ['// AUTO-GENERATED by @jasonshimmy/vite-plugin-cer-app', '']
|
|
20
|
-
|
|
21
|
-
for (const file of files) {
|
|
22
|
-
lines.push(`export * from ${JSON.stringify(file)}`)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
lines.push('')
|
|
26
|
-
|
|
27
|
-
return lines.join('\n')
|
|
28
|
-
}
|