@octanejs/tanstack-start 0.1.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/LICENSE +22 -0
- package/README.md +52 -0
- package/THIRD_PARTY_NOTICES.md +11 -0
- package/package.json +149 -0
- package/src/client-only.d.ts +1 -0
- package/src/client-only.js +0 -0
- package/src/client-rpc.d.ts +1 -0
- package/src/client-rpc.js +1 -0
- package/src/client.d.ts +3 -0
- package/src/client.js +2 -0
- package/src/default-entry/client.js +12 -0
- package/src/default-entry/server.js +13 -0
- package/src/default-entry/start.js +1 -0
- package/src/default-entry-paths.d.ts +5 -0
- package/src/default-entry-paths.js +11 -0
- package/src/index.d.ts +11 -0
- package/src/index.js +22 -0
- package/src/internal/README.md +15 -0
- package/src/internal/router-generator/config.d.ts +255 -0
- package/src/internal/router-generator/config.js +134 -0
- package/src/internal/router-generator/filesystem/physical/getRouteNodes.d.ts +53 -0
- package/src/internal/router-generator/filesystem/physical/getRouteNodes.js +335 -0
- package/src/internal/router-generator/filesystem/physical/rootPathId.d.ts +1 -0
- package/src/internal/router-generator/filesystem/physical/rootPathId.js +4 -0
- package/src/internal/router-generator/filesystem/virtual/config.d.ts +3 -0
- package/src/internal/router-generator/filesystem/virtual/config.js +36 -0
- package/src/internal/router-generator/filesystem/virtual/getRouteNodes.d.ts +31 -0
- package/src/internal/router-generator/filesystem/virtual/getRouteNodes.js +272 -0
- package/src/internal/router-generator/filesystem/virtual/loadConfigFile.d.ts +1 -0
- package/src/internal/router-generator/filesystem/virtual/loadConfigFile.js +10 -0
- package/src/internal/router-generator/generator.d.ts +119 -0
- package/src/internal/router-generator/generator.js +1080 -0
- package/src/internal/router-generator/index.d.ts +40 -0
- package/src/internal/router-generator/index.js +49 -0
- package/src/internal/router-generator/logger.d.ts +8 -0
- package/src/internal/router-generator/logger.js +30 -0
- package/src/internal/router-generator/plugin/types.d.ts +37 -0
- package/src/internal/router-generator/template.d.ts +38 -0
- package/src/internal/router-generator/template.js +220 -0
- package/src/internal/router-generator/transform/transform.d.ts +8 -0
- package/src/internal/router-generator/transform/transform.js +385 -0
- package/src/internal/router-generator/transform/types.d.ts +34 -0
- package/src/internal/router-generator/types.d.ts +73 -0
- package/src/internal/router-generator/utils.d.ts +270 -0
- package/src/internal/router-generator/utils.js +864 -0
- package/src/internal/router-generator/validate-route-params.d.ts +13 -0
- package/src/internal/router-generator/validate-route-params.js +75 -0
- package/src/internal/router-plugin/context.d.ts +2 -0
- package/src/internal/router-plugin/context.js +2 -0
- package/src/internal/router-plugin/core/code-splitter/compilers.d.ts +69 -0
- package/src/internal/router-plugin/core/code-splitter/compilers.js +1042 -0
- package/src/internal/router-plugin/core/code-splitter/framework-options.d.ts +11 -0
- package/src/internal/router-plugin/core/code-splitter/framework-options.js +41 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/framework-plugins.d.ts +12 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/framework-plugins.js +35 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/octane-hmr-split-route-components.d.ts +5 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/octane-hmr-split-route-components.js +106 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/octane-split-route-components.d.ts +8 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/octane-split-route-components.js +85 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.ts +2 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/react-refresh-ignored-route-exports.js +55 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/react-refresh-route-components.d.ts +2 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/react-refresh-route-components.js +50 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.ts +5 -0
- package/src/internal/router-plugin/core/code-splitter/plugins/react-stable-hmr-split-route-components.js +54 -0
- package/src/internal/router-plugin/core/code-splitter/plugins.d.ts +62 -0
- package/src/internal/router-plugin/core/code-splitter/types.d.ts +9 -0
- package/src/internal/router-plugin/core/config.d.ts +294 -0
- package/src/internal/router-plugin/core/config.js +56 -0
- package/src/internal/router-plugin/core/constants.d.ts +12 -0
- package/src/internal/router-plugin/core/constants.js +13 -0
- package/src/internal/router-plugin/core/framework-plugin-order.d.ts +8 -0
- package/src/internal/router-plugin/core/framework-plugin-order.js +78 -0
- package/src/internal/router-plugin/core/hmr/handle-route-update.d.ts +1 -0
- package/src/internal/router-plugin/core/hmr/handle-route-update.js +126 -0
- package/src/internal/router-plugin/core/hmr/index.d.ts +5 -0
- package/src/internal/router-plugin/core/hmr/select-adapter.d.ts +17 -0
- package/src/internal/router-plugin/core/hmr/select-adapter.js +24 -0
- package/src/internal/router-plugin/core/hmr/vite-adapter.d.ts +18 -0
- package/src/internal/router-plugin/core/hmr/vite-adapter.js +73 -0
- package/src/internal/router-plugin/core/hmr/webpack-adapter.d.ts +22 -0
- package/src/internal/router-plugin/core/hmr/webpack-adapter.js +78 -0
- package/src/internal/router-plugin/core/router-code-splitter-plugin.d.ts +10 -0
- package/src/internal/router-plugin/core/router-code-splitter-plugin.js +244 -0
- package/src/internal/router-plugin/core/router-composed-plugin.d.ts +5 -0
- package/src/internal/router-plugin/core/router-composed-plugin.js +62 -0
- package/src/internal/router-plugin/core/router-generator-plugin.d.ts +10 -0
- package/src/internal/router-plugin/core/router-generator-plugin.js +125 -0
- package/src/internal/router-plugin/core/router-hmr-plugin.d.ts +13 -0
- package/src/internal/router-plugin/core/router-hmr-plugin.js +101 -0
- package/src/internal/router-plugin/core/router-plugin-context.d.ts +5 -0
- package/src/internal/router-plugin/core/router-plugin-context.js +6 -0
- package/src/internal/router-plugin/core/utils.d.ts +17 -0
- package/src/internal/router-plugin/core/utils.js +47 -0
- package/src/internal/router-plugin/esbuild.d.ts +197 -0
- package/src/internal/router-plugin/esbuild.js +58 -0
- package/src/internal/router-plugin/index.d.ts +19 -0
- package/src/internal/router-plugin/index.js +17 -0
- package/src/internal/router-plugin/rspack.d.ts +61 -0
- package/src/internal/router-plugin/rspack.js +92 -0
- package/src/internal/router-plugin/vite.d.ts +201 -0
- package/src/internal/router-plugin/vite.js +62 -0
- package/src/internal/router-plugin/webpack.d.ts +50 -0
- package/src/internal/router-plugin/webpack.js +77 -0
- package/src/internal/start-plugin-core/build-sitemap.d.ts +34 -0
- package/src/internal/start-plugin-core/build-sitemap.js +125 -0
- package/src/internal/start-plugin-core/config-context.d.ts +30 -0
- package/src/internal/start-plugin-core/config-context.js +89 -0
- package/src/internal/start-plugin-core/constants.d.ts +20 -0
- package/src/internal/start-plugin-core/constants.js +24 -0
- package/src/internal/start-plugin-core/debug.d.ts +1 -0
- package/src/internal/start-plugin-core/hydrate-when-transform.d.ts +5 -0
- package/src/internal/start-plugin-core/hydrate-when-transform.js +661 -0
- package/src/internal/start-plugin-core/hydration-constants.d.ts +1 -0
- package/src/internal/start-plugin-core/hydration-constants.js +4 -0
- package/src/internal/start-plugin-core/import-protection/adapterUtils.d.ts +40 -0
- package/src/internal/start-plugin-core/import-protection/adapterUtils.js +42 -0
- package/src/internal/start-plugin-core/import-protection/analysis.d.ts +63 -0
- package/src/internal/start-plugin-core/import-protection/analysis.js +533 -0
- package/src/internal/start-plugin-core/import-protection/constants.d.ts +11 -0
- package/src/internal/start-plugin-core/import-protection/constants.js +39 -0
- package/src/internal/start-plugin-core/import-protection/defaults.d.ts +19 -0
- package/src/internal/start-plugin-core/import-protection/defaults.js +34 -0
- package/src/internal/start-plugin-core/import-protection/extensionlessAbsoluteIdResolver.d.ts +22 -0
- package/src/internal/start-plugin-core/import-protection/extensionlessAbsoluteIdResolver.js +94 -0
- package/src/internal/start-plugin-core/import-protection/matchers.d.ts +18 -0
- package/src/internal/start-plugin-core/import-protection/matchers.js +39 -0
- package/src/internal/start-plugin-core/import-protection/rewrite.d.ts +29 -0
- package/src/internal/start-plugin-core/import-protection/rewrite.js +184 -0
- package/src/internal/start-plugin-core/import-protection/sourceLocation.d.ts +170 -0
- package/src/internal/start-plugin-core/import-protection/sourceLocation.js +376 -0
- package/src/internal/start-plugin-core/import-protection/trace.d.ts +89 -0
- package/src/internal/start-plugin-core/import-protection/trace.js +186 -0
- package/src/internal/start-plugin-core/import-protection/utils.d.ts +78 -0
- package/src/internal/start-plugin-core/import-protection/utils.js +171 -0
- package/src/internal/start-plugin-core/import-protection/virtualModules.d.ts +38 -0
- package/src/internal/start-plugin-core/import-protection/virtualModules.js +241 -0
- package/src/internal/start-plugin-core/index.d.ts +8 -0
- package/src/internal/start-plugin-core/index.js +2 -0
- package/src/internal/start-plugin-core/planning.d.ts +44 -0
- package/src/internal/start-plugin-core/planning.js +98 -0
- package/src/internal/start-plugin-core/post-build.d.ts +12 -0
- package/src/internal/start-plugin-core/post-build.js +40 -0
- package/src/internal/start-plugin-core/prerender.d.ts +17 -0
- package/src/internal/start-plugin-core/prerender.js +172 -0
- package/src/internal/start-plugin-core/queue.d.ts +37 -0
- package/src/internal/start-plugin-core/queue.js +118 -0
- package/src/internal/start-plugin-core/resolve-entries.d.ts +10 -0
- package/src/internal/start-plugin-core/resolve-entries.js +32 -0
- package/src/internal/start-plugin-core/schema.d.ts +1799 -0
- package/src/internal/start-plugin-core/schema.js +252 -0
- package/src/internal/start-plugin-core/serialization-adapters-module.d.ts +18 -0
- package/src/internal/start-plugin-core/serialization-adapters-module.js +37 -0
- package/src/internal/start-plugin-core/start-compiler/compiler.d.ts +181 -0
- package/src/internal/start-plugin-core/start-compiler/compiler.js +1078 -0
- package/src/internal/start-plugin-core/start-compiler/config.d.ts +20 -0
- package/src/internal/start-plugin-core/start-compiler/config.js +84 -0
- package/src/internal/start-plugin-core/start-compiler/handleClientOnlyJSX.d.ts +24 -0
- package/src/internal/start-plugin-core/start-compiler/handleClientOnlyJSX.js +25 -0
- package/src/internal/start-plugin-core/start-compiler/handleCreateIsomorphicFn.d.ts +11 -0
- package/src/internal/start-plugin-core/start-compiler/handleCreateIsomorphicFn.js +24 -0
- package/src/internal/start-plugin-core/start-compiler/handleCreateMiddleware.d.ts +11 -0
- package/src/internal/start-plugin-core/start-compiler/handleCreateMiddleware.js +35 -0
- package/src/internal/start-plugin-core/start-compiler/handleCreateServerFn.d.ts +22 -0
- package/src/internal/start-plugin-core/start-compiler/handleCreateServerFn.js +292 -0
- package/src/internal/start-plugin-core/start-compiler/handleEnvOnly.d.ts +14 -0
- package/src/internal/start-plugin-core/start-compiler/handleEnvOnly.js +41 -0
- package/src/internal/start-plugin-core/start-compiler/host.d.ts +44 -0
- package/src/internal/start-plugin-core/start-compiler/host.js +75 -0
- package/src/internal/start-plugin-core/start-compiler/server-fn-resolver-module.d.ts +10 -0
- package/src/internal/start-plugin-core/start-compiler/server-fn-resolver-module.js +87 -0
- package/src/internal/start-plugin-core/start-compiler/types.d.ts +119 -0
- package/src/internal/start-plugin-core/start-compiler/utils.d.ts +27 -0
- package/src/internal/start-plugin-core/start-compiler/utils.js +36 -0
- package/src/internal/start-plugin-core/start-manifest-plugin/inlineCss.d.ts +16 -0
- package/src/internal/start-plugin-core/start-manifest-plugin/inlineCss.js +131 -0
- package/src/internal/start-plugin-core/start-manifest-plugin/manifestBuilder.d.ts +64 -0
- package/src/internal/start-plugin-core/start-manifest-plugin/manifestBuilder.js +441 -0
- package/src/internal/start-plugin-core/start-router-plugin/constants.d.ts +1 -0
- package/src/internal/start-plugin-core/start-router-plugin/constants.js +4 -0
- package/src/internal/start-plugin-core/start-router-plugin/generator-plugins/compose-generator-plugins.d.ts +6 -0
- package/src/internal/start-plugin-core/start-router-plugin/generator-plugins/compose-generator-plugins.js +6 -0
- package/src/internal/start-plugin-core/start-router-plugin/generator-plugins/prerender-routes-plugin.d.ts +6 -0
- package/src/internal/start-plugin-core/start-router-plugin/generator-plugins/prerender-routes-plugin.js +27 -0
- package/src/internal/start-plugin-core/start-router-plugin/generator-plugins/routes-manifest-plugin.d.ts +6 -0
- package/src/internal/start-plugin-core/start-router-plugin/generator-plugins/routes-manifest-plugin.js +34 -0
- package/src/internal/start-plugin-core/start-router-plugin/pruneServerOnlySubtrees.d.ts +11 -0
- package/src/internal/start-plugin-core/start-router-plugin/pruneServerOnlySubtrees.js +42 -0
- package/src/internal/start-plugin-core/start-router-plugin/route-tree-footer.d.ts +6 -0
- package/src/internal/start-plugin-core/start-router-plugin/route-tree-footer.js +59 -0
- package/src/internal/start-plugin-core/types.d.ts +135 -0
- package/src/internal/start-plugin-core/types.js +4 -0
- package/src/internal/start-plugin-core/utils.d.ts +13 -0
- package/src/internal/start-plugin-core/utils.js +42 -0
- package/src/internal/start-plugin-core/vite/createVirtualModule.d.ts +15 -0
- package/src/internal/start-plugin-core/vite/createVirtualModule.js +27 -0
- package/src/internal/start-plugin-core/vite/dev-server-plugin/dev-styles.d.ts +26 -0
- package/src/internal/start-plugin-core/vite/dev-server-plugin/dev-styles.js +165 -0
- package/src/internal/start-plugin-core/vite/dev-server-plugin/plugin.d.ts +11 -0
- package/src/internal/start-plugin-core/vite/dev-server-plugin/plugin.js +170 -0
- package/src/internal/start-plugin-core/vite/import-protection-plugin/plugin.d.ts +4 -0
- package/src/internal/start-plugin-core/vite/import-protection-plugin/plugin.js +1553 -0
- package/src/internal/start-plugin-core/vite/import-protection-plugin/types.d.ts +103 -0
- package/src/internal/start-plugin-core/vite/import-protection-plugin/virtualModules.d.ts +40 -0
- package/src/internal/start-plugin-core/vite/import-protection-plugin/virtualModules.js +68 -0
- package/src/internal/start-plugin-core/vite/index.d.ts +13 -0
- package/src/internal/start-plugin-core/vite/index.js +4 -0
- package/src/internal/start-plugin-core/vite/load-env-plugin/plugin.d.ts +2 -0
- package/src/internal/start-plugin-core/vite/load-env-plugin/plugin.js +13 -0
- package/src/internal/start-plugin-core/vite/output-directory.d.ts +7 -0
- package/src/internal/start-plugin-core/vite/output-directory.js +18 -0
- package/src/internal/start-plugin-core/vite/planning.d.ts +112 -0
- package/src/internal/start-plugin-core/vite/planning.js +152 -0
- package/src/internal/start-plugin-core/vite/plugin.d.ts +7 -0
- package/src/internal/start-plugin-core/vite/plugin.js +208 -0
- package/src/internal/start-plugin-core/vite/plugins.d.ts +17 -0
- package/src/internal/start-plugin-core/vite/plugins.js +72 -0
- package/src/internal/start-plugin-core/vite/post-server-build.d.ts +9 -0
- package/src/internal/start-plugin-core/vite/post-server-build.js +22 -0
- package/src/internal/start-plugin-core/vite/prerender.d.ts +9 -0
- package/src/internal/start-plugin-core/vite/prerender.js +52 -0
- package/src/internal/start-plugin-core/vite/preview-server-plugin/plugin.d.ts +2 -0
- package/src/internal/start-plugin-core/vite/preview-server-plugin/plugin.js +54 -0
- package/src/internal/start-plugin-core/vite/schema.d.ts +2423 -0
- package/src/internal/start-plugin-core/vite/schema.js +17 -0
- package/src/internal/start-plugin-core/vite/serialization-adapters-plugin.d.ts +5 -0
- package/src/internal/start-plugin-core/vite/serialization-adapters-plugin.js +63 -0
- package/src/internal/start-plugin-core/vite/start-compiler-plugin/hot-update.d.ts +5 -0
- package/src/internal/start-plugin-core/vite/start-compiler-plugin/hot-update.js +14 -0
- package/src/internal/start-plugin-core/vite/start-compiler-plugin/module-specifier.d.ts +5 -0
- package/src/internal/start-plugin-core/vite/start-compiler-plugin/module-specifier.js +25 -0
- package/src/internal/start-plugin-core/vite/start-compiler-plugin/plugin.d.ts +29 -0
- package/src/internal/start-plugin-core/vite/start-compiler-plugin/plugin.js +380 -0
- package/src/internal/start-plugin-core/vite/start-manifest-plugin/normalized-client-build.d.ts +11 -0
- package/src/internal/start-plugin-core/vite/start-manifest-plugin/normalized-client-build.js +114 -0
- package/src/internal/start-plugin-core/vite/start-manifest-plugin/plugin.d.ts +3 -0
- package/src/internal/start-plugin-core/vite/start-manifest-plugin/plugin.js +103 -0
- package/src/internal/start-plugin-core/vite/start-router-plugin/plugin.d.ts +9 -0
- package/src/internal/start-plugin-core/vite/start-router-plugin/plugin.js +143 -0
- package/src/internal/start-plugin-core/vite/types.d.ts +17 -0
- package/src/package-names.js +10 -0
- package/src/plugin-vite.d.ts +23 -0
- package/src/plugin-vite.js +62 -0
- package/src/runtime/client/StartClient.d.ts +11 -0
- package/src/runtime/client/StartClient.js +16 -0
- package/src/runtime/client/hydrateStart.d.ts +4 -0
- package/src/runtime/client/hydrateStart.js +30 -0
- package/src/runtime/server/StartServer.d.ts +10 -0
- package/src/runtime/server/StartServer.js +6 -0
- package/src/runtime/server/defaultRenderHandler.d.ts +3 -0
- package/src/runtime/server/defaultRenderHandler.js +11 -0
- package/src/runtime/server/defaultStreamHandler.d.ts +3 -0
- package/src/runtime/server/defaultStreamHandler.js +13 -0
- package/src/server-entry.d.ts +11 -0
- package/src/server-entry.js +13 -0
- package/src/server-only.d.ts +1 -0
- package/src/server-only.js +0 -0
- package/src/server-rpc.d.ts +1 -0
- package/src/server-rpc.js +1 -0
- package/src/server.d.ts +6 -0
- package/src/server.js +4 -0
- package/src/ssr-rpc.d.ts +1 -0
- package/src/ssr-rpc.js +1 -0
- package/src/use-server-fn.d.ts +3 -0
- package/src/use-server-fn.js +18 -0
- package/src/validate-options.js +7 -0
|
@@ -0,0 +1,1078 @@
|
|
|
1
|
+
import { cleanId } from './utils.js';
|
|
2
|
+
import { handleCreateServerFn } from './handleCreateServerFn.js';
|
|
3
|
+
import { handleCreateMiddleware } from './handleCreateMiddleware.js';
|
|
4
|
+
import { handleCreateIsomorphicFn } from './handleCreateIsomorphicFn.js';
|
|
5
|
+
import { handleEnvOnlyFn } from './handleEnvOnly.js';
|
|
6
|
+
import { handleClientOnlyJSX } from './handleClientOnlyJSX.js';
|
|
7
|
+
import * as t from '@babel/types';
|
|
8
|
+
import {
|
|
9
|
+
deadCodeElimination,
|
|
10
|
+
extractModuleInfoFromAst,
|
|
11
|
+
findReferencedIdentifiers,
|
|
12
|
+
generateFromAst,
|
|
13
|
+
getVariableDeclaratorForExpressionPath,
|
|
14
|
+
parseAst,
|
|
15
|
+
unwrapExpression,
|
|
16
|
+
} from '@tanstack/router-utils';
|
|
17
|
+
import crypto from 'node:crypto';
|
|
18
|
+
import babel from '@babel/core';
|
|
19
|
+
//#region src/start-compiler/compiler.ts
|
|
20
|
+
function isLookupKind(kind) {
|
|
21
|
+
return kind in BuiltInLookupSetup || isExternalLookupKind(kind);
|
|
22
|
+
}
|
|
23
|
+
function getExternalLookupKind(transform) {
|
|
24
|
+
return `External:${transform.name}`;
|
|
25
|
+
}
|
|
26
|
+
function isExternalLookupKind(kind) {
|
|
27
|
+
return typeof kind === 'string' && kind.startsWith('External:');
|
|
28
|
+
}
|
|
29
|
+
function isCompilerTransformEnabledForEnv(transform, env) {
|
|
30
|
+
return isStartCompilerEnvironmentEnabled(transform.environment, env);
|
|
31
|
+
}
|
|
32
|
+
function isStartCompilerPluginEnabledForEnv(plugin, env) {
|
|
33
|
+
return isStartCompilerEnvironmentEnabled(plugin.environment, env);
|
|
34
|
+
}
|
|
35
|
+
function isStartCompilerEnvironmentEnabled(environment, env) {
|
|
36
|
+
if (!environment) return true;
|
|
37
|
+
if (Array.isArray(environment)) return environment.includes(env);
|
|
38
|
+
return environment === env;
|
|
39
|
+
}
|
|
40
|
+
var BuiltInLookupSetup = {
|
|
41
|
+
ServerFn: {
|
|
42
|
+
type: 'methodChain',
|
|
43
|
+
candidateCallIdentifier: new Set(['handler']),
|
|
44
|
+
},
|
|
45
|
+
Middleware: {
|
|
46
|
+
type: 'methodChain',
|
|
47
|
+
candidateCallIdentifier: new Set(['server', 'client', 'createMiddlewares']),
|
|
48
|
+
},
|
|
49
|
+
IsomorphicFn: {
|
|
50
|
+
type: 'methodChain',
|
|
51
|
+
candidateCallIdentifier: new Set(['server', 'client']),
|
|
52
|
+
},
|
|
53
|
+
ServerOnlyFn: {
|
|
54
|
+
type: 'directCall',
|
|
55
|
+
factoryNames: new Set(['createServerOnlyFn']),
|
|
56
|
+
},
|
|
57
|
+
ClientOnlyFn: {
|
|
58
|
+
type: 'directCall',
|
|
59
|
+
factoryNames: new Set(['createClientOnlyFn']),
|
|
60
|
+
},
|
|
61
|
+
ClientOnlyJSX: {
|
|
62
|
+
type: 'jsx',
|
|
63
|
+
componentName: 'ClientOnly',
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
var KindDetectionPatterns = {
|
|
67
|
+
ServerFn: /\bcreateServerFn\b|\.\s*handler\s*\(/,
|
|
68
|
+
Middleware: /createMiddleware/,
|
|
69
|
+
IsomorphicFn: /createIsomorphicFn/,
|
|
70
|
+
ServerOnlyFn: /createServerOnlyFn/,
|
|
71
|
+
ClientOnlyFn: /createClientOnlyFn/,
|
|
72
|
+
ClientOnlyJSX: /<ClientOnly|import\s*\{[^}]*\bClientOnly\b/,
|
|
73
|
+
};
|
|
74
|
+
var LookupKindsPerEnv = {
|
|
75
|
+
client: new Set(['Middleware', 'ServerFn', 'IsomorphicFn', 'ServerOnlyFn', 'ClientOnlyFn']),
|
|
76
|
+
server: new Set(['ServerFn', 'IsomorphicFn', 'ServerOnlyFn', 'ClientOnlyFn', 'ClientOnlyJSX']),
|
|
77
|
+
};
|
|
78
|
+
function getLookupKindsForEnv(env, opts) {
|
|
79
|
+
const kinds = new Set(LookupKindsPerEnv[env]);
|
|
80
|
+
for (const transform of opts?.compilerTransforms ?? [])
|
|
81
|
+
if (isCompilerTransformEnabledForEnv(transform, env))
|
|
82
|
+
kinds.add(getExternalLookupKind(transform));
|
|
83
|
+
return kinds;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Registry mapping each LookupKind to its handler function.
|
|
87
|
+
* When adding a new kind, add its handler here.
|
|
88
|
+
*/
|
|
89
|
+
var BuiltInKindHandlers = {
|
|
90
|
+
ServerFn: handleCreateServerFn,
|
|
91
|
+
Middleware: handleCreateMiddleware,
|
|
92
|
+
IsomorphicFn: handleCreateIsomorphicFn,
|
|
93
|
+
ServerOnlyFn: handleEnvOnlyFn,
|
|
94
|
+
ClientOnlyFn: handleEnvOnlyFn,
|
|
95
|
+
};
|
|
96
|
+
var BuiltInKindHandlerOrder = [
|
|
97
|
+
'ServerFn',
|
|
98
|
+
'Middleware',
|
|
99
|
+
'IsomorphicFn',
|
|
100
|
+
'ServerOnlyFn',
|
|
101
|
+
'ClientOnlyFn',
|
|
102
|
+
];
|
|
103
|
+
var AllBuiltInLookupKinds = Object.keys(BuiltInLookupSetup);
|
|
104
|
+
/**
|
|
105
|
+
* Detects which LookupKinds are present in the code using string matching.
|
|
106
|
+
* This is a fast pre-scan before AST parsing to limit the work done during compilation.
|
|
107
|
+
*/
|
|
108
|
+
function detectKindsInCode(code, env, opts) {
|
|
109
|
+
const detected = /* @__PURE__ */ new Set();
|
|
110
|
+
const validForEnv = getLookupKindsForEnv(env, opts);
|
|
111
|
+
for (const kind of AllBuiltInLookupKinds) {
|
|
112
|
+
const pattern = KindDetectionPatterns[kind];
|
|
113
|
+
pattern.lastIndex = 0;
|
|
114
|
+
if (validForEnv.has(kind) && pattern.test(code)) detected.add(kind);
|
|
115
|
+
}
|
|
116
|
+
for (const transform of opts?.compilerTransforms ?? []) {
|
|
117
|
+
if (!isCompilerTransformEnabledForEnv(transform, env)) continue;
|
|
118
|
+
transform.detect.lastIndex = 0;
|
|
119
|
+
if (transform.detect.test(code)) detected.add(getExternalLookupKind(transform));
|
|
120
|
+
}
|
|
121
|
+
return detected;
|
|
122
|
+
}
|
|
123
|
+
var IdentifierToKinds = /* @__PURE__ */ new Map();
|
|
124
|
+
for (const kind of AllBuiltInLookupKinds) {
|
|
125
|
+
const setup = BuiltInLookupSetup[kind];
|
|
126
|
+
if (setup.type === 'methodChain')
|
|
127
|
+
for (const id of setup.candidateCallIdentifier) {
|
|
128
|
+
let kinds = IdentifierToKinds.get(id);
|
|
129
|
+
if (!kinds) {
|
|
130
|
+
kinds = /* @__PURE__ */ new Set();
|
|
131
|
+
IdentifierToKinds.set(id, kinds);
|
|
132
|
+
}
|
|
133
|
+
kinds.add(kind);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function getLookupSetup(kind, externalLookupSetup) {
|
|
137
|
+
if (kind in BuiltInLookupSetup) return BuiltInLookupSetup[kind];
|
|
138
|
+
if (isExternalLookupKind(kind)) return externalLookupSetup?.get(kind);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Checks if all kinds in the set are guaranteed to be top-level only.
|
|
142
|
+
* Only ServerFn is always declared at module level (must be assigned to a variable).
|
|
143
|
+
* Middleware, IsomorphicFn, ServerOnlyFn, ClientOnlyFn can be nested inside functions.
|
|
144
|
+
* When all kinds are top-level-only, we can use a fast scan instead of full traversal.
|
|
145
|
+
*/
|
|
146
|
+
function areAllKindsTopLevelOnly(kinds) {
|
|
147
|
+
return kinds.size === 1 && kinds.has('ServerFn');
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Checks if we need to detect JSX elements (e.g., <ClientOnly>).
|
|
151
|
+
*/
|
|
152
|
+
function needsJSXDetection(kinds, externalLookupSetup) {
|
|
153
|
+
for (const kind of kinds)
|
|
154
|
+
if (getLookupSetup(kind, externalLookupSetup)?.type === 'jsx') return true;
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Checks if a CallExpression is a direct-call candidate for NESTED detection.
|
|
159
|
+
* Returns true if the callee is a known factory function name.
|
|
160
|
+
* This is stricter than top-level detection because we need to filter out
|
|
161
|
+
* invocations of existing server functions (e.g., `myServerFn()`).
|
|
162
|
+
*/
|
|
163
|
+
function isNestedDirectCallCandidate(node, lookupKinds, externalLookupSetup) {
|
|
164
|
+
let calleeName;
|
|
165
|
+
if (t.isIdentifier(node.callee)) calleeName = node.callee.name;
|
|
166
|
+
else if (t.isMemberExpression(node.callee) && t.isIdentifier(node.callee.property))
|
|
167
|
+
calleeName = node.callee.property.name;
|
|
168
|
+
if (!calleeName) return false;
|
|
169
|
+
for (const kind of lookupKinds) {
|
|
170
|
+
if (isExternalLookupKind(kind)) continue;
|
|
171
|
+
const setup = getLookupSetup(kind, externalLookupSetup);
|
|
172
|
+
if (setup?.type === 'directCall' && setup.factoryNames.has(calleeName)) return true;
|
|
173
|
+
}
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
function isSimpleDirectCallExpression(node) {
|
|
177
|
+
return (
|
|
178
|
+
t.isIdentifier(node.callee) ||
|
|
179
|
+
(t.isMemberExpression(node.callee) &&
|
|
180
|
+
t.isIdentifier(node.callee.object) &&
|
|
181
|
+
t.isIdentifier(node.callee.property))
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
function isTopLevelDirectCallCandidateNode(node) {
|
|
185
|
+
return isSimpleDirectCallExpression(node);
|
|
186
|
+
}
|
|
187
|
+
function getPotentialCandidateCallExpression(node) {
|
|
188
|
+
if (!node) return null;
|
|
189
|
+
const unwrapped = unwrapExpression(node);
|
|
190
|
+
return t.isCallExpression(unwrapped) ? unwrapped : null;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Checks if a CallExpression path is a top-level direct-call candidate.
|
|
194
|
+
* Top-level means the call is the init of a VariableDeclarator at program level.
|
|
195
|
+
* We accept any simple identifier call or namespace call at top level
|
|
196
|
+
* (e.g., `createServerOnlyFn()`, `TanStackStart.createServerOnlyFn()`) and let
|
|
197
|
+
* resolution verify it. This handles renamed imports.
|
|
198
|
+
*/
|
|
199
|
+
function isTopLevelDirectCallCandidate(path) {
|
|
200
|
+
const node = path.node;
|
|
201
|
+
if (!isSimpleDirectCallExpression(node)) return false;
|
|
202
|
+
const variableDeclarator = getVariableDeclaratorForExpressionPath(path);
|
|
203
|
+
if (!variableDeclarator) return false;
|
|
204
|
+
const variableDeclaration = variableDeclarator.parentPath;
|
|
205
|
+
if (!variableDeclaration.isVariableDeclaration()) return false;
|
|
206
|
+
const parent = variableDeclaration.parentPath;
|
|
207
|
+
return parent.isProgram() || (parent.isExportNamedDeclaration() && parent.parentPath.isProgram());
|
|
208
|
+
}
|
|
209
|
+
function isDirectCallCandidateForKind(kind, externalLookupSetup) {
|
|
210
|
+
return getLookupSetup(kind, externalLookupSetup)?.type === 'directCall';
|
|
211
|
+
}
|
|
212
|
+
function hasBuiltInDirectCallKinds(kinds) {
|
|
213
|
+
for (const kind of kinds) {
|
|
214
|
+
if (isExternalLookupKind(kind)) continue;
|
|
215
|
+
if (BuiltInLookupSetup[kind].type === 'directCall') return true;
|
|
216
|
+
}
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
function hasExternalLookupKinds(kinds) {
|
|
220
|
+
for (const kind of kinds) if (isExternalLookupKind(kind)) return true;
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
function hasExternalDirectCallCandidates(candidates) {
|
|
224
|
+
return candidates.identifiers.size > 0 || candidates.namespaces.size > 0;
|
|
225
|
+
}
|
|
226
|
+
function getExternalDirectCallCandidateKind(path, candidates) {
|
|
227
|
+
const node = path.node;
|
|
228
|
+
if (t.isIdentifier(node.callee)) {
|
|
229
|
+
const kind = candidates.identifiers.get(node.callee.name);
|
|
230
|
+
if (!kind) return void 0;
|
|
231
|
+
return path.scope.getBinding(node.callee.name)?.path.isImportSpecifier() ? kind : void 0;
|
|
232
|
+
}
|
|
233
|
+
if (
|
|
234
|
+
t.isMemberExpression(node.callee) &&
|
|
235
|
+
t.isIdentifier(node.callee.object) &&
|
|
236
|
+
t.isIdentifier(node.callee.property)
|
|
237
|
+
) {
|
|
238
|
+
const kind = candidates.namespaces.get(node.callee.object.name)?.get(node.callee.property.name);
|
|
239
|
+
if (!kind) return void 0;
|
|
240
|
+
return path.scope.getBinding(node.callee.object.name)?.path.isImportNamespaceSpecifier()
|
|
241
|
+
? kind
|
|
242
|
+
: void 0;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
var StartCompiler = class {
|
|
246
|
+
options;
|
|
247
|
+
moduleCache = /* @__PURE__ */ new Map();
|
|
248
|
+
initialized = false;
|
|
249
|
+
validLookupKinds;
|
|
250
|
+
externalTransformsByKind = /* @__PURE__ */ new Map();
|
|
251
|
+
externalLookupSetup = /* @__PURE__ */ new Map();
|
|
252
|
+
compilerPlugins;
|
|
253
|
+
externalDirectCallKindsBySource = /* @__PURE__ */ new Map();
|
|
254
|
+
resolveIdCache = /* @__PURE__ */ new Map();
|
|
255
|
+
exportResolutionCache = /* @__PURE__ */ new Map();
|
|
256
|
+
knownRootImports = /* @__PURE__ */ new Map();
|
|
257
|
+
entryIdToFunctionId = /* @__PURE__ */ new Map();
|
|
258
|
+
functionIds = /* @__PURE__ */ new Set();
|
|
259
|
+
constructor(options) {
|
|
260
|
+
this.options = options;
|
|
261
|
+
this.validLookupKinds = options.lookupKinds;
|
|
262
|
+
this.compilerPlugins = (options.compilerPlugins ?? []).filter((plugin) =>
|
|
263
|
+
isStartCompilerPluginEnabledForEnv(plugin, options.env),
|
|
264
|
+
);
|
|
265
|
+
for (const transform of options.compilerTransforms ?? []) {
|
|
266
|
+
const kind = getExternalLookupKind(transform);
|
|
267
|
+
if (!this.validLookupKinds.has(kind)) continue;
|
|
268
|
+
this.externalTransformsByKind.set(kind, transform);
|
|
269
|
+
const factoryNames = /* @__PURE__ */ new Set();
|
|
270
|
+
for (const entry of transform.imports) {
|
|
271
|
+
factoryNames.add(entry.rootExport);
|
|
272
|
+
let rootExports = this.externalDirectCallKindsBySource.get(entry.libName);
|
|
273
|
+
if (!rootExports) {
|
|
274
|
+
rootExports = /* @__PURE__ */ new Map();
|
|
275
|
+
this.externalDirectCallKindsBySource.set(entry.libName, rootExports);
|
|
276
|
+
}
|
|
277
|
+
rootExports.set(entry.rootExport, kind);
|
|
278
|
+
}
|
|
279
|
+
this.externalLookupSetup.set(kind, {
|
|
280
|
+
type: 'directCall',
|
|
281
|
+
factoryNames,
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Generates a unique function ID for a server function.
|
|
287
|
+
* In dev mode, uses a base64-encoded JSON with file path and export name.
|
|
288
|
+
* In build mode, uses SHA256 hash or custom generator.
|
|
289
|
+
*/
|
|
290
|
+
generateFunctionId(opts) {
|
|
291
|
+
if (this.mode === 'dev') {
|
|
292
|
+
const encodeModuleSpecifier = this.options.devServerFnModuleSpecifierEncoder;
|
|
293
|
+
if (!encodeModuleSpecifier)
|
|
294
|
+
throw new Error('devServerFnModuleSpecifierEncoder is required in dev mode.');
|
|
295
|
+
const serverFn = {
|
|
296
|
+
file: encodeModuleSpecifier({
|
|
297
|
+
extractedFilename: opts.extractedFilename,
|
|
298
|
+
root: this.options.root,
|
|
299
|
+
}),
|
|
300
|
+
export: opts.functionName,
|
|
301
|
+
};
|
|
302
|
+
return Buffer.from(JSON.stringify(serverFn), 'utf8').toString('base64url');
|
|
303
|
+
}
|
|
304
|
+
const entryId = `${opts.filename}--${opts.functionName}`;
|
|
305
|
+
let functionId = this.entryIdToFunctionId.get(entryId);
|
|
306
|
+
if (functionId === void 0) {
|
|
307
|
+
const knownFn = Object.values(this.options.getKnownServerFns()).find(
|
|
308
|
+
(serverFn) =>
|
|
309
|
+
serverFn.functionName === opts.functionName &&
|
|
310
|
+
serverFn.extractedFilename === opts.extractedFilename,
|
|
311
|
+
);
|
|
312
|
+
if (knownFn) functionId = knownFn.functionId;
|
|
313
|
+
if (this.options.generateFunctionId)
|
|
314
|
+
functionId ??= this.options.generateFunctionId({
|
|
315
|
+
filename: opts.filename,
|
|
316
|
+
functionName: opts.functionName,
|
|
317
|
+
});
|
|
318
|
+
if (!functionId) functionId = crypto.createHash('sha256').update(entryId).digest('hex');
|
|
319
|
+
if (this.functionIds.has(functionId)) {
|
|
320
|
+
let deduplicatedId;
|
|
321
|
+
let iteration = 0;
|
|
322
|
+
do deduplicatedId = `${functionId}_${++iteration}`;
|
|
323
|
+
while (this.functionIds.has(deduplicatedId));
|
|
324
|
+
functionId = deduplicatedId;
|
|
325
|
+
}
|
|
326
|
+
this.entryIdToFunctionId.set(entryId, functionId);
|
|
327
|
+
this.functionIds.add(functionId);
|
|
328
|
+
}
|
|
329
|
+
return functionId;
|
|
330
|
+
}
|
|
331
|
+
get mode() {
|
|
332
|
+
return this.options.mode ?? 'dev';
|
|
333
|
+
}
|
|
334
|
+
getExternalDirectCallCandidates(kinds, moduleInfo) {
|
|
335
|
+
const identifiers = /* @__PURE__ */ new Map();
|
|
336
|
+
const namespaces = /* @__PURE__ */ new Map();
|
|
337
|
+
if (this.externalDirectCallKindsBySource.size === 0)
|
|
338
|
+
return {
|
|
339
|
+
identifiers,
|
|
340
|
+
namespaces,
|
|
341
|
+
};
|
|
342
|
+
for (const [localName, binding] of moduleInfo.bindings) {
|
|
343
|
+
if (binding.type !== 'import') continue;
|
|
344
|
+
const rootExports = this.externalDirectCallKindsBySource.get(binding.source);
|
|
345
|
+
if (!rootExports) continue;
|
|
346
|
+
if (binding.importedName === '*') {
|
|
347
|
+
const namespaceExports = /* @__PURE__ */ new Map();
|
|
348
|
+
for (const [rootExport, kind] of rootExports)
|
|
349
|
+
if (kinds.has(kind)) namespaceExports.set(rootExport, kind);
|
|
350
|
+
if (namespaceExports.size > 0) namespaces.set(localName, namespaceExports);
|
|
351
|
+
} else {
|
|
352
|
+
const kind = rootExports.get(binding.importedName);
|
|
353
|
+
if (kind && kinds.has(kind)) identifiers.set(localName, kind);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
identifiers,
|
|
358
|
+
namespaces,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
async resolveIdCached(id, importer) {
|
|
362
|
+
if (this.mode === 'dev') return this.options.resolveId(id, importer);
|
|
363
|
+
const cacheKey = importer ? `${importer}::${id}` : id;
|
|
364
|
+
const cached = this.resolveIdCache.get(cacheKey);
|
|
365
|
+
if (cached !== void 0) return cached;
|
|
366
|
+
const resolved = await this.options.resolveId(id, importer);
|
|
367
|
+
this.resolveIdCache.set(cacheKey, resolved);
|
|
368
|
+
return resolved;
|
|
369
|
+
}
|
|
370
|
+
getExportResolutionCache(moduleId) {
|
|
371
|
+
let cache = this.exportResolutionCache.get(moduleId);
|
|
372
|
+
if (!cache) {
|
|
373
|
+
cache = /* @__PURE__ */ new Map();
|
|
374
|
+
this.exportResolutionCache.set(moduleId, cache);
|
|
375
|
+
}
|
|
376
|
+
return cache;
|
|
377
|
+
}
|
|
378
|
+
init() {
|
|
379
|
+
this.knownRootImports.set(
|
|
380
|
+
'@tanstack/start-fn-stubs',
|
|
381
|
+
new Map([
|
|
382
|
+
['createIsomorphicFn', 'IsomorphicFn'],
|
|
383
|
+
['createServerOnlyFn', 'ServerOnlyFn'],
|
|
384
|
+
['createClientOnlyFn', 'ClientOnlyFn'],
|
|
385
|
+
]),
|
|
386
|
+
);
|
|
387
|
+
this.knownRootImports.set(
|
|
388
|
+
'@tanstack/start-client-core',
|
|
389
|
+
new Map([
|
|
390
|
+
['createServerFn', 'Root'],
|
|
391
|
+
['createIsomorphicFn', 'IsomorphicFn'],
|
|
392
|
+
['createServerOnlyFn', 'ServerOnlyFn'],
|
|
393
|
+
['createClientOnlyFn', 'ClientOnlyFn'],
|
|
394
|
+
['createMiddleware', 'Middleware'],
|
|
395
|
+
['createStart', 'Root'],
|
|
396
|
+
]),
|
|
397
|
+
);
|
|
398
|
+
for (const config of this.options.lookupConfigurations) {
|
|
399
|
+
let libExports = this.knownRootImports.get(config.libName);
|
|
400
|
+
if (!libExports) {
|
|
401
|
+
libExports = /* @__PURE__ */ new Map();
|
|
402
|
+
this.knownRootImports.set(config.libName, libExports);
|
|
403
|
+
}
|
|
404
|
+
libExports.set(config.rootExport, config.kind);
|
|
405
|
+
if (config.kind !== 'Root') {
|
|
406
|
+
if (getLookupSetup(config.kind, this.externalLookupSetup)?.type === 'jsx') continue;
|
|
407
|
+
}
|
|
408
|
+
const libId = config.libName;
|
|
409
|
+
let rootModule = this.moduleCache.get(libId);
|
|
410
|
+
if (!rootModule) {
|
|
411
|
+
rootModule = {
|
|
412
|
+
bindings: /* @__PURE__ */ new Map(),
|
|
413
|
+
exports: /* @__PURE__ */ new Map(),
|
|
414
|
+
id: libId,
|
|
415
|
+
reExportAllSources: [],
|
|
416
|
+
};
|
|
417
|
+
this.moduleCache.set(libId, rootModule);
|
|
418
|
+
}
|
|
419
|
+
rootModule.exports.set(config.rootExport, config.rootExport);
|
|
420
|
+
rootModule.exports.set('*', config.rootExport);
|
|
421
|
+
rootModule.bindings.set(config.rootExport, {
|
|
422
|
+
type: 'var',
|
|
423
|
+
init: null,
|
|
424
|
+
resolvedKind: config.kind,
|
|
425
|
+
});
|
|
426
|
+
this.moduleCache.set(libId, rootModule);
|
|
427
|
+
}
|
|
428
|
+
this.initialized = true;
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Extracts bindings and exports from an already-parsed AST.
|
|
432
|
+
*/
|
|
433
|
+
extractModuleInfo(ast, id) {
|
|
434
|
+
const extracted = extractModuleInfoFromAst(ast);
|
|
435
|
+
const info = {
|
|
436
|
+
id,
|
|
437
|
+
bindings: new Map(extracted.bindings),
|
|
438
|
+
exports: extracted.exports,
|
|
439
|
+
reExportAllSources: extracted.reExportAllSources,
|
|
440
|
+
};
|
|
441
|
+
this.moduleCache.set(id, info);
|
|
442
|
+
return info;
|
|
443
|
+
}
|
|
444
|
+
ingestModule({ code, id, parserFilename }) {
|
|
445
|
+
const ast = parseAst({
|
|
446
|
+
code,
|
|
447
|
+
filename: parserFilename ?? cleanId(id),
|
|
448
|
+
});
|
|
449
|
+
return {
|
|
450
|
+
info: this.extractModuleInfo(ast, id),
|
|
451
|
+
ast,
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
invalidateModule(id) {
|
|
455
|
+
return this.invalidateModules([id]).size > 0;
|
|
456
|
+
}
|
|
457
|
+
invalidateModules(ids) {
|
|
458
|
+
const normalizedIds = /* @__PURE__ */ new Set();
|
|
459
|
+
for (const id of ids) {
|
|
460
|
+
normalizedIds.add(cleanId(id));
|
|
461
|
+
for (const plugin of this.compilerPlugins)
|
|
462
|
+
plugin.invalidateModule?.({
|
|
463
|
+
id,
|
|
464
|
+
envName: this.options.envName,
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
const deletedModuleIds = /* @__PURE__ */ new Set();
|
|
468
|
+
if (normalizedIds.size === 0) return deletedModuleIds;
|
|
469
|
+
for (const moduleId of Array.from(this.moduleCache.keys())) {
|
|
470
|
+
const normalizedModuleId = cleanId(moduleId);
|
|
471
|
+
if (normalizedIds.has(normalizedModuleId)) {
|
|
472
|
+
this.moduleCache.delete(moduleId);
|
|
473
|
+
deletedModuleIds.add(normalizedModuleId);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
for (const [moduleId, moduleInfo] of this.moduleCache) {
|
|
477
|
+
if (this.knownRootImports.has(moduleId)) continue;
|
|
478
|
+
for (const binding of moduleInfo.bindings.values()) binding.resolvedKind = void 0;
|
|
479
|
+
}
|
|
480
|
+
this.resolveIdCache.clear();
|
|
481
|
+
this.exportResolutionCache.clear();
|
|
482
|
+
return deletedModuleIds;
|
|
483
|
+
}
|
|
484
|
+
async getTransitiveImporters(ids) {
|
|
485
|
+
const discoveredImporters = /* @__PURE__ */ new Set();
|
|
486
|
+
const pendingTargets =
|
|
487
|
+
typeof ids === 'string' ? [cleanId(ids)] : Array.from(ids, (id) => cleanId(id));
|
|
488
|
+
const visitedTargets = /* @__PURE__ */ new Set();
|
|
489
|
+
const resolveCache = /* @__PURE__ */ new Map();
|
|
490
|
+
const importersByTarget = /* @__PURE__ */ new Map();
|
|
491
|
+
const resolveSource = (source, importer) => {
|
|
492
|
+
const cacheKey = `${importer}::${source}`;
|
|
493
|
+
let resolved = resolveCache.get(cacheKey);
|
|
494
|
+
if (!resolved) {
|
|
495
|
+
resolved = this.resolveIdCached(source, importer);
|
|
496
|
+
resolveCache.set(cacheKey, resolved);
|
|
497
|
+
}
|
|
498
|
+
return resolved;
|
|
499
|
+
};
|
|
500
|
+
await Promise.all(
|
|
501
|
+
Array.from(this.moduleCache.values()).map(async (moduleInfo) => {
|
|
502
|
+
if (this.knownRootImports.has(moduleInfo.id)) return;
|
|
503
|
+
const moduleId = cleanId(moduleInfo.id);
|
|
504
|
+
const importSources = new Set(moduleInfo.reExportAllSources);
|
|
505
|
+
for (const binding of moduleInfo.bindings.values())
|
|
506
|
+
if (binding.type === 'import') importSources.add(binding.source);
|
|
507
|
+
await Promise.all(
|
|
508
|
+
Array.from(importSources, async (source) => {
|
|
509
|
+
const resolved = await resolveSource(source, moduleInfo.id);
|
|
510
|
+
if (!resolved) return;
|
|
511
|
+
const targetId = cleanId(resolved);
|
|
512
|
+
if (targetId === moduleId) return;
|
|
513
|
+
let importers = importersByTarget.get(targetId);
|
|
514
|
+
if (!importers) {
|
|
515
|
+
importers = /* @__PURE__ */ new Set();
|
|
516
|
+
importersByTarget.set(targetId, importers);
|
|
517
|
+
}
|
|
518
|
+
importers.add(moduleId);
|
|
519
|
+
}),
|
|
520
|
+
);
|
|
521
|
+
}),
|
|
522
|
+
);
|
|
523
|
+
while (pendingTargets.length > 0) {
|
|
524
|
+
const targetId = pendingTargets.pop();
|
|
525
|
+
if (visitedTargets.has(targetId)) continue;
|
|
526
|
+
visitedTargets.add(targetId);
|
|
527
|
+
for (const importerId of importersByTarget.get(targetId) ?? []) {
|
|
528
|
+
if (discoveredImporters.has(importerId)) continue;
|
|
529
|
+
discoveredImporters.add(importerId);
|
|
530
|
+
pendingTargets.push(importerId);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return discoveredImporters;
|
|
534
|
+
}
|
|
535
|
+
async compile({ code, id, parserFilename, detectedKinds, warn }) {
|
|
536
|
+
if (!this.initialized) await this.init();
|
|
537
|
+
const fileKinds = detectedKinds
|
|
538
|
+
? new Set([...detectedKinds].filter((k) => this.validLookupKinds.has(k)))
|
|
539
|
+
: this.validLookupKinds;
|
|
540
|
+
const astTransformPlugins = this.getAstTransformPluginsForCode(code);
|
|
541
|
+
const ast = this.ingestModule({
|
|
542
|
+
code,
|
|
543
|
+
id,
|
|
544
|
+
parserFilename,
|
|
545
|
+
}).ast;
|
|
546
|
+
const warnFn = warn ?? this.options.warn;
|
|
547
|
+
let astHasChanges = false;
|
|
548
|
+
builtInTransforms: {
|
|
549
|
+
if (fileKinds.size === 0) break builtInTransforms;
|
|
550
|
+
const hasExternalKinds = hasExternalLookupKinds(fileKinds);
|
|
551
|
+
const checkDirectCalls =
|
|
552
|
+
hasBuiltInDirectCallKinds(fileKinds) ||
|
|
553
|
+
(fileKinds.has('ServerFn') &&
|
|
554
|
+
!hasExternalKinds &&
|
|
555
|
+
hasBuiltInDirectCallKinds(this.validLookupKinds));
|
|
556
|
+
const canUseFastPath = areAllKindsTopLevelOnly(fileKinds);
|
|
557
|
+
const candidatePaths = [];
|
|
558
|
+
const chainCallPaths = /* @__PURE__ */ new Map();
|
|
559
|
+
const jsxCandidatePaths = [];
|
|
560
|
+
const checkJSX = needsJSXDetection(fileKinds, this.externalLookupSetup);
|
|
561
|
+
const moduleInfo = this.moduleCache.get(id);
|
|
562
|
+
const externalDirectCallCandidates = this.getExternalDirectCallCandidates(
|
|
563
|
+
fileKinds,
|
|
564
|
+
moduleInfo,
|
|
565
|
+
);
|
|
566
|
+
const checkExternalDirectCalls = hasExternalDirectCallCandidates(
|
|
567
|
+
externalDirectCallCandidates,
|
|
568
|
+
);
|
|
569
|
+
if (canUseFastPath) {
|
|
570
|
+
const candidateIndices = [];
|
|
571
|
+
for (let i = 0; i < ast.program.body.length; i++) {
|
|
572
|
+
const node = ast.program.body[i];
|
|
573
|
+
let declarations;
|
|
574
|
+
if (t.isVariableDeclaration(node)) declarations = node.declarations;
|
|
575
|
+
else if (t.isExportNamedDeclaration(node) && node.declaration) {
|
|
576
|
+
if (t.isVariableDeclaration(node.declaration))
|
|
577
|
+
declarations = node.declaration.declarations;
|
|
578
|
+
}
|
|
579
|
+
if (declarations)
|
|
580
|
+
for (const decl of declarations) {
|
|
581
|
+
const init = getPotentialCandidateCallExpression(decl.init);
|
|
582
|
+
if (init) {
|
|
583
|
+
if (
|
|
584
|
+
isMethodChainCandidate(init, fileKinds) ||
|
|
585
|
+
(checkDirectCalls && isTopLevelDirectCallCandidateNode(init))
|
|
586
|
+
) {
|
|
587
|
+
candidateIndices.push(i);
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if (candidateIndices.length === 0) break builtInTransforms;
|
|
594
|
+
babel.traverse(ast, {
|
|
595
|
+
Program(programPath) {
|
|
596
|
+
const bodyPaths = programPath.get('body');
|
|
597
|
+
for (const idx of candidateIndices) {
|
|
598
|
+
const stmtPath = bodyPaths[idx];
|
|
599
|
+
if (!stmtPath) continue;
|
|
600
|
+
stmtPath.traverse({
|
|
601
|
+
CallExpression(path) {
|
|
602
|
+
const node = path.node;
|
|
603
|
+
const parent = path.parent;
|
|
604
|
+
if (t.isMemberExpression(parent) && t.isCallExpression(path.parentPath.parent)) {
|
|
605
|
+
chainCallPaths.set(node, path);
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
if (isMethodChainCandidate(node, fileKinds)) {
|
|
609
|
+
candidatePaths.push({ path });
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (checkExternalDirectCalls) {
|
|
613
|
+
const kind = getExternalDirectCallCandidateKind(
|
|
614
|
+
path,
|
|
615
|
+
externalDirectCallCandidates,
|
|
616
|
+
);
|
|
617
|
+
if (kind) {
|
|
618
|
+
candidatePaths.push({
|
|
619
|
+
path,
|
|
620
|
+
kind,
|
|
621
|
+
});
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
if (isTopLevelDirectCallCandidate(path)) candidatePaths.push({ path });
|
|
626
|
+
},
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
programPath.stop();
|
|
630
|
+
},
|
|
631
|
+
});
|
|
632
|
+
} else
|
|
633
|
+
babel.traverse(ast, {
|
|
634
|
+
CallExpression: (path) => {
|
|
635
|
+
const node = path.node;
|
|
636
|
+
const parent = path.parent;
|
|
637
|
+
if (t.isMemberExpression(parent) && t.isCallExpression(path.parentPath.parent)) {
|
|
638
|
+
chainCallPaths.set(node, path);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
if (isMethodChainCandidate(node, fileKinds)) {
|
|
642
|
+
candidatePaths.push({ path });
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
if (checkExternalDirectCalls) {
|
|
646
|
+
const kind = getExternalDirectCallCandidateKind(path, externalDirectCallCandidates);
|
|
647
|
+
if (kind) {
|
|
648
|
+
candidatePaths.push({
|
|
649
|
+
path,
|
|
650
|
+
kind,
|
|
651
|
+
});
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (checkDirectCalls && isTopLevelDirectCallCandidate(path)) {
|
|
656
|
+
candidatePaths.push({ path });
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
if (checkDirectCalls) {
|
|
660
|
+
if (isNestedDirectCallCandidate(node, fileKinds, this.externalLookupSetup)) {
|
|
661
|
+
candidatePaths.push({ path });
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
JSXElement: (path) => {
|
|
667
|
+
if (!checkJSX) return;
|
|
668
|
+
const nameNode = path.node.openingElement.name;
|
|
669
|
+
if (!t.isJSXIdentifier(nameNode)) return;
|
|
670
|
+
const componentName = nameNode.name;
|
|
671
|
+
const binding = moduleInfo.bindings.get(componentName);
|
|
672
|
+
if (!binding || binding.type !== 'import') return;
|
|
673
|
+
const knownExports = this.knownRootImports.get(binding.source);
|
|
674
|
+
if (!knownExports) return;
|
|
675
|
+
if (knownExports.get(binding.importedName) !== 'ClientOnlyJSX') return;
|
|
676
|
+
jsxCandidatePaths.push(path);
|
|
677
|
+
},
|
|
678
|
+
});
|
|
679
|
+
if (candidatePaths.length === 0 && jsxCandidatePaths.length === 0) break builtInTransforms;
|
|
680
|
+
const resolvedCandidates = [];
|
|
681
|
+
const unresolvedCandidates = [];
|
|
682
|
+
for (const candidate of candidatePaths)
|
|
683
|
+
if (candidate.kind)
|
|
684
|
+
resolvedCandidates.push({
|
|
685
|
+
path: candidate.path,
|
|
686
|
+
kind: candidate.kind,
|
|
687
|
+
});
|
|
688
|
+
else unresolvedCandidates.push(candidate);
|
|
689
|
+
if (unresolvedCandidates.length > 0)
|
|
690
|
+
resolvedCandidates.push(
|
|
691
|
+
...(await Promise.all(
|
|
692
|
+
unresolvedCandidates.map(async (candidate) => ({
|
|
693
|
+
path: candidate.path,
|
|
694
|
+
kind: await this.resolveExprKind(candidate.path.node, id),
|
|
695
|
+
})),
|
|
696
|
+
)),
|
|
697
|
+
);
|
|
698
|
+
const validCandidates = resolvedCandidates.filter(({ path, kind }) => {
|
|
699
|
+
if (!this.validLookupKinds.has(kind)) return false;
|
|
700
|
+
if (
|
|
701
|
+
isLookupKind(kind) &&
|
|
702
|
+
kind !== 'ClientOnlyJSX' &&
|
|
703
|
+
!isMethodChainCandidate(path.node, fileKinds)
|
|
704
|
+
)
|
|
705
|
+
return isDirectCallCandidateForKind(kind, this.externalLookupSetup);
|
|
706
|
+
return true;
|
|
707
|
+
});
|
|
708
|
+
if (validCandidates.length === 0 && jsxCandidatePaths.length === 0) break builtInTransforms;
|
|
709
|
+
const pathsToRewrite = [];
|
|
710
|
+
for (const { path, kind } of validCandidates) {
|
|
711
|
+
const node = path.node;
|
|
712
|
+
const methodChain = {
|
|
713
|
+
middleware: null,
|
|
714
|
+
validator: null,
|
|
715
|
+
inputValidator: null,
|
|
716
|
+
handler: null,
|
|
717
|
+
server: null,
|
|
718
|
+
client: null,
|
|
719
|
+
};
|
|
720
|
+
let currentNode = node;
|
|
721
|
+
let currentPath = path;
|
|
722
|
+
while (true) {
|
|
723
|
+
const callee = currentNode.callee;
|
|
724
|
+
if (!t.isMemberExpression(callee)) break;
|
|
725
|
+
if (t.isIdentifier(callee.property)) {
|
|
726
|
+
const name = callee.property.name;
|
|
727
|
+
if (name in methodChain) {
|
|
728
|
+
const args = currentPath.get('arguments');
|
|
729
|
+
const firstArgPath =
|
|
730
|
+
Array.isArray(args) && args.length > 0 ? (args[0] ?? null) : null;
|
|
731
|
+
methodChain[name] = {
|
|
732
|
+
callPath: currentPath,
|
|
733
|
+
firstArgPath,
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (!t.isCallExpression(callee.object)) break;
|
|
738
|
+
currentNode = callee.object;
|
|
739
|
+
const nextPath = chainCallPaths.get(currentNode);
|
|
740
|
+
if (!nextPath) break;
|
|
741
|
+
currentPath = nextPath;
|
|
742
|
+
}
|
|
743
|
+
pathsToRewrite.push({
|
|
744
|
+
path,
|
|
745
|
+
kind,
|
|
746
|
+
methodChain,
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
const refIdents = findReferencedIdentifiers(ast);
|
|
750
|
+
const context = {
|
|
751
|
+
ast,
|
|
752
|
+
id,
|
|
753
|
+
code,
|
|
754
|
+
env: this.options.env,
|
|
755
|
+
envName: this.options.envName,
|
|
756
|
+
mode: this.mode,
|
|
757
|
+
root: this.options.root,
|
|
758
|
+
framework: this.options.framework,
|
|
759
|
+
providerEnvName: this.options.providerEnvName,
|
|
760
|
+
types: t,
|
|
761
|
+
parseExpression: (expressionCode) =>
|
|
762
|
+
babel.template.expression(expressionCode, { placeholderPattern: false })(),
|
|
763
|
+
warn: warnFn,
|
|
764
|
+
generateFunctionId: (opts) => this.generateFunctionId(opts),
|
|
765
|
+
getKnownServerFns: this.options.getKnownServerFns,
|
|
766
|
+
serverFnProviderModuleDirectives: this.options.serverFnProviderModuleDirectives,
|
|
767
|
+
onServerFnsById: this.options.onServerFnsById,
|
|
768
|
+
};
|
|
769
|
+
const candidatesByKind = /* @__PURE__ */ new Map();
|
|
770
|
+
for (const { path: candidatePath, kind, methodChain } of pathsToRewrite) {
|
|
771
|
+
const candidate = {
|
|
772
|
+
path: candidatePath,
|
|
773
|
+
methodChain,
|
|
774
|
+
};
|
|
775
|
+
const existing = candidatesByKind.get(kind);
|
|
776
|
+
if (existing) existing.push(candidate);
|
|
777
|
+
else candidatesByKind.set(kind, [candidate]);
|
|
778
|
+
}
|
|
779
|
+
this.runExternalTransforms('pre', candidatesByKind, context);
|
|
780
|
+
for (const kind of BuiltInKindHandlerOrder) {
|
|
781
|
+
const candidates = candidatesByKind.get(kind);
|
|
782
|
+
if (!candidates) continue;
|
|
783
|
+
const handler = BuiltInKindHandlers[kind];
|
|
784
|
+
handler(candidates, context, kind);
|
|
785
|
+
}
|
|
786
|
+
this.runExternalTransforms('post', candidatesByKind, context);
|
|
787
|
+
for (const jsxPath of jsxCandidatePaths) handleClientOnlyJSX(jsxPath, { env: 'server' });
|
|
788
|
+
deadCodeElimination(ast, refIdents);
|
|
789
|
+
astHasChanges = true;
|
|
790
|
+
}
|
|
791
|
+
if (astTransformPlugins.length > 0)
|
|
792
|
+
astHasChanges =
|
|
793
|
+
this.runAstTransforms({
|
|
794
|
+
ast,
|
|
795
|
+
code,
|
|
796
|
+
id,
|
|
797
|
+
transforms: astTransformPlugins,
|
|
798
|
+
warn: warnFn,
|
|
799
|
+
}) || astHasChanges;
|
|
800
|
+
return astHasChanges ? this.generateResultFromAst(ast, code, id) : null;
|
|
801
|
+
}
|
|
802
|
+
generateResultFromAst(ast, sourceCode, id) {
|
|
803
|
+
const result = generateFromAst(ast, {
|
|
804
|
+
sourceMaps: true,
|
|
805
|
+
sourceFileName: id,
|
|
806
|
+
filename: id,
|
|
807
|
+
});
|
|
808
|
+
if (result.map) result.map.sourcesContent = [sourceCode];
|
|
809
|
+
return result;
|
|
810
|
+
}
|
|
811
|
+
getAstTransformPluginsForCode(code) {
|
|
812
|
+
return this.compilerPlugins.filter((plugin) => {
|
|
813
|
+
if (!plugin.transformAst) return false;
|
|
814
|
+
if (!plugin.detect) return true;
|
|
815
|
+
plugin.detect.lastIndex = 0;
|
|
816
|
+
return plugin.detect.test(code);
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
runAstTransforms({ ast, code, id, transforms, warn }) {
|
|
820
|
+
let modified = false;
|
|
821
|
+
for (const plugin of transforms) {
|
|
822
|
+
const context = {
|
|
823
|
+
ast,
|
|
824
|
+
code,
|
|
825
|
+
id,
|
|
826
|
+
env: this.options.env,
|
|
827
|
+
envName: this.options.envName,
|
|
828
|
+
mode: this.mode,
|
|
829
|
+
root: this.options.root,
|
|
830
|
+
framework: this.options.framework,
|
|
831
|
+
providerEnvName: this.options.providerEnvName,
|
|
832
|
+
types: t,
|
|
833
|
+
parseExpression: (expressionCode) =>
|
|
834
|
+
babel.template.expression(expressionCode, { placeholderPattern: false })(),
|
|
835
|
+
warn,
|
|
836
|
+
};
|
|
837
|
+
modified = plugin.transformAst(context) || modified;
|
|
838
|
+
}
|
|
839
|
+
return modified;
|
|
840
|
+
}
|
|
841
|
+
runExternalTransforms(order, candidatesByKind, context) {
|
|
842
|
+
for (const [kind, transform] of this.externalTransformsByKind) {
|
|
843
|
+
if ((transform.order ?? 'pre') !== order) continue;
|
|
844
|
+
const candidates = candidatesByKind.get(kind);
|
|
845
|
+
if (!candidates) continue;
|
|
846
|
+
transform.transform(candidates, context);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
async resolveIdentifierKind(ident, id, visited = /* @__PURE__ */ new Set()) {
|
|
850
|
+
const binding = (await this.getModuleInfo(id)).bindings.get(ident);
|
|
851
|
+
if (!binding) return 'None';
|
|
852
|
+
if (binding.resolvedKind) return binding.resolvedKind;
|
|
853
|
+
const vKey = `${cleanId(id)}:${ident}`;
|
|
854
|
+
if (visited.has(vKey)) return 'None';
|
|
855
|
+
visited.add(vKey);
|
|
856
|
+
const resolvedKind = await this.resolveBindingKind(binding, id, visited);
|
|
857
|
+
binding.resolvedKind = resolvedKind;
|
|
858
|
+
return resolvedKind;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Recursively find an export in a module, following `export * from` chains.
|
|
862
|
+
* Returns the module info and binding if found, or undefined if not found.
|
|
863
|
+
*/
|
|
864
|
+
async findExportInModule(moduleInfo, exportName, visitedModules = /* @__PURE__ */ new Set()) {
|
|
865
|
+
const isBuildMode = this.mode === 'build';
|
|
866
|
+
if (isBuildMode && visitedModules.size === 0) {
|
|
867
|
+
const moduleCache = this.exportResolutionCache.get(moduleInfo.id);
|
|
868
|
+
if (moduleCache) {
|
|
869
|
+
const cached = moduleCache.get(exportName);
|
|
870
|
+
if (cached !== void 0) return cached ?? void 0;
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
if (visitedModules.has(moduleInfo.id)) return;
|
|
874
|
+
visitedModules.add(moduleInfo.id);
|
|
875
|
+
const localBindingName = moduleInfo.exports.get(exportName);
|
|
876
|
+
if (localBindingName) {
|
|
877
|
+
const binding = moduleInfo.bindings.get(localBindingName);
|
|
878
|
+
if (binding) {
|
|
879
|
+
const result = {
|
|
880
|
+
moduleInfo,
|
|
881
|
+
localName: localBindingName,
|
|
882
|
+
binding,
|
|
883
|
+
};
|
|
884
|
+
if (isBuildMode) this.getExportResolutionCache(moduleInfo.id).set(exportName, result);
|
|
885
|
+
return result;
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (moduleInfo.reExportAllSources.length > 0) {
|
|
889
|
+
const results = await Promise.all(
|
|
890
|
+
moduleInfo.reExportAllSources.map(async (reExportSource) => {
|
|
891
|
+
const reExportTarget = await this.resolveIdCached(reExportSource, moduleInfo.id);
|
|
892
|
+
if (reExportTarget) {
|
|
893
|
+
const reExportModule = await this.getModuleInfo(reExportTarget);
|
|
894
|
+
return this.findExportInModule(reExportModule, exportName, visitedModules);
|
|
895
|
+
}
|
|
896
|
+
}),
|
|
897
|
+
);
|
|
898
|
+
for (const result of results)
|
|
899
|
+
if (result) {
|
|
900
|
+
if (isBuildMode) this.getExportResolutionCache(moduleInfo.id).set(exportName, result);
|
|
901
|
+
return result;
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
if (isBuildMode) this.getExportResolutionCache(moduleInfo.id).set(exportName, null);
|
|
905
|
+
}
|
|
906
|
+
async resolveBindingTarget(resolution, visited = /* @__PURE__ */ new Set()) {
|
|
907
|
+
const key = `${cleanId(resolution.moduleInfo.id)}:${resolution.localName}`;
|
|
908
|
+
if (visited.has(key)) return;
|
|
909
|
+
visited.add(key);
|
|
910
|
+
if (resolution.binding.type !== 'import') return resolution;
|
|
911
|
+
const target = await this.resolveIdCached(resolution.binding.source, resolution.moduleInfo.id);
|
|
912
|
+
if (!target) return;
|
|
913
|
+
const importedModule = await this.getModuleInfo(target);
|
|
914
|
+
const found = await this.findExportInModule(importedModule, resolution.binding.importedName);
|
|
915
|
+
if (!found) return;
|
|
916
|
+
return this.resolveBindingTarget(found, visited);
|
|
917
|
+
}
|
|
918
|
+
async resolveKnownImportKind(binding, resolved) {
|
|
919
|
+
const directKind =
|
|
920
|
+
this.knownRootImports.get(binding.source)?.get(binding.importedName) ?? 'None';
|
|
921
|
+
if (directKind !== 'None') return directKind;
|
|
922
|
+
if (!resolved) return 'None';
|
|
923
|
+
for (const [source, rootExports] of this.knownRootImports) {
|
|
924
|
+
const kind = rootExports.get(binding.importedName);
|
|
925
|
+
if (!kind) continue;
|
|
926
|
+
let targetId;
|
|
927
|
+
try {
|
|
928
|
+
targetId = await this.resolveIdCached(source, resolved.moduleInfo.id);
|
|
929
|
+
} catch {
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
if (!targetId) continue;
|
|
933
|
+
try {
|
|
934
|
+
const rootModule = await this.getModuleInfo(targetId);
|
|
935
|
+
const found = await this.findExportInModule(rootModule, binding.importedName);
|
|
936
|
+
const target = found ? ((await this.resolveBindingTarget(found)) ?? found) : void 0;
|
|
937
|
+
if (
|
|
938
|
+
target &&
|
|
939
|
+
cleanId(resolved.moduleInfo.id) === cleanId(target.moduleInfo.id) &&
|
|
940
|
+
resolved.localName === target.localName
|
|
941
|
+
)
|
|
942
|
+
return kind;
|
|
943
|
+
} catch {
|
|
944
|
+
continue;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return 'None';
|
|
948
|
+
}
|
|
949
|
+
async resolveImportKind(binding, fileId, visited) {
|
|
950
|
+
const directKnownKind = await this.resolveKnownImportKind(binding);
|
|
951
|
+
if (directKnownKind !== 'None') {
|
|
952
|
+
binding.resolvedKind = directKnownKind;
|
|
953
|
+
return directKnownKind;
|
|
954
|
+
}
|
|
955
|
+
if (binding.importedName === '*') return 'None';
|
|
956
|
+
const target = await this.resolveIdCached(binding.source, fileId);
|
|
957
|
+
if (!target) return 'None';
|
|
958
|
+
const importedModule = await this.getModuleInfo(target);
|
|
959
|
+
const found = await this.findExportInModule(importedModule, binding.importedName);
|
|
960
|
+
if (!found) return 'None';
|
|
961
|
+
const knownKind = await this.resolveKnownImportKind(binding, found);
|
|
962
|
+
if (knownKind !== 'None') {
|
|
963
|
+
found.binding.resolvedKind = knownKind;
|
|
964
|
+
binding.resolvedKind = knownKind;
|
|
965
|
+
return knownKind;
|
|
966
|
+
}
|
|
967
|
+
if (found.binding.resolvedKind) return found.binding.resolvedKind;
|
|
968
|
+
const vKey = `${cleanId(found.moduleInfo.id)}:${found.localName}`;
|
|
969
|
+
if (visited.has(vKey)) return 'None';
|
|
970
|
+
visited.add(vKey);
|
|
971
|
+
const resolvedKind = await this.resolveBindingKind(found.binding, found.moduleInfo.id, visited);
|
|
972
|
+
found.binding.resolvedKind = resolvedKind;
|
|
973
|
+
return resolvedKind;
|
|
974
|
+
}
|
|
975
|
+
async resolveBindingKind(binding, fileId, visited = /* @__PURE__ */ new Set()) {
|
|
976
|
+
if (binding.resolvedKind) return binding.resolvedKind;
|
|
977
|
+
if (binding.type === 'import') return this.resolveImportKind(binding, fileId, visited);
|
|
978
|
+
const resolvedKind = await this.resolveExprKind(binding.init, fileId, visited);
|
|
979
|
+
if (
|
|
980
|
+
isLookupKind(resolvedKind) &&
|
|
981
|
+
getLookupSetup(resolvedKind, this.externalLookupSetup)?.type === 'directCall' &&
|
|
982
|
+
binding.init &&
|
|
983
|
+
t.isCallExpression(unwrapExpression(binding.init))
|
|
984
|
+
) {
|
|
985
|
+
binding.resolvedKind = 'None';
|
|
986
|
+
return 'None';
|
|
987
|
+
}
|
|
988
|
+
binding.resolvedKind = resolvedKind;
|
|
989
|
+
return resolvedKind;
|
|
990
|
+
}
|
|
991
|
+
async resolveExprKind(expr, fileId, visited = /* @__PURE__ */ new Set()) {
|
|
992
|
+
if (!expr) return 'None';
|
|
993
|
+
expr = unwrapExpression(expr);
|
|
994
|
+
let result = 'None';
|
|
995
|
+
if (t.isCallExpression(expr)) {
|
|
996
|
+
if (!t.isExpression(expr.callee)) return 'None';
|
|
997
|
+
const calleeKind = await this.resolveCalleeKind(expr.callee, fileId, visited);
|
|
998
|
+
if (calleeKind === 'Root' || calleeKind === 'Builder') return 'Builder';
|
|
999
|
+
if (t.isMemberExpression(expr.callee)) {
|
|
1000
|
+
if (this.validLookupKinds.has(calleeKind)) return calleeKind;
|
|
1001
|
+
}
|
|
1002
|
+
if (t.isIdentifier(expr.callee)) {
|
|
1003
|
+
if (this.validLookupKinds.has(calleeKind)) return calleeKind;
|
|
1004
|
+
}
|
|
1005
|
+
} else if (t.isMemberExpression(expr) && t.isIdentifier(expr.property))
|
|
1006
|
+
result = await this.resolveCalleeKind(expr.object, fileId, visited);
|
|
1007
|
+
if (result === 'None' && t.isIdentifier(expr))
|
|
1008
|
+
result = await this.resolveIdentifierKind(expr.name, fileId, visited);
|
|
1009
|
+
return result;
|
|
1010
|
+
}
|
|
1011
|
+
async resolveCalleeKind(callee, fileId, visited = /* @__PURE__ */ new Set()) {
|
|
1012
|
+
if (t.isIdentifier(callee)) return this.resolveIdentifierKind(callee.name, fileId, visited);
|
|
1013
|
+
if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {
|
|
1014
|
+
const prop = callee.property.name;
|
|
1015
|
+
const possibleKinds = IdentifierToKinds.get(prop);
|
|
1016
|
+
if (possibleKinds) {
|
|
1017
|
+
const base = await this.resolveExprKind(callee.object, fileId, visited);
|
|
1018
|
+
for (const kind of possibleKinds) {
|
|
1019
|
+
if (!this.validLookupKinds.has(kind)) continue;
|
|
1020
|
+
if (kind === 'ServerFn') {
|
|
1021
|
+
if (base === 'Root' || base === 'Builder') return 'ServerFn';
|
|
1022
|
+
} else if (kind === 'Middleware') {
|
|
1023
|
+
if (base === 'Root' || base === 'Builder' || base === 'Middleware') return 'Middleware';
|
|
1024
|
+
} else if (kind === 'IsomorphicFn') {
|
|
1025
|
+
if (base === 'Root' || base === 'Builder' || base === 'IsomorphicFn')
|
|
1026
|
+
return 'IsomorphicFn';
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
if (t.isIdentifier(callee.object)) {
|
|
1031
|
+
const binding = (await this.getModuleInfo(fileId)).bindings.get(callee.object.name);
|
|
1032
|
+
if (binding && binding.type === 'import' && binding.importedName === '*')
|
|
1033
|
+
return this.resolveImportKind(
|
|
1034
|
+
{
|
|
1035
|
+
type: 'import',
|
|
1036
|
+
source: binding.source,
|
|
1037
|
+
importedName: callee.property.name,
|
|
1038
|
+
},
|
|
1039
|
+
fileId,
|
|
1040
|
+
visited,
|
|
1041
|
+
);
|
|
1042
|
+
}
|
|
1043
|
+
return this.resolveExprKind(callee.object, fileId, visited);
|
|
1044
|
+
}
|
|
1045
|
+
return this.resolveExprKind(callee, fileId, visited);
|
|
1046
|
+
}
|
|
1047
|
+
async getModuleInfo(id) {
|
|
1048
|
+
let cached = this.moduleCache.get(id);
|
|
1049
|
+
if (cached) return cached;
|
|
1050
|
+
await this.options.loadModule(id);
|
|
1051
|
+
cached = this.moduleCache.get(id);
|
|
1052
|
+
if (!cached) throw new Error(`could not load module info for ${id}`);
|
|
1053
|
+
return cached;
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
/**
|
|
1057
|
+
* Checks if a CallExpression has a method chain pattern that matches any of the lookup kinds.
|
|
1058
|
+
* E.g., `.handler()`, `.server()`, `.client()`, `.createMiddlewares()`
|
|
1059
|
+
*/
|
|
1060
|
+
function isMethodChainCandidate(node, lookupKinds) {
|
|
1061
|
+
const callee = node.callee;
|
|
1062
|
+
if (!t.isMemberExpression(callee) || !t.isIdentifier(callee.property)) return false;
|
|
1063
|
+
const possibleKinds = IdentifierToKinds.get(callee.property.name);
|
|
1064
|
+
if (possibleKinds) {
|
|
1065
|
+
for (const kind of possibleKinds) if (lookupKinds.has(kind)) return true;
|
|
1066
|
+
}
|
|
1067
|
+
return false;
|
|
1068
|
+
}
|
|
1069
|
+
//#endregion
|
|
1070
|
+
export {
|
|
1071
|
+
KindDetectionPatterns,
|
|
1072
|
+
StartCompiler,
|
|
1073
|
+
detectKindsInCode,
|
|
1074
|
+
getExternalLookupKind,
|
|
1075
|
+
getLookupKindsForEnv,
|
|
1076
|
+
isCompilerTransformEnabledForEnv,
|
|
1077
|
+
isStartCompilerPluginEnabledForEnv,
|
|
1078
|
+
};
|