@tanstack/start-plugin-core 1.162.1 → 1.162.3
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.
|
@@ -235,7 +235,6 @@ function importProtectionPlugin(opts) {
|
|
|
235
235
|
}
|
|
236
236
|
},
|
|
237
237
|
postTransformImports: /* @__PURE__ */ new Map(),
|
|
238
|
-
hasSeenEntry: false,
|
|
239
238
|
serverFnLookupModules: /* @__PURE__ */ new Set(),
|
|
240
239
|
pendingViolations: /* @__PURE__ */ new Map()
|
|
241
240
|
};
|
|
@@ -311,6 +310,7 @@ function importProtectionPlugin(opts) {
|
|
|
311
310
|
let edgeLive = false;
|
|
312
311
|
if (keySet) {
|
|
313
312
|
for (const k of keySet) {
|
|
313
|
+
if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue;
|
|
314
314
|
const resolvedImports = env.postTransformImports.get(k);
|
|
315
315
|
if (resolvedImports) {
|
|
316
316
|
anyVariantCached = true;
|
|
@@ -350,7 +350,7 @@ function importProtectionPlugin(opts) {
|
|
|
350
350
|
if (env.pendingViolations.size === 0) return;
|
|
351
351
|
const toDelete = [];
|
|
352
352
|
for (const [file, violations] of env.pendingViolations) {
|
|
353
|
-
const status = env.
|
|
353
|
+
const status = env.graph.entries.size > 0 ? checkPostTransformReachability(env, file) : "unknown";
|
|
354
354
|
if (status === "reachable") {
|
|
355
355
|
for (const pv of violations) {
|
|
356
356
|
const key = dedupeKey(
|
|
@@ -537,7 +537,6 @@ function importProtectionPlugin(opts) {
|
|
|
537
537
|
envState.transformResultCache.clear();
|
|
538
538
|
envState.transformResultKeysByFile.clear();
|
|
539
539
|
envState.postTransformImports.clear();
|
|
540
|
-
envState.hasSeenEntry = false;
|
|
541
540
|
envState.serverFnLookupModules.clear();
|
|
542
541
|
envState.graph.clear();
|
|
543
542
|
envState.deniedSources.clear();
|
|
@@ -600,7 +599,6 @@ function importProtectionPlugin(opts) {
|
|
|
600
599
|
source,
|
|
601
600
|
importer: importerPath,
|
|
602
601
|
isEntryResolve,
|
|
603
|
-
hasSeenEntry: env.hasSeenEntry,
|
|
604
602
|
command: config.command,
|
|
605
603
|
behavior: config.effectiveBehavior
|
|
606
604
|
});
|
|
@@ -620,7 +618,7 @@ function importProtectionPlugin(opts) {
|
|
|
620
618
|
}
|
|
621
619
|
if (!importer) {
|
|
622
620
|
env.graph.addEntry(source);
|
|
623
|
-
env.
|
|
621
|
+
await processPendingViolations(env, this.warn.bind(this));
|
|
624
622
|
return void 0;
|
|
625
623
|
}
|
|
626
624
|
if (source.startsWith("\0") || source.startsWith("virtual:")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../../src/import-protection-plugin/plugin.ts"],"sourcesContent":["import { normalizePath } from 'vite'\n\nimport { resolveViteId } from '../utils'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { 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":"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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 * 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 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 // Skip SERVER_FN_LOOKUP variants — they contain untransformed\n // code (the compiler excludes them), so their import lists\n // include imports that the compiler would normally strip.\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 if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue\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 // Wait for entries before running reachability. registerEntries()\n // populates entries at buildStart; resolveId(!importer) may add more.\n const status =\n env.graph.entries.size > 0\n ? checkPostTransformReachability(env, file)\n : 'unknown'\n\n if (status === 'reachable') {\n for (const pv of 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.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 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 // Flush pending violations now that an additional entry is known\n // and reachability analysis may have new roots.\n await processPendingViolations(env, this.warn.bind(this))\n return undefined\n }\n\n if (source.startsWith('\\0') || source.startsWith('virtual:')) {\n return undefined\n }\n\n const normalizedImporter = normalizeFilePath(importer)\n const isDirectLookup = importer.includes(SERVER_FN_LOOKUP_QUERY)\n\n if (isDirectLookup) {\n env.serverFnLookupModules.add(normalizedImporter)\n }\n\n const isPreTransformResolve =\n isDirectLookup ||\n env.serverFnLookupModules.has(normalizedImporter) ||\n isScanResolve\n\n // Dev mock mode: defer 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":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.162.
|
|
3
|
+
"version": "1.162.3",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
"vitefu": "^1.1.1",
|
|
61
61
|
"xmlbuilder2": "^4.0.3",
|
|
62
62
|
"zod": "^3.24.2",
|
|
63
|
-
"@tanstack/router-
|
|
64
|
-
"@tanstack/router-
|
|
63
|
+
"@tanstack/router-core": "1.162.2",
|
|
64
|
+
"@tanstack/router-plugin": "1.162.2",
|
|
65
|
+
"@tanstack/router-generator": "1.162.2",
|
|
65
66
|
"@tanstack/router-utils": "1.161.4",
|
|
66
|
-
"@tanstack/
|
|
67
|
-
"@tanstack/start-
|
|
68
|
-
"@tanstack/start-server-core": "1.162.1"
|
|
67
|
+
"@tanstack/start-client-core": "1.162.2",
|
|
68
|
+
"@tanstack/start-server-core": "1.162.2"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/babel__code-frame": "^7.0.6",
|
|
@@ -185,18 +185,6 @@ interface EnvState {
|
|
|
185
185
|
*/
|
|
186
186
|
postTransformImports: Map<string, Set<string>>
|
|
187
187
|
|
|
188
|
-
/**
|
|
189
|
-
* Whether a `resolveId` call without an importer has been observed for this
|
|
190
|
-
* environment since `buildStart`. Vite calls `resolveId(source, undefined)`
|
|
191
|
-
* for true entry modules during a cold start. On warm start (`.vite` cache
|
|
192
|
-
* exists), Vite reuses its module graph and does NOT call `resolveId` for
|
|
193
|
-
* entries, so this stays `false`.
|
|
194
|
-
*
|
|
195
|
-
* When `false`, the import graph is considered unreliable (edges may be
|
|
196
|
-
* missing) and violations are reported immediately instead of deferred.
|
|
197
|
-
*/
|
|
198
|
-
hasSeenEntry: boolean
|
|
199
|
-
|
|
200
188
|
/**
|
|
201
189
|
* Violations deferred in dev mock mode. Keyed by the violating importer's
|
|
202
190
|
* normalized file path. Violations are confirmed or discarded by the
|
|
@@ -579,7 +567,6 @@ export function importProtectionPlugin(
|
|
|
579
567
|
},
|
|
580
568
|
},
|
|
581
569
|
postTransformImports: new Map(),
|
|
582
|
-
hasSeenEntry: false,
|
|
583
570
|
serverFnLookupModules: new Set(),
|
|
584
571
|
pendingViolations: new Map(),
|
|
585
572
|
}
|
|
@@ -682,12 +669,16 @@ export function importProtectionPlugin(
|
|
|
682
669
|
|
|
683
670
|
// Check all code-split variants for this parent. The edge is
|
|
684
671
|
// live if ANY variant's resolved imports include `current`.
|
|
672
|
+
// Skip SERVER_FN_LOOKUP variants — they contain untransformed
|
|
673
|
+
// code (the compiler excludes them), so their import lists
|
|
674
|
+
// include imports that the compiler would normally strip.
|
|
685
675
|
const keySet = env.transformResultKeysByFile.get(parent)
|
|
686
676
|
let anyVariantCached = false
|
|
687
677
|
let edgeLive = false
|
|
688
678
|
|
|
689
679
|
if (keySet) {
|
|
690
680
|
for (const k of keySet) {
|
|
681
|
+
if (k.includes(SERVER_FN_LOOKUP_QUERY)) continue
|
|
691
682
|
const resolvedImports = env.postTransformImports.get(k)
|
|
692
683
|
if (resolvedImports) {
|
|
693
684
|
anyVariantCached = true
|
|
@@ -752,10 +743,12 @@ export function importProtectionPlugin(
|
|
|
752
743
|
const toDelete: Array<string> = []
|
|
753
744
|
|
|
754
745
|
for (const [file, violations] of env.pendingViolations) {
|
|
755
|
-
//
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
746
|
+
// Wait for entries before running reachability. registerEntries()
|
|
747
|
+
// populates entries at buildStart; resolveId(!importer) may add more.
|
|
748
|
+
const status =
|
|
749
|
+
env.graph.entries.size > 0
|
|
750
|
+
? checkPostTransformReachability(env, file)
|
|
751
|
+
: 'unknown'
|
|
759
752
|
|
|
760
753
|
if (status === 'reachable') {
|
|
761
754
|
for (const pv of violations) {
|
|
@@ -1033,7 +1026,6 @@ export function importProtectionPlugin(
|
|
|
1033
1026
|
envState.transformResultCache.clear()
|
|
1034
1027
|
envState.transformResultKeysByFile.clear()
|
|
1035
1028
|
envState.postTransformImports.clear()
|
|
1036
|
-
envState.hasSeenEntry = false
|
|
1037
1029
|
envState.serverFnLookupModules.clear()
|
|
1038
1030
|
envState.graph.clear()
|
|
1039
1031
|
envState.deniedSources.clear()
|
|
@@ -1118,7 +1110,6 @@ export function importProtectionPlugin(
|
|
|
1118
1110
|
source,
|
|
1119
1111
|
importer: importerPath,
|
|
1120
1112
|
isEntryResolve,
|
|
1121
|
-
hasSeenEntry: env.hasSeenEntry,
|
|
1122
1113
|
command: config.command,
|
|
1123
1114
|
behavior: config.effectiveBehavior,
|
|
1124
1115
|
})
|
|
@@ -1141,7 +1132,9 @@ export function importProtectionPlugin(
|
|
|
1141
1132
|
|
|
1142
1133
|
if (!importer) {
|
|
1143
1134
|
env.graph.addEntry(source)
|
|
1144
|
-
|
|
1135
|
+
// Flush pending violations now that an additional entry is known
|
|
1136
|
+
// and reachability analysis may have new roots.
|
|
1137
|
+
await processPendingViolations(env, this.warn.bind(this))
|
|
1145
1138
|
return undefined
|
|
1146
1139
|
}
|
|
1147
1140
|
|