@tanstack/start-plugin-core 1.161.4 → 1.162.1

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.
Files changed (32) hide show
  1. package/dist/esm/import-protection-plugin/defaults.d.ts +6 -4
  2. package/dist/esm/import-protection-plugin/defaults.js +3 -12
  3. package/dist/esm/import-protection-plugin/defaults.js.map +1 -1
  4. package/dist/esm/import-protection-plugin/plugin.d.ts +1 -1
  5. package/dist/esm/import-protection-plugin/plugin.js +488 -257
  6. package/dist/esm/import-protection-plugin/plugin.js.map +1 -1
  7. package/dist/esm/import-protection-plugin/postCompileUsage.d.ts +4 -2
  8. package/dist/esm/import-protection-plugin/postCompileUsage.js +31 -150
  9. package/dist/esm/import-protection-plugin/postCompileUsage.js.map +1 -1
  10. package/dist/esm/import-protection-plugin/rewriteDeniedImports.js +13 -9
  11. package/dist/esm/import-protection-plugin/rewriteDeniedImports.js.map +1 -1
  12. package/dist/esm/import-protection-plugin/sourceLocation.d.ts +32 -66
  13. package/dist/esm/import-protection-plugin/sourceLocation.js +129 -56
  14. package/dist/esm/import-protection-plugin/sourceLocation.js.map +1 -1
  15. package/dist/esm/import-protection-plugin/trace.d.ts +10 -0
  16. package/dist/esm/import-protection-plugin/trace.js +30 -44
  17. package/dist/esm/import-protection-plugin/trace.js.map +1 -1
  18. package/dist/esm/import-protection-plugin/utils.d.ts +8 -4
  19. package/dist/esm/import-protection-plugin/utils.js +43 -1
  20. package/dist/esm/import-protection-plugin/utils.js.map +1 -1
  21. package/dist/esm/import-protection-plugin/virtualModules.d.ts +7 -1
  22. package/dist/esm/import-protection-plugin/virtualModules.js +104 -135
  23. package/dist/esm/import-protection-plugin/virtualModules.js.map +1 -1
  24. package/package.json +6 -6
  25. package/src/import-protection-plugin/defaults.ts +8 -19
  26. package/src/import-protection-plugin/plugin.ts +776 -433
  27. package/src/import-protection-plugin/postCompileUsage.ts +57 -229
  28. package/src/import-protection-plugin/rewriteDeniedImports.ts +34 -42
  29. package/src/import-protection-plugin/sourceLocation.ts +184 -185
  30. package/src/import-protection-plugin/trace.ts +38 -49
  31. package/src/import-protection-plugin/utils.ts +62 -1
  32. package/src/import-protection-plugin/virtualModules.ts +163 -177
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/import-protection-plugin/plugin.ts"],"sourcesContent":["import * as path from 'pathe'\nimport { normalizePath } from 'vite'\n\nimport { resolveViteId } from '../utils'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { SERVER_FN_LOOKUP } from '../start-compiler-plugin/plugin'\nimport { ImportGraph, buildTrace, formatViolation } from './trace'\nimport {\n getDefaultImportProtectionRules,\n getMarkerSpecifiers,\n} from './defaults'\nimport { findPostCompileUsagePos } from './postCompileUsage'\nimport { compileMatchers, matchesAny } from './matchers'\nimport { dedupePatterns, normalizeFilePath } from './utils'\nimport { collectMockExportNamesBySource } from './rewriteDeniedImports'\nimport {\n MARKER_PREFIX,\n MOCK_EDGE_PREFIX,\n MOCK_MODULE_ID,\n MOCK_RUNTIME_PREFIX,\n RESOLVED_MARKER_PREFIX,\n RESOLVED_MOCK_EDGE_PREFIX,\n RESOLVED_MOCK_MODULE_ID,\n RESOLVED_MOCK_RUNTIME_PREFIX,\n loadMarkerModule,\n loadMockEdgeModule,\n loadMockRuntimeModule,\n loadSilentMockModule,\n makeMockEdgeModuleId,\n mockRuntimeModuleIdFromViolation,\n} from './virtualModules'\nimport {\n addTraceImportLocations,\n buildCodeSnippet,\n buildLineIndex,\n findImportStatementLocationFromTransformed,\n findPostCompileUsageLocation,\n pickOriginalCodeFromSourcesContent,\n} from './sourceLocation'\nimport type { PluginOption } from 'vite'\nimport type { CompiledMatcher } from './matchers'\nimport type { ViolationInfo } from './trace'\nimport type {\n SourceMapLike,\n TransformResult,\n TransformResultProvider,\n} from './sourceLocation'\nimport type {\n ImportProtectionBehavior,\n ImportProtectionOptions,\n} from '../schema'\nimport type { CompileStartFrameworkOptions, GetConfigFn } from '../types'\n\n// Re-export public API that tests and other consumers depend on.\nexport { RESOLVED_MOCK_MODULE_ID } from './virtualModules'\nexport { rewriteDeniedImports } from './rewriteDeniedImports'\nexport { dedupePatterns } from './utils'\nexport type { Pattern } from './utils'\n\n/**\n * Immutable plugin configuration — set once in `configResolved`, never mutated\n * per-env or per-request afterward.\n */\ninterface PluginConfig {\n enabled: boolean\n root: string\n command: 'build' | 'serve'\n srcDirectory: string\n framework: CompileStartFrameworkOptions\n\n effectiveBehavior: ImportProtectionBehavior\n mockAccess: 'error' | 'warn' | 'off'\n logMode: 'once' | 'always'\n maxTraceDepth: number\n\n compiledRules: {\n client: {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n }\n server: {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n }\n }\n includeMatchers: Array<CompiledMatcher>\n excludeMatchers: Array<CompiledMatcher>\n ignoreImporterMatchers: Array<CompiledMatcher>\n\n markerSpecifiers: { serverOnly: Set<string>; clientOnly: Set<string> }\n envTypeMap: Map<string, 'client' | 'server'>\n\n onViolation?: (info: ViolationInfo) => boolean | void\n}\n\n/**\n * Per-Vite-environment mutable state. One instance per environment name,\n * stored in `envStates: Map<string, EnvState>`.\n *\n * All caches that previously lived on `PluginState` with `${envName}:` key\n * prefixes now live here without any prefix.\n */\ninterface EnvState {\n graph: ImportGraph\n /** Specifiers that resolved to the mock module (for transform-time rewriting). */\n deniedSources: Set<string>\n /** Per-importer denied edges (for dev ESM mock modules). */\n deniedEdges: Map<string, Set<string>>\n /**\n * During `vite dev` in mock mode, we generate a per-importer mock module that\n * exports the names the importer expects.\n * Populated in the transform hook (no disk reads).\n */\n mockExportsByImporter: Map<string, Map<string, Array<string>>>\n\n /** Resolve cache. Key: `${normalizedImporter}:${source}` (no env prefix). */\n resolveCache: Map<string, string | null>\n /** Reverse index: file path → Set of resolveCache keys involving that file. */\n resolveCacheByFile: Map<string, Set<string>>\n\n /** Import location cache. Key: `${importerFile}::${source}`. */\n importLocCache: Map<\n string,\n { file?: string; line: number; column: number } | null\n >\n /** Reverse index: file path → Set of importLocCache keys for that file. */\n importLocByFile: Map<string, Set<string>>\n\n /** Deduplication of logged violations (no env prefix in key). */\n seenViolations: Set<string>\n\n /** Transform result cache (code + composed sourcemap + original source). */\n transformResultCache: Map<string, TransformResult>\n /** Reverse index: physical file path → Set of transformResultCache keys. */\n transformResultKeysByFile: Map<string, Set<string>>\n}\n\n/**\n * Intentionally cross-env shared mutable state.\n *\n * A file's `'use server'`/`'use client'` directive is inherent to the file\n * content, not the environment that happens to discover it first.\n */\ninterface SharedState {\n fileMarkerKind: Map<string, 'server' | 'client'>\n}\n\nexport interface ImportProtectionPluginOptions {\n getConfig: GetConfigFn\n framework: CompileStartFrameworkOptions\n environments: Array<{ name: string; type: 'client' | 'server' }>\n providerEnvName: string\n}\n\nexport function importProtectionPlugin(\n opts: ImportProtectionPluginOptions,\n): PluginOption {\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: [] },\n server: { specifiers: [], files: [] },\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 // Internal helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Create a per-env `importLocCache` whose `.set` method automatically\n * maintains the reverse index (`importLocByFile`) for O(1) invalidation\n * in `hotUpdate`.\n *\n * Cache keys have the format `${importerFile}::${source}`.\n */\n function createImportLocCache(\n env: EnvState,\n ): Map<string, { file?: string; line: number; column: number } | null> {\n const cache = new Map<\n string,\n { file?: string; line: number; column: number } | null\n >()\n const originalSet = cache.set.bind(cache)\n cache.set = function (key, value) {\n originalSet(key, value)\n const sepIdx = key.indexOf('::')\n if (sepIdx !== -1) {\n const file = key.slice(0, sepIdx)\n let fileKeys = env.importLocByFile.get(file)\n if (!fileKeys) {\n fileKeys = new Set()\n env.importLocByFile.set(file, fileKeys)\n }\n fileKeys.add(key)\n }\n return this\n }\n return cache\n }\n\n function getMockEdgeExports(\n env: EnvState,\n importerId: string,\n source: string,\n ): Array<string> {\n const importerFile = normalizeFilePath(importerId)\n return env.mockExportsByImporter.get(importerFile)?.get(source) ?? []\n }\n\n function getMarkerKindForFile(\n fileId: string,\n ): 'server' | 'client' | undefined {\n const file = normalizeFilePath(fileId)\n return shared.fileMarkerKind.get(file)\n }\n\n /**\n * Build a {@link TransformResultProvider} for the given environment.\n *\n * The provider reads from the transform result cache that is populated by\n * the `tanstack-start-core:import-protection-transform-cache` plugin's\n * transform hook.\n */\n function getTransformResultProvider(env: EnvState): TransformResultProvider {\n return {\n getTransformResult(id: string) {\n // Try the full normalized ID first (preserves query params like\n // ?tsr-split=component for virtual modules).\n const fullKey = normalizePath(id)\n const exact = env.transformResultCache.get(fullKey)\n if (exact) return exact\n\n // Fall back to the query-stripped path for modules looked up by\n // their physical file path (e.g. trace steps, modules without\n // query params).\n const strippedKey = normalizeFilePath(id)\n return strippedKey !== fullKey\n ? env.transformResultCache.get(strippedKey)\n : undefined\n },\n }\n }\n\n type ViolationReporter = {\n warn: (msg: string) => void\n error: (msg: string) => never\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. Centralizing it eliminates the duplicated sequences of\n * `buildTrace` → `addTraceImportLocations` → location lookup → annotate →\n * snippet that previously appeared 5 times in the codebase.\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 ): Promise<ViolationInfo> {\n const trace = buildTrace(\n env.graph,\n normalizedImporter,\n config.maxTraceDepth,\n )\n await addTraceImportLocations(provider, trace, env.importLocCache)\n\n const loc =\n (await findPostCompileUsageLocation(\n provider,\n importer,\n source,\n findPostCompileUsagePos,\n )) ||\n (await findImportStatementLocationFromTransformed(\n provider,\n importer,\n source,\n env.importLocCache,\n ))\n\n // Annotate the last trace step with the denied import's specifier and\n // location so every trace step (including the leaf) gets file:line:col.\n if (trace.length > 0) {\n const last = trace[trace.length - 1]!\n if (!last.specifier) last.specifier = source\n if (loc && last.line == null) {\n last.line = loc.line\n last.column = loc.column\n }\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 maybeReportMarkerViolationFromResolvedImport(\n ctx: ViolationReporter,\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 opts?: { silent?: boolean },\n ): Promise<ReturnType<typeof handleViolation> | undefined> {\n const markerKind = getMarkerKindForFile(resolvedId)\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 const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'marker',\n resolved: normalizeFilePath(resolvedId),\n message:\n 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\n return handleViolation.call(ctx, env, info, opts)\n }\n\n function buildMockEdgeModuleId(\n env: EnvState,\n importerId: string,\n source: string,\n runtimeId: string,\n ): string {\n const exports = getMockEdgeExports(env, importerId, source)\n return makeMockEdgeModuleId(exports, source, runtimeId)\n }\n\n function getEnvType(envName: string): 'client' | 'server' {\n return config.envTypeMap.get(envName) ?? 'server'\n }\n\n function getRulesForEnvironment(envName: string): {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n } {\n const type = getEnvType(envName)\n return type === 'client'\n ? config.compiledRules.client\n : config.compiledRules.server\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 importLocByFile = new Map<string, Set<string>>()\n envState = {\n graph: new ImportGraph(),\n deniedSources: new Set(),\n deniedEdges: new Map(),\n mockExportsByImporter: new Map(),\n resolveCache: new Map(),\n resolveCacheByFile: new Map(),\n importLocCache: new Map(), // placeholder, replaced below\n importLocByFile,\n seenViolations: new Set(),\n transformResultCache: new Map(),\n transformResultKeysByFile: new Map(),\n }\n // Install reverse-index-maintaining importLocCache\n envState.importLocCache = createImportLocCache(envState)\n envStates.set(envName, envState)\n }\n return envState\n }\n\n function shouldCheckImporter(importer: string): boolean {\n // Normalize for matching\n const relativePath = path.relative(config.root, importer)\n\n // Check exclude first\n if (\n config.excludeMatchers.length > 0 &&\n matchesAny(relativePath, config.excludeMatchers)\n ) {\n return false\n }\n\n // Check ignore importers\n if (\n config.ignoreImporterMatchers.length > 0 &&\n matchesAny(relativePath, config.ignoreImporterMatchers)\n ) {\n return false\n }\n\n // Check include\n if (config.includeMatchers.length > 0) {\n return !!matchesAny(relativePath, config.includeMatchers)\n }\n\n // Default: check if within srcDirectory\n if (config.srcDirectory) {\n return importer.startsWith(config.srcDirectory)\n }\n\n return true\n }\n\n function dedupeKey(\n type: string,\n importer: string,\n specifier: string,\n resolved?: string,\n ): string {\n return `${type}:${importer}:${specifier}:${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 normalizePath(path.relative(config.root, absolutePath))\n }\n\n // ---------------------------------------------------------------------------\n // Vite plugins\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 // Determine if plugin is enabled\n if (userOpts?.enabled === false) {\n config.enabled = false\n return\n }\n\n config.enabled = true\n\n // Determine effective behavior\n if (userOpts?.behavior) {\n if (typeof userOpts.behavior === 'string') {\n config.effectiveBehavior = userOpts.behavior\n } else {\n config.effectiveBehavior =\n viteConfig.command === 'serve'\n ? (userOpts.behavior.dev ?? 'mock')\n : (userOpts.behavior.build ?? 'error')\n }\n } else {\n // Defaults: dev='mock', build='error'\n config.effectiveBehavior =\n viteConfig.command === 'serve' ? 'mock' : 'error'\n }\n\n // Log mode\n config.logMode = userOpts?.log ?? 'once'\n\n // Mock runtime access diagnostics\n config.mockAccess = userOpts?.mockAccess ?? 'error'\n\n // Max trace depth\n config.maxTraceDepth = userOpts?.maxTraceDepth ?? 20\n\n // User callback\n config.onViolation = userOpts?.onViolation as\n | ((info: ViolationInfo) => boolean | void)\n | undefined\n\n // Get default rules\n const defaults = getDefaultImportProtectionRules(opts.framework)\n\n // Merge user rules with defaults and compile matchers per env.\n // IMPORTANT: client specifier denies for Start server entrypoints must\n // always include the framework defaults even when the user provides a\n // custom list.\n const clientSpecifiers = dedupePatterns([\n ...defaults.client.specifiers,\n ...(userOpts?.client?.specifiers ?? []),\n ])\n\n // For file patterns, user config overrides defaults.\n const clientFiles = userOpts?.client?.files\n ? [...userOpts.client.files]\n : [...defaults.client.files]\n const serverSpecifiers = userOpts?.server?.specifiers\n ? dedupePatterns([...userOpts.server.specifiers])\n : dedupePatterns([...defaults.server.specifiers])\n const serverFiles = userOpts?.server?.files\n ? [...userOpts.server.files]\n : [...defaults.server.files]\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(clientFiles),\n }\n config.compiledRules.server = {\n specifiers: compileMatchers(serverSpecifiers),\n files: compileMatchers(serverFiles),\n }\n\n // Include/exclude\n if (userOpts?.include) {\n config.includeMatchers = compileMatchers(userOpts.include)\n }\n if (userOpts?.exclude) {\n config.excludeMatchers = compileMatchers(userOpts.exclude)\n }\n if (userOpts?.ignoreImporters) {\n config.ignoreImporterMatchers = compileMatchers(\n userOpts.ignoreImporters,\n )\n }\n\n // Marker specifiers\n const markers = getMarkerSpecifiers(opts.framework)\n config.markerSpecifiers = {\n serverOnly: new Set(markers.serverOnly),\n clientOnly: new Set(markers.clientOnly),\n }\n\n // Use known Start env entrypoints as trace roots.\n // This makes traces deterministic and prevents 1-line traces.\n for (const envDef of opts.environments) {\n const envState = getEnv(envDef.name)\n\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 buildStart() {\n if (!config.enabled) return\n // Clear per-env caches\n for (const envState of envStates.values()) {\n envState.resolveCache.clear()\n envState.resolveCacheByFile.clear()\n envState.importLocCache.clear()\n envState.importLocByFile.clear()\n envState.seenViolations.clear()\n envState.transformResultCache.clear()\n envState.transformResultKeysByFile.clear()\n envState.graph.clear()\n envState.deniedSources.clear()\n envState.deniedEdges.clear()\n envState.mockExportsByImporter.clear()\n }\n\n // Clear shared state\n shared.fileMarkerKind.clear()\n\n // Re-add known entries after clearing.\n for (const envDef of opts.environments) {\n const envState = getEnv(envDef.name)\n const { resolvedStartConfig } = opts.getConfig()\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 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 shared.fileMarkerKind.delete(importerFile)\n\n // Invalidate per-env caches\n for (const envState of envStates.values()) {\n // Invalidate cached import locations using reverse index\n const locKeys = envState.importLocByFile.get(importerFile)\n if (locKeys) {\n for (const key of locKeys) {\n envState.importLocCache.delete(key)\n }\n envState.importLocByFile.delete(importerFile)\n }\n\n // Invalidate resolve cache using reverse index\n const resolveKeys = envState.resolveCacheByFile.get(importerFile)\n if (resolveKeys) {\n for (const key of resolveKeys) {\n envState.resolveCache.delete(key)\n }\n envState.resolveCacheByFile.delete(importerFile)\n }\n\n // Invalidate graph edges\n envState.graph.invalidate(importerFile)\n envState.deniedEdges.delete(importerFile)\n envState.mockExportsByImporter.delete(importerFile)\n\n // Invalidate transform result cache for this file.\n const transformKeys =\n envState.transformResultKeysByFile.get(importerFile)\n if (transformKeys) {\n for (const key of transformKeys) {\n envState.transformResultCache.delete(key)\n }\n envState.transformResultKeysByFile.delete(importerFile)\n } else {\n // Fallback: at least clear the physical-file entry.\n envState.transformResultCache.delete(importerFile)\n }\n }\n }\n }\n },\n\n async resolveId(source, importer, _options) {\n if (!config.enabled) return undefined\n const envName = this.environment.name\n const env = getEnv(envName)\n const envType = getEnvType(envName)\n const provider = getTransformResultProvider(env)\n\n // Internal virtual modules must resolve in dev.\n if (source === MOCK_MODULE_ID) {\n return RESOLVED_MOCK_MODULE_ID\n }\n if (source.startsWith(MOCK_EDGE_PREFIX)) {\n return resolveViteId(source)\n }\n if (source.startsWith(MOCK_RUNTIME_PREFIX)) {\n return resolveViteId(source)\n }\n if (source.startsWith(MARKER_PREFIX)) {\n return resolveViteId(source)\n }\n\n // Skip if no importer (entry points)\n if (!importer) {\n // Track entry-ish modules so traces can terminate.\n // Vite may pass virtual ids here; normalize but keep them.\n env.graph.addEntry(source)\n return undefined\n }\n\n // Skip virtual modules\n if (source.startsWith('\\0') || source.startsWith('virtual:')) {\n return undefined\n }\n\n // Two code paths resolve imports from raw (pre-compiler-transform)\n // source in dev mode:\n //\n // 1. The Start compiler calls `fetchModule(id + '?' + SERVER_FN_LOOKUP)`\n // to inspect a child module's exports. The compiler's own transform\n // is excluded for these requests, so Vite sees the original imports.\n //\n // 2. Vite's dep-optimizer scanner (`options.scan === true`) uses esbuild\n // to discover bare imports for pre-bundling. esbuild reads raw source\n // without running Vite transform hooks, so it also sees imports that\n // the compiler would normally strip.\n //\n // In both cases the imports are NOT real client-side imports. We must\n // suppress violation *reporting* (no warnings / errors) but still return\n // mock module IDs so that transitive resolution doesn't blow up.\n const isPreTransformResolve =\n importer.includes('?' + SERVER_FN_LOOKUP) ||\n !!(_options as Record<string, unknown>).scan\n\n // Check if this is a marker import\n if (config.markerSpecifiers.serverOnly.has(source)) {\n // Record importer as server-only\n const resolvedImporter = normalizeFilePath(importer)\n const existing = shared.fileMarkerKind.get(resolvedImporter)\n if (existing && existing !== 'server') {\n this.error(\n `[import-protection] File \"${getRelativePath(resolvedImporter)}\" has both server-only and client-only markers. This is not allowed.`,\n )\n }\n shared.fileMarkerKind.set(resolvedImporter, 'server')\n\n // If we're in the client environment, this is a violation\n if (envType === 'client') {\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n resolvedImporter,\n source,\n {\n type: 'marker',\n message: `Module \"${getRelativePath(resolvedImporter)}\" is marked server-only but is imported in the client environment`,\n },\n )\n handleViolation.call(this, env, info, {\n silent: isPreTransformResolve,\n })\n }\n\n // Return virtual empty module\n return resolveViteId(`${MARKER_PREFIX}server-only`)\n }\n\n if (config.markerSpecifiers.clientOnly.has(source)) {\n const resolvedImporter = normalizeFilePath(importer)\n const existing = shared.fileMarkerKind.get(resolvedImporter)\n if (existing && existing !== 'client') {\n this.error(\n `[import-protection] File \"${getRelativePath(resolvedImporter)}\" has both server-only and client-only markers. This is not allowed.`,\n )\n }\n shared.fileMarkerKind.set(resolvedImporter, 'client')\n\n if (envType === 'server') {\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n resolvedImporter,\n source,\n {\n type: 'marker',\n message: `Module \"${getRelativePath(resolvedImporter)}\" is marked client-only but is imported in the server environment`,\n },\n )\n handleViolation.call(this, env, info, {\n silent: isPreTransformResolve,\n })\n }\n\n return resolveViteId(`${MARKER_PREFIX}client-only`)\n }\n\n // Check if the importer is within our scope\n const normalizedImporter = normalizeFilePath(importer)\n if (!shouldCheckImporter(normalizedImporter)) {\n return undefined\n }\n\n const matchers = getRulesForEnvironment(envName)\n\n // 1. Specifier-based denial (fast, no resolution needed)\n const specifierMatch = matchesAny(source, matchers.specifiers)\n if (specifierMatch) {\n env.graph.addEdge(source, normalizedImporter, source)\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 \"${envName}\" environment`,\n },\n )\n return handleViolation.call(this, env, info, {\n silent: isPreTransformResolve,\n })\n }\n\n // 2. Resolve the import (cached) — needed for file-based denial,\n // marker checks, and graph edge tracking.\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 const result = await this.resolve(source, importer, {\n skipSelf: true,\n })\n resolved = result ? normalizeFilePath(result.id) : null\n env.resolveCache.set(cacheKey, resolved)\n\n // Maintain reverse index for O(1) hotUpdate invalidation.\n // Index by the importer so that when a file changes, all resolve\n // cache entries where it was the importer are cleared.\n let fileKeys = env.resolveCacheByFile.get(normalizedImporter)\n if (!fileKeys) {\n fileKeys = new Set()\n env.resolveCacheByFile.set(normalizedImporter, fileKeys)\n }\n fileKeys.add(cacheKey)\n }\n\n if (resolved) {\n const relativePath = getRelativePath(resolved)\n\n // Always record the edge for trace building, even when not denied.\n env.graph.addEdge(resolved, normalizedImporter, source)\n\n // File-based denial check\n const fileMatch =\n matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n\n if (fileMatch) {\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'file',\n pattern: fileMatch.pattern,\n resolved,\n message: `Import \"${source}\" (resolved to \"${relativePath}\") is denied in the \"${envName}\" environment`,\n },\n )\n return handleViolation.call(this, env, info, {\n silent: isPreTransformResolve,\n })\n }\n\n // Marker restrictions apply regardless of explicit deny rules.\n const markerRes = await maybeReportMarkerViolationFromResolvedImport(\n this,\n provider,\n env,\n envName,\n envType,\n importer,\n source,\n resolved,\n relativePath,\n { silent: isPreTransformResolve },\n )\n if (markerRes !== undefined) {\n return markerRes\n }\n }\n\n return undefined\n },\n\n load: {\n filter: {\n id: new RegExp(\n `(${RESOLVED_MOCK_MODULE_ID.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}|${RESOLVED_MARKER_PREFIX.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}|${RESOLVED_MOCK_EDGE_PREFIX.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}|${RESOLVED_MOCK_RUNTIME_PREFIX.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')})`,\n ),\n },\n handler(id) {\n if (!config.enabled) return undefined\n if (id === RESOLVED_MOCK_MODULE_ID) {\n return loadSilentMockModule()\n }\n\n if (id.startsWith(RESOLVED_MOCK_EDGE_PREFIX)) {\n return loadMockEdgeModule(\n id.slice(RESOLVED_MOCK_EDGE_PREFIX.length),\n )\n }\n\n if (id.startsWith(RESOLVED_MOCK_RUNTIME_PREFIX)) {\n return loadMockRuntimeModule(\n id.slice(RESOLVED_MOCK_RUNTIME_PREFIX.length),\n )\n }\n\n if (id.startsWith(RESOLVED_MARKER_PREFIX)) {\n return loadMarkerModule()\n }\n\n return undefined\n },\n },\n },\n {\n // This plugin runs WITHOUT `enforce` so it executes after all\n // `enforce: 'pre'` transform hooks (including the Start compiler).\n // It captures the transformed code + composed sourcemap for every module\n // so that the `resolveId` hook (in the main plugin above) can look up\n // the importer's transform result and map violation locations back to\n // original source.\n //\n // Why not use `ctx.load()` in `resolveId`?\n // - Vite dev: `this.load()` returns a ModuleInfo proxy that throws on\n // `.code` access — code is not exposed.\n // - Rollup build: `ModuleInfo` has `.code` but NOT `.map`, so we\n // can't map generated positions back to original source.\n //\n // By caching in the transform hook we get both code and the composed\n // sourcemap that chains all the way back to the original file.\n //\n // Performance: only files under `srcDirectory` are cached because only\n // those can be importers in a violation. Third-party code in\n // node_modules is never checked.\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 handler(code, id) {\n if (!config.enabled) return undefined\n const envName = this.environment.name\n const file = normalizeFilePath(id)\n\n // Only cache files that could ever be checked as an importer.\n // This reuses the same include/exclude/ignoreImporters predicate as\n // the main import-protection resolveId hook.\n if (!shouldCheckImporter(file)) {\n return undefined\n }\n\n // getCombinedSourcemap() returns the composed sourcemap of all\n // transform hooks that ran before this one. It includes\n // sourcesContent so we can extract original source later.\n let map: SourceMapLike | undefined\n try {\n map = this.getCombinedSourcemap()\n } catch {\n // No sourcemap available (e.g. virtual modules or modules\n // that no prior plugin produced a map for).\n map = undefined\n }\n\n // Extract the original source from sourcesContent right here.\n // Composed sourcemaps can contain multiple sources; try to pick the\n // entry that best matches this importer.\n let originalCode: string | undefined\n if (map?.sourcesContent) {\n originalCode = pickOriginalCodeFromSourcesContent(\n map,\n file,\n config.root,\n )\n }\n\n // Precompute a line index for fast index->line/col conversions.\n const lineIndex = buildLineIndex(code)\n\n // Key by the full normalized module ID including query params\n // (e.g. \"src/routes/index.tsx?tsr-split=component\") so that\n // virtual modules derived from the same physical file each get\n // their own cache entry.\n const cacheKey = normalizePath(id)\n const envState = getEnv(envName)\n envState.transformResultCache.set(cacheKey, {\n code,\n map,\n originalCode,\n lineIndex,\n })\n\n // Maintain reverse index so hotUpdate invalidation is O(keys for file).\n let keySet = envState.transformResultKeysByFile.get(file)\n if (!keySet) {\n keySet = new Set<string>()\n envState.transformResultKeysByFile.set(file, keySet)\n }\n keySet.add(cacheKey)\n\n // Also store/update the stripped-path entry so that lookups by\n // physical file path (e.g. from trace steps in the import graph,\n // which normalize away query params) still find a result.\n // The last variant transformed wins, which is acceptable — trace\n // lookups are best-effort for line numbers.\n if (cacheKey !== file) {\n envState.transformResultCache.set(file, {\n code,\n map,\n originalCode,\n lineIndex,\n })\n keySet.add(file)\n }\n\n // Return nothing — we don't modify the code.\n return undefined\n },\n },\n },\n {\n // Separate plugin so the transform can be enabled/disabled per-environment.\n name: 'tanstack-start-core:import-protection-mock-rewrite',\n enforce: 'pre',\n\n // Only needed during dev. In build, we rely on Rollup's syntheticNamedExports.\n apply: 'serve',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n // Only needed in mock mode — when not mocking, there is nothing to\n // record. applyToEnvironment runs after configResolved, so\n // config.effectiveBehavior is already set.\n if (config.effectiveBehavior !== 'mock') return false\n // We record expected named exports per importer in all Start Vite\n // environments during dev so mock-edge modules can provide explicit\n // ESM named exports.\n return environmentNames.has(env.name)\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[cm]?[tj]sx?($|\\?)/],\n },\n },\n handler(code, id) {\n if (!config.enabled) return undefined\n const envName = this.environment.name\n const envState = envStates.get(envName)\n if (!envState) return undefined\n\n // Record export names per source for this importer so we can generate\n // dev mock-edge modules without any disk reads.\n try {\n const importerFile = normalizeFilePath(id)\n envState.mockExportsByImporter.set(\n importerFile,\n collectMockExportNamesBySource(code),\n )\n } catch {\n // Best-effort only\n }\n\n // Note: we no longer rewrite imports here.\n // Dev uses per-importer mock-edge modules in resolveId so native ESM\n // has explicit named exports, and runtime diagnostics are handled by\n // the mock runtime proxy when those mocks are actually invoked.\n return undefined\n },\n },\n },\n ] satisfies Array<PluginOption>\n\n // ---------------------------------------------------------------------------\n // Violation handling\n // ---------------------------------------------------------------------------\n\n function handleViolation(\n this: { warn: (msg: string) => void; error: (msg: string) => never },\n env: EnvState,\n info: ViolationInfo,\n opts?: { silent?: boolean },\n ): { id: string; syntheticNamedExports: boolean } | string | undefined {\n const key = dedupeKey(\n info.type,\n info.importer,\n info.specifier,\n info.resolved,\n )\n\n if (!opts?.silent) {\n // Call user callback\n if (config.onViolation) {\n const result = config.onViolation(info)\n if (result === false) {\n return undefined\n }\n }\n\n const seen = hasSeen(env, key)\n\n if (config.effectiveBehavior === 'error') {\n if (!seen) this.error(formatViolation(info, config.root))\n return undefined\n }\n\n // Mock mode: log once, but always return the mock module.\n if (!seen) {\n this.warn(formatViolation(info, config.root))\n }\n } else {\n // Silent mode: in error behavior, skip entirely (no mock needed\n // for compiler-internal lookups); in mock mode, fall through to\n // return the mock module ID without logging.\n if (config.effectiveBehavior === 'error') {\n return undefined\n }\n }\n\n env.deniedSources.add(info.specifier)\n let edgeSet = env.deniedEdges.get(info.importer)\n if (!edgeSet) {\n edgeSet = new Set<string>()\n env.deniedEdges.set(info.importer, edgeSet)\n }\n edgeSet.add(info.specifier)\n\n if (config.command === 'serve') {\n const runtimeId = mockRuntimeModuleIdFromViolation(\n info,\n config.mockAccess,\n config.root,\n )\n return resolveViteId(\n buildMockEdgeModuleId(env, info.importer, info.specifier, runtimeId),\n )\n }\n\n // Build: Rollup can synthesize named exports.\n return { id: RESOLVED_MOCK_MODULE_ID, syntheticNamedExports: true }\n }\n}\n"],"names":["opts"],"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 { SERVER_FN_LOOKUP } from '../start-compiler-plugin/plugin'\nimport { ImportGraph, buildTrace, formatViolation } from './trace'\nimport {\n getDefaultImportProtectionRules,\n getMarkerSpecifiers,\n} from './defaults'\nimport { findPostCompileUsagePos } from './postCompileUsage'\nimport { compileMatchers, matchesAny } from './matchers'\nimport {\n clearNormalizeFilePathCache,\n dedupePatterns,\n escapeRegExp,\n extractImportSources,\n getOrCreate,\n normalizeFilePath,\n relativizePath,\n} from './utils'\nimport { collectMockExportNamesBySource } from './rewriteDeniedImports'\nimport {\n MARKER_PREFIX,\n MOCK_EDGE_PREFIX,\n MOCK_MODULE_ID,\n MOCK_RUNTIME_PREFIX,\n RESOLVED_MARKER_PREFIX,\n RESOLVED_MOCK_EDGE_PREFIX,\n RESOLVED_MOCK_MODULE_ID,\n RESOLVED_MOCK_RUNTIME_PREFIX,\n loadMarkerModule,\n loadMockEdgeModule,\n loadMockRuntimeModule,\n loadSilentMockModule,\n makeMockEdgeModuleId,\n mockRuntimeModuleIdFromViolation,\n} from './virtualModules'\nimport {\n ImportLocCache,\n addTraceImportLocations,\n buildCodeSnippet,\n buildLineIndex,\n clearImportPatternCache,\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 {\n ImportProtectionBehavior,\n ImportProtectionOptions,\n} from '../schema'\nimport type { CompileStartFrameworkOptions, GetConfigFn } from '../types'\n\nconst SERVER_FN_LOOKUP_QUERY = '?' + SERVER_FN_LOOKUP\nconst RESOLVED_MARKER_SERVER_ONLY = resolveViteId(`${MARKER_PREFIX}server-only`)\nconst RESOLVED_MARKER_CLIENT_ONLY = resolveViteId(`${MARKER_PREFIX}client-only`)\n\nconst IMPORT_PROTECTION_DEBUG =\n process.env.TSR_IMPORT_PROTECTION_DEBUG === '1' ||\n process.env.TSR_IMPORT_PROTECTION_DEBUG === 'true'\nconst IMPORT_PROTECTION_DEBUG_FILTER =\n process.env.TSR_IMPORT_PROTECTION_DEBUG_FILTER\n\nfunction debugLog(...args: Array<unknown>) {\n if (!IMPORT_PROTECTION_DEBUG) return\n console.warn('[import-protection:debug]', ...args)\n}\n\n/** Check if a value matches the debug filter (when set). */\nfunction matchesDebugFilter(...values: Array<string>): boolean {\n if (!IMPORT_PROTECTION_DEBUG_FILTER) return true\n return values.some((v) => v.includes(IMPORT_PROTECTION_DEBUG_FILTER))\n}\n\nexport { RESOLVED_MOCK_MODULE_ID } from './virtualModules'\nexport { rewriteDeniedImports } from './rewriteDeniedImports'\nexport { dedupePatterns, extractImportSources } from './utils'\nexport type { Pattern } from './utils'\n\n/**\n * Immutable plugin configuration — set once in `configResolved`, never mutated\n * per-env or per-request afterward.\n */\ninterface PluginConfig {\n enabled: boolean\n root: string\n command: 'build' | 'serve'\n srcDirectory: string\n framework: CompileStartFrameworkOptions\n\n /** Absolute, query-free entry file ids used for trace roots. */\n entryFiles: Array<string>\n\n effectiveBehavior: ImportProtectionBehavior\n mockAccess: 'error' | 'warn' | 'off'\n logMode: 'once' | 'always'\n maxTraceDepth: number\n\n compiledRules: {\n client: {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n }\n server: {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n }\n }\n includeMatchers: Array<CompiledMatcher>\n excludeMatchers: Array<CompiledMatcher>\n ignoreImporterMatchers: Array<CompiledMatcher>\n\n markerSpecifiers: { serverOnly: Set<string>; clientOnly: Set<string> }\n envTypeMap: Map<string, 'client' | 'server'>\n\n onViolation?: (info: ViolationInfo) => boolean | void\n}\n\n/**\n * Per-Vite-environment mutable state. One instance per environment name,\n * stored in `envStates: Map<string, EnvState>`.\n *\n * All caches that previously lived on `PluginState` with `${envName}:` key\n * prefixes now live here without any prefix.\n */\ninterface EnvState {\n graph: ImportGraph\n /** Specifiers that resolved to the mock module (for transform-time rewriting). */\n deniedSources: Set<string>\n /** Per-importer denied edges (for dev ESM mock modules). */\n deniedEdges: Map<string, Set<string>>\n /**\n * During `vite dev` in mock mode, we generate a per-importer mock module that\n * exports the names the importer expects.\n * Populated in the transform hook (no disk reads).\n */\n mockExportsByImporter: Map<string, Map<string, Array<string>>>\n\n /** Resolve cache. Key: `${normalizedImporter}:${source}` (no env prefix). */\n resolveCache: Map<string, string | null>\n /** Reverse index: file path → Set of resolveCache keys involving that file. */\n resolveCacheByFile: Map<string, Set<string>>\n\n /** Import location cache. Key: `${importerFile}::${source}`. */\n importLocCache: ImportLocCache\n\n /** Deduplication of logged violations (no env prefix in key). */\n seenViolations: Set<string>\n\n /**\n * Modules transitively loaded during a `fetchModule(?SERVER_FN_LOOKUP)` call.\n * In dev mode the compiler calls `fetchModule(id + '?' + SERVER_FN_LOOKUP)` to\n * analyse a module's exports. The direct target carries the query parameter so\n * `isPreTransformResolve` is `true`. But Vite also resolves the target's own\n * imports (and their imports, etc.) with the plain file path as the importer —\n * those would otherwise fire false-positive violations.\n *\n * We record every module resolved while walking a SERVER_FN_LOOKUP chain so\n * that their child imports are also treated as pre-transform resolves.\n */\n serverFnLookupModules: Set<string>\n\n /** Transform result cache (code + composed sourcemap + original source). */\n transformResultCache: Map<string, TransformResult>\n /** Reverse index: physical file path → Set of transformResultCache keys. */\n transformResultKeysByFile: Map<string, Set<string>>\n\n /** Cached provider that reads from {@link transformResultCache}. */\n transformResultProvider: TransformResultProvider\n\n /**\n * Post-transform resolved imports. Populated by the transform-cache hook\n * after resolving every import source found in the transformed code.\n * Key: transform cache key (normalised module ID incl. query params).\n * Value: set of resolved child file paths.\n */\n postTransformImports: Map<string, Set<string>>\n\n /**\n * Whether a `resolveId` call without an importer has been observed for this\n * environment since `buildStart`. Vite calls `resolveId(source, undefined)`\n * for true entry modules during a cold start. On warm start (`.vite` cache\n * exists), Vite reuses its module graph and does NOT call `resolveId` for\n * entries, so this stays `false`.\n *\n * When `false`, the import graph is considered unreliable (edges may be\n * missing) and violations are reported immediately instead of deferred.\n */\n hasSeenEntry: boolean\n\n /**\n * Violations deferred in dev mock mode. Keyed by the violating importer's\n * normalized file path. Violations are confirmed or discarded by the\n * transform-cache hook once enough post-transform data is available to\n * determine whether the importer is still reachable from an entry point.\n */\n pendingViolations: Map<string, Array<PendingViolation>>\n}\n\ninterface PendingViolation {\n info: ViolationInfo\n /** The mock module ID that resolveId already returned for this violation. */\n mockReturnValue: string\n}\n\n/**\n * Intentionally cross-env shared mutable state.\n *\n * A file's `'use server'`/`'use client'` directive is inherent to the file\n * content, not the environment that happens to discover it first.\n */\ninterface SharedState {\n fileMarkerKind: Map<string, 'server' | 'client'>\n}\n\nexport interface ImportProtectionPluginOptions {\n getConfig: GetConfigFn\n framework: CompileStartFrameworkOptions\n environments: Array<{ name: string; type: 'client' | 'server' }>\n providerEnvName: string\n}\n\nexport function importProtectionPlugin(\n opts: ImportProtectionPluginOptions,\n): PluginOption {\n let devServer: ViteDevServer | null = null\n\n type ModuleGraphNode = {\n id?: string | null\n url?: string\n importers: Set<ModuleGraphNode>\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 entryFiles: [],\n effectiveBehavior: 'error',\n mockAccess: 'error',\n logMode: 'once',\n maxTraceDepth: 20,\n compiledRules: {\n client: { specifiers: [], files: [] },\n server: { specifiers: [], files: [] },\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 function getMarkerKindForFile(\n fileId: string,\n ): 'server' | 'client' | undefined {\n const file = normalizeFilePath(fileId)\n return shared.fileMarkerKind.get(file)\n }\n\n type ViolationReporter = {\n warn: (msg: string) => void\n error: (msg: string) => never\n }\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(provider, trace, env.importLocCache)\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 loc =\n (await findPostCompileUsageLocation(\n provider,\n importer,\n source,\n findPostCompileUsagePos,\n )) ||\n (await findImportStatementLocationFromTransformed(\n provider,\n importer,\n source,\n env.importLocCache,\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 /**\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 markerKind = getMarkerKindForFile(resolvedId)\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: normalizeFilePath(resolvedId),\n message:\n 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 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): {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n } {\n const type = getEnvType(envName)\n return type === 'client'\n ? config.compiledRules.client\n : config.compiledRules.server\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 deniedSources: new Set(),\n deniedEdges: new Map(),\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 hasSeenEntry: false,\n serverFnLookupModules: new Set(),\n pendingViolations: new Map(),\n }\n envStates.set(envName, envState)\n }\n return envState\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 if (\n config.excludeMatchers.length > 0 &&\n matchesAny(relativePath, config.excludeMatchers)\n ) {\n result = false\n } else if (\n config.ignoreImporterMatchers.length > 0 &&\n matchesAny(relativePath, config.ignoreImporterMatchers)\n ) {\n result = false\n } else if (config.includeMatchers.length > 0) {\n result = !!matchesAny(relativePath, config.includeMatchers)\n } else if (config.srcDirectory) {\n result = importer.startsWith(config.srcDirectory)\n } else {\n result = true\n }\n\n shouldCheckImporterCache.set(importer, result)\n return result\n }\n\n function dedupeKey(\n type: string,\n importer: string,\n specifier: string,\n resolved?: string,\n ): string {\n return `${type}:${importer}:${specifier}:${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 /** 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 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 // Walk reverse edges\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\n // Check all code-split variants for this parent. The edge is\n // live if ANY variant's resolved imports include `current`.\n const keySet = env.transformResultKeysByFile.get(parent)\n let anyVariantCached = false\n let edgeLive = false\n\n if (keySet) {\n for (const k of keySet) {\n const resolvedImports = env.postTransformImports.get(k)\n if (resolvedImports) {\n anyVariantCached = true\n if (resolvedImports.has(current)) {\n edgeLive = true\n break\n }\n }\n }\n }\n\n // Fallback: direct file-path key\n if (!anyVariantCached) {\n const resolvedImports = env.postTransformImports.get(parent)\n if (resolvedImports) {\n anyVariantCached = true\n if (resolvedImports.has(current)) {\n edgeLive = true\n }\n }\n }\n\n if (!anyVariantCached) {\n const hasTransformResult =\n env.transformResultCache.has(parent) ||\n (keySet ? keySet.size > 0 : false)\n\n if (hasTransformResult) {\n // Transform ran but postTransformImports not yet populated\n hasUnknownEdge = true\n continue\n }\n\n // Transform never ran — Vite served from cache (warm start).\n // Conservatively treat edge as live.\n queue.push(parent)\n continue\n }\n\n if (edgeLive) {\n queue.push(parent)\n }\n }\n }\n\n return hasUnknownEdge ? 'unknown' : 'unreachable'\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 // On warm start, skip graph reachability — confirm immediately.\n const status = env.hasSeenEntry\n ? checkPostTransformReachability(env, file)\n : 'reachable'\n\n if (status === 'reachable') {\n for (const pv of violations) {\n const key = dedupeKey(\n pv.info.type,\n pv.info.importer,\n pv.info.specifier,\n pv.info.resolved,\n )\n if (!hasSeen(env, key)) {\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 = config.onViolation(pv.info)\n if (result === false) continue\n }\n warnFn(formatViolation(pv.info, config.root))\n }\n }\n toDelete.push(file)\n } else if (status === 'unreachable') {\n toDelete.push(file)\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 /**\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 mockReturnValue:\n | { id: string; syntheticNamedExports: boolean }\n | string\n | undefined,\n ): void {\n getOrCreate(env.pendingViolations, importerFile, () => []).push({\n info,\n mockReturnValue:\n typeof mockReturnValue === 'string'\n ? mockReturnValue\n : (mockReturnValue?.id ?? ''),\n })\n }\n\n function handleViolation(\n ctx: ViolationReporter,\n env: EnvState,\n info: ViolationInfo,\n violationOpts?: { silent?: boolean },\n ): { id: string; syntheticNamedExports: boolean } | string | undefined {\n const key = dedupeKey(\n info.type,\n info.importer,\n info.specifier,\n info.resolved,\n )\n\n if (!violationOpts?.silent) {\n if (config.onViolation) {\n const result = config.onViolation(info)\n if (result === false) {\n return undefined\n }\n }\n\n const seen = hasSeen(env, key)\n\n if (config.effectiveBehavior === 'error') {\n if (!seen) ctx.error(formatViolation(info, config.root))\n return undefined\n }\n\n if (!seen) {\n ctx.warn(formatViolation(info, config.root))\n }\n } else {\n if (config.effectiveBehavior === 'error') {\n return undefined\n }\n }\n\n env.deniedSources.add(info.specifier)\n getOrCreate(env.deniedEdges, info.importer, () => new Set<string>()).add(\n info.specifier,\n )\n\n if (config.command === 'serve') {\n const runtimeId = mockRuntimeModuleIdFromViolation(\n info,\n config.mockAccess,\n config.root,\n )\n const importerFile = normalizeFilePath(info.importer)\n const exports =\n env.mockExportsByImporter.get(importerFile)?.get(info.specifier) ?? []\n return resolveViteId(\n makeMockEdgeModuleId(exports, info.specifier, runtimeId),\n )\n }\n\n // Build: Rollup uses syntheticNamedExports\n return { id: RESOLVED_MOCK_MODULE_ID, syntheticNamedExports: true }\n }\n\n /**\n * Unified violation dispatch: either defers or reports immediately.\n *\n * When `shouldDefer` is true, calls `handleViolation` silently to obtain\n * the mock module ID, stores the violation as pending, and triggers\n * `processPendingViolations`. Otherwise reports (or silences for\n * pre-transform resolves) immediately.\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 info: ViolationInfo,\n shouldDefer: boolean,\n isPreTransformResolve: boolean,\n ): Promise<ReturnType<typeof handleViolation>> {\n if (shouldDefer) {\n const result = handleViolation(ctx, env, info, { silent: true })\n deferViolation(env, importerFile, info, result)\n await processPendingViolations(env, ctx.warn.bind(ctx))\n return result\n }\n return handleViolation(ctx, env, info, {\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 config.entryFiles = [\n resolvedStartConfig.routerFilePath,\n resolvedStartConfig.startFilePath,\n ].filter((f): f is string => Boolean(f))\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 if (userOpts?.behavior) {\n if (typeof userOpts.behavior === 'string') {\n config.effectiveBehavior = userOpts.behavior\n } else {\n config.effectiveBehavior =\n viteConfig.command === 'serve'\n ? (userOpts.behavior.dev ?? 'mock')\n : (userOpts.behavior.build ?? 'error')\n }\n } else {\n config.effectiveBehavior =\n viteConfig.command === 'serve' ? 'mock' : '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\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 const clientFiles = userOpts?.client?.files\n ? [...userOpts.client.files]\n : [...defaults.client.files]\n const serverSpecifiers = userOpts?.server?.specifiers\n ? dedupePatterns([...userOpts.server.specifiers])\n : dedupePatterns([...defaults.server.specifiers])\n const serverFiles = userOpts?.server?.files\n ? [...userOpts.server.files]\n : [...defaults.server.files]\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(clientFiles),\n }\n config.compiledRules.server = {\n specifiers: compileMatchers(serverSpecifiers),\n files: compileMatchers(serverFiles),\n }\n\n // Include/exclude\n if (userOpts?.include) {\n config.includeMatchers = compileMatchers(userOpts.include)\n }\n if (userOpts?.exclude) {\n config.excludeMatchers = compileMatchers(userOpts.exclude)\n }\n if (userOpts?.ignoreImporters) {\n config.ignoreImporterMatchers = compileMatchers(\n userOpts.ignoreImporters,\n )\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 clearImportPatternCache()\n shouldCheckImporterCache.clear()\n\n // Clear per-env caches\n for (const envState of envStates.values()) {\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.hasSeenEntry = false\n envState.serverFnLookupModules.clear()\n envState.graph.clear()\n envState.deniedSources.clear()\n envState.deniedEdges.clear()\n envState.mockExportsByImporter.clear()\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 shared.fileMarkerKind.delete(importerFile)\n\n // Invalidate per-env caches\n for (const envState of envStates.values()) {\n envState.importLocCache.deleteByFile(importerFile)\n\n // Invalidate resolve cache using reverse index\n const resolveKeys = envState.resolveCacheByFile.get(importerFile)\n if (resolveKeys) {\n for (const key of resolveKeys) {\n envState.resolveCache.delete(key)\n }\n envState.resolveCacheByFile.delete(importerFile)\n }\n\n // Invalidate graph edges\n envState.graph.invalidate(importerFile)\n envState.deniedEdges.delete(importerFile)\n envState.mockExportsByImporter.delete(importerFile)\n envState.serverFnLookupModules.delete(importerFile)\n envState.pendingViolations.delete(importerFile)\n\n // Invalidate transform result cache for this file.\n const transformKeys =\n envState.transformResultKeysByFile.get(importerFile)\n if (transformKeys) {\n for (const key of transformKeys) {\n envState.transformResultCache.delete(key)\n envState.postTransformImports.delete(key)\n }\n envState.transformResultKeysByFile.delete(importerFile)\n } else {\n // Fallback: at least clear the physical-file entry.\n envState.transformResultCache.delete(importerFile)\n envState.postTransformImports.delete(importerFile)\n }\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 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 hasSeenEntry: env.hasSeenEntry,\n command: config.command,\n behavior: config.effectiveBehavior,\n })\n }\n }\n\n // Internal virtual modules\n if (source === MOCK_MODULE_ID) {\n return RESOLVED_MOCK_MODULE_ID\n }\n if (source.startsWith(MOCK_EDGE_PREFIX)) {\n return resolveViteId(source)\n }\n if (source.startsWith(MOCK_RUNTIME_PREFIX)) {\n return resolveViteId(source)\n }\n if (source.startsWith(MARKER_PREFIX)) {\n return resolveViteId(source)\n }\n\n if (!importer) {\n env.graph.addEntry(source)\n env.hasSeenEntry = true\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 violations until post-transform data is\n // available, then confirm/discard via graph reachability.\n const isDevMock =\n config.command === 'serve' && config.effectiveBehavior === 'mock'\n\n const shouldDefer = isDevMock && !isPreTransformResolve\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:\n markerKind === 'server'\n ? `Module \"${getRelativePath(normalizedImporter)}\" is marked server-only but is imported in the client environment`\n : `Module \"${getRelativePath(normalizedImporter)}\" is marked client-only but is imported in the server environment`,\n },\n )\n await reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n\n return markerKind === 'server'\n ? RESOLVED_MARKER_SERVER_ONLY\n : RESOLVED_MARKER_CLIENT_ONLY\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 env.graph.addEdge(source, normalizedImporter, source)\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 return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\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 const result = await this.resolve(source, importer, {\n skipSelf: true,\n })\n resolved = result ? normalizeFilePath(result.id) : null\n env.resolveCache.set(cacheKey, resolved)\n getOrCreate(\n env.resolveCacheByFile,\n normalizedImporter,\n () => new Set(),\n ).add(cacheKey)\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 env.graph.addEdge(resolved, normalizedImporter, source)\n\n const fileMatch =\n matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n\n if (fileMatch) {\n const info = await buildViolationInfo(\n provider,\n env,\n envName,\n envType,\n importer,\n normalizedImporter,\n source,\n {\n type: 'file',\n pattern: fileMatch.pattern,\n resolved,\n message: `Import \"${source}\" (resolved to \"${relativePath}\") is denied in the ${envType} environment`,\n },\n )\n return reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\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 markerInfo,\n shouldDefer,\n isPreTransformResolve,\n )\n }\n }\n\n return undefined\n },\n\n load: {\n filter: {\n id: new RegExp(\n [\n RESOLVED_MOCK_MODULE_ID,\n RESOLVED_MARKER_PREFIX,\n RESOLVED_MOCK_EDGE_PREFIX,\n RESOLVED_MOCK_RUNTIME_PREFIX,\n ]\n .map(escapeRegExp)\n .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 if (id === RESOLVED_MOCK_MODULE_ID) {\n return loadSilentMockModule()\n }\n\n if (id.startsWith(RESOLVED_MOCK_EDGE_PREFIX)) {\n return loadMockEdgeModule(\n id.slice(RESOLVED_MOCK_EDGE_PREFIX.length),\n )\n }\n\n if (id.startsWith(RESOLVED_MOCK_RUNTIME_PREFIX)) {\n return loadMockRuntimeModule(\n id.slice(RESOLVED_MOCK_RUNTIME_PREFIX.length),\n )\n }\n\n if (id.startsWith(RESOLVED_MARKER_PREFIX)) {\n return loadMarkerModule()\n }\n\n return undefined\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\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 // 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\n // Propagate SERVER_FN_LOOKUP status before import-analysis\n if (id.includes(SERVER_FN_LOOKUP_QUERY)) {\n envState.serverFnLookupModules.add(file)\n }\n\n envState.transformResultCache.set(cacheKey, {\n code,\n map,\n originalCode,\n lineIndex,\n })\n\n const keySet = getOrCreate(\n envState.transformResultKeysByFile,\n file,\n () => new Set<string>(),\n )\n keySet.add(cacheKey)\n\n // Also store stripped-path entry for physical-file lookups.\n if (cacheKey !== file) {\n envState.transformResultCache.set(file, {\n code,\n map,\n originalCode,\n lineIndex,\n })\n keySet.add(file)\n }\n\n // Resolve import sources to canonical paths for reachability checks.\n const importSources = extractImportSources(code)\n const resolvedChildren = new Set<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 = normalizeFilePath(resolved.id)\n resolvedChildren.add(resolvedPath)\n // Populate import graph edges for warm-start trace accuracy\n envState.graph.addEdge(resolvedPath, file, src)\n }\n } catch {\n // Non-fatal\n }\n }\n envState.postTransformImports.set(cacheKey, resolvedChildren)\n if (cacheKey !== file) {\n envState.postTransformImports.set(file, resolvedChildren)\n }\n\n await processPendingViolations(envState, this.warn.bind(this))\n\n return undefined\n },\n },\n },\n {\n // Separate plugin so the transform can be enabled/disabled per-environment.\n name: 'tanstack-start-core:import-protection-mock-rewrite',\n enforce: 'pre',\n\n // Only needed during dev. In build, we rely on Rollup's syntheticNamedExports.\n apply: 'serve',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n // Only needed in mock mode — when not mocking, there is nothing to\n // record. applyToEnvironment runs after configResolved, so\n // config.effectiveBehavior is already set.\n if (config.effectiveBehavior !== 'mock') return false\n // We record expected named exports per importer in all Start Vite\n // environments during dev so mock-edge modules can provide explicit\n // ESM named exports.\n return environmentNames.has(env.name)\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[cm]?[tj]sx?($|\\?)/],\n },\n },\n handler(code, id) {\n const envName = this.environment.name\n const envState = envStates.get(envName)\n if (!envState) return undefined\n\n // Record export names per source for this importer so we can generate\n // dev mock-edge modules without any disk reads.\n try {\n const importerFile = normalizeFilePath(id)\n envState.mockExportsByImporter.set(\n importerFile,\n collectMockExportNamesBySource(code),\n )\n } catch {\n // Best-effort only\n }\n\n // Note: we no longer rewrite imports here.\n // Dev uses per-importer mock-edge modules in resolveId so native ESM\n // has explicit named exports, and runtime diagnostics are handled by\n // the mock runtime proxy when those mocks are actually invoked.\n return undefined\n },\n },\n },\n ] satisfies Array<PluginOption>\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AA8DA,MAAM,yBAAyB,MAAM;AACrC,MAAM,8BAA8B,cAAc,GAAG,aAAa,aAAa;AAC/E,MAAM,8BAA8B,cAAc,GAAG,aAAa,aAAa;AAE/E,MAAM,0BACJ,QAAQ,IAAI,gCAAgC,OAC5C,QAAQ,IAAI,gCAAgC;AAC9C,MAAM,iCACJ,QAAQ,IAAI;AAEd,SAAS,YAAY,MAAsB;AACzC,MAAI,CAAC,wBAAyB;AAC9B,UAAQ,KAAK,6BAA6B,GAAG,IAAI;AACnD;AAGA,SAAS,sBAAsB,QAAgC;AAC7D,MAAI,CAAC,+BAAgC,QAAO;AAC5C,SAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,8BAA8B,CAAC;AACtE;AAsJO,SAAS,uBACd,MACc;AACd,MAAI,YAAkC;AAatC,WAAS,0BACP,SACA,KACA,YACyB;AACzB,QAAI,CAAC,UAAW,QAAO;AACvB,UAAM,cAAc,UAAU,aAAa,OAAO;AAClD,QAAI,CAAC,YAAa,QAAO;AAEzB,UAAM,OAAO,kBAAkB,UAAU;AACzC,UAAM,QAAQ,YAAY,YAAY,cAAc,IAAI;AACxD,QAAI,CAAC,MAAO,QAAO;AAInB,UAAM,8BAAc,IAAA;AACpB,aAAS,OAAO,GAA4B;AAC1C,UAAI,SAAS,QAAQ,IAAI,CAAC;AAC1B,UAAI,WAAW,QAAW;AACxB,iBAAS,EAAE,KACP,kBAAkB,EAAE,EAAE,IACtB,EAAE,MACA,kBAAkB,EAAE,GAAG,IACvB;AACN,gBAAQ,IAAI,GAAG,MAAM;AAAA,MACvB;AACA,aAAO;AAAA,IACT;AAEA,UAAM,QAAgC,CAAC,KAAK;AAC5C,UAAM,UAAU,oBAAI,IAAqB,CAAC,KAAK,CAAC;AAChD,UAAM,6BAAa,IAAA;AAEnB,QAAI,YAAoC;AACxC,QAAI,eAAuC;AAC3C,QAAI,KAAK;AACT,WAAO,KAAK,MAAM,QAAQ;AACxB,YAAM,OAAO,MAAM,IAAI;AACvB,YAAM,KAAK,OAAO,IAAI;AAEtB,UAAI,MAAM,IAAI,MAAM,QAAQ,IAAI,EAAE,GAAG;AACnC,oBAAY;AACZ;AAAA,MACF;AAEA,YAAM,YAAY,KAAK;AACvB,UAAI,UAAU,SAAS,GAAG;AACxB,YAAI,CAAC,aAAc,gBAAe;AAClC;AAAA,MACF;AAEA,iBAAW,OAAO,WAAW;AAC3B,YAAI,QAAQ,IAAI,GAAG,EAAG;AACtB,gBAAQ,IAAI,GAAG;AACf,eAAO,IAAI,KAAK,IAAI;AACpB,cAAM,KAAK,GAAG;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,OAAO,aAAa;AAE1B,QAAI,CAAC,KAAM,QAAO;AAGlB,UAAM,QAAgC,CAAA;AACtC,QAAI,MAAmC;AACvC,aAAS,IAAI,GAAG,IAAI,OAAO,gBAAgB,KAAK,KAAK,KAAK;AACxD,YAAM,KAAK,GAAG;AACd,UAAI,QAAQ,MAAO;AACnB,YAAM,OAAO,IAAI,GAAG;AAAA,IACtB;AAEA,UAAM,QAA0B,CAAA;AAChC,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,KAAK,OAAO,MAAM,CAAC,CAAE;AAC3B,UAAI,CAAC,GAAI;AACT,UAAI;AACJ,UAAI,IAAI,IAAI,MAAM,QAAQ;AACxB,cAAM,SAAS,OAAO,MAAM,IAAI,CAAC,CAAE;AACnC,YAAI,QAAQ;AACV,sBAAY,IAAI,MAAM,aAAa,IAAI,MAAM,GAAG,IAAI,EAAE;AAAA,QACxD;AAAA,MACF;AACA,YAAM,KAAK,YAAY,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,IAAI;AAAA,IAC/D;AAEA,WAAO,MAAM,SAAS,QAAQ;AAAA,EAChC;AAEA,QAAM,SAAuB;AAAA,IAC3B,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,IACT,cAAc;AAAA,IACd,WAAW,KAAK;AAAA,IAChB,YAAY,CAAA;AAAA,IACZ,mBAAmB;AAAA,IACnB,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,eAAe;AAAA,IACf,eAAe;AAAA,MACb,QAAQ,EAAE,YAAY,IAAI,OAAO,CAAA,EAAC;AAAA,MAClC,QAAQ,EAAE,YAAY,CAAA,GAAI,OAAO,CAAA,EAAC;AAAA,IAAE;AAAA,IAEtC,iBAAiB,CAAA;AAAA,IACjB,iBAAiB,CAAA;AAAA,IACjB,wBAAwB,CAAA;AAAA,IACxB,kBAAkB,EAAE,YAAY,oBAAI,OAAO,YAAY,oBAAI,MAAI;AAAA,IAC/D,YAAY,IAAI,IAAI,KAAK,aAAa,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAAA,IAClE,aAAa;AAAA,EAAA;AAGf,QAAM,gCAAgB,IAAA;AACtB,QAAM,SAAsB,EAAE,gBAAgB,oBAAI,MAAI;AAEtD,WAAS,qBACP,QACiC;AACjC,UAAM,OAAO,kBAAkB,MAAM;AACrC,WAAO,OAAO,eAAe,IAAI,IAAI;AAAA,EACvC;AAeA,iBAAe,wBACb,UACA,KACA,SACA,oBACA,WACA,aACA,eAC2B;AAC3B,QAAI,QACF,iBACA,WAAW,IAAI,OAAO,oBAAoB,OAAO,aAAa;AAEhE,QAAI,OAAO,YAAY,SAAS;AAC9B,YAAM,UAAU;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAEF,UAAI,WAAW,QAAQ,SAAS,MAAM,QAAQ;AAC5C,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,UAAM,wBAAwB,UAAU,OAAO,IAAI,cAAc;AAEjE,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,UAAI,CAAC,KAAK,UAAW,MAAK,YAAY;AACtC,UAAI,eAAe,KAAK,QAAQ,MAAM;AACpC,aAAK,OAAO,YAAY;AACxB,aAAK,SAAS,YAAY;AAAA,MAC5B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAQA,iBAAe,mBACb,UACA,KACA,SACA,SACA,UACA,oBACA,QACA,WAWA,eACwB;AACxB,UAAM,MACH,MAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA,KAED,MAAM;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI;AAAA,IAAA;AAGR,UAAM,QAAQ,MAAM;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,UAAM,UAAU,MAAM,iBAAiB,UAAU,UAAU,GAAG,IAAI;AAElE,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,WAAW;AAAA,MACX,UAAU;AAAA,MACV,GAAI,MAAM,EAAE,aAAa,IAAA,IAAQ,CAAA;AAAA,MACjC;AAAA,MACA;AAAA,MACA,GAAG;AAAA,IAAA;AAAA,EAEP;AASA,iBAAe,uCACb,UACA,KACA,SACA,SACA,UACA,QACA,YACA,cACA,eACoC;AACpC,UAAM,aAAa,qBAAqB,UAAU;AAClD,UAAM,WACH,YAAY,YAAY,eAAe,YACvC,YAAY,YAAY,eAAe;AAC1C,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,qBAAqB,kBAAkB,QAAQ;AAErD,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,UAAU,kBAAkB,UAAU;AAAA,QACtC,SACE,eAAe,WACX,WAAW,YAAY,sEACvB,WAAW,YAAY;AAAA,MAAA;AAAA,MAE/B;AAAA,IAAA;AAAA,EAEJ;AAEA,WAAS,WAAW,SAAsC;AACxD,WAAO,OAAO,WAAW,IAAI,OAAO,KAAK;AAAA,EAC3C;AAEA,WAAS,uBAAuB,SAG9B;AACA,UAAM,OAAO,WAAW,OAAO;AAC/B,WAAO,SAAS,WACZ,OAAO,cAAc,SACrB,OAAO,cAAc;AAAA,EAC3B;AAEA,QAAM,uCAAuB,IAAY;AAAA,IACvC,uBAAuB;AAAA,IACvB,uBAAuB;AAAA,EAAA,CACxB;AACD,MAAI,KAAK,oBAAoB,uBAAuB,QAAQ;AAC1D,qBAAiB,IAAI,KAAK,eAAe;AAAA,EAC3C;AAGA,WAAS,OAAO,SAA2B;AACzC,QAAI,WAAW,UAAU,IAAI,OAAO;AACpC,QAAI,CAAC,UAAU;AACb,YAAM,2CAA2B,IAAA;AACjC,iBAAW;AAAA,QACT,OAAO,IAAI,YAAA;AAAA,QACX,mCAAmB,IAAA;AAAA,QACnB,iCAAiB,IAAA;AAAA,QACjB,2CAA2B,IAAA;AAAA,QAC3B,kCAAkB,IAAA;AAAA,QAClB,wCAAwB,IAAA;AAAA,QACxB,gBAAgB,IAAI,eAAA;AAAA,QACpB,oCAAoB,IAAA;AAAA,QACpB;AAAA,QACA,+CAA+B,IAAA;AAAA,QAC/B,yBAAyB;AAAA,UACvB,mBAAmB,IAAY;AAC7B,kBAAM,UAAU,cAAc,EAAE;AAChC,kBAAM,QAAQ,qBAAqB,IAAI,OAAO;AAC9C,gBAAI,MAAO,QAAO;AAClB,kBAAM,cAAc,kBAAkB,EAAE;AACxC,mBAAO,gBAAgB,UACnB,qBAAqB,IAAI,WAAW,IACpC;AAAA,UACN;AAAA,QAAA;AAAA,QAEF,0CAA0B,IAAA;AAAA,QAC1B,cAAc;AAAA,QACd,2CAA2B,IAAA;AAAA,QAC3B,uCAAuB,IAAA;AAAA,MAAI;AAE7B,gBAAU,IAAI,SAAS,QAAQ;AAAA,IACjC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,+CAA+B,IAAA;AACrC,WAAS,oBAAoB,UAA2B;AACtD,QAAI,SAAS,yBAAyB,IAAI,QAAQ;AAClD,QAAI,WAAW,OAAW,QAAO;AAEjC,UAAM,eAAe,eAAe,UAAU,OAAO,IAAI;AAEzD,QACE,OAAO,gBAAgB,SAAS,KAChC,WAAW,cAAc,OAAO,eAAe,GAC/C;AACA,eAAS;AAAA,IACX,WACE,OAAO,uBAAuB,SAAS,KACvC,WAAW,cAAc,OAAO,sBAAsB,GACtD;AACA,eAAS;AAAA,IACX,WAAW,OAAO,gBAAgB,SAAS,GAAG;AAC5C,eAAS,CAAC,CAAC,WAAW,cAAc,OAAO,eAAe;AAAA,IAC5D,WAAW,OAAO,cAAc;AAC9B,eAAS,SAAS,WAAW,OAAO,YAAY;AAAA,IAClD,OAAO;AACL,eAAS;AAAA,IACX;AAEA,6BAAyB,IAAI,UAAU,MAAM;AAC7C,WAAO;AAAA,EACT;AAEA,WAAS,UACP,MACA,UACA,WACA,UACQ;AACR,WAAO,GAAG,IAAI,IAAI,QAAQ,IAAI,SAAS,IAAI,YAAY,EAAE;AAAA,EAC3D;AAEA,WAAS,QAAQ,KAAe,KAAsB;AACpD,QAAI,OAAO,YAAY,SAAU,QAAO;AACxC,QAAI,IAAI,eAAe,IAAI,GAAG,EAAG,QAAO;AACxC,QAAI,eAAe,IAAI,GAAG;AAC1B,WAAO;AAAA,EACT;AAEA,WAAS,gBAAgB,cAA8B;AACrD,WAAO,eAAe,cAAc,YAAY,GAAG,OAAO,IAAI;AAAA,EAChE;AAGA,WAAS,kBAAwB;AAC/B,UAAM,EAAE,oBAAA,IAAwB,KAAK,UAAA;AACrC,eAAW,UAAU,KAAK,cAAc;AACtC,YAAM,WAAW,OAAO,OAAO,IAAI;AACnC,UAAI,oBAAoB,gBAAgB;AACtC,iBAAS,MAAM;AAAA,UACb,cAAc,oBAAoB,cAAc;AAAA,QAAA;AAAA,MAEpD;AACA,UAAI,oBAAoB,eAAe;AACrC,iBAAS,MAAM;AAAA,UACb,cAAc,oBAAoB,aAAa;AAAA,QAAA;AAAA,MAEnD;AAAA,IACF;AAAA,EACF;AAEA,WAAS,+BACP,KACA,MACyC;AACzC,UAAM,8BAAc,IAAA;AACpB,UAAM,QAAuB,CAAC,IAAI;AAClC,QAAI,iBAAiB;AACrB,QAAI,KAAK;AAET,WAAO,KAAK,MAAM,QAAQ;AACxB,YAAM,UAAU,MAAM,IAAI;AAC1B,UAAI,QAAQ,IAAI,OAAO,EAAG;AAC1B,cAAQ,IAAI,OAAO;AAEnB,UAAI,IAAI,MAAM,QAAQ,IAAI,OAAO,GAAG;AAClC,eAAO;AAAA,MACT;AAGA,YAAM,YAAY,IAAI,MAAM,aAAa,IAAI,OAAO;AACpD,UAAI,CAAC,UAAW;AAEhB,iBAAW,CAAC,MAAM,KAAK,WAAW;AAChC,YAAI,QAAQ,IAAI,MAAM,EAAG;AAIzB,cAAM,SAAS,IAAI,0BAA0B,IAAI,MAAM;AACvD,YAAI,mBAAmB;AACvB,YAAI,WAAW;AAEf,YAAI,QAAQ;AACV,qBAAW,KAAK,QAAQ;AACtB,kBAAM,kBAAkB,IAAI,qBAAqB,IAAI,CAAC;AACtD,gBAAI,iBAAiB;AACnB,iCAAmB;AACnB,kBAAI,gBAAgB,IAAI,OAAO,GAAG;AAChC,2BAAW;AACX;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,YAAI,CAAC,kBAAkB;AACrB,gBAAM,kBAAkB,IAAI,qBAAqB,IAAI,MAAM;AAC3D,cAAI,iBAAiB;AACnB,+BAAmB;AACnB,gBAAI,gBAAgB,IAAI,OAAO,GAAG;AAChC,yBAAW;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAEA,YAAI,CAAC,kBAAkB;AACrB,gBAAM,qBACJ,IAAI,qBAAqB,IAAI,MAAM,MAClC,SAAS,OAAO,OAAO,IAAI;AAE9B,cAAI,oBAAoB;AAEtB,6BAAiB;AACjB;AAAA,UACF;AAIA,gBAAM,KAAK,MAAM;AACjB;AAAA,QACF;AAEA,YAAI,UAAU;AACZ,gBAAM,KAAK,MAAM;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAEA,WAAO,iBAAiB,YAAY;AAAA,EACtC;AASA,iBAAe,yBACb,KACA,QACe;AACf,QAAI,IAAI,kBAAkB,SAAS,EAAG;AAEtC,UAAM,WAA0B,CAAA;AAEhC,eAAW,CAAC,MAAM,UAAU,KAAK,IAAI,mBAAmB;AAEtD,YAAM,SAAS,IAAI,eACf,+BAA+B,KAAK,IAAI,IACxC;AAEJ,UAAI,WAAW,aAAa;AAC1B,mBAAW,MAAM,YAAY;AAC3B,gBAAM,MAAM;AAAA,YACV,GAAG,KAAK;AAAA,YACR,GAAG,KAAK;AAAA,YACR,GAAG,KAAK;AAAA,YACR,GAAG,KAAK;AAAA,UAAA;AAEV,cAAI,CAAC,QAAQ,KAAK,GAAG,GAAG;AACtB,kBAAM,aAAa,MAAM;AAAA,cACvB,IAAI;AAAA,cACJ;AAAA,cACA,GAAG,KAAK;AAAA,cACR,GAAG,KAAK;AAAA,cACR,GAAG,KAAK;AAAA,cACR,GAAG,KAAK;AAAA,YAAA;AAEV,gBAAI,WAAW,SAAS,GAAG,KAAK,MAAM,QAAQ;AAC5C,iBAAG,KAAK,QAAQ;AAAA,YAClB;AAEA,gBAAI,OAAO,aAAa;AACtB,oBAAM,SAAS,OAAO,YAAY,GAAG,IAAI;AACzC,kBAAI,WAAW,MAAO;AAAA,YACxB;AACA,mBAAO,gBAAgB,GAAG,MAAM,OAAO,IAAI,CAAC;AAAA,UAC9C;AAAA,QACF;AACA,iBAAS,KAAK,IAAI;AAAA,MACpB,WAAW,WAAW,eAAe;AACnC,iBAAS,KAAK,IAAI;AAAA,MACpB;AAAA,IAEF;AAEA,eAAW,QAAQ,UAAU;AAC3B,UAAI,kBAAkB,OAAO,IAAI;AAAA,IACnC;AAAA,EACF;AAMA,WAAS,eACP,KACA,cACA,MACA,iBAIM;AACN,gBAAY,IAAI,mBAAmB,cAAc,MAAM,CAAA,CAAE,EAAE,KAAK;AAAA,MAC9D;AAAA,MACA,iBACE,OAAO,oBAAoB,WACvB,kBACC,iBAAiB,MAAM;AAAA,IAAA,CAC/B;AAAA,EACH;AAEA,WAAS,gBACP,KACA,KACA,MACA,eACqE;AACrE,UAAM,MAAM;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,IAAA;AAGP,QAAI,CAAC,eAAe,QAAQ;AAC1B,UAAI,OAAO,aAAa;AACtB,cAAM,SAAS,OAAO,YAAY,IAAI;AACtC,YAAI,WAAW,OAAO;AACpB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,YAAM,OAAO,QAAQ,KAAK,GAAG;AAE7B,UAAI,OAAO,sBAAsB,SAAS;AACxC,YAAI,CAAC,KAAM,KAAI,MAAM,gBAAgB,MAAM,OAAO,IAAI,CAAC;AACvD,eAAO;AAAA,MACT;AAEA,UAAI,CAAC,MAAM;AACT,YAAI,KAAK,gBAAgB,MAAM,OAAO,IAAI,CAAC;AAAA,MAC7C;AAAA,IACF,OAAO;AACL,UAAI,OAAO,sBAAsB,SAAS;AACxC,eAAO;AAAA,MACT;AAAA,IACF;AAEA,QAAI,cAAc,IAAI,KAAK,SAAS;AACpC,gBAAY,IAAI,aAAa,KAAK,UAAU,MAAM,oBAAI,IAAA,CAAa,EAAE;AAAA,MACnE,KAAK;AAAA,IAAA;AAGP,QAAI,OAAO,YAAY,SAAS;AAC9B,YAAM,YAAY;AAAA,QAChB;AAAA,QACA,OAAO;AAAA,QACP,OAAO;AAAA,MAAA;AAET,YAAM,eAAe,kBAAkB,KAAK,QAAQ;AACpD,YAAM,UACJ,IAAI,sBAAsB,IAAI,YAAY,GAAG,IAAI,KAAK,SAAS,KAAK,CAAA;AACtE,aAAO;AAAA,QACL,qBAAqB,SAAS,KAAK,WAAW,SAAS;AAAA,MAAA;AAAA,IAE3D;AAGA,WAAO,EAAE,IAAI,yBAAyB,uBAAuB,KAAA;AAAA,EAC/D;AAYA,iBAAe,uBACb,KACA,KACA,cACA,MACA,aACA,uBAC6C;AAC7C,QAAI,aAAa;AACf,YAAM,SAAS,gBAAgB,KAAK,KAAK,MAAM,EAAE,QAAQ,MAAM;AAC/D,qBAAe,KAAK,cAAc,MAAM,MAAM;AAC9C,YAAM,yBAAyB,KAAK,IAAI,KAAK,KAAK,GAAG,CAAC;AACtD,aAAO;AAAA,IACT;AACA,WAAO,gBAAgB,KAAK,KAAK,MAAM;AAAA,MACrC,QAAQ;AAAA,IAAA,CACT;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MAET,mBAAmB,KAAK;AACtB,YAAI,CAAC,OAAO,QAAS,QAAO;AAG5B,eAAO,iBAAiB,IAAI,IAAI,IAAI;AAAA,MACtC;AAAA,MAEA,eAAe,YAAY;AACzB,eAAO,OAAO,WAAW;AACzB,eAAO,UAAU,WAAW;AAE5B,cAAM,EAAE,aAAa,wBAAwB,KAAK,UAAA;AAClD,eAAO,eAAe,oBAAoB;AAE1C,eAAO,aAAa;AAAA,UAClB,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,QAAA,EACpB,OAAO,CAAC,MAAmB,QAAQ,CAAC,CAAC;AAEvC,cAAM,WACJ,YAAY;AAEd,YAAI,UAAU,YAAY,OAAO;AAC/B,iBAAO,UAAU;AACjB;AAAA,QACF;AAEA,eAAO,UAAU;AAEjB,YAAI,UAAU,UAAU;AACtB,cAAI,OAAO,SAAS,aAAa,UAAU;AACzC,mBAAO,oBAAoB,SAAS;AAAA,UACtC,OAAO;AACL,mBAAO,oBACL,WAAW,YAAY,UAClB,SAAS,SAAS,OAAO,SACzB,SAAS,SAAS,SAAS;AAAA,UACpC;AAAA,QACF,OAAO;AACL,iBAAO,oBACL,WAAW,YAAY,UAAU,SAAS;AAAA,QAC9C;AAEA,eAAO,UAAU,UAAU,OAAO;AAClC,eAAO,aAAa,UAAU,cAAc;AAC5C,eAAO,gBAAgB,UAAU,iBAAiB;AAClD,YAAI,UAAU,aAAa;AACzB,gBAAM,KAAK,SAAS;AACpB,iBAAO,cAAc,CAAC,SAAS,GAAG,IAAI;AAAA,QACxC;AAEA,cAAM,WAAW,gCAAA;AAIjB,cAAM,mBAAmB,eAAe;AAAA,UACtC,GAAG,SAAS,OAAO;AAAA,UACnB,GAAI,UAAU,QAAQ,cAAc,CAAA;AAAA,QAAC,CACtC;AAED,cAAM,cAAc,UAAU,QAAQ,QAClC,CAAC,GAAG,SAAS,OAAO,KAAK,IACzB,CAAC,GAAG,SAAS,OAAO,KAAK;AAC7B,cAAM,mBAAmB,UAAU,QAAQ,aACvC,eAAe,CAAC,GAAG,SAAS,OAAO,UAAU,CAAC,IAC9C,eAAe,CAAC,GAAG,SAAS,OAAO,UAAU,CAAC;AAClD,cAAM,cAAc,UAAU,QAAQ,QAClC,CAAC,GAAG,SAAS,OAAO,KAAK,IACzB,CAAC,GAAG,SAAS,OAAO,KAAK;AAE7B,eAAO,cAAc,SAAS;AAAA,UAC5B,YAAY,gBAAgB,gBAAgB;AAAA,UAC5C,OAAO,gBAAgB,WAAW;AAAA,QAAA;AAEpC,eAAO,cAAc,SAAS;AAAA,UAC5B,YAAY,gBAAgB,gBAAgB;AAAA,UAC5C,OAAO,gBAAgB,WAAW;AAAA,QAAA;AAIpC,YAAI,UAAU,SAAS;AACrB,iBAAO,kBAAkB,gBAAgB,SAAS,OAAO;AAAA,QAC3D;AACA,YAAI,UAAU,SAAS;AACrB,iBAAO,kBAAkB,gBAAgB,SAAS,OAAO;AAAA,QAC3D;AACA,YAAI,UAAU,iBAAiB;AAC7B,iBAAO,yBAAyB;AAAA,YAC9B,SAAS;AAAA,UAAA;AAAA,QAEb;AAGA,cAAM,UAAU,oBAAA;AAChB,eAAO,mBAAmB;AAAA,UACxB,YAAY,IAAI,IAAI,QAAQ,UAAU;AAAA,UACtC,YAAY,IAAI,IAAI,QAAQ,UAAU;AAAA,QAAA;AAAA,MAE1C;AAAA,MAEA,gBAAgB,QAAQ;AACtB,oBAAY;AAAA,MACd;AAAA,MAEA,aAAa;AACX,YAAI,CAAC,OAAO,QAAS;AAErB,oCAAA;AACA,gCAAA;AACA,iCAAyB,MAAA;AAGzB,mBAAW,YAAY,UAAU,UAAU;AACzC,mBAAS,aAAa,MAAA;AACtB,mBAAS,mBAAmB,MAAA;AAC5B,mBAAS,eAAe,MAAA;AACxB,mBAAS,eAAe,MAAA;AACxB,mBAAS,qBAAqB,MAAA;AAC9B,mBAAS,0BAA0B,MAAA;AACnC,mBAAS,qBAAqB,MAAA;AAC9B,mBAAS,eAAe;AACxB,mBAAS,sBAAsB,MAAA;AAC/B,mBAAS,MAAM,MAAA;AACf,mBAAS,cAAc,MAAA;AACvB,mBAAS,YAAY,MAAA;AACrB,mBAAS,sBAAsB,MAAA;AAAA,QACjC;AAGA,eAAO,eAAe,MAAA;AAEtB,wBAAA;AAAA,MACF;AAAA,MAEA,UAAU,KAAK;AACb,YAAI,CAAC,OAAO,QAAS;AAErB,mBAAW,OAAO,IAAI,SAAS;AAC7B,cAAI,IAAI,IAAI;AACV,kBAAM,KAAK,IAAI;AACf,kBAAM,eAAe,kBAAkB,EAAE;AACzC,mBAAO,eAAe,OAAO,YAAY;AAGzC,uBAAW,YAAY,UAAU,UAAU;AACzC,uBAAS,eAAe,aAAa,YAAY;AAGjD,oBAAM,cAAc,SAAS,mBAAmB,IAAI,YAAY;AAChE,kBAAI,aAAa;AACf,2BAAW,OAAO,aAAa;AAC7B,2BAAS,aAAa,OAAO,GAAG;AAAA,gBAClC;AACA,yBAAS,mBAAmB,OAAO,YAAY;AAAA,cACjD;AAGA,uBAAS,MAAM,WAAW,YAAY;AACtC,uBAAS,YAAY,OAAO,YAAY;AACxC,uBAAS,sBAAsB,OAAO,YAAY;AAClD,uBAAS,sBAAsB,OAAO,YAAY;AAClD,uBAAS,kBAAkB,OAAO,YAAY;AAG9C,oBAAM,gBACJ,SAAS,0BAA0B,IAAI,YAAY;AACrD,kBAAI,eAAe;AACjB,2BAAW,OAAO,eAAe;AAC/B,2BAAS,qBAAqB,OAAO,GAAG;AACxC,2BAAS,qBAAqB,OAAO,GAAG;AAAA,gBAC1C;AACA,yBAAS,0BAA0B,OAAO,YAAY;AAAA,cACxD,OAAO;AAEL,yBAAS,qBAAqB,OAAO,YAAY;AACjD,yBAAS,qBAAqB,OAAO,YAAY;AAAA,cACnD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,UAAU,QAAQ,UAAU,UAAU;AAC1C,cAAM,UAAU,KAAK,YAAY;AACjC,cAAM,MAAM,OAAO,OAAO;AAC1B,cAAM,UAAU,WAAW,OAAO;AAClC,cAAM,WAAW,IAAI;AACrB,cAAM,gBAAgB,CAAC,CAAE,SAAqC;AAE9D,YAAI,yBAAyB;AAC3B,gBAAM,eAAe,WACjB,kBAAkB,QAAQ,IAC1B;AACJ,gBAAM,iBAAiB,CAAC;AACxB,gBAAM,WACJ,mCAAmC,UAC/B,iBACA,mBAAmB,QAAQ,YAAY;AAC7C,cAAI,UAAU;AACZ,qBAAS,aAAa;AAAA,cACpB,KAAK;AAAA,cACL;AAAA,cACA;AAAA,cACA,UAAU;AAAA,cACV;AAAA,cACA,cAAc,IAAI;AAAA,cAClB,SAAS,OAAO;AAAA,cAChB,UAAU,OAAO;AAAA,YAAA,CAClB;AAAA,UACH;AAAA,QACF;AAGA,YAAI,WAAW,gBAAgB;AAC7B,iBAAO;AAAA,QACT;AACA,YAAI,OAAO,WAAW,gBAAgB,GAAG;AACvC,iBAAO,cAAc,MAAM;AAAA,QAC7B;AACA,YAAI,OAAO,WAAW,mBAAmB,GAAG;AAC1C,iBAAO,cAAc,MAAM;AAAA,QAC7B;AACA,YAAI,OAAO,WAAW,aAAa,GAAG;AACpC,iBAAO,cAAc,MAAM;AAAA,QAC7B;AAEA,YAAI,CAAC,UAAU;AACb,cAAI,MAAM,SAAS,MAAM;AACzB,cAAI,eAAe;AACnB,iBAAO;AAAA,QACT;AAEA,YAAI,OAAO,WAAW,IAAI,KAAK,OAAO,WAAW,UAAU,GAAG;AAC5D,iBAAO;AAAA,QACT;AAEA,cAAM,qBAAqB,kBAAkB,QAAQ;AACrD,cAAM,iBAAiB,SAAS,SAAS,sBAAsB;AAE/D,YAAI,gBAAgB;AAClB,cAAI,sBAAsB,IAAI,kBAAkB;AAAA,QAClD;AAEA,cAAM,wBACJ,kBACA,IAAI,sBAAsB,IAAI,kBAAkB,KAChD;AAIF,cAAM,YACJ,OAAO,YAAY,WAAW,OAAO,sBAAsB;AAE7D,cAAM,cAAc,aAAa,CAAC;AAGlC,cAAM,aAAa,OAAO,iBAAiB,WAAW,IAAI,MAAM,IAC3D,WACD,OAAO,iBAAiB,WAAW,IAAI,MAAM,IAC1C,WACD;AAEN,YAAI,YAAY;AACd,gBAAM,WAAW,OAAO,eAAe,IAAI,kBAAkB;AAC7D,cAAI,YAAY,aAAa,YAAY;AACvC,iBAAK;AAAA,cACH,6BAA6B,gBAAgB,kBAAkB,CAAC;AAAA,YAAA;AAAA,UAEpE;AACA,iBAAO,eAAe,IAAI,oBAAoB,UAAU;AAExD,gBAAM,cACH,YAAY,YAAY,eAAe,YACvC,YAAY,YAAY,eAAe;AAE1C,cAAI,aAAa;AACf,kBAAM,OAAO,MAAM;AAAA,cACjB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,gBACE,MAAM;AAAA,gBACN,SACE,eAAe,WACX,WAAW,gBAAgB,kBAAkB,CAAC,sEAC9C,WAAW,gBAAgB,kBAAkB,CAAC;AAAA,cAAA;AAAA,YACtD;AAEF,kBAAM;AAAA,cACJ;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAEA,iBAAO,eAAe,WAClB,8BACA;AAAA,QACN;AAGA,YAAI,CAAC,oBAAoB,kBAAkB,GAAG;AAC5C,iBAAO;AAAA,QACT;AAEA,cAAM,WAAW,uBAAuB,OAAO;AAG/C,cAAM,iBAAiB,WAAW,QAAQ,SAAS,UAAU;AAC7D,YAAI,gBAAgB;AAClB,cAAI,MAAM,QAAQ,QAAQ,oBAAoB,MAAM;AACpD,gBAAM,OAAO,MAAM;AAAA,YACjB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,cACE,MAAM;AAAA,cACN,SAAS,eAAe;AAAA,cACxB,SAAS,WAAW,MAAM,sBAAsB,OAAO;AAAA,YAAA;AAAA,UACzD;AAEF,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,QAEJ;AAGA,cAAM,WAAW,GAAG,kBAAkB,IAAI,MAAM;AAChD,YAAI;AAEJ,YAAI,IAAI,aAAa,IAAI,QAAQ,GAAG;AAClC,qBAAW,IAAI,aAAa,IAAI,QAAQ,KAAK;AAAA,QAC/C,OAAO;AACL,gBAAM,SAAS,MAAM,KAAK,QAAQ,QAAQ,UAAU;AAAA,YAClD,UAAU;AAAA,UAAA,CACX;AACD,qBAAW,SAAS,kBAAkB,OAAO,EAAE,IAAI;AACnD,cAAI,aAAa,IAAI,UAAU,QAAQ;AACvC;AAAA,YACE,IAAI;AAAA,YACJ;AAAA,YACA,0BAAU,IAAA;AAAA,UAAI,EACd,IAAI,QAAQ;AAAA,QAChB;AAEA,YAAI,UAAU;AACZ,gBAAM,eAAe,gBAAgB,QAAQ;AAG7C,cAAI,yBAAyB,CAAC,eAAe;AAC3C,gBAAI,sBAAsB,IAAI,QAAQ;AAAA,UACxC;AAEA,cAAI,MAAM,QAAQ,UAAU,oBAAoB,MAAM;AAEtD,gBAAM,YACJ,SAAS,MAAM,SAAS,IACpB,WAAW,cAAc,SAAS,KAAK,IACvC;AAEN,cAAI,WAAW;AACb,kBAAM,OAAO,MAAM;AAAA,cACjB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,gBACE,MAAM;AAAA,gBACN,SAAS,UAAU;AAAA,gBACnB;AAAA,gBACA,SAAS,WAAW,MAAM,mBAAmB,YAAY,uBAAuB,OAAO;AAAA,cAAA;AAAA,YACzF;AAEF,mBAAO;AAAA,cACL;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAEA,gBAAM,aAAa,MAAM;AAAA,YACvB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAEF,cAAI,YAAY;AACd,mBAAO;AAAA,cACL;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA,MAEA,MAAM;AAAA,QACJ,QAAQ;AAAA,UACN,IAAI,IAAI;AAAA,YACN;AAAA,cACE;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA,EAEC,IAAI,YAAY,EAChB,KAAK,GAAG;AAAA,UAAA;AAAA,QACb;AAAA,QAEF,QAAQ,IAAI;AACV,cAAI,yBAAyB;AAC3B,gBAAI,mBAAmB,EAAE,GAAG;AAC1B,uBAAS,gBAAgB;AAAA,gBACvB,KAAK,KAAK,YAAY;AAAA,gBACtB,IAAI,cAAc,EAAE;AAAA,cAAA,CACrB;AAAA,YACH;AAAA,UACF;AAEA,cAAI,OAAO,yBAAyB;AAClC,mBAAO,qBAAA;AAAA,UACT;AAEA,cAAI,GAAG,WAAW,yBAAyB,GAAG;AAC5C,mBAAO;AAAA,cACL,GAAG,MAAM,0BAA0B,MAAM;AAAA,YAAA;AAAA,UAE7C;AAEA,cAAI,GAAG,WAAW,4BAA4B,GAAG;AAC/C,mBAAO;AAAA,cACL,GAAG,MAAM,6BAA6B,MAAM;AAAA,YAAA;AAAA,UAEhD;AAEA,cAAI,GAAG,WAAW,sBAAsB,GAAG;AACzC,mBAAO,iBAAA;AAAA,UACT;AAEA,iBAAO;AAAA,QACT;AAAA,MAAA;AAAA,IACF;AAAA,IAEF;AAAA;AAAA;AAAA;AAAA,MAIE,MAAM;AAAA,MAEN,mBAAmB,KAAK;AACtB,YAAI,CAAC,OAAO,QAAS,QAAO;AAC5B,eAAO,iBAAiB,IAAI,IAAI,IAAI;AAAA,MACtC;AAAA,MAEA,WAAW;AAAA,QACT,QAAQ;AAAA,UACN,IAAI;AAAA,YACF,SAAS,CAAC,sBAAsB;AAAA,UAAA;AAAA,QAClC;AAAA,QAEF,MAAM,QAAQ,MAAM,IAAI;AACtB,gBAAM,UAAU,KAAK,YAAY;AACjC,gBAAM,OAAO,kBAAkB,EAAE;AAEjC,cAAI,yBAAyB;AAC3B,gBAAI,mBAAmB,IAAI,GAAG;AAC5B,uBAAS,mBAAmB;AAAA,gBAC1B,KAAK;AAAA,gBACL,IAAI,cAAc,EAAE;AAAA,gBACpB;AAAA,cAAA,CACD;AAAA,YACH;AAAA,UACF;AAEA,cAAI,CAAC,oBAAoB,IAAI,GAAG;AAC9B,mBAAO;AAAA,UACT;AAGA,cAAI;AACJ,cAAI;AACF,kBAAM,KAAK,qBAAA;AAAA,UACb,QAAQ;AACN,kBAAM;AAAA,UACR;AAEA,cAAI;AACJ,cAAI,KAAK,gBAAgB;AACvB,2BAAe;AAAA,cACb;AAAA,cACA;AAAA,cACA,OAAO;AAAA,YAAA;AAAA,UAEX;AAEA,gBAAM,YAAY,eAAe,IAAI;AACrC,gBAAM,WAAW,cAAc,EAAE;AAEjC,gBAAM,WAAW,OAAO,OAAO;AAG/B,cAAI,GAAG,SAAS,sBAAsB,GAAG;AACvC,qBAAS,sBAAsB,IAAI,IAAI;AAAA,UACzC;AAEA,mBAAS,qBAAqB,IAAI,UAAU;AAAA,YAC1C;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA,CACD;AAED,gBAAM,SAAS;AAAA,YACb,SAAS;AAAA,YACT;AAAA,YACA,0BAAU,IAAA;AAAA,UAAY;AAExB,iBAAO,IAAI,QAAQ;AAGnB,cAAI,aAAa,MAAM;AACrB,qBAAS,qBAAqB,IAAI,MAAM;AAAA,cACtC;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA,CACD;AACD,mBAAO,IAAI,IAAI;AAAA,UACjB;AAGA,gBAAM,gBAAgB,qBAAqB,IAAI;AAC/C,gBAAM,uCAAuB,IAAA;AAC7B,qBAAW,OAAO,eAAe;AAC/B,gBAAI;AACF,oBAAM,WAAW,MAAM,KAAK,QAAQ,KAAK,IAAI,EAAE,UAAU,MAAM;AAC/D,kBAAI,YAAY,CAAC,SAAS,UAAU;AAClC,sBAAM,eAAe,kBAAkB,SAAS,EAAE;AAClD,iCAAiB,IAAI,YAAY;AAEjC,yBAAS,MAAM,QAAQ,cAAc,MAAM,GAAG;AAAA,cAChD;AAAA,YACF,QAAQ;AAAA,YAER;AAAA,UACF;AACA,mBAAS,qBAAqB,IAAI,UAAU,gBAAgB;AAC5D,cAAI,aAAa,MAAM;AACrB,qBAAS,qBAAqB,IAAI,MAAM,gBAAgB;AAAA,UAC1D;AAEA,gBAAM,yBAAyB,UAAU,KAAK,KAAK,KAAK,IAAI,CAAC;AAE7D,iBAAO;AAAA,QACT;AAAA,MAAA;AAAA,IACF;AAAA,IAEF;AAAA;AAAA,MAEE,MAAM;AAAA,MACN,SAAS;AAAA;AAAA,MAGT,OAAO;AAAA,MAEP,mBAAmB,KAAK;AACtB,YAAI,CAAC,OAAO,QAAS,QAAO;AAI5B,YAAI,OAAO,sBAAsB,OAAQ,QAAO;AAIhD,eAAO,iBAAiB,IAAI,IAAI,IAAI;AAAA,MACtC;AAAA,MAEA,WAAW;AAAA,QACT,QAAQ;AAAA,UACN,IAAI;AAAA,YACF,SAAS,CAAC,sBAAsB;AAAA,UAAA;AAAA,QAClC;AAAA,QAEF,QAAQ,MAAM,IAAI;AAChB,gBAAM,UAAU,KAAK,YAAY;AACjC,gBAAM,WAAW,UAAU,IAAI,OAAO;AACtC,cAAI,CAAC,SAAU,QAAO;AAItB,cAAI;AACF,kBAAM,eAAe,kBAAkB,EAAE;AACzC,qBAAS,sBAAsB;AAAA,cAC7B;AAAA,cACA,+BAA+B,IAAI;AAAA,YAAA;AAAA,UAEvC,QAAQ;AAAA,UAER;AAMA,iBAAO;AAAA,QACT;AAAA,MAAA;AAAA,IACF;AAAA,EACF;AAEJ;"}
@@ -1,4 +1,4 @@
1
- export type UsagePos = {
1
+ type UsagePos = {
2
2
  line: number;
3
3
  column0: number;
4
4
  };
@@ -6,6 +6,8 @@ export type UsagePos = {
6
6
  * Given transformed code, returns the first "meaningful" usage position for an
7
7
  * import from `source` that survives compilation.
8
8
  *
9
- * The returned column is 0-based (Babel loc semantics).
9
+ * "Preferred" positions (call, new, member-access) take priority over bare
10
+ * identifier references. The returned column is 0-based (Babel loc semantics).
10
11
  */
11
12
  export declare function findPostCompileUsagePos(code: string, source: string): UsagePos | undefined;
13
+ export {};
@@ -1,80 +1,6 @@
1
+ import babel from "@babel/core";
1
2
  import * as t from "@babel/types";
2
3
  import { parseAst } from "@tanstack/router-utils";
3
- function collectPatternBindings(node, out) {
4
- if (!node) return;
5
- if (t.isIdentifier(node)) {
6
- out.add(node.name);
7
- return;
8
- }
9
- if (t.isRestElement(node)) {
10
- collectPatternBindings(node.argument, out);
11
- return;
12
- }
13
- if (t.isAssignmentPattern(node)) {
14
- collectPatternBindings(node.left, out);
15
- return;
16
- }
17
- if (t.isObjectPattern(node)) {
18
- for (const prop of node.properties) {
19
- if (t.isRestElement(prop)) {
20
- collectPatternBindings(prop.argument, out);
21
- } else if (t.isObjectProperty(prop)) {
22
- collectPatternBindings(prop.value, out);
23
- }
24
- }
25
- return;
26
- }
27
- if (t.isArrayPattern(node)) {
28
- for (const el of node.elements) {
29
- collectPatternBindings(el, out);
30
- }
31
- return;
32
- }
33
- }
34
- function isBindingPosition(node, parent) {
35
- if (!parent) return false;
36
- if (t.isFunctionDeclaration(parent) && parent.id === node) return true;
37
- if (t.isFunctionExpression(parent) && parent.id === node) return true;
38
- if (t.isClassDeclaration(parent) && parent.id === node) return true;
39
- if (t.isClassExpression(parent) && parent.id === node) return true;
40
- if (t.isVariableDeclarator(parent) && parent.id === node) return true;
41
- if (t.isImportSpecifier(parent) && parent.local === node) return true;
42
- if (t.isImportDefaultSpecifier(parent) && parent.local === node) return true;
43
- if (t.isImportNamespaceSpecifier(parent) && parent.local === node) return true;
44
- if (t.isObjectProperty(parent) && parent.key === node && !parent.computed && // In `{ foo }`, the identifier is also a value reference and must count as
45
- // usage. Babel represents this as `shorthand: true`.
46
- !parent.shorthand)
47
- return true;
48
- if (t.isObjectMethod(parent) && parent.key === node && !parent.computed)
49
- return true;
50
- if (t.isExportSpecifier(parent) && parent.exported === node) return true;
51
- return false;
52
- }
53
- function isPreferredUsage(node, parent) {
54
- if (!parent) return false;
55
- if (t.isCallExpression(parent) && parent.callee === node) return true;
56
- if (t.isNewExpression(parent) && parent.callee === node) return true;
57
- if (t.isMemberExpression(parent) && parent.object === node) return true;
58
- return false;
59
- }
60
- function isScopeNode(node) {
61
- return t.isProgram(node) || t.isFunctionDeclaration(node) || t.isFunctionExpression(node) || t.isArrowFunctionExpression(node) || t.isBlockStatement(node) || t.isCatchClause(node);
62
- }
63
- function isFunctionScopeNode(node) {
64
- return t.isProgram(node) || t.isFunctionDeclaration(node) || t.isFunctionExpression(node) || t.isArrowFunctionExpression(node);
65
- }
66
- function collectScopeBindings(node, out) {
67
- if (t.isFunctionDeclaration(node) || t.isFunctionExpression(node) || t.isArrowFunctionExpression(node)) {
68
- for (const p of node.params) {
69
- collectPatternBindings(p, out);
70
- }
71
- return;
72
- }
73
- if (t.isCatchClause(node)) {
74
- collectPatternBindings(node.param, out);
75
- return;
76
- }
77
- }
78
4
  function findPostCompileUsagePos(code, source) {
79
5
  const ast = parseAst({ code });
80
6
  const imported = /* @__PURE__ */ new Set();
@@ -90,85 +16,40 @@ function findPostCompileUsagePos(code, source) {
90
16
  if (imported.size === 0) return void 0;
91
17
  let preferred;
92
18
  let anyUsage;
93
- const scopes = [{ bindings: /* @__PURE__ */ new Set(), isFnScope: true }];
94
- function isShadowed(name) {
95
- for (let i = scopes.length - 1; i >= 1; i--) {
96
- if (scopes[i].bindings.has(name)) return true;
97
- }
98
- return false;
99
- }
100
- function record(node, kind) {
101
- const loc = node.loc?.start;
102
- if (!loc) return;
103
- const pos = { line: loc.line, column0: loc.column };
104
- if (kind === "preferred") {
105
- preferred ||= pos;
106
- } else {
107
- anyUsage ||= pos;
108
- }
109
- }
110
- function pushScope(node) {
111
- const bindings = /* @__PURE__ */ new Set();
112
- collectScopeBindings(node, bindings);
113
- scopes.push({ bindings, isFnScope: isFunctionScopeNode(node) });
114
- }
115
- function popScope() {
116
- scopes.pop();
117
- }
118
- function nearestFnScope() {
119
- for (let i = scopes.length - 1; i >= 0; i--) {
120
- if (scopes[i].isFnScope) return scopes[i];
121
- }
122
- return scopes[0];
123
- }
124
- function walk(node, parent) {
125
- if (!node) return;
126
- if (preferred && anyUsage) return;
127
- if (Array.isArray(node)) {
128
- for (const n of node) walk(n, parent);
129
- return;
130
- }
131
- const astNode = node;
132
- if (t.isImportDeclaration(astNode)) return;
133
- const enterScope = isScopeNode(astNode);
134
- if (enterScope) {
135
- pushScope(astNode);
136
- }
137
- if (t.isFunctionDeclaration(astNode) && astNode.id) {
138
- scopes[scopes.length - 2]?.bindings.add(astNode.id.name);
139
- }
140
- if (t.isClassDeclaration(astNode) && astNode.id) {
141
- scopes[scopes.length - 2]?.bindings.add(astNode.id.name);
142
- }
143
- if (t.isVariableDeclarator(astNode)) {
144
- const isVar = t.isVariableDeclaration(parent) && parent.kind === "var";
145
- const target = isVar ? nearestFnScope().bindings : scopes[scopes.length - 1].bindings;
146
- collectPatternBindings(astNode.id, target);
147
- }
148
- if (t.isIdentifier(astNode) && imported.has(astNode.name)) {
149
- if (!isBindingPosition(astNode, parent) && !isShadowed(astNode.name)) {
150
- if (isPreferredUsage(astNode, parent)) {
151
- record(astNode, "preferred");
19
+ try {
20
+ babel.traverse(ast, {
21
+ ImportDeclaration(path) {
22
+ path.skip();
23
+ },
24
+ Identifier(path) {
25
+ if (preferred && anyUsage) {
26
+ path.stop();
27
+ return;
28
+ }
29
+ const { node, parent, scope } = path;
30
+ if (!imported.has(node.name)) return;
31
+ if (path.isBindingIdentifier()) return;
32
+ if (t.isObjectProperty(parent) && parent.key === node && !parent.computed && !parent.shorthand)
33
+ return;
34
+ if (t.isObjectMethod(parent) && parent.key === node && !parent.computed)
35
+ return;
36
+ if (t.isExportSpecifier(parent) && parent.exported === node) return;
37
+ const binding = scope.getBinding(node.name);
38
+ if (binding && binding.kind !== "module") return;
39
+ const loc = node.loc?.start;
40
+ if (!loc) return;
41
+ const pos = { line: loc.line, column0: loc.column };
42
+ const isPreferred = t.isCallExpression(parent) && parent.callee === node || t.isNewExpression(parent) && parent.callee === node || t.isMemberExpression(parent) && parent.object === node;
43
+ if (isPreferred) {
44
+ preferred ||= pos;
152
45
  } else {
153
- record(astNode, "any");
46
+ anyUsage ||= pos;
154
47
  }
155
48
  }
156
- }
157
- const record_ = astNode;
158
- for (const key of Object.keys(record_)) {
159
- const value = record_[key];
160
- if (!value) continue;
161
- if (key === "loc" || key === "start" || key === "end") continue;
162
- if (key === "parent") continue;
163
- if (typeof value === "string" || typeof value === "number") continue;
164
- walk(value, astNode);
165
- if (preferred && anyUsage) break;
166
- }
167
- if (enterScope) {
168
- popScope();
169
- }
49
+ });
50
+ } catch {
51
+ return void 0;
170
52
  }
171
- walk(ast.program, null);
172
53
  return preferred ?? anyUsage;
173
54
  }
174
55
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"postCompileUsage.js","sources":["../../../src/import-protection-plugin/postCompileUsage.ts"],"sourcesContent":["import * as t from '@babel/types'\nimport { parseAst } from '@tanstack/router-utils'\n\nexport type UsagePos = { line: number; column0: number }\n\nfunction collectPatternBindings(\n node: t.Node | null | undefined,\n out: Set<string>,\n): void {\n if (!node) return\n if (t.isIdentifier(node)) {\n out.add(node.name)\n return\n }\n if (t.isRestElement(node)) {\n collectPatternBindings(node.argument, out)\n return\n }\n if (t.isAssignmentPattern(node)) {\n collectPatternBindings(node.left, out)\n return\n }\n if (t.isObjectPattern(node)) {\n for (const prop of node.properties) {\n if (t.isRestElement(prop)) {\n collectPatternBindings(prop.argument, out)\n } else if (t.isObjectProperty(prop)) {\n collectPatternBindings(prop.value as t.Node, out)\n }\n }\n return\n }\n if (t.isArrayPattern(node)) {\n for (const el of node.elements) {\n collectPatternBindings(el, out)\n }\n return\n }\n}\n\nfunction isBindingPosition(node: t.Node, parent: t.Node | null): boolean {\n if (!parent) return false\n if (t.isFunctionDeclaration(parent) && parent.id === node) return true\n if (t.isFunctionExpression(parent) && parent.id === node) return true\n if (t.isClassDeclaration(parent) && parent.id === node) return true\n if (t.isClassExpression(parent) && parent.id === node) return true\n if (t.isVariableDeclarator(parent) && parent.id === node) return true\n if (t.isImportSpecifier(parent) && parent.local === node) return true\n if (t.isImportDefaultSpecifier(parent) && parent.local === node) return true\n if (t.isImportNamespaceSpecifier(parent) && parent.local === node) return true\n if (\n t.isObjectProperty(parent) &&\n parent.key === node &&\n !parent.computed &&\n // In `{ foo }`, the identifier is also a value reference and must count as\n // usage. Babel represents this as `shorthand: true`.\n !parent.shorthand\n )\n return true\n if (t.isObjectMethod(parent) && parent.key === node && !parent.computed)\n return true\n if (t.isExportSpecifier(parent) && parent.exported === node) return true\n return false\n}\n\nfunction isPreferredUsage(node: t.Node, parent: t.Node | null): boolean {\n if (!parent) return false\n if (t.isCallExpression(parent) && parent.callee === node) return true\n if (t.isNewExpression(parent) && parent.callee === node) return true\n if (t.isMemberExpression(parent) && parent.object === node) return true\n return false\n}\n\nfunction isScopeNode(node: t.Node): boolean {\n return (\n t.isProgram(node) ||\n t.isFunctionDeclaration(node) ||\n t.isFunctionExpression(node) ||\n t.isArrowFunctionExpression(node) ||\n t.isBlockStatement(node) ||\n t.isCatchClause(node)\n )\n}\n\n/** `var` hoists to the nearest function or program scope, not block scopes. */\nfunction isFunctionScopeNode(node: t.Node): boolean {\n return (\n t.isProgram(node) ||\n t.isFunctionDeclaration(node) ||\n t.isFunctionExpression(node) ||\n t.isArrowFunctionExpression(node)\n )\n}\n\nfunction collectScopeBindings(node: t.Node, out: Set<string>): void {\n if (\n t.isFunctionDeclaration(node) ||\n t.isFunctionExpression(node) ||\n t.isArrowFunctionExpression(node)\n ) {\n for (const p of node.params) {\n collectPatternBindings(p, out)\n }\n return\n }\n\n if (t.isCatchClause(node)) {\n collectPatternBindings(node.param, out)\n return\n }\n}\n\n/**\n * Given transformed code, returns the first \"meaningful\" usage position for an\n * import from `source` that survives compilation.\n *\n * The returned column is 0-based (Babel loc semantics).\n */\nexport function findPostCompileUsagePos(\n code: string,\n source: string,\n): UsagePos | undefined {\n const ast = parseAst({ code })\n\n // 1) Determine local names bound from this specifier\n const imported = new Set<string>()\n for (const node of ast.program.body) {\n if (t.isImportDeclaration(node) && node.source.value === source) {\n if (node.importKind === 'type') continue\n for (const s of node.specifiers) {\n if (t.isImportSpecifier(s) && s.importKind === 'type') continue\n imported.add(s.local.name)\n }\n }\n }\n if (imported.size === 0) return undefined\n\n let preferred: UsagePos | undefined\n let anyUsage: UsagePos | undefined\n\n // Scope stack (module scope at index 0).\n // Each entry tracks bindings and whether it is a function/program scope\n // (needed for `var` hoisting).\n interface ScopeEntry {\n bindings: Set<string>\n isFnScope: boolean\n }\n const scopes: Array<ScopeEntry> = [{ bindings: new Set(), isFnScope: true }]\n\n function isShadowed(name: string): boolean {\n // Check inner scopes only\n for (let i = scopes.length - 1; i >= 1; i--) {\n if (scopes[i]!.bindings.has(name)) return true\n }\n return false\n }\n\n function record(node: t.Node, kind: 'preferred' | 'any') {\n const loc = node.loc?.start\n if (!loc) return\n const pos: UsagePos = { line: loc.line, column0: loc.column }\n if (kind === 'preferred') {\n preferred ||= pos\n } else {\n anyUsage ||= pos\n }\n }\n\n function pushScope(node: t.Node): void {\n const bindings = new Set<string>()\n collectScopeBindings(node, bindings)\n scopes.push({ bindings, isFnScope: isFunctionScopeNode(node) })\n }\n\n function popScope(): void {\n scopes.pop()\n }\n\n /** Find the nearest function/program scope entry in the stack. */\n function nearestFnScope(): ScopeEntry {\n for (let i = scopes.length - 1; i >= 0; i--) {\n if (scopes[i]!.isFnScope) return scopes[i]!\n }\n // Should never happen (index 0 is always a function scope).\n return scopes[0]!\n }\n\n // The walker accepts AST nodes, arrays (from node children like\n // `body`, `params`, etc.), or null/undefined for optional children.\n type Walkable =\n | t.Node\n | ReadonlyArray<t.Node | null | undefined>\n | null\n | undefined\n\n function walk(node: Walkable, parent: t.Node | null) {\n if (!node) return\n if (preferred && anyUsage) return\n\n if (Array.isArray(node)) {\n for (const n of node) walk(n, parent)\n return\n }\n\n // After the array check + early return, node is guaranteed to be t.Node.\n // TypeScript doesn't narrow ReadonlyArray from the union, so we assert.\n const astNode = node as t.Node\n\n // Skip import declarations entirely\n if (t.isImportDeclaration(astNode)) return\n\n const enterScope = isScopeNode(astNode)\n if (enterScope) {\n pushScope(astNode)\n }\n\n // Add lexical bindings for variable declarations and class/function decls.\n // Note: function/class *declaration* identifiers bind in the parent scope,\n // so we register them before walking children.\n if (t.isFunctionDeclaration(astNode) && astNode.id) {\n scopes[scopes.length - 2]?.bindings.add(astNode.id.name)\n }\n if (t.isClassDeclaration(astNode) && astNode.id) {\n scopes[scopes.length - 2]?.bindings.add(astNode.id.name)\n }\n if (t.isVariableDeclarator(astNode)) {\n // `var` hoists to the nearest function/program scope, not block scope.\n const isVar = t.isVariableDeclaration(parent) && parent.kind === 'var'\n const target = isVar\n ? nearestFnScope().bindings\n : scopes[scopes.length - 1]!.bindings\n collectPatternBindings(astNode.id, target)\n }\n\n if (t.isIdentifier(astNode) && imported.has(astNode.name)) {\n if (!isBindingPosition(astNode, parent) && !isShadowed(astNode.name)) {\n if (isPreferredUsage(astNode, parent)) {\n record(astNode, 'preferred')\n } else {\n record(astNode, 'any')\n }\n }\n }\n\n // Iterate child properties of this AST node. We use a Record cast since\n // Babel node types don't expose an index signature, but we need to walk\n // all child properties generically.\n const record_ = astNode as unknown as Record<string, unknown>\n for (const key of Object.keys(record_)) {\n const value = record_[key]\n if (!value) continue\n if (key === 'loc' || key === 'start' || key === 'end') continue\n if (key === 'parent') continue\n if (typeof value === 'string' || typeof value === 'number') continue\n walk(value as Walkable, astNode)\n if (preferred && anyUsage) break\n }\n\n if (enterScope) {\n popScope()\n }\n }\n\n walk(ast.program, null)\n return preferred ?? anyUsage\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"postCompileUsage.js","sources":["../../../src/import-protection-plugin/postCompileUsage.ts"],"sourcesContent":["import babel from '@babel/core'\nimport * as t from '@babel/types'\nimport { parseAst } from '@tanstack/router-utils'\n\ntype UsagePos = { line: number; column0: number }\n\n/**\n * Given transformed code, returns the first \"meaningful\" usage position for an\n * import from `source` that survives compilation.\n *\n * \"Preferred\" positions (call, new, member-access) take priority over bare\n * identifier references. The returned column is 0-based (Babel loc semantics).\n */\nexport function findPostCompileUsagePos(\n code: string,\n source: string,\n): UsagePos | undefined {\n const ast = parseAst({ code })\n\n // Collect local names bound from this specifier\n const imported = new Set<string>()\n for (const node of ast.program.body) {\n if (t.isImportDeclaration(node) && node.source.value === source) {\n if (node.importKind === 'type') continue\n for (const s of node.specifiers) {\n if (t.isImportSpecifier(s) && s.importKind === 'type') continue\n imported.add(s.local.name)\n }\n }\n }\n if (imported.size === 0) return undefined\n\n let preferred: UsagePos | undefined\n let anyUsage: UsagePos | undefined\n\n // babel.traverse can throw on malformed scopes (e.g. duplicate bindings from\n // import + const re-declaration) because parseAst doesn't attach a hub\n try {\n babel.traverse(ast, {\n ImportDeclaration(path) {\n path.skip()\n },\n\n Identifier(path: babel.NodePath<t.Identifier>) {\n if (preferred && anyUsage) {\n path.stop()\n return\n }\n\n const { node, parent, scope } = path\n if (!imported.has(node.name)) return\n\n // Skip binding positions (declarations, import specifiers, etc.)\n if (path.isBindingIdentifier()) return\n\n // Skip non-shorthand object property keys — they don't reference the import\n if (\n t.isObjectProperty(parent) &&\n parent.key === node &&\n !parent.computed &&\n !parent.shorthand\n )\n return\n if (t.isObjectMethod(parent) && parent.key === node && !parent.computed)\n return\n if (t.isExportSpecifier(parent) && parent.exported === node) return\n\n // Skip if shadowed by a closer binding\n const binding = scope.getBinding(node.name)\n if (binding && binding.kind !== 'module') return\n\n const loc = node.loc?.start\n if (!loc) return\n const pos: UsagePos = { line: loc.line, column0: loc.column }\n\n const isPreferred =\n (t.isCallExpression(parent) && parent.callee === node) ||\n (t.isNewExpression(parent) && parent.callee === node) ||\n (t.isMemberExpression(parent) && parent.object === node)\n\n if (isPreferred) {\n preferred ||= pos\n } else {\n anyUsage ||= pos\n }\n },\n })\n } catch {\n // Scope analysis failed — cannot determine usage positions reliably\n return undefined\n }\n\n return preferred ?? anyUsage\n}\n"],"names":[],"mappings":";;;AAaO,SAAS,wBACd,MACA,QACsB;AACtB,QAAM,MAAM,SAAS,EAAE,MAAM;AAG7B,QAAM,+BAAe,IAAA;AACrB,aAAW,QAAQ,IAAI,QAAQ,MAAM;AACnC,QAAI,EAAE,oBAAoB,IAAI,KAAK,KAAK,OAAO,UAAU,QAAQ;AAC/D,UAAI,KAAK,eAAe,OAAQ;AAChC,iBAAW,KAAK,KAAK,YAAY;AAC/B,YAAI,EAAE,kBAAkB,CAAC,KAAK,EAAE,eAAe,OAAQ;AACvD,iBAAS,IAAI,EAAE,MAAM,IAAI;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,SAAS,EAAG,QAAO;AAEhC,MAAI;AACJ,MAAI;AAIJ,MAAI;AACF,UAAM,SAAS,KAAK;AAAA,MAClB,kBAAkB,MAAM;AACtB,aAAK,KAAA;AAAA,MACP;AAAA,MAEA,WAAW,MAAoC;AAC7C,YAAI,aAAa,UAAU;AACzB,eAAK,KAAA;AACL;AAAA,QACF;AAEA,cAAM,EAAE,MAAM,QAAQ,MAAA,IAAU;AAChC,YAAI,CAAC,SAAS,IAAI,KAAK,IAAI,EAAG;AAG9B,YAAI,KAAK,sBAAuB;AAGhC,YACE,EAAE,iBAAiB,MAAM,KACzB,OAAO,QAAQ,QACf,CAAC,OAAO,YACR,CAAC,OAAO;AAER;AACF,YAAI,EAAE,eAAe,MAAM,KAAK,OAAO,QAAQ,QAAQ,CAAC,OAAO;AAC7D;AACF,YAAI,EAAE,kBAAkB,MAAM,KAAK,OAAO,aAAa,KAAM;AAG7D,cAAM,UAAU,MAAM,WAAW,KAAK,IAAI;AAC1C,YAAI,WAAW,QAAQ,SAAS,SAAU;AAE1C,cAAM,MAAM,KAAK,KAAK;AACtB,YAAI,CAAC,IAAK;AACV,cAAM,MAAgB,EAAE,MAAM,IAAI,MAAM,SAAS,IAAI,OAAA;AAErD,cAAM,cACH,EAAE,iBAAiB,MAAM,KAAK,OAAO,WAAW,QAChD,EAAE,gBAAgB,MAAM,KAAK,OAAO,WAAW,QAC/C,EAAE,mBAAmB,MAAM,KAAK,OAAO,WAAW;AAErD,YAAI,aAAa;AACf,wBAAc;AAAA,QAChB,OAAO;AACL,uBAAa;AAAA,QACf;AAAA,MACF;AAAA,IAAA,CACD;AAAA,EACH,QAAQ;AAEN,WAAO;AAAA,EACT;AAEA,SAAO,aAAa;AACtB;"}
@@ -1,20 +1,24 @@
1
1
  import * as t from "@babel/types";
2
2
  import { parseAst } from "@tanstack/router-utils";
3
+ import { getOrCreate } from "./utils.js";
3
4
  function isValidExportName(name) {
4
- if (name === "default") return false;
5
- return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
5
+ if (name === "default" || name.length === 0) return false;
6
+ const first = name.charCodeAt(0);
7
+ if (!(first >= 65 && first <= 90 || first >= 97 && first <= 122 || first === 95 || first === 36))
8
+ return false;
9
+ for (let i = 1; i < name.length; i++) {
10
+ const ch = name.charCodeAt(i);
11
+ if (!(ch >= 65 && ch <= 90 || ch >= 97 && ch <= 122 || ch >= 48 && ch <= 57 || ch === 95 || ch === 36))
12
+ return false;
13
+ }
14
+ return true;
6
15
  }
7
16
  function collectMockExportNamesBySource(code) {
8
17
  const ast = parseAst({ code });
9
18
  const namesBySource = /* @__PURE__ */ new Map();
10
19
  const add = (source, name) => {
11
- if (!isValidExportName(name)) return;
12
- let set = namesBySource.get(source);
13
- if (!set) {
14
- set = /* @__PURE__ */ new Set();
15
- namesBySource.set(source, set);
16
- }
17
- set.add(name);
20
+ if (name === "default" || name.length === 0) return;
21
+ getOrCreate(namesBySource, source, () => /* @__PURE__ */ new Set()).add(name);
18
22
  };
19
23
  for (const node of ast.program.body) {
20
24
  if (t.isImportDeclaration(node)) {