@tanstack/start-plugin-core 1.162.8 → 1.163.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,11 +6,13 @@ function getDefaultImportProtectionRules() {
6
6
  return {
7
7
  client: {
8
8
  specifiers: clientSpecifiers,
9
- files: ["**/*.server.*"]
9
+ files: ["**/*.server.*"],
10
+ excludeFiles: ["**/node_modules/**"]
10
11
  },
11
12
  server: {
12
13
  specifiers: [],
13
- files: ["**/*.client.*"]
14
+ files: ["**/*.client.*"],
15
+ excludeFiles: ["**/node_modules/**"]
14
16
  }
15
17
  };
16
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"defaults.js","sources":["../../../src/import-protection-plugin/defaults.ts"],"sourcesContent":["import type { ImportProtectionEnvRules } from '../schema'\nimport type { Pattern } from './utils'\n\nexport interface DefaultImportProtectionRules {\n client: Required<ImportProtectionEnvRules>\n server: Required<ImportProtectionEnvRules>\n}\n\nconst frameworks = ['react', 'solid', 'vue'] as const\n\n/**\n * Returns the default import protection rules.\n *\n * All three framework variants are always included so that, e.g., a React\n * project also denies `@tanstack/solid-start/server` imports.\n */\nexport function getDefaultImportProtectionRules(): DefaultImportProtectionRules {\n const clientSpecifiers: Array<Pattern> = frameworks.map(\n (fw) => `@tanstack/${fw}-start/server`,\n )\n\n return {\n client: {\n specifiers: clientSpecifiers,\n files: ['**/*.server.*'],\n },\n server: {\n specifiers: [],\n files: ['**/*.client.*'],\n },\n }\n}\n\n/**\n * Marker module specifiers that restrict a file to a specific environment.\n */\nexport function getMarkerSpecifiers(): {\n serverOnly: Array<string>\n clientOnly: Array<string>\n} {\n return {\n serverOnly: frameworks.map((fw) => `@tanstack/${fw}-start/server-only`),\n clientOnly: frameworks.map((fw) => `@tanstack/${fw}-start/client-only`),\n }\n}\n"],"names":[],"mappings":"AAQA,MAAM,aAAa,CAAC,SAAS,SAAS,KAAK;AAQpC,SAAS,kCAAgE;AAC9E,QAAM,mBAAmC,WAAW;AAAA,IAClD,CAAC,OAAO,aAAa,EAAE;AAAA,EAAA;AAGzB,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,OAAO,CAAC,eAAe;AAAA,IAAA;AAAA,IAEzB,QAAQ;AAAA,MACN,YAAY,CAAA;AAAA,MACZ,OAAO,CAAC,eAAe;AAAA,IAAA;AAAA,EACzB;AAEJ;AAKO,SAAS,sBAGd;AACA,SAAO;AAAA,IACL,YAAY,WAAW,IAAI,CAAC,OAAO,aAAa,EAAE,oBAAoB;AAAA,IACtE,YAAY,WAAW,IAAI,CAAC,OAAO,aAAa,EAAE,oBAAoB;AAAA,EAAA;AAE1E;"}
1
+ {"version":3,"file":"defaults.js","sources":["../../../src/import-protection-plugin/defaults.ts"],"sourcesContent":["import type { ImportProtectionEnvRules } from '../schema'\nimport type { Pattern } from './utils'\n\nexport interface DefaultImportProtectionRules {\n client: Required<ImportProtectionEnvRules>\n server: Required<ImportProtectionEnvRules>\n}\n\nconst frameworks = ['react', 'solid', 'vue'] as const\n\n/**\n * Returns the default import protection rules.\n *\n * All three framework variants are always included so that, e.g., a React\n * project also denies `@tanstack/solid-start/server` imports.\n */\nexport function getDefaultImportProtectionRules(): DefaultImportProtectionRules {\n const clientSpecifiers: Array<Pattern> = frameworks.map(\n (fw) => `@tanstack/${fw}-start/server`,\n )\n\n return {\n client: {\n specifiers: clientSpecifiers,\n files: ['**/*.server.*'],\n excludeFiles: ['**/node_modules/**'],\n },\n server: {\n specifiers: [],\n files: ['**/*.client.*'],\n excludeFiles: ['**/node_modules/**'],\n },\n }\n}\n\n/**\n * Marker module specifiers that restrict a file to a specific environment.\n */\nexport function getMarkerSpecifiers(): {\n serverOnly: Array<string>\n clientOnly: Array<string>\n} {\n return {\n serverOnly: frameworks.map((fw) => `@tanstack/${fw}-start/server-only`),\n clientOnly: frameworks.map((fw) => `@tanstack/${fw}-start/client-only`),\n }\n}\n"],"names":[],"mappings":"AAQA,MAAM,aAAa,CAAC,SAAS,SAAS,KAAK;AAQpC,SAAS,kCAAgE;AAC9E,QAAM,mBAAmC,WAAW;AAAA,IAClD,CAAC,OAAO,aAAa,EAAE;AAAA,EAAA;AAGzB,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,OAAO,CAAC,eAAe;AAAA,MACvB,cAAc,CAAC,oBAAoB;AAAA,IAAA;AAAA,IAErC,QAAQ;AAAA,MACN,YAAY,CAAA;AAAA,MACZ,OAAO,CAAC,eAAe;AAAA,MACvB,cAAc,CAAC,oBAAoB;AAAA,IAAA;AAAA,EACrC;AAEJ;AAKO,SAAS,sBAGd;AACA,SAAO;AAAA,IACL,YAAY,WAAW,IAAI,CAAC,OAAO,aAAa,EAAE,oBAAoB;AAAA,IACtE,YAAY,WAAW,IAAI,CAAC,OAAO,aAAa,EAAE,oBAAoB;AAAA,EAAA;AAE1E;"}
@@ -102,8 +102,8 @@ function importProtectionPlugin(opts) {
102
102
  logMode: "once",
103
103
  maxTraceDepth: 20,
104
104
  compiledRules: {
105
- client: { specifiers: [], files: [] },
106
- server: { specifiers: [], files: [] }
105
+ client: { specifiers: [], files: [], excludeFiles: [] },
106
+ server: { specifiers: [], files: [], excludeFiles: [] }
107
107
  },
108
108
  includeMatchers: [],
109
109
  excludeMatchers: [],
@@ -501,15 +501,19 @@ function importProtectionPlugin(opts) {
501
501
  ...userOpts?.client?.specifiers ?? []
502
502
  ]);
503
503
  const clientFiles = userOpts?.client?.files ? [...userOpts.client.files] : [...defaults.client.files];
504
+ const clientExcludeFiles = userOpts?.client?.excludeFiles ? [...userOpts.client.excludeFiles] : [...defaults.client.excludeFiles];
504
505
  const serverSpecifiers = userOpts?.server?.specifiers ? dedupePatterns([...userOpts.server.specifiers]) : dedupePatterns([...defaults.server.specifiers]);
505
506
  const serverFiles = userOpts?.server?.files ? [...userOpts.server.files] : [...defaults.server.files];
507
+ const serverExcludeFiles = userOpts?.server?.excludeFiles ? [...userOpts.server.excludeFiles] : [...defaults.server.excludeFiles];
506
508
  config.compiledRules.client = {
507
509
  specifiers: compileMatchers(clientSpecifiers),
508
- files: compileMatchers(clientFiles)
510
+ files: compileMatchers(clientFiles),
511
+ excludeFiles: compileMatchers(clientExcludeFiles)
509
512
  };
