@analogjs/platform 3.0.0-alpha.8 → 3.0.0-alpha.80
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/migrations/migration.json +7 -1
- package/package.json +27 -24
- package/src/index.d.ts +5 -2
- package/src/index.js +9 -3
- package/src/index.js.map +1 -0
- package/src/lib/clear-client-page-endpoint.d.ts +2 -2
- package/src/lib/clear-client-page-endpoint.js +44 -34
- package/src/lib/clear-client-page-endpoint.js.map +1 -0
- package/src/lib/content/marked/index.d.ts +5 -5
- package/src/lib/content/marked/index.js +10 -6
- package/src/lib/content/marked/index.js.map +1 -0
- package/src/lib/content/marked/marked-content-highlighter.d.ts +2 -2
- package/src/lib/content/marked/marked-content-highlighter.js +6 -3
- package/src/lib/content/marked/marked-content-highlighter.js.map +1 -0
- package/src/lib/content/marked/marked-setup.service.d.ts +8 -8
- package/src/lib/content/marked/marked-setup.service.js +44 -54
- package/src/lib/content/marked/marked-setup.service.js.map +1 -0
- package/src/lib/content/prism/angular.js +18 -19
- package/src/lib/content/prism/angular.js.map +1 -0
- package/src/lib/content/prism/index.d.ts +1 -1
- package/src/lib/content/prism/index.js +10 -7
- package/src/lib/content/prism/index.js.map +1 -0
- package/src/lib/content/prism/options.d.ts +1 -1
- package/src/lib/content/prism/prism-highlighter.d.ts +5 -5
- package/src/lib/content/prism/prism-highlighter.js +33 -33
- package/src/lib/content/prism/prism-highlighter.js.map +1 -0
- package/src/lib/content/shiki/index.d.ts +3 -3
- package/src/lib/content/shiki/index.js +22 -28
- package/src/lib/content/shiki/index.js.map +1 -0
- package/src/lib/content/shiki/options.d.ts +8 -7
- package/src/lib/content/shiki/shiki-highlighter.d.ts +14 -13
- package/src/lib/content/shiki/shiki-highlighter.js +49 -43
- package/src/lib/content/shiki/shiki-highlighter.js.map +1 -0
- package/src/lib/content-plugin.d.ts +19 -19
- package/src/lib/content-plugin.js +181 -223
- package/src/lib/content-plugin.js.map +1 -0
- package/src/lib/deps-plugin.d.ts +2 -2
- package/src/lib/deps-plugin.js +84 -78
- package/src/lib/deps-plugin.js.map +1 -0
- package/src/lib/discover-library-routes.d.ts +19 -0
- package/src/lib/discover-library-routes.js +72 -0
- package/src/lib/discover-library-routes.js.map +1 -0
- package/src/lib/i18n-component-registry-plugin.d.ts +17 -0
- package/src/lib/i18n-component-registry-plugin.js +100 -0
- package/src/lib/i18n-component-registry-plugin.js.map +1 -0
- package/src/lib/i18n-extract-plugin.d.ts +33 -0
- package/src/lib/inject-server-fn-ids.d.ts +17 -0
- package/src/lib/inject-server-fn-ids.js +94 -0
- package/src/lib/inject-server-fn-ids.js.map +1 -0
- package/src/lib/json-ld-manifest-plugin.d.ts +41 -0
- package/src/lib/json-ld-manifest-plugin.js +84 -0
- package/src/lib/json-ld-manifest-plugin.js.map +1 -0
- package/src/lib/library-pages-plugin.d.ts +8 -0
- package/src/lib/library-pages-plugin.js +21 -0
- package/src/lib/library-pages-plugin.js.map +1 -0
- package/src/lib/nitro/analog-nitro-plugin.d.ts +18 -0
- package/src/lib/nitro/analog-nitro-plugin.js +555 -0
- package/src/lib/nitro/analog-nitro-plugin.js.map +1 -0
- package/src/lib/nitro/angular-linker-plugin.d.ts +17 -0
- package/src/lib/nitro/angular-linker-plugin.js +51 -0
- package/src/lib/nitro/angular-linker-plugin.js.map +1 -0
- package/src/lib/nitro/build-sitemap.d.ts +23 -0
- package/src/lib/nitro/build-sitemap.js +137 -0
- package/src/lib/nitro/build-sitemap.js.map +1 -0
- package/src/lib/nitro/debug.d.ts +5 -0
- package/src/lib/nitro/debug.js +11 -0
- package/src/lib/nitro/debug.js.map +1 -0
- package/src/lib/nitro/get-content-files.d.ts +13 -0
- package/src/lib/nitro/get-content-files.js +52 -0
- package/src/lib/nitro/get-content-files.js.map +1 -0
- package/src/lib/nitro/get-page-handlers.d.ts +22 -0
- package/src/lib/nitro/get-page-handlers.js +33 -0
- package/src/lib/nitro/get-page-handlers.js.map +1 -0
- package/src/lib/nitro/i18n-prerender.d.ts +29 -0
- package/src/lib/nitro/i18n-prerender.js +61 -0
- package/src/lib/nitro/i18n-prerender.js.map +1 -0
- package/src/lib/nitro/page-endpoints-plugin.d.ts +7 -0
- package/src/lib/nitro/page-endpoints-plugin.js +72 -0
- package/src/lib/nitro/page-endpoints-plugin.js.map +1 -0
- package/src/lib/nitro/post-rendering-hook.d.ts +2 -0
- package/src/lib/nitro/post-rendering-hook.js +10 -0
- package/src/lib/nitro/post-rendering-hook.js.map +1 -0
- package/src/lib/nitro/renderers.d.ts +33 -0
- package/src/lib/nitro/renderers.js +22 -0
- package/src/lib/nitro/renderers.js.map +1 -0
- package/src/lib/nitro/types.d.ts +122 -0
- package/src/lib/nx-plugin/_virtual/_rolldown/runtime.js +23 -0
- package/src/lib/nx-plugin/builders.json +15 -0
- package/src/lib/nx-plugin/executors.json +13 -5
- package/src/lib/nx-plugin/generators.json +25 -0
- package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js +13 -0
- package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/camelCase.js.map +1 -0
- package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js +8 -0
- package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/capitalize.js.map +1 -0
- package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js +9 -0
- package/src/lib/nx-plugin/node_modules/.pnpm/es-toolkit@1.45.1/node_modules/es-toolkit/dist/string/words.js.map +1 -0
- package/src/lib/nx-plugin/package.json +1 -5
- package/src/lib/nx-plugin/src/builders/vite/schema.json +39 -0
- package/src/lib/nx-plugin/src/builders/vite/vite-build.d.ts +11 -0
- package/src/lib/nx-plugin/src/builders/vite/vite-build.js +18 -0
- package/src/lib/nx-plugin/src/builders/vite/vite-build.js.map +1 -0
- package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.d.ts +7 -0
- package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js +14 -0
- package/src/lib/nx-plugin/src/builders/vite-dev-server/dev-server.js.map +1 -0
- package/src/lib/nx-plugin/src/builders/vite-dev-server/schema.json +27 -0
- package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.d.ts +1 -1
- package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.js +7 -7
- package/src/lib/nx-plugin/src/executors/vite-dev-server/compat.js.map +1 -1
- package/src/lib/nx-plugin/src/executors/vite-dev-server/schema.d.ts +1 -1
- package/src/lib/nx-plugin/src/executors/vite-dev-server/vite-dev-server.impl.d.ts +1 -1
- package/src/lib/nx-plugin/src/executors/vite-dev-server/vite-dev-server.impl.js +6 -4
- package/src/lib/nx-plugin/src/executors/vite-dev-server/vite-dev-server.impl.js.map +1 -1
- package/src/lib/nx-plugin/src/executors/vitest/compat.d.ts +1 -1
- package/src/lib/nx-plugin/src/executors/vitest/compat.js +7 -7
- package/src/lib/nx-plugin/src/executors/vitest/compat.js.map +1 -1
- package/src/lib/nx-plugin/src/executors/vitest/schema.d.ts +1 -1
- package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.d.ts +1 -1
- package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.js +6 -4
- package/src/lib/nx-plugin/src/executors/vitest/vitest.impl.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/compat.d.ts +9 -3
- package/src/lib/nx-plugin/src/generators/app/compat.js +18 -7
- package/src/lib/nx-plugin/src/generators/app/compat.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/files/agents/AGENTS.md +11 -0
- package/src/lib/nx-plugin/src/generators/app/files/agents/CLAUDE.md +1 -0
- package/src/lib/nx-plugin/src/generators/app/files/root/tsconfig.base.json +3 -6
- package/src/lib/nx-plugin/src/generators/app/files/template-angular/src/test-setup.ts__template__ +1 -0
- package/src/lib/nx-plugin/src/generators/app/files/template-angular/tsconfig.app.json__template__ +1 -3
- package/src/lib/nx-plugin/src/generators/app/files/template-angular/tsconfig.json__template__ +2 -1
- package/src/lib/nx-plugin/src/generators/app/files/template-angular/vite.config.ts__template__ +6 -2
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/src/app/app.config.ts__template__ +0 -6
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/tsconfig.json__template__ +4 -2
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v17/vite.config.ts__template__ +1 -21
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/src/app/app.config.ts__template__ +0 -6
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/tsconfig.json__template__ +4 -2
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v18/vite.config.ts__template__ +2 -22
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/src/app/app.config.ts__template__ +0 -6
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/tsconfig.app.json__template__ +1 -3
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/tsconfig.json__template__ +4 -2
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v19/vite.config.ts__template__ +1 -12
- package/src/lib/nx-plugin/src/generators/app/generator.d.ts +11 -11
- package/src/lib/nx-plugin/src/generators/app/generator.js +81 -92
- package/src/lib/nx-plugin/src/generators/app/generator.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.d.ts +2 -0
- package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.js +16 -0
- package/src/lib/nx-plugin/src/generators/app/lib/add-agent-context.js.map +1 -0
- package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.js +73 -81
- package/src/lib/nx-plugin/src/generators/app/lib/add-analog-project-config.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.js +25 -58
- package/src/lib/nx-plugin/src/generators/app/lib/add-angular-app.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/app/lib/add-files.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/app/lib/add-files.js +16 -16
- package/src/lib/nx-plugin/src/generators/app/lib/add-files.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.js +15 -13
- package/src/lib/nx-plugin/src/generators/app/lib/add-home-page.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.d.ts +7 -7
- package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js +19 -29
- package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-config.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.d.ts +4 -5
- package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js +61 -103
- package/src/lib/nx-plugin/src/generators/app/lib/add-tailwind-helpers.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.js +17 -20
- package/src/lib/nx-plugin/src/generators/app/lib/cleanup-files.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.js +15 -18
- package/src/lib/nx-plugin/src/generators/app/lib/update-index-html.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/schema.d.ts +2 -0
- package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.d.ts +2 -3
- package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.js +7 -10
- package/src/lib/nx-plugin/src/generators/app/versions/minimum-supported-versions.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.d.ts +0 -3
- package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.d.ts +1 -6
- package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.d.ts +12 -17
- package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js +11 -37
- package/src/lib/nx-plugin/src/generators/app/versions/nx_18_X/versions.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js +11 -15
- package/src/lib/nx-plugin/src/generators/app/versions/tailwind-dependencies.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/app/versions.d.ts +0 -28
- package/src/lib/nx-plugin/src/generators/init/compat.d.ts +9 -3
- package/src/lib/nx-plugin/src/generators/init/compat.js +18 -7
- package/src/lib/nx-plugin/src/generators/init/compat.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/files/vite.config.ts__template__ +2 -6
- package/src/lib/nx-plugin/src/generators/init/generator.d.ts +3 -3
- package/src/lib/nx-plugin/src/generators/init/generator.js +55 -65
- package/src/lib/nx-plugin/src/generators/init/generator.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.js +20 -20
- package/src/lib/nx-plugin/src/generators/init/lib/add-analog-dependencies.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.js +21 -21
- package/src/lib/nx-plugin/src/generators/init/lib/update-app-tsconfig.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.js +57 -66
- package/src/lib/nx-plugin/src/generators/init/lib/update-build-target.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.js +12 -11
- package/src/lib/nx-plugin/src/generators/init/lib/update-git-ignore.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.js +18 -21
- package/src/lib/nx-plugin/src/generators/init/lib/update-index-html.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-main.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-main.js +13 -15
- package/src/lib/nx-plugin/src/generators/init/lib/update-main.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.js +20 -31
- package/src/lib/nx-plugin/src/generators/init/lib/update-package-json.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.js +44 -51
- package/src/lib/nx-plugin/src/generators/init/lib/update-serve-target.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.js +28 -34
- package/src/lib/nx-plugin/src/generators/init/lib/update-test-target.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.js +20 -20
- package/src/lib/nx-plugin/src/generators/init/lib/update-test-tsconfig.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/init/test-files/src/test-setup.ts__template__ +1 -0
- package/src/lib/nx-plugin/src/generators/page/__snapshots__/generator.spec.ts.snap +0 -7
- package/src/lib/nx-plugin/src/generators/page/compat.d.ts +9 -0
- package/src/lib/nx-plugin/src/generators/page/compat.js +19 -0
- package/src/lib/nx-plugin/src/generators/page/compat.js.map +1 -0
- package/src/lib/nx-plugin/src/generators/page/files/__fileName__.page.ts__template__ +0 -1
- package/src/lib/nx-plugin/src/generators/page/generator.d.ts +3 -4
- package/src/lib/nx-plugin/src/generators/page/generator.js +35 -44
- package/src/lib/nx-plugin/src/generators/page/generator.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/preset/__snapshots__/generator.spec.ts.snap +8 -7
- package/src/lib/nx-plugin/src/generators/preset/generator.d.ts +3 -3
- package/src/lib/nx-plugin/src/generators/preset/generator.js +24 -43
- package/src/lib/nx-plugin/src/generators/preset/generator.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/setup-vitest/compat.d.ts +9 -3
- package/src/lib/nx-plugin/src/generators/setup-vitest/compat.js +18 -7
- package/src/lib/nx-plugin/src/generators/setup-vitest/compat.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/setup-vitest/files/src/test-setup.ts__template__ +1 -0
- package/src/lib/nx-plugin/src/generators/setup-vitest/files/vite.config.mts__template__ +0 -6
- package/src/lib/nx-plugin/src/generators/setup-vitest/generator.d.ts +3 -3
- package/src/lib/nx-plugin/src/generators/setup-vitest/generator.js +33 -42
- package/src/lib/nx-plugin/src/generators/setup-vitest/generator.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.d.ts +1 -1
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.js +8 -7
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/add-analog-dependencies.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.js +21 -27
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-test-target.js.map +1 -1
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.d.ts +2 -2
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.js +20 -22
- package/src/lib/nx-plugin/src/generators/setup-vitest/lib/update-tsconfig.js.map +1 -1
- package/src/lib/nx-plugin/src/index.js +0 -2
- package/src/lib/nx-plugin/src/utils/version-utils.d.ts +1 -1
- package/src/lib/nx-plugin/src/utils/version-utils.js +21 -27
- package/src/lib/nx-plugin/src/utils/version-utils.js.map +1 -1
- package/src/lib/nx-plugin/src/utils/versions/dependencies.js +43 -62
- package/src/lib/nx-plugin/src/utils/versions/dependencies.js.map +1 -1
- package/src/lib/nx-plugin/src/utils/versions/dev-dependencies.js +50 -83
- package/src/lib/nx-plugin/src/utils/versions/dev-dependencies.js.map +1 -1
- package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.d.ts +1 -1
- package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.js +33 -20
- package/src/lib/nx-plugin/src/utils/versions/ng_17_X/versions.js.map +1 -1
- package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.d.ts +1 -1
- package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.js +33 -20
- package/src/lib/nx-plugin/src/utils/versions/ng_18_X/versions.js.map +1 -1
- package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.d.ts +9 -8
- package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js +39 -23
- package/src/lib/nx-plugin/src/utils/versions/ng_19_X/versions.js.map +1 -1
- package/src/lib/options.d.ts +165 -84
- package/src/lib/platform-plugin.d.ts +2 -2
- package/src/lib/platform-plugin.js +45 -65
- package/src/lib/platform-plugin.js.map +1 -0
- package/src/lib/route-file-discovery.d.ts +23 -0
- package/src/lib/route-file-discovery.js +114 -0
- package/src/lib/route-file-discovery.js.map +1 -0
- package/src/lib/route-generation-plugin.d.ts +3 -0
- package/src/lib/route-generation-plugin.js +45 -0
- package/src/lib/route-generation-plugin.js.map +1 -0
- package/src/lib/route-idiom-diagnostics.d.ts +13 -0
- package/src/lib/route-idiom-diagnostics.js +160 -0
- package/src/lib/route-idiom-diagnostics.js.map +1 -0
- package/src/lib/route-manifest.d.ts +122 -0
- package/src/lib/route-manifest.js +431 -0
- package/src/lib/route-manifest.js.map +1 -0
- package/src/lib/router-plugin.d.ts +19 -19
- package/src/lib/router-plugin.js +229 -185
- package/src/lib/router-plugin.js.map +1 -0
- package/src/lib/server-fn-client-transform.d.ts +26 -0
- package/src/lib/server-fn-client-transform.js +97 -0
- package/src/lib/server-fn-client-transform.js.map +1 -0
- package/src/lib/server-fn-id.d.ts +25 -0
- package/src/lib/server-fn-id.js +37 -0
- package/src/lib/server-fn-id.js.map +1 -0
- package/src/lib/ssr/defer-streaming-plugin.d.ts +65 -0
- package/src/lib/ssr/inject-html-plugin.d.ts +1 -1
- package/src/lib/ssr/inject-html-plugin.js +25 -25
- package/src/lib/ssr/inject-html-plugin.js.map +1 -0
- package/src/lib/ssr/ssr-build-plugin.d.ts +24 -16
- package/src/lib/ssr/ssr-build-plugin.js +37 -88
- package/src/lib/ssr/ssr-build-plugin.js.map +1 -0
- package/src/lib/typed-routes-plugin.d.ts +50 -0
- package/src/lib/typed-routes-plugin.js +234 -0
- package/src/lib/typed-routes-plugin.js.map +1 -0
- package/src/lib/utils/debug-harness.d.ts +23 -0
- package/src/lib/utils/debug-harness.js +88 -0
- package/src/lib/utils/debug-harness.js.map +1 -0
- package/src/lib/utils/debug-log-file.d.ts +5 -0
- package/src/lib/utils/debug-log-file.js +56 -0
- package/src/lib/utils/debug-log-file.js.map +1 -0
- package/src/lib/utils/debug.d.ts +20 -0
- package/src/lib/utils/debug.js +24 -0
- package/src/lib/utils/debug.js.map +1 -0
- package/src/lib/utils/rolldown.d.ts +2 -2
- package/src/lib/utils/rolldown.js +12 -8
- package/src/lib/utils/rolldown.js.map +1 -0
- package/src/server-mode-plugin.d.ts +5 -5
- package/src/server-mode-plugin.js +16 -20
- package/src/server-mode-plugin.js.map +1 -0
- package/README.md +0 -5
- package/src/lib/content/prism/options.js +0 -1
- package/src/lib/content/shiki/options.js +0 -1
- package/src/lib/nx-plugin/README.md +0 -23
- package/src/lib/nx-plugin/src/executors/vite/compat.d.ts +0 -3
- package/src/lib/nx-plugin/src/executors/vite/compat.js +0 -8
- package/src/lib/nx-plugin/src/executors/vite/compat.js.map +0 -1
- package/src/lib/nx-plugin/src/executors/vite/schema.d.ts +0 -2
- package/src/lib/nx-plugin/src/executors/vite/schema.json +0 -147
- package/src/lib/nx-plugin/src/executors/vite/vite.impl.d.ts +0 -2
- package/src/lib/nx-plugin/src/executors/vite/vite.impl.js +0 -5
- package/src/lib/nx-plugin/src/executors/vite/vite.impl.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/files/tailwind/v4/.postcssrc.json +0 -5
- package/src/lib/nx-plugin/src/generators/app/files/tailwind/v4/tailwind.config.ts__template__ +0 -14
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/index.html__template__ +0 -15
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.spec.ts__template__ +0 -17
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/app/app.component.ts__template__ +0 -10
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/favicon.ico__template__ +0 -0
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.providers.ts__template__ +0 -5
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.server.ts__template__ +0 -23
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/main.ts__template__ +0 -17
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/.gitkeep__template__ +0 -0
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/analog.svg__template__ +0 -1
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/public/assets/vite.svg__template__ +0 -1
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/server/routes/v1/hello.ts__template__ +0 -3
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/styles.css__template__ +0 -4
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/test-setup.ts__template__ +0 -12
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/src/vite-env.d.ts__template__ +0 -1
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.app.json__template__ +0 -16
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.editor.json__template__ +0 -7
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.json__template__ +0 -32
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/tsconfig.spec.json__template__ +0 -14
- package/src/lib/nx-plugin/src/generators/app/files/template-angular-v15/vite.config.ts__template__ +0 -69
- package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.js +0 -15
- package/src/lib/nx-plugin/src/generators/app/lib/add-analog-dependencies.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.js +0 -58
- package/src/lib/nx-plugin/src/generators/app/lib/add-eslint.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.js +0 -47
- package/src/lib/nx-plugin/src/generators/app/lib/add-vite-plugin.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.js +0 -110
- package/src/lib/nx-plugin/src/generators/app/lib/initialize-analog-workspace.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/versions/dependencies.js +0 -56
- package/src/lib/nx-plugin/src/generators/app/versions/dependencies.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/versions/dev-dependencies.js +0 -72
- package/src/lib/nx-plugin/src/generators/app/versions/dev-dependencies.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.js +0 -46
- package/src/lib/nx-plugin/src/generators/app/versions/nx-dependencies.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.js +0 -37
- package/src/lib/nx-plugin/src/generators/app/versions/nx_17_X/versions.js.map +0 -1
- package/src/lib/nx-plugin/src/generators/app/versions.js +0 -43
- package/src/lib/nx-plugin/src/generators/app/versions.js.map +0 -1
- package/src/lib/nx-plugin/src/index.d.ts +0 -0
- package/src/lib/nx-plugin/src/index.js.map +0 -1
- package/src/lib/options.js +0 -1
package/src/lib/router-plugin.js
CHANGED
|
@@ -1,192 +1,236 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { analyzeAnalogRouteFile, formatAnalogRouteIdiomDiagnostic } from "./route-idiom-diagnostics.js";
|
|
2
|
+
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { normalizePath } from "vite";
|
|
5
|
+
import { globSync } from "tinyglobby";
|
|
6
|
+
//#region packages/platform/src/lib/router-plugin.ts
|
|
4
7
|
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
8
|
+
* Router plugin that handles route file discovery and hot module replacement.
|
|
9
|
+
*
|
|
10
|
+
* This plugin provides three main functionalities:
|
|
11
|
+
* 1. Route invalidation when files are added/deleted (HMR workaround)
|
|
12
|
+
* 2. Dynamic route file discovery and import generation
|
|
13
|
+
* 3. Content route file discovery for markdown and Analog content
|
|
14
|
+
*
|
|
15
|
+
* @param options Configuration options for the router plugin
|
|
16
|
+
* @returns Array of Vite plugins for route handling
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT: This plugin uses tinyglobby for file discovery.
|
|
19
|
+
* Key behavior with { dot: true, absolute: true }:
|
|
20
|
+
* - Returns absolute paths for ALL discovered files
|
|
21
|
+
* - Path normalization is required to match expected output format
|
|
22
|
+
* - Files within project root must use relative paths in object keys
|
|
23
|
+
* - Files outside project root keep absolute paths in object keys
|
|
24
|
+
*/
|
|
25
|
+
function routerPlugin(options) {
|
|
26
|
+
const workspaceRoot = normalizePath(options?.workspaceRoot ?? process.env["NX_WORKSPACE_ROOT"] ?? process.cwd());
|
|
27
|
+
let config;
|
|
28
|
+
let root;
|
|
29
|
+
const normalizeWatchedDir = (dir) => {
|
|
30
|
+
const normalizedDir = normalizePath(dir.startsWith(`${workspaceRoot}/`) || dir === workspaceRoot ? dir : dir.startsWith("/") ? `${workspaceRoot}${dir}` : resolve(workspaceRoot, dir));
|
|
31
|
+
return normalizedDir.endsWith("/") ? normalizedDir.slice(0, -1) : normalizedDir;
|
|
32
|
+
};
|
|
33
|
+
const additionalPagesDirs = (options?.additionalPagesDirs || []).map((dir) => normalizeWatchedDir(dir));
|
|
34
|
+
const additionalContentDirs = (options?.additionalContentDirs || []).map((dir) => normalizeWatchedDir(dir));
|
|
35
|
+
const getRouteLikeDirs = () => [
|
|
36
|
+
...root ? [
|
|
37
|
+
normalizeWatchedDir(`${root}/app/routes`),
|
|
38
|
+
normalizeWatchedDir(`${root}/src/app/routes`),
|
|
39
|
+
normalizeWatchedDir(`${root}/src/app/pages`),
|
|
40
|
+
normalizeWatchedDir(`${root}/src/content`)
|
|
41
|
+
] : [],
|
|
42
|
+
"/app/routes",
|
|
43
|
+
"/src/app/routes",
|
|
44
|
+
"/src/app/pages",
|
|
45
|
+
"/src/content",
|
|
46
|
+
...additionalPagesDirs,
|
|
47
|
+
...additionalContentDirs
|
|
48
|
+
];
|
|
49
|
+
let routeFilesCache;
|
|
50
|
+
let pageRouteFilesCache;
|
|
51
|
+
let contentRouteFilesCache;
|
|
52
|
+
let endpointFilesCache;
|
|
53
|
+
const routeDiagnosticCache = /* @__PURE__ */ new Map();
|
|
54
|
+
const isRouteLikeFile = (path) => {
|
|
55
|
+
const normalizedPath = normalizePath(path);
|
|
56
|
+
return getRouteLikeDirs().some((dir) => normalizedPath === dir || normalizedPath.startsWith(`${dir}/`));
|
|
57
|
+
};
|
|
58
|
+
const discoverRouteFiles = () => {
|
|
59
|
+
routeFilesCache ??= globSync([
|
|
60
|
+
`${root}/app/routes/**/*.ts`,
|
|
61
|
+
`${root}/src/app/routes/**/*.ts`,
|
|
62
|
+
`${root}/src/app/pages/**/*.page.ts`,
|
|
63
|
+
...additionalPagesDirs.map((dir) => `${dir}/**/*.page.ts`)
|
|
64
|
+
], {
|
|
65
|
+
dot: true,
|
|
66
|
+
absolute: true
|
|
67
|
+
});
|
|
68
|
+
return routeFilesCache;
|
|
69
|
+
};
|
|
70
|
+
const discoverContentRouteFiles = () => {
|
|
71
|
+
contentRouteFilesCache ??= globSync([
|
|
72
|
+
`${root}/src/app/routes/**/*.md`,
|
|
73
|
+
`${root}/src/app/pages/**/*.md`,
|
|
74
|
+
`${root}/src/content/**/*.md`,
|
|
75
|
+
...additionalContentDirs.map((dir) => `${dir}/**/*.md`)
|
|
76
|
+
], {
|
|
77
|
+
dot: true,
|
|
78
|
+
absolute: true
|
|
79
|
+
});
|
|
80
|
+
return contentRouteFilesCache;
|
|
81
|
+
};
|
|
82
|
+
const discoverEndpointFiles = () => {
|
|
83
|
+
endpointFilesCache ??= globSync([`${root}/src/app/pages/**/*.server.ts`, ...additionalPagesDirs.map((dir) => `${dir}/**/*.server.ts`)], {
|
|
84
|
+
dot: true,
|
|
85
|
+
absolute: true
|
|
86
|
+
});
|
|
87
|
+
return endpointFilesCache;
|
|
88
|
+
};
|
|
89
|
+
const discoverPageRouteFiles = () => {
|
|
90
|
+
pageRouteFilesCache ??= discoverRouteFiles().filter((file) => file.endsWith(".page.ts"));
|
|
91
|
+
return pageRouteFilesCache;
|
|
92
|
+
};
|
|
93
|
+
const invalidateDiscoveryCaches = () => {
|
|
94
|
+
routeFilesCache = void 0;
|
|
95
|
+
pageRouteFilesCache = void 0;
|
|
96
|
+
contentRouteFilesCache = void 0;
|
|
97
|
+
endpointFilesCache = void 0;
|
|
98
|
+
};
|
|
99
|
+
const reportRouteDiagnostics = (path) => {
|
|
100
|
+
if (!path.endsWith(".page.ts")) return;
|
|
101
|
+
try {
|
|
102
|
+
const rendered = analyzeAnalogRouteFile({
|
|
103
|
+
filename: path,
|
|
104
|
+
code: readFileSync(path, "utf-8"),
|
|
105
|
+
routeFiles: discoverPageRouteFiles()
|
|
106
|
+
}).map((diagnostic) => formatAnalogRouteIdiomDiagnostic(diagnostic, path, workspaceRoot));
|
|
107
|
+
const fingerprint = rendered.join("\n\n");
|
|
108
|
+
if (!fingerprint) {
|
|
109
|
+
routeDiagnosticCache.delete(path);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (routeDiagnosticCache.get(path) === fingerprint) return;
|
|
113
|
+
routeDiagnosticCache.set(path, fingerprint);
|
|
114
|
+
rendered.forEach((message) => console.warn(message));
|
|
115
|
+
} catch {
|
|
116
|
+
routeDiagnosticCache.delete(path);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const getModuleKey = (module) => {
|
|
120
|
+
if (!root) return `/${normalizePath(relative(workspaceRoot, module))}`;
|
|
121
|
+
const relToRoot = normalizePath(relative(root, module));
|
|
122
|
+
if (!relToRoot.startsWith("..") && !isAbsolute(relToRoot)) return `/${relToRoot}`;
|
|
123
|
+
return `/${normalizePath(relative(workspaceRoot, module))}`;
|
|
124
|
+
};
|
|
125
|
+
const invalidateFileModules = (server, path) => {
|
|
126
|
+
const normalizedPath = normalizePath(path);
|
|
127
|
+
(server.moduleGraph.getModulesByFile?.(normalizedPath) ?? server.moduleGraph.fileToModulesMap.get(normalizedPath))?.forEach((mod) => {
|
|
128
|
+
server.moduleGraph.invalidateModule(mod);
|
|
129
|
+
mod.importers.forEach((imp) => {
|
|
130
|
+
server.moduleGraph.invalidateModule(imp);
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
return [
|
|
135
|
+
{
|
|
136
|
+
name: "analogjs-router-invalidate-routes",
|
|
137
|
+
configureServer(server) {
|
|
138
|
+
/**
|
|
139
|
+
* Invalidates route modules when files are added or deleted.
|
|
140
|
+
* This is a workaround for Vite's HMR limitations with dynamic imports.
|
|
141
|
+
*
|
|
142
|
+
* @param path The file path that was added or deleted
|
|
143
|
+
*/
|
|
144
|
+
function invalidateRoutes(path, event) {
|
|
145
|
+
if (!isRouteLikeFile(path)) return;
|
|
146
|
+
if (event !== "change") invalidateDiscoveryCaches();
|
|
147
|
+
if (event === "change") reportRouteDiagnostics(path);
|
|
148
|
+
else if (event === "unlink") {
|
|
149
|
+
routeDiagnosticCache.delete(path);
|
|
150
|
+
discoverPageRouteFiles().forEach((file) => reportRouteDiagnostics(file));
|
|
151
|
+
} else discoverPageRouteFiles().forEach((file) => reportRouteDiagnostics(file));
|
|
152
|
+
invalidateFileModules(server, path);
|
|
153
|
+
if (event === "change") return;
|
|
154
|
+
server.moduleGraph.fileToModulesMap.forEach((mods) => {
|
|
155
|
+
mods.forEach((mod) => {
|
|
156
|
+
if (mod.id?.includes("analogjs") && mod.id?.includes("fesm")) {
|
|
157
|
+
server.moduleGraph.invalidateModule(mod);
|
|
158
|
+
mod.importers.forEach((imp) => {
|
|
159
|
+
server.moduleGraph.invalidateModule(imp);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
server.ws.send("analog:debug-full-reload", {
|
|
165
|
+
plugin: "platform:router-plugin",
|
|
166
|
+
reason: "route-graph-shape-changed",
|
|
167
|
+
event,
|
|
168
|
+
path
|
|
169
|
+
});
|
|
170
|
+
server.ws.send({ type: "full-reload" });
|
|
171
|
+
}
|
|
172
|
+
server.watcher.on("add", (path) => invalidateRoutes(path, "add"));
|
|
173
|
+
server.watcher.on("change", (path) => invalidateRoutes(path, "change"));
|
|
174
|
+
server.watcher.on("unlink", (path) => invalidateRoutes(path, "unlink"));
|
|
175
|
+
for (const dir of [...additionalPagesDirs, ...additionalContentDirs]) server.watcher.add(dir);
|
|
176
|
+
discoverPageRouteFiles().forEach((file) => reportRouteDiagnostics(file));
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: "analog-glob-routes",
|
|
181
|
+
enforce: "post",
|
|
182
|
+
config(_config) {
|
|
183
|
+
config = _config;
|
|
184
|
+
root = normalizePath(resolve(workspaceRoot, config.root || ".") || ".");
|
|
185
|
+
},
|
|
186
|
+
transform: {
|
|
187
|
+
filter: { code: "_ROUTE_FILES" },
|
|
188
|
+
handler(code) {
|
|
189
|
+
if (code.includes("ANALOG_ROUTE_FILES") || code.includes("ANALOG_CONTENT_ROUTE_FILES")) {
|
|
190
|
+
const routeFiles = discoverRouteFiles();
|
|
191
|
+
const contentRouteFiles = discoverContentRouteFiles();
|
|
192
|
+
let result = code.replace("ANALOG_ROUTE_FILES = {};", `
|
|
121
193
|
ANALOG_ROUTE_FILES = {${routeFiles.map((module) => {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const key = module.startsWith(root)
|
|
125
|
-
? module.replace(root, '')
|
|
126
|
-
: module;
|
|
127
|
-
return `"${key}": () => import('${module}')`;
|
|
128
|
-
})}};
|
|
194
|
+
return `"${getModuleKey(module)}": () => import('${module}')`;
|
|
195
|
+
})}};
|
|
129
196
|
`);
|
|
130
|
-
|
|
197
|
+
result = result.replace("ANALOG_CONTENT_ROUTE_FILES = {};", `
|
|
131
198
|
ANALOG_CONTENT_ROUTE_FILES = {${contentRouteFiles.map((module) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
? module.replace(root, '')
|
|
135
|
-
: module;
|
|
136
|
-
return `"${key}": () => import('${module}?analog-content-file=true').then(m => m.default)`;
|
|
137
|
-
})}};
|
|
199
|
+
return `"${getModuleKey(module)}": () => import('${module}?analog-content-file=true').then(m => m.default)`;
|
|
200
|
+
})}};
|
|
138
201
|
`);
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
* @param code The source code to transform
|
|
159
|
-
* @returns Transformed code with dynamic imports or undefined if no transformation needed
|
|
160
|
-
*/
|
|
161
|
-
transform: {
|
|
162
|
-
filter: {
|
|
163
|
-
code: 'ANALOG_PAGE_ENDPOINTS',
|
|
164
|
-
},
|
|
165
|
-
handler(code) {
|
|
166
|
-
if (code.includes('ANALOG_PAGE_ENDPOINTS')) {
|
|
167
|
-
// Discover server endpoint files using tinyglobby
|
|
168
|
-
const endpointFiles = globSync([
|
|
169
|
-
`${root}/src/app/pages/**/*.server.ts`,
|
|
170
|
-
...(options?.additionalPagesDirs || []).map((glob) => `${workspaceRoot}${glob}/**/*.server.ts`),
|
|
171
|
-
], { dot: true, absolute: true });
|
|
172
|
-
const result = code.replace('ANALOG_PAGE_ENDPOINTS = {};', `
|
|
202
|
+
result = result.replace("ANALOG_CONTENT_FILE_COUNT = 0", `ANALOG_CONTENT_FILE_COUNT = ${contentRouteFiles.length}`);
|
|
203
|
+
return {
|
|
204
|
+
code: result,
|
|
205
|
+
map: { mappings: "" }
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: "analog-glob-endpoints",
|
|
213
|
+
enforce: "post",
|
|
214
|
+
transform: {
|
|
215
|
+
filter: { code: "ANALOG_PAGE_ENDPOINTS" },
|
|
216
|
+
handler(code) {
|
|
217
|
+
if (code.includes("ANALOG_PAGE_ENDPOINTS")) {
|
|
218
|
+
const endpointFiles = discoverEndpointFiles();
|
|
219
|
+
return {
|
|
220
|
+
code: code.replace("ANALOG_PAGE_ENDPOINTS = {};", `
|
|
173
221
|
ANALOG_PAGE_ENDPOINTS = {${endpointFiles.map((module) => {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
|
-
return;
|
|
187
|
-
},
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
];
|
|
222
|
+
return `"${getModuleKey(module)}": () => import('${module}')`;
|
|
223
|
+
})}};
|
|
224
|
+
`),
|
|
225
|
+
map: { mappings: "" }
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
];
|
|
191
232
|
}
|
|
192
|
-
//#
|
|
233
|
+
//#endregion
|
|
234
|
+
export { routerPlugin };
|
|
235
|
+
|
|
236
|
+
//# sourceMappingURL=router-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router-plugin.js","names":[],"sources":["../../../src/lib/router-plugin.ts"],"sourcesContent":["import { normalizePath, Plugin, UserConfig, ViteDevServer } from 'vite';\nimport { globSync } from 'tinyglobby';\nimport { readFileSync } from 'node:fs';\nimport { isAbsolute, relative, resolve } from 'node:path';\n\nimport { Options } from './options.js';\nimport {\n analyzeAnalogRouteFile,\n formatAnalogRouteIdiomDiagnostic,\n} from './route-idiom-diagnostics.js';\n\n/**\n * Router plugin that handles route file discovery and hot module replacement.\n *\n * This plugin provides three main functionalities:\n * 1. Route invalidation when files are added/deleted (HMR workaround)\n * 2. Dynamic route file discovery and import generation\n * 3. Content route file discovery for markdown and Analog content\n *\n * @param options Configuration options for the router plugin\n * @returns Array of Vite plugins for route handling\n *\n * IMPORTANT: This plugin uses tinyglobby for file discovery.\n * Key behavior with { dot: true, absolute: true }:\n * - Returns absolute paths for ALL discovered files\n * - Path normalization is required to match expected output format\n * - Files within project root must use relative paths in object keys\n * - Files outside project root keep absolute paths in object keys\n */\nexport function routerPlugin(options?: Options): Plugin[] {\n const workspaceRoot = normalizePath(\n options?.workspaceRoot ?? process.env['NX_WORKSPACE_ROOT'] ?? process.cwd(),\n );\n let config: UserConfig;\n let root: string;\n // Option dirs are workspace-relative, often written with a leading `/`.\n // Normalize them once into absolute workspace paths so watcher events,\n // glob patterns, and key generation all compare against the same shape.\n const normalizeWatchedDir = (dir: string) => {\n const normalizedDir = normalizePath(\n dir.startsWith(`${workspaceRoot}/`) || dir === workspaceRoot\n ? dir\n : dir.startsWith('/')\n ? `${workspaceRoot}${dir}`\n : resolve(workspaceRoot, dir),\n );\n return normalizedDir.endsWith('/')\n ? normalizedDir.slice(0, -1)\n : normalizedDir;\n };\n // Computed eagerly — these depend only on `options` and `workspaceRoot`,\n // both of which are fixed at construction time.\n const additionalPagesDirs = (options?.additionalPagesDirs || []).map((dir) =>\n normalizeWatchedDir(dir),\n );\n const additionalContentDirs = (options?.additionalContentDirs || []).map(\n (dir) => normalizeWatchedDir(dir),\n );\n // Returns every directory that can contain route-like files. The root-\n // relative entries are only available after the Vite `config` hook sets\n // `root`. The short-form fallbacks (`/app/routes`, etc.) let watcher\n // events match before `config` runs — they cover the common convention\n // where paths start with these prefixes.\n const getRouteLikeDirs = () => [\n ...(root\n ? [\n normalizeWatchedDir(`${root}/app/routes`),\n normalizeWatchedDir(`${root}/src/app/routes`),\n normalizeWatchedDir(`${root}/src/app/pages`),\n normalizeWatchedDir(`${root}/src/content`),\n ]\n : []),\n '/app/routes',\n '/src/app/routes',\n '/src/app/pages',\n '/src/content',\n ...additionalPagesDirs,\n ...additionalContentDirs,\n ];\n // These lists are used repeatedly by transform hooks during serve. Keeping\n // them warm avoids a full glob on every route/content invalidation.\n let routeFilesCache: string[] | undefined;\n let pageRouteFilesCache: string[] | undefined;\n let contentRouteFilesCache: string[] | undefined;\n let endpointFilesCache: string[] | undefined;\n const routeDiagnosticCache = new Map<string, string>();\n const isRouteLikeFile = (path: string) => {\n // Watcher paths from chokidar are already absolute — `normalizePath`\n // (forward-slash only) is sufficient; `resolve()` would be a no-op.\n const normalizedPath = normalizePath(path);\n\n return getRouteLikeDirs().some(\n (dir) => normalizedPath === dir || normalizedPath.startsWith(`${dir}/`),\n );\n };\n const discoverRouteFiles = () => {\n routeFilesCache ??= globSync(\n [\n `${root}/app/routes/**/*.ts`,\n `${root}/src/app/routes/**/*.ts`,\n `${root}/src/app/pages/**/*.page.ts`,\n ...additionalPagesDirs.map((dir) => `${dir}/**/*.page.ts`),\n ],\n { dot: true, absolute: true },\n );\n\n return routeFilesCache;\n };\n const discoverContentRouteFiles = () => {\n contentRouteFilesCache ??= globSync(\n [\n `${root}/src/app/routes/**/*.md`,\n `${root}/src/app/pages/**/*.md`,\n `${root}/src/content/**/*.md`,\n ...additionalContentDirs.map((dir) => `${dir}/**/*.md`),\n ],\n { dot: true, absolute: true },\n );\n\n return contentRouteFilesCache;\n };\n const discoverEndpointFiles = () => {\n endpointFilesCache ??= globSync(\n [\n `${root}/src/app/pages/**/*.server.ts`,\n ...additionalPagesDirs.map((dir) => `${dir}/**/*.server.ts`),\n ],\n { dot: true, absolute: true },\n );\n\n return endpointFilesCache;\n };\n const discoverPageRouteFiles = () => {\n pageRouteFilesCache ??= discoverRouteFiles().filter((file) =>\n file.endsWith('.page.ts'),\n );\n\n return pageRouteFilesCache;\n };\n const invalidateDiscoveryCaches = () => {\n routeFilesCache = undefined;\n pageRouteFilesCache = undefined;\n contentRouteFilesCache = undefined;\n endpointFilesCache = undefined;\n };\n const reportRouteDiagnostics = (path: string) => {\n if (!path.endsWith('.page.ts')) {\n return;\n }\n\n try {\n const code = readFileSync(path, 'utf-8');\n const routeFiles = discoverPageRouteFiles();\n const diagnostics = analyzeAnalogRouteFile({\n filename: path,\n code,\n routeFiles,\n });\n\n const rendered = diagnostics.map((diagnostic) =>\n formatAnalogRouteIdiomDiagnostic(diagnostic, path, workspaceRoot),\n );\n const fingerprint = rendered.join('\\n\\n');\n\n if (!fingerprint) {\n routeDiagnosticCache.delete(path);\n return;\n }\n\n if (routeDiagnosticCache.get(path) === fingerprint) {\n return;\n }\n\n routeDiagnosticCache.set(path, fingerprint);\n rendered.forEach((message) => console.warn(message));\n } catch {\n routeDiagnosticCache.delete(path);\n }\n };\n const getModuleKey = (module: string) => {\n // Before config sets `root`, fall back to workspace-relative keys.\n if (!root) {\n return `/${normalizePath(relative(workspaceRoot, module))}`;\n }\n\n const relToRoot = normalizePath(relative(root, module));\n // Use true path containment instead of a raw prefix check so siblings like\n // `/apps/my-app-tools/...` are not mistaken for files inside `/apps/my-app`.\n const isInRoot = !relToRoot.startsWith('..') && !isAbsolute(relToRoot);\n\n if (isInRoot) {\n return `/${relToRoot}`;\n }\n\n return `/${normalizePath(relative(workspaceRoot, module))}`;\n };\n const invalidateFileModules = (server: ViteDevServer, path: string) => {\n const normalizedPath = normalizePath(path);\n // A newly added page can be discovered before its final contents settle.\n // Invalidate the page module itself so later edits don't keep serving the\n // first incomplete transform from Vite's module graph.\n const fileModules =\n server.moduleGraph.getModulesByFile?.(normalizedPath) ??\n server.moduleGraph.fileToModulesMap.get(normalizedPath);\n\n fileModules?.forEach((mod) => {\n server.moduleGraph.invalidateModule(mod);\n\n mod.importers.forEach((imp) => {\n server.moduleGraph.invalidateModule(imp);\n });\n });\n };\n\n return [\n {\n name: 'analogjs-router-invalidate-routes',\n configureServer(server) {\n /**\n * Invalidates route modules when files are added or deleted.\n * This is a workaround for Vite's HMR limitations with dynamic imports.\n *\n * @param path The file path that was added or deleted\n */\n function invalidateRoutes(\n path: string,\n event: 'add' | 'change' | 'unlink',\n ) {\n if (!isRouteLikeFile(path)) {\n return;\n }\n\n // Add/remove changes the route graph shape, so the discovery caches\n // must be rebuilt. Plain edits can keep using the current file set.\n if (event !== 'change') {\n invalidateDiscoveryCaches();\n }\n\n if (event === 'change') {\n reportRouteDiagnostics(path);\n } else if (event === 'unlink') {\n routeDiagnosticCache.delete(path);\n discoverPageRouteFiles().forEach((file) =>\n reportRouteDiagnostics(file),\n );\n } else {\n discoverPageRouteFiles().forEach((file) =>\n reportRouteDiagnostics(file),\n );\n }\n\n invalidateFileModules(server, path);\n\n // For an in-place edit we only need module invalidation. Keeping the\n // app alive here lets Angular/Vite attempt the narrower HMR path.\n if (event === 'change') {\n return;\n }\n\n server.moduleGraph.fileToModulesMap.forEach((mods) => {\n mods.forEach((mod) => {\n if (mod.id?.includes('analogjs') && mod.id?.includes('fesm')) {\n server.moduleGraph.invalidateModule(mod);\n\n mod.importers.forEach((imp) => {\n server.moduleGraph.invalidateModule(imp);\n });\n }\n });\n });\n\n server.ws.send('analog:debug-full-reload', {\n plugin: 'platform:router-plugin',\n reason: 'route-graph-shape-changed',\n event,\n path,\n });\n server.ws.send({\n type: 'full-reload',\n });\n }\n\n server.watcher.on('add', (path) => invalidateRoutes(path, 'add'));\n server.watcher.on('change', (path) => invalidateRoutes(path, 'change'));\n server.watcher.on('unlink', (path) => invalidateRoutes(path, 'unlink'));\n\n // Vite's watcher only covers the app root by default.\n // additionalPagesDirs / additionalContentDirs live outside the\n // root (e.g. libs/shared/feature in a monorepo), so file\n // add/rename/delete events are never fired for them. Explicitly\n // add these directories to chokidar so route invalidation works.\n for (const dir of [...additionalPagesDirs, ...additionalContentDirs]) {\n server.watcher.add(dir);\n }\n\n discoverPageRouteFiles().forEach((file) =>\n reportRouteDiagnostics(file),\n );\n },\n },\n {\n name: 'analog-glob-routes',\n // enforce: 'post' ensures this transform runs AFTER the Angular compiler\n // plugin, which replaces module content with its own compiled output.\n // Without this, the Angular plugin would overwrite the route replacements.\n enforce: 'post',\n config(_config) {\n config = _config;\n root = normalizePath(resolve(workspaceRoot, config.root || '.') || '.');\n },\n /**\n * Transforms code to replace ANALOG_ROUTE_FILES and ANALOG_CONTENT_ROUTE_FILES\n * placeholders with actual dynamic imports of discovered route and content files.\n *\n * @param code The source code to transform\n * @returns Transformed code with dynamic imports or undefined if no transformation needed\n */\n // Vite 8 / Rolldown filtered transform: the `filter.code` substring\n // pre-filter lets the bundler skip modules that don't contain the\n // marker. '_ROUTE_FILES' is a common substring of both\n // 'ANALOG_ROUTE_FILES' and 'ANALOG_CONTENT_ROUTE_FILES'.\n //\n // IMPORTANT: Do NOT change this to 'ANALOG_ROUTE_FILES' — that is NOT\n // a substring of 'ANALOG_CONTENT_ROUTE_FILES' (they diverge at\n // position 7: 'ANALOG_C...' vs 'ANALOG_R...'). When tsconfig path\n // aliases resolve @analogjs/router and @analogjs/router/content to\n // separate source files, each variable lives in its own module and\n // the filter must match both independently.\n transform: {\n filter: {\n code: '_ROUTE_FILES',\n },\n handler(code) {\n if (\n code.includes('ANALOG_ROUTE_FILES') ||\n code.includes('ANALOG_CONTENT_ROUTE_FILES')\n ) {\n // Discover route files using tinyglobby\n // NOTE: { absolute: true } returns absolute paths for ALL files\n const routeFiles = discoverRouteFiles();\n\n // Discover content files using tinyglobby\n const contentRouteFiles = discoverContentRouteFiles();\n\n let result = code.replace(\n 'ANALOG_ROUTE_FILES = {};',\n `\n ANALOG_ROUTE_FILES = {${routeFiles.map((module) => {\n // Keys are app-root-relative for in-app files,\n // workspace-relative for library files (additionalPagesDirs).\n // import() keeps absolute paths for Vite's module resolution.\n const key = getModuleKey(module);\n return `\"${key}\": () => import('${module}')`;\n })}};\n `,\n );\n\n result = result.replace(\n 'ANALOG_CONTENT_ROUTE_FILES = {};',\n `\n ANALOG_CONTENT_ROUTE_FILES = {${contentRouteFiles.map((module) => {\n const key = getModuleKey(module);\n return `\"${key}\": () => import('${module}?analog-content-file=true').then(m => m.default)`;\n })}};\n `,\n );\n\n result = result.replace(\n 'ANALOG_CONTENT_FILE_COUNT = 0',\n `ANALOG_CONTENT_FILE_COUNT = ${contentRouteFiles.length}`,\n );\n\n return {\n code: result,\n map: { mappings: '' },\n };\n }\n\n return;\n },\n },\n },\n {\n name: 'analog-glob-endpoints',\n // enforce: 'post' ensures this transform runs AFTER the Angular compiler\n // plugin, which replaces module content with its own compiled output.\n // Without this, the Angular plugin would overwrite the endpoint replacements.\n enforce: 'post',\n /**\n * Transforms code to replace ANALOG_PAGE_ENDPOINTS placeholder\n * with actual dynamic imports of discovered server endpoint files.\n *\n * @param code The source code to transform\n * @returns Transformed code with dynamic imports or undefined if no transformation needed\n */\n transform: {\n filter: {\n code: 'ANALOG_PAGE_ENDPOINTS',\n },\n handler(code) {\n if (code.includes('ANALOG_PAGE_ENDPOINTS')) {\n // Discover server endpoint files using tinyglobby\n const endpointFiles = discoverEndpointFiles();\n\n const result = code.replace(\n 'ANALOG_PAGE_ENDPOINTS = {};',\n `\n ANALOG_PAGE_ENDPOINTS = {${endpointFiles.map((module) => {\n const key = getModuleKey(module);\n return `\"${key}\": () => import('${module}')`;\n })}};\n `,\n );\n\n return {\n code: result,\n map: { mappings: '' },\n };\n }\n\n return;\n },\n },\n },\n ];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-build scrub + proxy generation for server functions.
|
|
3
|
+
*
|
|
4
|
+
* On the client build a `*.server.ts` module must not carry server handler
|
|
5
|
+
* bodies (which `inject()` server services, read the request, hit the database).
|
|
6
|
+
* But the client still imports the named `serverFn` exports to dispatch them.
|
|
7
|
+
* This transform regenerates the module so each `export const NAME = serverFn(
|
|
8
|
+
* config, handler)` becomes a call to the client-safe `createServerFnRef`
|
|
9
|
+
* factory — keeping the `{ id, url, method }` metadata `injectServerFn` needs,
|
|
10
|
+
* dropping the handler and every server-only import. Because the regenerated
|
|
11
|
+
* module references nothing else, the server code tree-shakes away entirely.
|
|
12
|
+
*
|
|
13
|
+
* Returns the new module source, or `null` when the module defines no server
|
|
14
|
+
* function (the caller falls back to the page-endpoint scrub for those).
|
|
15
|
+
*/
|
|
16
|
+
export interface ServerFnProxy {
|
|
17
|
+
name: string;
|
|
18
|
+
id: string;
|
|
19
|
+
method: "GET" | "POST";
|
|
20
|
+
}
|
|
21
|
+
export interface ScrubResult {
|
|
22
|
+
code: string;
|
|
23
|
+
proxies: ServerFnProxy[];
|
|
24
|
+
hadDefaultExport: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function scrubServerFnModule(code: string, fileId?: string): ScrubResult | null;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { deriveServerFnId } from "./server-fn-id.js";
|
|
2
|
+
import { parseSync } from "oxc-parser";
|
|
3
|
+
//#region packages/platform/src/lib/server-fn-client-transform.ts
|
|
4
|
+
var SERVER_FN_SOURCE = "@analogjs/router/server";
|
|
5
|
+
function scrubServerFnModule(code, fileId = "file.ts") {
|
|
6
|
+
if (!code.includes("serverFn")) return null;
|
|
7
|
+
const { program } = parseSync(fileId, code);
|
|
8
|
+
const body = program.body;
|
|
9
|
+
const serverFnLocalNames = collectServerFnLocalNames(body);
|
|
10
|
+
const hadDefaultExport = body.some((node) => node.type === "ExportDefaultDeclaration");
|
|
11
|
+
const proxies = [];
|
|
12
|
+
for (const node of body) {
|
|
13
|
+
if (node.type !== "ExportNamedDeclaration" || node.declaration?.type !== "VariableDeclaration") continue;
|
|
14
|
+
for (const declarator of node.declaration.declarations) {
|
|
15
|
+
if (declarator.id?.type !== "Identifier" || declarator.init?.type !== "CallExpression" || declarator.init.callee?.type !== "Identifier" || !serverFnLocalNames.has(declarator.init.callee.name)) continue;
|
|
16
|
+
proxies.push(toProxy(declarator.id.name, declarator.init.arguments ?? [], fileId));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const callCount = countServerFnCalls(program, serverFnLocalNames);
|
|
20
|
+
if (callCount > proxies.length) throw new Error(`[analog] ${fileId}: found ${callCount} serverFn call(s) but could only rewrite ${proxies.length} for the client build. Server functions must be declared as a directly exported const — \`export const name = serverFn(…)\` — so the handler can be stripped from the browser bundle.`);
|
|
21
|
+
if (proxies.length === 0) return null;
|
|
22
|
+
const lines = [
|
|
23
|
+
`import { createServerFnRef } from '@analogjs/router';`,
|
|
24
|
+
"",
|
|
25
|
+
...proxies.map((p) => `export const ${p.name} = createServerFnRef({ id: ${JSON.stringify(p.id)}, method: ${JSON.stringify(p.method)} });`)
|
|
26
|
+
];
|
|
27
|
+
if (hadDefaultExport) lines.push("", "export default undefined;");
|
|
28
|
+
return {
|
|
29
|
+
code: lines.join("\n") + "\n",
|
|
30
|
+
proxies,
|
|
31
|
+
hadDefaultExport
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Local identifier(s) `serverFn` is imported under from `@analogjs/router/server`. */
|
|
35
|
+
function collectServerFnLocalNames(body) {
|
|
36
|
+
const names = /* @__PURE__ */ new Set();
|
|
37
|
+
for (const node of body) {
|
|
38
|
+
if (node.type !== "ImportDeclaration" || node.source?.value !== SERVER_FN_SOURCE) continue;
|
|
39
|
+
for (const spec of node.specifiers ?? []) if (spec.type === "ImportSpecifier" && spec.imported?.name === "serverFn") names.add(spec.local.name);
|
|
40
|
+
}
|
|
41
|
+
if (names.size === 0) names.add("serverFn");
|
|
42
|
+
return names;
|
|
43
|
+
}
|
|
44
|
+
function toProxy(name, args, fileId) {
|
|
45
|
+
const method = methodForCall(name, args, fileId);
|
|
46
|
+
return {
|
|
47
|
+
name,
|
|
48
|
+
id: deriveServerFnId(fileId, name),
|
|
49
|
+
method
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Resolve the HTTP method from the call shape, matching the runtime overloads:
|
|
54
|
+
* `serverFn(handler)` ⇒ GET, `serverFn(schema, handler)` ⇒ POST,
|
|
55
|
+
* `serverFn(config, handler)` ⇒ config-driven.
|
|
56
|
+
*/
|
|
57
|
+
function methodForCall(name, args, fileId) {
|
|
58
|
+
const arg0 = args[0];
|
|
59
|
+
if (isFunctionNode(arg0)) return "GET";
|
|
60
|
+
if (arg0?.type === "ObjectExpression") {
|
|
61
|
+
let method;
|
|
62
|
+
let hasInput = false;
|
|
63
|
+
for (const prop of arg0.properties ?? []) {
|
|
64
|
+
if (prop.type !== "Property") continue;
|
|
65
|
+
const key = prop.key?.type === "Identifier" ? prop.key.name : prop.key?.value;
|
|
66
|
+
if (key === "method" && isStringLiteral(prop.value)) method = prop.value.value;
|
|
67
|
+
else if (key === "input") hasInput = true;
|
|
68
|
+
}
|
|
69
|
+
if (method === "GET" && hasInput) throw new Error(`[analog] serverFn "${name}" in ${fileId} declares method: 'GET' with an input schema; GET carries no body. Use POST or drop the input.`);
|
|
70
|
+
return method ?? (hasInput ? "POST" : "GET");
|
|
71
|
+
}
|
|
72
|
+
if (arg0 && args.length >= 2) return "POST";
|
|
73
|
+
throw new Error(`[analog] serverFn "${name}" in ${fileId} must be called as serverFn(handler), serverFn(schema, handler), or serverFn(config, handler).`);
|
|
74
|
+
}
|
|
75
|
+
function isFunctionNode(node) {
|
|
76
|
+
return node?.type === "ArrowFunctionExpression" || node?.type === "FunctionExpression";
|
|
77
|
+
}
|
|
78
|
+
function isStringLiteral(node) {
|
|
79
|
+
return node?.type === "Literal" && typeof node.value === "string";
|
|
80
|
+
}
|
|
81
|
+
/** Every `serverFn(...)` call anywhere in the module, not just exported ones. */
|
|
82
|
+
function countServerFnCalls(node, names) {
|
|
83
|
+
if (!node || typeof node !== "object") return 0;
|
|
84
|
+
if (Array.isArray(node)) return node.reduce((total, child) => total + countServerFnCalls(child, names), 0);
|
|
85
|
+
const record = node;
|
|
86
|
+
let count = 0;
|
|
87
|
+
if (record.type === "CallExpression") {
|
|
88
|
+
const callee = record["callee"];
|
|
89
|
+
if (callee?.type === "Identifier" && callee.name && names.has(callee.name)) count += 1;
|
|
90
|
+
}
|
|
91
|
+
for (const key of Object.keys(record)) count += countServerFnCalls(record[key], names);
|
|
92
|
+
return count;
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { scrubServerFnModule };
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=server-fn-client-transform.js.map
|