@tanstack/start-plugin-core 1.166.10 → 1.166.12

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.
@@ -120,7 +120,8 @@ function buildSitemap({
120
120
  }
121
121
  function createXml(elementName) {
122
122
  return create({ version: "1.0", encoding: "UTF-8" }).ele(elementName, {
123
- xmlns: "https://www.sitemaps.org/schemas/sitemap/0.9"
123
+ xmlns: "https://www.sitemaps.org/schemas/sitemap/0.9",
124
+ "xmlns:xhtml": "http://www.w3.org/1999/xhtml"
124
125
  }).com(`This file was automatically generated by TanStack Start.`);
125
126
  }
126
127
  function checkSlash(host) {
@@ -1 +1 @@
1
- {"version":3,"file":"build-sitemap.js","sources":["../../src/build-sitemap.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { create } from 'xmlbuilder2'\nimport { createLogger } from './utils'\nimport type { TanStackStartOutputConfig } from './schema'\nimport type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'\n\nexport type SitemapUrl = {\n loc: string\n lastmod: string\n priority?: number\n changefreq?:\n | 'always'\n | 'hourly'\n | 'daily'\n | 'weekly'\n | 'monthly'\n | 'yearly'\n | 'never'\n alternateRefs?: Array<{\n href: string\n hreflang?: string\n }>\n images?: Array<{\n loc: string\n title?: string\n caption?: string\n }>\n news?: {\n publication: {\n name: string\n language: string\n }\n publicationDate: string | Date\n title: string\n }\n}\n\nexport type SitemapData = {\n urls: Array<SitemapUrl>\n}\n\nfunction buildSitemapJson(\n pages: TanStackStartOutputConfig['pages'],\n host: string,\n): SitemapData {\n const slash = checkSlash(host)\n\n const urls: Array<SitemapUrl> = pages\n .filter((page) => {\n return page.sitemap?.exclude !== true\n })\n .map((page) => ({\n loc: `${host}${slash}${page.path.replace(/^\\/+/g, '')}`,\n lastmod: page.sitemap?.lastmod\n ? new Date(page.sitemap.lastmod).toISOString().split('T')[0]!\n : new Date().toISOString().split('T')[0]!,\n priority: page.sitemap?.priority,\n changefreq: page.sitemap?.changefreq,\n alternateRefs: page.sitemap?.alternateRefs,\n images: page.sitemap?.images,\n news: page.sitemap?.news,\n }))\n\n return { urls }\n}\n\nfunction jsonToXml(sitemapData: SitemapData): string {\n const sitemap = createXml('urlset')\n\n for (const item of sitemapData.urls) {\n const page = sitemap.ele('url')\n page.ele('loc').txt(item.loc)\n page.ele('lastmod').txt(item.lastmod)\n\n if (item.priority !== undefined) {\n page.ele('priority').txt(item.priority.toString())\n }\n if (item.changefreq) {\n page.ele('changefreq').txt(item.changefreq)\n }\n\n // Add alternate references\n if (item.alternateRefs?.length) {\n for (const ref of item.alternateRefs) {\n const alternateRef = page.ele('xhtml:link')\n alternateRef.att('rel', 'alternate')\n alternateRef.att('href', ref.href)\n if (ref.hreflang) {\n alternateRef.att('hreflang', ref.hreflang)\n }\n }\n }\n\n // Add images\n if (item.images?.length) {\n for (const image of item.images) {\n const imageElement = page.ele('image:image')\n imageElement.ele('image:loc').txt(image.loc)\n if (image.title) {\n imageElement.ele('image:title').txt(image.title)\n }\n if (image.caption) {\n imageElement.ele('image:caption').txt(image.caption)\n }\n }\n }\n\n // Add news\n if (item.news) {\n const newsElement = page.ele('news:news')\n const publication = newsElement.ele('news:publication')\n publication.ele('news:name').txt(item.news.publication.name)\n publication.ele('news:language').txt(item.news.publication.language)\n newsElement\n .ele('news:publication_date')\n .txt(new Date(item.news.publicationDate).toISOString().split('T')[0]!)\n newsElement.ele('news:title').txt(item.news.title)\n }\n }\n\n return sitemap.end({ prettyPrint: true })\n}\n\nexport function buildSitemap({\n startConfig,\n publicDir,\n}: {\n startConfig: TanStackStartOutputConfig\n publicDir: string\n}) {\n const logger = createLogger('sitemap')\n\n let sitemapOptions = startConfig.sitemap\n\n if (!sitemapOptions && startConfig.pages.length) {\n sitemapOptions = { enabled: true, outputPath: 'sitemap.xml' }\n }\n\n if (!sitemapOptions?.enabled) {\n throw new Error('Sitemap is not enabled')\n }\n\n const { host, outputPath } = sitemapOptions\n\n if (!host) {\n if (!startConfig.sitemap) {\n logger.info(\n 'Hint: Pages found, but no sitemap host has been set. To enable sitemap generation, set the `sitemap.host` option.',\n )\n return\n }\n throw new Error(\n 'Sitemap host is not set and required to build the sitemap.',\n )\n }\n\n if (!outputPath) {\n throw new Error('Sitemap output path is not set')\n }\n\n const { pages } = startConfig\n\n if (!pages.length) {\n logger.info('No pages were found to build the sitemap. Skipping...')\n return\n }\n\n logger.info('Building Sitemap...')\n\n // Build the sitemap data\n const sitemapData = buildSitemapJson(pages, host)\n\n // Generate output paths\n const xmlOutputPath = path.join(publicDir, outputPath)\n const pagesOutputPath = path.join(publicDir, 'pages.json')\n\n try {\n // Write XML sitemap\n logger.info(`Writing sitemap XML at ${xmlOutputPath}`)\n writeFileSync(xmlOutputPath, jsonToXml(sitemapData))\n\n // Write pages data for runtime use\n logger.info(`Writing pages data at ${pagesOutputPath}`)\n writeFileSync(\n pagesOutputPath,\n JSON.stringify(\n {\n pages,\n host,\n lastBuilt: new Date().toISOString(),\n },\n null,\n 2,\n ),\n )\n } catch (e) {\n logger.error(`Unable to write sitemap files`, e)\n }\n}\n\nfunction createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {\n return create({ version: '1.0', encoding: 'UTF-8' })\n .ele(elementName, {\n xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',\n })\n .com(`This file was automatically generated by TanStack Start.`)\n}\n\nfunction checkSlash(host: string): string {\n const finalChar = host.slice(-1)\n return finalChar === '/' ? '' : '/'\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-sitemap.js","sources":["../../src/build-sitemap.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { create } from 'xmlbuilder2'\nimport { createLogger } from './utils'\nimport type { TanStackStartOutputConfig } from './schema'\nimport type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'\n\nexport type SitemapUrl = {\n loc: string\n lastmod: string\n priority?: number\n changefreq?:\n | 'always'\n | 'hourly'\n | 'daily'\n | 'weekly'\n | 'monthly'\n | 'yearly'\n | 'never'\n alternateRefs?: Array<{\n href: string\n hreflang?: string\n }>\n images?: Array<{\n loc: string\n title?: string\n caption?: string\n }>\n news?: {\n publication: {\n name: string\n language: string\n }\n publicationDate: string | Date\n title: string\n }\n}\n\nexport type SitemapData = {\n urls: Array<SitemapUrl>\n}\n\nfunction buildSitemapJson(\n pages: TanStackStartOutputConfig['pages'],\n host: string,\n): SitemapData {\n const slash = checkSlash(host)\n\n const urls: Array<SitemapUrl> = pages\n .filter((page) => {\n return page.sitemap?.exclude !== true\n })\n .map((page) => ({\n loc: `${host}${slash}${page.path.replace(/^\\/+/g, '')}`,\n lastmod: page.sitemap?.lastmod\n ? new Date(page.sitemap.lastmod).toISOString().split('T')[0]!\n : new Date().toISOString().split('T')[0]!,\n priority: page.sitemap?.priority,\n changefreq: page.sitemap?.changefreq,\n alternateRefs: page.sitemap?.alternateRefs,\n images: page.sitemap?.images,\n news: page.sitemap?.news,\n }))\n\n return { urls }\n}\n\nfunction jsonToXml(sitemapData: SitemapData): string {\n const sitemap = createXml('urlset')\n\n for (const item of sitemapData.urls) {\n const page = sitemap.ele('url')\n page.ele('loc').txt(item.loc)\n page.ele('lastmod').txt(item.lastmod)\n\n if (item.priority !== undefined) {\n page.ele('priority').txt(item.priority.toString())\n }\n if (item.changefreq) {\n page.ele('changefreq').txt(item.changefreq)\n }\n\n // Add alternate references\n if (item.alternateRefs?.length) {\n for (const ref of item.alternateRefs) {\n const alternateRef = page.ele('xhtml:link')\n alternateRef.att('rel', 'alternate')\n alternateRef.att('href', ref.href)\n if (ref.hreflang) {\n alternateRef.att('hreflang', ref.hreflang)\n }\n }\n }\n\n // Add images\n if (item.images?.length) {\n for (const image of item.images) {\n const imageElement = page.ele('image:image')\n imageElement.ele('image:loc').txt(image.loc)\n if (image.title) {\n imageElement.ele('image:title').txt(image.title)\n }\n if (image.caption) {\n imageElement.ele('image:caption').txt(image.caption)\n }\n }\n }\n\n // Add news\n if (item.news) {\n const newsElement = page.ele('news:news')\n const publication = newsElement.ele('news:publication')\n publication.ele('news:name').txt(item.news.publication.name)\n publication.ele('news:language').txt(item.news.publication.language)\n newsElement\n .ele('news:publication_date')\n .txt(new Date(item.news.publicationDate).toISOString().split('T')[0]!)\n newsElement.ele('news:title').txt(item.news.title)\n }\n }\n\n return sitemap.end({ prettyPrint: true })\n}\n\nexport function buildSitemap({\n startConfig,\n publicDir,\n}: {\n startConfig: TanStackStartOutputConfig\n publicDir: string\n}) {\n const logger = createLogger('sitemap')\n\n let sitemapOptions = startConfig.sitemap\n\n if (!sitemapOptions && startConfig.pages.length) {\n sitemapOptions = { enabled: true, outputPath: 'sitemap.xml' }\n }\n\n if (!sitemapOptions?.enabled) {\n throw new Error('Sitemap is not enabled')\n }\n\n const { host, outputPath } = sitemapOptions\n\n if (!host) {\n if (!startConfig.sitemap) {\n logger.info(\n 'Hint: Pages found, but no sitemap host has been set. To enable sitemap generation, set the `sitemap.host` option.',\n )\n return\n }\n throw new Error(\n 'Sitemap host is not set and required to build the sitemap.',\n )\n }\n\n if (!outputPath) {\n throw new Error('Sitemap output path is not set')\n }\n\n const { pages } = startConfig\n\n if (!pages.length) {\n logger.info('No pages were found to build the sitemap. Skipping...')\n return\n }\n\n logger.info('Building Sitemap...')\n\n // Build the sitemap data\n const sitemapData = buildSitemapJson(pages, host)\n\n // Generate output paths\n const xmlOutputPath = path.join(publicDir, outputPath)\n const pagesOutputPath = path.join(publicDir, 'pages.json')\n\n try {\n // Write XML sitemap\n logger.info(`Writing sitemap XML at ${xmlOutputPath}`)\n writeFileSync(xmlOutputPath, jsonToXml(sitemapData))\n\n // Write pages data for runtime use\n logger.info(`Writing pages data at ${pagesOutputPath}`)\n writeFileSync(\n pagesOutputPath,\n JSON.stringify(\n {\n pages,\n host,\n lastBuilt: new Date().toISOString(),\n },\n null,\n 2,\n ),\n )\n } catch (e) {\n logger.error(`Unable to write sitemap files`, e)\n }\n}\n\nfunction createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {\n return create({ version: '1.0', encoding: 'UTF-8' })\n .ele(elementName, {\n xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',\n 'xmlns:xhtml': 'http://www.w3.org/1999/xhtml',\n })\n .com(`This file was automatically generated by TanStack Start.`)\n}\n\nfunction checkSlash(host: string): string {\n const finalChar = host.slice(-1)\n return finalChar === '/' ? '' : '/'\n}\n"],"names":[],"mappings":"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"}
@@ -685,14 +685,14 @@ function importProtectionPlugin(opts) {
685
685
  return void 0;
686
686
  }
687
687
  if (info.type === "file") return info.resolved;
688
- const exports = await resolveExportsForDeniedSpecifier(
688
+ const exports$1 = await resolveExportsForDeniedSpecifier(
689
689
  env,
690
690
  ctx,
691
691
  info,
692
692
  importerIdHint
693
693
  );
694
694
  const baseMockId = config.command === "serve" ? mockRuntimeModuleIdFromViolation(info, config.mockAccess, config.root) : `${MOCK_BUILD_PREFIX}${buildViolationCounter++}`;
695
- return resolveViteId(makeMockEdgeModuleId(exports, baseMockId));
695
+ return resolveViteId(makeMockEdgeModuleId(exports$1, baseMockId));
696
696
  }
697
697
  async function reportOrDeferViolation(ctx, env, importerFile, importerIdHint, info, shouldDefer, isPreTransformResolve) {
698
698
  if (shouldDefer) {
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/import-protection-plugin/plugin.ts"],"sourcesContent":["import { normalizePath } from 'vite'\n\nimport { resolveViteId } from '../utils'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { ImportGraph, buildTrace, formatViolation } from './trace'\nimport {\n getDefaultImportProtectionRules,\n getMarkerSpecifiers,\n} from './defaults'\nimport { compileMatchers, matchesAny } from './matchers'\nimport {\n buildResolutionCandidates,\n buildSourceCandidates,\n canonicalizeResolvedId,\n clearNormalizeFilePathCache,\n debugLog,\n dedupePatterns,\n escapeRegExp,\n extractImportSources,\n getOrCreate,\n isInsideDirectory,\n matchesDebugFilter,\n normalizeFilePath,\n relativizePath,\n shouldDeferViolation,\n} from './utils'\nimport {\n collectMockExportNamesBySource,\n collectNamedExports,\n rewriteDeniedImports,\n} from './rewriteDeniedImports'\nimport {\n MOCK_BUILD_PREFIX,\n generateDevSelfDenialModule,\n generateSelfContainedMockModule,\n getResolvedVirtualModuleMatchers,\n loadResolvedVirtualModule,\n makeMockEdgeModuleId,\n mockRuntimeModuleIdFromViolation,\n resolveInternalVirtualModuleId,\n resolvedMarkerVirtualModuleId,\n} from './virtualModules'\nimport { ExtensionlessAbsoluteIdResolver } from './extensionlessAbsoluteIdResolver'\nimport {\n IMPORT_PROTECTION_DEBUG,\n SERVER_FN_LOOKUP_QUERY,\n VITE_BROWSER_VIRTUAL_PREFIX,\n} from './constants'\nimport {\n ImportLocCache,\n addTraceImportLocations,\n buildCodeSnippet,\n buildLineIndex,\n findImportStatementLocationFromTransformed,\n findPostCompileUsageLocation,\n pickOriginalCodeFromSourcesContent,\n} from './sourceLocation'\nimport type { PluginOption, ViteDevServer } from 'vite'\nimport type { CompiledMatcher } from './matchers'\nimport type { Loc, TraceStep, ViolationInfo } from './trace'\nimport type {\n SourceMapLike,\n TransformResult,\n TransformResultProvider,\n} from './sourceLocation'\nimport type { ImportProtectionOptions } from '../schema'\nimport type {\n EnvRules,\n EnvState,\n HandleViolationResult,\n ImportProtectionPluginOptions,\n ModuleGraphNode,\n PendingViolation,\n PluginConfig,\n SharedState,\n ViolationReporter,\n} from './types'\n\nexport type { ImportProtectionPluginOptions } from './types'\n\nexport function importProtectionPlugin(\n opts: ImportProtectionPluginOptions,\n): PluginOption {\n let devServer: ViteDevServer | null = null\n const extensionlessIdResolver = new ExtensionlessAbsoluteIdResolver()\n const resolveExtensionlessAbsoluteId = (id: string) =>\n extensionlessIdResolver.resolve(id)\n\n const importPatternCache = new Map<string, Array<RegExp>>()\n\n function findFirstImportSpecifierIndex(code: string, source: string): number {\n let patterns = importPatternCache.get(source)\n if (!patterns) {\n const escaped = escapeRegExp(source)\n patterns = [\n new RegExp(`\\\\bimport\\\\s+(['\"])${escaped}\\\\1`),\n new RegExp(`\\\\bfrom\\\\s+(['\"])${escaped}\\\\1`),\n new RegExp(`\\\\bimport\\\\s*\\\\(\\\\s*(['\"])${escaped}\\\\1\\\\s*\\\\)`),\n ]\n importPatternCache.set(source, patterns)\n }\n\n let best = -1\n for (const re of patterns) {\n const m = re.exec(code)\n if (!m) continue\n const idx = m.index + m[0].indexOf(source)\n if (idx === -1) continue\n if (best === -1 || idx < best) best = idx\n }\n return best\n }\n\n /**\n * Build an import trace using Vite's per-environment module graph, which\n * is authoritative even on warm starts when the plugin's own ImportGraph\n * may be incomplete (Vite skips resolveId for cached modules).\n */\n function buildTraceFromModuleGraph(\n envName: string,\n env: EnvState,\n targetFile: string,\n ): Array<TraceStep> | null {\n if (!devServer) return null\n const environment = devServer.environments[envName]\n if (!environment) return null\n\n const file = normalizeFilePath(targetFile)\n const start = environment.moduleGraph.getModuleById(file)\n if (!start) return null\n\n // Resolve a module graph node to its normalized file path once and\n // cache the result so BFS + reconstruction don't recompute.\n const nodeIds = new Map<ModuleGraphNode, string>()\n function nodeId(n: ModuleGraphNode): string {\n let cached = nodeIds.get(n)\n if (cached === undefined) {\n cached = n.id\n ? normalizeFilePath(n.id)\n : n.url\n ? normalizeFilePath(n.url)\n : ''\n nodeIds.set(n, cached)\n }\n return cached\n }\n\n const queue: Array<ModuleGraphNode> = [start]\n const visited = new Set<ModuleGraphNode>([start])\n const parent = new Map<ModuleGraphNode, ModuleGraphNode>()\n\n let entryRoot: ModuleGraphNode | null = null\n let fallbackRoot: ModuleGraphNode | null = null\n let qi = 0\n while (qi < queue.length) {\n const node = queue[qi++]!\n const id = nodeId(node)\n\n if (id && env.graph.entries.has(id)) {\n entryRoot = node\n break\n }\n\n const importers = node.importers\n if (importers.size === 0) {\n if (!fallbackRoot) fallbackRoot = node\n continue\n }\n\n for (const imp of importers) {\n if (visited.has(imp)) continue\n visited.add(imp)\n parent.set(imp, node)\n queue.push(imp)\n }\n }\n\n const root = entryRoot ?? fallbackRoot\n\n if (!root) return null\n\n // Reconstruct: root -> ... -> start\n const chain: Array<ModuleGraphNode> = []\n let cur: ModuleGraphNode | undefined = root\n for (let i = 0; i < config.maxTraceDepth + 2 && cur; i++) {\n chain.push(cur)\n if (cur === start) break\n cur = parent.get(cur)\n }\n\n const steps: Array<TraceStep> = []\n for (let i = 0; i < chain.length; i++) {\n const id = nodeId(chain[i]!)\n if (!id) continue\n let specifier: string | undefined\n if (i + 1 < chain.length) {\n const nextId = nodeId(chain[i + 1]!)\n if (nextId) {\n specifier = env.graph.reverseEdges.get(nextId)?.get(id)\n }\n }\n steps.push(specifier ? { file: id, specifier } : { file: id })\n }\n\n return steps.length ? steps : null\n }\n\n const config: PluginConfig = {\n enabled: true,\n root: '',\n command: 'build',\n srcDirectory: '',\n framework: opts.framework,\n effectiveBehavior: 'error',\n mockAccess: 'error',\n logMode: 'once',\n maxTraceDepth: 20,\n compiledRules: {\n client: { specifiers: [], files: [], excludeFiles: [] },\n server: { specifiers: [], files: [], excludeFiles: [] },\n },\n includeMatchers: [],\n excludeMatchers: [],\n ignoreImporterMatchers: [],\n markerSpecifiers: { serverOnly: new Set(), clientOnly: new Set() },\n envTypeMap: new Map(opts.environments.map((e) => [e.name, e.type])),\n onViolation: undefined,\n }\n\n const envStates = new Map<string, EnvState>()\n const shared: SharedState = { fileMarkerKind: new Map() }\n\n /**\n * Build the best available trace for a module and enrich each step with\n * line/column locations. Tries the plugin's own ImportGraph first, then\n * Vite's moduleGraph (authoritative on warm start), keeping whichever is\n * longer. Annotates the last step with the denied specifier + location.\n *\n * Shared by {@link buildViolationInfo} and {@link processPendingViolations}.\n */\n async function rebuildAndAnnotateTrace(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n normalizedImporter: string,\n specifier: string,\n importerLoc: Loc | undefined,\n traceOverride?: Array<TraceStep>,\n ): Promise<Array<TraceStep>> {\n let trace =\n traceOverride ??\n buildTrace(env.graph, normalizedImporter, config.maxTraceDepth)\n\n if (config.command === 'serve') {\n const mgTrace = buildTraceFromModuleGraph(\n envName,\n env,\n normalizedImporter,\n )\n if (mgTrace && mgTrace.length > trace.length) {\n trace = mgTrace\n }\n }\n await addTraceImportLocations(\n provider,\n trace,\n env.importLocCache,\n findFirstImportSpecifierIndex,\n )\n\n if (trace.length > 0) {\n const last = trace[trace.length - 1]!\n if (!last.specifier) last.specifier = specifier\n if (importerLoc && last.line == null) {\n last.line = importerLoc.line\n last.column = importerLoc.column\n }\n }\n\n return trace\n }\n\n /**\n * Build a complete {@link ViolationInfo} with trace, location, and snippet.\n *\n * This is the single path that all violation types go through: specifier,\n * file, and marker.\n */\n async function buildViolationInfo(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n envType: 'client' | 'server',\n importer: string,\n normalizedImporter: string,\n source: string,\n overrides: Omit<\n ViolationInfo,\n | 'env'\n | 'envType'\n | 'behavior'\n | 'specifier'\n | 'importer'\n | 'trace'\n | 'snippet'\n | 'importerLoc'\n >,\n traceOverride?: Array<TraceStep>,\n ): Promise<ViolationInfo> {\n const sourceCandidates = buildSourceCandidates(\n source,\n 'resolved' in overrides && typeof overrides.resolved === 'string'\n ? overrides.resolved\n : undefined,\n config.root,\n )\n\n const loc = await resolveImporterLocation(\n provider,\n env,\n importer,\n sourceCandidates,\n )\n\n const trace = await rebuildAndAnnotateTrace(\n provider,\n env,\n envName,\n normalizedImporter,\n source,\n loc,\n traceOverride,\n )\n\n const snippet = loc ? buildCodeSnippet(provider, importer, loc) : undefined\n\n return {\n env: envName,\n envType,\n behavior: config.effectiveBehavior,\n specifier: source,\n importer: normalizedImporter,\n ...(loc ? { importerLoc: loc } : {}),\n trace,\n snippet,\n ...overrides,\n }\n }\n\n async function resolveImporterLocation(\n provider: TransformResultProvider,\n env: EnvState,\n importer: string,\n sourceCandidates: Iterable<string>,\n ): Promise<Loc | undefined> {\n for (const candidate of sourceCandidates) {\n const loc =\n (await findPostCompileUsageLocation(provider, importer, candidate)) ||\n (await findImportStatementLocationFromTransformed(\n provider,\n importer,\n candidate,\n env.importLocCache,\n findFirstImportSpecifierIndex,\n ))\n if (loc) return loc\n }\n return undefined\n }\n\n /**\n * Check if a resolved import violates marker restrictions (e.g. importing\n * a server-only module in the client env). If so, build and return the\n * {@link ViolationInfo} — the caller is responsible for reporting/deferring.\n *\n * Returns `undefined` when the resolved import has no marker conflict.\n */\n async function buildMarkerViolationFromResolvedImport(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n envType: 'client' | 'server',\n importer: string,\n source: string,\n resolvedId: string,\n relativePath: string,\n traceOverride?: Array<TraceStep>,\n ): Promise<ViolationInfo | undefined> {\n const normalizedResolvedId = normalizeFilePath(resolvedId)\n const markerKind = shared.fileMarkerKind.get(normalizedResolvedId)\n const violates =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n if (!violates) return undefined\n\n const normalizedImporter = normalizeFilePath(importer)\n\n return buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'marker',\n resolved: normalizedResolvedId,\n message: buildMarkerViolationMessage(relativePath, markerKind),\n },\n traceOverride,\n )\n }\n\n function buildMarkerViolationMessage(\n relativePath: string,\n markerKind: 'server' | 'client' | undefined,\n ): string {\n return markerKind === 'server'\n ? `Module \"${relativePath}\" is marked server-only but is imported in the client environment`\n : `Module \"${relativePath}\" is marked client-only but is imported in the server environment`\n }\n\n async function buildFileViolationInfo(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n envType: 'client' | 'server',\n importer: string,\n normalizedImporter: string,\n source: string,\n resolvedPath: string,\n pattern: string | RegExp,\n traceOverride?: Array<TraceStep>,\n ): Promise<ViolationInfo> {\n const relativePath = getRelativePath(resolvedPath)\n\n return buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'file',\n pattern,\n resolved: resolvedPath,\n message: `Import \"${source}\" (resolved to \"${relativePath}\") is denied in the ${envType} environment`,\n },\n traceOverride,\n )\n }\n\n function getEnvType(envName: string): 'client' | 'server' {\n return config.envTypeMap.get(envName) ?? 'server'\n }\n\n function getRulesForEnvironment(envName: string): EnvRules {\n const type = getEnvType(envName)\n return type === 'client'\n ? config.compiledRules.client\n : config.compiledRules.server\n }\n\n /**\n * Check if a relative path matches any denied file pattern for the given\n * environment, respecting `excludeFiles`. Returns the matching pattern\n * or `undefined` if the file is not denied.\n */\n function checkFileDenial(\n relativePath: string,\n matchers: {\n files: Array<CompiledMatcher>\n excludeFiles: Array<CompiledMatcher>\n },\n ): CompiledMatcher | undefined {\n if (\n matchers.excludeFiles.length > 0 &&\n matchesAny(relativePath, matchers.excludeFiles)\n ) {\n return undefined\n }\n return matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n }\n\n const environmentNames = new Set<string>([\n VITE_ENVIRONMENT_NAMES.client,\n VITE_ENVIRONMENT_NAMES.server,\n ])\n if (opts.providerEnvName !== VITE_ENVIRONMENT_NAMES.server) {\n environmentNames.add(opts.providerEnvName)\n }\n\n /** Get (or lazily create) the per-env state for the given environment name. */\n function getEnv(envName: string): EnvState {\n let envState = envStates.get(envName)\n if (!envState) {\n const transformResultCache = new Map<string, TransformResult>()\n envState = {\n graph: new ImportGraph(),\n mockExportsByImporter: new Map(),\n resolveCache: new Map(),\n resolveCacheByFile: new Map(),\n importLocCache: new ImportLocCache(),\n seenViolations: new Set(),\n transformResultCache,\n transformResultKeysByFile: new Map(),\n transformResultProvider: {\n getTransformResult(id: string) {\n const fullKey = normalizePath(id)\n const exact = transformResultCache.get(fullKey)\n if (exact) return exact\n const strippedKey = normalizeFilePath(id)\n return strippedKey !== fullKey\n ? transformResultCache.get(strippedKey)\n : undefined\n },\n },\n postTransformImports: new Map(),\n serverFnLookupModules: new Set(),\n pendingViolations: new Map(),\n deferredBuildViolations: [],\n }\n envStates.set(envName, envState)\n }\n return envState\n }\n\n /**\n * Search a parsed export-names map for an entry matching any of the\n * specifier candidates. Returns matching names or empty array.\n */\n function findExportsInMap(\n exportMap: Map<string, Array<string>>,\n candidates: Array<string>,\n ): Array<string> {\n for (const candidate of candidates) {\n const hit = exportMap.get(candidate)\n if (hit && hit.length > 0) return hit\n }\n return []\n }\n\n /**\n * Build deduped resolution candidates for a module ID, including the\n * extensionless absolute path when the ID looks like a file path.\n */\n function buildIdCandidates(id: string, extra?: string): Array<string> {\n const set = new Set(buildResolutionCandidates(id))\n if (extra) {\n for (const c of buildResolutionCandidates(extra)) set.add(c)\n set.add(resolveExtensionlessAbsoluteId(extra))\n }\n return Array.from(set)\n }\n\n /**\n * Resolve which named exports the importer needs from a denied specifier,\n * so mock-edge modules can provide explicit ESM named exports.\n *\n * Tries multiple strategies: cached export maps, AST parsing, and\n * resolver-based comparison.\n */\n async function resolveExportsForDeniedSpecifier(\n env: EnvState,\n ctx: ViolationReporter,\n info: ViolationInfo,\n importerIdHint?: string,\n ): Promise<Array<string>> {\n const importerFile = normalizeFilePath(info.importer)\n const specifierCandidates = buildIdCandidates(info.specifier, info.resolved)\n\n // Only parse AST when a violation occurs (this function is only called\n // while handling a violation). Cache per-importer to avoid repeated parses\n // across multiple violations.\n let parsedBySource = env.mockExportsByImporter.get(importerFile)\n if (!parsedBySource) {\n // Try transform-cache result first, then moduleInfo fallback.\n const importerCode =\n env.transformResultProvider.getTransformResult(importerFile)?.code ??\n (importerIdHint && ctx.getModuleInfo\n ? (ctx.getModuleInfo(importerIdHint)?.code ?? undefined)\n : undefined)\n if (typeof importerCode !== 'string' || importerCode.length === 0)\n return []\n\n try {\n parsedBySource = collectMockExportNamesBySource(importerCode)\n\n // Also index by resolved physical IDs so later lookups match.\n await recordMockExportsForImporter(\n env,\n importerFile,\n parsedBySource,\n async (src) => {\n const cacheKey = `${importerFile}:${src}`\n if (env.resolveCache.has(cacheKey)) {\n return env.resolveCache.get(cacheKey) ?? undefined\n }\n if (!ctx.resolve) return undefined\n const resolved = await ctx.resolve(src, info.importer, {\n skipSelf: true,\n })\n if (!resolved || resolved.external) return undefined\n return resolved.id\n },\n )\n\n // Keep the parsed-by-source map for direct lookups.\n parsedBySource =\n env.mockExportsByImporter.get(importerFile) ?? parsedBySource\n } catch {\n return []\n }\n }\n\n // 1. Direct candidate match\n const direct = findExportsInMap(parsedBySource, specifierCandidates)\n if (direct.length > 0) return direct\n\n // 2. Resolve each source key and compare candidates.\n const candidateSet = new Set(specifierCandidates)\n for (const [sourceKey, names] of parsedBySource) {\n if (!names.length) continue\n\n const resolvedId = await resolveSourceKey(\n env,\n ctx,\n importerFile,\n sourceKey,\n info.importer,\n )\n if (!resolvedId) continue\n\n const resolvedCandidates = buildIdCandidates(resolvedId)\n resolvedCandidates.push(resolveExtensionlessAbsoluteId(resolvedId))\n if (resolvedCandidates.some((v) => candidateSet.has(v))) {\n return names\n }\n }\n\n return []\n }\n\n /** Best-effort resolve a source key using the cache or ctx.resolve. */\n async function resolveSourceKey(\n env: EnvState,\n ctx: ViolationReporter,\n importerFile: string,\n sourceKey: string,\n importerId: string,\n ): Promise<string | undefined> {\n const cacheKey = `${importerFile}:${sourceKey}`\n if (env.resolveCache.has(cacheKey)) {\n return env.resolveCache.get(cacheKey) ?? undefined\n }\n if (!ctx.resolve) return undefined\n try {\n const resolved = await ctx.resolve(sourceKey, importerId, {\n skipSelf: true,\n })\n if (!resolved || resolved.external) return undefined\n return resolved.id\n } catch {\n return undefined\n }\n }\n\n async function recordMockExportsForImporter(\n env: EnvState,\n importerId: string,\n namesBySource: Map<string, Array<string>>,\n resolveSource: (source: string) => Promise<string | undefined>,\n ): Promise<void> {\n const importerFile = normalizeFilePath(importerId)\n\n if (namesBySource.size === 0) return\n\n for (const [source, names] of namesBySource) {\n try {\n const resolvedId = await resolveSource(source)\n if (!resolvedId) continue\n\n namesBySource.set(normalizeFilePath(resolvedId), names)\n namesBySource.set(resolveExtensionlessAbsoluteId(resolvedId), names)\n } catch {\n // Best-effort only\n }\n }\n\n const existing = env.mockExportsByImporter.get(importerFile)\n if (!existing) {\n env.mockExportsByImporter.set(importerFile, namesBySource)\n return\n }\n\n for (const [source, names] of namesBySource) {\n const prev = existing.get(source)\n if (!prev) {\n existing.set(source, names)\n continue\n }\n\n const union = new Set([...prev, ...names])\n existing.set(source, Array.from(union).sort())\n }\n }\n\n const shouldCheckImporterCache = new Map<string, boolean>()\n function shouldCheckImporter(importer: string): boolean {\n let result = shouldCheckImporterCache.get(importer)\n if (result !== undefined) return result\n\n const relativePath = relativizePath(importer, config.root)\n\n // Excluded or ignored importers are never checked.\n const excluded =\n (config.excludeMatchers.length > 0 &&\n matchesAny(relativePath, config.excludeMatchers)) ||\n (config.ignoreImporterMatchers.length > 0 &&\n matchesAny(relativePath, config.ignoreImporterMatchers))\n\n if (excluded) {\n result = false\n } else if (config.includeMatchers.length > 0) {\n result = !!matchesAny(relativePath, config.includeMatchers)\n } else if (config.srcDirectory) {\n result = isInsideDirectory(importer, config.srcDirectory)\n } else {\n result = true\n }\n\n shouldCheckImporterCache.set(importer, result)\n return result\n }\n\n function dedupeKey(info: ViolationInfo): string {\n return `${info.type}:${info.importer}:${info.specifier}:${info.resolved ?? ''}`\n }\n\n function hasSeen(env: EnvState, key: string): boolean {\n if (config.logMode === 'always') return false\n if (env.seenViolations.has(key)) return true\n env.seenViolations.add(key)\n return false\n }\n\n function getRelativePath(absolutePath: string): string {\n return relativizePath(normalizePath(absolutePath), config.root)\n }\n\n /** Reset all caches on an EnvState (called from buildStart). */\n function clearEnvState(envState: EnvState): void {\n envState.resolveCache.clear()\n envState.resolveCacheByFile.clear()\n envState.importLocCache.clear()\n envState.seenViolations.clear()\n envState.transformResultCache.clear()\n envState.transformResultKeysByFile.clear()\n envState.postTransformImports.clear()\n envState.serverFnLookupModules.clear()\n envState.pendingViolations.clear()\n envState.deferredBuildViolations.length = 0\n envState.graph.clear()\n envState.mockExportsByImporter.clear()\n }\n\n /** Invalidate all env-level caches that reference a specific file. */\n function invalidateFileFromEnv(envState: EnvState, file: string): void {\n envState.importLocCache.deleteByFile(file)\n\n // Resolve cache (keyed \"importer:source\")\n const resolveKeys = envState.resolveCacheByFile.get(file)\n if (resolveKeys) {\n for (const key of resolveKeys) envState.resolveCache.delete(key)\n envState.resolveCacheByFile.delete(file)\n }\n\n envState.graph.invalidate(file)\n envState.mockExportsByImporter.delete(file)\n envState.serverFnLookupModules.delete(file)\n envState.pendingViolations.delete(file)\n\n // Transform result cache + post-transform imports\n const transformKeys = envState.transformResultKeysByFile.get(file)\n if (transformKeys) {\n for (const key of transformKeys) {\n envState.transformResultCache.delete(key)\n envState.postTransformImports.delete(key)\n }\n envState.transformResultKeysByFile.delete(file)\n } else {\n envState.transformResultCache.delete(file)\n envState.postTransformImports.delete(file)\n }\n }\n\n /** Store a transform result under both the cacheKey and physical file path. */\n function cacheTransformResult(\n envState: EnvState,\n file: string,\n cacheKey: string,\n result: TransformResult,\n ): void {\n envState.transformResultCache.set(cacheKey, result)\n const keySet = getOrCreate(\n envState.transformResultKeysByFile,\n file,\n () => new Set<string>(),\n )\n keySet.add(cacheKey)\n if (cacheKey !== file) {\n envState.transformResultCache.set(file, result)\n keySet.add(file)\n }\n }\n\n /** Register known Start entrypoints as trace roots for all environments. */\n function registerEntries(): void {\n const { resolvedStartConfig } = opts.getConfig()\n for (const envDef of opts.environments) {\n const envState = getEnv(envDef.name)\n if (resolvedStartConfig.routerFilePath) {\n envState.graph.addEntry(\n normalizePath(resolvedStartConfig.routerFilePath),\n )\n }\n if (resolvedStartConfig.startFilePath) {\n envState.graph.addEntry(\n normalizePath(resolvedStartConfig.startFilePath),\n )\n }\n }\n }\n\n /**\n * Get the merged set of post-transform imports for a file, checking all\n * code-split variants. Returns `null` if no post-transform data exists\n * yet (transform hasn't run).\n *\n * Skips `SERVER_FN_LOOKUP` variants because they contain untransformed\n * code — the Start compiler excludes them.\n */\n function getPostTransformImports(\n env: EnvState,\n file: string,\n ): Set<string> | null {\n const keySet = env.transformResultKeysByFile.get(file)\n let merged: Set<string> | null = null\n\n if (keySet) {\n for (const k of keySet) {\n if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue\n const imports = env.postTransformImports.get(k)\n if (imports) {\n if (!merged) merged = new Set(imports)\n else for (const v of imports) merged.add(v)\n }\n }\n }\n\n // Fallback: direct file-path key\n if (!merged) {\n const imports = env.postTransformImports.get(file)\n if (imports) merged = new Set(imports)\n }\n\n return merged\n }\n\n /**\n * Check whether an import edge from `parent` to `target` survived\n * post-transform compilation.\n *\n * Returns:\n * - `'live'` — target appears in a non-lookup variant's post-transform imports\n * - `'dead'` — post-transform data exists but target is absent (compiler stripped it)\n * - `'pending'` — transform ran but import data not yet posted\n * - `'no-data'` — transform never ran (warm-start cached module)\n */\n function checkEdgeLiveness(\n env: EnvState,\n parent: string,\n target: string,\n ): 'live' | 'dead' | 'pending' | 'no-data' {\n const keySet = env.transformResultKeysByFile.get(parent)\n let anyVariantCached = false\n\n if (keySet) {\n for (const k of keySet) {\n if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue\n const imports = env.postTransformImports.get(k)\n if (imports) {\n anyVariantCached = true\n if (imports.has(target)) return 'live'\n }\n }\n }\n\n if (!anyVariantCached) {\n const imports = env.postTransformImports.get(parent)\n if (imports) return imports.has(target) ? 'live' : 'dead'\n const hasTransformResult =\n env.transformResultCache.has(parent) ||\n (keySet ? keySet.size > 0 : false)\n return hasTransformResult ? 'pending' : 'no-data'\n }\n\n return 'dead'\n }\n\n function checkPostTransformReachability(\n env: EnvState,\n file: string,\n ): 'reachable' | 'unreachable' | 'unknown' {\n const visited = new Set<string>()\n const queue: Array<string> = [file]\n let hasUnknownEdge = false\n let qi = 0\n\n while (qi < queue.length) {\n const current = queue[qi++]!\n if (visited.has(current)) continue\n visited.add(current)\n\n if (env.graph.entries.has(current)) {\n return 'reachable'\n }\n\n const importers = env.graph.reverseEdges.get(current)\n if (!importers) continue\n\n for (const [parent] of importers) {\n if (visited.has(parent)) continue\n const liveness = checkEdgeLiveness(env, parent, current)\n if (liveness === 'live' || liveness === 'no-data') {\n // Live edge or warm-start (no transform data) — follow it\n queue.push(parent)\n } else if (liveness === 'pending') {\n hasUnknownEdge = true\n }\n // 'dead' — edge was stripped by compiler, skip\n }\n }\n\n return hasUnknownEdge ? 'unknown' : 'unreachable'\n }\n\n /**\n * Filter pending violations using edge-survival data. Returns the subset\n * of violations whose resolved import survived the Start compiler (or all\n * violations when no post-transform data is available yet).\n *\n * Returns `undefined` when all violations were stripped or when we must wait\n * for post-transform data before proceeding.\n */\n function filterEdgeSurvival(\n env: EnvState,\n file: string,\n violations: Array<PendingViolation>,\n ):\n | { active: Array<PendingViolation>; edgeSurvivalApplied: boolean }\n | 'all-stripped'\n | 'await-transform' {\n const postTransform = getPostTransformImports(env, file)\n\n if (postTransform) {\n const surviving = violations.filter(\n (pv) => !pv.info.resolved || postTransform.has(pv.info.resolved),\n )\n if (surviving.length === 0) return 'all-stripped'\n env.pendingViolations.set(file, surviving)\n return { active: surviving, edgeSurvivalApplied: true }\n }\n\n // Pre-transform violations need edge-survival verification first.\n if (violations.some((pv) => pv.fromPreTransformResolve)) {\n return 'await-transform'\n }\n\n return { active: violations, edgeSurvivalApplied: false }\n }\n\n /**\n * Process pending violations for the given environment. Called from the\n * transform-cache hook after each module transform is cached, because new\n * transform data may allow us to confirm or discard pending violations.\n *\n * @param warnFn - `this.warn` from the transform hook context\n */\n async function processPendingViolations(\n env: EnvState,\n warnFn: (msg: string) => void,\n ): Promise<void> {\n if (env.pendingViolations.size === 0) return\n\n const toDelete: Array<string> = []\n\n for (const [file, violations] of env.pendingViolations) {\n const filtered = filterEdgeSurvival(env, file, violations)\n\n if (filtered === 'all-stripped') {\n toDelete.push(file)\n continue\n }\n if (filtered === 'await-transform') continue\n\n const { active, edgeSurvivalApplied } = filtered\n\n // Wait for entries before running reachability. registerEntries()\n // populates entries at buildStart; resolveId(!importer) may add more.\n const status =\n env.graph.entries.size > 0\n ? checkPostTransformReachability(env, file)\n : 'unknown'\n\n if (status === 'reachable') {\n for (const pv of active) {\n await emitPendingViolation(env, warnFn, pv)\n }\n toDelete.push(file)\n } else if (status === 'unreachable') {\n toDelete.push(file)\n } else if (config.command === 'serve') {\n // 'unknown' reachability — some graph edges lack transform data.\n // When edge-survival was applied, surviving violations are confirmed\n // real. Without it (warm start), emit conservatively.\n let emittedAny = false\n for (const pv of active) {\n if (pv.fromPreTransformResolve) continue\n\n const shouldEmit =\n edgeSurvivalApplied ||\n (pv.info.type === 'file' &&\n !!pv.info.resolved &&\n isInsideDirectory(pv.info.resolved, config.srcDirectory))\n\n if (shouldEmit) {\n emittedAny =\n (await emitPendingViolation(env, warnFn, pv)) || emittedAny\n }\n }\n\n if (emittedAny) {\n toDelete.push(file)\n }\n }\n // 'unknown' — keep pending for next transform-cache invocation.\n }\n\n for (const file of toDelete) {\n env.pendingViolations.delete(file)\n }\n }\n\n async function emitPendingViolation(\n env: EnvState,\n warnFn: (msg: string) => void,\n pv: PendingViolation,\n ): Promise<boolean> {\n if (!pv.info.importerLoc) {\n const sourceCandidates = buildSourceCandidates(\n pv.info.specifier,\n pv.info.resolved,\n config.root,\n )\n const loc = await resolveImporterLocation(\n env.transformResultProvider,\n env,\n pv.info.importer,\n sourceCandidates,\n )\n\n if (loc) {\n pv.info.importerLoc = loc\n pv.info.snippet = buildCodeSnippet(\n env.transformResultProvider,\n pv.info.importer,\n loc,\n )\n }\n }\n\n if (hasSeen(env, dedupeKey(pv.info))) {\n return false\n }\n\n const freshTrace = await rebuildAndAnnotateTrace(\n env.transformResultProvider,\n env,\n pv.info.env,\n pv.info.importer,\n pv.info.specifier,\n pv.info.importerLoc,\n )\n if (freshTrace.length > pv.info.trace.length) {\n pv.info.trace = freshTrace\n }\n\n if (config.onViolation) {\n const result = await config.onViolation(pv.info)\n if (result === false) return false\n }\n\n warnFn(formatViolation(pv.info, config.root))\n return true\n }\n\n /**\n * Record a violation as pending for later confirmation via graph\n * reachability. Called from `resolveId` when `shouldDefer` is true.\n */\n function deferViolation(\n env: EnvState,\n importerFile: string,\n info: ViolationInfo,\n isPreTransformResolve?: boolean,\n ): void {\n getOrCreate(env.pendingViolations, importerFile, () => []).push({\n info,\n fromPreTransformResolve: isPreTransformResolve,\n })\n }\n\n /** Counter for generating unique per-violation mock module IDs in build mode. */\n let buildViolationCounter = 0\n\n async function handleViolation(\n ctx: ViolationReporter,\n env: EnvState,\n info: ViolationInfo,\n importerIdHint?: string,\n violationOpts?: { silent?: boolean },\n ): Promise<HandleViolationResult> {\n if (!violationOpts?.silent) {\n if (config.onViolation) {\n const result = await config.onViolation(info)\n if (result === false) return undefined\n }\n\n if (config.effectiveBehavior === 'error') {\n // Dev+error: throw immediately.\n // Always throw on error — do NOT deduplicate via hasSeen().\n // Rollup may resolve the same specifier multiple times (e.g.\n // commonjs--resolver's nested this.resolve() fires before\n // getResolveStaticDependencyPromises). If we record the key\n // on the first (nested) throw, the second (real) resolve\n // silently returns undefined and the build succeeds — which\n // is the bug this fixes.\n //\n // Build mode never reaches here — all build violations are\n // deferred via shouldDefer and handled silently.\n return ctx.error(formatViolation(info, config.root))\n }\n\n if (!hasSeen(env, dedupeKey(info))) {\n ctx.warn(formatViolation(info, config.root))\n }\n } else if (\n config.effectiveBehavior === 'error' &&\n config.command !== 'build'\n ) {\n return undefined\n }\n\n // File violations: return resolved path — the self-denial transform\n // will replace the file's content with a mock module. This avoids\n // virtual module IDs that could leak across environments via\n // third-party resolver caches.\n if (info.type === 'file') return info.resolved\n\n // Non-file violations (specifier/marker): create mock-edge module.\n // Dev mode uses a runtime diagnostics ID; build mode uses a unique\n // per-violation ID so generateBundle can check tree-shaking survival.\n const exports = await resolveExportsForDeniedSpecifier(\n env,\n ctx,\n info,\n importerIdHint,\n )\n const baseMockId =\n config.command === 'serve'\n ? mockRuntimeModuleIdFromViolation(info, config.mockAccess, config.root)\n : `${MOCK_BUILD_PREFIX}${buildViolationCounter++}`\n return resolveViteId(makeMockEdgeModuleId(exports, baseMockId))\n }\n\n /**\n * Unified violation dispatch: either defers or reports immediately.\n *\n * When `shouldDefer` is true (dev mock + build modes), calls\n * `handleViolation` silently to obtain the mock module ID, then stores\n * the violation for later verification:\n * - Dev mock mode: all violations are deferred to `pendingViolations`\n * for edge-survival and graph-reachability checking via\n * `processPendingViolations`.\n * - Build mode (mock + error): defers to `deferredBuildViolations` for\n * tree-shaking verification in `generateBundle`.\n *\n * Otherwise reports immediately (dev error mode). Pre-transform\n * resolves are silenced in error mode because they fire before the\n * compiler runs and there is no deferred verification path.\n *\n * Returns the mock module ID / resolve result from `handleViolation`.\n */\n async function reportOrDeferViolation(\n ctx: ViolationReporter,\n env: EnvState,\n importerFile: string,\n importerIdHint: string | undefined,\n info: ViolationInfo,\n shouldDefer: boolean,\n isPreTransformResolve: boolean,\n ): Promise<HandleViolationResult> {\n if (shouldDefer) {\n const result = await handleViolation(ctx, env, info, importerIdHint, {\n silent: true,\n })\n\n if (config.command === 'build') {\n // Build mode: store for generateBundle tree-shaking check.\n // The mock-edge module ID is returned as a plain string.\n const mockId = result ?? ''\n env.deferredBuildViolations.push({\n info,\n mockModuleId: mockId,\n // For marker violations, check importer survival instead of mock.\n checkModuleId: info.type === 'marker' ? info.importer : undefined,\n })\n } else {\n // Dev mock: store for graph-reachability check.\n deferViolation(env, importerFile, info, isPreTransformResolve)\n await processPendingViolations(env, ctx.warn.bind(ctx))\n }\n\n return result\n }\n\n // Non-deferred path: dev error mode only.\n // Pre-transform resolves are silenced because they fire before the\n // compiler runs — imports inside `.server()` callbacks haven't been\n // stripped yet and error mode has no deferred verification.\n return handleViolation(ctx, env, info, importerIdHint, {\n silent: isPreTransformResolve,\n })\n }\n\n return [\n {\n name: 'tanstack-start-core:import-protection',\n enforce: 'pre',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n // Start's environments are named `client` and `ssr` (not `server`), plus\n // an optional serverFn provider environment (eg `rsc`) when configured.\n return environmentNames.has(env.name)\n },\n\n configResolved(viteConfig) {\n config.root = viteConfig.root\n config.command = viteConfig.command\n\n const { startConfig, resolvedStartConfig } = opts.getConfig()\n config.srcDirectory = resolvedStartConfig.srcDirectory\n\n const userOpts: ImportProtectionOptions | undefined =\n startConfig.importProtection\n\n if (userOpts?.enabled === false) {\n config.enabled = false\n return\n }\n\n config.enabled = true\n\n const behavior = userOpts?.behavior\n if (typeof behavior === 'string') {\n config.effectiveBehavior = behavior\n } else {\n config.effectiveBehavior =\n viteConfig.command === 'serve'\n ? (behavior?.dev ?? 'mock')\n : (behavior?.build ?? 'error')\n }\n\n config.logMode = userOpts?.log ?? 'once'\n config.mockAccess = userOpts?.mockAccess ?? 'error'\n config.maxTraceDepth = userOpts?.maxTraceDepth ?? 20\n if (userOpts?.onViolation) {\n const fn = userOpts.onViolation\n config.onViolation = (info) => fn(info)\n }\n\n const defaults = getDefaultImportProtectionRules()\n // Use user-provided patterns when available, otherwise defaults.\n const pick = <T>(user: Array<T> | undefined, fallback: Array<T>) =>\n user ? [...user] : [...fallback]\n\n // Client specifier denies always include framework defaults even\n // when the user provides a custom list.\n const clientSpecifiers = dedupePatterns([\n ...defaults.client.specifiers,\n ...(userOpts?.client?.specifiers ?? []),\n ])\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(\n pick(userOpts?.client?.files, defaults.client.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.client?.excludeFiles, defaults.client.excludeFiles),\n ),\n }\n config.compiledRules.server = {\n specifiers: compileMatchers(\n dedupePatterns(\n pick(userOpts?.server?.specifiers, defaults.server.specifiers),\n ),\n ),\n files: compileMatchers(\n pick(userOpts?.server?.files, defaults.server.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.server?.excludeFiles, defaults.server.excludeFiles),\n ),\n }\n\n config.includeMatchers = compileMatchers(userOpts?.include ?? [])\n config.excludeMatchers = compileMatchers(userOpts?.exclude ?? [])\n config.ignoreImporterMatchers = compileMatchers(\n userOpts?.ignoreImporters ?? [],\n )\n\n // Marker specifiers\n const markers = getMarkerSpecifiers()\n config.markerSpecifiers = {\n serverOnly: new Set(markers.serverOnly),\n clientOnly: new Set(markers.clientOnly),\n }\n },\n\n configureServer(server) {\n devServer = server\n },\n\n buildStart() {\n if (!config.enabled) return\n // Clear memoization caches that grow unboundedly across builds\n clearNormalizeFilePathCache()\n extensionlessIdResolver.clear()\n importPatternCache.clear()\n shouldCheckImporterCache.clear()\n\n // Clear per-env caches\n for (const envState of envStates.values()) {\n clearEnvState(envState)\n }\n\n // Clear shared state\n shared.fileMarkerKind.clear()\n\n registerEntries()\n },\n\n hotUpdate(ctx) {\n if (!config.enabled) return\n // Invalidate caches for updated files\n for (const mod of ctx.modules) {\n if (mod.id) {\n const id = mod.id\n const importerFile = normalizeFilePath(id)\n\n // Invalidate extensionless-resolution cache entries affected by this file.\n extensionlessIdResolver.invalidateByFile(importerFile)\n shared.fileMarkerKind.delete(importerFile)\n\n // Invalidate per-env caches\n for (const envState of envStates.values()) {\n invalidateFileFromEnv(envState, importerFile)\n }\n }\n }\n },\n\n async resolveId(source, importer, _options) {\n const envName = this.environment.name\n const env = getEnv(envName)\n const envType = getEnvType(envName)\n const provider = env.transformResultProvider\n const isScanResolve = !!(_options as Record<string, unknown>).scan\n\n if (IMPORT_PROTECTION_DEBUG) {\n const importerPath = importer\n ? normalizeFilePath(importer)\n : '(entry)'\n const isEntryResolve = !importer\n const filtered =\n process.env.TSR_IMPORT_PROTECTION_DEBUG_FILTER === 'entry'\n ? isEntryResolve\n : matchesDebugFilter(source, importerPath)\n if (filtered) {\n debugLog('resolveId', {\n env: envName,\n envType,\n source,\n importer: importerPath,\n isEntryResolve,\n command: config.command,\n })\n }\n }\n\n // Internal virtual modules (mock:build:N, mock-edge, mock-runtime, marker)\n const internalVirtualId = resolveInternalVirtualModuleId(source)\n if (internalVirtualId) return internalVirtualId\n\n if (!importer) {\n env.graph.addEntry(source)\n // Flush pending violations now that an additional entry is known\n // and reachability analysis may have new roots.\n await processPendingViolations(env, this.warn.bind(this))\n return undefined\n }\n\n if (source.startsWith('\\0') || source.startsWith('virtual:')) {\n return undefined\n }\n\n const normalizedImporter = normalizeFilePath(importer)\n const isDirectLookup = importer.includes(SERVER_FN_LOOKUP_QUERY)\n\n if (isDirectLookup) {\n env.serverFnLookupModules.add(normalizedImporter)\n }\n\n const isPreTransformResolve =\n isDirectLookup ||\n env.serverFnLookupModules.has(normalizedImporter) ||\n isScanResolve\n\n // Dev mock mode: defer all violations (including pre-transform\n // resolves) until post-transform data is available, then\n // confirm/discard via graph reachability.\n // Build mode (both mock and error): defer violations until\n // generateBundle so tree-shaking can eliminate false positives.\n const isDevMock =\n config.command === 'serve' && config.effectiveBehavior === 'mock'\n const isBuild = config.command === 'build'\n const shouldDefer = shouldDeferViolation({ isBuild, isDevMock })\n\n const resolveAgainstImporter = async (): Promise<string | null> => {\n const primary = await this.resolve(source, importer, {\n skipSelf: true,\n })\n if (primary) {\n return canonicalizeResolvedId(\n primary.id,\n config.root,\n resolveExtensionlessAbsoluteId,\n )\n }\n\n return null\n }\n\n // Check if this is a marker import\n const markerKind = config.markerSpecifiers.serverOnly.has(source)\n ? ('server' as const)\n : config.markerSpecifiers.clientOnly.has(source)\n ? ('client' as const)\n : undefined\n\n if (markerKind) {\n const existing = shared.fileMarkerKind.get(normalizedImporter)\n if (existing && existing !== markerKind) {\n this.error(\n `[import-protection] File \"${getRelativePath(normalizedImporter)}\" has both server-only and client-only markers. This is not allowed.`,\n )\n }\n shared.fileMarkerKind.set(normalizedImporter, markerKind)\n\n const violatesEnv =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n\n if (violatesEnv) {\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'marker',\n message: buildMarkerViolationMessage(\n getRelativePath(normalizedImporter),\n markerKind,\n ),\n },\n )\n const markerResult = await reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n\n // In build mode, if the violation was deferred, return the unique\n // build mock ID instead of the marker module. This lets\n // generateBundle check whether the importer (and thus its marker\n // import) survived tree-shaking. The mock is side-effect-free just\n // like the marker module, and the bare import has no bindings, so\n // replacing it is transparent.\n if (isBuild && markerResult != null) {\n return markerResult\n }\n }\n\n // Retroactive marker violation detection: on cold starts, module\n // A may import module B before B's marker is set (because B hasn't\n // been processed yet). When B's marker is set (here),\n // retroactively check all known importers of B in the graph and\n // create deferred marker violations for them. Without this,\n // cold-start ordering can miss marker violations that warm starts\n // detect (warm starts see markers early from cached transforms).\n //\n // Uses lightweight `deferViolation` to avoid heavy side effects\n // (mock module creation, export resolution). Immediately calls\n // `processPendingViolations` to flush the deferred violations,\n // because the marker resolveId fires during Vite's import\n // analysis (after our transform hook) — there may be no\n // subsequent transform invocation to flush them.\n //\n // Guarded by `violatesEnv` (per-environment) plus a per-env\n // seen-set. The marker is shared across environments but each\n // env's graph has its own edges; this ensures the check runs\n // at most once per (env, module) pair.\n const envRetroKey = `retro-marker:${normalizedImporter}`\n if (violatesEnv && !env.seenViolations.has(envRetroKey)) {\n env.seenViolations.add(envRetroKey)\n let retroDeferred = false\n const importersMap = env.graph.reverseEdges.get(normalizedImporter)\n if (importersMap && importersMap.size > 0) {\n for (const [importerFile, specifier] of importersMap) {\n if (!specifier) continue\n if (!shouldCheckImporter(importerFile)) continue\n const markerInfo = await buildMarkerViolationFromResolvedImport(\n provider,\n env,\n envName,\n envType,\n importerFile,\n specifier,\n normalizedImporter,\n getRelativePath(normalizedImporter),\n )\n if (markerInfo) {\n deferViolation(\n env,\n importerFile,\n markerInfo,\n isPreTransformResolve,\n )\n retroDeferred = true\n }\n }\n }\n if (retroDeferred) {\n await processPendingViolations(env, this.warn.bind(this))\n }\n }\n\n return markerKind === 'server'\n ? resolvedMarkerVirtualModuleId('server')\n : resolvedMarkerVirtualModuleId('client')\n }\n\n // Check if the importer is within our scope\n if (!shouldCheckImporter(normalizedImporter)) {\n return undefined\n }\n\n const matchers = getRulesForEnvironment(envName)\n\n // 1. Specifier-based denial\n const specifierMatch = matchesAny(source, matchers.specifiers)\n if (specifierMatch) {\n if (!isPreTransformResolve) {\n env.graph.addEdge(source, normalizedImporter, source)\n }\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'specifier',\n pattern: specifierMatch.pattern,\n message: `Import \"${source}\" is denied in the ${envType} environment`,\n },\n )\n\n // Resolve the specifier so edge-survival can verify whether\n // the import survives the Start compiler transform (e.g.\n // factory-safe pattern strips imports inside .server() callbacks).\n if (shouldDefer && !info.resolved) {\n try {\n const resolvedForInfo = await resolveAgainstImporter()\n if (resolvedForInfo) info.resolved = resolvedForInfo\n } catch {\n // Non-fatal: edge-survival will skip unresolved specifiers\n }\n }\n\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n\n // 2. Resolve the import (cached)\n const cacheKey = `${normalizedImporter}:${source}`\n let resolved: string | null\n\n if (env.resolveCache.has(cacheKey)) {\n resolved = env.resolveCache.get(cacheKey) ?? null\n } else {\n resolved = await resolveAgainstImporter()\n\n // Only cache successful resolves. Null resolves can be\n // order-dependent across importer variants (e.g. code-split\n // `?tsr-split=...` ids) and may poison later lookups.\n if (resolved !== null) {\n env.resolveCache.set(cacheKey, resolved)\n getOrCreate(\n env.resolveCacheByFile,\n normalizedImporter,\n () => new Set(),\n ).add(cacheKey)\n }\n }\n\n if (resolved) {\n const relativePath = getRelativePath(resolved)\n\n // Propagate pre-transform status transitively\n if (isPreTransformResolve && !isScanResolve) {\n env.serverFnLookupModules.add(resolved)\n }\n\n if (!isPreTransformResolve) {\n env.graph.addEdge(resolved, normalizedImporter, source)\n }\n\n // Skip file-based and marker-based denial for resolved paths that\n // match the per-environment `excludeFiles` patterns. By default\n // this includes `**/node_modules/**` so that third-party packages\n // using `.client.` / `.server.` in their filenames (e.g. react-tweet\n // exports `index.client.js`) are not treated as user-authored\n // environment boundaries. Users can override `excludeFiles` per\n // environment to narrow or widen this exclusion.\n const isExcludedFile =\n matchers.excludeFiles.length > 0 &&\n matchesAny(relativePath, matchers.excludeFiles)\n\n if (!isExcludedFile) {\n const fileMatch =\n matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n\n if (fileMatch) {\n const info = await buildFileViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n resolved,\n fileMatch.pattern,\n )\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n\n const markerInfo = await buildMarkerViolationFromResolvedImport(\n provider,\n env,\n envName,\n envType,\n importer,\n source,\n resolved,\n relativePath,\n )\n if (markerInfo) {\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n markerInfo,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n }\n }\n\n return undefined\n },\n\n load: {\n filter: {\n id: new RegExp(\n getResolvedVirtualModuleMatchers().map(escapeRegExp).join('|'),\n ),\n },\n handler(id) {\n if (IMPORT_PROTECTION_DEBUG) {\n if (matchesDebugFilter(id)) {\n debugLog('load:handler', {\n env: this.environment.name,\n id: normalizePath(id),\n })\n }\n }\n\n return loadResolvedVirtualModule(id)\n },\n },\n\n async generateBundle(_options, bundle) {\n const envName = this.environment.name\n const env = envStates.get(envName)\n if (!env || env.deferredBuildViolations.length === 0) return\n\n const candidateCache = new Map<string, Array<string>>()\n const toModuleIdCandidates = (id: string): Array<string> => {\n let cached = candidateCache.get(id)\n if (cached) return cached\n\n const out = new Set<string>()\n const normalized = normalizeFilePath(id)\n out.add(id)\n out.add(normalized)\n out.add(relativizePath(normalized, config.root))\n\n if (normalized.startsWith(VITE_BROWSER_VIRTUAL_PREFIX)) {\n const internal = `\\0${normalized.slice(VITE_BROWSER_VIRTUAL_PREFIX.length)}`\n out.add(internal)\n out.add(relativizePath(normalizeFilePath(internal), config.root))\n }\n\n if (normalized.startsWith('\\0')) {\n const browser = `${VITE_BROWSER_VIRTUAL_PREFIX}${normalized.slice(1)}`\n out.add(browser)\n out.add(relativizePath(normalizeFilePath(browser), config.root))\n }\n\n cached = Array.from(out)\n candidateCache.set(id, cached)\n return cached\n }\n\n // Collect all module IDs that survived tree-shaking in this bundle.\n const survivingModules = new Set<string>()\n for (const chunk of Object.values(bundle)) {\n if (chunk.type === 'chunk') {\n for (const moduleId of Object.keys(chunk.modules)) {\n for (const candidate of toModuleIdCandidates(moduleId)) {\n survivingModules.add(candidate)\n }\n }\n }\n }\n\n const didModuleSurvive = (moduleId: string): boolean =>\n toModuleIdCandidates(moduleId).some((candidate) =>\n survivingModules.has(candidate),\n )\n\n // Check each deferred violation: if its check module survived\n // in the bundle, the import was NOT tree-shaken — real leak.\n const realViolations: Array<ViolationInfo> = []\n for (const {\n info,\n mockModuleId,\n checkModuleId,\n } of env.deferredBuildViolations) {\n let survived: boolean\n if (checkModuleId != null) {\n // Marker violation: check if the importer survived\n // (marker is about the file's directive, not a binding).\n // Include transform-result keys (e.g. code-split variants)\n // to cover all bundle representations of the importer.\n const importerVariantIds = new Set<string>([info.importer])\n const importerKeys = env.transformResultKeysByFile.get(\n normalizeFilePath(info.importer),\n )\n if (importerKeys) {\n for (const key of importerKeys) {\n importerVariantIds.add(key)\n }\n }\n survived = false\n for (const importerId of importerVariantIds) {\n if (didModuleSurvive(importerId)) {\n survived = true\n break\n }\n }\n } else {\n // File/specifier violation: check if the mock module survived.\n survived = didModuleSurvive(mockModuleId)\n }\n\n if (!survived) continue\n\n if (config.onViolation) {\n const result = await config.onViolation(info)\n if (result === false) continue\n }\n\n realViolations.push(info)\n }\n\n if (realViolations.length === 0) return\n\n if (config.effectiveBehavior === 'error') {\n // Error mode: fail the build on the first real violation.\n this.error(formatViolation(realViolations[0]!, config.root))\n } else {\n // Mock mode: warn for each surviving violation.\n const seen = new Set<string>()\n for (const info of realViolations) {\n const key = dedupeKey(info)\n if (!seen.has(key)) {\n seen.add(key)\n this.warn(formatViolation(info, config.root))\n }\n }\n }\n },\n },\n {\n // Captures transformed code + composed sourcemap for location mapping.\n // Runs after all `enforce: 'pre'` hooks (including the Start compiler).\n // Only files under `srcDirectory` are cached.\n name: 'tanstack-start-core:import-protection-transform-cache',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n return environmentNames.has(env.name)\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[cm]?[tj]sx?($|\\?)/],\n },\n },\n async handler(code, id) {\n const envName = this.environment.name\n const file = normalizeFilePath(id)\n const envType = getEnvType(envName)\n const matchers = getRulesForEnvironment(envName)\n const isBuild = config.command === 'build'\n\n if (IMPORT_PROTECTION_DEBUG) {\n if (matchesDebugFilter(file)) {\n debugLog('transform-cache', {\n env: envName,\n id: normalizePath(id),\n file,\n })\n }\n }\n\n if (!shouldCheckImporter(file)) {\n return undefined\n }\n\n // Self-denial: if this file is denied in the current environment\n // (e.g. a `.server` file transformed in the client environment),\n // replace its entire content with a mock module.\n //\n // This is the core mechanism for preventing cross-environment\n // cache contamination: resolveId never returns virtual module\n // IDs for file-based violations, so there is nothing for\n // third-party resolver caches (e.g. vite-tsconfig-paths) to\n // leak across environments. Each environment's transform\n // independently decides whether the file is denied.\n //\n // In dev mode, this also solves the cold-start problem where\n // the importer's AST is unavailable for export resolution:\n // the denied file's own source code is always available here,\n // so we parse its exports directly.\n const selfFileMatch = checkFileDenial(getRelativePath(file), matchers)\n if (selfFileMatch) {\n // Parse exports once — shared by build and dev paths.\n // Falls back to empty list on non-standard syntax.\n let exportNames: Array<string> = []\n try {\n exportNames = collectNamedExports(code)\n } catch {\n // Parsing may fail on non-standard syntax\n }\n\n if (isBuild) {\n return generateSelfContainedMockModule(exportNames)\n }\n\n // Dev mode: generate a mock that imports mock-runtime for\n // runtime diagnostics (error/warn on property access).\n const runtimeId = mockRuntimeModuleIdFromViolation(\n {\n type: 'file',\n env: envType,\n envType,\n behavior:\n config.effectiveBehavior === 'error' ? 'error' : 'mock',\n importer: file,\n specifier: relativizePath(file, config.root),\n resolved: file,\n pattern: selfFileMatch.pattern,\n message: `File \"${relativizePath(file, config.root)}\" is denied in the ${envType} environment`,\n trace: [],\n },\n config.mockAccess,\n config.root,\n )\n return generateDevSelfDenialModule(exportNames, runtimeId)\n }\n\n // getCombinedSourcemap() returns the composed sourcemap\n let map: SourceMapLike | undefined\n try {\n map = this.getCombinedSourcemap()\n } catch {\n map = undefined\n }\n\n let originalCode: string | undefined\n if (map?.sourcesContent) {\n originalCode = pickOriginalCodeFromSourcesContent(\n map,\n file,\n config.root,\n )\n }\n\n const lineIndex = buildLineIndex(code)\n const cacheKey = normalizePath(id)\n\n const envState = getEnv(envName)\n const isServerFnLookup = id.includes(SERVER_FN_LOOKUP_QUERY)\n\n // Propagate SERVER_FN_LOOKUP status before import-analysis\n if (isServerFnLookup) {\n envState.serverFnLookupModules.add(file)\n }\n\n const result: TransformResult = {\n code,\n map,\n originalCode,\n lineIndex,\n }\n cacheTransformResult(envState, file, cacheKey, result)\n\n // Build mode: only self-denial (above) and transform caching are\n // needed. All violations are detected and deferred in resolveId;\n // self-denial replaces denied file content; generateBundle checks\n // tree-shaking survival. The import resolution loop below is\n // dev-mode only — it resolves imports for graph reachability,\n // catches violations missed on warm starts (where Vite caches\n // resolveId), and rewrites denied imports to mock modules.\n if (isBuild) return undefined\n\n // Dev mode: resolve imports, populate graph, detect violations,\n // and rewrite denied imports.\n const isDevMock = config.effectiveBehavior === 'mock'\n const importSources = extractImportSources(code)\n const resolvedChildren = new Set<string>()\n const deniedSourceReplacements = new Map<string, string>()\n for (const src of importSources) {\n try {\n const resolved = await this.resolve(src, id, { skipSelf: true })\n if (resolved && !resolved.external) {\n const resolvedPath = canonicalizeResolvedId(\n resolved.id,\n config.root,\n resolveExtensionlessAbsoluteId,\n )\n\n resolvedChildren.add(resolvedPath)\n\n // When the resolved ID is a mock-module (from our\n // resolveId returning a mock-edge ID), postTransformImports\n // would only contain the mock ID. Edge-survival needs the\n // real physical path so pending violations can be matched.\n //\n // For relative specifiers we can compute the physical path\n // directly. For bare/alias specifiers, look up the real\n // resolved path from the pending violations that were\n // already stored by resolveId before this transform ran.\n if (resolved.id.includes('tanstack-start-import-protection:')) {\n let physicalPath: string | undefined\n // Look up real resolved path from pending violations\n const pending = envState.pendingViolations.get(file)\n if (pending) {\n const match = pending.find(\n (pv) => pv.info.specifier === src && pv.info.resolved,\n )\n if (match) physicalPath = match.info.resolved\n }\n if (physicalPath && physicalPath !== resolvedPath) {\n resolvedChildren.add(physicalPath)\n envState.graph.addEdge(physicalPath, file, src)\n }\n }\n\n // Populate import graph edges for warm-start trace accuracy\n envState.graph.addEdge(resolvedPath, file, src)\n\n if (isDevMock) {\n const relativePath = getRelativePath(resolvedPath)\n const fileMatch = checkFileDenial(relativePath, matchers)\n\n if (fileMatch) {\n const info = await buildFileViolationInfo(\n envState.transformResultProvider,\n envState,\n envName,\n envType,\n id,\n file,\n src,\n resolvedPath,\n fileMatch.pattern,\n )\n\n const replacement = await reportOrDeferViolation(\n this,\n envState,\n file,\n id,\n info,\n isDevMock,\n isServerFnLookup,\n )\n\n if (replacement) {\n deniedSourceReplacements.set(\n src,\n replacement.startsWith('\\0')\n ? VITE_BROWSER_VIRTUAL_PREFIX + replacement.slice(1)\n : replacement,\n )\n }\n }\n }\n }\n } catch {\n // Non-fatal\n }\n }\n envState.postTransformImports.set(cacheKey, resolvedChildren)\n if (cacheKey !== file && !isServerFnLookup) {\n envState.postTransformImports.set(file, resolvedChildren)\n }\n\n await processPendingViolations(envState, this.warn.bind(this))\n\n if (deniedSourceReplacements.size > 0) {\n try {\n const rewritten = rewriteDeniedImports(\n code,\n id,\n new Set(deniedSourceReplacements.keys()),\n (source: string) =>\n deniedSourceReplacements.get(source) ?? source,\n )\n\n if (!rewritten) {\n return undefined\n }\n\n const normalizedMap = rewritten.map\n ? {\n ...rewritten.map,\n version: Number(rewritten.map.version),\n sourcesContent:\n rewritten.map.sourcesContent?.map(\n (s: string | null) => s ?? '',\n ) ?? [],\n }\n : {\n version: 3,\n file: id,\n names: [],\n sources: [id],\n sourcesContent: [code],\n mappings: '',\n }\n\n return {\n code: rewritten.code,\n map: normalizedMap,\n }\n } catch {\n // Non-fatal: keep original code when rewrite fails.\n }\n }\n\n return undefined\n },\n },\n },\n ] satisfies Array<PluginOption>\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["../../../src/import-protection-plugin/plugin.ts"],"sourcesContent":["import { normalizePath } from 'vite'\n\nimport { resolveViteId } from '../utils'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { ImportGraph, buildTrace, formatViolation } from './trace'\nimport {\n getDefaultImportProtectionRules,\n getMarkerSpecifiers,\n} from './defaults'\nimport { compileMatchers, matchesAny } from './matchers'\nimport {\n buildResolutionCandidates,\n buildSourceCandidates,\n canonicalizeResolvedId,\n clearNormalizeFilePathCache,\n debugLog,\n dedupePatterns,\n escapeRegExp,\n extractImportSources,\n getOrCreate,\n isInsideDirectory,\n matchesDebugFilter,\n normalizeFilePath,\n relativizePath,\n shouldDeferViolation,\n} from './utils'\nimport {\n collectMockExportNamesBySource,\n collectNamedExports,\n rewriteDeniedImports,\n} from './rewriteDeniedImports'\nimport {\n MOCK_BUILD_PREFIX,\n generateDevSelfDenialModule,\n generateSelfContainedMockModule,\n getResolvedVirtualModuleMatchers,\n loadResolvedVirtualModule,\n makeMockEdgeModuleId,\n mockRuntimeModuleIdFromViolation,\n resolveInternalVirtualModuleId,\n resolvedMarkerVirtualModuleId,\n} from './virtualModules'\nimport { ExtensionlessAbsoluteIdResolver } from './extensionlessAbsoluteIdResolver'\nimport {\n IMPORT_PROTECTION_DEBUG,\n SERVER_FN_LOOKUP_QUERY,\n VITE_BROWSER_VIRTUAL_PREFIX,\n} from './constants'\nimport {\n ImportLocCache,\n addTraceImportLocations,\n buildCodeSnippet,\n buildLineIndex,\n findImportStatementLocationFromTransformed,\n findPostCompileUsageLocation,\n pickOriginalCodeFromSourcesContent,\n} from './sourceLocation'\nimport type { PluginOption, ViteDevServer } from 'vite'\nimport type { CompiledMatcher } from './matchers'\nimport type { Loc, TraceStep, ViolationInfo } from './trace'\nimport type {\n SourceMapLike,\n TransformResult,\n TransformResultProvider,\n} from './sourceLocation'\nimport type { ImportProtectionOptions } from '../schema'\nimport type {\n EnvRules,\n EnvState,\n HandleViolationResult,\n ImportProtectionPluginOptions,\n ModuleGraphNode,\n PendingViolation,\n PluginConfig,\n SharedState,\n ViolationReporter,\n} from './types'\n\nexport type { ImportProtectionPluginOptions } from './types'\n\nexport function importProtectionPlugin(\n opts: ImportProtectionPluginOptions,\n): PluginOption {\n let devServer: ViteDevServer | null = null\n const extensionlessIdResolver = new ExtensionlessAbsoluteIdResolver()\n const resolveExtensionlessAbsoluteId = (id: string) =>\n extensionlessIdResolver.resolve(id)\n\n const importPatternCache = new Map<string, Array<RegExp>>()\n\n function findFirstImportSpecifierIndex(code: string, source: string): number {\n let patterns = importPatternCache.get(source)\n if (!patterns) {\n const escaped = escapeRegExp(source)\n patterns = [\n new RegExp(`\\\\bimport\\\\s+(['\"])${escaped}\\\\1`),\n new RegExp(`\\\\bfrom\\\\s+(['\"])${escaped}\\\\1`),\n new RegExp(`\\\\bimport\\\\s*\\\\(\\\\s*(['\"])${escaped}\\\\1\\\\s*\\\\)`),\n ]\n importPatternCache.set(source, patterns)\n }\n\n let best = -1\n for (const re of patterns) {\n const m = re.exec(code)\n if (!m) continue\n const idx = m.index + m[0].indexOf(source)\n if (idx === -1) continue\n if (best === -1 || idx < best) best = idx\n }\n return best\n }\n\n /**\n * Build an import trace using Vite's per-environment module graph, which\n * is authoritative even on warm starts when the plugin's own ImportGraph\n * may be incomplete (Vite skips resolveId for cached modules).\n */\n function buildTraceFromModuleGraph(\n envName: string,\n env: EnvState,\n targetFile: string,\n ): Array<TraceStep> | null {\n if (!devServer) return null\n const environment = devServer.environments[envName]\n if (!environment) return null\n\n const file = normalizeFilePath(targetFile)\n const start = environment.moduleGraph.getModuleById(file)\n if (!start) return null\n\n // Resolve a module graph node to its normalized file path once and\n // cache the result so BFS + reconstruction don't recompute.\n const nodeIds = new Map<ModuleGraphNode, string>()\n function nodeId(n: ModuleGraphNode): string {\n let cached = nodeIds.get(n)\n if (cached === undefined) {\n cached = n.id\n ? normalizeFilePath(n.id)\n : n.url\n ? normalizeFilePath(n.url)\n : ''\n nodeIds.set(n, cached)\n }\n return cached\n }\n\n const queue: Array<ModuleGraphNode> = [start]\n const visited = new Set<ModuleGraphNode>([start])\n const parent = new Map<ModuleGraphNode, ModuleGraphNode>()\n\n let entryRoot: ModuleGraphNode | null = null\n let fallbackRoot: ModuleGraphNode | null = null\n let qi = 0\n while (qi < queue.length) {\n const node = queue[qi++]!\n const id = nodeId(node)\n\n if (id && env.graph.entries.has(id)) {\n entryRoot = node\n break\n }\n\n const importers = node.importers\n if (importers.size === 0) {\n if (!fallbackRoot) fallbackRoot = node\n continue\n }\n\n for (const imp of importers) {\n if (visited.has(imp)) continue\n visited.add(imp)\n parent.set(imp, node)\n queue.push(imp)\n }\n }\n\n const root = entryRoot ?? fallbackRoot\n\n if (!root) return null\n\n // Reconstruct: root -> ... -> start\n const chain: Array<ModuleGraphNode> = []\n let cur: ModuleGraphNode | undefined = root\n for (let i = 0; i < config.maxTraceDepth + 2 && cur; i++) {\n chain.push(cur)\n if (cur === start) break\n cur = parent.get(cur)\n }\n\n const steps: Array<TraceStep> = []\n for (let i = 0; i < chain.length; i++) {\n const id = nodeId(chain[i]!)\n if (!id) continue\n let specifier: string | undefined\n if (i + 1 < chain.length) {\n const nextId = nodeId(chain[i + 1]!)\n if (nextId) {\n specifier = env.graph.reverseEdges.get(nextId)?.get(id)\n }\n }\n steps.push(specifier ? { file: id, specifier } : { file: id })\n }\n\n return steps.length ? steps : null\n }\n\n const config: PluginConfig = {\n enabled: true,\n root: '',\n command: 'build',\n srcDirectory: '',\n framework: opts.framework,\n effectiveBehavior: 'error',\n mockAccess: 'error',\n logMode: 'once',\n maxTraceDepth: 20,\n compiledRules: {\n client: { specifiers: [], files: [], excludeFiles: [] },\n server: { specifiers: [], files: [], excludeFiles: [] },\n },\n includeMatchers: [],\n excludeMatchers: [],\n ignoreImporterMatchers: [],\n markerSpecifiers: { serverOnly: new Set(), clientOnly: new Set() },\n envTypeMap: new Map(opts.environments.map((e) => [e.name, e.type])),\n onViolation: undefined,\n }\n\n const envStates = new Map<string, EnvState>()\n const shared: SharedState = { fileMarkerKind: new Map() }\n\n /**\n * Build the best available trace for a module and enrich each step with\n * line/column locations. Tries the plugin's own ImportGraph first, then\n * Vite's moduleGraph (authoritative on warm start), keeping whichever is\n * longer. Annotates the last step with the denied specifier + location.\n *\n * Shared by {@link buildViolationInfo} and {@link processPendingViolations}.\n */\n async function rebuildAndAnnotateTrace(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n normalizedImporter: string,\n specifier: string,\n importerLoc: Loc | undefined,\n traceOverride?: Array<TraceStep>,\n ): Promise<Array<TraceStep>> {\n let trace =\n traceOverride ??\n buildTrace(env.graph, normalizedImporter, config.maxTraceDepth)\n\n if (config.command === 'serve') {\n const mgTrace = buildTraceFromModuleGraph(\n envName,\n env,\n normalizedImporter,\n )\n if (mgTrace && mgTrace.length > trace.length) {\n trace = mgTrace\n }\n }\n await addTraceImportLocations(\n provider,\n trace,\n env.importLocCache,\n findFirstImportSpecifierIndex,\n )\n\n if (trace.length > 0) {\n const last = trace[trace.length - 1]!\n if (!last.specifier) last.specifier = specifier\n if (importerLoc && last.line == null) {\n last.line = importerLoc.line\n last.column = importerLoc.column\n }\n }\n\n return trace\n }\n\n /**\n * Build a complete {@link ViolationInfo} with trace, location, and snippet.\n *\n * This is the single path that all violation types go through: specifier,\n * file, and marker.\n */\n async function buildViolationInfo(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n envType: 'client' | 'server',\n importer: string,\n normalizedImporter: string,\n source: string,\n overrides: Omit<\n ViolationInfo,\n | 'env'\n | 'envType'\n | 'behavior'\n | 'specifier'\n | 'importer'\n | 'trace'\n | 'snippet'\n | 'importerLoc'\n >,\n traceOverride?: Array<TraceStep>,\n ): Promise<ViolationInfo> {\n const sourceCandidates = buildSourceCandidates(\n source,\n 'resolved' in overrides && typeof overrides.resolved === 'string'\n ? overrides.resolved\n : undefined,\n config.root,\n )\n\n const loc = await resolveImporterLocation(\n provider,\n env,\n importer,\n sourceCandidates,\n )\n\n const trace = await rebuildAndAnnotateTrace(\n provider,\n env,\n envName,\n normalizedImporter,\n source,\n loc,\n traceOverride,\n )\n\n const snippet = loc ? buildCodeSnippet(provider, importer, loc) : undefined\n\n return {\n env: envName,\n envType,\n behavior: config.effectiveBehavior,\n specifier: source,\n importer: normalizedImporter,\n ...(loc ? { importerLoc: loc } : {}),\n trace,\n snippet,\n ...overrides,\n }\n }\n\n async function resolveImporterLocation(\n provider: TransformResultProvider,\n env: EnvState,\n importer: string,\n sourceCandidates: Iterable<string>,\n ): Promise<Loc | undefined> {\n for (const candidate of sourceCandidates) {\n const loc =\n (await findPostCompileUsageLocation(provider, importer, candidate)) ||\n (await findImportStatementLocationFromTransformed(\n provider,\n importer,\n candidate,\n env.importLocCache,\n findFirstImportSpecifierIndex,\n ))\n if (loc) return loc\n }\n return undefined\n }\n\n /**\n * Check if a resolved import violates marker restrictions (e.g. importing\n * a server-only module in the client env). If so, build and return the\n * {@link ViolationInfo} — the caller is responsible for reporting/deferring.\n *\n * Returns `undefined` when the resolved import has no marker conflict.\n */\n async function buildMarkerViolationFromResolvedImport(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n envType: 'client' | 'server',\n importer: string,\n source: string,\n resolvedId: string,\n relativePath: string,\n traceOverride?: Array<TraceStep>,\n ): Promise<ViolationInfo | undefined> {\n const normalizedResolvedId = normalizeFilePath(resolvedId)\n const markerKind = shared.fileMarkerKind.get(normalizedResolvedId)\n const violates =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n if (!violates) return undefined\n\n const normalizedImporter = normalizeFilePath(importer)\n\n return buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'marker',\n resolved: normalizedResolvedId,\n message: buildMarkerViolationMessage(relativePath, markerKind),\n },\n traceOverride,\n )\n }\n\n function buildMarkerViolationMessage(\n relativePath: string,\n markerKind: 'server' | 'client' | undefined,\n ): string {\n return markerKind === 'server'\n ? `Module \"${relativePath}\" is marked server-only but is imported in the client environment`\n : `Module \"${relativePath}\" is marked client-only but is imported in the server environment`\n }\n\n async function buildFileViolationInfo(\n provider: TransformResultProvider,\n env: EnvState,\n envName: string,\n envType: 'client' | 'server',\n importer: string,\n normalizedImporter: string,\n source: string,\n resolvedPath: string,\n pattern: string | RegExp,\n traceOverride?: Array<TraceStep>,\n ): Promise<ViolationInfo> {\n const relativePath = getRelativePath(resolvedPath)\n\n return buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'file',\n pattern,\n resolved: resolvedPath,\n message: `Import \"${source}\" (resolved to \"${relativePath}\") is denied in the ${envType} environment`,\n },\n traceOverride,\n )\n }\n\n function getEnvType(envName: string): 'client' | 'server' {\n return config.envTypeMap.get(envName) ?? 'server'\n }\n\n function getRulesForEnvironment(envName: string): EnvRules {\n const type = getEnvType(envName)\n return type === 'client'\n ? config.compiledRules.client\n : config.compiledRules.server\n }\n\n /**\n * Check if a relative path matches any denied file pattern for the given\n * environment, respecting `excludeFiles`. Returns the matching pattern\n * or `undefined` if the file is not denied.\n */\n function checkFileDenial(\n relativePath: string,\n matchers: {\n files: Array<CompiledMatcher>\n excludeFiles: Array<CompiledMatcher>\n },\n ): CompiledMatcher | undefined {\n if (\n matchers.excludeFiles.length > 0 &&\n matchesAny(relativePath, matchers.excludeFiles)\n ) {\n return undefined\n }\n return matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n }\n\n const environmentNames = new Set<string>([\n VITE_ENVIRONMENT_NAMES.client,\n VITE_ENVIRONMENT_NAMES.server,\n ])\n if (opts.providerEnvName !== VITE_ENVIRONMENT_NAMES.server) {\n environmentNames.add(opts.providerEnvName)\n }\n\n /** Get (or lazily create) the per-env state for the given environment name. */\n function getEnv(envName: string): EnvState {\n let envState = envStates.get(envName)\n if (!envState) {\n const transformResultCache = new Map<string, TransformResult>()\n envState = {\n graph: new ImportGraph(),\n mockExportsByImporter: new Map(),\n resolveCache: new Map(),\n resolveCacheByFile: new Map(),\n importLocCache: new ImportLocCache(),\n seenViolations: new Set(),\n transformResultCache,\n transformResultKeysByFile: new Map(),\n transformResultProvider: {\n getTransformResult(id: string) {\n const fullKey = normalizePath(id)\n const exact = transformResultCache.get(fullKey)\n if (exact) return exact\n const strippedKey = normalizeFilePath(id)\n return strippedKey !== fullKey\n ? transformResultCache.get(strippedKey)\n : undefined\n },\n },\n postTransformImports: new Map(),\n serverFnLookupModules: new Set(),\n pendingViolations: new Map(),\n deferredBuildViolations: [],\n }\n envStates.set(envName, envState)\n }\n return envState\n }\n\n /**\n * Search a parsed export-names map for an entry matching any of the\n * specifier candidates. Returns matching names or empty array.\n */\n function findExportsInMap(\n exportMap: Map<string, Array<string>>,\n candidates: Array<string>,\n ): Array<string> {\n for (const candidate of candidates) {\n const hit = exportMap.get(candidate)\n if (hit && hit.length > 0) return hit\n }\n return []\n }\n\n /**\n * Build deduped resolution candidates for a module ID, including the\n * extensionless absolute path when the ID looks like a file path.\n */\n function buildIdCandidates(id: string, extra?: string): Array<string> {\n const set = new Set(buildResolutionCandidates(id))\n if (extra) {\n for (const c of buildResolutionCandidates(extra)) set.add(c)\n set.add(resolveExtensionlessAbsoluteId(extra))\n }\n return Array.from(set)\n }\n\n /**\n * Resolve which named exports the importer needs from a denied specifier,\n * so mock-edge modules can provide explicit ESM named exports.\n *\n * Tries multiple strategies: cached export maps, AST parsing, and\n * resolver-based comparison.\n */\n async function resolveExportsForDeniedSpecifier(\n env: EnvState,\n ctx: ViolationReporter,\n info: ViolationInfo,\n importerIdHint?: string,\n ): Promise<Array<string>> {\n const importerFile = normalizeFilePath(info.importer)\n const specifierCandidates = buildIdCandidates(info.specifier, info.resolved)\n\n // Only parse AST when a violation occurs (this function is only called\n // while handling a violation). Cache per-importer to avoid repeated parses\n // across multiple violations.\n let parsedBySource = env.mockExportsByImporter.get(importerFile)\n if (!parsedBySource) {\n // Try transform-cache result first, then moduleInfo fallback.\n const importerCode =\n env.transformResultProvider.getTransformResult(importerFile)?.code ??\n (importerIdHint && ctx.getModuleInfo\n ? (ctx.getModuleInfo(importerIdHint)?.code ?? undefined)\n : undefined)\n if (typeof importerCode !== 'string' || importerCode.length === 0)\n return []\n\n try {\n parsedBySource = collectMockExportNamesBySource(importerCode)\n\n // Also index by resolved physical IDs so later lookups match.\n await recordMockExportsForImporter(\n env,\n importerFile,\n parsedBySource,\n async (src) => {\n const cacheKey = `${importerFile}:${src}`\n if (env.resolveCache.has(cacheKey)) {\n return env.resolveCache.get(cacheKey) ?? undefined\n }\n if (!ctx.resolve) return undefined\n const resolved = await ctx.resolve(src, info.importer, {\n skipSelf: true,\n })\n if (!resolved || resolved.external) return undefined\n return resolved.id\n },\n )\n\n // Keep the parsed-by-source map for direct lookups.\n parsedBySource =\n env.mockExportsByImporter.get(importerFile) ?? parsedBySource\n } catch {\n return []\n }\n }\n\n // 1. Direct candidate match\n const direct = findExportsInMap(parsedBySource, specifierCandidates)\n if (direct.length > 0) return direct\n\n // 2. Resolve each source key and compare candidates.\n const candidateSet = new Set(specifierCandidates)\n for (const [sourceKey, names] of parsedBySource) {\n if (!names.length) continue\n\n const resolvedId = await resolveSourceKey(\n env,\n ctx,\n importerFile,\n sourceKey,\n info.importer,\n )\n if (!resolvedId) continue\n\n const resolvedCandidates = buildIdCandidates(resolvedId)\n resolvedCandidates.push(resolveExtensionlessAbsoluteId(resolvedId))\n if (resolvedCandidates.some((v) => candidateSet.has(v))) {\n return names\n }\n }\n\n return []\n }\n\n /** Best-effort resolve a source key using the cache or ctx.resolve. */\n async function resolveSourceKey(\n env: EnvState,\n ctx: ViolationReporter,\n importerFile: string,\n sourceKey: string,\n importerId: string,\n ): Promise<string | undefined> {\n const cacheKey = `${importerFile}:${sourceKey}`\n if (env.resolveCache.has(cacheKey)) {\n return env.resolveCache.get(cacheKey) ?? undefined\n }\n if (!ctx.resolve) return undefined\n try {\n const resolved = await ctx.resolve(sourceKey, importerId, {\n skipSelf: true,\n })\n if (!resolved || resolved.external) return undefined\n return resolved.id\n } catch {\n return undefined\n }\n }\n\n async function recordMockExportsForImporter(\n env: EnvState,\n importerId: string,\n namesBySource: Map<string, Array<string>>,\n resolveSource: (source: string) => Promise<string | undefined>,\n ): Promise<void> {\n const importerFile = normalizeFilePath(importerId)\n\n if (namesBySource.size === 0) return\n\n for (const [source, names] of namesBySource) {\n try {\n const resolvedId = await resolveSource(source)\n if (!resolvedId) continue\n\n namesBySource.set(normalizeFilePath(resolvedId), names)\n namesBySource.set(resolveExtensionlessAbsoluteId(resolvedId), names)\n } catch {\n // Best-effort only\n }\n }\n\n const existing = env.mockExportsByImporter.get(importerFile)\n if (!existing) {\n env.mockExportsByImporter.set(importerFile, namesBySource)\n return\n }\n\n for (const [source, names] of namesBySource) {\n const prev = existing.get(source)\n if (!prev) {\n existing.set(source, names)\n continue\n }\n\n const union = new Set([...prev, ...names])\n existing.set(source, Array.from(union).sort())\n }\n }\n\n const shouldCheckImporterCache = new Map<string, boolean>()\n function shouldCheckImporter(importer: string): boolean {\n let result = shouldCheckImporterCache.get(importer)\n if (result !== undefined) return result\n\n const relativePath = relativizePath(importer, config.root)\n\n // Excluded or ignored importers are never checked.\n const excluded =\n (config.excludeMatchers.length > 0 &&\n matchesAny(relativePath, config.excludeMatchers)) ||\n (config.ignoreImporterMatchers.length > 0 &&\n matchesAny(relativePath, config.ignoreImporterMatchers))\n\n if (excluded) {\n result = false\n } else if (config.includeMatchers.length > 0) {\n result = !!matchesAny(relativePath, config.includeMatchers)\n } else if (config.srcDirectory) {\n result = isInsideDirectory(importer, config.srcDirectory)\n } else {\n result = true\n }\n\n shouldCheckImporterCache.set(importer, result)\n return result\n }\n\n function dedupeKey(info: ViolationInfo): string {\n return `${info.type}:${info.importer}:${info.specifier}:${info.resolved ?? ''}`\n }\n\n function hasSeen(env: EnvState, key: string): boolean {\n if (config.logMode === 'always') return false\n if (env.seenViolations.has(key)) return true\n env.seenViolations.add(key)\n return false\n }\n\n function getRelativePath(absolutePath: string): string {\n return relativizePath(normalizePath(absolutePath), config.root)\n }\n\n /** Reset all caches on an EnvState (called from buildStart). */\n function clearEnvState(envState: EnvState): void {\n envState.resolveCache.clear()\n envState.resolveCacheByFile.clear()\n envState.importLocCache.clear()\n envState.seenViolations.clear()\n envState.transformResultCache.clear()\n envState.transformResultKeysByFile.clear()\n envState.postTransformImports.clear()\n envState.serverFnLookupModules.clear()\n envState.pendingViolations.clear()\n envState.deferredBuildViolations.length = 0\n envState.graph.clear()\n envState.mockExportsByImporter.clear()\n }\n\n /** Invalidate all env-level caches that reference a specific file. */\n function invalidateFileFromEnv(envState: EnvState, file: string): void {\n envState.importLocCache.deleteByFile(file)\n\n // Resolve cache (keyed \"importer:source\")\n const resolveKeys = envState.resolveCacheByFile.get(file)\n if (resolveKeys) {\n for (const key of resolveKeys) envState.resolveCache.delete(key)\n envState.resolveCacheByFile.delete(file)\n }\n\n envState.graph.invalidate(file)\n envState.mockExportsByImporter.delete(file)\n envState.serverFnLookupModules.delete(file)\n envState.pendingViolations.delete(file)\n\n // Transform result cache + post-transform imports\n const transformKeys = envState.transformResultKeysByFile.get(file)\n if (transformKeys) {\n for (const key of transformKeys) {\n envState.transformResultCache.delete(key)\n envState.postTransformImports.delete(key)\n }\n envState.transformResultKeysByFile.delete(file)\n } else {\n envState.transformResultCache.delete(file)\n envState.postTransformImports.delete(file)\n }\n }\n\n /** Store a transform result under both the cacheKey and physical file path. */\n function cacheTransformResult(\n envState: EnvState,\n file: string,\n cacheKey: string,\n result: TransformResult,\n ): void {\n envState.transformResultCache.set(cacheKey, result)\n const keySet = getOrCreate(\n envState.transformResultKeysByFile,\n file,\n () => new Set<string>(),\n )\n keySet.add(cacheKey)\n if (cacheKey !== file) {\n envState.transformResultCache.set(file, result)\n keySet.add(file)\n }\n }\n\n /** Register known Start entrypoints as trace roots for all environments. */\n function registerEntries(): void {\n const { resolvedStartConfig } = opts.getConfig()\n for (const envDef of opts.environments) {\n const envState = getEnv(envDef.name)\n if (resolvedStartConfig.routerFilePath) {\n envState.graph.addEntry(\n normalizePath(resolvedStartConfig.routerFilePath),\n )\n }\n if (resolvedStartConfig.startFilePath) {\n envState.graph.addEntry(\n normalizePath(resolvedStartConfig.startFilePath),\n )\n }\n }\n }\n\n /**\n * Get the merged set of post-transform imports for a file, checking all\n * code-split variants. Returns `null` if no post-transform data exists\n * yet (transform hasn't run).\n *\n * Skips `SERVER_FN_LOOKUP` variants because they contain untransformed\n * code — the Start compiler excludes them.\n */\n function getPostTransformImports(\n env: EnvState,\n file: string,\n ): Set<string> | null {\n const keySet = env.transformResultKeysByFile.get(file)\n let merged: Set<string> | null = null\n\n if (keySet) {\n for (const k of keySet) {\n if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue\n const imports = env.postTransformImports.get(k)\n if (imports) {\n if (!merged) merged = new Set(imports)\n else for (const v of imports) merged.add(v)\n }\n }\n }\n\n // Fallback: direct file-path key\n if (!merged) {\n const imports = env.postTransformImports.get(file)\n if (imports) merged = new Set(imports)\n }\n\n return merged\n }\n\n /**\n * Check whether an import edge from `parent` to `target` survived\n * post-transform compilation.\n *\n * Returns:\n * - `'live'` — target appears in a non-lookup variant's post-transform imports\n * - `'dead'` — post-transform data exists but target is absent (compiler stripped it)\n * - `'pending'` — transform ran but import data not yet posted\n * - `'no-data'` — transform never ran (warm-start cached module)\n */\n function checkEdgeLiveness(\n env: EnvState,\n parent: string,\n target: string,\n ): 'live' | 'dead' | 'pending' | 'no-data' {\n const keySet = env.transformResultKeysByFile.get(parent)\n let anyVariantCached = false\n\n if (keySet) {\n for (const k of keySet) {\n if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue\n const imports = env.postTransformImports.get(k)\n if (imports) {\n anyVariantCached = true\n if (imports.has(target)) return 'live'\n }\n }\n }\n\n if (!anyVariantCached) {\n const imports = env.postTransformImports.get(parent)\n if (imports) return imports.has(target) ? 'live' : 'dead'\n const hasTransformResult =\n env.transformResultCache.has(parent) ||\n (keySet ? keySet.size > 0 : false)\n return hasTransformResult ? 'pending' : 'no-data'\n }\n\n return 'dead'\n }\n\n function checkPostTransformReachability(\n env: EnvState,\n file: string,\n ): 'reachable' | 'unreachable' | 'unknown' {\n const visited = new Set<string>()\n const queue: Array<string> = [file]\n let hasUnknownEdge = false\n let qi = 0\n\n while (qi < queue.length) {\n const current = queue[qi++]!\n if (visited.has(current)) continue\n visited.add(current)\n\n if (env.graph.entries.has(current)) {\n return 'reachable'\n }\n\n const importers = env.graph.reverseEdges.get(current)\n if (!importers) continue\n\n for (const [parent] of importers) {\n if (visited.has(parent)) continue\n const liveness = checkEdgeLiveness(env, parent, current)\n if (liveness === 'live' || liveness === 'no-data') {\n // Live edge or warm-start (no transform data) — follow it\n queue.push(parent)\n } else if (liveness === 'pending') {\n hasUnknownEdge = true\n }\n // 'dead' — edge was stripped by compiler, skip\n }\n }\n\n return hasUnknownEdge ? 'unknown' : 'unreachable'\n }\n\n /**\n * Filter pending violations using edge-survival data. Returns the subset\n * of violations whose resolved import survived the Start compiler (or all\n * violations when no post-transform data is available yet).\n *\n * Returns `undefined` when all violations were stripped or when we must wait\n * for post-transform data before proceeding.\n */\n function filterEdgeSurvival(\n env: EnvState,\n file: string,\n violations: Array<PendingViolation>,\n ):\n | { active: Array<PendingViolation>; edgeSurvivalApplied: boolean }\n | 'all-stripped'\n | 'await-transform' {\n const postTransform = getPostTransformImports(env, file)\n\n if (postTransform) {\n const surviving = violations.filter(\n (pv) => !pv.info.resolved || postTransform.has(pv.info.resolved),\n )\n if (surviving.length === 0) return 'all-stripped'\n env.pendingViolations.set(file, surviving)\n return { active: surviving, edgeSurvivalApplied: true }\n }\n\n // Pre-transform violations need edge-survival verification first.\n if (violations.some((pv) => pv.fromPreTransformResolve)) {\n return 'await-transform'\n }\n\n return { active: violations, edgeSurvivalApplied: false }\n }\n\n /**\n * Process pending violations for the given environment. Called from the\n * transform-cache hook after each module transform is cached, because new\n * transform data may allow us to confirm or discard pending violations.\n *\n * @param warnFn - `this.warn` from the transform hook context\n */\n async function processPendingViolations(\n env: EnvState,\n warnFn: (msg: string) => void,\n ): Promise<void> {\n if (env.pendingViolations.size === 0) return\n\n const toDelete: Array<string> = []\n\n for (const [file, violations] of env.pendingViolations) {\n const filtered = filterEdgeSurvival(env, file, violations)\n\n if (filtered === 'all-stripped') {\n toDelete.push(file)\n continue\n }\n if (filtered === 'await-transform') continue\n\n const { active, edgeSurvivalApplied } = filtered\n\n // Wait for entries before running reachability. registerEntries()\n // populates entries at buildStart; resolveId(!importer) may add more.\n const status =\n env.graph.entries.size > 0\n ? checkPostTransformReachability(env, file)\n : 'unknown'\n\n if (status === 'reachable') {\n for (const pv of active) {\n await emitPendingViolation(env, warnFn, pv)\n }\n toDelete.push(file)\n } else if (status === 'unreachable') {\n toDelete.push(file)\n } else if (config.command === 'serve') {\n // 'unknown' reachability — some graph edges lack transform data.\n // When edge-survival was applied, surviving violations are confirmed\n // real. Without it (warm start), emit conservatively.\n let emittedAny = false\n for (const pv of active) {\n if (pv.fromPreTransformResolve) continue\n\n const shouldEmit =\n edgeSurvivalApplied ||\n (pv.info.type === 'file' &&\n !!pv.info.resolved &&\n isInsideDirectory(pv.info.resolved, config.srcDirectory))\n\n if (shouldEmit) {\n emittedAny =\n (await emitPendingViolation(env, warnFn, pv)) || emittedAny\n }\n }\n\n if (emittedAny) {\n toDelete.push(file)\n }\n }\n // 'unknown' — keep pending for next transform-cache invocation.\n }\n\n for (const file of toDelete) {\n env.pendingViolations.delete(file)\n }\n }\n\n async function emitPendingViolation(\n env: EnvState,\n warnFn: (msg: string) => void,\n pv: PendingViolation,\n ): Promise<boolean> {\n if (!pv.info.importerLoc) {\n const sourceCandidates = buildSourceCandidates(\n pv.info.specifier,\n pv.info.resolved,\n config.root,\n )\n const loc = await resolveImporterLocation(\n env.transformResultProvider,\n env,\n pv.info.importer,\n sourceCandidates,\n )\n\n if (loc) {\n pv.info.importerLoc = loc\n pv.info.snippet = buildCodeSnippet(\n env.transformResultProvider,\n pv.info.importer,\n loc,\n )\n }\n }\n\n if (hasSeen(env, dedupeKey(pv.info))) {\n return false\n }\n\n const freshTrace = await rebuildAndAnnotateTrace(\n env.transformResultProvider,\n env,\n pv.info.env,\n pv.info.importer,\n pv.info.specifier,\n pv.info.importerLoc,\n )\n if (freshTrace.length > pv.info.trace.length) {\n pv.info.trace = freshTrace\n }\n\n if (config.onViolation) {\n const result = await config.onViolation(pv.info)\n if (result === false) return false\n }\n\n warnFn(formatViolation(pv.info, config.root))\n return true\n }\n\n /**\n * Record a violation as pending for later confirmation via graph\n * reachability. Called from `resolveId` when `shouldDefer` is true.\n */\n function deferViolation(\n env: EnvState,\n importerFile: string,\n info: ViolationInfo,\n isPreTransformResolve?: boolean,\n ): void {\n getOrCreate(env.pendingViolations, importerFile, () => []).push({\n info,\n fromPreTransformResolve: isPreTransformResolve,\n })\n }\n\n /** Counter for generating unique per-violation mock module IDs in build mode. */\n let buildViolationCounter = 0\n\n async function handleViolation(\n ctx: ViolationReporter,\n env: EnvState,\n info: ViolationInfo,\n importerIdHint?: string,\n violationOpts?: { silent?: boolean },\n ): Promise<HandleViolationResult> {\n if (!violationOpts?.silent) {\n if (config.onViolation) {\n const result = await config.onViolation(info)\n if (result === false) return undefined\n }\n\n if (config.effectiveBehavior === 'error') {\n // Dev+error: throw immediately.\n // Always throw on error — do NOT deduplicate via hasSeen().\n // Rollup may resolve the same specifier multiple times (e.g.\n // commonjs--resolver's nested this.resolve() fires before\n // getResolveStaticDependencyPromises). If we record the key\n // on the first (nested) throw, the second (real) resolve\n // silently returns undefined and the build succeeds — which\n // is the bug this fixes.\n //\n // Build mode never reaches here — all build violations are\n // deferred via shouldDefer and handled silently.\n return ctx.error(formatViolation(info, config.root))\n }\n\n if (!hasSeen(env, dedupeKey(info))) {\n ctx.warn(formatViolation(info, config.root))\n }\n } else if (\n config.effectiveBehavior === 'error' &&\n config.command !== 'build'\n ) {\n return undefined\n }\n\n // File violations: return resolved path — the self-denial transform\n // will replace the file's content with a mock module. This avoids\n // virtual module IDs that could leak across environments via\n // third-party resolver caches.\n if (info.type === 'file') return info.resolved\n\n // Non-file violations (specifier/marker): create mock-edge module.\n // Dev mode uses a runtime diagnostics ID; build mode uses a unique\n // per-violation ID so generateBundle can check tree-shaking survival.\n const exports = await resolveExportsForDeniedSpecifier(\n env,\n ctx,\n info,\n importerIdHint,\n )\n const baseMockId =\n config.command === 'serve'\n ? mockRuntimeModuleIdFromViolation(info, config.mockAccess, config.root)\n : `${MOCK_BUILD_PREFIX}${buildViolationCounter++}`\n return resolveViteId(makeMockEdgeModuleId(exports, baseMockId))\n }\n\n /**\n * Unified violation dispatch: either defers or reports immediately.\n *\n * When `shouldDefer` is true (dev mock + build modes), calls\n * `handleViolation` silently to obtain the mock module ID, then stores\n * the violation for later verification:\n * - Dev mock mode: all violations are deferred to `pendingViolations`\n * for edge-survival and graph-reachability checking via\n * `processPendingViolations`.\n * - Build mode (mock + error): defers to `deferredBuildViolations` for\n * tree-shaking verification in `generateBundle`.\n *\n * Otherwise reports immediately (dev error mode). Pre-transform\n * resolves are silenced in error mode because they fire before the\n * compiler runs and there is no deferred verification path.\n *\n * Returns the mock module ID / resolve result from `handleViolation`.\n */\n async function reportOrDeferViolation(\n ctx: ViolationReporter,\n env: EnvState,\n importerFile: string,\n importerIdHint: string | undefined,\n info: ViolationInfo,\n shouldDefer: boolean,\n isPreTransformResolve: boolean,\n ): Promise<HandleViolationResult> {\n if (shouldDefer) {\n const result = await handleViolation(ctx, env, info, importerIdHint, {\n silent: true,\n })\n\n if (config.command === 'build') {\n // Build mode: store for generateBundle tree-shaking check.\n // The mock-edge module ID is returned as a plain string.\n const mockId = result ?? ''\n env.deferredBuildViolations.push({\n info,\n mockModuleId: mockId,\n // For marker violations, check importer survival instead of mock.\n checkModuleId: info.type === 'marker' ? info.importer : undefined,\n })\n } else {\n // Dev mock: store for graph-reachability check.\n deferViolation(env, importerFile, info, isPreTransformResolve)\n await processPendingViolations(env, ctx.warn.bind(ctx))\n }\n\n return result\n }\n\n // Non-deferred path: dev error mode only.\n // Pre-transform resolves are silenced because they fire before the\n // compiler runs — imports inside `.server()` callbacks haven't been\n // stripped yet and error mode has no deferred verification.\n return handleViolation(ctx, env, info, importerIdHint, {\n silent: isPreTransformResolve,\n })\n }\n\n return [\n {\n name: 'tanstack-start-core:import-protection',\n enforce: 'pre',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n // Start's environments are named `client` and `ssr` (not `server`), plus\n // an optional serverFn provider environment (eg `rsc`) when configured.\n return environmentNames.has(env.name)\n },\n\n configResolved(viteConfig) {\n config.root = viteConfig.root\n config.command = viteConfig.command\n\n const { startConfig, resolvedStartConfig } = opts.getConfig()\n config.srcDirectory = resolvedStartConfig.srcDirectory\n\n const userOpts: ImportProtectionOptions | undefined =\n startConfig.importProtection\n\n if (userOpts?.enabled === false) {\n config.enabled = false\n return\n }\n\n config.enabled = true\n\n const behavior = userOpts?.behavior\n if (typeof behavior === 'string') {\n config.effectiveBehavior = behavior\n } else {\n config.effectiveBehavior =\n viteConfig.command === 'serve'\n ? (behavior?.dev ?? 'mock')\n : (behavior?.build ?? 'error')\n }\n\n config.logMode = userOpts?.log ?? 'once'\n config.mockAccess = userOpts?.mockAccess ?? 'error'\n config.maxTraceDepth = userOpts?.maxTraceDepth ?? 20\n if (userOpts?.onViolation) {\n const fn = userOpts.onViolation\n config.onViolation = (info) => fn(info)\n }\n\n const defaults = getDefaultImportProtectionRules()\n // Use user-provided patterns when available, otherwise defaults.\n const pick = <T>(user: Array<T> | undefined, fallback: Array<T>) =>\n user ? [...user] : [...fallback]\n\n // Client specifier denies always include framework defaults even\n // when the user provides a custom list.\n const clientSpecifiers = dedupePatterns([\n ...defaults.client.specifiers,\n ...(userOpts?.client?.specifiers ?? []),\n ])\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(\n pick(userOpts?.client?.files, defaults.client.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.client?.excludeFiles, defaults.client.excludeFiles),\n ),\n }\n config.compiledRules.server = {\n specifiers: compileMatchers(\n dedupePatterns(\n pick(userOpts?.server?.specifiers, defaults.server.specifiers),\n ),\n ),\n files: compileMatchers(\n pick(userOpts?.server?.files, defaults.server.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.server?.excludeFiles, defaults.server.excludeFiles),\n ),\n }\n\n config.includeMatchers = compileMatchers(userOpts?.include ?? [])\n config.excludeMatchers = compileMatchers(userOpts?.exclude ?? [])\n config.ignoreImporterMatchers = compileMatchers(\n userOpts?.ignoreImporters ?? [],\n )\n\n // Marker specifiers\n const markers = getMarkerSpecifiers()\n config.markerSpecifiers = {\n serverOnly: new Set(markers.serverOnly),\n clientOnly: new Set(markers.clientOnly),\n }\n },\n\n configureServer(server) {\n devServer = server\n },\n\n buildStart() {\n if (!config.enabled) return\n // Clear memoization caches that grow unboundedly across builds\n clearNormalizeFilePathCache()\n extensionlessIdResolver.clear()\n importPatternCache.clear()\n shouldCheckImporterCache.clear()\n\n // Clear per-env caches\n for (const envState of envStates.values()) {\n clearEnvState(envState)\n }\n\n // Clear shared state\n shared.fileMarkerKind.clear()\n\n registerEntries()\n },\n\n hotUpdate(ctx) {\n if (!config.enabled) return\n // Invalidate caches for updated files\n for (const mod of ctx.modules) {\n if (mod.id) {\n const id = mod.id\n const importerFile = normalizeFilePath(id)\n\n // Invalidate extensionless-resolution cache entries affected by this file.\n extensionlessIdResolver.invalidateByFile(importerFile)\n shared.fileMarkerKind.delete(importerFile)\n\n // Invalidate per-env caches\n for (const envState of envStates.values()) {\n invalidateFileFromEnv(envState, importerFile)\n }\n }\n }\n },\n\n async resolveId(source, importer, _options) {\n const envName = this.environment.name\n const env = getEnv(envName)\n const envType = getEnvType(envName)\n const provider = env.transformResultProvider\n const isScanResolve = !!(_options as Record<string, unknown>).scan\n\n if (IMPORT_PROTECTION_DEBUG) {\n const importerPath = importer\n ? normalizeFilePath(importer)\n : '(entry)'\n const isEntryResolve = !importer\n const filtered =\n process.env.TSR_IMPORT_PROTECTION_DEBUG_FILTER === 'entry'\n ? isEntryResolve\n : matchesDebugFilter(source, importerPath)\n if (filtered) {\n debugLog('resolveId', {\n env: envName,\n envType,\n source,\n importer: importerPath,\n isEntryResolve,\n command: config.command,\n })\n }\n }\n\n // Internal virtual modules (mock:build:N, mock-edge, mock-runtime, marker)\n const internalVirtualId = resolveInternalVirtualModuleId(source)\n if (internalVirtualId) return internalVirtualId\n\n if (!importer) {\n env.graph.addEntry(source)\n // Flush pending violations now that an additional entry is known\n // and reachability analysis may have new roots.\n await processPendingViolations(env, this.warn.bind(this))\n return undefined\n }\n\n if (source.startsWith('\\0') || source.startsWith('virtual:')) {\n return undefined\n }\n\n const normalizedImporter = normalizeFilePath(importer)\n const isDirectLookup = importer.includes(SERVER_FN_LOOKUP_QUERY)\n\n if (isDirectLookup) {\n env.serverFnLookupModules.add(normalizedImporter)\n }\n\n const isPreTransformResolve =\n isDirectLookup ||\n env.serverFnLookupModules.has(normalizedImporter) ||\n isScanResolve\n\n // Dev mock mode: defer all violations (including pre-transform\n // resolves) until post-transform data is available, then\n // confirm/discard via graph reachability.\n // Build mode (both mock and error): defer violations until\n // generateBundle so tree-shaking can eliminate false positives.\n const isDevMock =\n config.command === 'serve' && config.effectiveBehavior === 'mock'\n const isBuild = config.command === 'build'\n const shouldDefer = shouldDeferViolation({ isBuild, isDevMock })\n\n const resolveAgainstImporter = async (): Promise<string | null> => {\n const primary = await this.resolve(source, importer, {\n skipSelf: true,\n })\n if (primary) {\n return canonicalizeResolvedId(\n primary.id,\n config.root,\n resolveExtensionlessAbsoluteId,\n )\n }\n\n return null\n }\n\n // Check if this is a marker import\n const markerKind = config.markerSpecifiers.serverOnly.has(source)\n ? ('server' as const)\n : config.markerSpecifiers.clientOnly.has(source)\n ? ('client' as const)\n : undefined\n\n if (markerKind) {\n const existing = shared.fileMarkerKind.get(normalizedImporter)\n if (existing && existing !== markerKind) {\n this.error(\n `[import-protection] File \"${getRelativePath(normalizedImporter)}\" has both server-only and client-only markers. This is not allowed.`,\n )\n }\n shared.fileMarkerKind.set(normalizedImporter, markerKind)\n\n const violatesEnv =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n\n if (violatesEnv) {\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'marker',\n message: buildMarkerViolationMessage(\n getRelativePath(normalizedImporter),\n markerKind,\n ),\n },\n )\n const markerResult = await reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n\n // In build mode, if the violation was deferred, return the unique\n // build mock ID instead of the marker module. This lets\n // generateBundle check whether the importer (and thus its marker\n // import) survived tree-shaking. The mock is side-effect-free just\n // like the marker module, and the bare import has no bindings, so\n // replacing it is transparent.\n if (isBuild && markerResult != null) {\n return markerResult\n }\n }\n\n // Retroactive marker violation detection: on cold starts, module\n // A may import module B before B's marker is set (because B hasn't\n // been processed yet). When B's marker is set (here),\n // retroactively check all known importers of B in the graph and\n // create deferred marker violations for them. Without this,\n // cold-start ordering can miss marker violations that warm starts\n // detect (warm starts see markers early from cached transforms).\n //\n // Uses lightweight `deferViolation` to avoid heavy side effects\n // (mock module creation, export resolution). Immediately calls\n // `processPendingViolations` to flush the deferred violations,\n // because the marker resolveId fires during Vite's import\n // analysis (after our transform hook) — there may be no\n // subsequent transform invocation to flush them.\n //\n // Guarded by `violatesEnv` (per-environment) plus a per-env\n // seen-set. The marker is shared across environments but each\n // env's graph has its own edges; this ensures the check runs\n // at most once per (env, module) pair.\n const envRetroKey = `retro-marker:${normalizedImporter}`\n if (violatesEnv && !env.seenViolations.has(envRetroKey)) {\n env.seenViolations.add(envRetroKey)\n let retroDeferred = false\n const importersMap = env.graph.reverseEdges.get(normalizedImporter)\n if (importersMap && importersMap.size > 0) {\n for (const [importerFile, specifier] of importersMap) {\n if (!specifier) continue\n if (!shouldCheckImporter(importerFile)) continue\n const markerInfo = await buildMarkerViolationFromResolvedImport(\n provider,\n env,\n envName,\n envType,\n importerFile,\n specifier,\n normalizedImporter,\n getRelativePath(normalizedImporter),\n )\n if (markerInfo) {\n deferViolation(\n env,\n importerFile,\n markerInfo,\n isPreTransformResolve,\n )\n retroDeferred = true\n }\n }\n }\n if (retroDeferred) {\n await processPendingViolations(env, this.warn.bind(this))\n }\n }\n\n return markerKind === 'server'\n ? resolvedMarkerVirtualModuleId('server')\n : resolvedMarkerVirtualModuleId('client')\n }\n\n // Check if the importer is within our scope\n if (!shouldCheckImporter(normalizedImporter)) {\n return undefined\n }\n\n const matchers = getRulesForEnvironment(envName)\n\n // 1. Specifier-based denial\n const specifierMatch = matchesAny(source, matchers.specifiers)\n if (specifierMatch) {\n if (!isPreTransformResolve) {\n env.graph.addEdge(source, normalizedImporter, source)\n }\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'specifier',\n pattern: specifierMatch.pattern,\n message: `Import \"${source}\" is denied in the ${envType} environment`,\n },\n )\n\n // Resolve the specifier so edge-survival can verify whether\n // the import survives the Start compiler transform (e.g.\n // factory-safe pattern strips imports inside .server() callbacks).\n if (shouldDefer && !info.resolved) {\n try {\n const resolvedForInfo = await resolveAgainstImporter()\n if (resolvedForInfo) info.resolved = resolvedForInfo\n } catch {\n // Non-fatal: edge-survival will skip unresolved specifiers\n }\n }\n\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n\n // 2. Resolve the import (cached)\n const cacheKey = `${normalizedImporter}:${source}`\n let resolved: string | null\n\n if (env.resolveCache.has(cacheKey)) {\n resolved = env.resolveCache.get(cacheKey) ?? null\n } else {\n resolved = await resolveAgainstImporter()\n\n // Only cache successful resolves. Null resolves can be\n // order-dependent across importer variants (e.g. code-split\n // `?tsr-split=...` ids) and may poison later lookups.\n if (resolved !== null) {\n env.resolveCache.set(cacheKey, resolved)\n getOrCreate(\n env.resolveCacheByFile,\n normalizedImporter,\n () => new Set(),\n ).add(cacheKey)\n }\n }\n\n if (resolved) {\n const relativePath = getRelativePath(resolved)\n\n // Propagate pre-transform status transitively\n if (isPreTransformResolve && !isScanResolve) {\n env.serverFnLookupModules.add(resolved)\n }\n\n if (!isPreTransformResolve) {\n env.graph.addEdge(resolved, normalizedImporter, source)\n }\n\n // Skip file-based and marker-based denial for resolved paths that\n // match the per-environment `excludeFiles` patterns. By default\n // this includes `**/node_modules/**` so that third-party packages\n // using `.client.` / `.server.` in their filenames (e.g. react-tweet\n // exports `index.client.js`) are not treated as user-authored\n // environment boundaries. Users can override `excludeFiles` per\n // environment to narrow or widen this exclusion.\n const isExcludedFile =\n matchers.excludeFiles.length > 0 &&\n matchesAny(relativePath, matchers.excludeFiles)\n\n if (!isExcludedFile) {\n const fileMatch =\n matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n\n if (fileMatch) {\n const info = await buildFileViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n resolved,\n fileMatch.pattern,\n )\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n\n const markerInfo = await buildMarkerViolationFromResolvedImport(\n provider,\n env,\n envName,\n envType,\n importer,\n source,\n resolved,\n relativePath,\n )\n if (markerInfo) {\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n importer,\n markerInfo,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n }\n }\n\n return undefined\n },\n\n load: {\n filter: {\n id: new RegExp(\n getResolvedVirtualModuleMatchers().map(escapeRegExp).join('|'),\n ),\n },\n handler(id) {\n if (IMPORT_PROTECTION_DEBUG) {\n if (matchesDebugFilter(id)) {\n debugLog('load:handler', {\n env: this.environment.name,\n id: normalizePath(id),\n })\n }\n }\n\n return loadResolvedVirtualModule(id)\n },\n },\n\n async generateBundle(_options, bundle) {\n const envName = this.environment.name\n const env = envStates.get(envName)\n if (!env || env.deferredBuildViolations.length === 0) return\n\n const candidateCache = new Map<string, Array<string>>()\n const toModuleIdCandidates = (id: string): Array<string> => {\n let cached = candidateCache.get(id)\n if (cached) return cached\n\n const out = new Set<string>()\n const normalized = normalizeFilePath(id)\n out.add(id)\n out.add(normalized)\n out.add(relativizePath(normalized, config.root))\n\n if (normalized.startsWith(VITE_BROWSER_VIRTUAL_PREFIX)) {\n const internal = `\\0${normalized.slice(VITE_BROWSER_VIRTUAL_PREFIX.length)}`\n out.add(internal)\n out.add(relativizePath(normalizeFilePath(internal), config.root))\n }\n\n if (normalized.startsWith('\\0')) {\n const browser = `${VITE_BROWSER_VIRTUAL_PREFIX}${normalized.slice(1)}`\n out.add(browser)\n out.add(relativizePath(normalizeFilePath(browser), config.root))\n }\n\n cached = Array.from(out)\n candidateCache.set(id, cached)\n return cached\n }\n\n // Collect all module IDs that survived tree-shaking in this bundle.\n const survivingModules = new Set<string>()\n for (const chunk of Object.values(bundle)) {\n if (chunk.type === 'chunk') {\n for (const moduleId of Object.keys(chunk.modules)) {\n for (const candidate of toModuleIdCandidates(moduleId)) {\n survivingModules.add(candidate)\n }\n }\n }\n }\n\n const didModuleSurvive = (moduleId: string): boolean =>\n toModuleIdCandidates(moduleId).some((candidate) =>\n survivingModules.has(candidate),\n )\n\n // Check each deferred violation: if its check module survived\n // in the bundle, the import was NOT tree-shaken — real leak.\n const realViolations: Array<ViolationInfo> = []\n for (const {\n info,\n mockModuleId,\n checkModuleId,\n } of env.deferredBuildViolations) {\n let survived: boolean\n if (checkModuleId != null) {\n // Marker violation: check if the importer survived\n // (marker is about the file's directive, not a binding).\n // Include transform-result keys (e.g. code-split variants)\n // to cover all bundle representations of the importer.\n const importerVariantIds = new Set<string>([info.importer])\n const importerKeys = env.transformResultKeysByFile.get(\n normalizeFilePath(info.importer),\n )\n if (importerKeys) {\n for (const key of importerKeys) {\n importerVariantIds.add(key)\n }\n }\n survived = false\n for (const importerId of importerVariantIds) {\n if (didModuleSurvive(importerId)) {\n survived = true\n break\n }\n }\n } else {\n // File/specifier violation: check if the mock module survived.\n survived = didModuleSurvive(mockModuleId)\n }\n\n if (!survived) continue\n\n if (config.onViolation) {\n const result = await config.onViolation(info)\n if (result === false) continue\n }\n\n realViolations.push(info)\n }\n\n if (realViolations.length === 0) return\n\n if (config.effectiveBehavior === 'error') {\n // Error mode: fail the build on the first real violation.\n this.error(formatViolation(realViolations[0]!, config.root))\n } else {\n // Mock mode: warn for each surviving violation.\n const seen = new Set<string>()\n for (const info of realViolations) {\n const key = dedupeKey(info)\n if (!seen.has(key)) {\n seen.add(key)\n this.warn(formatViolation(info, config.root))\n }\n }\n }\n },\n },\n {\n // Captures transformed code + composed sourcemap for location mapping.\n // Runs after all `enforce: 'pre'` hooks (including the Start compiler).\n // Only files under `srcDirectory` are cached.\n name: 'tanstack-start-core:import-protection-transform-cache',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n return environmentNames.has(env.name)\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[cm]?[tj]sx?($|\\?)/],\n },\n },\n async handler(code, id) {\n const envName = this.environment.name\n const file = normalizeFilePath(id)\n const envType = getEnvType(envName)\n const matchers = getRulesForEnvironment(envName)\n const isBuild = config.command === 'build'\n\n if (IMPORT_PROTECTION_DEBUG) {\n if (matchesDebugFilter(file)) {\n debugLog('transform-cache', {\n env: envName,\n id: normalizePath(id),\n file,\n })\n }\n }\n\n if (!shouldCheckImporter(file)) {\n return undefined\n }\n\n // Self-denial: if this file is denied in the current environment\n // (e.g. a `.server` file transformed in the client environment),\n // replace its entire content with a mock module.\n //\n // This is the core mechanism for preventing cross-environment\n // cache contamination: resolveId never returns virtual module\n // IDs for file-based violations, so there is nothing for\n // third-party resolver caches (e.g. vite-tsconfig-paths) to\n // leak across environments. Each environment's transform\n // independently decides whether the file is denied.\n //\n // In dev mode, this also solves the cold-start problem where\n // the importer's AST is unavailable for export resolution:\n // the denied file's own source code is always available here,\n // so we parse its exports directly.\n const selfFileMatch = checkFileDenial(getRelativePath(file), matchers)\n if (selfFileMatch) {\n // Parse exports once — shared by build and dev paths.\n // Falls back to empty list on non-standard syntax.\n let exportNames: Array<string> = []\n try {\n exportNames = collectNamedExports(code)\n } catch {\n // Parsing may fail on non-standard syntax\n }\n\n if (isBuild) {\n return generateSelfContainedMockModule(exportNames)\n }\n\n // Dev mode: generate a mock that imports mock-runtime for\n // runtime diagnostics (error/warn on property access).\n const runtimeId = mockRuntimeModuleIdFromViolation(\n {\n type: 'file',\n env: envType,\n envType,\n behavior:\n config.effectiveBehavior === 'error' ? 'error' : 'mock',\n importer: file,\n specifier: relativizePath(file, config.root),\n resolved: file,\n pattern: selfFileMatch.pattern,\n message: `File \"${relativizePath(file, config.root)}\" is denied in the ${envType} environment`,\n trace: [],\n },\n config.mockAccess,\n config.root,\n )\n return generateDevSelfDenialModule(exportNames, runtimeId)\n }\n\n // getCombinedSourcemap() returns the composed sourcemap\n let map: SourceMapLike | undefined\n try {\n map = this.getCombinedSourcemap()\n } catch {\n map = undefined\n }\n\n let originalCode: string | undefined\n if (map?.sourcesContent) {\n originalCode = pickOriginalCodeFromSourcesContent(\n map,\n file,\n config.root,\n )\n }\n\n const lineIndex = buildLineIndex(code)\n const cacheKey = normalizePath(id)\n\n const envState = getEnv(envName)\n const isServerFnLookup = id.includes(SERVER_FN_LOOKUP_QUERY)\n\n // Propagate SERVER_FN_LOOKUP status before import-analysis\n if (isServerFnLookup) {\n envState.serverFnLookupModules.add(file)\n }\n\n const result: TransformResult = {\n code,\n map,\n originalCode,\n lineIndex,\n }\n cacheTransformResult(envState, file, cacheKey, result)\n\n // Build mode: only self-denial (above) and transform caching are\n // needed. All violations are detected and deferred in resolveId;\n // self-denial replaces denied file content; generateBundle checks\n // tree-shaking survival. The import resolution loop below is\n // dev-mode only — it resolves imports for graph reachability,\n // catches violations missed on warm starts (where Vite caches\n // resolveId), and rewrites denied imports to mock modules.\n if (isBuild) return undefined\n\n // Dev mode: resolve imports, populate graph, detect violations,\n // and rewrite denied imports.\n const isDevMock = config.effectiveBehavior === 'mock'\n const importSources = extractImportSources(code)\n const resolvedChildren = new Set<string>()\n const deniedSourceReplacements = new Map<string, string>()\n for (const src of importSources) {\n try {\n const resolved = await this.resolve(src, id, { skipSelf: true })\n if (resolved && !resolved.external) {\n const resolvedPath = canonicalizeResolvedId(\n resolved.id,\n config.root,\n resolveExtensionlessAbsoluteId,\n )\n\n resolvedChildren.add(resolvedPath)\n\n // When the resolved ID is a mock-module (from our\n // resolveId returning a mock-edge ID), postTransformImports\n // would only contain the mock ID. Edge-survival needs the\n // real physical path so pending violations can be matched.\n //\n // For relative specifiers we can compute the physical path\n // directly. For bare/alias specifiers, look up the real\n // resolved path from the pending violations that were\n // already stored by resolveId before this transform ran.\n if (resolved.id.includes('tanstack-start-import-protection:')) {\n let physicalPath: string | undefined\n // Look up real resolved path from pending violations\n const pending = envState.pendingViolations.get(file)\n if (pending) {\n const match = pending.find(\n (pv) => pv.info.specifier === src && pv.info.resolved,\n )\n if (match) physicalPath = match.info.resolved\n }\n if (physicalPath && physicalPath !== resolvedPath) {\n resolvedChildren.add(physicalPath)\n envState.graph.addEdge(physicalPath, file, src)\n }\n }\n\n // Populate import graph edges for warm-start trace accuracy\n envState.graph.addEdge(resolvedPath, file, src)\n\n if (isDevMock) {\n const relativePath = getRelativePath(resolvedPath)\n const fileMatch = checkFileDenial(relativePath, matchers)\n\n if (fileMatch) {\n const info = await buildFileViolationInfo(\n envState.transformResultProvider,\n envState,\n envName,\n envType,\n id,\n file,\n src,\n resolvedPath,\n fileMatch.pattern,\n )\n\n const replacement = await reportOrDeferViolation(\n this,\n envState,\n file,\n id,\n info,\n isDevMock,\n isServerFnLookup,\n )\n\n if (replacement) {\n deniedSourceReplacements.set(\n src,\n replacement.startsWith('\\0')\n ? VITE_BROWSER_VIRTUAL_PREFIX + replacement.slice(1)\n : replacement,\n )\n }\n }\n }\n }\n } catch {\n // Non-fatal\n }\n }\n envState.postTransformImports.set(cacheKey, resolvedChildren)\n if (cacheKey !== file && !isServerFnLookup) {\n envState.postTransformImports.set(file, resolvedChildren)\n }\n\n await processPendingViolations(envState, this.warn.bind(this))\n\n if (deniedSourceReplacements.size > 0) {\n try {\n const rewritten = rewriteDeniedImports(\n code,\n id,\n new Set(deniedSourceReplacements.keys()),\n (source: string) =>\n deniedSourceReplacements.get(source) ?? source,\n )\n\n if (!rewritten) {\n return undefined\n }\n\n const normalizedMap = rewritten.map\n ? {\n ...rewritten.map,\n version: Number(rewritten.map.version),\n sourcesContent:\n rewritten.map.sourcesContent?.map(\n (s: string | null) => s ?? '',\n ) ?? [],\n }\n : {\n version: 3,\n file: id,\n names: [],\n sources: [id],\n sourcesContent: [code],\n mappings: '',\n }\n\n return {\n code: rewritten.code,\n map: normalizedMap,\n }\n } catch {\n // Non-fatal: keep original code when rewrite fails.\n }\n }\n\n return undefined\n },\n },\n },\n ] satisfies Array<PluginOption>\n}\n"],"names":["exports"],"mappings":"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"}
@@ -79,8 +79,8 @@ function mockRuntimeModuleIdFromViolation(info, mode, root) {
79
79
  };
80
80
  return `${MOCK_RUNTIME_PREFIX}${toBase64Url(JSON.stringify(payload))}`;
81
81
  }
82
- function makeMockEdgeModuleId(exports, runtimeId) {
83
- const payload = { exports, runtimeId };
82
+ function makeMockEdgeModuleId(exports$1, runtimeId) {
83
+ const payload = { exports: exports$1, runtimeId };
84
84
  return `${MOCK_EDGE_PREFIX}${toBase64Url(JSON.stringify(payload))}`;
85
85
  }
86
86
  function generateMockCode(diagnostics) {
@@ -174,8 +174,8 @@ export default mock;
174
174
  function loadSilentMockModule() {
175
175
  return { code: generateMockCode() };
176
176
  }
177
- function filterExportNames(exports) {
178
- return exports.filter((n) => n.length > 0 && n !== "default");
177
+ function filterExportNames(exports$1) {
178
+ return exports$1.filter((n) => n.length > 0 && n !== "default");
179
179
  }
180
180
  function generateExportLines(names) {
181
181
  const lines = [];
@@ -1 +1 @@
1
- {"version":3,"file":"virtualModules.js","sources":["../../../src/import-protection-plugin/virtualModules.ts"],"sourcesContent":["import { resolveViteId } from '../utils'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { isValidExportName } from './rewriteDeniedImports'\nimport { CLIENT_ENV_SUGGESTIONS } from './trace'\nimport { VITE_BROWSER_VIRTUAL_PREFIX } from './constants'\nimport { relativizePath } from './utils'\nimport type { ViolationInfo } from './trace'\n\nexport const MOCK_MODULE_ID = 'tanstack-start-import-protection:mock'\nconst RESOLVED_MOCK_MODULE_ID = resolveViteId(MOCK_MODULE_ID)\n\n/**\n * Per-violation mock prefix used in build+error mode.\n * Each deferred violation gets a unique ID so we can check which ones\n * survived tree-shaking in `generateBundle`.\n */\nexport const MOCK_BUILD_PREFIX = 'tanstack-start-import-protection:mock:build:'\nconst RESOLVED_MOCK_BUILD_PREFIX = resolveViteId(MOCK_BUILD_PREFIX)\n\nexport const MOCK_EDGE_PREFIX = 'tanstack-start-import-protection:mock-edge:'\nconst RESOLVED_MOCK_EDGE_PREFIX = resolveViteId(MOCK_EDGE_PREFIX)\n\nexport const MOCK_RUNTIME_PREFIX =\n 'tanstack-start-import-protection:mock-runtime:'\nconst RESOLVED_MOCK_RUNTIME_PREFIX = resolveViteId(MOCK_RUNTIME_PREFIX)\n\nconst MARKER_PREFIX = 'tanstack-start-import-protection:marker:'\nconst RESOLVED_MARKER_PREFIX = resolveViteId(MARKER_PREFIX)\n\nconst RESOLVED_MARKER_SERVER_ONLY = resolveViteId(`${MARKER_PREFIX}server-only`)\nconst RESOLVED_MARKER_CLIENT_ONLY = resolveViteId(`${MARKER_PREFIX}client-only`)\n\nexport function resolvedMarkerVirtualModuleId(\n kind: 'server' | 'client',\n): string {\n return kind === 'server'\n ? RESOLVED_MARKER_SERVER_ONLY\n : RESOLVED_MARKER_CLIENT_ONLY\n}\n\n/**\n * Convenience list for plugin `load` filters/handlers.\n *\n * Vite/Rollup call `load(id)` with the *resolved* virtual id (prefixed by `\\0`).\n * `resolveId(source)` sees the *unresolved* id/prefix (without `\\0`).\n */\nexport function getResolvedVirtualModuleMatchers(): ReadonlyArray<string> {\n return RESOLVED_VIRTUAL_MODULE_MATCHERS\n}\n\nconst RESOLVED_VIRTUAL_MODULE_MATCHERS = [\n RESOLVED_MOCK_MODULE_ID,\n RESOLVED_MOCK_BUILD_PREFIX,\n RESOLVED_MOCK_EDGE_PREFIX,\n RESOLVED_MOCK_RUNTIME_PREFIX,\n RESOLVED_MARKER_PREFIX,\n] as const\n\nconst RESOLVE_PREFIX_PAIRS = [\n [MOCK_EDGE_PREFIX, RESOLVED_MOCK_EDGE_PREFIX],\n [MOCK_RUNTIME_PREFIX, RESOLVED_MOCK_RUNTIME_PREFIX],\n [MOCK_BUILD_PREFIX, RESOLVED_MOCK_BUILD_PREFIX],\n [MARKER_PREFIX, RESOLVED_MARKER_PREFIX],\n] as const\n\n/**\n * Resolve import-protection's internal virtual module IDs.\n *\n * `resolveId(source)` sees *unresolved* ids/prefixes (no `\\0`).\n * Returning a resolved id (with `\\0`) ensures Vite/Rollup route it to `load`.\n */\nexport function resolveInternalVirtualModuleId(\n source: string,\n): string | undefined {\n if (source.startsWith(VITE_BROWSER_VIRTUAL_PREFIX)) {\n return resolveInternalVirtualModuleId(\n `\\0${source.slice(VITE_BROWSER_VIRTUAL_PREFIX.length)}`,\n )\n }\n\n if (source === MOCK_MODULE_ID || source === RESOLVED_MOCK_MODULE_ID) {\n return RESOLVED_MOCK_MODULE_ID\n }\n\n for (const [unresolvedPrefix, resolvedPrefix] of RESOLVE_PREFIX_PAIRS) {\n if (source.startsWith(unresolvedPrefix)) {\n return resolveViteId(source)\n }\n\n if (source.startsWith(resolvedPrefix)) {\n return source\n }\n }\n\n return undefined\n}\n\nfunction toBase64Url(input: string): string {\n return Buffer.from(input, 'utf8').toString('base64url')\n}\n\nfunction fromBase64Url(input: string): string {\n return Buffer.from(input, 'base64url').toString('utf8')\n}\n\ntype MockAccessMode = 'error' | 'warn' | 'off'\n\n/**\n * Compact runtime suggestion text for browser console, derived from\n * {@link CLIENT_ENV_SUGGESTIONS} so there's a single source of truth.\n */\nexport const RUNTIME_SUGGESTION_TEXT =\n 'Fix: ' +\n CLIENT_ENV_SUGGESTIONS.join('. ') +\n '. To disable these runtime diagnostics, set importProtection.mockAccess: \"off\".'\n\nexport function mockRuntimeModuleIdFromViolation(\n info: ViolationInfo,\n mode: MockAccessMode,\n root: string,\n): string {\n if (mode === 'off') return MOCK_MODULE_ID\n if (info.env !== VITE_ENVIRONMENT_NAMES.client) return MOCK_MODULE_ID\n\n const rel = (p: string) => relativizePath(p, root)\n const trace = info.trace.map((s) => {\n const file = rel(s.file)\n if (s.line == null) return file\n return `${file}:${s.line}:${s.column ?? 1}`\n })\n\n const payload = {\n env: info.env,\n importer: info.importer,\n specifier: info.specifier,\n trace,\n mode,\n }\n return `${MOCK_RUNTIME_PREFIX}${toBase64Url(JSON.stringify(payload))}`\n}\n\nexport function makeMockEdgeModuleId(\n exports: Array<string>,\n runtimeId: string,\n): string {\n const payload = { exports, runtimeId }\n return `${MOCK_EDGE_PREFIX}${toBase64Url(JSON.stringify(payload))}`\n}\n\n/**\n * Generate a recursive Proxy-based mock module.\n *\n * When `diagnostics` is provided, the generated code includes a `__report`\n * function that logs runtime warnings/errors when the mock is actually used\n * (property access for primitive coercion, calls, construction, sets).\n *\n * When `diagnostics` is omitted, the mock is completely silent — suitable\n * for base mock modules (e.g. `MOCK_MODULE_ID` or per-violation build mocks)\n * that are consumed by mock-edge modules providing explicit named exports.\n */\nfunction generateMockCode(diagnostics?: {\n meta: {\n env: string\n importer: string\n specifier: string\n trace: Array<unknown>\n }\n mode: 'error' | 'warn' | 'off'\n}): string {\n const fnName = diagnostics ? '__createMock' : 'createMock'\n const hasDiag = !!diagnostics\n\n const preamble = hasDiag\n ? `const __meta = ${JSON.stringify(diagnostics.meta)};\nconst __mode = ${JSON.stringify(diagnostics.mode)};\n\nconst __seen = new Set();\nfunction __report(action, accessPath) {\n if (__mode === 'off') return;\n const key = action + ':' + accessPath;\n if (__seen.has(key)) return;\n __seen.add(key);\n\n const traceLines = Array.isArray(__meta.trace) && __meta.trace.length\n ? \"\\\\n\\\\nTrace:\\\\n\" + __meta.trace.map((t, i) => ' ' + (i + 1) + '. ' + String(t)).join('\\\\n')\n : '';\n\n const msg =\n '[import-protection] Mocked import used in dev client\\\\n\\\\n' +\n 'Denied import: \"' + __meta.specifier + '\"\\\\n' +\n 'Importer: ' + __meta.importer + '\\\\n' +\n 'Access: ' + accessPath + ' (' + action + ')' +\n traceLines +\n '\\\\n\\\\n' + ${JSON.stringify(RUNTIME_SUGGESTION_TEXT)};\n\n const err = new Error(msg);\n if (__mode === 'warn') {\n console.warn(err);\n } else {\n console.error(err);\n }\n}\n`\n : ''\n\n // Diagnostic-only traps for primitive coercion, set\n const diagGetTraps = hasDiag\n ? `\n if (prop === Symbol.toPrimitive) {\n return () => {\n __report('toPrimitive', name);\n return '[import-protection mock]';\n };\n }\n if (prop === 'toString' || prop === 'valueOf' || prop === 'toJSON') {\n return () => {\n __report(String(prop), name);\n return '[import-protection mock]';\n };\n }`\n : ''\n\n const applyBody = hasDiag\n ? `__report('call', name + '()');\n return ${fnName}(name + '()');`\n : `return ${fnName}(name + '()');`\n\n const constructBody = hasDiag\n ? `__report('construct', 'new ' + name);\n return ${fnName}('new ' + name);`\n : `return ${fnName}('new ' + name);`\n\n const setTrap = hasDiag\n ? `\n set(_target, prop) {\n __report('set', name + '.' + String(prop));\n return true;\n },`\n : ''\n\n return `\n${preamble}/* @__NO_SIDE_EFFECTS__ */\nfunction ${fnName}(name) {\n const fn = function () {};\n fn.prototype.name = name;\n const children = Object.create(null);\n const proxy = new Proxy(fn, {\n get(_target, prop) {\n if (prop === '__esModule') return true;\n if (prop === 'default') return proxy;\n if (prop === 'caller') return null;\n if (prop === 'then') return (f) => Promise.resolve(f(proxy));\n if (prop === 'catch') return () => Promise.resolve(proxy);\n if (prop === 'finally') return (f) => { f(); return Promise.resolve(proxy); };${diagGetTraps}\n if (typeof prop === 'symbol') return undefined;\n if (!(prop in children)) {\n children[prop] = ${fnName}(name + '.' + prop);\n }\n return children[prop];\n },\n apply() {\n ${applyBody}\n },\n construct() {\n ${constructBody}\n },${setTrap}\n });\n return proxy;\n}\nconst mock = /* @__PURE__ */ ${fnName}('mock');\nexport default mock;\n`\n}\n\nexport function loadSilentMockModule(): { code: string } {\n return { code: generateMockCode() }\n}\n\n/**\n * Filter export names to valid, non-default names.\n */\nfunction filterExportNames(exports: ReadonlyArray<string>): Array<string> {\n return exports.filter((n) => n.length > 0 && n !== 'default')\n}\n\n/**\n * Generate ESM export lines that re-export named properties from `mock`.\n *\n * Produces `export const foo = mock.foo;` for valid identifiers and\n * string-keyed re-exports for non-identifier names.\n */\nfunction generateExportLines(names: ReadonlyArray<string>): Array<string> {\n const lines: Array<string> = []\n const stringExports: Array<{ alias: string; name: string }> = []\n\n for (let i = 0; i < names.length; i++) {\n const n = names[i]!\n if (isValidExportName(n)) {\n lines.push(`export const ${n} = mock.${n};`)\n } else {\n const alias = `__tss_str_${i}`\n lines.push(`const ${alias} = mock[${JSON.stringify(n)}];`)\n stringExports.push({ alias, name: n })\n }\n }\n\n if (stringExports.length > 0) {\n const reexports = stringExports\n .map((s) => `${s.alias} as ${JSON.stringify(s.name)}`)\n .join(', ')\n lines.push(`export { ${reexports} };`)\n }\n\n return lines\n}\n\n/**\n * Generate a self-contained mock module with explicit named exports.\n *\n * Used by the transform hook's \"self-denial\" check: when a denied file\n * (e.g. `.server.ts` in the client environment) is transformed, its entire\n * content is replaced with this mock module. This avoids returning virtual\n * module IDs from `resolveId`, which prevents cross-environment cache\n * contamination from third-party resolver plugins.\n *\n * The generated code is side-effect-free and tree-shakeable.\n */\nexport function generateSelfContainedMockModule(exportNames: Array<string>): {\n code: string\n} {\n const mockCode = generateMockCode()\n const exportLines = generateExportLines(filterExportNames(exportNames))\n\n return {\n code: `${mockCode}\n${exportLines.join('\\n')}\n`,\n }\n}\n\n/**\n * Generate a dev-mode mock module for self-denial transforms.\n *\n * Similar to `loadMockEdgeModule` but takes export names and a runtime ID\n * directly (instead of parsing them from a base64url-encoded payload).\n * Used by the transform hook when a denied file (e.g. `.server.ts` in\n * the client environment) is replaced in dev mode.\n *\n * The generated module imports mock-runtime for runtime diagnostics\n * (error/warn on property access) and re-exports explicit named exports\n * so that `import { foo } from './denied.server'` works.\n */\nexport function generateDevSelfDenialModule(\n exportNames: Array<string>,\n runtimeId: string,\n): { code: string } {\n const names = filterExportNames(exportNames)\n const exportLines = generateExportLines(names)\n\n return {\n code: `import mock from ${JSON.stringify(runtimeId)};\n${exportLines.join('\\n')}\nexport default mock;\n`,\n }\n}\n\nexport function loadMockEdgeModule(encodedPayload: string): { code: string } {\n let payload: { exports?: Array<string>; runtimeId?: string }\n try {\n payload = JSON.parse(fromBase64Url(encodedPayload)) as typeof payload\n } catch {\n payload = { exports: [] }\n }\n const names = filterExportNames(payload.exports ?? [])\n\n const runtimeId: string =\n typeof payload.runtimeId === 'string' && payload.runtimeId.length > 0\n ? payload.runtimeId\n : MOCK_MODULE_ID\n\n const exportLines = generateExportLines(names)\n\n return {\n code: `import mock from ${JSON.stringify(runtimeId)};\n${exportLines.join('\\n')}\nexport default mock;\n`,\n }\n}\n\nexport function loadMockRuntimeModule(encodedPayload: string): {\n code: string\n} {\n let payload: {\n mode?: string\n env?: string\n importer?: string\n specifier?: string\n trace?: Array<unknown>\n }\n try {\n payload = JSON.parse(fromBase64Url(encodedPayload)) as typeof payload\n } catch {\n payload = {}\n }\n\n const mode: 'error' | 'warn' | 'off' =\n payload.mode === 'warn' || payload.mode === 'off' ? payload.mode : 'error'\n\n const meta = {\n env: String(payload.env ?? ''),\n importer: String(payload.importer ?? ''),\n specifier: String(payload.specifier ?? ''),\n trace: Array.isArray(payload.trace) ? payload.trace : [],\n }\n\n return { code: generateMockCode({ meta, mode }) }\n}\n\nconst MARKER_MODULE_RESULT = { code: 'export {}' } as const\n\nexport function loadMarkerModule(): { code: string } {\n return MARKER_MODULE_RESULT\n}\n\nexport function loadResolvedVirtualModule(\n id: string,\n): { code: string } | undefined {\n if (id === RESOLVED_MOCK_MODULE_ID) {\n return loadSilentMockModule()\n }\n\n // Per-violation build mock modules — same silent mock code\n if (id.startsWith(RESOLVED_MOCK_BUILD_PREFIX)) {\n return loadSilentMockModule()\n }\n\n if (id.startsWith(RESOLVED_MOCK_EDGE_PREFIX)) {\n return loadMockEdgeModule(id.slice(RESOLVED_MOCK_EDGE_PREFIX.length))\n }\n\n if (id.startsWith(RESOLVED_MOCK_RUNTIME_PREFIX)) {\n return loadMockRuntimeModule(id.slice(RESOLVED_MOCK_RUNTIME_PREFIX.length))\n }\n\n if (id.startsWith(RESOLVED_MARKER_PREFIX)) {\n return loadMarkerModule()\n }\n\n return undefined\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"virtualModules.js","sources":["../../../src/import-protection-plugin/virtualModules.ts"],"sourcesContent":["import { resolveViteId } from '../utils'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { isValidExportName } from './rewriteDeniedImports'\nimport { CLIENT_ENV_SUGGESTIONS } from './trace'\nimport { VITE_BROWSER_VIRTUAL_PREFIX } from './constants'\nimport { relativizePath } from './utils'\nimport type { ViolationInfo } from './trace'\n\nexport const MOCK_MODULE_ID = 'tanstack-start-import-protection:mock'\nconst RESOLVED_MOCK_MODULE_ID = resolveViteId(MOCK_MODULE_ID)\n\n/**\n * Per-violation mock prefix used in build+error mode.\n * Each deferred violation gets a unique ID so we can check which ones\n * survived tree-shaking in `generateBundle`.\n */\nexport const MOCK_BUILD_PREFIX = 'tanstack-start-import-protection:mock:build:'\nconst RESOLVED_MOCK_BUILD_PREFIX = resolveViteId(MOCK_BUILD_PREFIX)\n\nexport const MOCK_EDGE_PREFIX = 'tanstack-start-import-protection:mock-edge:'\nconst RESOLVED_MOCK_EDGE_PREFIX = resolveViteId(MOCK_EDGE_PREFIX)\n\nexport const MOCK_RUNTIME_PREFIX =\n 'tanstack-start-import-protection:mock-runtime:'\nconst RESOLVED_MOCK_RUNTIME_PREFIX = resolveViteId(MOCK_RUNTIME_PREFIX)\n\nconst MARKER_PREFIX = 'tanstack-start-import-protection:marker:'\nconst RESOLVED_MARKER_PREFIX = resolveViteId(MARKER_PREFIX)\n\nconst RESOLVED_MARKER_SERVER_ONLY = resolveViteId(`${MARKER_PREFIX}server-only`)\nconst RESOLVED_MARKER_CLIENT_ONLY = resolveViteId(`${MARKER_PREFIX}client-only`)\n\nexport function resolvedMarkerVirtualModuleId(\n kind: 'server' | 'client',\n): string {\n return kind === 'server'\n ? RESOLVED_MARKER_SERVER_ONLY\n : RESOLVED_MARKER_CLIENT_ONLY\n}\n\n/**\n * Convenience list for plugin `load` filters/handlers.\n *\n * Vite/Rollup call `load(id)` with the *resolved* virtual id (prefixed by `\\0`).\n * `resolveId(source)` sees the *unresolved* id/prefix (without `\\0`).\n */\nexport function getResolvedVirtualModuleMatchers(): ReadonlyArray<string> {\n return RESOLVED_VIRTUAL_MODULE_MATCHERS\n}\n\nconst RESOLVED_VIRTUAL_MODULE_MATCHERS = [\n RESOLVED_MOCK_MODULE_ID,\n RESOLVED_MOCK_BUILD_PREFIX,\n RESOLVED_MOCK_EDGE_PREFIX,\n RESOLVED_MOCK_RUNTIME_PREFIX,\n RESOLVED_MARKER_PREFIX,\n] as const\n\nconst RESOLVE_PREFIX_PAIRS = [\n [MOCK_EDGE_PREFIX, RESOLVED_MOCK_EDGE_PREFIX],\n [MOCK_RUNTIME_PREFIX, RESOLVED_MOCK_RUNTIME_PREFIX],\n [MOCK_BUILD_PREFIX, RESOLVED_MOCK_BUILD_PREFIX],\n [MARKER_PREFIX, RESOLVED_MARKER_PREFIX],\n] as const\n\n/**\n * Resolve import-protection's internal virtual module IDs.\n *\n * `resolveId(source)` sees *unresolved* ids/prefixes (no `\\0`).\n * Returning a resolved id (with `\\0`) ensures Vite/Rollup route it to `load`.\n */\nexport function resolveInternalVirtualModuleId(\n source: string,\n): string | undefined {\n if (source.startsWith(VITE_BROWSER_VIRTUAL_PREFIX)) {\n return resolveInternalVirtualModuleId(\n `\\0${source.slice(VITE_BROWSER_VIRTUAL_PREFIX.length)}`,\n )\n }\n\n if (source === MOCK_MODULE_ID || source === RESOLVED_MOCK_MODULE_ID) {\n return RESOLVED_MOCK_MODULE_ID\n }\n\n for (const [unresolvedPrefix, resolvedPrefix] of RESOLVE_PREFIX_PAIRS) {\n if (source.startsWith(unresolvedPrefix)) {\n return resolveViteId(source)\n }\n\n if (source.startsWith(resolvedPrefix)) {\n return source\n }\n }\n\n return undefined\n}\n\nfunction toBase64Url(input: string): string {\n return Buffer.from(input, 'utf8').toString('base64url')\n}\n\nfunction fromBase64Url(input: string): string {\n return Buffer.from(input, 'base64url').toString('utf8')\n}\n\ntype MockAccessMode = 'error' | 'warn' | 'off'\n\n/**\n * Compact runtime suggestion text for browser console, derived from\n * {@link CLIENT_ENV_SUGGESTIONS} so there's a single source of truth.\n */\nexport const RUNTIME_SUGGESTION_TEXT =\n 'Fix: ' +\n CLIENT_ENV_SUGGESTIONS.join('. ') +\n '. To disable these runtime diagnostics, set importProtection.mockAccess: \"off\".'\n\nexport function mockRuntimeModuleIdFromViolation(\n info: ViolationInfo,\n mode: MockAccessMode,\n root: string,\n): string {\n if (mode === 'off') return MOCK_MODULE_ID\n if (info.env !== VITE_ENVIRONMENT_NAMES.client) return MOCK_MODULE_ID\n\n const rel = (p: string) => relativizePath(p, root)\n const trace = info.trace.map((s) => {\n const file = rel(s.file)\n if (s.line == null) return file\n return `${file}:${s.line}:${s.column ?? 1}`\n })\n\n const payload = {\n env: info.env,\n importer: info.importer,\n specifier: info.specifier,\n trace,\n mode,\n }\n return `${MOCK_RUNTIME_PREFIX}${toBase64Url(JSON.stringify(payload))}`\n}\n\nexport function makeMockEdgeModuleId(\n exports: Array<string>,\n runtimeId: string,\n): string {\n const payload = { exports, runtimeId }\n return `${MOCK_EDGE_PREFIX}${toBase64Url(JSON.stringify(payload))}`\n}\n\n/**\n * Generate a recursive Proxy-based mock module.\n *\n * When `diagnostics` is provided, the generated code includes a `__report`\n * function that logs runtime warnings/errors when the mock is actually used\n * (property access for primitive coercion, calls, construction, sets).\n *\n * When `diagnostics` is omitted, the mock is completely silent — suitable\n * for base mock modules (e.g. `MOCK_MODULE_ID` or per-violation build mocks)\n * that are consumed by mock-edge modules providing explicit named exports.\n */\nfunction generateMockCode(diagnostics?: {\n meta: {\n env: string\n importer: string\n specifier: string\n trace: Array<unknown>\n }\n mode: 'error' | 'warn' | 'off'\n}): string {\n const fnName = diagnostics ? '__createMock' : 'createMock'\n const hasDiag = !!diagnostics\n\n const preamble = hasDiag\n ? `const __meta = ${JSON.stringify(diagnostics.meta)};\nconst __mode = ${JSON.stringify(diagnostics.mode)};\n\nconst __seen = new Set();\nfunction __report(action, accessPath) {\n if (__mode === 'off') return;\n const key = action + ':' + accessPath;\n if (__seen.has(key)) return;\n __seen.add(key);\n\n const traceLines = Array.isArray(__meta.trace) && __meta.trace.length\n ? \"\\\\n\\\\nTrace:\\\\n\" + __meta.trace.map((t, i) => ' ' + (i + 1) + '. ' + String(t)).join('\\\\n')\n : '';\n\n const msg =\n '[import-protection] Mocked import used in dev client\\\\n\\\\n' +\n 'Denied import: \"' + __meta.specifier + '\"\\\\n' +\n 'Importer: ' + __meta.importer + '\\\\n' +\n 'Access: ' + accessPath + ' (' + action + ')' +\n traceLines +\n '\\\\n\\\\n' + ${JSON.stringify(RUNTIME_SUGGESTION_TEXT)};\n\n const err = new Error(msg);\n if (__mode === 'warn') {\n console.warn(err);\n } else {\n console.error(err);\n }\n}\n`\n : ''\n\n // Diagnostic-only traps for primitive coercion, set\n const diagGetTraps = hasDiag\n ? `\n if (prop === Symbol.toPrimitive) {\n return () => {\n __report('toPrimitive', name);\n return '[import-protection mock]';\n };\n }\n if (prop === 'toString' || prop === 'valueOf' || prop === 'toJSON') {\n return () => {\n __report(String(prop), name);\n return '[import-protection mock]';\n };\n }`\n : ''\n\n const applyBody = hasDiag\n ? `__report('call', name + '()');\n return ${fnName}(name + '()');`\n : `return ${fnName}(name + '()');`\n\n const constructBody = hasDiag\n ? `__report('construct', 'new ' + name);\n return ${fnName}('new ' + name);`\n : `return ${fnName}('new ' + name);`\n\n const setTrap = hasDiag\n ? `\n set(_target, prop) {\n __report('set', name + '.' + String(prop));\n return true;\n },`\n : ''\n\n return `\n${preamble}/* @__NO_SIDE_EFFECTS__ */\nfunction ${fnName}(name) {\n const fn = function () {};\n fn.prototype.name = name;\n const children = Object.create(null);\n const proxy = new Proxy(fn, {\n get(_target, prop) {\n if (prop === '__esModule') return true;\n if (prop === 'default') return proxy;\n if (prop === 'caller') return null;\n if (prop === 'then') return (f) => Promise.resolve(f(proxy));\n if (prop === 'catch') return () => Promise.resolve(proxy);\n if (prop === 'finally') return (f) => { f(); return Promise.resolve(proxy); };${diagGetTraps}\n if (typeof prop === 'symbol') return undefined;\n if (!(prop in children)) {\n children[prop] = ${fnName}(name + '.' + prop);\n }\n return children[prop];\n },\n apply() {\n ${applyBody}\n },\n construct() {\n ${constructBody}\n },${setTrap}\n });\n return proxy;\n}\nconst mock = /* @__PURE__ */ ${fnName}('mock');\nexport default mock;\n`\n}\n\nexport function loadSilentMockModule(): { code: string } {\n return { code: generateMockCode() }\n}\n\n/**\n * Filter export names to valid, non-default names.\n */\nfunction filterExportNames(exports: ReadonlyArray<string>): Array<string> {\n return exports.filter((n) => n.length > 0 && n !== 'default')\n}\n\n/**\n * Generate ESM export lines that re-export named properties from `mock`.\n *\n * Produces `export const foo = mock.foo;` for valid identifiers and\n * string-keyed re-exports for non-identifier names.\n */\nfunction generateExportLines(names: ReadonlyArray<string>): Array<string> {\n const lines: Array<string> = []\n const stringExports: Array<{ alias: string; name: string }> = []\n\n for (let i = 0; i < names.length; i++) {\n const n = names[i]!\n if (isValidExportName(n)) {\n lines.push(`export const ${n} = mock.${n};`)\n } else {\n const alias = `__tss_str_${i}`\n lines.push(`const ${alias} = mock[${JSON.stringify(n)}];`)\n stringExports.push({ alias, name: n })\n }\n }\n\n if (stringExports.length > 0) {\n const reexports = stringExports\n .map((s) => `${s.alias} as ${JSON.stringify(s.name)}`)\n .join(', ')\n lines.push(`export { ${reexports} };`)\n }\n\n return lines\n}\n\n/**\n * Generate a self-contained mock module with explicit named exports.\n *\n * Used by the transform hook's \"self-denial\" check: when a denied file\n * (e.g. `.server.ts` in the client environment) is transformed, its entire\n * content is replaced with this mock module. This avoids returning virtual\n * module IDs from `resolveId`, which prevents cross-environment cache\n * contamination from third-party resolver plugins.\n *\n * The generated code is side-effect-free and tree-shakeable.\n */\nexport function generateSelfContainedMockModule(exportNames: Array<string>): {\n code: string\n} {\n const mockCode = generateMockCode()\n const exportLines = generateExportLines(filterExportNames(exportNames))\n\n return {\n code: `${mockCode}\n${exportLines.join('\\n')}\n`,\n }\n}\n\n/**\n * Generate a dev-mode mock module for self-denial transforms.\n *\n * Similar to `loadMockEdgeModule` but takes export names and a runtime ID\n * directly (instead of parsing them from a base64url-encoded payload).\n * Used by the transform hook when a denied file (e.g. `.server.ts` in\n * the client environment) is replaced in dev mode.\n *\n * The generated module imports mock-runtime for runtime diagnostics\n * (error/warn on property access) and re-exports explicit named exports\n * so that `import { foo } from './denied.server'` works.\n */\nexport function generateDevSelfDenialModule(\n exportNames: Array<string>,\n runtimeId: string,\n): { code: string } {\n const names = filterExportNames(exportNames)\n const exportLines = generateExportLines(names)\n\n return {\n code: `import mock from ${JSON.stringify(runtimeId)};\n${exportLines.join('\\n')}\nexport default mock;\n`,\n }\n}\n\nexport function loadMockEdgeModule(encodedPayload: string): { code: string } {\n let payload: { exports?: Array<string>; runtimeId?: string }\n try {\n payload = JSON.parse(fromBase64Url(encodedPayload)) as typeof payload\n } catch {\n payload = { exports: [] }\n }\n const names = filterExportNames(payload.exports ?? [])\n\n const runtimeId: string =\n typeof payload.runtimeId === 'string' && payload.runtimeId.length > 0\n ? payload.runtimeId\n : MOCK_MODULE_ID\n\n const exportLines = generateExportLines(names)\n\n return {\n code: `import mock from ${JSON.stringify(runtimeId)};\n${exportLines.join('\\n')}\nexport default mock;\n`,\n }\n}\n\nexport function loadMockRuntimeModule(encodedPayload: string): {\n code: string\n} {\n let payload: {\n mode?: string\n env?: string\n importer?: string\n specifier?: string\n trace?: Array<unknown>\n }\n try {\n payload = JSON.parse(fromBase64Url(encodedPayload)) as typeof payload\n } catch {\n payload = {}\n }\n\n const mode: 'error' | 'warn' | 'off' =\n payload.mode === 'warn' || payload.mode === 'off' ? payload.mode : 'error'\n\n const meta = {\n env: String(payload.env ?? ''),\n importer: String(payload.importer ?? ''),\n specifier: String(payload.specifier ?? ''),\n trace: Array.isArray(payload.trace) ? payload.trace : [],\n }\n\n return { code: generateMockCode({ meta, mode }) }\n}\n\nconst MARKER_MODULE_RESULT = { code: 'export {}' } as const\n\nexport function loadMarkerModule(): { code: string } {\n return MARKER_MODULE_RESULT\n}\n\nexport function loadResolvedVirtualModule(\n id: string,\n): { code: string } | undefined {\n if (id === RESOLVED_MOCK_MODULE_ID) {\n return loadSilentMockModule()\n }\n\n // Per-violation build mock modules — same silent mock code\n if (id.startsWith(RESOLVED_MOCK_BUILD_PREFIX)) {\n return loadSilentMockModule()\n }\n\n if (id.startsWith(RESOLVED_MOCK_EDGE_PREFIX)) {\n return loadMockEdgeModule(id.slice(RESOLVED_MOCK_EDGE_PREFIX.length))\n }\n\n if (id.startsWith(RESOLVED_MOCK_RUNTIME_PREFIX)) {\n return loadMockRuntimeModule(id.slice(RESOLVED_MOCK_RUNTIME_PREFIX.length))\n }\n\n if (id.startsWith(RESOLVED_MARKER_PREFIX)) {\n return loadMarkerModule()\n }\n\n return undefined\n}\n"],"names":["exports"],"mappings":"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"}
@@ -284,7 +284,7 @@ class StartCompiler {
284
284
  */
285
285
  extractModuleInfo(ast, id) {
286
286
  const bindings = /* @__PURE__ */ new Map();
287
- const exports = /* @__PURE__ */ new Map();
287
+ const exports$1 = /* @__PURE__ */ new Map();
288
288
  const reExportAllSources = [];
289
289
  for (const node of ast.program.body) {
290
290
  if (t.isImportDeclaration(node)) {
@@ -321,7 +321,7 @@ class StartCompiler {
321
321
  if (t.isVariableDeclaration(node.declaration)) {
322
322
  for (const d of node.declaration.declarations) {
323
323
  if (t.isIdentifier(d.id)) {
324
- exports.set(d.id.name, d.id.name);
324
+ exports$1.set(d.id.name, d.id.name);
325
325
  bindings.set(d.id.name, { type: "var", init: d.init ?? null });
326
326
  }
327
327
  }
@@ -329,11 +329,11 @@ class StartCompiler {
329
329
  }
330
330
  for (const sp of node.specifiers) {
331
331
  if (t.isExportNamespaceSpecifier(sp)) {
332
- exports.set(sp.exported.name, sp.exported.name);
332
+ exports$1.set(sp.exported.name, sp.exported.name);
333
333
  } else if (t.isExportSpecifier(sp)) {
334
334
  const local = sp.local.name;
335
335
  const exported = t.isIdentifier(sp.exported) ? sp.exported.name : sp.exported.value;
336
- exports.set(exported, local);
336
+ exports$1.set(exported, local);
337
337
  if (node.source) {
338
338
  bindings.set(local, {
339
339
  type: "import",
@@ -346,11 +346,11 @@ class StartCompiler {
346
346
  } else if (t.isExportDefaultDeclaration(node)) {
347
347
  const d = node.declaration;
348
348
  if (t.isIdentifier(d)) {
349
- exports.set("default", d.name);
349
+ exports$1.set("default", d.name);
350
350
  } else {
351
351
  const synth = "__default_export__";
352
352
  bindings.set(synth, { type: "var", init: d });
353
- exports.set("default", synth);
353
+ exports$1.set("default", synth);
354
354
  }
355
355
  } else if (t.isExportAllDeclaration(node)) {
356
356
  reExportAllSources.push(node.source.value);
@@ -359,7 +359,7 @@ class StartCompiler {
359
359
  const info = {
360
360
  id,
361
361
  bindings,
362
- exports,
362
+ exports: exports$1,
363
363
  reExportAllSources
364
364
  };
365
365
  this.moduleCache.set(id, info);
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.js","sources":["../../../src/start-compiler-plugin/compiler.ts"],"sourcesContent":["/* eslint-disable import/no-commonjs */\nimport crypto from 'node:crypto'\nimport * as t from '@babel/types'\nimport {\n deadCodeElimination,\n findReferencedIdentifiers,\n generateFromAst,\n parseAst,\n} from '@tanstack/router-utils'\nimport babel from '@babel/core'\nimport { handleCreateServerFn } from './handleCreateServerFn'\nimport { handleCreateMiddleware } from './handleCreateMiddleware'\nimport { handleCreateIsomorphicFn } from './handleCreateIsomorphicFn'\nimport { handleEnvOnlyFn } from './handleEnvOnly'\nimport { handleClientOnlyJSX } from './handleClientOnlyJSX'\nimport type {\n CompilationContext,\n MethodChainPaths,\n RewriteCandidate,\n ServerFn,\n} from './types'\nimport type { CompileStartFrameworkOptions } from '../types'\n\ntype Binding =\n | {\n type: 'import'\n source: string\n importedName: string\n resolvedKind?: Kind\n }\n | {\n type: 'var'\n init: t.Expression | null\n resolvedKind?: Kind\n }\n\ntype Kind = 'None' | `Root` | `Builder` | LookupKind\n\nexport type LookupKind =\n | 'ServerFn'\n | 'Middleware'\n | 'IsomorphicFn'\n | 'ServerOnlyFn'\n | 'ClientOnlyFn'\n | 'ClientOnlyJSX'\n\n// Detection strategy for each kind\ntype MethodChainSetup = {\n type: 'methodChain'\n candidateCallIdentifier: Set<string>\n}\ntype DirectCallSetup = {\n type: 'directCall'\n // The factory function name used to create this kind (e.g., 'createServerOnlyFn')\n factoryName: string\n}\ntype JSXSetup = { type: 'jsx'; componentName: string }\n\nfunction isLookupKind(kind: Kind): kind is LookupKind {\n return kind in LookupSetup\n}\n\nconst LookupSetup: Record<\n LookupKind,\n MethodChainSetup | DirectCallSetup | JSXSetup\n> = {\n ServerFn: {\n type: 'methodChain',\n candidateCallIdentifier: new Set(['handler']),\n },\n Middleware: {\n type: 'methodChain',\n candidateCallIdentifier: new Set(['server', 'client', 'createMiddlewares']),\n },\n IsomorphicFn: {\n type: 'methodChain',\n candidateCallIdentifier: new Set(['server', 'client']),\n },\n ServerOnlyFn: { type: 'directCall', factoryName: 'createServerOnlyFn' },\n ClientOnlyFn: { type: 'directCall', factoryName: 'createClientOnlyFn' },\n ClientOnlyJSX: { type: 'jsx', componentName: 'ClientOnly' },\n}\n\n// Single source of truth for detecting which kinds are present in code\n// These patterns are used for:\n// 1. Pre-scanning code to determine which kinds to look for (before AST parsing)\n// 2. Deriving the plugin's transform code filter\nexport const KindDetectionPatterns: Record<LookupKind, RegExp> = {\n ServerFn: /\\bcreateServerFn\\b|\\.\\s*handler\\s*\\(/,\n Middleware: /createMiddleware/,\n IsomorphicFn: /createIsomorphicFn/,\n ServerOnlyFn: /createServerOnlyFn/,\n ClientOnlyFn: /createClientOnlyFn/,\n ClientOnlyJSX: /<ClientOnly|import\\s*\\{[^}]*\\bClientOnly\\b/,\n}\n\n// Which kinds are valid for each environment\nexport const LookupKindsPerEnv: Record<'client' | 'server', Set<LookupKind>> = {\n client: new Set([\n 'Middleware',\n 'ServerFn',\n 'IsomorphicFn',\n 'ServerOnlyFn',\n 'ClientOnlyFn',\n ] as const),\n server: new Set([\n 'ServerFn',\n 'IsomorphicFn',\n 'ServerOnlyFn',\n 'ClientOnlyFn',\n 'ClientOnlyJSX', // Only transform on server to remove children\n ] as const),\n}\n\n/**\n * Handler type for processing candidates of a specific kind.\n * The kind is passed as the third argument to allow shared handlers (like handleEnvOnlyFn).\n */\ntype KindHandler = (\n candidates: Array<RewriteCandidate>,\n context: CompilationContext,\n kind: LookupKind,\n) => void\n\n/**\n * Registry mapping each LookupKind to its handler function.\n * When adding a new kind, add its handler here.\n */\nconst KindHandlers: Record<\n Exclude<LookupKind, 'ClientOnlyJSX'>,\n KindHandler\n> = {\n ServerFn: handleCreateServerFn,\n Middleware: handleCreateMiddleware,\n IsomorphicFn: handleCreateIsomorphicFn,\n ServerOnlyFn: handleEnvOnlyFn,\n ClientOnlyFn: handleEnvOnlyFn,\n // ClientOnlyJSX is handled separately via JSX traversal, not here\n}\n\n// All lookup kinds as an array for iteration with proper typing\nconst AllLookupKinds = Object.keys(LookupSetup) as Array<LookupKind>\n\n/**\n * Detects which LookupKinds are present in the code using string matching.\n * This is a fast pre-scan before AST parsing to limit the work done during compilation.\n */\nexport function detectKindsInCode(\n code: string,\n env: 'client' | 'server',\n): Set<LookupKind> {\n const detected = new Set<LookupKind>()\n const validForEnv = LookupKindsPerEnv[env]\n\n for (const kind of AllLookupKinds) {\n if (validForEnv.has(kind) && KindDetectionPatterns[kind].test(code)) {\n detected.add(kind)\n }\n }\n\n return detected\n}\n\n// Pre-computed map: identifier name -> Set<LookupKind> for fast candidate detection (method chain only)\n// Multiple kinds can share the same identifier (e.g., 'server' and 'client' are used by both Middleware and IsomorphicFn)\nconst IdentifierToKinds = new Map<string, Set<LookupKind>>()\nfor (const kind of AllLookupKinds) {\n const setup = LookupSetup[kind]\n if (setup.type === 'methodChain') {\n for (const id of setup.candidateCallIdentifier) {\n let kinds = IdentifierToKinds.get(id)\n if (!kinds) {\n kinds = new Set()\n IdentifierToKinds.set(id, kinds)\n }\n kinds.add(kind)\n }\n }\n}\n\n// Factory function names for direct call patterns.\n// Used to filter nested candidates - we only want to include actual factory calls,\n// not invocations of already-created functions (e.g., `myServerFn()` should NOT be a candidate)\nconst DirectCallFactoryNames = new Set<string>()\nfor (const kind of AllLookupKinds) {\n const setup = LookupSetup[kind]\n if (setup.type === 'directCall') {\n DirectCallFactoryNames.add(setup.factoryName)\n }\n}\n\nexport type LookupConfig = {\n libName: string\n rootExport: string\n kind: LookupKind | 'Root' // 'Root' for builder pattern, LookupKind for direct call\n}\n\ninterface ModuleInfo {\n id: string\n bindings: Map<string, Binding>\n // Maps exported name → local binding name\n exports: Map<string, string>\n // Track `export * from './module'` declarations for re-export resolution\n reExportAllSources: Array<string>\n}\n\n/**\n * Computes whether any file kinds need direct-call candidate detection.\n * This applies to directCall types (ServerOnlyFn, ClientOnlyFn).\n */\nfunction needsDirectCallDetection(kinds: Set<LookupKind>): boolean {\n for (const kind of kinds) {\n if (LookupSetup[kind].type === 'directCall') {\n return true\n }\n }\n return false\n}\n\n/**\n * Checks if all kinds in the set are guaranteed to be top-level only.\n * Only ServerFn is always declared at module level (must be assigned to a variable).\n * Middleware, IsomorphicFn, ServerOnlyFn, ClientOnlyFn can be nested inside functions.\n * When all kinds are top-level-only, we can use a fast scan instead of full traversal.\n */\nfunction areAllKindsTopLevelOnly(kinds: Set<LookupKind>): boolean {\n return kinds.size === 1 && kinds.has('ServerFn')\n}\n\n/**\n * Checks if we need to detect JSX elements (e.g., <ClientOnly>).\n */\nfunction needsJSXDetection(kinds: Set<LookupKind>): boolean {\n for (const kind of kinds) {\n if (LookupSetup[kind].type === 'jsx') {\n return true\n }\n }\n return false\n}\n\n/**\n * Checks if a CallExpression is a direct-call candidate for NESTED detection.\n * Returns true if the callee is a known factory function name.\n * This is stricter than top-level detection because we need to filter out\n * invocations of existing server functions (e.g., `myServerFn()`).\n */\nfunction isNestedDirectCallCandidate(node: t.CallExpression): boolean {\n let calleeName: string | undefined\n if (t.isIdentifier(node.callee)) {\n calleeName = node.callee.name\n } else if (\n t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.property)\n ) {\n calleeName = node.callee.property.name\n }\n return calleeName !== undefined && DirectCallFactoryNames.has(calleeName)\n}\n\n/**\n * Checks if a CallExpression path is a top-level direct-call candidate.\n * Top-level means the call is the init of a VariableDeclarator at program level.\n * We accept any simple identifier call or namespace call at top level\n * (e.g., `createServerOnlyFn()`, `TanStackStart.createServerOnlyFn()`) and let\n * resolution verify it. This handles renamed imports.\n */\nfunction isTopLevelDirectCallCandidate(\n path: babel.NodePath<t.CallExpression>,\n): boolean {\n const node = path.node\n\n // Must be a simple identifier call or namespace call\n const isSimpleCall =\n t.isIdentifier(node.callee) ||\n (t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.object) &&\n t.isIdentifier(node.callee.property))\n\n if (!isSimpleCall) {\n return false\n }\n\n // Must be top-level: VariableDeclarator -> VariableDeclaration -> Program\n const parent = path.parent\n if (!t.isVariableDeclarator(parent) || parent.init !== node) {\n return false\n }\n const grandParent = path.parentPath.parent\n if (!t.isVariableDeclaration(grandParent)) {\n return false\n }\n return t.isProgram(path.parentPath.parentPath?.parent)\n}\n\nexport class StartCompiler {\n private moduleCache = new Map<string, ModuleInfo>()\n private initialized = false\n private validLookupKinds: Set<LookupKind>\n private resolveIdCache = new Map<string, string | null>()\n private exportResolutionCache = new Map<\n string,\n Map<string, { moduleInfo: ModuleInfo; binding: Binding } | null>\n >()\n // Fast lookup for direct imports from known libraries (e.g., '@tanstack/react-start')\n // Maps: libName → (exportName → Kind)\n // This allows O(1) resolution for the common case without async resolveId calls\n private knownRootImports = new Map<string, Map<string, Kind>>()\n\n // For generating unique function IDs in production builds\n private entryIdToFunctionId = new Map<string, string>()\n private functionIds = new Set<string>()\n\n // Cached root path with trailing slash for dev mode function ID generation\n private _rootWithTrailingSlash: string | undefined\n\n constructor(\n private options: {\n env: 'client' | 'server'\n envName: string\n root: string\n lookupConfigurations: Array<LookupConfig>\n lookupKinds: Set<LookupKind>\n loadModule: (id: string) => Promise<void>\n resolveId: (id: string, importer?: string) => Promise<string | null>\n /**\n * In 'build' mode, resolution results are cached for performance.\n * In 'dev' mode (default), caching is disabled to avoid invalidation complexity with HMR.\n */\n mode?: 'dev' | 'build'\n /**\n * The framework being used (e.g., 'react', 'solid').\n */\n framework: CompileStartFrameworkOptions\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n /**\n * Custom function ID generator (optional, defaults to hash-based).\n */\n generateFunctionId?: (opts: {\n filename: string\n functionName: string\n }) => string | undefined\n /**\n * Callback when server functions are discovered.\n * Called after each file is compiled with its new functions.\n */\n onServerFnsById?: (d: Record<string, ServerFn>) => void\n /**\n * Returns the currently known server functions from previous builds.\n * Used by server callers to look up canonical extracted filenames.\n */\n getKnownServerFns?: () => Record<string, ServerFn>\n },\n ) {\n this.validLookupKinds = options.lookupKinds\n }\n\n /**\n * Generates a unique function ID for a server function.\n * In dev mode, uses a base64-encoded JSON with file path and export name.\n * In build mode, uses SHA256 hash or custom generator.\n */\n private generateFunctionId(opts: {\n filename: string\n functionName: string\n extractedFilename: string\n }): string {\n if (this.mode === 'dev') {\n // In dev, encode the file path and export name for direct lookup\n let file = opts.extractedFilename\n if (opts.extractedFilename.startsWith(this.rootWithTrailingSlash)) {\n file = opts.extractedFilename.slice(this.rootWithTrailingSlash.length)\n }\n file = `/@id/${file}`\n\n const serverFn = {\n file,\n export: opts.functionName,\n }\n return Buffer.from(JSON.stringify(serverFn), 'utf8').toString('base64url')\n }\n\n // Production build: use custom generator or hash\n const entryId = `${opts.filename}--${opts.functionName}`\n let functionId = this.entryIdToFunctionId.get(entryId)\n if (functionId === undefined) {\n if (this.options.generateFunctionId) {\n functionId = this.options.generateFunctionId({\n filename: opts.filename,\n functionName: opts.functionName,\n })\n }\n if (!functionId) {\n functionId = crypto.createHash('sha256').update(entryId).digest('hex')\n }\n // Deduplicate in case the generated id conflicts with an existing id\n if (this.functionIds.has(functionId)) {\n let deduplicatedId\n let iteration = 0\n do {\n deduplicatedId = `${functionId}_${++iteration}`\n } while (this.functionIds.has(deduplicatedId))\n functionId = deduplicatedId\n }\n this.entryIdToFunctionId.set(entryId, functionId)\n this.functionIds.add(functionId)\n }\n return functionId\n }\n\n private get mode(): 'dev' | 'build' {\n return this.options.mode ?? 'dev'\n }\n\n private get rootWithTrailingSlash(): string {\n if (this._rootWithTrailingSlash === undefined) {\n this._rootWithTrailingSlash = this.options.root.endsWith('/')\n ? this.options.root\n : `${this.options.root}/`\n }\n return this._rootWithTrailingSlash\n }\n\n private async resolveIdCached(id: string, importer?: string) {\n if (this.mode === 'dev') {\n return this.options.resolveId(id, importer)\n }\n\n const cacheKey = importer ? `${importer}::${id}` : id\n const cached = this.resolveIdCache.get(cacheKey)\n if (cached !== undefined) {\n return cached\n }\n const resolved = await this.options.resolveId(id, importer)\n this.resolveIdCache.set(cacheKey, resolved)\n return resolved\n }\n\n private getExportResolutionCache(moduleId: string) {\n let cache = this.exportResolutionCache.get(moduleId)\n if (!cache) {\n cache = new Map()\n this.exportResolutionCache.set(moduleId, cache)\n }\n return cache\n }\n\n private async init() {\n // Register internal stub package exports for recognition.\n // These don't need module resolution - only the knownRootImports fast path.\n this.knownRootImports.set(\n '@tanstack/start-fn-stubs',\n new Map<string, Kind>([\n ['createIsomorphicFn', 'IsomorphicFn'],\n ['createServerOnlyFn', 'ServerOnlyFn'],\n ['createClientOnlyFn', 'ClientOnlyFn'],\n ]),\n )\n\n await Promise.all(\n this.options.lookupConfigurations.map(async (config) => {\n // Populate the fast lookup map for direct imports (by package name)\n // This allows O(1) recognition of imports from known packages.\n let libExports = this.knownRootImports.get(config.libName)\n if (!libExports) {\n libExports = new Map()\n this.knownRootImports.set(config.libName, libExports)\n }\n libExports.set(config.rootExport, config.kind)\n\n // For JSX lookups (e.g., ClientOnlyJSX), we only need the knownRootImports\n // fast path to verify imports. Skip module resolution which may fail if\n // the package isn't a direct dependency (e.g., @tanstack/react-router from\n // within start-plugin-core).\n if (config.kind !== 'Root') {\n const setup = LookupSetup[config.kind]\n if (setup.type === 'jsx') {\n return\n }\n }\n\n const libId = await this.resolveIdCached(config.libName)\n if (!libId) {\n throw new Error(`could not resolve \"${config.libName}\"`)\n }\n let rootModule = this.moduleCache.get(libId)\n if (!rootModule) {\n // insert root binding\n rootModule = {\n bindings: new Map(),\n exports: new Map(),\n id: libId,\n reExportAllSources: [],\n }\n this.moduleCache.set(libId, rootModule)\n }\n\n rootModule.exports.set(config.rootExport, config.rootExport)\n rootModule.exports.set('*', config.rootExport)\n rootModule.bindings.set(config.rootExport, {\n type: 'var',\n init: null, // Not needed since resolvedKind is set\n resolvedKind: config.kind satisfies Kind,\n })\n this.moduleCache.set(libId, rootModule)\n }),\n )\n\n this.initialized = true\n }\n\n /**\n * Extracts bindings and exports from an already-parsed AST.\n * This is the core logic shared by ingestModule and ingestModuleFromAst.\n */\n private extractModuleInfo(\n ast: ReturnType<typeof parseAst>,\n id: string,\n ): ModuleInfo {\n const bindings = new Map<string, Binding>()\n const exports = new Map<string, string>()\n const reExportAllSources: Array<string> = []\n\n // we are only interested in top-level bindings, hence we don't traverse the AST\n // instead we only iterate over the program body\n for (const node of ast.program.body) {\n if (t.isImportDeclaration(node)) {\n const source = node.source.value\n for (const s of node.specifiers) {\n if (t.isImportSpecifier(s)) {\n const importedName = t.isIdentifier(s.imported)\n ? s.imported.name\n : s.imported.value\n bindings.set(s.local.name, { type: 'import', source, importedName })\n } else if (t.isImportDefaultSpecifier(s)) {\n bindings.set(s.local.name, {\n type: 'import',\n source,\n importedName: 'default',\n })\n } else if (t.isImportNamespaceSpecifier(s)) {\n bindings.set(s.local.name, {\n type: 'import',\n source,\n importedName: '*',\n })\n }\n }\n } else if (t.isVariableDeclaration(node)) {\n for (const decl of node.declarations) {\n if (t.isIdentifier(decl.id)) {\n bindings.set(decl.id.name, {\n type: 'var',\n init: decl.init ?? null,\n })\n }\n }\n } else if (t.isExportNamedDeclaration(node)) {\n // export const foo = ...\n if (node.declaration) {\n if (t.isVariableDeclaration(node.declaration)) {\n for (const d of node.declaration.declarations) {\n if (t.isIdentifier(d.id)) {\n exports.set(d.id.name, d.id.name)\n bindings.set(d.id.name, { type: 'var', init: d.init ?? null })\n }\n }\n }\n }\n for (const sp of node.specifiers) {\n if (t.isExportNamespaceSpecifier(sp)) {\n exports.set(sp.exported.name, sp.exported.name)\n }\n // export { local as exported }\n else if (t.isExportSpecifier(sp)) {\n const local = sp.local.name\n const exported = t.isIdentifier(sp.exported)\n ? sp.exported.name\n : sp.exported.value\n exports.set(exported, local)\n\n // When re-exporting from another module (export { foo } from './module'),\n // create an import binding so the server function can be resolved\n if (node.source) {\n bindings.set(local, {\n type: 'import',\n source: node.source.value,\n importedName: local,\n })\n }\n }\n }\n } else if (t.isExportDefaultDeclaration(node)) {\n const d = node.declaration\n if (t.isIdentifier(d)) {\n exports.set('default', d.name)\n } else {\n const synth = '__default_export__'\n bindings.set(synth, { type: 'var', init: d as t.Expression })\n exports.set('default', synth)\n }\n } else if (t.isExportAllDeclaration(node)) {\n // Handle `export * from './module'` syntax\n // Track the source so we can look up exports from it when needed\n reExportAllSources.push(node.source.value)\n }\n }\n\n const info: ModuleInfo = {\n id,\n bindings,\n exports,\n reExportAllSources,\n }\n this.moduleCache.set(id, info)\n return info\n }\n\n public ingestModule({ code, id }: { code: string; id: string }) {\n const ast = parseAst({ code })\n const info = this.extractModuleInfo(ast, id)\n return { info, ast }\n }\n\n public invalidateModule(id: string) {\n // Note: Resolution caches (resolveIdCache, exportResolutionCache) are only\n // used in build mode where there's no HMR. In dev mode, caching is disabled,\n // so we only need to invalidate the moduleCache here.\n return this.moduleCache.delete(id)\n }\n\n public async compile({\n code,\n id,\n detectedKinds,\n }: {\n code: string\n id: string\n /** Pre-detected kinds present in this file. If not provided, all valid kinds are checked. */\n detectedKinds?: Set<LookupKind>\n }) {\n if (!this.initialized) {\n await this.init()\n }\n\n // Use detected kinds if provided, otherwise fall back to all valid kinds for this env\n const fileKinds = detectedKinds\n ? new Set([...detectedKinds].filter((k) => this.validLookupKinds.has(k)))\n : this.validLookupKinds\n\n // Early exit if no kinds to process\n if (fileKinds.size === 0) {\n return null\n }\n\n const checkDirectCalls = needsDirectCallDetection(fileKinds)\n // Optimization: ServerFn is always a top-level declaration (must be assigned to a variable).\n // If the file only has ServerFn, we can skip full AST traversal and only visit\n // the specific top-level declarations that have candidates.\n const canUseFastPath = areAllKindsTopLevelOnly(fileKinds)\n\n // Always parse and extract module info upfront.\n // This ensures the module is cached for import resolution even if no candidates are found.\n const { ast } = this.ingestModule({ code, id })\n\n // Single-pass traversal to:\n // 1. Collect candidate paths (only candidates, not all CallExpressions)\n // 2. Build a map for looking up paths of nested calls in method chains\n const candidatePaths: Array<babel.NodePath<t.CallExpression>> = []\n // Map for nested chain lookup - only populated for CallExpressions that are\n // part of a method chain (callee.object is a CallExpression)\n const chainCallPaths = new Map<\n t.CallExpression,\n babel.NodePath<t.CallExpression>\n >()\n\n // JSX candidates (e.g., <ClientOnly>)\n const jsxCandidatePaths: Array<babel.NodePath<t.JSXElement>> = []\n const checkJSX = needsJSXDetection(fileKinds)\n // Get module info that was just cached by ingestModule\n const moduleInfo = this.moduleCache.get(id)!\n\n if (canUseFastPath) {\n // Fast path: only visit top-level statements that have potential candidates\n\n // Collect indices of top-level statements that contain candidates\n const candidateIndices: Array<number> = []\n for (let i = 0; i < ast.program.body.length; i++) {\n const node = ast.program.body[i]!\n let declarations: Array<t.VariableDeclarator> | undefined\n\n if (t.isVariableDeclaration(node)) {\n declarations = node.declarations\n } else if (t.isExportNamedDeclaration(node) && node.declaration) {\n if (t.isVariableDeclaration(node.declaration)) {\n declarations = node.declaration.declarations\n }\n }\n\n if (declarations) {\n for (const decl of declarations) {\n if (decl.init && t.isCallExpression(decl.init)) {\n if (isMethodChainCandidate(decl.init, fileKinds)) {\n candidateIndices.push(i)\n break // Only need to mark this statement once\n }\n }\n }\n }\n }\n\n // Early exit: no potential candidates found at top level\n if (candidateIndices.length === 0) {\n return null\n }\n\n // Targeted traversal: only visit the specific statements that have candidates\n // This is much faster than traversing the entire AST\n babel.traverse(ast, {\n Program(programPath) {\n const bodyPaths = programPath.get('body')\n for (const idx of candidateIndices) {\n const stmtPath = bodyPaths[idx]\n if (!stmtPath) continue\n\n // Traverse only this statement's subtree\n stmtPath.traverse({\n CallExpression(path) {\n const node = path.node\n const parent = path.parent\n\n // Check if this call is part of a larger chain (inner call)\n if (\n t.isMemberExpression(parent) &&\n t.isCallExpression(path.parentPath.parent)\n ) {\n chainCallPaths.set(node, path)\n return\n }\n\n // Method chain pattern\n if (isMethodChainCandidate(node, fileKinds)) {\n candidatePaths.push(path)\n }\n },\n })\n }\n // Stop traversal after processing Program\n programPath.stop()\n },\n })\n } else {\n // Normal path: full traversal for non-fast-path kinds\n babel.traverse(ast, {\n CallExpression: (path) => {\n const node = path.node\n const parent = path.parent\n\n // Check if this call is part of a larger chain (inner call)\n // If so, store it for method chain lookup but don't treat as candidate\n if (\n t.isMemberExpression(parent) &&\n t.isCallExpression(path.parentPath.parent)\n ) {\n // This is an inner call in a chain - store for later lookup\n chainCallPaths.set(node, path)\n return\n }\n\n // Pattern 1: Method chain pattern (.handler(), .server(), .client(), etc.)\n if (isMethodChainCandidate(node, fileKinds)) {\n candidatePaths.push(path)\n return\n }\n\n // Pattern 2: Direct call pattern\n if (checkDirectCalls) {\n if (isTopLevelDirectCallCandidate(path)) {\n candidatePaths.push(path)\n } else if (isNestedDirectCallCandidate(node)) {\n candidatePaths.push(path)\n }\n }\n },\n // Pattern 3: JSX element pattern (e.g., <ClientOnly>)\n // Collect JSX elements where the component is imported from a known package\n // and resolves to a JSX kind (e.g., ClientOnly from @tanstack/react-router)\n JSXElement: (path) => {\n if (!checkJSX) return\n\n const openingElement = path.node.openingElement\n const nameNode = openingElement.name\n\n // Only handle simple identifier names (not namespaced or member expressions)\n if (!t.isJSXIdentifier(nameNode)) return\n\n const componentName = nameNode.name\n const binding = moduleInfo.bindings.get(componentName)\n\n // Must be an import binding from a known package\n if (!binding || binding.type !== 'import') return\n\n // Verify the import source is a known TanStack router package\n const knownExports = this.knownRootImports.get(binding.source)\n if (!knownExports) return\n\n // Verify the imported name resolves to a JSX kind (e.g., ClientOnlyJSX)\n const kind = knownExports.get(binding.importedName)\n if (kind !== 'ClientOnlyJSX') return\n\n jsxCandidatePaths.push(path)\n },\n })\n }\n\n if (candidatePaths.length === 0 && jsxCandidatePaths.length === 0) {\n return null\n }\n\n // Resolve all candidates in parallel to determine their kinds\n const resolvedCandidates = await Promise.all(\n candidatePaths.map(async (path) => ({\n path,\n kind: await this.resolveExprKind(path.node, id),\n })),\n )\n\n // Filter to valid candidates\n const validCandidates = resolvedCandidates.filter(({ kind }) =>\n this.validLookupKinds.has(kind as Exclude<LookupKind, 'ClientOnlyJSX'>),\n ) as Array<{\n path: babel.NodePath<t.CallExpression>\n kind: Exclude<LookupKind, 'ClientOnlyJSX'>\n }>\n\n if (validCandidates.length === 0 && jsxCandidatePaths.length === 0) {\n return null\n }\n\n // Process valid candidates to collect method chains\n const pathsToRewrite: Array<{\n path: babel.NodePath<t.CallExpression>\n kind: Exclude<LookupKind, 'ClientOnlyJSX'>\n methodChain: MethodChainPaths\n }> = []\n\n for (const { path, kind } of validCandidates) {\n const node = path.node\n\n // Collect method chain paths by walking DOWN from root through the chain\n const methodChain: MethodChainPaths = {\n middleware: null,\n inputValidator: null,\n handler: null,\n server: null,\n client: null,\n }\n\n // Walk down the call chain using nodes, look up paths from map\n let currentNode: t.CallExpression = node\n let currentPath: babel.NodePath<t.CallExpression> = path\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n const callee = currentNode.callee\n if (!t.isMemberExpression(callee)) {\n break\n }\n\n // Record method chain path if it's a known method\n if (t.isIdentifier(callee.property)) {\n const name = callee.property.name as keyof MethodChainPaths\n if (name in methodChain) {\n // Get first argument path\n const args = currentPath.get('arguments')\n const firstArgPath =\n Array.isArray(args) && args.length > 0 ? (args[0] ?? null) : null\n methodChain[name] = {\n callPath: currentPath,\n firstArgPath,\n }\n }\n }\n\n // Move to the inner call (the object of the member expression)\n if (!t.isCallExpression(callee.object)) {\n break\n }\n currentNode = callee.object\n // Look up path from chain map, or use candidate path if not found\n const nextPath = chainCallPaths.get(currentNode)\n if (!nextPath) {\n break\n }\n currentPath = nextPath\n }\n\n pathsToRewrite.push({ path, kind, methodChain })\n }\n\n const refIdents = findReferencedIdentifiers(ast)\n\n const context: CompilationContext = {\n ast,\n id,\n code,\n env: this.options.env,\n envName: this.options.envName,\n root: this.options.root,\n framework: this.options.framework,\n providerEnvName: this.options.providerEnvName,\n\n generateFunctionId: (opts) => this.generateFunctionId(opts),\n getKnownServerFns: () => this.options.getKnownServerFns?.() ?? {},\n onServerFnsById: this.options.onServerFnsById,\n }\n\n // Group candidates by kind for batch processing\n const candidatesByKind = new Map<\n Exclude<LookupKind, 'ClientOnlyJSX'>,\n Array<RewriteCandidate>\n >()\n\n for (const { path: candidatePath, kind, methodChain } of pathsToRewrite) {\n const candidate: RewriteCandidate = { path: candidatePath, methodChain }\n const existing = candidatesByKind.get(kind)\n if (existing) {\n existing.push(candidate)\n } else {\n candidatesByKind.set(kind, [candidate])\n }\n }\n\n // Process each kind using its registered handler\n for (const [kind, candidates] of candidatesByKind) {\n const handler = KindHandlers[kind]\n handler(candidates, context, kind)\n }\n\n // Handle JSX candidates (e.g., <ClientOnly>)\n // Validation was already done during traversal - just call the handler\n for (const jsxPath of jsxCandidatePaths) {\n handleClientOnlyJSX(jsxPath, { env: 'server' })\n }\n\n deadCodeElimination(ast, refIdents)\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n sourceFileName: id,\n filename: id,\n })\n\n // @babel/generator does not populate sourcesContent because it only has\n // the AST, not the original text. Without this, Vite's composed\n // sourcemap omits the original source, causing downstream consumers\n // (e.g. import-protection snippet display) to fall back to the shorter\n // compiled output and fail to resolve original line numbers.\n if (result.map) {\n result.map.sourcesContent = [code]\n }\n\n return result\n }\n\n private async resolveIdentifierKind(\n ident: string,\n id: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n const info = await this.getModuleInfo(id)\n\n const binding = info.bindings.get(ident)\n if (!binding) {\n return 'None'\n }\n if (binding.resolvedKind) {\n return binding.resolvedKind\n }\n\n // TODO improve cycle detection? should we throw here instead of returning 'None'?\n // prevent cycles\n const vKey = `${id}:${ident}`\n if (visited.has(vKey)) {\n return 'None'\n }\n visited.add(vKey)\n\n const resolvedKind = await this.resolveBindingKind(binding, id, visited)\n binding.resolvedKind = resolvedKind\n return resolvedKind\n }\n\n /**\n * Recursively find an export in a module, following `export * from` chains.\n * Returns the module info and binding if found, or undefined if not found.\n */\n private async findExportInModule(\n moduleInfo: ModuleInfo,\n exportName: string,\n visitedModules = new Set<string>(),\n ): Promise<{ moduleInfo: ModuleInfo; binding: Binding } | undefined> {\n const isBuildMode = this.mode === 'build'\n\n // Check cache first (only for top-level calls in build mode)\n if (isBuildMode && visitedModules.size === 0) {\n const moduleCache = this.exportResolutionCache.get(moduleInfo.id)\n if (moduleCache) {\n const cached = moduleCache.get(exportName)\n if (cached !== undefined) {\n return cached ?? undefined\n }\n }\n }\n\n // Prevent infinite loops in circular re-exports\n if (visitedModules.has(moduleInfo.id)) {\n return undefined\n }\n visitedModules.add(moduleInfo.id)\n\n // First check direct exports\n const localBindingName = moduleInfo.exports.get(exportName)\n if (localBindingName) {\n const binding = moduleInfo.bindings.get(localBindingName)\n if (binding) {\n const result = { moduleInfo, binding }\n // Cache the result (build mode only)\n if (isBuildMode) {\n this.getExportResolutionCache(moduleInfo.id).set(exportName, result)\n }\n return result\n }\n }\n\n // If not found, recursively check re-export-all sources in parallel\n // Valid code won't have duplicate exports across chains, so first match wins\n if (moduleInfo.reExportAllSources.length > 0) {\n const results = await Promise.all(\n moduleInfo.reExportAllSources.map(async (reExportSource) => {\n const reExportTarget = await this.resolveIdCached(\n reExportSource,\n moduleInfo.id,\n )\n\n if (reExportTarget) {\n const reExportModule = await this.getModuleInfo(reExportTarget)\n return this.findExportInModule(\n reExportModule,\n exportName,\n visitedModules,\n )\n }\n return undefined\n }),\n )\n // Return the first valid result\n for (const result of results) {\n if (result) {\n // Cache the result (build mode only)\n if (isBuildMode) {\n this.getExportResolutionCache(moduleInfo.id).set(exportName, result)\n }\n return result\n }\n }\n }\n\n // Cache negative result (build mode only)\n if (isBuildMode) {\n this.getExportResolutionCache(moduleInfo.id).set(exportName, null)\n }\n return undefined\n }\n\n private async resolveBindingKind(\n binding: Binding,\n fileId: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n if (binding.resolvedKind) {\n return binding.resolvedKind\n }\n if (binding.type === 'import') {\n // Fast path: check if this is a direct import from a known library\n // (e.g., import { createServerFn } from '@tanstack/react-start')\n // This avoids async resolveId calls for the common case\n const knownExports = this.knownRootImports.get(binding.source)\n if (knownExports) {\n const kind = knownExports.get(binding.importedName)\n if (kind) {\n binding.resolvedKind = kind\n return kind\n }\n }\n\n // Slow path: resolve through the module graph\n const target = await this.resolveIdCached(binding.source, fileId)\n if (!target) {\n return 'None'\n }\n\n const importedModule = await this.getModuleInfo(target)\n\n // Find the export, recursively searching through export * from chains\n const found = await this.findExportInModule(\n importedModule,\n binding.importedName,\n )\n\n if (!found) {\n return 'None'\n }\n\n const { moduleInfo: foundModule, binding: foundBinding } = found\n\n if (foundBinding.resolvedKind) {\n return foundBinding.resolvedKind\n }\n\n const resolvedKind = await this.resolveBindingKind(\n foundBinding,\n foundModule.id,\n visited,\n )\n foundBinding.resolvedKind = resolvedKind\n return resolvedKind\n }\n\n const resolvedKind = await this.resolveExprKind(\n binding.init,\n fileId,\n visited,\n )\n // When a var binding's init is a call to a directCall factory\n // (e.g., `const myFn = createServerOnlyFn(() => ...)`), the binding holds\n // the RESULT of the factory, not the factory itself. Clear the kind so\n // `myFn()` isn't incorrectly matched as a directCall candidate.\n // We only clear when the init is a CallExpression — an alias like\n // `const createSO = createServerOnlyFn` should still propagate the kind.\n if (\n isLookupKind(resolvedKind) &&\n LookupSetup[resolvedKind].type === 'directCall' &&\n binding.init &&\n t.isCallExpression(binding.init)\n ) {\n binding.resolvedKind = 'None'\n return 'None'\n }\n binding.resolvedKind = resolvedKind\n return resolvedKind\n }\n\n private async resolveExprKind(\n expr: t.Expression | null,\n fileId: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n if (!expr) {\n return 'None'\n }\n\n // Unwrap common TypeScript/parenthesized wrappers first for efficiency\n while (\n t.isTSAsExpression(expr) ||\n t.isTSNonNullExpression(expr) ||\n t.isParenthesizedExpression(expr)\n ) {\n expr = expr.expression\n }\n\n let result: Kind = 'None'\n\n if (t.isCallExpression(expr)) {\n if (!t.isExpression(expr.callee)) {\n return 'None'\n }\n const calleeKind = await this.resolveCalleeKind(\n expr.callee,\n fileId,\n visited,\n )\n if (calleeKind === 'Root' || calleeKind === 'Builder') {\n return 'Builder'\n }\n // For method chain patterns (callee is MemberExpression like .server() or .client()),\n // return the resolved kind if valid\n if (t.isMemberExpression(expr.callee)) {\n if (this.validLookupKinds.has(calleeKind as LookupKind)) {\n return calleeKind\n }\n }\n // For direct calls (callee is Identifier like createServerOnlyFn()),\n // trust calleeKind if it resolved to a valid LookupKind. This means\n // resolveBindingKind successfully traced the import back to\n // @tanstack/start-fn-stubs (via fast path or slow path through re-exports).\n // This handles both direct imports from @tanstack/react-start and imports\n // from intermediate packages that re-export from @tanstack/start-client-core.\n if (t.isIdentifier(expr.callee)) {\n if (this.validLookupKinds.has(calleeKind as LookupKind)) {\n return calleeKind\n }\n }\n } else if (t.isMemberExpression(expr) && t.isIdentifier(expr.property)) {\n result = await this.resolveCalleeKind(expr.object, fileId, visited)\n }\n\n if (result === 'None' && t.isIdentifier(expr)) {\n result = await this.resolveIdentifierKind(expr.name, fileId, visited)\n }\n\n return result\n }\n\n private async resolveCalleeKind(\n callee: t.Expression,\n fileId: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n if (t.isIdentifier(callee)) {\n return this.resolveIdentifierKind(callee.name, fileId, visited)\n }\n\n if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {\n const prop = callee.property.name\n\n // Check if this property matches any method chain pattern\n const possibleKinds = IdentifierToKinds.get(prop)\n if (possibleKinds) {\n // Resolve base expression ONCE and reuse for all pattern checks\n const base = await this.resolveExprKind(callee.object, fileId, visited)\n\n // Check each possible kind that uses this identifier\n for (const kind of possibleKinds) {\n if (!this.validLookupKinds.has(kind)) continue\n\n if (kind === 'ServerFn') {\n if (base === 'Root' || base === 'Builder') {\n return 'ServerFn'\n }\n } else if (kind === 'Middleware') {\n if (\n base === 'Root' ||\n base === 'Builder' ||\n base === 'Middleware'\n ) {\n return 'Middleware'\n }\n } else if (kind === 'IsomorphicFn') {\n if (\n base === 'Root' ||\n base === 'Builder' ||\n base === 'IsomorphicFn'\n ) {\n return 'IsomorphicFn'\n }\n }\n }\n }\n\n // Check if the object is a namespace import\n if (t.isIdentifier(callee.object)) {\n const info = await this.getModuleInfo(fileId)\n const binding = info.bindings.get(callee.object.name)\n if (\n binding &&\n binding.type === 'import' &&\n binding.importedName === '*'\n ) {\n // resolve the property from the target module\n const targetModuleId = await this.resolveIdCached(\n binding.source,\n fileId,\n )\n if (targetModuleId) {\n const targetModule = await this.getModuleInfo(targetModuleId)\n const localBindingName = targetModule.exports.get(\n callee.property.name,\n )\n if (localBindingName) {\n const exportedBinding =\n targetModule.bindings.get(localBindingName)\n if (exportedBinding) {\n return await this.resolveBindingKind(\n exportedBinding,\n targetModule.id,\n visited,\n )\n }\n }\n } else {\n return 'None'\n }\n }\n }\n return this.resolveExprKind(callee.object, fileId, visited)\n }\n\n // handle nested expressions\n return this.resolveExprKind(callee, fileId, visited)\n }\n\n private async getModuleInfo(id: string) {\n let cached = this.moduleCache.get(id)\n if (cached) {\n return cached\n }\n\n await this.options.loadModule(id)\n\n cached = this.moduleCache.get(id)\n if (!cached) {\n throw new Error(`could not load module info for ${id}`)\n }\n return cached\n }\n}\n\n/**\n * Checks if a CallExpression has a method chain pattern that matches any of the lookup kinds.\n * E.g., `.handler()`, `.server()`, `.client()`, `.createMiddlewares()`\n */\nfunction isMethodChainCandidate(\n node: t.CallExpression,\n lookupKinds: Set<LookupKind>,\n): boolean {\n const callee = node.callee\n if (!t.isMemberExpression(callee) || !t.isIdentifier(callee.property)) {\n return false\n }\n\n // Use pre-computed map for O(1) lookup\n // IdentifierToKinds maps identifier -> Set<LookupKind> to handle shared identifiers\n const possibleKinds = IdentifierToKinds.get(callee.property.name)\n if (possibleKinds) {\n // Check if any of the possible kinds are in the valid lookup kinds\n for (const kind of possibleKinds) {\n if (lookupKinds.has(kind)) {\n return true\n }\n }\n }\n\n return false\n}\n"],"names":["resolvedKind"],"mappings":"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"}
1
+ {"version":3,"file":"compiler.js","sources":["../../../src/start-compiler-plugin/compiler.ts"],"sourcesContent":["/* eslint-disable import/no-commonjs */\nimport crypto from 'node:crypto'\nimport * as t from '@babel/types'\nimport {\n deadCodeElimination,\n findReferencedIdentifiers,\n generateFromAst,\n parseAst,\n} from '@tanstack/router-utils'\nimport babel from '@babel/core'\nimport { handleCreateServerFn } from './handleCreateServerFn'\nimport { handleCreateMiddleware } from './handleCreateMiddleware'\nimport { handleCreateIsomorphicFn } from './handleCreateIsomorphicFn'\nimport { handleEnvOnlyFn } from './handleEnvOnly'\nimport { handleClientOnlyJSX } from './handleClientOnlyJSX'\nimport type {\n CompilationContext,\n MethodChainPaths,\n RewriteCandidate,\n ServerFn,\n} from './types'\nimport type { CompileStartFrameworkOptions } from '../types'\n\ntype Binding =\n | {\n type: 'import'\n source: string\n importedName: string\n resolvedKind?: Kind\n }\n | {\n type: 'var'\n init: t.Expression | null\n resolvedKind?: Kind\n }\n\ntype Kind = 'None' | `Root` | `Builder` | LookupKind\n\nexport type LookupKind =\n | 'ServerFn'\n | 'Middleware'\n | 'IsomorphicFn'\n | 'ServerOnlyFn'\n | 'ClientOnlyFn'\n | 'ClientOnlyJSX'\n\n// Detection strategy for each kind\ntype MethodChainSetup = {\n type: 'methodChain'\n candidateCallIdentifier: Set<string>\n}\ntype DirectCallSetup = {\n type: 'directCall'\n // The factory function name used to create this kind (e.g., 'createServerOnlyFn')\n factoryName: string\n}\ntype JSXSetup = { type: 'jsx'; componentName: string }\n\nfunction isLookupKind(kind: Kind): kind is LookupKind {\n return kind in LookupSetup\n}\n\nconst LookupSetup: Record<\n LookupKind,\n MethodChainSetup | DirectCallSetup | JSXSetup\n> = {\n ServerFn: {\n type: 'methodChain',\n candidateCallIdentifier: new Set(['handler']),\n },\n Middleware: {\n type: 'methodChain',\n candidateCallIdentifier: new Set(['server', 'client', 'createMiddlewares']),\n },\n IsomorphicFn: {\n type: 'methodChain',\n candidateCallIdentifier: new Set(['server', 'client']),\n },\n ServerOnlyFn: { type: 'directCall', factoryName: 'createServerOnlyFn' },\n ClientOnlyFn: { type: 'directCall', factoryName: 'createClientOnlyFn' },\n ClientOnlyJSX: { type: 'jsx', componentName: 'ClientOnly' },\n}\n\n// Single source of truth for detecting which kinds are present in code\n// These patterns are used for:\n// 1. Pre-scanning code to determine which kinds to look for (before AST parsing)\n// 2. Deriving the plugin's transform code filter\nexport const KindDetectionPatterns: Record<LookupKind, RegExp> = {\n ServerFn: /\\bcreateServerFn\\b|\\.\\s*handler\\s*\\(/,\n Middleware: /createMiddleware/,\n IsomorphicFn: /createIsomorphicFn/,\n ServerOnlyFn: /createServerOnlyFn/,\n ClientOnlyFn: /createClientOnlyFn/,\n ClientOnlyJSX: /<ClientOnly|import\\s*\\{[^}]*\\bClientOnly\\b/,\n}\n\n// Which kinds are valid for each environment\nexport const LookupKindsPerEnv: Record<'client' | 'server', Set<LookupKind>> = {\n client: new Set([\n 'Middleware',\n 'ServerFn',\n 'IsomorphicFn',\n 'ServerOnlyFn',\n 'ClientOnlyFn',\n ] as const),\n server: new Set([\n 'ServerFn',\n 'IsomorphicFn',\n 'ServerOnlyFn',\n 'ClientOnlyFn',\n 'ClientOnlyJSX', // Only transform on server to remove children\n ] as const),\n}\n\n/**\n * Handler type for processing candidates of a specific kind.\n * The kind is passed as the third argument to allow shared handlers (like handleEnvOnlyFn).\n */\ntype KindHandler = (\n candidates: Array<RewriteCandidate>,\n context: CompilationContext,\n kind: LookupKind,\n) => void\n\n/**\n * Registry mapping each LookupKind to its handler function.\n * When adding a new kind, add its handler here.\n */\nconst KindHandlers: Record<\n Exclude<LookupKind, 'ClientOnlyJSX'>,\n KindHandler\n> = {\n ServerFn: handleCreateServerFn,\n Middleware: handleCreateMiddleware,\n IsomorphicFn: handleCreateIsomorphicFn,\n ServerOnlyFn: handleEnvOnlyFn,\n ClientOnlyFn: handleEnvOnlyFn,\n // ClientOnlyJSX is handled separately via JSX traversal, not here\n}\n\n// All lookup kinds as an array for iteration with proper typing\nconst AllLookupKinds = Object.keys(LookupSetup) as Array<LookupKind>\n\n/**\n * Detects which LookupKinds are present in the code using string matching.\n * This is a fast pre-scan before AST parsing to limit the work done during compilation.\n */\nexport function detectKindsInCode(\n code: string,\n env: 'client' | 'server',\n): Set<LookupKind> {\n const detected = new Set<LookupKind>()\n const validForEnv = LookupKindsPerEnv[env]\n\n for (const kind of AllLookupKinds) {\n if (validForEnv.has(kind) && KindDetectionPatterns[kind].test(code)) {\n detected.add(kind)\n }\n }\n\n return detected\n}\n\n// Pre-computed map: identifier name -> Set<LookupKind> for fast candidate detection (method chain only)\n// Multiple kinds can share the same identifier (e.g., 'server' and 'client' are used by both Middleware and IsomorphicFn)\nconst IdentifierToKinds = new Map<string, Set<LookupKind>>()\nfor (const kind of AllLookupKinds) {\n const setup = LookupSetup[kind]\n if (setup.type === 'methodChain') {\n for (const id of setup.candidateCallIdentifier) {\n let kinds = IdentifierToKinds.get(id)\n if (!kinds) {\n kinds = new Set()\n IdentifierToKinds.set(id, kinds)\n }\n kinds.add(kind)\n }\n }\n}\n\n// Factory function names for direct call patterns.\n// Used to filter nested candidates - we only want to include actual factory calls,\n// not invocations of already-created functions (e.g., `myServerFn()` should NOT be a candidate)\nconst DirectCallFactoryNames = new Set<string>()\nfor (const kind of AllLookupKinds) {\n const setup = LookupSetup[kind]\n if (setup.type === 'directCall') {\n DirectCallFactoryNames.add(setup.factoryName)\n }\n}\n\nexport type LookupConfig = {\n libName: string\n rootExport: string\n kind: LookupKind | 'Root' // 'Root' for builder pattern, LookupKind for direct call\n}\n\ninterface ModuleInfo {\n id: string\n bindings: Map<string, Binding>\n // Maps exported name → local binding name\n exports: Map<string, string>\n // Track `export * from './module'` declarations for re-export resolution\n reExportAllSources: Array<string>\n}\n\n/**\n * Computes whether any file kinds need direct-call candidate detection.\n * This applies to directCall types (ServerOnlyFn, ClientOnlyFn).\n */\nfunction needsDirectCallDetection(kinds: Set<LookupKind>): boolean {\n for (const kind of kinds) {\n if (LookupSetup[kind].type === 'directCall') {\n return true\n }\n }\n return false\n}\n\n/**\n * Checks if all kinds in the set are guaranteed to be top-level only.\n * Only ServerFn is always declared at module level (must be assigned to a variable).\n * Middleware, IsomorphicFn, ServerOnlyFn, ClientOnlyFn can be nested inside functions.\n * When all kinds are top-level-only, we can use a fast scan instead of full traversal.\n */\nfunction areAllKindsTopLevelOnly(kinds: Set<LookupKind>): boolean {\n return kinds.size === 1 && kinds.has('ServerFn')\n}\n\n/**\n * Checks if we need to detect JSX elements (e.g., <ClientOnly>).\n */\nfunction needsJSXDetection(kinds: Set<LookupKind>): boolean {\n for (const kind of kinds) {\n if (LookupSetup[kind].type === 'jsx') {\n return true\n }\n }\n return false\n}\n\n/**\n * Checks if a CallExpression is a direct-call candidate for NESTED detection.\n * Returns true if the callee is a known factory function name.\n * This is stricter than top-level detection because we need to filter out\n * invocations of existing server functions (e.g., `myServerFn()`).\n */\nfunction isNestedDirectCallCandidate(node: t.CallExpression): boolean {\n let calleeName: string | undefined\n if (t.isIdentifier(node.callee)) {\n calleeName = node.callee.name\n } else if (\n t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.property)\n ) {\n calleeName = node.callee.property.name\n }\n return calleeName !== undefined && DirectCallFactoryNames.has(calleeName)\n}\n\n/**\n * Checks if a CallExpression path is a top-level direct-call candidate.\n * Top-level means the call is the init of a VariableDeclarator at program level.\n * We accept any simple identifier call or namespace call at top level\n * (e.g., `createServerOnlyFn()`, `TanStackStart.createServerOnlyFn()`) and let\n * resolution verify it. This handles renamed imports.\n */\nfunction isTopLevelDirectCallCandidate(\n path: babel.NodePath<t.CallExpression>,\n): boolean {\n const node = path.node\n\n // Must be a simple identifier call or namespace call\n const isSimpleCall =\n t.isIdentifier(node.callee) ||\n (t.isMemberExpression(node.callee) &&\n t.isIdentifier(node.callee.object) &&\n t.isIdentifier(node.callee.property))\n\n if (!isSimpleCall) {\n return false\n }\n\n // Must be top-level: VariableDeclarator -> VariableDeclaration -> Program\n const parent = path.parent\n if (!t.isVariableDeclarator(parent) || parent.init !== node) {\n return false\n }\n const grandParent = path.parentPath.parent\n if (!t.isVariableDeclaration(grandParent)) {\n return false\n }\n return t.isProgram(path.parentPath.parentPath?.parent)\n}\n\nexport class StartCompiler {\n private moduleCache = new Map<string, ModuleInfo>()\n private initialized = false\n private validLookupKinds: Set<LookupKind>\n private resolveIdCache = new Map<string, string | null>()\n private exportResolutionCache = new Map<\n string,\n Map<string, { moduleInfo: ModuleInfo; binding: Binding } | null>\n >()\n // Fast lookup for direct imports from known libraries (e.g., '@tanstack/react-start')\n // Maps: libName → (exportName → Kind)\n // This allows O(1) resolution for the common case without async resolveId calls\n private knownRootImports = new Map<string, Map<string, Kind>>()\n\n // For generating unique function IDs in production builds\n private entryIdToFunctionId = new Map<string, string>()\n private functionIds = new Set<string>()\n\n // Cached root path with trailing slash for dev mode function ID generation\n private _rootWithTrailingSlash: string | undefined\n\n constructor(\n private options: {\n env: 'client' | 'server'\n envName: string\n root: string\n lookupConfigurations: Array<LookupConfig>\n lookupKinds: Set<LookupKind>\n loadModule: (id: string) => Promise<void>\n resolveId: (id: string, importer?: string) => Promise<string | null>\n /**\n * In 'build' mode, resolution results are cached for performance.\n * In 'dev' mode (default), caching is disabled to avoid invalidation complexity with HMR.\n */\n mode?: 'dev' | 'build'\n /**\n * The framework being used (e.g., 'react', 'solid').\n */\n framework: CompileStartFrameworkOptions\n /**\n * The Vite environment name for the server function provider.\n */\n providerEnvName: string\n /**\n * Custom function ID generator (optional, defaults to hash-based).\n */\n generateFunctionId?: (opts: {\n filename: string\n functionName: string\n }) => string | undefined\n /**\n * Callback when server functions are discovered.\n * Called after each file is compiled with its new functions.\n */\n onServerFnsById?: (d: Record<string, ServerFn>) => void\n /**\n * Returns the currently known server functions from previous builds.\n * Used by server callers to look up canonical extracted filenames.\n */\n getKnownServerFns?: () => Record<string, ServerFn>\n },\n ) {\n this.validLookupKinds = options.lookupKinds\n }\n\n /**\n * Generates a unique function ID for a server function.\n * In dev mode, uses a base64-encoded JSON with file path and export name.\n * In build mode, uses SHA256 hash or custom generator.\n */\n private generateFunctionId(opts: {\n filename: string\n functionName: string\n extractedFilename: string\n }): string {\n if (this.mode === 'dev') {\n // In dev, encode the file path and export name for direct lookup\n let file = opts.extractedFilename\n if (opts.extractedFilename.startsWith(this.rootWithTrailingSlash)) {\n file = opts.extractedFilename.slice(this.rootWithTrailingSlash.length)\n }\n file = `/@id/${file}`\n\n const serverFn = {\n file,\n export: opts.functionName,\n }\n return Buffer.from(JSON.stringify(serverFn), 'utf8').toString('base64url')\n }\n\n // Production build: use custom generator or hash\n const entryId = `${opts.filename}--${opts.functionName}`\n let functionId = this.entryIdToFunctionId.get(entryId)\n if (functionId === undefined) {\n if (this.options.generateFunctionId) {\n functionId = this.options.generateFunctionId({\n filename: opts.filename,\n functionName: opts.functionName,\n })\n }\n if (!functionId) {\n functionId = crypto.createHash('sha256').update(entryId).digest('hex')\n }\n // Deduplicate in case the generated id conflicts with an existing id\n if (this.functionIds.has(functionId)) {\n let deduplicatedId\n let iteration = 0\n do {\n deduplicatedId = `${functionId}_${++iteration}`\n } while (this.functionIds.has(deduplicatedId))\n functionId = deduplicatedId\n }\n this.entryIdToFunctionId.set(entryId, functionId)\n this.functionIds.add(functionId)\n }\n return functionId\n }\n\n private get mode(): 'dev' | 'build' {\n return this.options.mode ?? 'dev'\n }\n\n private get rootWithTrailingSlash(): string {\n if (this._rootWithTrailingSlash === undefined) {\n this._rootWithTrailingSlash = this.options.root.endsWith('/')\n ? this.options.root\n : `${this.options.root}/`\n }\n return this._rootWithTrailingSlash\n }\n\n private async resolveIdCached(id: string, importer?: string) {\n if (this.mode === 'dev') {\n return this.options.resolveId(id, importer)\n }\n\n const cacheKey = importer ? `${importer}::${id}` : id\n const cached = this.resolveIdCache.get(cacheKey)\n if (cached !== undefined) {\n return cached\n }\n const resolved = await this.options.resolveId(id, importer)\n this.resolveIdCache.set(cacheKey, resolved)\n return resolved\n }\n\n private getExportResolutionCache(moduleId: string) {\n let cache = this.exportResolutionCache.get(moduleId)\n if (!cache) {\n cache = new Map()\n this.exportResolutionCache.set(moduleId, cache)\n }\n return cache\n }\n\n private async init() {\n // Register internal stub package exports for recognition.\n // These don't need module resolution - only the knownRootImports fast path.\n this.knownRootImports.set(\n '@tanstack/start-fn-stubs',\n new Map<string, Kind>([\n ['createIsomorphicFn', 'IsomorphicFn'],\n ['createServerOnlyFn', 'ServerOnlyFn'],\n ['createClientOnlyFn', 'ClientOnlyFn'],\n ]),\n )\n\n await Promise.all(\n this.options.lookupConfigurations.map(async (config) => {\n // Populate the fast lookup map for direct imports (by package name)\n // This allows O(1) recognition of imports from known packages.\n let libExports = this.knownRootImports.get(config.libName)\n if (!libExports) {\n libExports = new Map()\n this.knownRootImports.set(config.libName, libExports)\n }\n libExports.set(config.rootExport, config.kind)\n\n // For JSX lookups (e.g., ClientOnlyJSX), we only need the knownRootImports\n // fast path to verify imports. Skip module resolution which may fail if\n // the package isn't a direct dependency (e.g., @tanstack/react-router from\n // within start-plugin-core).\n if (config.kind !== 'Root') {\n const setup = LookupSetup[config.kind]\n if (setup.type === 'jsx') {\n return\n }\n }\n\n const libId = await this.resolveIdCached(config.libName)\n if (!libId) {\n throw new Error(`could not resolve \"${config.libName}\"`)\n }\n let rootModule = this.moduleCache.get(libId)\n if (!rootModule) {\n // insert root binding\n rootModule = {\n bindings: new Map(),\n exports: new Map(),\n id: libId,\n reExportAllSources: [],\n }\n this.moduleCache.set(libId, rootModule)\n }\n\n rootModule.exports.set(config.rootExport, config.rootExport)\n rootModule.exports.set('*', config.rootExport)\n rootModule.bindings.set(config.rootExport, {\n type: 'var',\n init: null, // Not needed since resolvedKind is set\n resolvedKind: config.kind satisfies Kind,\n })\n this.moduleCache.set(libId, rootModule)\n }),\n )\n\n this.initialized = true\n }\n\n /**\n * Extracts bindings and exports from an already-parsed AST.\n * This is the core logic shared by ingestModule and ingestModuleFromAst.\n */\n private extractModuleInfo(\n ast: ReturnType<typeof parseAst>,\n id: string,\n ): ModuleInfo {\n const bindings = new Map<string, Binding>()\n const exports = new Map<string, string>()\n const reExportAllSources: Array<string> = []\n\n // we are only interested in top-level bindings, hence we don't traverse the AST\n // instead we only iterate over the program body\n for (const node of ast.program.body) {\n if (t.isImportDeclaration(node)) {\n const source = node.source.value\n for (const s of node.specifiers) {\n if (t.isImportSpecifier(s)) {\n const importedName = t.isIdentifier(s.imported)\n ? s.imported.name\n : s.imported.value\n bindings.set(s.local.name, { type: 'import', source, importedName })\n } else if (t.isImportDefaultSpecifier(s)) {\n bindings.set(s.local.name, {\n type: 'import',\n source,\n importedName: 'default',\n })\n } else if (t.isImportNamespaceSpecifier(s)) {\n bindings.set(s.local.name, {\n type: 'import',\n source,\n importedName: '*',\n })\n }\n }\n } else if (t.isVariableDeclaration(node)) {\n for (const decl of node.declarations) {\n if (t.isIdentifier(decl.id)) {\n bindings.set(decl.id.name, {\n type: 'var',\n init: decl.init ?? null,\n })\n }\n }\n } else if (t.isExportNamedDeclaration(node)) {\n // export const foo = ...\n if (node.declaration) {\n if (t.isVariableDeclaration(node.declaration)) {\n for (const d of node.declaration.declarations) {\n if (t.isIdentifier(d.id)) {\n exports.set(d.id.name, d.id.name)\n bindings.set(d.id.name, { type: 'var', init: d.init ?? null })\n }\n }\n }\n }\n for (const sp of node.specifiers) {\n if (t.isExportNamespaceSpecifier(sp)) {\n exports.set(sp.exported.name, sp.exported.name)\n }\n // export { local as exported }\n else if (t.isExportSpecifier(sp)) {\n const local = sp.local.name\n const exported = t.isIdentifier(sp.exported)\n ? sp.exported.name\n : sp.exported.value\n exports.set(exported, local)\n\n // When re-exporting from another module (export { foo } from './module'),\n // create an import binding so the server function can be resolved\n if (node.source) {\n bindings.set(local, {\n type: 'import',\n source: node.source.value,\n importedName: local,\n })\n }\n }\n }\n } else if (t.isExportDefaultDeclaration(node)) {\n const d = node.declaration\n if (t.isIdentifier(d)) {\n exports.set('default', d.name)\n } else {\n const synth = '__default_export__'\n bindings.set(synth, { type: 'var', init: d as t.Expression })\n exports.set('default', synth)\n }\n } else if (t.isExportAllDeclaration(node)) {\n // Handle `export * from './module'` syntax\n // Track the source so we can look up exports from it when needed\n reExportAllSources.push(node.source.value)\n }\n }\n\n const info: ModuleInfo = {\n id,\n bindings,\n exports,\n reExportAllSources,\n }\n this.moduleCache.set(id, info)\n return info\n }\n\n public ingestModule({ code, id }: { code: string; id: string }) {\n const ast = parseAst({ code })\n const info = this.extractModuleInfo(ast, id)\n return { info, ast }\n }\n\n public invalidateModule(id: string) {\n // Note: Resolution caches (resolveIdCache, exportResolutionCache) are only\n // used in build mode where there's no HMR. In dev mode, caching is disabled,\n // so we only need to invalidate the moduleCache here.\n return this.moduleCache.delete(id)\n }\n\n public async compile({\n code,\n id,\n detectedKinds,\n }: {\n code: string\n id: string\n /** Pre-detected kinds present in this file. If not provided, all valid kinds are checked. */\n detectedKinds?: Set<LookupKind>\n }) {\n if (!this.initialized) {\n await this.init()\n }\n\n // Use detected kinds if provided, otherwise fall back to all valid kinds for this env\n const fileKinds = detectedKinds\n ? new Set([...detectedKinds].filter((k) => this.validLookupKinds.has(k)))\n : this.validLookupKinds\n\n // Early exit if no kinds to process\n if (fileKinds.size === 0) {\n return null\n }\n\n const checkDirectCalls = needsDirectCallDetection(fileKinds)\n // Optimization: ServerFn is always a top-level declaration (must be assigned to a variable).\n // If the file only has ServerFn, we can skip full AST traversal and only visit\n // the specific top-level declarations that have candidates.\n const canUseFastPath = areAllKindsTopLevelOnly(fileKinds)\n\n // Always parse and extract module info upfront.\n // This ensures the module is cached for import resolution even if no candidates are found.\n const { ast } = this.ingestModule({ code, id })\n\n // Single-pass traversal to:\n // 1. Collect candidate paths (only candidates, not all CallExpressions)\n // 2. Build a map for looking up paths of nested calls in method chains\n const candidatePaths: Array<babel.NodePath<t.CallExpression>> = []\n // Map for nested chain lookup - only populated for CallExpressions that are\n // part of a method chain (callee.object is a CallExpression)\n const chainCallPaths = new Map<\n t.CallExpression,\n babel.NodePath<t.CallExpression>\n >()\n\n // JSX candidates (e.g., <ClientOnly>)\n const jsxCandidatePaths: Array<babel.NodePath<t.JSXElement>> = []\n const checkJSX = needsJSXDetection(fileKinds)\n // Get module info that was just cached by ingestModule\n const moduleInfo = this.moduleCache.get(id)!\n\n if (canUseFastPath) {\n // Fast path: only visit top-level statements that have potential candidates\n\n // Collect indices of top-level statements that contain candidates\n const candidateIndices: Array<number> = []\n for (let i = 0; i < ast.program.body.length; i++) {\n const node = ast.program.body[i]!\n let declarations: Array<t.VariableDeclarator> | undefined\n\n if (t.isVariableDeclaration(node)) {\n declarations = node.declarations\n } else if (t.isExportNamedDeclaration(node) && node.declaration) {\n if (t.isVariableDeclaration(node.declaration)) {\n declarations = node.declaration.declarations\n }\n }\n\n if (declarations) {\n for (const decl of declarations) {\n if (decl.init && t.isCallExpression(decl.init)) {\n if (isMethodChainCandidate(decl.init, fileKinds)) {\n candidateIndices.push(i)\n break // Only need to mark this statement once\n }\n }\n }\n }\n }\n\n // Early exit: no potential candidates found at top level\n if (candidateIndices.length === 0) {\n return null\n }\n\n // Targeted traversal: only visit the specific statements that have candidates\n // This is much faster than traversing the entire AST\n babel.traverse(ast, {\n Program(programPath) {\n const bodyPaths = programPath.get('body')\n for (const idx of candidateIndices) {\n const stmtPath = bodyPaths[idx]\n if (!stmtPath) continue\n\n // Traverse only this statement's subtree\n stmtPath.traverse({\n CallExpression(path) {\n const node = path.node\n const parent = path.parent\n\n // Check if this call is part of a larger chain (inner call)\n if (\n t.isMemberExpression(parent) &&\n t.isCallExpression(path.parentPath.parent)\n ) {\n chainCallPaths.set(node, path)\n return\n }\n\n // Method chain pattern\n if (isMethodChainCandidate(node, fileKinds)) {\n candidatePaths.push(path)\n }\n },\n })\n }\n // Stop traversal after processing Program\n programPath.stop()\n },\n })\n } else {\n // Normal path: full traversal for non-fast-path kinds\n babel.traverse(ast, {\n CallExpression: (path) => {\n const node = path.node\n const parent = path.parent\n\n // Check if this call is part of a larger chain (inner call)\n // If so, store it for method chain lookup but don't treat as candidate\n if (\n t.isMemberExpression(parent) &&\n t.isCallExpression(path.parentPath.parent)\n ) {\n // This is an inner call in a chain - store for later lookup\n chainCallPaths.set(node, path)\n return\n }\n\n // Pattern 1: Method chain pattern (.handler(), .server(), .client(), etc.)\n if (isMethodChainCandidate(node, fileKinds)) {\n candidatePaths.push(path)\n return\n }\n\n // Pattern 2: Direct call pattern\n if (checkDirectCalls) {\n if (isTopLevelDirectCallCandidate(path)) {\n candidatePaths.push(path)\n } else if (isNestedDirectCallCandidate(node)) {\n candidatePaths.push(path)\n }\n }\n },\n // Pattern 3: JSX element pattern (e.g., <ClientOnly>)\n // Collect JSX elements where the component is imported from a known package\n // and resolves to a JSX kind (e.g., ClientOnly from @tanstack/react-router)\n JSXElement: (path) => {\n if (!checkJSX) return\n\n const openingElement = path.node.openingElement\n const nameNode = openingElement.name\n\n // Only handle simple identifier names (not namespaced or member expressions)\n if (!t.isJSXIdentifier(nameNode)) return\n\n const componentName = nameNode.name\n const binding = moduleInfo.bindings.get(componentName)\n\n // Must be an import binding from a known package\n if (!binding || binding.type !== 'import') return\n\n // Verify the import source is a known TanStack router package\n const knownExports = this.knownRootImports.get(binding.source)\n if (!knownExports) return\n\n // Verify the imported name resolves to a JSX kind (e.g., ClientOnlyJSX)\n const kind = knownExports.get(binding.importedName)\n if (kind !== 'ClientOnlyJSX') return\n\n jsxCandidatePaths.push(path)\n },\n })\n }\n\n if (candidatePaths.length === 0 && jsxCandidatePaths.length === 0) {\n return null\n }\n\n // Resolve all candidates in parallel to determine their kinds\n const resolvedCandidates = await Promise.all(\n candidatePaths.map(async (path) => ({\n path,\n kind: await this.resolveExprKind(path.node, id),\n })),\n )\n\n // Filter to valid candidates\n const validCandidates = resolvedCandidates.filter(({ kind }) =>\n this.validLookupKinds.has(kind as Exclude<LookupKind, 'ClientOnlyJSX'>),\n ) as Array<{\n path: babel.NodePath<t.CallExpression>\n kind: Exclude<LookupKind, 'ClientOnlyJSX'>\n }>\n\n if (validCandidates.length === 0 && jsxCandidatePaths.length === 0) {\n return null\n }\n\n // Process valid candidates to collect method chains\n const pathsToRewrite: Array<{\n path: babel.NodePath<t.CallExpression>\n kind: Exclude<LookupKind, 'ClientOnlyJSX'>\n methodChain: MethodChainPaths\n }> = []\n\n for (const { path, kind } of validCandidates) {\n const node = path.node\n\n // Collect method chain paths by walking DOWN from root through the chain\n const methodChain: MethodChainPaths = {\n middleware: null,\n inputValidator: null,\n handler: null,\n server: null,\n client: null,\n }\n\n // Walk down the call chain using nodes, look up paths from map\n let currentNode: t.CallExpression = node\n let currentPath: babel.NodePath<t.CallExpression> = path\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n while (true) {\n const callee = currentNode.callee\n if (!t.isMemberExpression(callee)) {\n break\n }\n\n // Record method chain path if it's a known method\n if (t.isIdentifier(callee.property)) {\n const name = callee.property.name as keyof MethodChainPaths\n if (name in methodChain) {\n // Get first argument path\n const args = currentPath.get('arguments')\n const firstArgPath =\n Array.isArray(args) && args.length > 0 ? (args[0] ?? null) : null\n methodChain[name] = {\n callPath: currentPath,\n firstArgPath,\n }\n }\n }\n\n // Move to the inner call (the object of the member expression)\n if (!t.isCallExpression(callee.object)) {\n break\n }\n currentNode = callee.object\n // Look up path from chain map, or use candidate path if not found\n const nextPath = chainCallPaths.get(currentNode)\n if (!nextPath) {\n break\n }\n currentPath = nextPath\n }\n\n pathsToRewrite.push({ path, kind, methodChain })\n }\n\n const refIdents = findReferencedIdentifiers(ast)\n\n const context: CompilationContext = {\n ast,\n id,\n code,\n env: this.options.env,\n envName: this.options.envName,\n root: this.options.root,\n framework: this.options.framework,\n providerEnvName: this.options.providerEnvName,\n\n generateFunctionId: (opts) => this.generateFunctionId(opts),\n getKnownServerFns: () => this.options.getKnownServerFns?.() ?? {},\n onServerFnsById: this.options.onServerFnsById,\n }\n\n // Group candidates by kind for batch processing\n const candidatesByKind = new Map<\n Exclude<LookupKind, 'ClientOnlyJSX'>,\n Array<RewriteCandidate>\n >()\n\n for (const { path: candidatePath, kind, methodChain } of pathsToRewrite) {\n const candidate: RewriteCandidate = { path: candidatePath, methodChain }\n const existing = candidatesByKind.get(kind)\n if (existing) {\n existing.push(candidate)\n } else {\n candidatesByKind.set(kind, [candidate])\n }\n }\n\n // Process each kind using its registered handler\n for (const [kind, candidates] of candidatesByKind) {\n const handler = KindHandlers[kind]\n handler(candidates, context, kind)\n }\n\n // Handle JSX candidates (e.g., <ClientOnly>)\n // Validation was already done during traversal - just call the handler\n for (const jsxPath of jsxCandidatePaths) {\n handleClientOnlyJSX(jsxPath, { env: 'server' })\n }\n\n deadCodeElimination(ast, refIdents)\n\n const result = generateFromAst(ast, {\n sourceMaps: true,\n sourceFileName: id,\n filename: id,\n })\n\n // @babel/generator does not populate sourcesContent because it only has\n // the AST, not the original text. Without this, Vite's composed\n // sourcemap omits the original source, causing downstream consumers\n // (e.g. import-protection snippet display) to fall back to the shorter\n // compiled output and fail to resolve original line numbers.\n if (result.map) {\n result.map.sourcesContent = [code]\n }\n\n return result\n }\n\n private async resolveIdentifierKind(\n ident: string,\n id: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n const info = await this.getModuleInfo(id)\n\n const binding = info.bindings.get(ident)\n if (!binding) {\n return 'None'\n }\n if (binding.resolvedKind) {\n return binding.resolvedKind\n }\n\n // TODO improve cycle detection? should we throw here instead of returning 'None'?\n // prevent cycles\n const vKey = `${id}:${ident}`\n if (visited.has(vKey)) {\n return 'None'\n }\n visited.add(vKey)\n\n const resolvedKind = await this.resolveBindingKind(binding, id, visited)\n binding.resolvedKind = resolvedKind\n return resolvedKind\n }\n\n /**\n * Recursively find an export in a module, following `export * from` chains.\n * Returns the module info and binding if found, or undefined if not found.\n */\n private async findExportInModule(\n moduleInfo: ModuleInfo,\n exportName: string,\n visitedModules = new Set<string>(),\n ): Promise<{ moduleInfo: ModuleInfo; binding: Binding } | undefined> {\n const isBuildMode = this.mode === 'build'\n\n // Check cache first (only for top-level calls in build mode)\n if (isBuildMode && visitedModules.size === 0) {\n const moduleCache = this.exportResolutionCache.get(moduleInfo.id)\n if (moduleCache) {\n const cached = moduleCache.get(exportName)\n if (cached !== undefined) {\n return cached ?? undefined\n }\n }\n }\n\n // Prevent infinite loops in circular re-exports\n if (visitedModules.has(moduleInfo.id)) {\n return undefined\n }\n visitedModules.add(moduleInfo.id)\n\n // First check direct exports\n const localBindingName = moduleInfo.exports.get(exportName)\n if (localBindingName) {\n const binding = moduleInfo.bindings.get(localBindingName)\n if (binding) {\n const result = { moduleInfo, binding }\n // Cache the result (build mode only)\n if (isBuildMode) {\n this.getExportResolutionCache(moduleInfo.id).set(exportName, result)\n }\n return result\n }\n }\n\n // If not found, recursively check re-export-all sources in parallel\n // Valid code won't have duplicate exports across chains, so first match wins\n if (moduleInfo.reExportAllSources.length > 0) {\n const results = await Promise.all(\n moduleInfo.reExportAllSources.map(async (reExportSource) => {\n const reExportTarget = await this.resolveIdCached(\n reExportSource,\n moduleInfo.id,\n )\n\n if (reExportTarget) {\n const reExportModule = await this.getModuleInfo(reExportTarget)\n return this.findExportInModule(\n reExportModule,\n exportName,\n visitedModules,\n )\n }\n return undefined\n }),\n )\n // Return the first valid result\n for (const result of results) {\n if (result) {\n // Cache the result (build mode only)\n if (isBuildMode) {\n this.getExportResolutionCache(moduleInfo.id).set(exportName, result)\n }\n return result\n }\n }\n }\n\n // Cache negative result (build mode only)\n if (isBuildMode) {\n this.getExportResolutionCache(moduleInfo.id).set(exportName, null)\n }\n return undefined\n }\n\n private async resolveBindingKind(\n binding: Binding,\n fileId: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n if (binding.resolvedKind) {\n return binding.resolvedKind\n }\n if (binding.type === 'import') {\n // Fast path: check if this is a direct import from a known library\n // (e.g., import { createServerFn } from '@tanstack/react-start')\n // This avoids async resolveId calls for the common case\n const knownExports = this.knownRootImports.get(binding.source)\n if (knownExports) {\n const kind = knownExports.get(binding.importedName)\n if (kind) {\n binding.resolvedKind = kind\n return kind\n }\n }\n\n // Slow path: resolve through the module graph\n const target = await this.resolveIdCached(binding.source, fileId)\n if (!target) {\n return 'None'\n }\n\n const importedModule = await this.getModuleInfo(target)\n\n // Find the export, recursively searching through export * from chains\n const found = await this.findExportInModule(\n importedModule,\n binding.importedName,\n )\n\n if (!found) {\n return 'None'\n }\n\n const { moduleInfo: foundModule, binding: foundBinding } = found\n\n if (foundBinding.resolvedKind) {\n return foundBinding.resolvedKind\n }\n\n const resolvedKind = await this.resolveBindingKind(\n foundBinding,\n foundModule.id,\n visited,\n )\n foundBinding.resolvedKind = resolvedKind\n return resolvedKind\n }\n\n const resolvedKind = await this.resolveExprKind(\n binding.init,\n fileId,\n visited,\n )\n // When a var binding's init is a call to a directCall factory\n // (e.g., `const myFn = createServerOnlyFn(() => ...)`), the binding holds\n // the RESULT of the factory, not the factory itself. Clear the kind so\n // `myFn()` isn't incorrectly matched as a directCall candidate.\n // We only clear when the init is a CallExpression — an alias like\n // `const createSO = createServerOnlyFn` should still propagate the kind.\n if (\n isLookupKind(resolvedKind) &&\n LookupSetup[resolvedKind].type === 'directCall' &&\n binding.init &&\n t.isCallExpression(binding.init)\n ) {\n binding.resolvedKind = 'None'\n return 'None'\n }\n binding.resolvedKind = resolvedKind\n return resolvedKind\n }\n\n private async resolveExprKind(\n expr: t.Expression | null,\n fileId: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n if (!expr) {\n return 'None'\n }\n\n // Unwrap common TypeScript/parenthesized wrappers first for efficiency\n while (\n t.isTSAsExpression(expr) ||\n t.isTSNonNullExpression(expr) ||\n t.isParenthesizedExpression(expr)\n ) {\n expr = expr.expression\n }\n\n let result: Kind = 'None'\n\n if (t.isCallExpression(expr)) {\n if (!t.isExpression(expr.callee)) {\n return 'None'\n }\n const calleeKind = await this.resolveCalleeKind(\n expr.callee,\n fileId,\n visited,\n )\n if (calleeKind === 'Root' || calleeKind === 'Builder') {\n return 'Builder'\n }\n // For method chain patterns (callee is MemberExpression like .server() or .client()),\n // return the resolved kind if valid\n if (t.isMemberExpression(expr.callee)) {\n if (this.validLookupKinds.has(calleeKind as LookupKind)) {\n return calleeKind\n }\n }\n // For direct calls (callee is Identifier like createServerOnlyFn()),\n // trust calleeKind if it resolved to a valid LookupKind. This means\n // resolveBindingKind successfully traced the import back to\n // @tanstack/start-fn-stubs (via fast path or slow path through re-exports).\n // This handles both direct imports from @tanstack/react-start and imports\n // from intermediate packages that re-export from @tanstack/start-client-core.\n if (t.isIdentifier(expr.callee)) {\n if (this.validLookupKinds.has(calleeKind as LookupKind)) {\n return calleeKind\n }\n }\n } else if (t.isMemberExpression(expr) && t.isIdentifier(expr.property)) {\n result = await this.resolveCalleeKind(expr.object, fileId, visited)\n }\n\n if (result === 'None' && t.isIdentifier(expr)) {\n result = await this.resolveIdentifierKind(expr.name, fileId, visited)\n }\n\n return result\n }\n\n private async resolveCalleeKind(\n callee: t.Expression,\n fileId: string,\n visited = new Set<string>(),\n ): Promise<Kind> {\n if (t.isIdentifier(callee)) {\n return this.resolveIdentifierKind(callee.name, fileId, visited)\n }\n\n if (t.isMemberExpression(callee) && t.isIdentifier(callee.property)) {\n const prop = callee.property.name\n\n // Check if this property matches any method chain pattern\n const possibleKinds = IdentifierToKinds.get(prop)\n if (possibleKinds) {\n // Resolve base expression ONCE and reuse for all pattern checks\n const base = await this.resolveExprKind(callee.object, fileId, visited)\n\n // Check each possible kind that uses this identifier\n for (const kind of possibleKinds) {\n if (!this.validLookupKinds.has(kind)) continue\n\n if (kind === 'ServerFn') {\n if (base === 'Root' || base === 'Builder') {\n return 'ServerFn'\n }\n } else if (kind === 'Middleware') {\n if (\n base === 'Root' ||\n base === 'Builder' ||\n base === 'Middleware'\n ) {\n return 'Middleware'\n }\n } else if (kind === 'IsomorphicFn') {\n if (\n base === 'Root' ||\n base === 'Builder' ||\n base === 'IsomorphicFn'\n ) {\n return 'IsomorphicFn'\n }\n }\n }\n }\n\n // Check if the object is a namespace import\n if (t.isIdentifier(callee.object)) {\n const info = await this.getModuleInfo(fileId)\n const binding = info.bindings.get(callee.object.name)\n if (\n binding &&\n binding.type === 'import' &&\n binding.importedName === '*'\n ) {\n // resolve the property from the target module\n const targetModuleId = await this.resolveIdCached(\n binding.source,\n fileId,\n )\n if (targetModuleId) {\n const targetModule = await this.getModuleInfo(targetModuleId)\n const localBindingName = targetModule.exports.get(\n callee.property.name,\n )\n if (localBindingName) {\n const exportedBinding =\n targetModule.bindings.get(localBindingName)\n if (exportedBinding) {\n return await this.resolveBindingKind(\n exportedBinding,\n targetModule.id,\n visited,\n )\n }\n }\n } else {\n return 'None'\n }\n }\n }\n return this.resolveExprKind(callee.object, fileId, visited)\n }\n\n // handle nested expressions\n return this.resolveExprKind(callee, fileId, visited)\n }\n\n private async getModuleInfo(id: string) {\n let cached = this.moduleCache.get(id)\n if (cached) {\n return cached\n }\n\n await this.options.loadModule(id)\n\n cached = this.moduleCache.get(id)\n if (!cached) {\n throw new Error(`could not load module info for ${id}`)\n }\n return cached\n }\n}\n\n/**\n * Checks if a CallExpression has a method chain pattern that matches any of the lookup kinds.\n * E.g., `.handler()`, `.server()`, `.client()`, `.createMiddlewares()`\n */\nfunction isMethodChainCandidate(\n node: t.CallExpression,\n lookupKinds: Set<LookupKind>,\n): boolean {\n const callee = node.callee\n if (!t.isMemberExpression(callee) || !t.isIdentifier(callee.property)) {\n return false\n }\n\n // Use pre-computed map for O(1) lookup\n // IdentifierToKinds maps identifier -> Set<LookupKind> to handle shared identifiers\n const possibleKinds = IdentifierToKinds.get(callee.property.name)\n if (possibleKinds) {\n // Check if any of the possible kinds are in the valid lookup kinds\n for (const kind of possibleKinds) {\n if (lookupKinds.has(kind)) {\n return true\n }\n }\n }\n\n return false\n}\n"],"names":["exports","resolvedKind"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-plugin-core",
3
- "version": "1.166.10",
3
+ "version": "1.166.12",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -60,12 +60,12 @@
60
60
  "vitefu": "^1.1.1",
61
61
  "xmlbuilder2": "^4.0.3",
62
62
  "zod": "^3.24.2",
63
- "@tanstack/router-core": "1.167.0",
64
- "@tanstack/router-generator": "1.166.8",
65
- "@tanstack/router-plugin": "1.166.9",
66
- "@tanstack/router-utils": "1.161.4",
67
- "@tanstack/start-client-core": "1.166.8",
68
- "@tanstack/start-server-core": "1.166.8"
63
+ "@tanstack/router-core": "1.167.1",
64
+ "@tanstack/router-generator": "1.166.9",
65
+ "@tanstack/router-plugin": "1.166.10",
66
+ "@tanstack/router-utils": "1.161.5",
67
+ "@tanstack/start-client-core": "1.166.9",
68
+ "@tanstack/start-server-core": "1.166.9"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/babel__code-frame": "^7.0.6",
@@ -203,6 +203,7 @@ function createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {
203
203
  return create({ version: '1.0', encoding: 'UTF-8' })
204
204
  .ele(elementName, {
205
205
  xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',
206
+ 'xmlns:xhtml': 'http://www.w3.org/1999/xhtml',
206
207
  })
207
208
  .com(`This file was automatically generated by TanStack Start.`)
208
209
  }