510
513
  config.compiledRules.server = {
511
514
  specifiers: compileMatchers(serverSpecifiers),
512
- files: compileMatchers(serverFiles)
515
+ files: compileMatchers(serverFiles),
516
+ excludeFiles: compileMatchers(serverExcludeFiles)
513
517
  };
514
518
  if (userOpts?.include) {
515
519
  config.includeMatchers = compileMatchers(userOpts.include);
@@ -732,51 +736,54 @@ function importProtectionPlugin(opts) {
732
736
  env.serverFnLookupModules.add(resolved);
733
737
  }
734
738
  env.graph.addEdge(resolved, normalizedImporter, source);
735
- const fileMatch = matchers.files.length > 0 ? matchesAny(relativePath, matchers.files) : void 0;
736
- if (fileMatch) {
737
- const info = await buildViolationInfo(
739
+ const isExcludedFile = matchers.excludeFiles.length > 0 && matchesAny(relativePath, matchers.excludeFiles);
740
+ if (!isExcludedFile) {
741
+ const fileMatch = matchers.files.length > 0 ? matchesAny(relativePath, matchers.files) : void 0;
742
+ if (fileMatch) {
743
+ const info = await buildViolationInfo(
744
+ provider,
745
+ env,
746
+ envName,
747
+ envType,
748
+ importer,
749
+ normalizedImporter,
750
+ source,
751
+ {
752
+ type: "file",
753
+ pattern: fileMatch.pattern,
754
+ resolved,
755
+ message: `Import "${source}" (resolved to "${relativePath}") is denied in the ${envType} environment`
756
+ }
757
+ );
758
+ return reportOrDeferViolation(
759
+ this,
760
+ env,
761
+ normalizedImporter,
762
+ info,
763
+ shouldDefer,
764
+ isPreTransformResolve
765
+ );
766
+ }
767
+ const markerInfo = await buildMarkerViolationFromResolvedImport(
738
768
  provider,
739
769
  env,
740
770
  envName,
741
771
  envType,
742
772
  importer,
743
- normalizedImporter,
744
773
  source,
745
- {
746
- type: "file",
747
- pattern: fileMatch.pattern,
748
- resolved,
749
- message: `Import "${source}" (resolved to "${relativePath}") is denied in the ${envType} environment`
750
- }
751
- );
752
- return reportOrDeferViolation(
753
- this,
754
- env,
755
- normalizedImporter,
756
- info,
757
- shouldDefer,
758
- isPreTransformResolve
759
- );
760
- }
761
- const markerInfo = await buildMarkerViolationFromResolvedImport(
762
- provider,
763
- env,
764
- envName,
765
- envType,
766
- importer,
767
- source,
768
- resolved,
769
- relativePath
770
- );
771
- if (markerInfo) {
772
- return reportOrDeferViolation(
773
- this,
774
- env,
775
- normalizedImporter,
776
- markerInfo,
777
- shouldDefer,
778
- isPreTransformResolve
774
+ resolved,
775
+ relativePath
779
776
  );
777
+ if (markerInfo) {
778
+ return reportOrDeferViolation(
779
+ this,
780
+ env,
781
+ normalizedImporter,
782
+ markerInfo,
783
+ shouldDefer,
784
+ isPreTransformResolve
785
+ );
786
+ }
780
787
  }
781
788
  }
782
789
  return void 0;
@@ -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_BUILD_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?: (\n info: ViolationInfo,\n ) => boolean | void | Promise<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 /**\n * Violations deferred in build mode (both mock and error). Each gets a\n * unique mock module ID so we can check which ones survived tree-shaking\n * in `generateBundle`.\n */\n deferredBuildViolations: Array<DeferredBuildViolation>\n}\n\ninterface PendingViolation {\n info: ViolationInfo\n /** The mock module ID that resolveId already returned for this violation. */\n mockReturnValue: string\n}\n\ninterface DeferredBuildViolation {\n info: ViolationInfo\n /** Unique mock module ID assigned to this violation. */\n mockModuleId: 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 deferredBuildViolations: [],\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 = await 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 /** Counter for generating unique per-violation mock module IDs in build mode. */\n let buildViolationCounter = 0\n\n type HandleViolationResult =\n | { id: string; syntheticNamedExports: boolean }\n | string\n | undefined\n\n async function handleViolation(\n ctx: ViolationReporter,\n env: EnvState,\n info: ViolationInfo,\n violationOpts?: { silent?: boolean },\n ): Promise<HandleViolationResult> {\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 = await config.onViolation(info)\n if (result === false) {\n return undefined\n }\n }\n\n if (config.effectiveBehavior === 'error') {\n // Dev+error: throw immediately.\n // Always throw on error — do NOT deduplicate via hasSeen().\n // Rollup may resolve the same specifier multiple times (e.g.\n // commonjs--resolver's nested this.resolve() fires before\n // getResolveStaticDependencyPromises). If we record the key\n // on the first (nested) throw, the second (real) resolve\n // silently returns undefined and the build succeeds — which\n // is the bug this fixes.\n //\n // Build mode never reaches here — all build violations are\n // deferred via shouldDefer and handled silently.\n\n return ctx.error(formatViolation(info, config.root))\n }\n\n const seen = hasSeen(env, key)\n\n if (!seen) {\n ctx.warn(formatViolation(info, config.root))\n }\n } else {\n if (config.effectiveBehavior === 'error' && config.command !== 'build') {\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: unique per-violation mock IDs so generateBundle can check\n // which violations survived tree-shaking (both mock and error mode).\n const mockId = `${RESOLVED_MOCK_BUILD_PREFIX}${buildViolationCounter++}`\n return { id: mockId, 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, then stores the violation for later verification:\n * - Dev mock mode: defers to `pendingViolations` for graph-reachability\n * checking via `processPendingViolations`.\n * - Build mode (mock + error): defers to `deferredBuildViolations` for\n * tree-shaking verification in `generateBundle`.\n *\n * Otherwise reports (or silences for 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<HandleViolationResult> {\n if (shouldDefer) {\n const result = await handleViolation(ctx, env, info, { silent: true })\n\n if (config.command === 'build') {\n // Build mode: store for generateBundle tree-shaking check.\n // The unique mock ID is inside `result`.\n const mockId = typeof result === 'string' ? result : (result?.id ?? '')\n env.deferredBuildViolations.push({ info, mockModuleId: mockId })\n } else {\n // Dev mock: store for graph-reachability check.\n deferViolation(env, importerFile, info, result)\n await processPendingViolations(env, ctx.warn.bind(ctx))\n }\n\n return result\n }\n return await 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.pendingViolations.clear()\n envState.deferredBuildViolations.length = 0\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 // Build mode (both mock and error): defer violations until\n // generateBundle so tree-shaking can eliminate false positives.\n const isDevMock =\n config.command === 'serve' && config.effectiveBehavior === 'mock'\n const isBuild = config.command === 'build'\n\n const shouldDefer = (isDevMock && !isPreTransformResolve) || isBuild\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 const markerResult = await reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n\n // In build mode, if the violation was deferred, return the unique\n // build mock ID instead of the marker module. This lets\n // generateBundle check whether the importer (and thus its marker\n // import) survived tree-shaking. The mock is side-effect-free just\n // like the marker module, and the bare import has no bindings, so\n // replacing it is transparent.\n if (isBuild && markerResult != null) {\n return markerResult\n }\n }\n\n 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_MOCK_BUILD_PREFIX,\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 // Per-violation build mock modules — same silent mock code\n if (id.startsWith(RESOLVED_MOCK_BUILD_PREFIX)) {\n return loadSilentMockModule()\n }\n\n if (id.startsWith(RESOLVED_MOCK_EDGE_PREFIX)) {\n return loadMockEdgeModule(\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 async generateBundle(_options, bundle) {\n const envName = this.environment.name\n const env = envStates.get(envName)\n if (!env || env.deferredBuildViolations.length === 0) return\n\n // Collect all module IDs that survived tree-shaking in this bundle.\n const survivingModules = new Set<string>()\n for (const chunk of Object.values(bundle)) {\n if (chunk.type === 'chunk') {\n for (const moduleId of Object.keys(chunk.modules)) {\n survivingModules.add(moduleId)\n }\n }\n }\n\n // Check each deferred violation: if its unique mock module survived\n // in the bundle, the import was NOT tree-shaken — real leak.\n const realViolations: Array<ViolationInfo> = []\n for (const { info, mockModuleId } of env.deferredBuildViolations) {\n if (!survivingModules.has(mockModuleId)) continue\n\n if (config.onViolation) {\n const result = await config.onViolation(info)\n if (result === false) continue\n }\n\n realViolations.push(info)\n }\n\n if (realViolations.length === 0) return\n\n if (config.effectiveBehavior === 'error') {\n // Error mode: fail the build on the first real violation.\n this.error(formatViolation(realViolations[0]!, config.root))\n } else {\n // Mock mode: warn for each surviving violation.\n const seen = new Set<string>()\n for (const info of realViolations) {\n const key = dedupeKey(\n info.type,\n info.importer,\n info.specifier,\n info.resolved,\n )\n if (!seen.has(key)) {\n seen.add(key)\n this.warn(formatViolation(info, config.root))\n }\n }\n }\n },\n },\n {\n // Captures transformed code + composed sourcemap for location mapping.\n // Runs after all `enforce: 'pre'` hooks (including the Start compiler).\n // Only files under `srcDirectory` are cached.\n name: 'tanstack-start-core:import-protection-transform-cache',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n return environmentNames.has(env.name)\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[cm]?[tj]sx?($|\\?)/],\n },\n },\n async handler(code, id) {\n const envName = this.environment.name\n const file = normalizeFilePath(id)\n\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_BUILD_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 excludeFiles: Array<CompiledMatcher>\n }\n server: {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n excludeFiles: 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?: (\n info: ViolationInfo,\n ) => boolean | void | Promise<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 /**\n * Violations deferred in build mode (both mock and error). Each gets a\n * unique mock module ID so we can check which ones survived tree-shaking\n * in `generateBundle`.\n */\n deferredBuildViolations: Array<DeferredBuildViolation>\n}\n\ninterface PendingViolation {\n info: ViolationInfo\n /** The mock module ID that resolveId already returned for this violation. */\n mockReturnValue: string\n}\n\ninterface DeferredBuildViolation {\n info: ViolationInfo\n /** Unique mock module ID assigned to this violation. */\n mockModuleId: 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: [], excludeFiles: [] },\n server: { specifiers: [], files: [], excludeFiles: [] },\n },\n includeMatchers: [],\n excludeMatchers: [],\n ignoreImporterMatchers: [],\n markerSpecifiers: { serverOnly: new Set(), clientOnly: new Set() },\n envTypeMap: new Map(opts.environments.map((e) => [e.name, e.type])),\n onViolation: undefined,\n }\n\n const envStates = new Map<string, EnvState>()\n const shared: SharedState = { fileMarkerKind: new Map() }\n\n 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 excludeFiles: 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 deferredBuildViolations: [],\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 = await 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 /** Counter for generating unique per-violation mock module IDs in build mode. */\n let buildViolationCounter = 0\n\n type HandleViolationResult =\n | { id: string; syntheticNamedExports: boolean }\n | string\n | undefined\n\n async function handleViolation(\n ctx: ViolationReporter,\n env: EnvState,\n info: ViolationInfo,\n violationOpts?: { silent?: boolean },\n ): Promise<HandleViolationResult> {\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 = await config.onViolation(info)\n if (result === false) {\n return undefined\n }\n }\n\n if (config.effectiveBehavior === 'error') {\n // Dev+error: throw immediately.\n // Always throw on error — do NOT deduplicate via hasSeen().\n // Rollup may resolve the same specifier multiple times (e.g.\n // commonjs--resolver's nested this.resolve() fires before\n // getResolveStaticDependencyPromises). If we record the key\n // on the first (nested) throw, the second (real) resolve\n // silently returns undefined and the build succeeds — which\n // is the bug this fixes.\n //\n // Build mode never reaches here — all build violations are\n // deferred via shouldDefer and handled silently.\n\n return ctx.error(formatViolation(info, config.root))\n }\n\n const seen = hasSeen(env, key)\n\n if (!seen) {\n ctx.warn(formatViolation(info, config.root))\n }\n } else {\n if (config.effectiveBehavior === 'error' && config.command !== 'build') {\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: unique per-violation mock IDs so generateBundle can check\n // which violations survived tree-shaking (both mock and error mode).\n const mockId = `${RESOLVED_MOCK_BUILD_PREFIX}${buildViolationCounter++}`\n return { id: mockId, 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, then stores the violation for later verification:\n * - Dev mock mode: defers to `pendingViolations` for graph-reachability\n * checking via `processPendingViolations`.\n * - Build mode (mock + error): defers to `deferredBuildViolations` for\n * tree-shaking verification in `generateBundle`.\n *\n * Otherwise reports (or silences for 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<HandleViolationResult> {\n if (shouldDefer) {\n const result = await handleViolation(ctx, env, info, { silent: true })\n\n if (config.command === 'build') {\n // Build mode: store for generateBundle tree-shaking check.\n // The unique mock ID is inside `result`.\n const mockId = typeof result === 'string' ? result : (result?.id ?? '')\n env.deferredBuildViolations.push({ info, mockModuleId: mockId })\n } else {\n // Dev mock: store for graph-reachability check.\n deferViolation(env, importerFile, info, result)\n await processPendingViolations(env, ctx.warn.bind(ctx))\n }\n\n return result\n }\n return await 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 clientExcludeFiles = userOpts?.client?.excludeFiles\n ? [...userOpts.client.excludeFiles]\n : [...defaults.client.excludeFiles]\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 const serverExcludeFiles = userOpts?.server?.excludeFiles\n ? [...userOpts.server.excludeFiles]\n : [...defaults.server.excludeFiles]\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(clientFiles),\n excludeFiles: compileMatchers(clientExcludeFiles),\n }\n config.compiledRules.server = {\n specifiers: compileMatchers(serverSpecifiers),\n files: compileMatchers(serverFiles),\n excludeFiles: compileMatchers(serverExcludeFiles),\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.pendingViolations.clear()\n envState.deferredBuildViolations.length = 0\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 // Build mode (both mock and error): defer violations until\n // generateBundle so tree-shaking can eliminate false positives.\n const isDevMock =\n config.command === 'serve' && config.effectiveBehavior === 'mock'\n const isBuild = config.command === 'build'\n\n const shouldDefer = (isDevMock && !isPreTransformResolve) || isBuild\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 const markerResult = await reportOrDeferViolation(\n this,\n env,\n normalizedImporter,\n info,\n shouldDefer,\n isPreTransformResolve,\n )\n\n // In build mode, if the violation was deferred, return the unique\n // build mock ID instead of the marker module. This lets\n // generateBundle check whether the importer (and thus its marker\n // import) survived tree-shaking. The mock is side-effect-free just\n // like the marker module, and the bare import has no bindings, so\n // replacing it is transparent.\n if (isBuild && markerResult != null) {\n return markerResult\n }\n }\n\n 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 // Skip file-based and marker-based denial for resolved paths that\n // match the per-environment `excludeFiles` patterns. By default\n // this includes `**/node_modules/**` so that third-party packages\n // using `.client.` / `.server.` in their filenames (e.g. react-tweet\n // exports `index.client.js`) are not treated as user-authored\n // environment boundaries. Users can override `excludeFiles` per\n // environment to narrow or widen this exclusion.\n const isExcludedFile =\n matchers.excludeFiles.length > 0 &&\n matchesAny(relativePath, matchers.excludeFiles)\n\n if (!isExcludedFile) {\n const fileMatch =\n matchers.files.length > 0\n ? matchesAny(relativePath, matchers.files)\n : undefined\n\n if (fileMatch) {\n const info = await 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\n return undefined\n },\n\n load: {\n filter: {\n id: new RegExp(\n [\n RESOLVED_MOCK_MODULE_ID,\n RESOLVED_MOCK_BUILD_PREFIX,\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 // Per-violation build mock modules — same silent mock code\n if (id.startsWith(RESOLVED_MOCK_BUILD_PREFIX)) {\n return loadSilentMockModule()\n }\n\n if (id.startsWith(RESOLVED_MOCK_EDGE_PREFIX)) {\n return loadMockEdgeModule(\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 async generateBundle(_options, bundle) {\n const envName = this.environment.name\n const env = envStates.get(envName)\n if (!env || env.deferredBuildViolations.length === 0) return\n\n // Collect all module IDs that survived tree-shaking in this bundle.\n const survivingModules = new Set<string>()\n for (const chunk of Object.values(bundle)) {\n if (chunk.type === 'chunk') {\n for (const moduleId of Object.keys(chunk.modules)) {\n survivingModules.add(moduleId)\n }\n }\n }\n\n // Check each deferred violation: if its unique mock module survived\n // in the bundle, the import was NOT tree-shaken — real leak.\n const realViolations: Array<ViolationInfo> = []\n for (const { info, mockModuleId } of env.deferredBuildViolations) {\n if (!survivingModules.has(mockModuleId)) continue\n\n if (config.onViolation) {\n const result = await config.onViolation(info)\n if (result === false) continue\n }\n\n realViolations.push(info)\n }\n\n if (realViolations.length === 0) return\n\n if (config.effectiveBehavior === 'error') {\n // Error mode: fail the build on the first real violation.\n this.error(formatViolation(realViolations[0]!, config.root))\n } else {\n // Mock mode: warn for each surviving violation.\n const seen = new Set<string>()\n for (const info of realViolations) {\n const key = dedupeKey(\n info.type,\n info.importer,\n info.specifier,\n info.resolved,\n )\n if (!seen.has(key)) {\n seen.add(key)\n this.warn(formatViolation(info, config.root))\n }\n }\n }\n },\n },\n {\n // Captures transformed code + composed sourcemap for location mapping.\n // Runs after all `enforce: 'pre'` hooks (including the Start compiler).\n // Only files under `srcDirectory` are cached.\n name: 'tanstack-start-core:import-protection-transform-cache',\n\n applyToEnvironment(env) {\n if (!config.enabled) return false\n return environmentNames.has(env.name)\n },\n\n transform: {\n filter: {\n id: {\n include: [/\\.[cm]?[tj]sx?($|\\?)/],\n },\n },\n async handler(code, id) {\n const envName = this.environment.name\n const file = normalizeFilePath(id)\n\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":";;;;;;;;;;;;AA+DA,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;AA2JO,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,CAAA,GAAI,OAAO,CAAA,GAAI,cAAc,GAAC;AAAA,MACpD,QAAQ,EAAE,YAAY,CAAA,GAAI,OAAO,CAAA,GAAI,cAAc,CAAA,EAAC;AAAA,IAAE;AAAA,IAExD,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,SAI9B;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,2CAA2B,IAAA;AAAA,QAC3B,uCAAuB,IAAA;AAAA,QACvB,yBAAyB,CAAA;AAAA,MAAC;AAE5B,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;AAOzB,cAAM,SAAS,IAAI,0BAA0B,IAAI,MAAM;AACvD,YAAI,mBAAmB;AACvB,YAAI,WAAW;AAEf,YAAI,QAAQ;AACV,qBAAW,KAAK,QAAQ;AACtB,gBAAI,EAAE,SAAS,sBAAsB,EAAG;AACxC,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;AAGtD,YAAM,SACJ,IAAI,MAAM,QAAQ,OAAO,IACrB,+BAA+B,KAAK,IAAI,IACxC;AAEN,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,MAAM,OAAO,YAAY,GAAG,IAAI;AAC/C,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;AAGA,MAAI,wBAAwB;AAO5B,iBAAe,gBACb,KACA,KACA,MACA,eACgC;AAChC,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,MAAM,OAAO,YAAY,IAAI;AAC5C,YAAI,WAAW,OAAO;AACpB,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,UAAI,OAAO,sBAAsB,SAAS;AAaxC,eAAO,IAAI,MAAM,gBAAgB,MAAM,OAAO,IAAI,CAAC;AAAA,MACrD;AAEA,YAAM,OAAO,QAAQ,KAAK,GAAG;AAE7B,UAAI,CAAC,MAAM;AACT,YAAI,KAAK,gBAAgB,MAAM,OAAO,IAAI,CAAC;AAAA,MAC7C;AAAA,IACF,OAAO;AACL,UAAI,OAAO,sBAAsB,WAAW,OAAO,YAAY,SAAS;AACtE,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;AAIA,UAAM,SAAS,GAAG,0BAA0B,GAAG,uBAAuB;AACtE,WAAO,EAAE,IAAI,QAAQ,uBAAuB,KAAA;AAAA,EAC9C;AAgBA,iBAAe,uBACb,KACA,KACA,cACA,MACA,aACA,uBACgC;AAChC,QAAI,aAAa;AACf,YAAM,SAAS,MAAM,gBAAgB,KAAK,KAAK,MAAM,EAAE,QAAQ,MAAM;AAErE,UAAI,OAAO,YAAY,SAAS;AAG9B,cAAM,SAAS,OAAO,WAAW,WAAW,SAAU,QAAQ,MAAM;AACpE,YAAI,wBAAwB,KAAK,EAAE,MAAM,cAAc,QAAQ;AAAA,MACjE,OAAO;AAEL,uBAAe,KAAK,cAAc,MAAM,MAAM;AAC9C,cAAM,yBAAyB,KAAK,IAAI,KAAK,KAAK,GAAG,CAAC;AAAA,MACxD;AAEA,aAAO;AAAA,IACT;AACA,WAAO,MAAM,gBAAgB,KAAK,KAAK,MAAM;AAAA,MAC3C,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,qBAAqB,UAAU,QAAQ,eACzC,CAAC,GAAG,SAAS,OAAO,YAAY,IAChC,CAAC,GAAG,SAAS,OAAO,YAAY;AACpC,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;AAC7B,cAAM,qBAAqB,UAAU,QAAQ,eACzC,CAAC,GAAG,SAAS,OAAO,YAAY,IAChC,CAAC,GAAG,SAAS,OAAO,YAAY;AAEpC,eAAO,cAAc,SAAS;AAAA,UAC5B,YAAY,gBAAgB,gBAAgB;AAAA,UAC5C,OAAO,gBAAgB,WAAW;AAAA,UAClC,cAAc,gBAAgB,kBAAkB;AAAA,QAAA;AAElD,eAAO,cAAc,SAAS;AAAA,UAC5B,YAAY,gBAAgB,gBAAgB;AAAA,UAC5C,OAAO,gBAAgB,WAAW;AAAA,UAClC,cAAc,gBAAgB,kBAAkB;AAAA,QAAA;AAIlD,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,sBAAsB,MAAA;AAC/B,mBAAS,kBAAkB,MAAA;AAC3B,mBAAS,wBAAwB,SAAS;AAC1C,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,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;AAGzB,gBAAM,yBAAyB,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AACxD,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;AAMF,cAAM,YACJ,OAAO,YAAY,WAAW,OAAO,sBAAsB;AAC7D,cAAM,UAAU,OAAO,YAAY;AAEnC,cAAM,cAAe,aAAa,CAAC,yBAA0B;AAG7D,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,eAAe,MAAM;AAAA,cACzB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AASF,gBAAI,WAAW,gBAAgB,MAAM;AACnC,qBAAO;AAAA,YACT;AAAA,UACF;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;AAStD,gBAAM,iBACJ,SAAS,aAAa,SAAS,KAC/B,WAAW,cAAc,SAAS,YAAY;AAEhD,cAAI,CAAC,gBAAgB;AACnB,kBAAM,YACJ,SAAS,MAAM,SAAS,IACpB,WAAW,cAAc,SAAS,KAAK,IACvC;AAEN,gBAAI,WAAW;AACb,oBAAM,OAAO,MAAM;AAAA,gBACjB;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,kBACE,MAAM;AAAA,kBACN,SAAS,UAAU;AAAA,kBACnB;AAAA,kBACA,SAAS,WAAW,MAAM,mBAAmB,YAAY,uBAAuB,OAAO;AAAA,gBAAA;AAAA,cACzF;AAEF,qBAAO;AAAA,gBACL;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAEJ;AAEA,kBAAM,aAAa,MAAM;AAAA,cACvB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAEF,gBAAI,YAAY;AACd,qBAAO;AAAA,gBACL;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA;AAAA,YAEJ;AAAA,UACF;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,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;AAGA,cAAI,GAAG,WAAW,0BAA0B,GAAG;AAC7C,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,MAGF,MAAM,eAAe,UAAU,QAAQ;AACrC,cAAM,UAAU,KAAK,YAAY;AACjC,cAAM,MAAM,UAAU,IAAI,OAAO;AACjC,YAAI,CAAC,OAAO,IAAI,wBAAwB,WAAW,EAAG;AAGtD,cAAM,uCAAuB,IAAA;AAC7B,mBAAW,SAAS,OAAO,OAAO,MAAM,GAAG;AACzC,cAAI,MAAM,SAAS,SAAS;AAC1B,uBAAW,YAAY,OAAO,KAAK,MAAM,OAAO,GAAG;AACjD,+BAAiB,IAAI,QAAQ;AAAA,YAC/B;AAAA,UACF;AAAA,QACF;AAIA,cAAM,iBAAuC,CAAA;AAC7C,mBAAW,EAAE,MAAM,aAAA,KAAkB,IAAI,yBAAyB;AAChE,cAAI,CAAC,iBAAiB,IAAI,YAAY,EAAG;AAEzC,cAAI,OAAO,aAAa;AACtB,kBAAM,SAAS,MAAM,OAAO,YAAY,IAAI;AAC5C,gBAAI,WAAW,MAAO;AAAA,UACxB;AAEA,yBAAe,KAAK,IAAI;AAAA,QAC1B;AAEA,YAAI,eAAe,WAAW,EAAG;AAEjC,YAAI,OAAO,sBAAsB,SAAS;AAExC,eAAK,MAAM,gBAAgB,eAAe,CAAC,GAAI,OAAO,IAAI,CAAC;AAAA,QAC7D,OAAO;AAEL,gBAAM,2BAAW,IAAA;AACjB,qBAAW,QAAQ,gBAAgB;AACjC,kBAAM,MAAM;AAAA,cACV,KAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAK;AAAA,YAAA;AAEP,gBAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,mBAAK,IAAI,GAAG;AACZ,mBAAK,KAAK,gBAAgB,MAAM,OAAO,IAAI,CAAC;AAAA,YAC9C;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IAAA;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;"}
@@ -4,12 +4,15 @@ declare const importProtectionBehaviorSchema: z.ZodEnum<["error", "mock"]>;
4
4
  declare const importProtectionEnvRulesSchema: z.ZodObject<{
5
5
  specifiers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
6
6
  files: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
7
+ excludeFiles: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
7
8
  }, "strip", z.ZodTypeAny, {
8
9
  specifiers?: (string | RegExp)[] | undefined;
9
10
  files?: (string | RegExp)[] | undefined;
11
+ excludeFiles?: (string | RegExp)[] | undefined;
10
12
  }, {
11
13
  specifiers?: (string | RegExp)[] | undefined;
12
14
  files?: (string | RegExp)[] | undefined;
15
+ excludeFiles?: (string | RegExp)[] | undefined;
13
16
  }>;
14
17
  declare const importProtectionOptionsSchema: z.ZodOptional<z.ZodObject<{
15
18
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -38,22 +41,28 @@ declare const importProtectionOptionsSchema: z.ZodOptional<z.ZodObject<{
38
41
  client: z.ZodOptional<z.ZodObject<{
39
42
  specifiers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
40
43
  files: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
44
+ excludeFiles: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
41
45
  }, "strip", z.ZodTypeAny, {
42
46
  specifiers?: (string | RegExp)[] | undefined;
43
47
  files?: (string | RegExp)[] | undefined;
48
+ excludeFiles?: (string | RegExp)[] | undefined;
44
49
  }, {
45
50
  specifiers?: (string | RegExp)[] | undefined;
46
51
  files?: (string | RegExp)[] | undefined;
52
+ excludeFiles?: (string | RegExp)[] | undefined;
47
53
  }>>;
48
54
  server: z.ZodOptional<z.ZodObject<{
49
55
  specifiers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
50
56
  files: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
57
+ excludeFiles: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
51
58
  }, "strip", z.ZodTypeAny, {
52
59
  specifiers?: (string | RegExp)[] | undefined;
53
60
  files?: (string | RegExp)[] | undefined;
61
+ excludeFiles?: (string | RegExp)[] | undefined;
54
62
  }, {
55
63
  specifiers?: (string | RegExp)[] | undefined;
56
64
  files?: (string | RegExp)[] | undefined;
65
+ excludeFiles?: (string | RegExp)[] | undefined;
57
66
  }>>;
58
67
  ignoreImporters: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
59
68
  maxTraceDepth: z.ZodOptional<z.ZodNumber>;
@@ -62,10 +71,12 @@ declare const importProtectionOptionsSchema: z.ZodOptional<z.ZodObject<{
62
71
  client?: {
63
72
  specifiers?: (string | RegExp)[] | undefined;
64
73
  files?: (string | RegExp)[] | undefined;
74
+ excludeFiles?: (string | RegExp)[] | undefined;
65
75
  } | undefined;
66
76
  server?: {
67
77
  specifiers?: (string | RegExp)[] | undefined;
68
78
  files?: (string | RegExp)[] | undefined;
79
+ excludeFiles?: (string | RegExp)[] | undefined;
69
80
  } | undefined;
70
81
  exclude?: (string | RegExp)[] | undefined;
71
82
  enabled?: boolean | undefined;
@@ -83,10 +94,12 @@ declare const importProtectionOptionsSchema: z.ZodOptional<z.ZodObject<{
83
94
  client?: {
84
95
  specifiers?: (string | RegExp)[] | undefined;
85
96
  files?: (string | RegExp)[] | undefined;
97
+ excludeFiles?: (string | RegExp)[] | undefined;
86
98
  } | undefined;
87
99
  server?: {
88
100
  specifiers?: (string | RegExp)[] | undefined;
89
101
  files?: (string | RegExp)[] | undefined;
102
+ excludeFiles?: (string | RegExp)[] | undefined;
90
103
  } | undefined;
91
104
  exclude?: (string | RegExp)[] | undefined;
92
105
  enabled?: boolean | undefined;
@@ -402,10 +415,12 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartOptio
402
415
  client?: {
403
416
  specifiers?: (string | RegExp)[] | undefined;
404
417
  files?: (string | RegExp)[] | undefined;
418
+ excludeFiles?: (string | RegExp)[] | undefined;
405
419
  } | undefined;
406
420
  server?: {
407
421
  specifiers?: (string | RegExp)[] | undefined;
408
422
  files?: (string | RegExp)[] | undefined;
423
+ excludeFiles?: (string | RegExp)[] | undefined;
409
424
  } | undefined;
410
425
  exclude?: (string | RegExp)[] | undefined;
411
426
  enabled?: boolean | undefined;
@@ -3236,22 +3251,28 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
3236
3251
  client: z.ZodOptional<z.ZodObject<{
3237
3252
  specifiers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3238
3253
  files: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3254
+ excludeFiles: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3239
3255
  }, "strip", z.ZodTypeAny, {
3240
3256
  specifiers?: (string | RegExp)[] | undefined;
3241
3257
  files?: (string | RegExp)[] | undefined;
3258
+ excludeFiles?: (string | RegExp)[] | undefined;
3242
3259
  }, {
3243
3260
  specifiers?: (string | RegExp)[] | undefined;
3244
3261
  files?: (string | RegExp)[] | undefined;
3262
+ excludeFiles?: (string | RegExp)[] | undefined;
3245
3263
  }>>;
3246
3264
  server: z.ZodOptional<z.ZodObject<{
3247
3265
  specifiers: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3248
3266
  files: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3267
+ excludeFiles: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3249
3268
  }, "strip", z.ZodTypeAny, {
3250
3269
  specifiers?: (string | RegExp)[] | undefined;
3251
3270
  files?: (string | RegExp)[] | undefined;
3271
+ excludeFiles?: (string | RegExp)[] | undefined;
3252
3272
  }, {
3253
3273
  specifiers?: (string | RegExp)[] | undefined;
3254
3274
  files?: (string | RegExp)[] | undefined;
3275
+ excludeFiles?: (string | RegExp)[] | undefined;
3255
3276
  }>>;
3256
3277
  ignoreImporters: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>]>, "many">>;
3257
3278
  maxTraceDepth: z.ZodOptional<z.ZodNumber>;
@@ -3260,10 +3281,12 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
3260
3281
  client?: {
3261
3282
  specifiers?: (string | RegExp)[] | undefined;
3262
3283
  files?: (string | RegExp)[] | undefined;
3284
+ excludeFiles?: (string | RegExp)[] | undefined;
3263
3285
  } | undefined;
3264
3286
  server?: {
3265
3287
  specifiers?: (string | RegExp)[] | undefined;
3266
3288
  files?: (string | RegExp)[] | undefined;
3289
+ excludeFiles?: (string | RegExp)[] | undefined;
3267
3290
  } | undefined;
3268
3291
  exclude?: (string | RegExp)[] | undefined;
3269
3292
  enabled?: boolean | undefined;
@@ -3281,10 +3304,12 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
3281
3304
  client?: {
3282
3305
  specifiers?: (string | RegExp)[] | undefined;
3283
3306
  files?: (string | RegExp)[] | undefined;
3307
+ excludeFiles?: (string | RegExp)[] | undefined;
3284
3308
  } | undefined;
3285
3309
  server?: {
3286
3310
  specifiers?: (string | RegExp)[] | undefined;
3287
3311
  files?: (string | RegExp)[] | undefined;
3312
+ excludeFiles?: (string | RegExp)[] | undefined;
3288
3313
  } | undefined;
3289
3314
  exclude?: (string | RegExp)[] | undefined;
3290
3315
  enabled?: boolean | undefined;
@@ -3598,10 +3623,12 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
3598
3623
  client?: {
3599
3624
  specifiers?: (string | RegExp)[] | undefined;
3600
3625
  files?: (string | RegExp)[] | undefined;
3626
+ excludeFiles?: (string | RegExp)[] | undefined;
3601
3627
  } | undefined;
3602
3628
  server?: {
3603
3629
  specifiers?: (string | RegExp)[] | undefined;
3604
3630
  files?: (string | RegExp)[] | undefined;
3631
+ excludeFiles?: (string | RegExp)[] | undefined;
3605
3632
  } | undefined;
3606
3633
  exclude?: (string | RegExp)[] | undefined;
3607
3634
  enabled?: boolean | undefined;
@@ -3915,10 +3942,12 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
3915
3942
  client?: {
3916
3943
  specifiers?: (string | RegExp)[] | undefined;
3917
3944
  files?: (string | RegExp)[] | undefined;
3945
+ excludeFiles?: (string | RegExp)[] | undefined;
3918
3946
  } | undefined;
3919
3947
  server?: {
3920
3948
  specifiers?: (string | RegExp)[] | undefined;
3921
3949
  files?: (string | RegExp)[] | undefined;
3950
+ excludeFiles?: (string | RegExp)[] | undefined;
3922
3951
  } | undefined;
3923
3952
  exclude?: (string | RegExp)[] | undefined;
3924
3953
  enabled?: boolean | undefined;
@@ -6,7 +6,8 @@ const patternSchema = z.union([z.string(), z.instanceof(RegExp)]);
6
6
  const importProtectionBehaviorSchema = z.enum(["error", "mock"]);
7
7
  const importProtectionEnvRulesSchema = z.object({
8
8
  specifiers: z.array(patternSchema).optional(),
9
- files: z.array(patternSchema).optional()
9
+ files: z.array(patternSchema).optional(),
10
+ excludeFiles: z.array(patternSchema).optional()
10
11
  });
11
12
  const importProtectionOptionsSchema = z.object({
12
13
  enabled: z.boolean().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-plugin'\nimport type { TanStackStartVitePluginCoreOptions } from './types'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })\n .partial()\n\n// --- Import Protection Schema ---\n\nconst patternSchema = z.union([z.string(), z.instanceof(RegExp)])\n\nconst importProtectionBehaviorSchema = z.enum(['error', 'mock'])\n\nconst importProtectionEnvRulesSchema = z.object({\n specifiers: z.array(patternSchema).optional(),\n files: z.array(patternSchema).optional(),\n})\n\nconst importProtectionOptionsSchema = z\n .object({\n enabled: z.boolean().optional(),\n behavior: z\n .union([\n importProtectionBehaviorSchema,\n z.object({\n dev: importProtectionBehaviorSchema.optional(),\n build: importProtectionBehaviorSchema.optional(),\n }),\n ])\n .optional(),\n /**\n * In `behavior: 'mock'`, control whether mocked imports emit a runtime\n * console diagnostic when accessed.\n *\n * - 'error': console.error(new Error(...)) (default)\n * - 'warn': console.warn(new Error(...))\n * - 'off': disable runtime diagnostics\n */\n mockAccess: z.enum(['error', 'warn', 'off']).optional(),\n onViolation: z\n .function()\n .args(z.any())\n .returns(\n z.union([\n z.boolean(),\n z.void(),\n z.promise(z.union([z.boolean(), z.void()])),\n ]),\n )\n .optional(),\n include: z.array(patternSchema).optional(),\n exclude: z.array(patternSchema).optional(),\n client: importProtectionEnvRulesSchema.optional(),\n server: importProtectionEnvRulesSchema.optional(),\n ignoreImporters: z.array(patternSchema).optional(),\n maxTraceDepth: z.number().optional(),\n log: z.enum(['once', 'always']).optional(),\n })\n .optional()\n\nexport function parseStartConfig(\n opts: z.input<typeof tanstackStartOptionsSchema>,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n root: string,\n) {\n const options = tanstackStartOptionsSchema.parse(opts)\n\n const srcDirectory = options.srcDirectory\n\n const routesDirectory = path.resolve(\n root,\n srcDirectory,\n options.router.routesDirectory ?? 'routes',\n )\n\n const generatedRouteTree = path.resolve(\n root,\n srcDirectory,\n options.router.generatedRouteTree ?? 'routeTree.gen.ts',\n )\n\n return {\n ...options,\n router: {\n ...options.router,\n ...getConfig(\n {\n ...options.router,\n routesDirectory,\n generatedRouteTree,\n },\n root,\n ),\n target: corePluginOpts.framework,\n },\n }\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n headers: z.record(z.string(), z.string()).optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nconst pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nconst tanstackStartOptionsSchema = z\n .object({\n srcDirectory: z.string().optional().default('src'),\n start: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n router: z\n .object({\n entry: z.string().optional(),\n basepath: z.string().optional(),\n })\n .and(tsrConfig.optional().default({}))\n .optional()\n .default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n build: z\n .object({\n staticNodeEnv: z.boolean().optional().default(true),\n })\n .optional()\n .default({}),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n generateFunctionId: z\n .function()\n .args(\n z.object({\n filename: z.string(),\n functionName: z.string(),\n }),\n )\n .returns(z.string().optional())\n .optional(),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n autoStaticPathsDiscovery: z.boolean().optional(),\n maxRedirects: z.number().min(0).optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n vite: z\n .object({ installDevServerMiddleware: z.boolean().optional() })\n .optional(),\n importProtection: importProtectionOptionsSchema,\n })\n .optional()\n .default({})\n\nexport type Page = z.infer<typeof pageSchema>\n\nexport type TanStackStartInputConfig = z.input<\n typeof tanstackStartOptionsSchema\n>\nexport type TanStackStartOutputConfig = ReturnType<typeof parseStartConfig>\n\nexport type ImportProtectionBehavior = z.infer<\n typeof importProtectionBehaviorSchema\n>\nexport type ImportProtectionEnvRules = z.infer<\n typeof importProtectionEnvRulesSchema\n>\nexport type ImportProtectionOptions = z.input<\n typeof importProtectionOptionsSchema\n>\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-plugin'\nimport type { TanStackStartVitePluginCoreOptions } from './types'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })\n .partial()\n\n// --- Import Protection Schema ---\n\nconst patternSchema = z.union([z.string(), z.instanceof(RegExp)])\n\nconst importProtectionBehaviorSchema = z.enum(['error', 'mock'])\n\nconst importProtectionEnvRulesSchema = z.object({\n specifiers: z.array(patternSchema).optional(),\n files: z.array(patternSchema).optional(),\n excludeFiles: z.array(patternSchema).optional(),\n})\n\nconst importProtectionOptionsSchema = z\n .object({\n enabled: z.boolean().optional(),\n behavior: z\n .union([\n importProtectionBehaviorSchema,\n z.object({\n dev: importProtectionBehaviorSchema.optional(),\n build: importProtectionBehaviorSchema.optional(),\n }),\n ])\n .optional(),\n /**\n * In `behavior: 'mock'`, control whether mocked imports emit a runtime\n * console diagnostic when accessed.\n *\n * - 'error': console.error(new Error(...)) (default)\n * - 'warn': console.warn(new Error(...))\n * - 'off': disable runtime diagnostics\n */\n mockAccess: z.enum(['error', 'warn', 'off']).optional(),\n onViolation: z\n .function()\n .args(z.any())\n .returns(\n z.union([\n z.boolean(),\n z.void(),\n z.promise(z.union([z.boolean(), z.void()])),\n ]),\n )\n .optional(),\n include: z.array(patternSchema).optional(),\n exclude: z.array(patternSchema).optional(),\n client: importProtectionEnvRulesSchema.optional(),\n server: importProtectionEnvRulesSchema.optional(),\n ignoreImporters: z.array(patternSchema).optional(),\n maxTraceDepth: z.number().optional(),\n log: z.enum(['once', 'always']).optional(),\n })\n .optional()\n\nexport function parseStartConfig(\n opts: z.input<typeof tanstackStartOptionsSchema>,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n root: string,\n) {\n const options = tanstackStartOptionsSchema.parse(opts)\n\n const srcDirectory = options.srcDirectory\n\n const routesDirectory = path.resolve(\n root,\n srcDirectory,\n options.router.routesDirectory ?? 'routes',\n )\n\n const generatedRouteTree = path.resolve(\n root,\n srcDirectory,\n options.router.generatedRouteTree ?? 'routeTree.gen.ts',\n )\n\n return {\n ...options,\n router: {\n ...options.router,\n ...getConfig(\n {\n ...options.router,\n routesDirectory,\n generatedRouteTree,\n },\n root,\n ),\n target: corePluginOpts.framework,\n },\n }\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n headers: z.record(z.string(), z.string()).optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nconst pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nconst tanstackStartOptionsSchema = z\n .object({\n srcDirectory: z.string().optional().default('src'),\n start: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n router: z\n .object({\n entry: z.string().optional(),\n basepath: z.string().optional(),\n })\n .and(tsrConfig.optional().default({}))\n .optional()\n .default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n build: z\n .object({\n staticNodeEnv: z.boolean().optional().default(true),\n })\n .optional()\n .default({}),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n generateFunctionId: z\n .function()\n .args(\n z.object({\n filename: z.string(),\n functionName: z.string(),\n }),\n )\n .returns(z.string().optional())\n .optional(),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n autoStaticPathsDiscovery: z.boolean().optional(),\n maxRedirects: z.number().min(0).optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n vite: z\n .object({ installDevServerMiddleware: z.boolean().optional() })\n .optional(),\n importProtection: importProtectionOptionsSchema,\n })\n .optional()\n .default({})\n\nexport type Page = z.infer<typeof pageSchema>\n\nexport type TanStackStartInputConfig = z.input<\n typeof tanstackStartOptionsSchema\n>\nexport type TanStackStartOutputConfig = ReturnType<typeof parseStartConfig>\n\nexport type ImportProtectionBehavior = z.infer<\n typeof importProtectionBehaviorSchema\n>\nexport type ImportProtectionEnvRules = z.infer<\n typeof importProtectionEnvRulesSchema\n>\nexport type ImportProtectionOptions = z.input<\n typeof importProtectionOptionsSchema\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.8",
3
+ "version": "1.163.0",
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-generator": "1.162.6",
64
- "@tanstack/router-core": "1.162.6",
65
- "@tanstack/router-plugin": "1.162.8",
63
+ "@tanstack/router-core": "1.162.9",
64
+ "@tanstack/router-generator": "1.162.9",
66
65
  "@tanstack/router-utils": "1.161.4",
67
- "@tanstack/start-client-core": "1.162.6",
68
- "@tanstack/start-server-core": "1.162.6"
66
+ "@tanstack/start-client-core": "1.162.9",
67
+ "@tanstack/router-plugin": "1.162.9",
68
+ "@tanstack/start-server-core": "1.162.9"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@types/babel__code-frame": "^7.0.6",
@@ -23,10 +23,12 @@ export function getDefaultImportProtectionRules(): DefaultImportProtectionRules
23
23
  client: {
24
24
  specifiers: clientSpecifiers,
25
25
  files: ['**/*.server.*'],
26
+ excludeFiles: ['**/node_modules/**'],
26
27
  },
27
28
  server: {
28
29
  specifiers: [],
29
30
  files: ['**/*.client.*'],
31
+ excludeFiles: ['**/node_modules/**'],
30
32
  },
31
33
  }
32
34
  }
@@ -110,10 +110,12 @@ interface PluginConfig {
110
110
  client: {
111
111
  specifiers: Array<CompiledMatcher>
112
112
  files: Array<CompiledMatcher>
113
+ excludeFiles: Array<CompiledMatcher>
113
114
  }
114
115
  server: {
115
116
  specifiers: Array<CompiledMatcher>
116
117
  files: Array<CompiledMatcher>
118
+ excludeFiles: Array<CompiledMatcher>
117
119
  }
118
120
  }
119
121
  includeMatchers: Array<CompiledMatcher>
@@ -350,8 +352,8 @@ export function importProtectionPlugin(
350
352
  logMode: 'once',
351
353
  maxTraceDepth: 20,
352
354
  compiledRules: {
353
- client: { specifiers: [], files: [] },
354
- server: { specifiers: [], files: [] },
355
+ client: { specifiers: [], files: [], excludeFiles: [] },
356
+ server: { specifiers: [], files: [], excludeFiles: [] },
355
357
  },
356
358
  includeMatchers: [],
357
359
  excludeMatchers: [],
@@ -540,6 +542,7 @@ export function importProtectionPlugin(
540
542
  function getRulesForEnvironment(envName: string): {
541
543
  specifiers: Array<CompiledMatcher>
542
544
  files: Array<CompiledMatcher>
545
+ excludeFiles: Array<CompiledMatcher>
543
546
  } {
544
547
  const type = getEnvType(envName)
545
548
  return type === 'client'
@@ -1021,20 +1024,28 @@ export function importProtectionPlugin(
1021
1024
  const clientFiles = userOpts?.client?.files
1022
1025
  ? [...userOpts.client.files]
1023
1026
  : [...defaults.client.files]
1027
+ const clientExcludeFiles = userOpts?.client?.excludeFiles
1028
+ ? [...userOpts.client.excludeFiles]
1029
+ : [...defaults.client.excludeFiles]
1024
1030
  const serverSpecifiers = userOpts?.server?.specifiers
1025
1031
  ? dedupePatterns([...userOpts.server.specifiers])
1026
1032
  : dedupePatterns([...defaults.server.specifiers])
1027
1033
  const serverFiles = userOpts?.server?.files
1028
1034
  ? [...userOpts.server.files]
1029
1035
  : [...defaults.server.files]
1036
+ const serverExcludeFiles = userOpts?.server?.excludeFiles
1037
+ ? [...userOpts.server.excludeFiles]
1038
+ : [...defaults.server.excludeFiles]
1030
1039
 
1031
1040
  config.compiledRules.client = {
1032
1041
  specifiers: compileMatchers(clientSpecifiers),
1033
1042
  files: compileMatchers(clientFiles),
1043
+ excludeFiles: compileMatchers(clientExcludeFiles),
1034
1044
  }
1035
1045
  config.compiledRules.server = {
1036
1046
  specifiers: compileMatchers(serverSpecifiers),
1037
1047
  files: compileMatchers(serverFiles),
1048
+ excludeFiles: compileMatchers(serverExcludeFiles),
1038
1049
  }
1039
1050
 
1040
1051
  // Include/exclude
@@ -1344,56 +1355,69 @@ export function importProtectionPlugin(
1344
1355
 
1345
1356
  env.graph.addEdge(resolved, normalizedImporter, source)
1346
1357
 
1347
- const fileMatch =
1348
- matchers.files.length > 0
1349
- ? matchesAny(relativePath, matchers.files)
1350
- : undefined
1358
+ // Skip file-based and marker-based denial for resolved paths that
1359
+ // match the per-environment `excludeFiles` patterns. By default
1360
+ // this includes `**/node_modules/**` so that third-party packages
1361
+ // using `.client.` / `.server.` in their filenames (e.g. react-tweet
1362
+ // exports `index.client.js`) are not treated as user-authored
1363
+ // environment boundaries. Users can override `excludeFiles` per
1364
+ // environment to narrow or widen this exclusion.
1365
+ const isExcludedFile =
1366
+ matchers.excludeFiles.length > 0 &&
1367
+ matchesAny(relativePath, matchers.excludeFiles)
1368
+
1369
+ if (!isExcludedFile) {
1370
+ const fileMatch =
1371
+ matchers.files.length > 0
1372
+ ? matchesAny(relativePath, matchers.files)
1373
+ : undefined
1374
+
1375
+ if (fileMatch) {
1376
+ const info = await buildViolationInfo(
1377
+ provider,
1378
+ env,
1379
+ envName,
1380
+ envType,
1381
+ importer,
1382
+ normalizedImporter,
1383
+ source,
1384
+ {
1385
+ type: 'file',
1386
+ pattern: fileMatch.pattern,
1387
+ resolved,
1388
+ message: `Import "${source}" (resolved to "${relativePath}") is denied in the ${envType} environment`,
1389
+ },
1390
+ )
1391
+ return reportOrDeferViolation(
1392
+ this,
1393
+ env,
1394
+ normalizedImporter,
1395
+ info,
1396
+ shouldDefer,
1397
+ isPreTransformResolve,
1398
+ )
1399
+ }
1351
1400
 
1352
- if (fileMatch) {
1353
- const info = await buildViolationInfo(
1401
+ const markerInfo = await buildMarkerViolationFromResolvedImport(
1354
1402
  provider,
1355
1403
  env,
1356
1404
  envName,
1357
1405
  envType,
1358
1406
  importer,
1359
- normalizedImporter,
1360
1407
  source,
1361
- {
1362
- type: 'file',
1363
- pattern: fileMatch.pattern,
1364
- resolved,
1365
- message: `Import "${source}" (resolved to "${relativePath}") is denied in the ${envType} environment`,
1366
- },
1367
- )
1368
- return reportOrDeferViolation(
1369
- this,
1370
- env,
1371
- normalizedImporter,
1372
- info,
1373
- shouldDefer,
1374
- isPreTransformResolve,
1375
- )
1376
- }
1377
-
1378
- const markerInfo = await buildMarkerViolationFromResolvedImport(
1379
- provider,
1380
- env,
1381
- envName,
1382
- envType,
1383
- importer,
1384
- source,
1385
- resolved,
1386
- relativePath,
1387
- )
1388
- if (markerInfo) {
1389
- return reportOrDeferViolation(
1390
- this,
1391
- env,
1392
- normalizedImporter,
1393
- markerInfo,
1394
- shouldDefer,
1395
- isPreTransformResolve,
1408
+ resolved,
1409
+ relativePath,
1396
1410
  )
1411
+ if (markerInfo) {
1412
+ return reportOrDeferViolation(
1413
+ this,
1414
+ env,
1415
+ normalizedImporter,
1416
+ markerInfo,
1417
+ shouldDefer,
1418
+ isPreTransformResolve,
1419
+ )
1420
+ }
1397
1421
  }
1398
1422
  }
1399
1423
 
package/src/schema.ts CHANGED
@@ -16,6 +16,7 @@ const importProtectionBehaviorSchema = z.enum(['error', 'mock'])
16
16
  const importProtectionEnvRulesSchema = z.object({
17
17
  specifiers: z.array(patternSchema).optional(),
18
18
  files: z.array(patternSchema).optional(),
19
+ excludeFiles: z.array(patternSchema).optional(),
19
20
  })
20
21
 
21
22
  const importProtectionOptionsSchema = z