@tanstack/start-plugin-core 1.167.18 → 1.167.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/config-context.d.ts +26 -0
- package/dist/esm/config-context.js +81 -0
- package/dist/esm/config-context.js.map +1 -0
- package/dist/esm/constants.d.ts +6 -1
- package/dist/esm/constants.js +3 -2
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/import-protection-plugin/extensionlessAbsoluteIdResolver.js +1 -1
- package/dist/esm/import-protection-plugin/plugin.js +1 -1
- package/dist/esm/import-protection-plugin/virtualModules.js +1 -1
- package/dist/esm/index.d.ts +5 -3
- package/dist/esm/index.js +3 -4
- package/dist/esm/planning.d.ts +40 -0
- package/dist/esm/planning.js +107 -0
- package/dist/esm/planning.js.map +1 -0
- package/dist/esm/schema.d.ts +3093 -44
- package/dist/esm/schema.js +5 -5
- package/dist/esm/schema.js.map +1 -1
- package/dist/esm/serialization-adapters-module.d.ts +17 -0
- package/dist/esm/serialization-adapters-module.js +39 -0
- package/dist/esm/serialization-adapters-module.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/compiler.d.ts +2 -3
- package/dist/esm/{start-compiler-plugin → start-compiler}/compiler.js +17 -16
- package/dist/esm/start-compiler/compiler.js.map +1 -0
- package/dist/esm/start-compiler/config.d.ts +4 -0
- package/dist/esm/start-compiler/config.js +54 -0
- package/dist/esm/start-compiler/config.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/handleClientOnlyJSX.js +1 -1
- package/dist/esm/start-compiler/handleClientOnlyJSX.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateIsomorphicFn.js +1 -1
- package/dist/esm/start-compiler/handleCreateIsomorphicFn.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateMiddleware.js +1 -1
- package/dist/esm/start-compiler/handleCreateMiddleware.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateServerFn.js +6 -17
- package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/handleEnvOnly.js +1 -1
- package/dist/esm/start-compiler/handleEnvOnly.js.map +1 -0
- package/dist/esm/start-compiler/host.d.ts +20 -0
- package/dist/esm/start-compiler/host.js +38 -0
- package/dist/esm/start-compiler/host.js.map +1 -0
- package/dist/esm/start-compiler/load-module.d.ts +14 -0
- package/dist/esm/start-compiler/load-module.js +18 -0
- package/dist/esm/start-compiler/load-module.js.map +1 -0
- package/dist/esm/start-compiler/server-fn-resolver-module.d.ts +8 -0
- package/dist/esm/start-compiler/server-fn-resolver-module.js +77 -0
- package/dist/esm/start-compiler/server-fn-resolver-module.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/types.d.ts +4 -0
- package/dist/esm/{start-compiler-plugin → start-compiler}/utils.js +1 -1
- package/dist/esm/start-compiler/utils.js.map +1 -0
- package/dist/esm/start-manifest-plugin/manifestBuilder.d.ts +16 -16
- package/dist/esm/start-manifest-plugin/manifestBuilder.js +14 -45
- package/dist/esm/start-manifest-plugin/manifestBuilder.js.map +1 -1
- package/dist/esm/start-router-plugin/route-tree-footer.d.ts +6 -0
- package/dist/esm/start-router-plugin/route-tree-footer.js +44 -0
- package/dist/esm/start-router-plugin/route-tree-footer.js.map +1 -0
- package/dist/esm/types.d.ts +44 -10
- package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/dev-styles.js +1 -1
- package/dist/esm/vite/dev-server-plugin/dev-styles.js.map +1 -0
- package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/extract-html-scripts.js +1 -1
- package/dist/esm/vite/dev-server-plugin/extract-html-scripts.js.map +1 -0
- package/dist/esm/vite/dev-server-plugin/plugin.d.ts +7 -0
- package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/plugin.js +5 -6
- package/dist/esm/vite/dev-server-plugin/plugin.js.map +1 -0
- package/dist/esm/{load-env-plugin → vite/load-env-plugin}/plugin.js +1 -1
- package/dist/esm/vite/load-env-plugin/plugin.js.map +1 -0
- package/dist/esm/{output-directory.js → vite/output-directory.js} +2 -2
- package/dist/esm/vite/output-directory.js.map +1 -0
- package/dist/esm/vite/planning.d.ts +105 -0
- package/dist/esm/vite/planning.js +116 -0
- package/dist/esm/vite/planning.js.map +1 -0
- package/dist/esm/vite/plugin.d.ts +4 -0
- package/dist/esm/vite/plugin.js +169 -0
- package/dist/esm/vite/plugin.js.map +1 -0
- package/dist/esm/vite/plugins.d.ts +17 -0
- package/dist/esm/vite/plugins.js +50 -0
- package/dist/esm/vite/plugins.js.map +1 -0
- package/dist/esm/{post-server-build.d.ts → vite/post-server-build.d.ts} +1 -1
- package/dist/esm/{post-server-build.js → vite/post-server-build.js} +4 -4
- package/dist/esm/vite/post-server-build.js.map +1 -0
- package/dist/esm/{prerender.d.ts → vite/prerender.d.ts} +1 -1
- package/dist/esm/{prerender.js → vite/prerender.js} +5 -10
- package/dist/esm/vite/prerender.js.map +1 -0
- package/dist/esm/{preview-server-plugin → vite/preview-server-plugin}/plugin.js +4 -4
- package/dist/esm/vite/preview-server-plugin/plugin.js.map +1 -0
- package/dist/esm/vite/schema.d.ts +3373 -0
- package/dist/esm/vite/schema.js +12 -0
- package/dist/esm/vite/schema.js.map +1 -0
- package/dist/esm/vite/serialization-adapters-plugin.d.ts +5 -0
- package/dist/esm/vite/serialization-adapters-plugin.js +42 -0
- package/dist/esm/vite/serialization-adapters-plugin.js.map +1 -0
- package/dist/esm/vite/start-compiler-plugin/module-specifier.d.ts +3 -0
- package/dist/esm/vite/start-compiler-plugin/module-specifier.js +19 -0
- package/dist/esm/vite/start-compiler-plugin/module-specifier.js.map +1 -0
- package/dist/esm/{start-compiler-plugin → vite/start-compiler-plugin}/plugin.d.ts +4 -3
- package/dist/esm/vite/start-compiler-plugin/plugin.js +202 -0
- package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -0
- package/dist/esm/vite/start-manifest-plugin/normalized-client-build.d.ts +6 -0
- package/dist/esm/vite/start-manifest-plugin/normalized-client-build.js +81 -0
- package/dist/esm/vite/start-manifest-plugin/normalized-client-build.js.map +1 -0
- package/dist/esm/vite/start-manifest-plugin/plugin.d.ts +6 -0
- package/dist/esm/{start-manifest-plugin → vite/start-manifest-plugin}/plugin.js +14 -9
- package/dist/esm/vite/start-manifest-plugin/plugin.js.map +1 -0
- package/dist/esm/{start-router-plugin → vite/start-router-plugin}/plugin.d.ts +3 -2
- package/dist/esm/{start-router-plugin → vite/start-router-plugin}/plugin.js +14 -37
- package/dist/esm/vite/start-router-plugin/plugin.js.map +1 -0
- package/dist/esm/vite/types.d.ts +15 -0
- package/package.json +12 -1
- package/src/config-context.ts +138 -0
- package/src/constants.ts +7 -3
- package/src/index.ts +5 -5
- package/src/planning.ts +151 -0
- package/src/schema.ts +93 -93
- package/src/serialization-adapters-module.ts +82 -0
- package/src/{start-compiler-plugin → start-compiler}/compiler.ts +67 -61
- package/src/start-compiler/config.ts +73 -0
- package/src/{start-compiler-plugin → start-compiler}/handleCreateServerFn.ts +14 -41
- package/src/start-compiler/host.ts +80 -0
- package/src/start-compiler/load-module.ts +31 -0
- package/src/start-compiler/server-fn-resolver-module.ts +129 -0
- package/src/{start-compiler-plugin → start-compiler}/types.ts +5 -0
- package/src/start-manifest-plugin/manifestBuilder.ts +65 -107
- package/src/start-router-plugin/route-tree-footer.ts +99 -0
- package/src/types.ts +53 -10
- package/src/{dev-server-plugin → vite/dev-server-plugin}/plugin.ts +7 -6
- package/src/{output-directory.ts → vite/output-directory.ts} +2 -2
- package/src/vite/planning.ts +234 -0
- package/src/vite/plugin.ts +276 -0
- package/src/vite/plugins.ts +81 -0
- package/src/{post-server-build.ts → vite/post-server-build.ts} +4 -6
- package/src/{prerender.ts → vite/prerender.ts} +21 -46
- package/src/{preview-server-plugin → vite/preview-server-plugin}/plugin.ts +2 -2
- package/src/vite/schema.ts +30 -0
- package/src/vite/serialization-adapters-plugin.ts +69 -0
- package/src/vite/start-compiler-plugin/module-specifier.ts +31 -0
- package/src/vite/start-compiler-plugin/plugin.ts +345 -0
- package/src/vite/start-manifest-plugin/normalized-client-build.ts +131 -0
- package/src/{start-manifest-plugin → vite/start-manifest-plugin}/plugin.ts +21 -13
- package/src/{start-router-plugin → vite/start-router-plugin}/plugin.ts +14 -80
- package/src/vite/types.ts +18 -0
- package/dist/esm/dev-server-plugin/dev-styles.js.map +0 -1
- package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +0 -1
- package/dist/esm/dev-server-plugin/plugin.d.ts +0 -6
- package/dist/esm/dev-server-plugin/plugin.js.map +0 -1
- package/dist/esm/load-env-plugin/plugin.js.map +0 -1
- package/dist/esm/output-directory.js.map +0 -1
- package/dist/esm/plugin.d.ts +0 -4
- package/dist/esm/plugin.js +0 -301
- package/dist/esm/plugin.js.map +0 -1
- package/dist/esm/post-server-build.js.map +0 -1
- package/dist/esm/prerender.js.map +0 -1
- package/dist/esm/preview-server-plugin/plugin.js.map +0 -1
- package/dist/esm/start-compiler-plugin/compiler.js.map +0 -1
- package/dist/esm/start-compiler-plugin/handleClientOnlyJSX.js.map +0 -1
- package/dist/esm/start-compiler-plugin/handleCreateIsomorphicFn.js.map +0 -1
- package/dist/esm/start-compiler-plugin/handleCreateMiddleware.js.map +0 -1
- package/dist/esm/start-compiler-plugin/handleCreateServerFn.js.map +0 -1
- package/dist/esm/start-compiler-plugin/handleEnvOnly.js.map +0 -1
- package/dist/esm/start-compiler-plugin/plugin.js +0 -297
- package/dist/esm/start-compiler-plugin/plugin.js.map +0 -1
- package/dist/esm/start-compiler-plugin/utils.js.map +0 -1
- package/dist/esm/start-manifest-plugin/plugin.d.ts +0 -6
- package/dist/esm/start-manifest-plugin/plugin.js.map +0 -1
- package/dist/esm/start-router-plugin/plugin.js.map +0 -1
- package/src/plugin.ts +0 -471
- package/src/start-compiler-plugin/plugin.ts +0 -478
- /package/dist/esm/{start-compiler-plugin → start-compiler}/handleClientOnlyJSX.d.ts +0 -0
- /package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateIsomorphicFn.d.ts +0 -0
- /package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateMiddleware.d.ts +0 -0
- /package/dist/esm/{start-compiler-plugin → start-compiler}/handleCreateServerFn.d.ts +0 -0
- /package/dist/esm/{start-compiler-plugin → start-compiler}/handleEnvOnly.d.ts +0 -0
- /package/dist/esm/{start-compiler-plugin → start-compiler}/utils.d.ts +0 -0
- /package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/dev-styles.d.ts +0 -0
- /package/dist/esm/{dev-server-plugin → vite/dev-server-plugin}/extract-html-scripts.d.ts +0 -0
- /package/dist/esm/{load-env-plugin → vite/load-env-plugin}/plugin.d.ts +0 -0
- /package/dist/esm/{output-directory.d.ts → vite/output-directory.d.ts} +0 -0
- /package/dist/esm/{preview-server-plugin → vite/preview-server-plugin}/plugin.d.ts +0 -0
- /package/src/{start-compiler-plugin → start-compiler}/handleClientOnlyJSX.ts +0 -0
- /package/src/{start-compiler-plugin → start-compiler}/handleCreateIsomorphicFn.ts +0 -0
- /package/src/{start-compiler-plugin → start-compiler}/handleCreateMiddleware.ts +0 -0
- /package/src/{start-compiler-plugin → start-compiler}/handleEnvOnly.ts +0 -0
- /package/src/{start-compiler-plugin → start-compiler}/utils.ts +0 -0
- /package/src/{dev-server-plugin → vite/dev-server-plugin}/dev-styles.ts +0 -0
- /package/src/{dev-server-plugin → vite/dev-server-plugin}/extract-html-scripts.ts +0 -0
- /package/src/{load-env-plugin → vite/load-env-plugin}/plugin.ts +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handleCreateServerFn.js","names":[],"sources":["../../../src/start-compiler-plugin/handleCreateServerFn.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport babel from '@babel/core'\nimport path from 'pathe'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { cleanId, codeFrameError, stripMethodCall } from './utils'\nimport type { CompilationContext, RewriteCandidate, ServerFn } from './types'\nimport type { CompileStartFrameworkOptions } from '../types'\n\nconst TSS_SERVERFN_SPLIT_PARAM = 'tss-serverfn-split'\n\n// ============================================================================\n// Pre-compiled babel templates (compiled once at module load time)\n// ============================================================================\n\n// Template for provider files: createServerRpc(serverFnMeta, fn)\nconst serverRpcTemplate = babel.template.expression(\n `createServerRpc(%%serverFnMeta%%, %%fn%%)`,\n)\n\n// Template for client caller files: createClientRpc(functionId)\nconst clientRpcTemplate = babel.template.expression(\n `createClientRpc(%%functionId%%)`,\n)\n\n// Template for SSR caller files (manifest lookup): createSsrRpc(functionId)\nconst ssrRpcManifestTemplate = babel.template.expression(\n `createSsrRpc(%%functionId%%)`,\n)\n\n// Template for SSR caller files (with importer): createSsrRpc(functionId, () => import(...).then(m => m['name']))\nconst ssrRpcImporterTemplate = babel.template.expression(\n `createSsrRpc(%%functionId%%, () => import(%%extractedFilename%%).then(m => m[%%functionName%%]))`,\n)\n\n// ============================================================================\n// Runtime code cache (cached per framework to avoid repeated AST generation)\n// ============================================================================\n\ntype RuntimeCodeType = 'provider' | 'client' | 'ssr'\ntype FrameworkRuntimeCache = Record<RuntimeCodeType, t.Statement>\nconst RuntimeCodeCache = new Map<\n CompileStartFrameworkOptions,\n FrameworkRuntimeCache\n>()\n\nfunction getCachedRuntimeCode(\n framework: CompileStartFrameworkOptions,\n type: RuntimeCodeType,\n): t.Statement {\n let cache = RuntimeCodeCache.get(framework)\n if (!cache) {\n cache = {\n provider: babel.template.ast(\n `import { createServerRpc } from '@tanstack/${framework}-start/server-rpc'`,\n { placeholderPattern: false },\n ) as t.Statement,\n client: babel.template.ast(\n `import { createClientRpc } from '@tanstack/${framework}-start/client-rpc'`,\n { placeholderPattern: false },\n ) as t.Statement,\n ssr: babel.template.ast(\n `import { createSsrRpc } from '@tanstack/${framework}-start/ssr-rpc'`,\n { placeholderPattern: false },\n ) as t.Statement,\n }\n RuntimeCodeCache.set(framework, cache)\n }\n return cache[type]\n}\n\n/**\n * Environment-specific configuration for server function transformation.\n * This is computed internally based on the compilation context.\n */\ninterface EnvConfig {\n /** Whether this environment is a client environment */\n isClientEnvironment: boolean\n /** Whether SSR is the provider environment */\n ssrIsProvider: boolean\n /** The runtime code type to use for imports */\n runtimeCodeType: RuntimeCodeType\n}\n\n/**\n * Gets the environment configuration for the current compilation context.\n */\nfunction getEnvConfig(\n context: CompilationContext,\n isProviderFile: boolean,\n): EnvConfig {\n const { providerEnvName, env } = context\n\n // SSR is the provider when the provider environment is the default server environment\n const ssrIsProvider = providerEnvName === VITE_ENVIRONMENT_NAMES.server\n\n if (isProviderFile) {\n return {\n isClientEnvironment: false,\n ssrIsProvider,\n runtimeCodeType: 'provider',\n }\n }\n\n if (env === 'client') {\n return {\n isClientEnvironment: true,\n ssrIsProvider,\n runtimeCodeType: 'client',\n }\n }\n\n // Server caller (SSR)\n return {\n isClientEnvironment: false,\n ssrIsProvider,\n runtimeCodeType: 'ssr',\n }\n}\n\n/**\n * Builds the serverFnMeta object literal AST node.\n * The object contains: { id, name, filename }\n */\nfunction buildServerFnMetaObject(\n functionId: string,\n variableName: string,\n filename: string,\n): t.ObjectExpression {\n return t.objectExpression([\n t.objectProperty(t.identifier('id'), t.stringLiteral(functionId)),\n t.objectProperty(t.identifier('name'), t.stringLiteral(variableName)),\n t.objectProperty(t.identifier('filename'), t.stringLiteral(filename)),\n ])\n}\n\n/**\n * Generates the RPC stub expression for provider files.\n * Uses pre-compiled template for performance.\n */\nfunction generateProviderRpcStub(\n serverFnMeta: t.ObjectExpression,\n fn: t.Expression,\n): t.Expression {\n return serverRpcTemplate({\n serverFnMeta,\n fn,\n })\n}\n\n/**\n * Generates the RPC stub expression for caller files.\n * Uses pre-compiled templates for performance.\n * Note: Client and SSR callers only receive the functionId string, not the full metadata.\n */\nfunction generateCallerRpcStub(\n functionId: string,\n functionName: string,\n extractedFilename: string,\n isClientReferenced: boolean,\n envConfig: EnvConfig,\n): t.Expression {\n const functionIdLiteral = t.stringLiteral(functionId)\n\n if (envConfig.runtimeCodeType === 'client') {\n return clientRpcTemplate({\n functionId: functionIdLiteral,\n })\n }\n\n // SSR caller\n // When the function is client-referenced, it's in the manifest - use manifest lookup\n // When SSR is NOT the provider, always use manifest lookup (no import() for different env)\n // Otherwise, use the importer for functions only referenced on the server when SSR is the provider\n if (isClientReferenced || !envConfig.ssrIsProvider) {\n return ssrRpcManifestTemplate({\n functionId: functionIdLiteral,\n })\n }\n\n return ssrRpcImporterTemplate({\n functionId: functionIdLiteral,\n extractedFilename: t.stringLiteral(extractedFilename),\n functionName: t.stringLiteral(functionName),\n })\n}\n\n/**\n * Handles createServerFn transformations for a batch of candidates.\n *\n * This function performs extraction and replacement of server functions\n *\n * For caller files (non-provider):\n * - Replaces the server function with an RPC stub\n * - Does not include the handler function body\n *\n * For provider files:\n * - Creates an extractedFn that calls __executeServer\n * - Modifies .handler() to pass (extractedFn, serverFn) - two arguments\n *\n * @param candidates - All ServerFn candidates to process\n * @param context - The compilation context with helpers and mutable state\n * @returns Result containing runtime code to add, or null if no candidates processed\n */\nexport function handleCreateServerFn(\n candidates: Array<RewriteCandidate>,\n context: CompilationContext,\n) {\n if (candidates.length === 0) {\n return\n }\n\n const isProviderFile = context.id.includes(TSS_SERVERFN_SPLIT_PARAM)\n // Get environment-specific configuration\n const envConfig = getEnvConfig(context, isProviderFile)\n\n // Track function names to ensure uniqueness within this file\n const functionNameSet = new Set<string>()\n\n const exportNames = new Set<string>()\n const serverFnsById: Record<string, ServerFn> = {}\n\n const [baseFilename] = context.id.split('?') as [string]\n const extractedFilename = `${baseFilename}?${TSS_SERVERFN_SPLIT_PARAM}`\n const relativeFilename = path.relative(context.root, baseFilename)\n const knownFns = context.getKnownServerFns()\n const cleanedContextId = cleanId(context.id)\n\n for (const candidate of candidates) {\n const { path: candidatePath, methodChain } = candidate\n const { inputValidator, handler } = methodChain\n\n // Check if the call is assigned to a variable\n if (!candidatePath.parentPath.isVariableDeclarator()) {\n throw new Error('createServerFn must be assigned to a variable!')\n }\n\n // Get the identifier name of the variable\n const variableDeclarator = candidatePath.parentPath.node\n if (!t.isIdentifier(variableDeclarator.id)) {\n throw codeFrameError(\n context.code,\n variableDeclarator.id.loc!,\n 'createServerFn must be assigned to a simple identifier, not a destructuring pattern',\n )\n }\n const existingVariableName = variableDeclarator.id.name\n\n // Generate unique function name with _createServerFn_handler suffix\n // The function name is derived from the variable name\n let functionName = `${existingVariableName}_createServerFn_handler`\n while (functionNameSet.has(functionName)) {\n functionName = incrementFunctionNameVersion(functionName)\n }\n functionNameSet.add(functionName)\n\n // Generate function ID using pre-computed relative filename\n const functionId = context.generateFunctionId({\n filename: relativeFilename,\n functionName,\n extractedFilename,\n })\n\n // Check if this function was already discovered by the client build\n const knownFn = knownFns[functionId]\n const isClientReferenced = envConfig.isClientEnvironment || !!knownFn\n\n // Use canonical extracted filename from known functions if available\n const canonicalExtractedFilename =\n knownFn?.extractedFilename ?? extractedFilename\n\n // Handle input validator - remove on client\n if (inputValidator) {\n const innerInputExpression = inputValidator.callPath.node.arguments[0]\n\n if (!innerInputExpression) {\n throw new Error(\n 'createServerFn().inputValidator() must be called with a validator!',\n )\n }\n\n // If we're on the client, remove the validator call expression\n if (context.env === 'client') {\n stripMethodCall(inputValidator.callPath)\n }\n }\n\n const handlerFnPath = handler?.firstArgPath\n\n if (!handler || !handlerFnPath?.node) {\n throw codeFrameError(\n context.code,\n candidatePath.node.callee.loc!,\n `createServerFn must be called with a \"handler\" property!`,\n )\n }\n\n // Validate the handler argument is an expression (not a SpreadElement, etc.)\n if (!t.isExpression(handlerFnPath.node)) {\n throw codeFrameError(\n context.code,\n handlerFnPath.node.loc!,\n `handler() must be called with an expression, not a ${handlerFnPath.node.type}`,\n )\n }\n\n const handlerFn = handlerFnPath.node\n\n // Register function only from caller files (not provider files)\n // to avoid duplicates - provider files process the same functions\n\n if (!isProviderFile) {\n serverFnsById[functionId] = {\n functionName,\n functionId,\n filename: cleanedContextId,\n extractedFilename: canonicalExtractedFilename,\n isClientReferenced,\n }\n }\n\n if (isProviderFile) {\n // PROVIDER FILE: This is the extracted file that contains the actual implementation\n // We need to:\n // 1. Create an extractedFn that calls __executeServer\n // 2. Modify .handler() to pass (extractedFn, serverFn) - two arguments\n //\n // Expected output format:\n // const extractedFn = createServerRpc({id, name, filename}, (opts) => varName.__executeServer(opts));\n // const varName = createServerFn().handler(extractedFn, originalHandler);\n\n // Build the arrow function: (opts) => varName.__executeServer(opts)\n // The signal parameter is passed through to allow abort signal propagation\n const executeServerArrowFn = t.arrowFunctionExpression(\n [t.identifier('opts')],\n t.callExpression(\n t.memberExpression(\n t.identifier(existingVariableName),\n t.identifier('__executeServer'),\n ),\n [t.identifier('opts')],\n ),\n )\n\n // Build the serverFnMeta object\n const serverFnMeta = buildServerFnMetaObject(\n functionId,\n existingVariableName,\n relativeFilename,\n )\n\n // Generate the replacement using pre-compiled template\n const extractedFnInit = generateProviderRpcStub(\n serverFnMeta,\n executeServerArrowFn,\n )\n\n // Build the extracted function statement\n const extractedFnStatement = t.variableDeclaration('const', [\n t.variableDeclarator(t.identifier(functionName), extractedFnInit),\n ])\n\n // Find the variable declaration statement containing our createServerFn\n const variableDeclaration = candidatePath.parentPath.parentPath\n if (!variableDeclaration.isVariableDeclaration()) {\n throw new Error(\n 'Expected createServerFn to be in a VariableDeclaration',\n )\n }\n\n // Insert the extracted function statement before the variable declaration\n variableDeclaration.insertBefore(extractedFnStatement)\n\n // Modify the .handler() call to pass two arguments: (extractedFn, serverFn)\n // The handlerFnPath.node contains the original serverFn\n const extractedFnIdentifier = t.identifier(functionName)\n const serverFnNode = t.cloneNode(handlerFn, true)\n\n // Replace handler's arguments with [extractedFn, serverFn]\n handler.callPath.node.arguments = [extractedFnIdentifier, serverFnNode]\n\n // Only export the extracted handler (e.g., myFn_createServerFn_handler)\n // The manifest and all import paths only look up this suffixed name.\n // The original variable (e.g., myFn) stays in the file but is not exported\n // since it's only used internally.\n exportNames.add(functionName)\n } else {\n // CALLER FILE: This file calls the server function but doesn't contain the implementation\n // We need to:\n // 1. Remove the handler function body (it will be in the provider file)\n // 2. Replace the handler argument with an RPC stub\n //\n // IMPORTANT: We must keep the createServerFn().handler(extractedFn) structure\n // so that the client middleware chain can unwrap the {result, error, context} response.\n //\n // Expected output format:\n // const myFn = createServerFn().handler(createClientRpc(\"id\"))\n // or\n // const myFn = createServerFn().handler(createSsrRpc(\"id\", () => import(...)))\n\n // If the handler function is an identifier, we need to remove the bound function\n // from the file since it won't be needed\n if (t.isIdentifier(handlerFn)) {\n const binding = handlerFnPath.scope.getBinding(handlerFn.name)\n if (binding) {\n binding.path.remove()\n }\n }\n\n // Generate the RPC stub using pre-compiled templates\n // Note: Caller files only pass functionId, not the full serverFnMeta\n const rpcStub = generateCallerRpcStub(\n functionId,\n functionName,\n canonicalExtractedFilename,\n isClientReferenced,\n envConfig,\n )\n\n // Replace ONLY the handler argument with the RPC stub\n // Keep the createServerFn().handler() wrapper intact for client middleware\n handlerFnPath.replaceWith(rpcStub)\n }\n }\n\n // For provider files, add exports for all extracted functions\n if (isProviderFile) {\n // Remove all existing exports first\n safeRemoveExports(context.ast)\n\n // Export all server function related variables from exportNames\n // These were populated by handleCreateServerFn:\n // 1. Extracted handlers: const fn_createServerFn_handler = createServerRpc(...)\n // 2. Original variables: const fn = createServerFn().handler(...)\n if (exportNames.size > 0) {\n context.ast.program.body.push(\n t.exportNamedDeclaration(\n undefined,\n Array.from(exportNames).map((name) =>\n t.exportSpecifier(t.identifier(name), t.identifier(name)),\n ),\n ),\n )\n }\n }\n\n // Notify about discovered functions (only for non-provider files)\n if (\n !isProviderFile &&\n Object.keys(serverFnsById).length > 0 &&\n context.onServerFnsById\n ) {\n context.onServerFnsById(serverFnsById)\n }\n\n // Add runtime import using cached AST node\n const runtimeCode = getCachedRuntimeCode(\n context.framework,\n envConfig.runtimeCodeType,\n )\n context.ast.program.body.unshift(t.cloneNode(runtimeCode))\n}\n\n/**\n * Makes an identifier safe for use as a JavaScript identifier.\n */\nfunction makeIdentifierSafe(identifier: string): string {\n return identifier\n .replace(/[^a-zA-Z0-9_$]/g, '_') // Replace unsafe chars with underscore\n .replace(/^[0-9]/, '_$&') // Prefix leading number with underscore\n .replace(/^\\$/, '_$') // Prefix leading $ with underscore\n .replace(/_{2,}/g, '_') // Collapse multiple underscores\n .replace(/^_|_$/g, '') // Trim leading/trailing underscores\n}\n\n/**\n * Increments the version number suffix on a function name.\n */\nfunction incrementFunctionNameVersion(functionName: string): string {\n const [realReferenceName, count] = functionName.split(/_(\\d+)$/)\n const resolvedCount = Number(count || '0')\n const suffix = `_${resolvedCount + 1}`\n return makeIdentifierSafe(realReferenceName!) + suffix\n}\n\n/**\n * Removes all exports from the AST while preserving the declarations.\n * Used for provider files where we want to re-export only the server functions.\n */\nfunction safeRemoveExports(ast: t.File): void {\n ast.program.body = ast.program.body.flatMap((node) => {\n if (\n t.isExportNamedDeclaration(node) ||\n t.isExportDefaultDeclaration(node)\n ) {\n if (\n t.isFunctionDeclaration(node.declaration) ||\n t.isClassDeclaration(node.declaration) ||\n t.isVariableDeclaration(node.declaration)\n ) {\n // do not remove export if it is an anonymous function / class,\n // otherwise this would produce a syntax error\n if (\n t.isFunctionDeclaration(node.declaration) ||\n t.isClassDeclaration(node.declaration)\n ) {\n if (!node.declaration.id) {\n return node\n }\n }\n return node.declaration\n } else if (node.declaration === null) {\n // remove e.g. `export { RouteComponent as component }`\n return []\n }\n }\n return node\n })\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"handleEnvOnly.js","names":[],"sources":["../../../src/start-compiler-plugin/handleEnvOnly.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport type { CompilationContext, RewriteCandidate } from './types'\nimport type { LookupKind } from './compiler'\n\nfunction capitalize(str: string) {\n if (!str) return ''\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()\n}\n\n/**\n * Handles serverOnly/clientOnly function transformations for a batch of candidates.\n *\n * @param candidates - All EnvOnly candidates to process (all same kind)\n * @param context - The compilation context\n * @param kind - The specific kind (ServerOnlyFn or ClientOnlyFn)\n */\nexport function handleEnvOnlyFn(\n candidates: Array<RewriteCandidate>,\n context: CompilationContext,\n kind: LookupKind,\n): void {\n const targetEnv = kind === 'ClientOnlyFn' ? 'client' : 'server'\n\n for (const candidate of candidates) {\n const { path } = candidate\n\n if (context.env === targetEnv) {\n // Matching environment - extract the inner function\n const innerFn = path.node.arguments[0]\n\n if (!t.isExpression(innerFn)) {\n throw new Error(\n `create${capitalize(targetEnv)}OnlyFn() must be called with a function!`,\n )\n }\n\n path.replaceWith(innerFn)\n } else {\n // Wrong environment - replace with a function that throws an error\n path.replaceWith(\n t.arrowFunctionExpression(\n [],\n t.blockStatement([\n t.throwStatement(\n t.newExpression(t.identifier('Error'), [\n t.stringLiteral(\n `create${capitalize(targetEnv)}OnlyFn() functions can only be called on the ${targetEnv}!`,\n ),\n ]),\n ),\n ]),\n ),\n )\n }\n }\n}\n"],"mappings":";;AAIA,SAAS,WAAW,KAAa;AAC/B,KAAI,CAAC,IAAK,QAAO;AACjB,QAAO,IAAI,OAAO,EAAE,CAAC,aAAa,GAAG,IAAI,MAAM,EAAE,CAAC,aAAa;;;;;;;;;AAUjE,SAAgB,gBACd,YACA,SACA,MACM;CACN,MAAM,YAAY,SAAS,iBAAiB,WAAW;AAEvD,MAAK,MAAM,aAAa,YAAY;EAClC,MAAM,EAAE,SAAS;AAEjB,MAAI,QAAQ,QAAQ,WAAW;GAE7B,MAAM,UAAU,KAAK,KAAK,UAAU;AAEpC,OAAI,CAAC,EAAE,aAAa,QAAQ,CAC1B,OAAM,IAAI,MACR,SAAS,WAAW,UAAU,CAAC,0CAChC;AAGH,QAAK,YAAY,QAAQ;QAGzB,MAAK,YACH,EAAE,wBACA,EAAE,EACF,EAAE,eAAe,CACf,EAAE,eACA,EAAE,cAAc,EAAE,WAAW,QAAQ,EAAE,CACrC,EAAE,cACA,SAAS,WAAW,UAAU,CAAC,+CAA+C,UAAU,GACzF,CACF,CAAC,CACH,CACF,CAAC,CACH,CACF"}
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
import { SERVER_FN_LOOKUP, TRANSFORM_ID_REGEX, VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
|
2
|
-
import { cleanId } from "./utils.js";
|
|
3
|
-
import { KindDetectionPatterns, LookupKindsPerEnv, StartCompiler, detectKindsInCode } from "./compiler.js";
|
|
4
|
-
import { resolve } from "pathe";
|
|
5
|
-
import { VIRTUAL_MODULES } from "@tanstack/start-server-core";
|
|
6
|
-
import assert from "node:assert";
|
|
7
|
-
//#region src/start-compiler-plugin/plugin.ts
|
|
8
|
-
function getTransformCodeFilterForEnv(env) {
|
|
9
|
-
const validKinds = LookupKindsPerEnv[env];
|
|
10
|
-
const patterns = [];
|
|
11
|
-
for (const [kind, pattern] of Object.entries(KindDetectionPatterns)) if (validKinds.has(kind)) patterns.push(pattern);
|
|
12
|
-
return patterns;
|
|
13
|
-
}
|
|
14
|
-
var getLookupConfigurationsForEnv = (env, framework) => {
|
|
15
|
-
const commonConfigs = [
|
|
16
|
-
{
|
|
17
|
-
libName: `@tanstack/${framework}-start`,
|
|
18
|
-
rootExport: "createServerFn",
|
|
19
|
-
kind: "Root"
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
libName: `@tanstack/${framework}-start`,
|
|
23
|
-
rootExport: "createIsomorphicFn",
|
|
24
|
-
kind: "IsomorphicFn"
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
libName: `@tanstack/${framework}-start`,
|
|
28
|
-
rootExport: "createServerOnlyFn",
|
|
29
|
-
kind: "ServerOnlyFn"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
libName: `@tanstack/${framework}-start`,
|
|
33
|
-
rootExport: "createClientOnlyFn",
|
|
34
|
-
kind: "ClientOnlyFn"
|
|
35
|
-
}
|
|
36
|
-
];
|
|
37
|
-
if (env === "client") return [
|
|
38
|
-
{
|
|
39
|
-
libName: `@tanstack/${framework}-start`,
|
|
40
|
-
rootExport: "createMiddleware",
|
|
41
|
-
kind: "Root"
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
libName: `@tanstack/${framework}-start`,
|
|
45
|
-
rootExport: "createStart",
|
|
46
|
-
kind: "Root"
|
|
47
|
-
},
|
|
48
|
-
...commonConfigs
|
|
49
|
-
];
|
|
50
|
-
else return [...commonConfigs, {
|
|
51
|
-
libName: `@tanstack/${framework}-router`,
|
|
52
|
-
rootExport: "ClientOnly",
|
|
53
|
-
kind: "ClientOnlyJSX"
|
|
54
|
-
}];
|
|
55
|
-
};
|
|
56
|
-
function resolveViteId(id) {
|
|
57
|
-
return `\0${id}`;
|
|
58
|
-
}
|
|
59
|
-
var validateServerFnIdVirtualModule = `virtual:tanstack-start-validate-server-fn-id`;
|
|
60
|
-
function parseIdQuery(id) {
|
|
61
|
-
if (!id.includes("?")) return {
|
|
62
|
-
filename: id,
|
|
63
|
-
query: {}
|
|
64
|
-
};
|
|
65
|
-
const [filename, rawQuery] = id.split(`?`, 2);
|
|
66
|
-
return {
|
|
67
|
-
filename,
|
|
68
|
-
query: Object.fromEntries(new URLSearchParams(rawQuery))
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Generates the manifest module code for server functions.
|
|
73
|
-
* @param serverFnsById - Map of function IDs to their server function info
|
|
74
|
-
* @param includeClientReferencedCheck - Whether to include isClientReferenced flag and runtime check.
|
|
75
|
-
* This is needed when SSR is NOT the provider, so server-only-referenced functions in the manifest
|
|
76
|
-
* can be blocked from client HTTP requests.
|
|
77
|
-
*/
|
|
78
|
-
function generateManifestModule(serverFnsById, includeClientReferencedCheck) {
|
|
79
|
-
return `
|
|
80
|
-
const manifest = {${Object.entries(serverFnsById).map(([id, fn]) => {
|
|
81
|
-
return `'${id}': {
|
|
82
|
-
functionName: '${fn.functionName}',
|
|
83
|
-
importer: () => import(${JSON.stringify(fn.extractedFilename)})${includeClientReferencedCheck ? `,
|
|
84
|
-
isClientReferenced: ${fn.isClientReferenced ?? true}` : ""}
|
|
85
|
-
}`;
|
|
86
|
-
}).join(",")}}
|
|
87
|
-
|
|
88
|
-
export async function getServerFnById(${includeClientReferencedCheck ? "id, opts" : "id"}) {
|
|
89
|
-
const serverFnInfo = manifest[id]
|
|
90
|
-
if (!serverFnInfo) {
|
|
91
|
-
throw new Error('Server function info not found for ' + id)
|
|
92
|
-
}
|
|
93
|
-
${includeClientReferencedCheck ? `
|
|
94
|
-
// If called from client, only allow client-referenced functions
|
|
95
|
-
if (opts?.fromClient && !serverFnInfo.isClientReferenced) {
|
|
96
|
-
throw new Error('Server function not accessible from client: ' + id)
|
|
97
|
-
}
|
|
98
|
-
` : ""}
|
|
99
|
-
const fnModule = await serverFnInfo.importer()
|
|
100
|
-
|
|
101
|
-
if (!fnModule) {
|
|
102
|
-
console.info('serverFnInfo', serverFnInfo)
|
|
103
|
-
throw new Error('Server function module not resolved for ' + id)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const action = fnModule[serverFnInfo.functionName]
|
|
107
|
-
|
|
108
|
-
if (!action) {
|
|
109
|
-
console.info('serverFnInfo', serverFnInfo)
|
|
110
|
-
console.info('fnModule', fnModule)
|
|
111
|
-
|
|
112
|
-
throw new Error(
|
|
113
|
-
\`Server function module export not resolved for serverFn ID: \${id}\`,
|
|
114
|
-
)
|
|
115
|
-
}
|
|
116
|
-
return action
|
|
117
|
-
}
|
|
118
|
-
`;
|
|
119
|
-
}
|
|
120
|
-
function startCompilerPlugin(opts) {
|
|
121
|
-
const compilers = {};
|
|
122
|
-
const serverFnsById = {};
|
|
123
|
-
const onServerFnsById = (d) => {
|
|
124
|
-
Object.assign(serverFnsById, d);
|
|
125
|
-
};
|
|
126
|
-
let root = process.cwd();
|
|
127
|
-
const resolvedResolverVirtualImportId = resolveViteId(VIRTUAL_MODULES.serverFnResolver);
|
|
128
|
-
const ssrEnvName = VITE_ENVIRONMENT_NAMES.server;
|
|
129
|
-
const ssrIsProvider = opts.providerEnvName === ssrEnvName;
|
|
130
|
-
const appliedResolverEnvironments = new Set(ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName]);
|
|
131
|
-
function perEnvServerFnPlugin(environment) {
|
|
132
|
-
const transformCodeFilter = getTransformCodeFilterForEnv(environment.type);
|
|
133
|
-
return {
|
|
134
|
-
name: `tanstack-start-core::server-fn:${environment.name}`,
|
|
135
|
-
enforce: "pre",
|
|
136
|
-
applyToEnvironment(env) {
|
|
137
|
-
return env.name === environment.name;
|
|
138
|
-
},
|
|
139
|
-
configResolved(config) {
|
|
140
|
-
root = config.root;
|
|
141
|
-
config.command;
|
|
142
|
-
},
|
|
143
|
-
transform: {
|
|
144
|
-
filter: {
|
|
145
|
-
id: {
|
|
146
|
-
exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),
|
|
147
|
-
include: TRANSFORM_ID_REGEX
|
|
148
|
-
},
|
|
149
|
-
code: { include: transformCodeFilter }
|
|
150
|
-
},
|
|
151
|
-
async handler(code, id) {
|
|
152
|
-
let compiler = compilers[this.environment.name];
|
|
153
|
-
if (!compiler) {
|
|
154
|
-
const mode = this.environment.mode === "build" ? "build" : "dev";
|
|
155
|
-
compiler = new StartCompiler({
|
|
156
|
-
env: environment.type,
|
|
157
|
-
envName: environment.name,
|
|
158
|
-
root,
|
|
159
|
-
lookupKinds: LookupKindsPerEnv[environment.type],
|
|
160
|
-
lookupConfigurations: getLookupConfigurationsForEnv(environment.type, opts.framework),
|
|
161
|
-
mode,
|
|
162
|
-
framework: opts.framework,
|
|
163
|
-
providerEnvName: opts.providerEnvName,
|
|
164
|
-
generateFunctionId: opts.generateFunctionId,
|
|
165
|
-
onServerFnsById,
|
|
166
|
-
getKnownServerFns: () => serverFnsById,
|
|
167
|
-
loadModule: async (id) => {
|
|
168
|
-
if (this.environment.mode === "build") {
|
|
169
|
-
const code = (await this.load({ id })).code ?? "";
|
|
170
|
-
compiler.ingestModule({
|
|
171
|
-
code,
|
|
172
|
-
id
|
|
173
|
-
});
|
|
174
|
-
} else if (this.environment.mode === "dev")
|
|
175
|
-
/**
|
|
176
|
-
* in dev, vite does not return code from `ctx.load()`
|
|
177
|
-
* so instead, we need to take a different approach
|
|
178
|
-
* we must force vite to load the module and run it through the vite plugin pipeline
|
|
179
|
-
* we can do this by using the `fetchModule` method
|
|
180
|
-
* the `captureServerFnModuleLookupPlugin` captures the module code via its transform hook and invokes analyzeModuleAST
|
|
181
|
-
*/
|
|
182
|
-
await this.environment.fetchModule(id + "?" + SERVER_FN_LOOKUP);
|
|
183
|
-
else throw new Error(`could not load module ${id}: unknown environment mode ${this.environment.mode}`);
|
|
184
|
-
},
|
|
185
|
-
resolveId: async (source, importer) => {
|
|
186
|
-
const r = await this.resolve(source, importer);
|
|
187
|
-
if (r) {
|
|
188
|
-
if (!r.external) return cleanId(r.id);
|
|
189
|
-
}
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
compilers[this.environment.name] = compiler;
|
|
194
|
-
}
|
|
195
|
-
const detectedKinds = detectKindsInCode(code, environment.type);
|
|
196
|
-
return await compiler.compile({
|
|
197
|
-
id,
|
|
198
|
-
code,
|
|
199
|
-
detectedKinds
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
hotUpdate(ctx) {
|
|
204
|
-
const compiler = compilers[this.environment.name];
|
|
205
|
-
ctx.modules.forEach((m) => {
|
|
206
|
-
if (m.id) {
|
|
207
|
-
if (compiler?.invalidateModule(m.id)) m.importers.forEach((importer) => {
|
|
208
|
-
if (importer.id) compiler?.invalidateModule(importer.id);
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
return [
|
|
216
|
-
...opts.environments.map(perEnvServerFnPlugin),
|
|
217
|
-
{
|
|
218
|
-
name: "tanstack-start-core:capture-server-fn-module-lookup",
|
|
219
|
-
apply: "serve",
|
|
220
|
-
applyToEnvironment(env) {
|
|
221
|
-
return !!opts.environments.find((e) => e.name === env.name);
|
|
222
|
-
},
|
|
223
|
-
transform: {
|
|
224
|
-
filter: { id: new RegExp(`${SERVER_FN_LOOKUP}$`) },
|
|
225
|
-
handler(code, id) {
|
|
226
|
-
compilers[this.environment.name]?.ingestModule({
|
|
227
|
-
code,
|
|
228
|
-
id: cleanId(id)
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
},
|
|
233
|
-
{
|
|
234
|
-
name: "tanstack-start-core:validate-server-fn-id",
|
|
235
|
-
apply: "serve",
|
|
236
|
-
load: {
|
|
237
|
-
filter: { id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)) },
|
|
238
|
-
async handler(id) {
|
|
239
|
-
const fnId = parseIdQuery(id).query.id;
|
|
240
|
-
if (fnId && serverFnsById[fnId]) return `export {}`;
|
|
241
|
-
if (fnId) try {
|
|
242
|
-
const decoded = JSON.parse(Buffer.from(fnId, "base64url").toString("utf8"));
|
|
243
|
-
if (typeof decoded.file === "string" && typeof decoded.export === "string") {
|
|
244
|
-
let sourceFile = decoded.file;
|
|
245
|
-
if (sourceFile.startsWith("/@id/")) sourceFile = sourceFile.slice(5);
|
|
246
|
-
const qIdx = sourceFile.indexOf("?");
|
|
247
|
-
if (qIdx !== -1) sourceFile = sourceFile.slice(0, qIdx);
|
|
248
|
-
const absPath = resolve(root, sourceFile);
|
|
249
|
-
assert(this.environment.mode === "dev");
|
|
250
|
-
await this.environment.fetchModule(absPath);
|
|
251
|
-
if (serverFnsById[fnId]) return `export {}`;
|
|
252
|
-
}
|
|
253
|
-
} catch {}
|
|
254
|
-
this.error(`Invalid server function ID: ${fnId}`);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
{
|
|
259
|
-
name: "tanstack-start-core:server-fn-resolver",
|
|
260
|
-
enforce: "pre",
|
|
261
|
-
applyToEnvironment: (env) => {
|
|
262
|
-
return appliedResolverEnvironments.has(env.name);
|
|
263
|
-
},
|
|
264
|
-
configResolved(config) {
|
|
265
|
-
root = config.root;
|
|
266
|
-
config.command;
|
|
267
|
-
},
|
|
268
|
-
resolveId: {
|
|
269
|
-
filter: { id: new RegExp(VIRTUAL_MODULES.serverFnResolver) },
|
|
270
|
-
handler() {
|
|
271
|
-
return resolvedResolverVirtualImportId;
|
|
272
|
-
}
|
|
273
|
-
},
|
|
274
|
-
load: {
|
|
275
|
-
filter: { id: new RegExp(resolvedResolverVirtualImportId) },
|
|
276
|
-
handler() {
|
|
277
|
-
if (this.environment.name !== opts.providerEnvName) return `export { getServerFnById } from '@tanstack/start-server-core/server-fn-ssr-caller'`;
|
|
278
|
-
if (this.environment.mode !== "build") return `
|
|
279
|
-
export async function getServerFnById(id) {
|
|
280
|
-
const validateIdImport = ${JSON.stringify(validateServerFnIdVirtualModule)} + '?id=' + id
|
|
281
|
-
await import(/* @vite-ignore */ '/@id/__x00__' + validateIdImport)
|
|
282
|
-
const decoded = Buffer.from(id, 'base64url').toString('utf8')
|
|
283
|
-
const devServerFn = JSON.parse(decoded)
|
|
284
|
-
const mod = await import(/* @vite-ignore */ devServerFn.file)
|
|
285
|
-
return mod[devServerFn.export]
|
|
286
|
-
}
|
|
287
|
-
`;
|
|
288
|
-
return generateManifestModule(serverFnsById, !ssrIsProvider);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
];
|
|
293
|
-
}
|
|
294
|
-
//#endregion
|
|
295
|
-
export { startCompilerPlugin };
|
|
296
|
-
|
|
297
|
-
//# sourceMappingURL=plugin.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/start-compiler-plugin/plugin.ts"],"sourcesContent":["import assert from 'node:assert'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { resolve as resolvePath } from 'pathe'\nimport {\n SERVER_FN_LOOKUP,\n TRANSFORM_ID_REGEX,\n VITE_ENVIRONMENT_NAMES,\n} from '../constants'\nimport {\n KindDetectionPatterns,\n LookupKindsPerEnv,\n StartCompiler,\n detectKindsInCode,\n} from './compiler'\nimport { cleanId } from './utils'\nimport type { CompileStartFrameworkOptions } from '../types'\nimport type { LookupConfig, LookupKind } from './compiler'\nimport type { GenerateFunctionIdFnOptional, ServerFn } from './types'\nimport type { PluginOption } from 'vite'\n\n// Derive transform code filter from KindDetectionPatterns (single source of truth)\nfunction getTransformCodeFilterForEnv(env: 'client' | 'server'): Array<RegExp> {\n const validKinds = LookupKindsPerEnv[env]\n const patterns: Array<RegExp> = []\n for (const [kind, pattern] of Object.entries(KindDetectionPatterns) as Array<\n [LookupKind, RegExp]\n >) {\n if (validKinds.has(kind)) {\n patterns.push(pattern)\n }\n }\n return patterns\n}\n\nconst getLookupConfigurationsForEnv = (\n env: 'client' | 'server',\n framework: CompileStartFrameworkOptions,\n): Array<LookupConfig> => {\n // Common configs for all environments\n const commonConfigs: Array<LookupConfig> = [\n {\n libName: `@tanstack/${framework}-start`,\n rootExport: 'createServerFn',\n kind: 'Root',\n },\n {\n libName: `@tanstack/${framework}-start`,\n rootExport: 'createIsomorphicFn',\n kind: 'IsomorphicFn',\n },\n {\n libName: `@tanstack/${framework}-start`,\n rootExport: 'createServerOnlyFn',\n kind: 'ServerOnlyFn',\n },\n {\n libName: `@tanstack/${framework}-start`,\n rootExport: 'createClientOnlyFn',\n kind: 'ClientOnlyFn',\n },\n ]\n\n if (env === 'client') {\n return [\n {\n libName: `@tanstack/${framework}-start`,\n rootExport: 'createMiddleware',\n kind: 'Root',\n },\n {\n libName: `@tanstack/${framework}-start`,\n rootExport: 'createStart',\n kind: 'Root',\n },\n ...commonConfigs,\n ]\n } else {\n // Server-only: add ClientOnly JSX component lookup\n return [\n ...commonConfigs,\n {\n libName: `@tanstack/${framework}-router`,\n rootExport: 'ClientOnly',\n kind: 'ClientOnlyJSX',\n },\n ]\n }\n}\n// Re-export from shared constants for backwards compatibility\nexport { SERVER_FN_LOOKUP }\n\nfunction resolveViteId(id: string) {\n return `\\0${id}`\n}\n\nconst validateServerFnIdVirtualModule = `virtual:tanstack-start-validate-server-fn-id`\n\nfunction parseIdQuery(id: string): {\n filename: string\n query: {\n [k: string]: string\n }\n} {\n if (!id.includes('?')) return { filename: id, query: {} }\n const [filename, rawQuery] = id.split(`?`, 2) as [string, string]\n const query = Object.fromEntries(new URLSearchParams(rawQuery))\n return { filename, query }\n}\n\n/**\n * Generates the manifest module code for server functions.\n * @param serverFnsById - Map of function IDs to their server function info\n * @param includeClientReferencedCheck - Whether to include isClientReferenced flag and runtime check.\n * This is needed when SSR is NOT the provider, so server-only-referenced functions in the manifest\n * can be blocked from client HTTP requests.\n */\nfunction generateManifestModule(\n serverFnsById: Record<string, ServerFn>,\n includeClientReferencedCheck: boolean,\n): string {\n const manifestEntries = Object.entries(serverFnsById)\n .map(([id, fn]) => {\n const baseEntry = `'${id}': {\n functionName: '${fn.functionName}',\n importer: () => import(${JSON.stringify(fn.extractedFilename)})${\n includeClientReferencedCheck\n ? `,\n isClientReferenced: ${fn.isClientReferenced ?? true}`\n : ''\n }\n }`\n return baseEntry\n })\n .join(',')\n\n const getServerFnByIdParams = includeClientReferencedCheck ? 'id, opts' : 'id'\n const clientReferencedCheck = includeClientReferencedCheck\n ? `\n // If called from client, only allow client-referenced functions\n if (opts?.fromClient && !serverFnInfo.isClientReferenced) {\n throw new Error('Server function not accessible from client: ' + id)\n }\n`\n : ''\n\n return `\n const manifest = {${manifestEntries}}\n\n export async function getServerFnById(${getServerFnByIdParams}) {\n const serverFnInfo = manifest[id]\n if (!serverFnInfo) {\n throw new Error('Server function info not found for ' + id)\n }\n${clientReferencedCheck}\n const fnModule = await serverFnInfo.importer()\n\n if (!fnModule) {\n console.info('serverFnInfo', serverFnInfo)\n throw new Error('Server function module not resolved for ' + id)\n }\n\n const action = fnModule[serverFnInfo.functionName]\n\n if (!action) {\n console.info('serverFnInfo', serverFnInfo)\n console.info('fnModule', fnModule)\n\n throw new Error(\n \\`Server function module export not resolved for serverFn ID: \\${id}\\`,\n )\n }\n return action\n }\n `\n}\n\nexport interface StartCompilerPluginOptions {\n framework: CompileStartFrameworkOptions\n environments: Array<{ name: string; type: 'client' | 'server' }>\n /**\n * Custom function ID generator (optional).\n */\n generateFunctionId?: GenerateFunctionIdFnOptional\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n}\n\nexport function startCompilerPlugin(\n opts: StartCompilerPluginOptions,\n): PluginOption {\n const compilers: Record<string /* envName */, StartCompiler> = {}\n\n // Shared registry of server functions across all environments\n const serverFnsById: Record<string, ServerFn> = {}\n\n const onServerFnsById = (d: Record<string, ServerFn>) => {\n Object.assign(serverFnsById, d)\n }\n\n let root = process.cwd()\n let _command: 'build' | 'serve' = 'build'\n\n const resolvedResolverVirtualImportId = resolveViteId(\n VIRTUAL_MODULES.serverFnResolver,\n )\n\n // Determine which environments need the resolver (getServerFnById)\n // SSR environment always needs the resolver for server-side calls\n // Provider environment needs it for the actual implementation\n const ssrEnvName = VITE_ENVIRONMENT_NAMES.server\n\n // SSR is the provider when the provider environment is the default server environment\n const ssrIsProvider = opts.providerEnvName === ssrEnvName\n\n // Environments that need the resolver: SSR (for server calls) and provider (for implementation)\n const appliedResolverEnvironments = new Set(\n ssrIsProvider ? [opts.providerEnvName] : [ssrEnvName, opts.providerEnvName],\n )\n\n function perEnvServerFnPlugin(environment: {\n name: string\n type: 'client' | 'server'\n }): PluginOption {\n // Derive transform code filter from KindDetectionPatterns (single source of truth)\n const transformCodeFilter = getTransformCodeFilterForEnv(environment.type)\n\n return {\n name: `tanstack-start-core::server-fn:${environment.name}`,\n enforce: 'pre',\n applyToEnvironment(env) {\n return env.name === environment.name\n },\n configResolved(config) {\n root = config.root\n _command = config.command\n },\n transform: {\n filter: {\n id: {\n exclude: new RegExp(`${SERVER_FN_LOOKUP}$`),\n include: TRANSFORM_ID_REGEX,\n },\n code: {\n include: transformCodeFilter,\n },\n },\n async handler(code, id) {\n let compiler = compilers[this.environment.name]\n if (!compiler) {\n // Default to 'dev' mode for unknown environments (conservative: no caching)\n const mode = this.environment.mode === 'build' ? 'build' : 'dev'\n compiler = new StartCompiler({\n env: environment.type,\n envName: environment.name,\n root,\n lookupKinds: LookupKindsPerEnv[environment.type],\n lookupConfigurations: getLookupConfigurationsForEnv(\n environment.type,\n opts.framework,\n ),\n mode,\n framework: opts.framework,\n providerEnvName: opts.providerEnvName,\n generateFunctionId: opts.generateFunctionId,\n onServerFnsById,\n getKnownServerFns: () => serverFnsById,\n loadModule: async (id: string) => {\n if (this.environment.mode === 'build') {\n const loaded = await this.load({ id })\n // Handle modules with no runtime code (e.g., type-only exports).\n // After TypeScript compilation, these become empty modules.\n // Create an empty module info instead of throwing.\n const code = loaded.code ?? ''\n compiler!.ingestModule({ code, id })\n } else if (this.environment.mode === 'dev') {\n /**\n * in dev, vite does not return code from `ctx.load()`\n * so instead, we need to take a different approach\n * we must force vite to load the module and run it through the vite plugin pipeline\n * we can do this by using the `fetchModule` method\n * the `captureServerFnModuleLookupPlugin` captures the module code via its transform hook and invokes analyzeModuleAST\n */\n await this.environment.fetchModule(\n id + '?' + SERVER_FN_LOOKUP,\n )\n } else {\n throw new Error(\n `could not load module ${id}: unknown environment mode ${this.environment.mode}`,\n )\n }\n },\n resolveId: async (source: string, importer?: string) => {\n const r = await this.resolve(source, importer)\n if (r) {\n if (!r.external) {\n return cleanId(r.id)\n }\n }\n return null\n },\n })\n compilers[this.environment.name] = compiler\n }\n\n // Detect which kinds are present in this file before parsing\n const detectedKinds = detectKindsInCode(code, environment.type)\n\n const result = await compiler.compile({\n id,\n code,\n detectedKinds,\n })\n return result\n },\n },\n\n hotUpdate(ctx) {\n const compiler = compilers[this.environment.name]\n\n ctx.modules.forEach((m) => {\n if (m.id) {\n const deleted = compiler?.invalidateModule(m.id)\n if (deleted) {\n m.importers.forEach((importer) => {\n if (importer.id) {\n compiler?.invalidateModule(importer.id)\n }\n })\n }\n }\n })\n },\n }\n }\n\n return [\n ...opts.environments.map(perEnvServerFnPlugin),\n {\n name: 'tanstack-start-core:capture-server-fn-module-lookup',\n // we only need this plugin in dev mode\n apply: 'serve',\n applyToEnvironment(env) {\n return !!opts.environments.find((e) => e.name === env.name)\n },\n transform: {\n filter: {\n id: new RegExp(`${SERVER_FN_LOOKUP}$`),\n },\n handler(code, id) {\n const compiler = compilers[this.environment.name]\n compiler?.ingestModule({ code, id: cleanId(id) })\n },\n },\n },\n // Validate server function ID in dev mode\n {\n name: 'tanstack-start-core:validate-server-fn-id',\n apply: 'serve',\n load: {\n filter: {\n id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)),\n },\n async handler(id) {\n const parsed = parseIdQuery(id)\n const fnId = parsed.query.id\n if (fnId && serverFnsById[fnId]) {\n return `export {}`\n }\n\n // ID not yet registered — the source file may not have been\n // transformed in this dev session yet (e.g. cold restart with\n // cached client). Try to decode the ID, discover the source\n // file, trigger its compilation, and re-check.\n if (fnId) {\n try {\n const decoded = JSON.parse(\n Buffer.from(fnId, 'base64url').toString('utf8'),\n )\n if (\n typeof decoded.file === 'string' &&\n typeof decoded.export === 'string'\n ) {\n // decoded.file looks like \"/@id/src/foo.ts?tss-serverfn-split\"\n // Strip the /@id/ prefix and ?tss-serverfn-split suffix to\n // get the original source file path that needs transforming.\n let sourceFile = decoded.file\n if (sourceFile.startsWith('/@id/')) {\n sourceFile = sourceFile.slice('/@id/'.length)\n }\n const qIdx = sourceFile.indexOf('?')\n if (qIdx !== -1) {\n sourceFile = sourceFile.slice(0, qIdx)\n }\n\n // Resolve to absolute path\n const absPath = resolvePath(root, sourceFile)\n\n // Trigger transform of the source file in this environment,\n // which will compile createServerFn calls and populate\n // serverFnsById as a side effect.\n // This plugin only runs in dev (apply: 'serve'), so mode\n // must be 'dev' — assert to narrow to DevEnvironment.\n assert(this.environment.mode === 'dev')\n await this.environment.fetchModule(absPath)\n\n // Re-check after lazy compilation\n if (serverFnsById[fnId]) {\n return `export {}`\n }\n }\n } catch {\n // Decoding or fetching failed — fall through to error\n }\n }\n\n this.error(`Invalid server function ID: ${fnId}`)\n },\n },\n },\n // Manifest plugin for server environments\n {\n name: 'tanstack-start-core:server-fn-resolver',\n enforce: 'pre',\n applyToEnvironment: (env) => {\n return appliedResolverEnvironments.has(env.name)\n },\n configResolved(config) {\n root = config.root\n _command = config.command\n },\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.serverFnResolver) },\n handler() {\n return resolvedResolverVirtualImportId\n },\n },\n load: {\n filter: { id: new RegExp(resolvedResolverVirtualImportId) },\n handler() {\n // When SSR is not the provider, SSR callers need to use HTTP to call server functions\n // since they can't directly import from the provider environment\n if (this.environment.name !== opts.providerEnvName) {\n // SSR caller: use HTTP-based getServerFnById\n // This re-exports from the start-server-core package which handles HTTP calls\n return `export { getServerFnById } from '@tanstack/start-server-core/server-fn-ssr-caller'`\n }\n\n if (this.environment.mode !== 'build') {\n const mod = `\n export async function getServerFnById(id) {\n const validateIdImport = ${JSON.stringify(validateServerFnIdVirtualModule)} + '?id=' + id\n await import(/* @vite-ignore */ '/@id/__x00__' + validateIdImport)\n const decoded = Buffer.from(id, 'base64url').toString('utf8')\n const devServerFn = JSON.parse(decoded)\n const mod = await import(/* @vite-ignore */ devServerFn.file)\n return mod[devServerFn.export]\n }\n `\n return mod\n }\n\n // When SSR is the provider, server-only-referenced functions aren't in the manifest,\n // so no isClientReferenced check is needed.\n // When SSR is NOT the provider (custom provider env), server-only-referenced\n // functions ARE in the manifest and need the isClientReferenced check to\n // block direct client HTTP requests to server-only-referenced functions.\n const includeClientReferencedCheck = !ssrIsProvider\n return generateManifestModule(\n serverFnsById,\n includeClientReferencedCheck,\n )\n },\n },\n },\n ]\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/start-compiler-plugin/utils.ts"],"sourcesContent":["import { codeFrameColumns } from '@babel/code-frame'\nimport * as t from '@babel/types'\nimport type babel from '@babel/core'\n\nexport function codeFrameError(\n code: string,\n loc: {\n start: { line: number; column: number }\n end: { line: number; column: number }\n },\n message: string,\n) {\n const frame = codeFrameColumns(\n code,\n {\n start: loc.start,\n end: loc.end,\n },\n {\n highlightCode: true,\n message,\n },\n )\n\n return new Error(frame)\n}\n\nexport function cleanId(id: string): string {\n // Remove null byte prefix used by Vite/Rollup for virtual modules\n if (id.startsWith('\\0')) {\n id = id.slice(1)\n }\n const queryIndex = id.indexOf('?')\n return queryIndex === -1 ? id : id.substring(0, queryIndex)\n}\n\n/**\n * Strips a method call by replacing it with its callee object.\n * E.g., `foo().bar()` -> `foo()`\n *\n * This is a common pattern used when removing method calls from chains\n * (e.g., removing .server() from middleware on client, or .inputValidator() on client).\n *\n * @param callPath - The path to the CallExpression to strip\n */\nexport function stripMethodCall(\n callPath: babel.NodePath<t.CallExpression>,\n): void {\n if (t.isMemberExpression(callPath.node.callee)) {\n callPath.replaceWith(callPath.node.callee.object)\n }\n}\n"],"mappings":";;;AAIA,SAAgB,eACd,MACA,KAIA,SACA;CACA,MAAM,QAAQ,iBACZ,MACA;EACE,OAAO,IAAI;EACX,KAAK,IAAI;EACV,EACD;EACE,eAAe;EACf;EACD,CACF;AAED,QAAO,IAAI,MAAM,MAAM;;AAGzB,SAAgB,QAAQ,IAAoB;AAE1C,KAAI,GAAG,WAAW,KAAK,CACrB,MAAK,GAAG,MAAM,EAAE;CAElB,MAAM,aAAa,GAAG,QAAQ,IAAI;AAClC,QAAO,eAAe,KAAK,KAAK,GAAG,UAAU,GAAG,WAAW;;;;;;;;;;;AAY7D,SAAgB,gBACd,UACM;AACN,KAAI,EAAE,mBAAmB,SAAS,KAAK,OAAO,CAC5C,UAAS,YAAY,SAAS,KAAK,OAAO,OAAO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import { joinURL } from 'ufo'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { resolveViteId } from '../utils'\nimport { ENTRY_POINTS } from '../constants'\nimport { buildStartManifest } from './manifestBuilder'\nimport type { GetConfigFn } from '../types'\nimport type { PluginOption, Rollup } from 'vite'\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\n\nexport function startManifestPlugin(opts: {\n getClientBundle: () => Rollup.OutputBundle\n getConfig: GetConfigFn\n}): PluginOption {\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n const { resolvedStartConfig } = opts.getConfig()\n if (id === resolvedModuleId) {\n if (\n this.environment.name !== resolvedStartConfig.serverFnProviderEnv\n ) {\n return `export default {}`\n }\n\n if (this.environment.config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(resolvedStartConfig.viteAppBase, '@id', ENTRY_POINTS.client)}',\n })`\n }\n\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST\n const startManifest = buildStartManifest({\n clientBundle: opts.getClientBundle(),\n routeTreeRoutes,\n basePath: resolvedStartConfig.viteAppBase,\n })\n\n return `export const tsrStartManifest = () => (${JSON.stringify(startManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"mappings":";;;;;;AAQA,IAAM,mBAAmB,cAAc,gBAAgB,cAAc;AAErE,SAAgB,oBAAoB,MAGnB;AACf,QAAO;EACL,MAAM;EACN,SAAS;EACT,WAAW;GACT,QAAQ,EAAE,IAAI,IAAI,OAAO,gBAAgB,cAAc,EAAE;GACzD,QAAQ,IAAI;AACV,QAAI,OAAO,gBAAgB,cACzB,QAAO;;GAIZ;EACD,MAAM;GACJ,QAAQ,EACN,IAAI,IAAI,OAAO,iBAAiB,EACjC;GACD,QAAQ,IAAI;IACV,MAAM,EAAE,wBAAwB,KAAK,WAAW;AAChD,QAAI,OAAO,kBAAkB;AAC3B,SACE,KAAK,YAAY,SAAS,oBAAoB,oBAE9C,QAAO;AAGT,SAAI,KAAK,YAAY,OAAO,YAAY,QACtC,QAAO;;4BAES,QAAQ,oBAAoB,aAAa,OAAO,aAAa,OAAO,CAAC;;KAIvF,MAAM,kBAAkB,WAAW;KACnC,MAAM,gBAAgB,mBAAmB;MACvC,cAAc,KAAK,iBAAiB;MACpC;MACA,UAAU,oBAAoB;MAC/B,CAAC;AAEF,YAAO,0CAA0C,KAAK,UAAU,cAAc,CAAC;;;GAKpF;EACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../../src/start-router-plugin/plugin.ts"],"sourcesContent":["import {\n tanStackRouterCodeSplitter,\n tanstackRouterAutoImport,\n tanstackRouterGenerator,\n} from '@tanstack/router-plugin/vite'\nimport { normalizePath } from 'vite'\nimport path from 'pathe'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { routesManifestPlugin } from './generator-plugins/routes-manifest-plugin'\nimport { prerenderRoutesPlugin } from './generator-plugins/prerender-routes-plugin'\nimport { pruneServerOnlySubtrees } from './pruneServerOnlySubtrees'\nimport { SERVER_PROP } from './constants'\nimport type { GetConfigFn, TanStackStartVitePluginCoreOptions } from '../types'\nimport type {\n Generator,\n GeneratorPlugin,\n RouteNode,\n} from '@tanstack/router-generator'\nimport type { DevEnvironment, Plugin, PluginOption } from 'vite'\nimport type { TanStackStartInputConfig } from '../schema'\n\nfunction isServerOnlyNode(node: RouteNode | undefined) {\n if (!node?.createFileRouteProps) {\n return false\n }\n return (\n node.createFileRouteProps.has(SERVER_PROP) &&\n node.createFileRouteProps.size === 1\n )\n}\n\nfunction moduleDeclaration({\n startFilePath,\n routerFilePath,\n corePluginOpts,\n generatedRouteTreePath,\n}: {\n startFilePath: string | undefined\n routerFilePath: string\n corePluginOpts: TanStackStartVitePluginCoreOptions\n generatedRouteTreePath: string\n}): string {\n function getImportPath(absolutePath: string) {\n let relativePath = path.relative(\n path.dirname(generatedRouteTreePath),\n absolutePath,\n )\n\n if (!relativePath.startsWith('.')) {\n relativePath = './' + relativePath\n }\n\n // convert to POSIX-style for ESM imports (important on Windows)\n relativePath = relativePath.split(path.sep).join('/')\n return relativePath\n }\n\n const result: Array<string> = [\n `import type { getRouter } from '${getImportPath(routerFilePath)}'`,\n ]\n if (startFilePath) {\n result.push(\n `import type { startInstance } from '${getImportPath(startFilePath)}'`,\n )\n }\n // make sure we import something from start to get the server route declaration merge\n else {\n result.push(\n `import type { createStart } from '@tanstack/${corePluginOpts.framework}-start'`,\n )\n }\n result.push(\n `declare module '@tanstack/${corePluginOpts.framework}-start' {\n interface Register {\n ssr: true\n router: Awaited<ReturnType<typeof getRouter>>`,\n )\n if (startFilePath) {\n result.push(\n ` config: Awaited<ReturnType<typeof startInstance.getOptions>>`,\n )\n }\n result.push(` }\n}`)\n\n return result.join('\\n')\n}\n\nexport function tanStackStartRouter(\n startPluginOpts: TanStackStartInputConfig,\n getConfig: GetConfigFn,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n): Array<PluginOption> {\n const getGeneratedRouteTreePath = () => {\n const { startConfig } = getConfig()\n return path.resolve(startConfig.router.generatedRouteTree)\n }\n\n let clientEnvironment: DevEnvironment | null = null\n function invalidate() {\n if (!clientEnvironment) {\n return\n }\n\n const mod = clientEnvironment.moduleGraph.getModuleById(\n getGeneratedRouteTreePath(),\n )\n if (mod) {\n clientEnvironment.moduleGraph.invalidateModule(mod)\n }\n clientEnvironment.hot.send({ type: 'full-reload', path: '*' })\n }\n\n let generatorInstance: Generator | null = null\n\n const clientTreeGeneratorPlugin: GeneratorPlugin = {\n name: 'start-client-tree-plugin',\n init({ generator }) {\n generatorInstance = generator\n },\n afterTransform({ node, prevNode }) {\n if (isServerOnlyNode(node) !== isServerOnlyNode(prevNode)) {\n invalidate()\n }\n },\n }\n\n let routeTreeFileFooter: Array<string> | null = null\n\n function getRouteTreeFileFooter() {\n if (routeTreeFileFooter) {\n return routeTreeFileFooter\n }\n const { startConfig, resolvedStartConfig } = getConfig()\n const ogRouteTreeFileFooter = startConfig.router.routeTreeFileFooter\n if (ogRouteTreeFileFooter) {\n if (Array.isArray(ogRouteTreeFileFooter)) {\n routeTreeFileFooter = ogRouteTreeFileFooter\n } else {\n routeTreeFileFooter = ogRouteTreeFileFooter()\n }\n }\n routeTreeFileFooter = [\n moduleDeclaration({\n generatedRouteTreePath: getGeneratedRouteTreePath(),\n corePluginOpts,\n startFilePath: resolvedStartConfig.startFilePath,\n routerFilePath: resolvedStartConfig.routerFilePath,\n }),\n ...(routeTreeFileFooter ?? []),\n ]\n return routeTreeFileFooter\n }\n\n let resolvedGeneratedRouteTreePath: string | null = null\n const clientTreePlugin: Plugin = {\n name: 'tanstack-start:route-tree-client-plugin',\n enforce: 'pre',\n applyToEnvironment: (env) => env.name === VITE_ENVIRONMENT_NAMES.client,\n configureServer(server) {\n clientEnvironment = server.environments[VITE_ENVIRONMENT_NAMES.client]\n },\n config() {\n type LoadObjectHook = Extract<\n typeof clientTreePlugin.load,\n { filter?: unknown }\n >\n resolvedGeneratedRouteTreePath = normalizePath(\n getGeneratedRouteTreePath(),\n )\n ;(clientTreePlugin.load as LoadObjectHook).filter = {\n id: { include: new RegExp(resolvedGeneratedRouteTreePath) },\n }\n },\n\n load: {\n filter: {\n // this will be set in the config hook above since it relies on `config` hook being called first\n },\n async handler() {\n if (!generatorInstance) {\n throw new Error('Generator instance not initialized')\n }\n const crawlingResult = await generatorInstance.getCrawlingResult()\n if (!crawlingResult) {\n throw new Error('Crawling result not available')\n }\n const prunedAcc = pruneServerOnlySubtrees(crawlingResult)\n const acc = {\n ...crawlingResult.acc,\n ...prunedAcc,\n }\n const buildResult = generatorInstance.buildRouteTree({\n ...crawlingResult,\n acc,\n config: {\n // importRoutesUsingAbsolutePaths: true,\n // addExtensions: true,\n disableTypes: true,\n enableRouteTreeFormatting: false,\n routeTreeFileHeader: [],\n routeTreeFileFooter: [],\n },\n })\n return { code: buildResult.routeTreeContent, map: null }\n },\n },\n }\n return [\n clientTreePlugin,\n tanstackRouterGenerator(() => {\n const routerConfig = getConfig().startConfig.router\n const plugins = [clientTreeGeneratorPlugin, routesManifestPlugin()]\n if (startPluginOpts?.prerender?.enabled === true) {\n plugins.push(prerenderRoutesPlugin())\n }\n return {\n ...routerConfig,\n target: corePluginOpts.framework,\n routeTreeFileFooter: getRouteTreeFileFooter,\n plugins,\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n deleteNodes: ['ssr', 'server', 'headers'],\n addHmr: true,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.client },\n },\n }\n }),\n tanStackRouterCodeSplitter(() => {\n const routerConfig = getConfig().startConfig.router\n return {\n ...routerConfig,\n codeSplittingOptions: {\n ...routerConfig.codeSplittingOptions,\n addHmr: false,\n },\n plugin: {\n vite: { environmentName: VITE_ENVIRONMENT_NAMES.server },\n },\n }\n }),\n tanstackRouterAutoImport(startPluginOpts?.router),\n ]\n}\n"],"mappings":"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"}
|