@tanstack/start-plugin-core 1.168.0 → 1.169.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/import-protection/extensionlessAbsoluteIdResolver.js +1 -1
- package/dist/esm/import-protection/utils.js +1 -1
- package/dist/esm/import-protection/utils.js.map +1 -1
- package/dist/esm/index.d.ts +1 -9
- package/dist/esm/index.js +2 -6
- package/dist/esm/rsbuild/import-protection.js +1 -1
- package/dist/esm/rsbuild/import-protection.js.map +1 -1
- package/dist/esm/rsbuild/index.d.ts +4 -0
- package/dist/esm/rsbuild/index.js +3 -0
- package/dist/esm/start-manifest-plugin/manifestBuilder.js +1 -1
- package/dist/esm/start-manifest-plugin/manifestBuilder.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -1
- package/dist/esm/utils.js +8 -2
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/vite/index.d.ts +5 -0
- package/dist/esm/vite/index.js +4 -0
- package/package.json +16 -1
- package/src/import-protection/utils.ts +1 -1
- package/src/index.ts +1 -13
- package/src/rsbuild/import-protection.ts +1 -2
- package/src/rsbuild/index.ts +4 -0
- package/src/start-manifest-plugin/manifestBuilder.ts +4 -4
- package/src/utils.ts +12 -2
- package/src/vite/index.ts +8 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { KNOWN_SOURCE_EXTENSIONS } from "./constants.js";
|
|
2
2
|
import { normalizeFilePath } from "./utils.js";
|
|
3
|
-
import { resolveModulePath } from "exsolve";
|
|
4
3
|
import { basename, dirname, extname, isAbsolute } from "node:path";
|
|
4
|
+
import { resolveModulePath } from "exsolve";
|
|
5
5
|
//#region src/import-protection/extensionlessAbsoluteIdResolver.ts
|
|
6
6
|
var FILE_RESOLUTION_EXTENSIONS = [...KNOWN_SOURCE_EXTENSIONS];
|
|
7
7
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { normalizePath } from "../utils.js";
|
|
1
2
|
import { IMPORT_PROTECTION_DEBUG, IMPORT_PROTECTION_DEBUG_FILTER, KNOWN_SOURCE_EXTENSIONS } from "./constants.js";
|
|
2
|
-
import { normalizePath } from "vite";
|
|
3
3
|
import { extname, isAbsolute, relative, resolve } from "node:path";
|
|
4
4
|
//#region src/import-protection/utils.ts
|
|
5
5
|
function dedupePatterns(patterns) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/import-protection/utils.ts"],"sourcesContent":["import {\n extname,\n isAbsolute,\n relative,\n resolve as resolvePath,\n} from 'node:path'\nimport { normalizePath } from '
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../src/import-protection/utils.ts"],"sourcesContent":["import {\n extname,\n isAbsolute,\n relative,\n resolve as resolvePath,\n} from 'node:path'\nimport { normalizePath } from '../utils'\n\nimport {\n IMPORT_PROTECTION_DEBUG,\n IMPORT_PROTECTION_DEBUG_FILTER,\n KNOWN_SOURCE_EXTENSIONS,\n} from './constants'\n\nexport type Pattern = string | RegExp\n\nexport function dedupePatterns(patterns: Array<Pattern>): Array<Pattern> {\n const out: Array<Pattern> = []\n const seen = new Set<string>()\n for (const p of patterns) {\n const key = typeof p === 'string' ? `s:${p}` : `r:${p.toString()}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(p)\n }\n return out\n}\n\nexport interface FileMatchers {\n files: Array<{ pattern: Pattern; test: (value: string) => boolean }>\n excludeFiles: Array<{ pattern: Pattern; test: (value: string) => boolean }>\n}\n\nexport function isFileExcluded(\n relativePath: string,\n matchers: Pick<FileMatchers, 'excludeFiles'>,\n): boolean {\n return (\n matchers.excludeFiles.length > 0 &&\n matchers.excludeFiles.some((matcher) => matcher.test(relativePath))\n )\n}\n\nexport function checkFileDenial(\n relativePath: string,\n matchers: FileMatchers,\n): FileMatchers['files'][number] | undefined {\n if (isFileExcluded(relativePath, matchers)) {\n return undefined\n }\n\n return matchers.files.find((matcher) => matcher.test(relativePath))\n}\n\nexport function dedupeViolationKey(info: {\n type: string\n importer: string\n specifier: string\n resolved?: string\n}): string {\n return `${info.type}:${info.importer}:${info.specifier}:${info.resolved ?? ''}`\n}\n\n/** Strip both `?query` and `#hash` from a module ID. */\nexport function stripQueryAndHash(id: string): string {\n const q = id.indexOf('?')\n const h = id.indexOf('#')\n if (q === -1 && h === -1) return id\n if (q === -1) return id.slice(0, h)\n if (h === -1) return id.slice(0, q)\n return id.slice(0, Math.min(q, h))\n}\n\n/**\n * Strip Vite query/hash parameters and normalize the path in one step.\n *\n * Results are memoized because the same module IDs are processed many\n * times across resolveId, transform, and trace-building hooks.\n */\nconst normalizeFilePathCache = new Map<string, string>()\nexport function normalizeFilePath(id: string): string {\n let result = normalizeFilePathCache.get(id)\n if (result === undefined) {\n result = normalizePath(stripQueryAndHash(id))\n normalizeFilePathCache.set(id, result)\n }\n return result\n}\n\n/** Clear the memoization cache (call from buildStart to bound growth). */\nexport function clearNormalizeFilePathCache(): void {\n normalizeFilePathCache.clear()\n}\n\nexport function escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/** Get a value from a Map, creating it with `factory` if absent. */\nexport function getOrCreate<TKey, TValue>(\n map: Map<TKey, TValue>,\n key: TKey,\n factory: () => TValue,\n): TValue {\n let value = map.get(key)\n if (value === undefined) {\n value = factory()\n map.set(key, value)\n }\n return value\n}\n\n/** Make a path relative to `root`, keeping non-rooted paths as-is. */\nexport function relativizePath(p: string, root: string): string {\n if (!p.startsWith(root)) return p\n const ch = p.charCodeAt(root.length)\n // Must be followed by a separator or end-of-string to be a true child\n if (ch !== 47 && !Number.isNaN(ch)) return p\n return ch === 47 ? p.slice(root.length + 1) : p.slice(root.length)\n}\n\n/** Log import-protection debug output when debug mode is enabled. */\nexport function debugLog(...args: Array<unknown>): void {\n if (!IMPORT_PROTECTION_DEBUG) return\n console.warn('[import-protection:debug]', ...args)\n}\n\n/** Check if any value matches the configured debug filter (if present). */\nexport function matchesDebugFilter(...values: Array<string>): boolean {\n const debugFilter = IMPORT_PROTECTION_DEBUG_FILTER\n if (!debugFilter) return true\n return values.some((v) => v.includes(debugFilter))\n}\n\n/** Strip `?query` (but not `#hash`) from a module ID. */\nexport function stripQuery(id: string): string {\n const queryIndex = id.indexOf('?')\n return queryIndex === -1 ? id : id.slice(0, queryIndex)\n}\n\nexport function withoutKnownExtension(id: string): string {\n const ext = extname(id)\n return KNOWN_SOURCE_EXTENSIONS.has(ext) ? id.slice(0, -ext.length) : id\n}\n\n/**\n * Check whether `filePath` is contained inside `directory` using a\n * boundary-safe comparison. A naïve `filePath.startsWith(directory)`\n * would incorrectly treat `/app/src2/foo.ts` as inside `/app/src`.\n */\nexport function isInsideDirectory(\n filePath: string,\n directory: string,\n): boolean {\n const rel = relative(resolvePath(directory), resolvePath(filePath))\n return rel.length > 0 && !rel.startsWith('..') && !isAbsolute(rel)\n}\n\n/**\n * Decide whether a violation should be deferred for later verification\n * rather than reported immediately.\n *\n * Build mode: always defer — generateBundle checks tree-shaking.\n * Dev mock mode: always defer — edge-survival verifies whether the Start\n * compiler strips the import (factory-safe pattern). All violation\n * types and specifier formats are handled uniformly by the\n * edge-survival mechanism in processPendingViolations.\n * Dev error mode: never defer — throw immediately (no mock fallback).\n */\nexport function shouldDeferViolation(opts: {\n isBuild: boolean\n isDevMock: boolean\n}): boolean {\n return opts.isBuild || opts.isDevMock\n}\n\nexport function buildSourceCandidates(\n source: string,\n resolved: string | undefined,\n root: string,\n): Set<string> {\n const candidates = new Set<string>()\n const push = (value: string | undefined) => {\n if (!value) return\n candidates.add(value)\n candidates.add(stripQuery(value))\n candidates.add(withoutKnownExtension(stripQuery(value)))\n }\n\n push(source)\n if (resolved) {\n push(resolved)\n const relativeResolved = relativizePath(resolved, root)\n push(relativeResolved)\n push(`./${relativeResolved}`)\n push(`/${relativeResolved}`)\n }\n\n return candidates\n}\n\nexport function buildResolutionCandidates(id: string): Array<string> {\n const normalized = normalizeFilePath(id)\n const stripped = stripQuery(normalized)\n\n return [...new Set([id, normalized, stripped])]\n}\n\nexport function canonicalizeResolvedId(\n id: string,\n root: string,\n resolveExtensionlessAbsoluteId: (value: string) => string,\n): string {\n const stripped = stripQuery(id)\n let normalized = normalizeFilePath(stripped)\n\n if (\n !isAbsolute(normalized) &&\n !normalized.startsWith('.') &&\n !normalized.startsWith('\\0') &&\n !/^[a-zA-Z]+:/.test(normalized)\n ) {\n normalized = normalizeFilePath(resolvePath(root, normalized))\n }\n\n return resolveExtensionlessAbsoluteId(normalized)\n}\n"],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,11 +1,3 @@
|
|
|
1
1
|
export type { TanStackStartInputConfig } from './schema.js';
|
|
2
2
|
export type { TanStackStartCoreOptions } from './types.js';
|
|
3
|
-
export
|
|
4
|
-
export type { TanStackStartViteInputConfig } from './vite/schema.js';
|
|
5
|
-
export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from './constants.js';
|
|
6
|
-
export { createVirtualModule } from './vite/createVirtualModule.js';
|
|
7
|
-
export { tanStackStartVite } from './vite/plugin.js';
|
|
8
|
-
export { RSBUILD_ENVIRONMENT_NAMES } from './rsbuild/planning.js';
|
|
9
|
-
export type { TanStackStartRsbuildPluginCoreOptions } from './rsbuild/types.js';
|
|
10
|
-
export type { TanStackStartRsbuildInputConfig } from './rsbuild/schema.js';
|
|
11
|
-
export { tanStackStartRsbuild } from './rsbuild/plugin.js';
|
|
3
|
+
export { START_ENVIRONMENT_NAMES } from './constants.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import { START_ENVIRONMENT_NAMES
|
|
2
|
-
|
|
3
|
-
import { tanStackStartVite } from "./vite/plugin.js";
|
|
4
|
-
import { RSBUILD_ENVIRONMENT_NAMES } from "./rsbuild/planning.js";
|
|
5
|
-
import { tanStackStartRsbuild } from "./rsbuild/plugin.js";
|
|
6
|
-
export { RSBUILD_ENVIRONMENT_NAMES, START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES, createVirtualModule, tanStackStartRsbuild, tanStackStartVite };
|
|
1
|
+
import { START_ENVIRONMENT_NAMES } from "./constants.js";
|
|
2
|
+
export { START_ENVIRONMENT_NAMES };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizePath } from "../utils.js";
|
|
1
2
|
import { buildResolutionCandidates, buildSourceCandidates, canonicalizeResolvedId, checkFileDenial, clearNormalizeFilePathCache, dedupePatterns, dedupeViolationKey, isFileExcluded, normalizeFilePath } from "../import-protection/utils.js";
|
|
2
3
|
import { ImportGraph, buildTrace, formatViolation } from "../import-protection/trace.js";
|
|
3
4
|
import { getDefaultImportProtectionRules, getMarkerSpecifiers } from "../import-protection/defaults.js";
|
|
@@ -8,7 +9,6 @@ import { findOriginalUnsafeUsagePosFromResult, getImportSources, getMockExportNa
|
|
|
8
9
|
import { rewriteDeniedImports } from "../import-protection/rewrite.js";
|
|
9
10
|
import { ExtensionlessAbsoluteIdResolver } from "../import-protection/extensionlessAbsoluteIdResolver.js";
|
|
10
11
|
import { generateDevSelfDenialModule, generateSelfContainedMockModule, loadMockEdgeModule, loadMockRuntimeModule, loadSilentMockModule } from "../import-protection/virtualModules.js";
|
|
11
|
-
import { normalizePath } from "vite";
|
|
12
12
|
import { extname, resolve } from "node:path";
|
|
13
13
|
//#region src/rsbuild/import-protection.ts
|
|
14
14
|
var importSpecifierLocationIndex = createImportSpecifierLocationIndex();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-protection.js","names":[],"sources":["../../../src/rsbuild/import-protection.ts"],"sourcesContent":["import { extname, resolve as resolvePath } from 'node:path'\n\nimport { normalizePath } from 'vite'\n\nimport {\n getDefaultImportProtectionRules,\n getMarkerSpecifiers,\n} from '../import-protection/defaults'\nimport { ExtensionlessAbsoluteIdResolver } from '../import-protection/extensionlessAbsoluteIdResolver'\nimport { compileMatchers, matchesAny } from '../import-protection/matchers'\nimport {\n getImportProtectionEnvType,\n getImportProtectionRelativePath,\n getImportProtectionRulesForEnvironment,\n shouldCheckImportProtectionImporter,\n} from '../import-protection/adapterUtils'\nimport {\n findOriginalUnsafeUsagePosFromResult,\n getImportSources,\n getMockExportNamesBySource,\n getNamedExports,\n} from '../import-protection/analysis'\nimport { rewriteDeniedImports } from '../import-protection/rewrite'\nimport {\n ImportLocCache,\n addTraceImportLocations,\n buildCodeSnippet,\n buildLineIndex,\n createImportSpecifierLocationIndex,\n findImportStatementLocationFromTransformed,\n findOriginalUsageLocation,\n findPostCompileUsageLocation,\n getOrCreateOriginalTransformResult,\n indexToLineColumn,\n normalizeSourceMap,\n pickOriginalCodeFromSourcesContent,\n} from '../import-protection/sourceLocation'\nimport {\n ImportGraph,\n buildTrace,\n formatViolation,\n} from '../import-protection/trace'\nimport {\n generateDevSelfDenialModule,\n generateSelfContainedMockModule,\n loadMockEdgeModule,\n loadMockRuntimeModule,\n loadSilentMockModule,\n} from '../import-protection/virtualModules'\nimport {\n buildResolutionCandidates,\n buildSourceCandidates,\n canonicalizeResolvedId,\n checkFileDenial,\n clearNormalizeFilePathCache,\n dedupePatterns,\n dedupeViolationKey,\n isFileExcluded,\n normalizeFilePath,\n} from '../import-protection/utils'\n\nimport type {\n ImportProtectionBehavior,\n ImportProtectionOptions,\n} from '../schema'\nimport type { CompiledMatcher } from '../import-protection/matchers'\nimport type {\n SourceMapLike,\n TransformResult,\n TransformResultProvider,\n} from '../import-protection/sourceLocation'\nimport type { Loc, TraceStep, ViolationInfo } from '../import-protection/trace'\nimport type { CompileStartFrameworkOptions, GetConfigFn } from '../types'\nimport type {\n RsbuildPluginAPI,\n Rspack,\n rspack as rspackNamespaceType,\n} from '@rsbuild/core'\n\ntype RspackNamespace = typeof rspackNamespaceType\ntype RspackVirtualModulesPlugin = InstanceType<\n RspackNamespace['experiments']['VirtualModulesPlugin']\n>\ntype ProcessAssetsContext = Parameters<\n Parameters<RsbuildPluginAPI['processAssets']>[1]\n>[0]\ntype TransformContext = Parameters<\n Parameters<RsbuildPluginAPI['transform']>[1]\n>[0]\ntype RspackCompilation = Rspack.Compilation\ntype RspackModule = Rspack.Module\ntype RspackModuleGraphConnection = {\n module?: RspackModule | null\n dependency?: unknown\n getActiveState?: (runtime: string | Array<string> | undefined) => unknown\n}\ntype OriginalCodeLoader = (file: string) => Promise<string | undefined>\nconst importSpecifierLocationIndex = createImportSpecifierLocationIndex()\n\ninterface EnvRules {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n excludeFiles: Array<CompiledMatcher>\n}\n\ninterface PluginConfig {\n enabled: boolean\n root: string\n command: 'build' | 'serve'\n srcDirectory: string\n framework: CompileStartFrameworkOptions\n effectiveBehavior: ImportProtectionBehavior\n mockAccess: 'error' | 'warn' | 'off'\n logMode: 'once' | 'always'\n maxTraceDepth: number\n compiledRules: {\n client: EnvRules\n server: EnvRules\n }\n includeMatchers: Array<CompiledMatcher>\n excludeMatchers: Array<CompiledMatcher>\n ignoreImporterMatchers: Array<CompiledMatcher>\n markerSpecifiers: {\n serverOnly: Set<string>\n clientOnly: Set<string>\n }\n envTypeMap: Map<string, 'client' | 'server'>\n onViolation?: (\n info: ViolationInfo,\n ) => boolean | void | Promise<boolean | void>\n}\n\ninterface EnvRuntimeState {\n resolveCache: Map<string, string | null>\n seenViolations: Set<string>\n buildTransformResults: Map<string, TransformResult>\n deferredFileViolations: Array<DeferredFileViolation>\n deferredFileViolationKeys: Set<string>\n}\n\ninterface DeferredFileViolation {\n importer: string\n specifier: string\n resolved: string\n relativeResolved: string\n pattern: string | RegExp\n useOriginalLocation: boolean\n}\n\ninterface SharedState {\n root: string\n virtualModules: Map<string, string>\n vmPlugins: Record<string, RspackVirtualModulesPlugin>\n readyVmPlugins: Record<string, boolean>\n inputFileSystems: Record<string, Rspack.Compiler['inputFileSystem']>\n pendingWrites: Map<string, Map<string, string>>\n}\n\ninterface CompilationEdge {\n importer: string\n specifier?: string\n resolved: string\n}\n\ninterface MockEdgePayload {\n exports: Array<string>\n runtimeId: string\n violation: {\n env: string\n envType: 'client' | 'server'\n importer: string\n specifier: string\n resolved?: string\n patternText: string\n }\n}\n\nconst IMPORT_PROTECTION_VIRTUAL_DIR = 'node_modules/.virtual/import-protection'\nconst MOCK_EDGE_FILE_PREFIX = 'mock-edge-'\nconst MOCK_RUNTIME_FILE_PREFIX = 'mock-runtime-'\nconst MOCK_SILENT_FILE = 'mock-silent.mjs'\n\nfunction toBase64Url(input: unknown): string {\n return Buffer.from(JSON.stringify(input), 'utf8').toString('base64url')\n}\n\nfunction fromBase64Url<T>(input: string): T {\n return JSON.parse(Buffer.from(input, 'base64url').toString('utf8')) as T\n}\n\nfunction getRulesForEnvironment(\n config: PluginConfig,\n envName: string,\n): EnvRules {\n return getImportProtectionRulesForEnvironment(config, envName) as EnvRules\n}\n\nfunction serializePattern(pattern: string | RegExp): string {\n return typeof pattern === 'string' ? pattern : pattern.toString()\n}\n\nfunction dedupeKey(info: ViolationInfo): string {\n return dedupeViolationKey(info)\n}\n\nfunction getOrCreateEnvState(\n envStates: Map<string, EnvRuntimeState>,\n envName: string,\n): EnvRuntimeState {\n let env = envStates.get(envName)\n\n if (!env) {\n env = {\n resolveCache: new Map(),\n seenViolations: new Set(),\n buildTransformResults: new Map(),\n deferredFileViolations: [],\n deferredFileViolationKeys: new Set(),\n }\n envStates.set(envName, env)\n }\n\n return env\n}\n\nfunction getVirtualModulePath(\n root: string,\n envName: string,\n filename: string,\n): string {\n return normalizePath(\n resolvePath(root, IMPORT_PROTECTION_VIRTUAL_DIR, envName, filename),\n )\n}\n\nfunction queuePendingWrite(\n shared: SharedState,\n envName: string,\n filePath: string,\n code: string,\n): void {\n let writes = shared.pendingWrites.get(envName)\n if (!writes) {\n writes = new Map()\n shared.pendingWrites.set(envName, writes)\n }\n\n writes.set(filePath, code)\n}\n\nfunction tryWriteVirtualModule(\n shared: SharedState,\n envName: string,\n filePath: string,\n code: string,\n): string {\n const current = shared.virtualModules.get(filePath)\n if (current === code) {\n return filePath\n }\n\n shared.virtualModules.set(filePath, code)\n\n const vmPlugin = shared.vmPlugins[envName]\n if (!vmPlugin || !shared.readyVmPlugins[envName]) {\n queuePendingWrite(shared, envName, filePath, code)\n return filePath\n }\n\n vmPlugin.writeModule(filePath, code)\n return filePath\n}\n\nfunction flushPendingWrites(shared: SharedState, envName: string): void {\n const writes = shared.pendingWrites.get(envName)\n if (!writes?.size || !shared.readyVmPlugins[envName]) {\n return\n }\n\n for (const [filePath, code] of writes) {\n shared.vmPlugins[envName]?.writeModule(filePath, code)\n writes.delete(filePath)\n }\n\n if (writes.size === 0) {\n shared.pendingWrites.delete(envName)\n }\n}\n\nfunction ensureSilentMockModule(shared: SharedState, envName: string): string {\n return tryWriteVirtualModule(\n shared,\n envName,\n getVirtualModulePath(shared.root, envName, MOCK_SILENT_FILE),\n loadSilentMockModule().code,\n )\n}\n\nfunction ensureRuntimeMockModule(opts: {\n shared: SharedState\n envName: string\n mode: 'error' | 'warn' | 'off'\n env: string\n importer: string\n specifier: string\n}): string {\n const encoded = toBase64Url({\n mode: opts.mode,\n env: opts.env,\n importer: opts.importer,\n specifier: opts.specifier,\n trace: [],\n })\n\n return tryWriteVirtualModule(\n opts.shared,\n opts.envName,\n getVirtualModulePath(\n opts.shared.root,\n opts.envName,\n `${MOCK_RUNTIME_FILE_PREFIX}${encoded}.mjs`,\n ),\n loadMockRuntimeModule(encoded).code,\n )\n}\n\nfunction ensureMockEdgeModule(opts: {\n shared: SharedState\n envName: string\n payload: MockEdgePayload\n}): string {\n const encoded = toBase64Url(opts.payload)\n\n return tryWriteVirtualModule(\n opts.shared,\n opts.envName,\n getVirtualModulePath(\n opts.shared.root,\n opts.envName,\n `${MOCK_EDGE_FILE_PREFIX}${encoded}.mjs`,\n ),\n loadMockEdgeModule(encoded).code,\n )\n}\n\nfunction getMockEdgePayloadFromFile(\n filePath: string,\n): MockEdgePayload | undefined {\n const match = /(?:^|[\\\\/])mock-edge-([^/\\\\]+)\\.mjs$/.exec(filePath)\n if (!match) {\n return undefined\n }\n\n try {\n return fromBase64Url<MockEdgePayload>(match[1]!)\n } catch {\n return undefined\n }\n}\n\nasync function loadOriginalCode(\n cache: Map<string, Promise<string | undefined>>,\n file: string,\n loader: OriginalCodeLoader,\n): Promise<string | undefined> {\n let result = cache.get(file)\n if (!result) {\n result = loader(file)\n cache.set(file, result)\n }\n\n return result\n}\n\nasync function loadOriginalCodeFromInputFileSystem(\n inputFileSystem: NonNullable<RspackCompilation['inputFileSystem']>,\n file: string,\n): Promise<string | undefined> {\n return new Promise((resolve) => {\n inputFileSystem.readFile(file, (error, data) => {\n if (error || data == null) {\n resolve(undefined)\n return\n }\n\n resolve(typeof data === 'string' ? data : data.toString('utf8'))\n })\n })\n}\n\nasync function resolveAgainstImporter(opts: {\n envState: EnvRuntimeState\n config: PluginConfig\n ctx: TransformContext\n importerId: string\n source: string\n extensionlessResolver: ExtensionlessAbsoluteIdResolver\n}): Promise<string | null> {\n const normalizedImporter = normalizeFilePath(opts.importerId)\n const cacheKey = `${normalizedImporter}:${opts.source}`\n\n if (opts.envState.resolveCache.has(cacheKey)) {\n return opts.envState.resolveCache.get(cacheKey) ?? null\n }\n\n const importerDir =\n opts.ctx.context ?? opts.importerId.replace(/[/\\\\][^/\\\\]*$/, '')\n\n const resolved = await new Promise<string | null>((resolve, reject) => {\n opts.ctx.resolve(importerDir, opts.source, (error, result) => {\n if (error) {\n reject(error)\n return\n }\n\n resolve(typeof result === 'string' ? result : null)\n })\n }).catch(() => null)\n\n if (!resolved) {\n opts.envState.resolveCache.set(cacheKey, null)\n return null\n }\n\n const canonical = canonicalizeResolvedId(\n resolved,\n opts.config.root,\n (value) => opts.extensionlessResolver.resolve(value),\n )\n\n opts.envState.resolveCache.set(cacheKey, canonical)\n return canonical\n}\n\nfunction getModuleResource(module: RspackModule): string | undefined {\n const candidate = module as RspackModule & {\n nameForCondition?: () => string | undefined\n resourceResolveData?: { resource?: string }\n resource?: string\n userRequest?: string\n request?: string\n }\n\n return (\n candidate.nameForCondition() ??\n candidate.resourceResolveData?.resource ??\n candidate.resource ??\n candidate.userRequest ??\n candidate.request\n )\n}\n\nfunction getModuleFile(module: RspackModule): string {\n return normalizeFilePath(getModuleResource(module) ?? module.identifier())\n}\n\nconst IMPORT_PROTECTION_PARSEABLE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n])\n\nfunction isImportProtectionSourceFile(file: string | undefined): boolean {\n if (!file) {\n return false\n }\n\n const extension = extname(normalizeFilePath(file))\n return (\n extension.length > 0 &&\n IMPORT_PROTECTION_PARSEABLE_EXTENSIONS.has(extension)\n )\n}\n\nfunction isImportProtectionSourceModule(module: RspackModule): boolean {\n return isImportProtectionSourceFile(getModuleResource(module))\n}\n\nfunction addTransformResult(\n cache: Map<string, TransformResult>,\n key: string,\n result: TransformResult,\n): void {\n cache.set(normalizePath(key), result)\n cache.set(normalizeFilePath(key), result)\n}\n\nfunction hasTransformResult(\n cache: Map<string, TransformResult>,\n key: string,\n): boolean {\n return cache.has(normalizePath(key)) || cache.has(normalizeFilePath(key))\n}\n\nfunction deferFileViolation(\n envState: EnvRuntimeState,\n violation: DeferredFileViolation,\n): void {\n const key = `${violation.importer}:${violation.specifier}:${violation.resolved}:${String(violation.pattern)}`\n if (envState.deferredFileViolationKeys.has(key)) {\n return\n }\n\n envState.deferredFileViolationKeys.add(key)\n envState.deferredFileViolations.push(violation)\n}\n\nfunction hasOriginalUnsafeUsage(\n result: TransformResult | undefined,\n source: string,\n envType: 'client' | 'server',\n): boolean {\n if (!result) {\n return false\n }\n\n const originalResult = getOrCreateOriginalTransformResult(result)\n if (!originalResult) {\n return false\n }\n\n return !!findOriginalUnsafeUsagePosFromResult(originalResult, source, envType)\n}\n\nasync function buildTransformResultProvider(opts: {\n modules: Array<RspackModule>\n root: string\n loadOriginalCode: OriginalCodeLoader\n preloaded?: Map<string, TransformResult>\n}): Promise<TransformResultProvider> {\n const cache = new Map<string, TransformResult>()\n\n if (opts.preloaded) {\n for (const [key, result] of opts.preloaded) {\n cache.set(key, result)\n }\n }\n\n for (const module of opts.modules) {\n const source = module.originalSource()\n if (!source) continue\n\n const sourceAndMap = source.sourceAndMap()\n const code = String(sourceAndMap.source)\n const map = normalizeSourceMap(sourceAndMap.map as SourceMapLike | null)\n const file = getModuleFile(module)\n const resource = getModuleResource(module)\n\n const originalCode = map?.sourcesContent\n ? (pickOriginalCodeFromSourcesContent(map, resource ?? file, opts.root) ??\n (resource ? await opts.loadOriginalCode(resource) : undefined))\n : resource\n ? await opts.loadOriginalCode(resource)\n : undefined\n\n const result: TransformResult = {\n code,\n map,\n originalCode,\n lineIndex: buildLineIndex(code),\n }\n\n if (!hasTransformResult(cache, file)) {\n addTransformResult(cache, file, result)\n }\n\n if (resource && !hasTransformResult(cache, resource)) {\n addTransformResult(cache, resource, result)\n }\n }\n\n return {\n getTransformResult(id: string) {\n return cache.get(normalizePath(id)) ?? cache.get(normalizeFilePath(id))\n },\n }\n}\n\nfunction getConnectionRequest(dependency: unknown): string | undefined {\n const candidate = dependency as { request?: unknown }\n return typeof candidate.request === 'string' ? candidate.request : undefined\n}\n\nfunction addEntryModulesToGraph(opts: {\n compilation: RspackCompilation\n graph: ImportGraph\n}): void {\n for (const entry of opts.compilation.entries.values()) {\n for (const dependency of entry.dependencies) {\n const connection = opts.compilation.moduleGraph.getConnection(dependency)\n const module = connection?.module\n if (!module) continue\n opts.graph.addEntry(getModuleFile(module))\n }\n }\n}\n\nfunction buildCompilationGraph(opts: {\n compilation: RspackCompilation\n modules: Array<RspackModule>\n}): { graph: ImportGraph; edges: Array<CompilationEdge> } {\n const graph = new ImportGraph()\n const edges: Array<CompilationEdge> = []\n\n addEntryModulesToGraph({\n compilation: opts.compilation,\n graph,\n })\n\n for (const module of opts.modules) {\n const importer = getModuleFile(module)\n const connections =\n opts.compilation.moduleGraph.getOutgoingConnectionsInOrder(module)\n\n for (const connection of connections) {\n if (!connection.module) continue\n if (!isActiveConnection(connection)) continue\n\n const resolved = getModuleFile(connection.module)\n const specifier = getConnectionRequest(connection.dependency)\n graph.addEdge(resolved, importer, specifier)\n edges.push({ importer, specifier, resolved })\n }\n }\n\n return { graph, edges }\n}\n\nfunction isActiveConnection(connection: RspackModuleGraphConnection): boolean {\n if (typeof connection.getActiveState !== 'function') {\n return true\n }\n\n return connection.getActiveState(undefined) === true\n}\n\nfunction findImportLocationInOriginalCode(\n provider: TransformResultProvider,\n importer: string,\n source: string,\n): Loc | undefined {\n const result = provider.getTransformResult(importer)\n if (!result) {\n return undefined\n }\n\n const originalResult = getOrCreateOriginalTransformResult(result)\n if (!originalResult) {\n return undefined\n }\n\n const index = importSpecifierLocationIndex.find(originalResult, source)\n if (index === -1) {\n return undefined\n }\n\n const lineIndex =\n originalResult.lineIndex ??\n (originalResult.lineIndex = buildLineIndex(originalResult.code))\n const loc = indexToLineColumn(lineIndex, index)\n\n return {\n file: normalizeFilePath(importer),\n line: loc.line,\n column: loc.column,\n }\n}\n\nasync function resolveImporterLocation(opts: {\n provider: TransformResultProvider\n importLocCache: ImportLocCache\n importer: string\n sourceCandidates: Iterable<string>\n preferOriginalCode?: boolean\n envType?: 'client' | 'server'\n}): Promise<Loc | undefined> {\n if (opts.preferOriginalCode) {\n for (const candidate of opts.sourceCandidates) {\n const loc =\n findOriginalUsageLocation(\n opts.provider,\n opts.importer,\n candidate,\n opts.envType,\n ) ??\n findImportLocationInOriginalCode(\n opts.provider,\n opts.importer,\n candidate,\n )\n if (loc) {\n return loc\n }\n }\n }\n\n for (const candidate of opts.sourceCandidates) {\n const loc =\n (await findPostCompileUsageLocation(\n opts.provider,\n opts.importer,\n candidate,\n )) ||\n (await findImportStatementLocationFromTransformed(\n opts.provider,\n opts.importer,\n candidate,\n opts.importLocCache,\n importSpecifierLocationIndex.find,\n ))\n\n if (loc) {\n return loc\n }\n }\n\n if (!opts.preferOriginalCode) {\n for (const candidate of opts.sourceCandidates) {\n const loc = findImportLocationInOriginalCode(\n opts.provider,\n opts.importer,\n candidate,\n )\n if (loc) {\n return loc\n }\n }\n }\n\n return undefined\n}\n\nasync function rebuildAndAnnotateTrace(opts: {\n provider: TransformResultProvider\n graph: ImportGraph\n importLocCache: ImportLocCache\n importer: string\n specifier: string\n importerLoc?: Loc\n maxTraceDepth: number\n}): Promise<Array<TraceStep>> {\n const trace = buildTrace(opts.graph, opts.importer, opts.maxTraceDepth)\n\n await addTraceImportLocations(\n opts.provider,\n trace,\n opts.importLocCache,\n importSpecifierLocationIndex.find,\n )\n\n if (trace.length > 0) {\n const last = trace[trace.length - 1]!\n if (!last.specifier) {\n last.specifier = opts.specifier\n }\n if (opts.importerLoc && last.line == null) {\n last.line = opts.importerLoc.line\n last.column = opts.importerLoc.column\n }\n }\n\n return trace\n}\n\nasync function buildViolationInfo(opts: {\n config: PluginConfig\n provider: TransformResultProvider\n graph: ImportGraph\n importLocCache: ImportLocCache\n envName: string\n envType: 'client' | 'server'\n importer: string\n source: string\n resolved?: string\n type: 'specifier' | 'file' | 'marker'\n pattern?: string | RegExp\n preferOriginalCode?: boolean\n}): Promise<ViolationInfo> {\n const importerLoc = await resolveImporterLocation({\n provider: opts.provider,\n importLocCache: opts.importLocCache,\n importer: opts.importer,\n sourceCandidates: buildSourceCandidates(\n opts.source,\n opts.resolved,\n opts.config.root,\n ),\n preferOriginalCode: opts.preferOriginalCode,\n envType: opts.envType,\n })\n\n const trace = await rebuildAndAnnotateTrace({\n provider: opts.provider,\n graph: opts.graph,\n importLocCache: opts.importLocCache,\n importer: opts.importer,\n specifier: opts.source,\n importerLoc,\n maxTraceDepth: opts.config.maxTraceDepth,\n })\n\n const snippet = importerLoc\n ? buildCodeSnippet(opts.provider, opts.importer, importerLoc)\n : undefined\n\n return {\n env: opts.envName,\n envType: opts.envType,\n behavior: opts.config.effectiveBehavior,\n type: opts.type,\n pattern: opts.pattern,\n specifier: opts.source,\n importer: opts.importer,\n ...(opts.resolved ? { resolved: opts.resolved } : {}),\n ...(importerLoc ? { importerLoc } : {}),\n trace,\n snippet,\n }\n}\n\nasync function getMarkerKindForFile(opts: {\n config: PluginConfig\n provider: TransformResultProvider\n loadOriginalCode: OriginalCodeLoader\n markerKindCache: Map<string, Promise<'server' | 'client' | undefined>>\n file: string\n}): Promise<'server' | 'client' | undefined> {\n if (!isImportProtectionSourceFile(opts.file)) {\n return undefined\n }\n\n let cached = opts.markerKindCache.get(opts.file)\n if (!cached) {\n cached = (async () => {\n const code =\n opts.provider.getTransformResult(opts.file)?.originalCode ??\n (await opts.loadOriginalCode(opts.file))\n\n if (!code) {\n return undefined\n }\n\n const imports = getImportSources(code)\n const hasServerOnly = imports.some((source) =>\n opts.config.markerSpecifiers.serverOnly.has(source),\n )\n const hasClientOnly = imports.some((source) =>\n opts.config.markerSpecifiers.clientOnly.has(source),\n )\n\n if (hasServerOnly && !hasClientOnly) {\n return 'server'\n }\n\n if (hasClientOnly && !hasServerOnly) {\n return 'client'\n }\n\n return undefined\n })()\n opts.markerKindCache.set(opts.file, cached)\n }\n\n return cached\n}\n\nasync function reportViolation(opts: {\n config: PluginConfig\n envState: EnvRuntimeState\n compilation: RspackCompilation\n rspack: RspackNamespace\n info: ViolationInfo\n}): Promise<void> {\n const key = dedupeKey(opts.info)\n if (\n opts.config.logMode !== 'always' &&\n opts.envState.seenViolations.has(key)\n ) {\n return\n }\n\n opts.envState.seenViolations.add(key)\n\n if (opts.config.onViolation) {\n const result = await opts.config.onViolation(opts.info)\n if (result === false) {\n return\n }\n }\n\n const message = formatViolation(opts.info, opts.config.root)\n const error = new opts.rspack.WebpackError(message)\n\n if (opts.config.effectiveBehavior === 'error') {\n opts.compilation.errors.push(error)\n } else {\n opts.compilation.warnings.push(error)\n }\n}\n\nexport function registerImportProtection(\n api: RsbuildPluginAPI,\n opts: {\n getConfig: GetConfigFn\n framework: CompileStartFrameworkOptions\n environments: Array<{ name: string; type: 'client' | 'server' }>\n },\n): void {\n const extensionlessResolver = new ExtensionlessAbsoluteIdResolver()\n const envStates = new Map<string, EnvRuntimeState>()\n const fileReadCache = new Map<string, Promise<string | undefined>>()\n\n const config: PluginConfig = {\n enabled: true,\n root: '',\n command: api.context.action === 'dev' ? 'serve' : 'build',\n srcDirectory: '',\n framework: opts.framework,\n effectiveBehavior: 'error',\n mockAccess: 'error',\n logMode: 'once',\n maxTraceDepth: 20,\n compiledRules: {\n client: {\n specifiers: [],\n files: [],\n excludeFiles: [],\n },\n server: {\n specifiers: [],\n files: [],\n excludeFiles: [],\n },\n },\n includeMatchers: [],\n excludeMatchers: [],\n ignoreImporterMatchers: [],\n markerSpecifiers: {\n serverOnly: new Set(),\n clientOnly: new Set(),\n },\n envTypeMap: new Map(opts.environments.map((env) => [env.name, env.type])),\n onViolation: undefined,\n }\n\n const shared: SharedState = {\n root: '',\n virtualModules: new Map(),\n vmPlugins: {},\n readyVmPlugins: {},\n inputFileSystems: {},\n pendingWrites: new Map(),\n }\n\n function applyUserConfig(): void {\n const { startConfig, resolvedStartConfig } = opts.getConfig()\n\n config.root = resolvedStartConfig.root\n config.srcDirectory = resolvedStartConfig.srcDirectory\n shared.root = resolvedStartConfig.root\n\n const userOpts: ImportProtectionOptions | undefined =\n startConfig.importProtection\n\n if (userOpts?.enabled === false) {\n config.enabled = false\n return\n }\n\n config.enabled = true\n\n const behavior = userOpts?.behavior\n if (typeof behavior === 'string') {\n config.effectiveBehavior = behavior\n } else {\n config.effectiveBehavior =\n config.command === 'serve'\n ? (behavior?.dev ?? 'mock')\n : (behavior?.build ?? 'error')\n }\n\n config.logMode = userOpts?.log ?? 'once'\n config.mockAccess = userOpts?.mockAccess ?? 'error'\n config.maxTraceDepth = userOpts?.maxTraceDepth ?? 20\n config.onViolation = userOpts?.onViolation\n ? (info) => userOpts.onViolation?.(info)\n : undefined\n\n const defaults = getDefaultImportProtectionRules()\n const pick = <T>(user: Array<T> | undefined, fallback: Array<T>) =>\n user ? [...user] : [...fallback]\n\n const clientSpecifiers = dedupePatterns([\n ...defaults.client.specifiers,\n ...(userOpts?.client?.specifiers ?? []),\n ])\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(\n pick(userOpts?.client?.files, defaults.client.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.client?.excludeFiles, defaults.client.excludeFiles),\n ),\n }\n\n config.compiledRules.server = {\n specifiers: compileMatchers(\n dedupePatterns(\n pick(userOpts?.server?.specifiers, defaults.server.specifiers),\n ),\n ),\n files: compileMatchers(\n pick(userOpts?.server?.files, defaults.server.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.server?.excludeFiles, defaults.server.excludeFiles),\n ),\n }\n\n config.includeMatchers = compileMatchers(userOpts?.include ?? [])\n config.excludeMatchers = compileMatchers(userOpts?.exclude ?? [])\n config.ignoreImporterMatchers = compileMatchers(\n userOpts?.ignoreImporters ?? [],\n )\n\n const markers = getMarkerSpecifiers()\n config.markerSpecifiers = {\n serverOnly: new Set(markers.serverOnly),\n clientOnly: new Set(markers.clientOnly),\n }\n }\n\n api.onBeforeBuild(() => {\n applyUserConfig()\n clearNormalizeFilePathCache()\n extensionlessResolver.clear()\n fileReadCache.clear()\n envStates.clear()\n })\n\n api.onBeforeDevCompile(() => {\n applyUserConfig()\n clearNormalizeFilePathCache()\n extensionlessResolver.clear()\n fileReadCache.clear()\n\n for (const envState of envStates.values()) {\n envState.resolveCache.clear()\n envState.buildTransformResults.clear()\n envState.deferredFileViolations.length = 0\n envState.deferredFileViolationKeys.clear()\n }\n })\n\n api.modifyRspackConfig((rspackConfig, utils) => {\n applyUserConfig()\n\n const envName = utils.environment.name\n const VMP = utils.rspack.experiments.VirtualModulesPlugin\n const vmPlugin = new VMP({})\n\n shared.vmPlugins[envName] = vmPlugin\n shared.readyVmPlugins[envName] = false\n\n rspackConfig.plugins.push(vmPlugin)\n rspackConfig.plugins.push({\n apply(compiler: Rspack.Compiler) {\n shared.inputFileSystems[envName] = compiler.inputFileSystem\n compiler.hooks.thisCompilation.tap(\n 'TanStackStartImportProtectionVirtualModulesReady',\n () => {\n shared.readyVmPlugins[envName] = true\n flushPendingWrites(shared, envName)\n },\n )\n },\n })\n })\n\n for (const environment of opts.environments) {\n api.transform(\n {\n test: /\\.[cm]?[tj]sx?$/,\n environments: [environment.name],\n order: 'post',\n },\n async (ctx) => {\n if (!config.enabled) {\n return ctx.code\n }\n\n const envName = environment.name\n const envType = getImportProtectionEnvType(config, envName)\n const envState = getOrCreateEnvState(envStates, envName)\n const id = ctx.resource\n const file = normalizeFilePath(ctx.resourcePath)\n\n if (!shouldCheckImportProtectionImporter(config, file)) {\n return ctx.code\n }\n\n const matchers = getRulesForEnvironment(config, envName)\n const relativeFile = getImportProtectionRelativePath(config.root, file)\n const importSources = getImportSources(ctx.code)\n const transformedImportSources = new Set(importSources)\n const transformInputFileSystem = shared.inputFileSystems[envName]\n const loadOriginalCodeForTransform: OriginalCodeLoader =\n transformInputFileSystem\n ? (target) =>\n loadOriginalCodeFromInputFileSystem(\n transformInputFileSystem,\n target,\n )\n : () => Promise.resolve(undefined)\n const originalCode =\n config.command === 'build'\n ? await loadOriginalCode(\n fileReadCache,\n file,\n loadOriginalCodeForTransform,\n )\n : undefined\n const buildImportSources = originalCode\n ? getImportSources(originalCode)\n : []\n const buildTransformResult: TransformResult | undefined =\n config.command === 'build'\n ? {\n code: ctx.code,\n map: undefined,\n originalCode,\n lineIndex: buildLineIndex(ctx.code),\n }\n : undefined\n\n if (config.command === 'build') {\n const relativeBuildFile = getImportProtectionRelativePath(\n config.root,\n file,\n )\n addTransformResult(\n envState.buildTransformResults,\n file,\n buildTransformResult!,\n )\n addTransformResult(\n envState.buildTransformResults,\n relativeBuildFile,\n buildTransformResult!,\n )\n if (id !== file) {\n addTransformResult(\n envState.buildTransformResults,\n id,\n buildTransformResult!,\n )\n }\n }\n\n const hasServerOnlyMarker = importSources.some((source) =>\n config.markerSpecifiers.serverOnly.has(source),\n )\n const hasClientOnlyMarker = importSources.some((source) =>\n config.markerSpecifiers.clientOnly.has(source),\n )\n\n if (hasServerOnlyMarker && hasClientOnlyMarker) {\n throw new Error(\n `[import-protection] File \"${relativeFile}\" has both server-only and client-only markers. This is not allowed.`,\n )\n }\n\n const markerKind = hasServerOnlyMarker\n ? ('server' as const)\n : hasClientOnlyMarker\n ? ('client' as const)\n : undefined\n\n const fileMatch = checkFileDenial(relativeFile, matchers)\n const markerViolation =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n\n if (fileMatch || markerViolation) {\n let exportNames: Array<string> = []\n\n try {\n exportNames = getNamedExports(ctx.code)\n } catch {\n exportNames = []\n }\n\n if (config.command === 'build') {\n return generateSelfContainedMockModule(exportNames)\n }\n\n const runtimeId = ensureRuntimeMockModule({\n shared,\n envName,\n mode: config.mockAccess,\n env: envName,\n importer: file,\n specifier: relativeFile,\n })\n\n return generateDevSelfDenialModule(exportNames, runtimeId)\n }\n\n const deniedSpecifierReplacements = new Map<string, string>()\n const exportsBySource = (() => {\n try {\n return getMockExportNamesBySource(ctx.code)\n } catch {\n return new Map<string, Array<string>>()\n }\n })()\n\n for (const source of importSources) {\n const specifierMatch = matchesAny(source, matchers.specifiers)\n if (!specifierMatch && config.command === 'build') {\n const resolved = await resolveAgainstImporter({\n envState,\n config,\n ctx,\n importerId: id,\n source,\n extensionlessResolver,\n })\n\n if (resolved) {\n const relativeResolved = getImportProtectionRelativePath(\n config.root,\n resolved,\n )\n const buildFileMatch = checkFileDenial(relativeResolved, matchers)\n if (\n buildFileMatch &&\n hasOriginalUnsafeUsage(buildTransformResult, source, envType)\n ) {\n deferFileViolation(envState, {\n importer: file,\n specifier: source,\n resolved,\n relativeResolved,\n pattern: buildFileMatch.pattern,\n useOriginalLocation: true,\n })\n }\n }\n\n continue\n }\n\n if (!specifierMatch) {\n continue\n }\n\n const resolved = await resolveAgainstImporter({\n envState,\n config,\n ctx,\n importerId: id,\n source,\n extensionlessResolver,\n })\n\n const runtimeId =\n config.command === 'build'\n ? ensureSilentMockModule(shared, envName)\n : ensureRuntimeMockModule({\n shared,\n envName,\n mode: config.mockAccess,\n env: envName,\n importer: file,\n specifier: source,\n })\n\n const replacement = ensureMockEdgeModule({\n shared,\n envName,\n payload: {\n exports: exportsBySource.get(source) ?? [],\n runtimeId,\n violation: {\n env: envName,\n envType,\n importer: file,\n specifier: source,\n ...(resolved ? { resolved } : {}),\n patternText: serializePattern(specifierMatch.pattern),\n },\n },\n })\n\n deniedSpecifierReplacements.set(source, replacement)\n }\n\n if (config.command === 'build') {\n for (const source of buildImportSources) {\n if (transformedImportSources.has(source)) {\n continue\n }\n\n if (matchesAny(source, matchers.specifiers)) {\n continue\n }\n\n const resolved = await resolveAgainstImporter({\n envState,\n config,\n ctx,\n importerId: id,\n source,\n extensionlessResolver,\n })\n\n if (!resolved) {\n continue\n }\n\n const relativeResolved = getImportProtectionRelativePath(\n config.root,\n resolved,\n )\n const buildFileMatch = checkFileDenial(relativeResolved, matchers)\n if (\n !buildFileMatch ||\n !hasOriginalUnsafeUsage(buildTransformResult, source, envType)\n ) {\n continue\n }\n\n deferFileViolation(envState, {\n importer: file,\n specifier: source,\n resolved,\n relativeResolved,\n pattern: buildFileMatch.pattern,\n useOriginalLocation: true,\n })\n }\n }\n\n if (deniedSpecifierReplacements.size === 0) {\n return ctx.code\n }\n\n const rewritten = rewriteDeniedImports(\n ctx.code,\n id,\n new Set(deniedSpecifierReplacements.keys()),\n (source) => deniedSpecifierReplacements.get(source) ?? source,\n )\n\n if (!rewritten) {\n return ctx.code\n }\n\n return {\n code: rewritten.code,\n map: normalizeSourceMap(rewritten.map) ?? null,\n }\n },\n )\n }\n\n api.processAssets(\n {\n stage: 'report',\n environments: opts.environments.map((environment) => environment.name),\n },\n async (context: ProcessAssetsContext) => {\n if (!config.enabled) {\n return\n }\n\n const envName = context.environment.name\n const envType = getImportProtectionEnvType(config, envName)\n const envState = getOrCreateEnvState(envStates, envName)\n const matchers = getRulesForEnvironment(config, envName)\n const processFileReadCache = new Map<\n string,\n Promise<string | undefined>\n >()\n const loadOriginalCodeFromCompilation: OriginalCodeLoader = (file) =>\n loadOriginalCode(\n processFileReadCache,\n file,\n context.compilation.inputFileSystem\n ? (target) =>\n loadOriginalCodeFromInputFileSystem(\n context.compilation.inputFileSystem!,\n target,\n )\n : () => Promise.resolve(undefined),\n )\n const allModules = Array.from(context.compilation.modules)\n const relevantModules = allModules.filter(isImportProtectionSourceModule)\n\n const provider = await buildTransformResultProvider({\n modules: relevantModules,\n root: config.root,\n loadOriginalCode: loadOriginalCodeFromCompilation,\n preloaded: envState.buildTransformResults,\n })\n const importLocCache = new ImportLocCache()\n const markerKindCache = new Map<\n string,\n Promise<'server' | 'client' | undefined>\n >()\n const { graph, edges } = buildCompilationGraph({\n compilation: context.compilation,\n modules: relevantModules,\n })\n const liveFileEdgeKeys = new Set(\n edges\n .filter((edge) => !!edge.specifier)\n .map(\n (edge) =>\n `${normalizeFilePath(edge.importer)}::${edge.specifier!}::${normalizeFilePath(edge.resolved)}`,\n ),\n )\n const survivingModules = new Set<string>()\n for (const module of relevantModules) {\n for (const candidate of buildResolutionCandidates(\n getModuleFile(module),\n )) {\n survivingModules.add(candidate)\n }\n }\n\n const didModuleSurvive = (id: string): boolean =>\n buildResolutionCandidates(id).some((candidate) =>\n survivingModules.has(candidate),\n )\n\n for (const module of relevantModules) {\n const payload = getMockEdgePayloadFromFile(getModuleFile(module))\n if (!payload) {\n continue\n }\n if (\n !shouldCheckImportProtectionImporter(\n config,\n payload.violation.importer,\n )\n ) {\n continue\n }\n\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: payload.violation.importer,\n source: payload.violation.specifier,\n resolved: payload.violation.resolved,\n type: 'specifier',\n pattern: payload.violation.patternText,\n preferOriginalCode: true,\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n }\n\n for (const edge of edges) {\n if (!edge.specifier) {\n continue\n }\n if (!shouldCheckImportProtectionImporter(config, edge.importer)) {\n continue\n }\n\n const relativeResolved = getImportProtectionRelativePath(\n config.root,\n edge.resolved,\n )\n if (isFileExcluded(relativeResolved, matchers)) {\n continue\n }\n const fileMatch = checkFileDenial(relativeResolved, matchers)\n if (fileMatch) {\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: edge.importer,\n source: edge.specifier,\n resolved: edge.resolved,\n type: 'file',\n pattern: fileMatch.pattern,\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n continue\n }\n\n const markerKind = await getMarkerKindForFile({\n config,\n provider,\n loadOriginalCode: loadOriginalCodeFromCompilation,\n markerKindCache,\n file: edge.resolved,\n })\n const violatesMarker =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n\n if (!violatesMarker) {\n continue\n }\n\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: edge.importer,\n source: edge.specifier,\n resolved: edge.resolved,\n type: 'marker',\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n }\n\n for (const violation of envState.deferredFileViolations) {\n const liveEdgeKey = `${normalizeFilePath(violation.importer)}::${violation.specifier}::${normalizeFilePath(violation.resolved)}`\n if (liveFileEdgeKeys.has(liveEdgeKey)) {\n continue\n }\n\n if (!didModuleSurvive(violation.resolved)) {\n continue\n }\n\n if (!didModuleSurvive(violation.importer)) {\n continue\n }\n\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: violation.importer,\n source: violation.specifier,\n resolved: violation.resolved,\n type: 'file',\n pattern: violation.pattern,\n preferOriginalCode: violation.useOriginalLocation,\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n }\n },\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"import-protection.js","names":[],"sources":["../../../src/rsbuild/import-protection.ts"],"sourcesContent":["import { extname, resolve as resolvePath } from 'node:path'\n\nimport {\n getDefaultImportProtectionRules,\n getMarkerSpecifiers,\n} from '../import-protection/defaults'\nimport { normalizePath } from '../utils'\nimport { ExtensionlessAbsoluteIdResolver } from '../import-protection/extensionlessAbsoluteIdResolver'\nimport { compileMatchers, matchesAny } from '../import-protection/matchers'\nimport {\n getImportProtectionEnvType,\n getImportProtectionRelativePath,\n getImportProtectionRulesForEnvironment,\n shouldCheckImportProtectionImporter,\n} from '../import-protection/adapterUtils'\nimport {\n findOriginalUnsafeUsagePosFromResult,\n getImportSources,\n getMockExportNamesBySource,\n getNamedExports,\n} from '../import-protection/analysis'\nimport { rewriteDeniedImports } from '../import-protection/rewrite'\nimport {\n ImportLocCache,\n addTraceImportLocations,\n buildCodeSnippet,\n buildLineIndex,\n createImportSpecifierLocationIndex,\n findImportStatementLocationFromTransformed,\n findOriginalUsageLocation,\n findPostCompileUsageLocation,\n getOrCreateOriginalTransformResult,\n indexToLineColumn,\n normalizeSourceMap,\n pickOriginalCodeFromSourcesContent,\n} from '../import-protection/sourceLocation'\nimport {\n ImportGraph,\n buildTrace,\n formatViolation,\n} from '../import-protection/trace'\nimport {\n generateDevSelfDenialModule,\n generateSelfContainedMockModule,\n loadMockEdgeModule,\n loadMockRuntimeModule,\n loadSilentMockModule,\n} from '../import-protection/virtualModules'\nimport {\n buildResolutionCandidates,\n buildSourceCandidates,\n canonicalizeResolvedId,\n checkFileDenial,\n clearNormalizeFilePathCache,\n dedupePatterns,\n dedupeViolationKey,\n isFileExcluded,\n normalizeFilePath,\n} from '../import-protection/utils'\n\nimport type {\n ImportProtectionBehavior,\n ImportProtectionOptions,\n} from '../schema'\nimport type { CompiledMatcher } from '../import-protection/matchers'\nimport type {\n SourceMapLike,\n TransformResult,\n TransformResultProvider,\n} from '../import-protection/sourceLocation'\nimport type { Loc, TraceStep, ViolationInfo } from '../import-protection/trace'\nimport type { CompileStartFrameworkOptions, GetConfigFn } from '../types'\nimport type {\n RsbuildPluginAPI,\n Rspack,\n rspack as rspackNamespaceType,\n} from '@rsbuild/core'\n\ntype RspackNamespace = typeof rspackNamespaceType\ntype RspackVirtualModulesPlugin = InstanceType<\n RspackNamespace['experiments']['VirtualModulesPlugin']\n>\ntype ProcessAssetsContext = Parameters<\n Parameters<RsbuildPluginAPI['processAssets']>[1]\n>[0]\ntype TransformContext = Parameters<\n Parameters<RsbuildPluginAPI['transform']>[1]\n>[0]\ntype RspackCompilation = Rspack.Compilation\ntype RspackModule = Rspack.Module\ntype RspackModuleGraphConnection = {\n module?: RspackModule | null\n dependency?: unknown\n getActiveState?: (runtime: string | Array<string> | undefined) => unknown\n}\ntype OriginalCodeLoader = (file: string) => Promise<string | undefined>\nconst importSpecifierLocationIndex = createImportSpecifierLocationIndex()\n\ninterface EnvRules {\n specifiers: Array<CompiledMatcher>\n files: Array<CompiledMatcher>\n excludeFiles: Array<CompiledMatcher>\n}\n\ninterface PluginConfig {\n enabled: boolean\n root: string\n command: 'build' | 'serve'\n srcDirectory: string\n framework: CompileStartFrameworkOptions\n effectiveBehavior: ImportProtectionBehavior\n mockAccess: 'error' | 'warn' | 'off'\n logMode: 'once' | 'always'\n maxTraceDepth: number\n compiledRules: {\n client: EnvRules\n server: EnvRules\n }\n includeMatchers: Array<CompiledMatcher>\n excludeMatchers: Array<CompiledMatcher>\n ignoreImporterMatchers: Array<CompiledMatcher>\n markerSpecifiers: {\n serverOnly: Set<string>\n clientOnly: Set<string>\n }\n envTypeMap: Map<string, 'client' | 'server'>\n onViolation?: (\n info: ViolationInfo,\n ) => boolean | void | Promise<boolean | void>\n}\n\ninterface EnvRuntimeState {\n resolveCache: Map<string, string | null>\n seenViolations: Set<string>\n buildTransformResults: Map<string, TransformResult>\n deferredFileViolations: Array<DeferredFileViolation>\n deferredFileViolationKeys: Set<string>\n}\n\ninterface DeferredFileViolation {\n importer: string\n specifier: string\n resolved: string\n relativeResolved: string\n pattern: string | RegExp\n useOriginalLocation: boolean\n}\n\ninterface SharedState {\n root: string\n virtualModules: Map<string, string>\n vmPlugins: Record<string, RspackVirtualModulesPlugin>\n readyVmPlugins: Record<string, boolean>\n inputFileSystems: Record<string, Rspack.Compiler['inputFileSystem']>\n pendingWrites: Map<string, Map<string, string>>\n}\n\ninterface CompilationEdge {\n importer: string\n specifier?: string\n resolved: string\n}\n\ninterface MockEdgePayload {\n exports: Array<string>\n runtimeId: string\n violation: {\n env: string\n envType: 'client' | 'server'\n importer: string\n specifier: string\n resolved?: string\n patternText: string\n }\n}\n\nconst IMPORT_PROTECTION_VIRTUAL_DIR = 'node_modules/.virtual/import-protection'\nconst MOCK_EDGE_FILE_PREFIX = 'mock-edge-'\nconst MOCK_RUNTIME_FILE_PREFIX = 'mock-runtime-'\nconst MOCK_SILENT_FILE = 'mock-silent.mjs'\n\nfunction toBase64Url(input: unknown): string {\n return Buffer.from(JSON.stringify(input), 'utf8').toString('base64url')\n}\n\nfunction fromBase64Url<T>(input: string): T {\n return JSON.parse(Buffer.from(input, 'base64url').toString('utf8')) as T\n}\n\nfunction getRulesForEnvironment(\n config: PluginConfig,\n envName: string,\n): EnvRules {\n return getImportProtectionRulesForEnvironment(config, envName) as EnvRules\n}\n\nfunction serializePattern(pattern: string | RegExp): string {\n return typeof pattern === 'string' ? pattern : pattern.toString()\n}\n\nfunction dedupeKey(info: ViolationInfo): string {\n return dedupeViolationKey(info)\n}\n\nfunction getOrCreateEnvState(\n envStates: Map<string, EnvRuntimeState>,\n envName: string,\n): EnvRuntimeState {\n let env = envStates.get(envName)\n\n if (!env) {\n env = {\n resolveCache: new Map(),\n seenViolations: new Set(),\n buildTransformResults: new Map(),\n deferredFileViolations: [],\n deferredFileViolationKeys: new Set(),\n }\n envStates.set(envName, env)\n }\n\n return env\n}\n\nfunction getVirtualModulePath(\n root: string,\n envName: string,\n filename: string,\n): string {\n return normalizePath(\n resolvePath(root, IMPORT_PROTECTION_VIRTUAL_DIR, envName, filename),\n )\n}\n\nfunction queuePendingWrite(\n shared: SharedState,\n envName: string,\n filePath: string,\n code: string,\n): void {\n let writes = shared.pendingWrites.get(envName)\n if (!writes) {\n writes = new Map()\n shared.pendingWrites.set(envName, writes)\n }\n\n writes.set(filePath, code)\n}\n\nfunction tryWriteVirtualModule(\n shared: SharedState,\n envName: string,\n filePath: string,\n code: string,\n): string {\n const current = shared.virtualModules.get(filePath)\n if (current === code) {\n return filePath\n }\n\n shared.virtualModules.set(filePath, code)\n\n const vmPlugin = shared.vmPlugins[envName]\n if (!vmPlugin || !shared.readyVmPlugins[envName]) {\n queuePendingWrite(shared, envName, filePath, code)\n return filePath\n }\n\n vmPlugin.writeModule(filePath, code)\n return filePath\n}\n\nfunction flushPendingWrites(shared: SharedState, envName: string): void {\n const writes = shared.pendingWrites.get(envName)\n if (!writes?.size || !shared.readyVmPlugins[envName]) {\n return\n }\n\n for (const [filePath, code] of writes) {\n shared.vmPlugins[envName]?.writeModule(filePath, code)\n writes.delete(filePath)\n }\n\n if (writes.size === 0) {\n shared.pendingWrites.delete(envName)\n }\n}\n\nfunction ensureSilentMockModule(shared: SharedState, envName: string): string {\n return tryWriteVirtualModule(\n shared,\n envName,\n getVirtualModulePath(shared.root, envName, MOCK_SILENT_FILE),\n loadSilentMockModule().code,\n )\n}\n\nfunction ensureRuntimeMockModule(opts: {\n shared: SharedState\n envName: string\n mode: 'error' | 'warn' | 'off'\n env: string\n importer: string\n specifier: string\n}): string {\n const encoded = toBase64Url({\n mode: opts.mode,\n env: opts.env,\n importer: opts.importer,\n specifier: opts.specifier,\n trace: [],\n })\n\n return tryWriteVirtualModule(\n opts.shared,\n opts.envName,\n getVirtualModulePath(\n opts.shared.root,\n opts.envName,\n `${MOCK_RUNTIME_FILE_PREFIX}${encoded}.mjs`,\n ),\n loadMockRuntimeModule(encoded).code,\n )\n}\n\nfunction ensureMockEdgeModule(opts: {\n shared: SharedState\n envName: string\n payload: MockEdgePayload\n}): string {\n const encoded = toBase64Url(opts.payload)\n\n return tryWriteVirtualModule(\n opts.shared,\n opts.envName,\n getVirtualModulePath(\n opts.shared.root,\n opts.envName,\n `${MOCK_EDGE_FILE_PREFIX}${encoded}.mjs`,\n ),\n loadMockEdgeModule(encoded).code,\n )\n}\n\nfunction getMockEdgePayloadFromFile(\n filePath: string,\n): MockEdgePayload | undefined {\n const match = /(?:^|[\\\\/])mock-edge-([^/\\\\]+)\\.mjs$/.exec(filePath)\n if (!match) {\n return undefined\n }\n\n try {\n return fromBase64Url<MockEdgePayload>(match[1]!)\n } catch {\n return undefined\n }\n}\n\nasync function loadOriginalCode(\n cache: Map<string, Promise<string | undefined>>,\n file: string,\n loader: OriginalCodeLoader,\n): Promise<string | undefined> {\n let result = cache.get(file)\n if (!result) {\n result = loader(file)\n cache.set(file, result)\n }\n\n return result\n}\n\nasync function loadOriginalCodeFromInputFileSystem(\n inputFileSystem: NonNullable<RspackCompilation['inputFileSystem']>,\n file: string,\n): Promise<string | undefined> {\n return new Promise((resolve) => {\n inputFileSystem.readFile(file, (error, data) => {\n if (error || data == null) {\n resolve(undefined)\n return\n }\n\n resolve(typeof data === 'string' ? data : data.toString('utf8'))\n })\n })\n}\n\nasync function resolveAgainstImporter(opts: {\n envState: EnvRuntimeState\n config: PluginConfig\n ctx: TransformContext\n importerId: string\n source: string\n extensionlessResolver: ExtensionlessAbsoluteIdResolver\n}): Promise<string | null> {\n const normalizedImporter = normalizeFilePath(opts.importerId)\n const cacheKey = `${normalizedImporter}:${opts.source}`\n\n if (opts.envState.resolveCache.has(cacheKey)) {\n return opts.envState.resolveCache.get(cacheKey) ?? null\n }\n\n const importerDir =\n opts.ctx.context ?? opts.importerId.replace(/[/\\\\][^/\\\\]*$/, '')\n\n const resolved = await new Promise<string | null>((resolve, reject) => {\n opts.ctx.resolve(importerDir, opts.source, (error, result) => {\n if (error) {\n reject(error)\n return\n }\n\n resolve(typeof result === 'string' ? result : null)\n })\n }).catch(() => null)\n\n if (!resolved) {\n opts.envState.resolveCache.set(cacheKey, null)\n return null\n }\n\n const canonical = canonicalizeResolvedId(\n resolved,\n opts.config.root,\n (value) => opts.extensionlessResolver.resolve(value),\n )\n\n opts.envState.resolveCache.set(cacheKey, canonical)\n return canonical\n}\n\nfunction getModuleResource(module: RspackModule): string | undefined {\n const candidate = module as RspackModule & {\n nameForCondition?: () => string | undefined\n resourceResolveData?: { resource?: string }\n resource?: string\n userRequest?: string\n request?: string\n }\n\n return (\n candidate.nameForCondition() ??\n candidate.resourceResolveData?.resource ??\n candidate.resource ??\n candidate.userRequest ??\n candidate.request\n )\n}\n\nfunction getModuleFile(module: RspackModule): string {\n return normalizeFilePath(getModuleResource(module) ?? module.identifier())\n}\n\nconst IMPORT_PROTECTION_PARSEABLE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n])\n\nfunction isImportProtectionSourceFile(file: string | undefined): boolean {\n if (!file) {\n return false\n }\n\n const extension = extname(normalizeFilePath(file))\n return (\n extension.length > 0 &&\n IMPORT_PROTECTION_PARSEABLE_EXTENSIONS.has(extension)\n )\n}\n\nfunction isImportProtectionSourceModule(module: RspackModule): boolean {\n return isImportProtectionSourceFile(getModuleResource(module))\n}\n\nfunction addTransformResult(\n cache: Map<string, TransformResult>,\n key: string,\n result: TransformResult,\n): void {\n cache.set(normalizePath(key), result)\n cache.set(normalizeFilePath(key), result)\n}\n\nfunction hasTransformResult(\n cache: Map<string, TransformResult>,\n key: string,\n): boolean {\n return cache.has(normalizePath(key)) || cache.has(normalizeFilePath(key))\n}\n\nfunction deferFileViolation(\n envState: EnvRuntimeState,\n violation: DeferredFileViolation,\n): void {\n const key = `${violation.importer}:${violation.specifier}:${violation.resolved}:${String(violation.pattern)}`\n if (envState.deferredFileViolationKeys.has(key)) {\n return\n }\n\n envState.deferredFileViolationKeys.add(key)\n envState.deferredFileViolations.push(violation)\n}\n\nfunction hasOriginalUnsafeUsage(\n result: TransformResult | undefined,\n source: string,\n envType: 'client' | 'server',\n): boolean {\n if (!result) {\n return false\n }\n\n const originalResult = getOrCreateOriginalTransformResult(result)\n if (!originalResult) {\n return false\n }\n\n return !!findOriginalUnsafeUsagePosFromResult(originalResult, source, envType)\n}\n\nasync function buildTransformResultProvider(opts: {\n modules: Array<RspackModule>\n root: string\n loadOriginalCode: OriginalCodeLoader\n preloaded?: Map<string, TransformResult>\n}): Promise<TransformResultProvider> {\n const cache = new Map<string, TransformResult>()\n\n if (opts.preloaded) {\n for (const [key, result] of opts.preloaded) {\n cache.set(key, result)\n }\n }\n\n for (const module of opts.modules) {\n const source = module.originalSource()\n if (!source) continue\n\n const sourceAndMap = source.sourceAndMap()\n const code = String(sourceAndMap.source)\n const map = normalizeSourceMap(sourceAndMap.map as SourceMapLike | null)\n const file = getModuleFile(module)\n const resource = getModuleResource(module)\n\n const originalCode = map?.sourcesContent\n ? (pickOriginalCodeFromSourcesContent(map, resource ?? file, opts.root) ??\n (resource ? await opts.loadOriginalCode(resource) : undefined))\n : resource\n ? await opts.loadOriginalCode(resource)\n : undefined\n\n const result: TransformResult = {\n code,\n map,\n originalCode,\n lineIndex: buildLineIndex(code),\n }\n\n if (!hasTransformResult(cache, file)) {\n addTransformResult(cache, file, result)\n }\n\n if (resource && !hasTransformResult(cache, resource)) {\n addTransformResult(cache, resource, result)\n }\n }\n\n return {\n getTransformResult(id: string) {\n return cache.get(normalizePath(id)) ?? cache.get(normalizeFilePath(id))\n },\n }\n}\n\nfunction getConnectionRequest(dependency: unknown): string | undefined {\n const candidate = dependency as { request?: unknown }\n return typeof candidate.request === 'string' ? candidate.request : undefined\n}\n\nfunction addEntryModulesToGraph(opts: {\n compilation: RspackCompilation\n graph: ImportGraph\n}): void {\n for (const entry of opts.compilation.entries.values()) {\n for (const dependency of entry.dependencies) {\n const connection = opts.compilation.moduleGraph.getConnection(dependency)\n const module = connection?.module\n if (!module) continue\n opts.graph.addEntry(getModuleFile(module))\n }\n }\n}\n\nfunction buildCompilationGraph(opts: {\n compilation: RspackCompilation\n modules: Array<RspackModule>\n}): { graph: ImportGraph; edges: Array<CompilationEdge> } {\n const graph = new ImportGraph()\n const edges: Array<CompilationEdge> = []\n\n addEntryModulesToGraph({\n compilation: opts.compilation,\n graph,\n })\n\n for (const module of opts.modules) {\n const importer = getModuleFile(module)\n const connections =\n opts.compilation.moduleGraph.getOutgoingConnectionsInOrder(module)\n\n for (const connection of connections) {\n if (!connection.module) continue\n if (!isActiveConnection(connection)) continue\n\n const resolved = getModuleFile(connection.module)\n const specifier = getConnectionRequest(connection.dependency)\n graph.addEdge(resolved, importer, specifier)\n edges.push({ importer, specifier, resolved })\n }\n }\n\n return { graph, edges }\n}\n\nfunction isActiveConnection(connection: RspackModuleGraphConnection): boolean {\n if (typeof connection.getActiveState !== 'function') {\n return true\n }\n\n return connection.getActiveState(undefined) === true\n}\n\nfunction findImportLocationInOriginalCode(\n provider: TransformResultProvider,\n importer: string,\n source: string,\n): Loc | undefined {\n const result = provider.getTransformResult(importer)\n if (!result) {\n return undefined\n }\n\n const originalResult = getOrCreateOriginalTransformResult(result)\n if (!originalResult) {\n return undefined\n }\n\n const index = importSpecifierLocationIndex.find(originalResult, source)\n if (index === -1) {\n return undefined\n }\n\n const lineIndex =\n originalResult.lineIndex ??\n (originalResult.lineIndex = buildLineIndex(originalResult.code))\n const loc = indexToLineColumn(lineIndex, index)\n\n return {\n file: normalizeFilePath(importer),\n line: loc.line,\n column: loc.column,\n }\n}\n\nasync function resolveImporterLocation(opts: {\n provider: TransformResultProvider\n importLocCache: ImportLocCache\n importer: string\n sourceCandidates: Iterable<string>\n preferOriginalCode?: boolean\n envType?: 'client' | 'server'\n}): Promise<Loc | undefined> {\n if (opts.preferOriginalCode) {\n for (const candidate of opts.sourceCandidates) {\n const loc =\n findOriginalUsageLocation(\n opts.provider,\n opts.importer,\n candidate,\n opts.envType,\n ) ??\n findImportLocationInOriginalCode(\n opts.provider,\n opts.importer,\n candidate,\n )\n if (loc) {\n return loc\n }\n }\n }\n\n for (const candidate of opts.sourceCandidates) {\n const loc =\n (await findPostCompileUsageLocation(\n opts.provider,\n opts.importer,\n candidate,\n )) ||\n (await findImportStatementLocationFromTransformed(\n opts.provider,\n opts.importer,\n candidate,\n opts.importLocCache,\n importSpecifierLocationIndex.find,\n ))\n\n if (loc) {\n return loc\n }\n }\n\n if (!opts.preferOriginalCode) {\n for (const candidate of opts.sourceCandidates) {\n const loc = findImportLocationInOriginalCode(\n opts.provider,\n opts.importer,\n candidate,\n )\n if (loc) {\n return loc\n }\n }\n }\n\n return undefined\n}\n\nasync function rebuildAndAnnotateTrace(opts: {\n provider: TransformResultProvider\n graph: ImportGraph\n importLocCache: ImportLocCache\n importer: string\n specifier: string\n importerLoc?: Loc\n maxTraceDepth: number\n}): Promise<Array<TraceStep>> {\n const trace = buildTrace(opts.graph, opts.importer, opts.maxTraceDepth)\n\n await addTraceImportLocations(\n opts.provider,\n trace,\n opts.importLocCache,\n importSpecifierLocationIndex.find,\n )\n\n if (trace.length > 0) {\n const last = trace[trace.length - 1]!\n if (!last.specifier) {\n last.specifier = opts.specifier\n }\n if (opts.importerLoc && last.line == null) {\n last.line = opts.importerLoc.line\n last.column = opts.importerLoc.column\n }\n }\n\n return trace\n}\n\nasync function buildViolationInfo(opts: {\n config: PluginConfig\n provider: TransformResultProvider\n graph: ImportGraph\n importLocCache: ImportLocCache\n envName: string\n envType: 'client' | 'server'\n importer: string\n source: string\n resolved?: string\n type: 'specifier' | 'file' | 'marker'\n pattern?: string | RegExp\n preferOriginalCode?: boolean\n}): Promise<ViolationInfo> {\n const importerLoc = await resolveImporterLocation({\n provider: opts.provider,\n importLocCache: opts.importLocCache,\n importer: opts.importer,\n sourceCandidates: buildSourceCandidates(\n opts.source,\n opts.resolved,\n opts.config.root,\n ),\n preferOriginalCode: opts.preferOriginalCode,\n envType: opts.envType,\n })\n\n const trace = await rebuildAndAnnotateTrace({\n provider: opts.provider,\n graph: opts.graph,\n importLocCache: opts.importLocCache,\n importer: opts.importer,\n specifier: opts.source,\n importerLoc,\n maxTraceDepth: opts.config.maxTraceDepth,\n })\n\n const snippet = importerLoc\n ? buildCodeSnippet(opts.provider, opts.importer, importerLoc)\n : undefined\n\n return {\n env: opts.envName,\n envType: opts.envType,\n behavior: opts.config.effectiveBehavior,\n type: opts.type,\n pattern: opts.pattern,\n specifier: opts.source,\n importer: opts.importer,\n ...(opts.resolved ? { resolved: opts.resolved } : {}),\n ...(importerLoc ? { importerLoc } : {}),\n trace,\n snippet,\n }\n}\n\nasync function getMarkerKindForFile(opts: {\n config: PluginConfig\n provider: TransformResultProvider\n loadOriginalCode: OriginalCodeLoader\n markerKindCache: Map<string, Promise<'server' | 'client' | undefined>>\n file: string\n}): Promise<'server' | 'client' | undefined> {\n if (!isImportProtectionSourceFile(opts.file)) {\n return undefined\n }\n\n let cached = opts.markerKindCache.get(opts.file)\n if (!cached) {\n cached = (async () => {\n const code =\n opts.provider.getTransformResult(opts.file)?.originalCode ??\n (await opts.loadOriginalCode(opts.file))\n\n if (!code) {\n return undefined\n }\n\n const imports = getImportSources(code)\n const hasServerOnly = imports.some((source) =>\n opts.config.markerSpecifiers.serverOnly.has(source),\n )\n const hasClientOnly = imports.some((source) =>\n opts.config.markerSpecifiers.clientOnly.has(source),\n )\n\n if (hasServerOnly && !hasClientOnly) {\n return 'server'\n }\n\n if (hasClientOnly && !hasServerOnly) {\n return 'client'\n }\n\n return undefined\n })()\n opts.markerKindCache.set(opts.file, cached)\n }\n\n return cached\n}\n\nasync function reportViolation(opts: {\n config: PluginConfig\n envState: EnvRuntimeState\n compilation: RspackCompilation\n rspack: RspackNamespace\n info: ViolationInfo\n}): Promise<void> {\n const key = dedupeKey(opts.info)\n if (\n opts.config.logMode !== 'always' &&\n opts.envState.seenViolations.has(key)\n ) {\n return\n }\n\n opts.envState.seenViolations.add(key)\n\n if (opts.config.onViolation) {\n const result = await opts.config.onViolation(opts.info)\n if (result === false) {\n return\n }\n }\n\n const message = formatViolation(opts.info, opts.config.root)\n const error = new opts.rspack.WebpackError(message)\n\n if (opts.config.effectiveBehavior === 'error') {\n opts.compilation.errors.push(error)\n } else {\n opts.compilation.warnings.push(error)\n }\n}\n\nexport function registerImportProtection(\n api: RsbuildPluginAPI,\n opts: {\n getConfig: GetConfigFn\n framework: CompileStartFrameworkOptions\n environments: Array<{ name: string; type: 'client' | 'server' }>\n },\n): void {\n const extensionlessResolver = new ExtensionlessAbsoluteIdResolver()\n const envStates = new Map<string, EnvRuntimeState>()\n const fileReadCache = new Map<string, Promise<string | undefined>>()\n\n const config: PluginConfig = {\n enabled: true,\n root: '',\n command: api.context.action === 'dev' ? 'serve' : 'build',\n srcDirectory: '',\n framework: opts.framework,\n effectiveBehavior: 'error',\n mockAccess: 'error',\n logMode: 'once',\n maxTraceDepth: 20,\n compiledRules: {\n client: {\n specifiers: [],\n files: [],\n excludeFiles: [],\n },\n server: {\n specifiers: [],\n files: [],\n excludeFiles: [],\n },\n },\n includeMatchers: [],\n excludeMatchers: [],\n ignoreImporterMatchers: [],\n markerSpecifiers: {\n serverOnly: new Set(),\n clientOnly: new Set(),\n },\n envTypeMap: new Map(opts.environments.map((env) => [env.name, env.type])),\n onViolation: undefined,\n }\n\n const shared: SharedState = {\n root: '',\n virtualModules: new Map(),\n vmPlugins: {},\n readyVmPlugins: {},\n inputFileSystems: {},\n pendingWrites: new Map(),\n }\n\n function applyUserConfig(): void {\n const { startConfig, resolvedStartConfig } = opts.getConfig()\n\n config.root = resolvedStartConfig.root\n config.srcDirectory = resolvedStartConfig.srcDirectory\n shared.root = resolvedStartConfig.root\n\n const userOpts: ImportProtectionOptions | undefined =\n startConfig.importProtection\n\n if (userOpts?.enabled === false) {\n config.enabled = false\n return\n }\n\n config.enabled = true\n\n const behavior = userOpts?.behavior\n if (typeof behavior === 'string') {\n config.effectiveBehavior = behavior\n } else {\n config.effectiveBehavior =\n config.command === 'serve'\n ? (behavior?.dev ?? 'mock')\n : (behavior?.build ?? 'error')\n }\n\n config.logMode = userOpts?.log ?? 'once'\n config.mockAccess = userOpts?.mockAccess ?? 'error'\n config.maxTraceDepth = userOpts?.maxTraceDepth ?? 20\n config.onViolation = userOpts?.onViolation\n ? (info) => userOpts.onViolation?.(info)\n : undefined\n\n const defaults = getDefaultImportProtectionRules()\n const pick = <T>(user: Array<T> | undefined, fallback: Array<T>) =>\n user ? [...user] : [...fallback]\n\n const clientSpecifiers = dedupePatterns([\n ...defaults.client.specifiers,\n ...(userOpts?.client?.specifiers ?? []),\n ])\n\n config.compiledRules.client = {\n specifiers: compileMatchers(clientSpecifiers),\n files: compileMatchers(\n pick(userOpts?.client?.files, defaults.client.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.client?.excludeFiles, defaults.client.excludeFiles),\n ),\n }\n\n config.compiledRules.server = {\n specifiers: compileMatchers(\n dedupePatterns(\n pick(userOpts?.server?.specifiers, defaults.server.specifiers),\n ),\n ),\n files: compileMatchers(\n pick(userOpts?.server?.files, defaults.server.files),\n ),\n excludeFiles: compileMatchers(\n pick(userOpts?.server?.excludeFiles, defaults.server.excludeFiles),\n ),\n }\n\n config.includeMatchers = compileMatchers(userOpts?.include ?? [])\n config.excludeMatchers = compileMatchers(userOpts?.exclude ?? [])\n config.ignoreImporterMatchers = compileMatchers(\n userOpts?.ignoreImporters ?? [],\n )\n\n const markers = getMarkerSpecifiers()\n config.markerSpecifiers = {\n serverOnly: new Set(markers.serverOnly),\n clientOnly: new Set(markers.clientOnly),\n }\n }\n\n api.onBeforeBuild(() => {\n applyUserConfig()\n clearNormalizeFilePathCache()\n extensionlessResolver.clear()\n fileReadCache.clear()\n envStates.clear()\n })\n\n api.onBeforeDevCompile(() => {\n applyUserConfig()\n clearNormalizeFilePathCache()\n extensionlessResolver.clear()\n fileReadCache.clear()\n\n for (const envState of envStates.values()) {\n envState.resolveCache.clear()\n envState.buildTransformResults.clear()\n envState.deferredFileViolations.length = 0\n envState.deferredFileViolationKeys.clear()\n }\n })\n\n api.modifyRspackConfig((rspackConfig, utils) => {\n applyUserConfig()\n\n const envName = utils.environment.name\n const VMP = utils.rspack.experiments.VirtualModulesPlugin\n const vmPlugin = new VMP({})\n\n shared.vmPlugins[envName] = vmPlugin\n shared.readyVmPlugins[envName] = false\n\n rspackConfig.plugins.push(vmPlugin)\n rspackConfig.plugins.push({\n apply(compiler: Rspack.Compiler) {\n shared.inputFileSystems[envName] = compiler.inputFileSystem\n compiler.hooks.thisCompilation.tap(\n 'TanStackStartImportProtectionVirtualModulesReady',\n () => {\n shared.readyVmPlugins[envName] = true\n flushPendingWrites(shared, envName)\n },\n )\n },\n })\n })\n\n for (const environment of opts.environments) {\n api.transform(\n {\n test: /\\.[cm]?[tj]sx?$/,\n environments: [environment.name],\n order: 'post',\n },\n async (ctx) => {\n if (!config.enabled) {\n return ctx.code\n }\n\n const envName = environment.name\n const envType = getImportProtectionEnvType(config, envName)\n const envState = getOrCreateEnvState(envStates, envName)\n const id = ctx.resource\n const file = normalizeFilePath(ctx.resourcePath)\n\n if (!shouldCheckImportProtectionImporter(config, file)) {\n return ctx.code\n }\n\n const matchers = getRulesForEnvironment(config, envName)\n const relativeFile = getImportProtectionRelativePath(config.root, file)\n const importSources = getImportSources(ctx.code)\n const transformedImportSources = new Set(importSources)\n const transformInputFileSystem = shared.inputFileSystems[envName]\n const loadOriginalCodeForTransform: OriginalCodeLoader =\n transformInputFileSystem\n ? (target) =>\n loadOriginalCodeFromInputFileSystem(\n transformInputFileSystem,\n target,\n )\n : () => Promise.resolve(undefined)\n const originalCode =\n config.command === 'build'\n ? await loadOriginalCode(\n fileReadCache,\n file,\n loadOriginalCodeForTransform,\n )\n : undefined\n const buildImportSources = originalCode\n ? getImportSources(originalCode)\n : []\n const buildTransformResult: TransformResult | undefined =\n config.command === 'build'\n ? {\n code: ctx.code,\n map: undefined,\n originalCode,\n lineIndex: buildLineIndex(ctx.code),\n }\n : undefined\n\n if (config.command === 'build') {\n const relativeBuildFile = getImportProtectionRelativePath(\n config.root,\n file,\n )\n addTransformResult(\n envState.buildTransformResults,\n file,\n buildTransformResult!,\n )\n addTransformResult(\n envState.buildTransformResults,\n relativeBuildFile,\n buildTransformResult!,\n )\n if (id !== file) {\n addTransformResult(\n envState.buildTransformResults,\n id,\n buildTransformResult!,\n )\n }\n }\n\n const hasServerOnlyMarker = importSources.some((source) =>\n config.markerSpecifiers.serverOnly.has(source),\n )\n const hasClientOnlyMarker = importSources.some((source) =>\n config.markerSpecifiers.clientOnly.has(source),\n )\n\n if (hasServerOnlyMarker && hasClientOnlyMarker) {\n throw new Error(\n `[import-protection] File \"${relativeFile}\" has both server-only and client-only markers. This is not allowed.`,\n )\n }\n\n const markerKind = hasServerOnlyMarker\n ? ('server' as const)\n : hasClientOnlyMarker\n ? ('client' as const)\n : undefined\n\n const fileMatch = checkFileDenial(relativeFile, matchers)\n const markerViolation =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n\n if (fileMatch || markerViolation) {\n let exportNames: Array<string> = []\n\n try {\n exportNames = getNamedExports(ctx.code)\n } catch {\n exportNames = []\n }\n\n if (config.command === 'build') {\n return generateSelfContainedMockModule(exportNames)\n }\n\n const runtimeId = ensureRuntimeMockModule({\n shared,\n envName,\n mode: config.mockAccess,\n env: envName,\n importer: file,\n specifier: relativeFile,\n })\n\n return generateDevSelfDenialModule(exportNames, runtimeId)\n }\n\n const deniedSpecifierReplacements = new Map<string, string>()\n const exportsBySource = (() => {\n try {\n return getMockExportNamesBySource(ctx.code)\n } catch {\n return new Map<string, Array<string>>()\n }\n })()\n\n for (const source of importSources) {\n const specifierMatch = matchesAny(source, matchers.specifiers)\n if (!specifierMatch && config.command === 'build') {\n const resolved = await resolveAgainstImporter({\n envState,\n config,\n ctx,\n importerId: id,\n source,\n extensionlessResolver,\n })\n\n if (resolved) {\n const relativeResolved = getImportProtectionRelativePath(\n config.root,\n resolved,\n )\n const buildFileMatch = checkFileDenial(relativeResolved, matchers)\n if (\n buildFileMatch &&\n hasOriginalUnsafeUsage(buildTransformResult, source, envType)\n ) {\n deferFileViolation(envState, {\n importer: file,\n specifier: source,\n resolved,\n relativeResolved,\n pattern: buildFileMatch.pattern,\n useOriginalLocation: true,\n })\n }\n }\n\n continue\n }\n\n if (!specifierMatch) {\n continue\n }\n\n const resolved = await resolveAgainstImporter({\n envState,\n config,\n ctx,\n importerId: id,\n source,\n extensionlessResolver,\n })\n\n const runtimeId =\n config.command === 'build'\n ? ensureSilentMockModule(shared, envName)\n : ensureRuntimeMockModule({\n shared,\n envName,\n mode: config.mockAccess,\n env: envName,\n importer: file,\n specifier: source,\n })\n\n const replacement = ensureMockEdgeModule({\n shared,\n envName,\n payload: {\n exports: exportsBySource.get(source) ?? [],\n runtimeId,\n violation: {\n env: envName,\n envType,\n importer: file,\n specifier: source,\n ...(resolved ? { resolved } : {}),\n patternText: serializePattern(specifierMatch.pattern),\n },\n },\n })\n\n deniedSpecifierReplacements.set(source, replacement)\n }\n\n if (config.command === 'build') {\n for (const source of buildImportSources) {\n if (transformedImportSources.has(source)) {\n continue\n }\n\n if (matchesAny(source, matchers.specifiers)) {\n continue\n }\n\n const resolved = await resolveAgainstImporter({\n envState,\n config,\n ctx,\n importerId: id,\n source,\n extensionlessResolver,\n })\n\n if (!resolved) {\n continue\n }\n\n const relativeResolved = getImportProtectionRelativePath(\n config.root,\n resolved,\n )\n const buildFileMatch = checkFileDenial(relativeResolved, matchers)\n if (\n !buildFileMatch ||\n !hasOriginalUnsafeUsage(buildTransformResult, source, envType)\n ) {\n continue\n }\n\n deferFileViolation(envState, {\n importer: file,\n specifier: source,\n resolved,\n relativeResolved,\n pattern: buildFileMatch.pattern,\n useOriginalLocation: true,\n })\n }\n }\n\n if (deniedSpecifierReplacements.size === 0) {\n return ctx.code\n }\n\n const rewritten = rewriteDeniedImports(\n ctx.code,\n id,\n new Set(deniedSpecifierReplacements.keys()),\n (source) => deniedSpecifierReplacements.get(source) ?? source,\n )\n\n if (!rewritten) {\n return ctx.code\n }\n\n return {\n code: rewritten.code,\n map: normalizeSourceMap(rewritten.map) ?? null,\n }\n },\n )\n }\n\n api.processAssets(\n {\n stage: 'report',\n environments: opts.environments.map((environment) => environment.name),\n },\n async (context: ProcessAssetsContext) => {\n if (!config.enabled) {\n return\n }\n\n const envName = context.environment.name\n const envType = getImportProtectionEnvType(config, envName)\n const envState = getOrCreateEnvState(envStates, envName)\n const matchers = getRulesForEnvironment(config, envName)\n const processFileReadCache = new Map<\n string,\n Promise<string | undefined>\n >()\n const loadOriginalCodeFromCompilation: OriginalCodeLoader = (file) =>\n loadOriginalCode(\n processFileReadCache,\n file,\n context.compilation.inputFileSystem\n ? (target) =>\n loadOriginalCodeFromInputFileSystem(\n context.compilation.inputFileSystem!,\n target,\n )\n : () => Promise.resolve(undefined),\n )\n const allModules = Array.from(context.compilation.modules)\n const relevantModules = allModules.filter(isImportProtectionSourceModule)\n\n const provider = await buildTransformResultProvider({\n modules: relevantModules,\n root: config.root,\n loadOriginalCode: loadOriginalCodeFromCompilation,\n preloaded: envState.buildTransformResults,\n })\n const importLocCache = new ImportLocCache()\n const markerKindCache = new Map<\n string,\n Promise<'server' | 'client' | undefined>\n >()\n const { graph, edges } = buildCompilationGraph({\n compilation: context.compilation,\n modules: relevantModules,\n })\n const liveFileEdgeKeys = new Set(\n edges\n .filter((edge) => !!edge.specifier)\n .map(\n (edge) =>\n `${normalizeFilePath(edge.importer)}::${edge.specifier!}::${normalizeFilePath(edge.resolved)}`,\n ),\n )\n const survivingModules = new Set<string>()\n for (const module of relevantModules) {\n for (const candidate of buildResolutionCandidates(\n getModuleFile(module),\n )) {\n survivingModules.add(candidate)\n }\n }\n\n const didModuleSurvive = (id: string): boolean =>\n buildResolutionCandidates(id).some((candidate) =>\n survivingModules.has(candidate),\n )\n\n for (const module of relevantModules) {\n const payload = getMockEdgePayloadFromFile(getModuleFile(module))\n if (!payload) {\n continue\n }\n if (\n !shouldCheckImportProtectionImporter(\n config,\n payload.violation.importer,\n )\n ) {\n continue\n }\n\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: payload.violation.importer,\n source: payload.violation.specifier,\n resolved: payload.violation.resolved,\n type: 'specifier',\n pattern: payload.violation.patternText,\n preferOriginalCode: true,\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n }\n\n for (const edge of edges) {\n if (!edge.specifier) {\n continue\n }\n if (!shouldCheckImportProtectionImporter(config, edge.importer)) {\n continue\n }\n\n const relativeResolved = getImportProtectionRelativePath(\n config.root,\n edge.resolved,\n )\n if (isFileExcluded(relativeResolved, matchers)) {\n continue\n }\n const fileMatch = checkFileDenial(relativeResolved, matchers)\n if (fileMatch) {\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: edge.importer,\n source: edge.specifier,\n resolved: edge.resolved,\n type: 'file',\n pattern: fileMatch.pattern,\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n continue\n }\n\n const markerKind = await getMarkerKindForFile({\n config,\n provider,\n loadOriginalCode: loadOriginalCodeFromCompilation,\n markerKindCache,\n file: edge.resolved,\n })\n const violatesMarker =\n (envType === 'client' && markerKind === 'server') ||\n (envType === 'server' && markerKind === 'client')\n\n if (!violatesMarker) {\n continue\n }\n\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: edge.importer,\n source: edge.specifier,\n resolved: edge.resolved,\n type: 'marker',\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n }\n\n for (const violation of envState.deferredFileViolations) {\n const liveEdgeKey = `${normalizeFilePath(violation.importer)}::${violation.specifier}::${normalizeFilePath(violation.resolved)}`\n if (liveFileEdgeKeys.has(liveEdgeKey)) {\n continue\n }\n\n if (!didModuleSurvive(violation.resolved)) {\n continue\n }\n\n if (!didModuleSurvive(violation.importer)) {\n continue\n }\n\n const info = await buildViolationInfo({\n config,\n provider,\n graph,\n importLocCache,\n envName,\n envType,\n importer: violation.importer,\n source: violation.specifier,\n resolved: violation.resolved,\n type: 'file',\n pattern: violation.pattern,\n preferOriginalCode: violation.useOriginalLocation,\n })\n\n await reportViolation({\n config,\n envState,\n compilation: context.compilation,\n rspack: context.compiler.rspack,\n info,\n })\n }\n },\n )\n}\n"],"mappings":"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"}
|
|
@@ -149,13 +149,13 @@ function createChunkCssAssetCollector(options) {
|
|
|
149
149
|
stateByChunk.set(chunk, VISITING_CHUNK);
|
|
150
150
|
const assets = [];
|
|
151
151
|
const seenAssets = /* @__PURE__ */ new Set();
|
|
152
|
-
for (const cssFile of chunk.css) appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile));
|
|
153
152
|
for (let i = 0; i < chunk.imports.length; i++) {
|
|
154
153
|
const importedChunk = options.chunksByFileName.get(chunk.imports[i]);
|
|
155
154
|
if (!importedChunk) continue;
|
|
156
155
|
const importedAssets = getChunkCssAssets(importedChunk);
|
|
157
156
|
for (let j = 0; j < importedAssets.length; j++) appendAsset(assets, seenAssets, importedAssets[j]);
|
|
158
157
|
}
|
|
158
|
+
for (const cssFile of chunk.css) appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile));
|
|
159
159
|
stateByChunk.delete(chunk);
|
|
160
160
|
assetsByChunk.set(chunk, assets);
|
|
161
161
|
return assets;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestBuilder.js","names":[],"sources":["../../../src/start-manifest-plugin/manifestBuilder.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/prefer-for-of */\nimport { serialize } from 'seroval'\nimport { joinURL } from 'ufo'\nimport { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'\nimport {\n getRouteFilePathsFromModuleIds,\n normalizeViteClientBuild,\n normalizeViteClientChunk,\n} from '../vite/start-manifest-plugin/normalized-client-build'\nimport type { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core'\nimport type { NormalizedClientBuild, NormalizedClientChunk } from '../types'\n\nconst VISITING_CHUNK = 1\n\ntype RouteTreeRoute = {\n filePath?: string\n preloads?: Array<string>\n assets?: Array<RouterManagedTag>\n children?: Array<string>\n}\n\ntype RouteTreeRoutes = Record<string, RouteTreeRoute>\n\ninterface ScannedClientChunks {\n entryChunk: NormalizedClientChunk\n chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>\n routeChunksByFilePath: ReadonlyMap<string, Array<NormalizedClientChunk>>\n}\n\ninterface ManifestAssetResolvers {\n getAssetPath: (fileName: string) => string\n getChunkPreloads: (chunk: NormalizedClientChunk) => Array<string>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}\n\ntype DedupeRoute = {\n preloads?: Array<ManifestAssetLink>\n assets?: Array<RouterManagedTag>\n children?: Array<string>\n}\n\nexport interface StartManifest {\n routes: Record<string, RouteTreeRoute>\n clientEntry: string\n}\n\nexport function appendUniqueStrings(\n target: Array<string> | undefined,\n source: Array<string>,\n) {\n // Similar to Set.prototype.union, but for ordered arrays.\n // It preserves first-seen order and returns the original target array when\n // source contributes no new values, which avoids extra allocations.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target)\n let result: Array<string> | undefined\n\n for (const value of source) {\n if (seen.has(value)) {\n continue\n }\n\n seen.add(value)\n if (!result) {\n result = target.slice()\n }\n result.push(value)\n }\n\n return result ?? target\n}\n\nexport function appendUniqueAssets(\n target: Array<RouterManagedTag> | undefined,\n source: Array<RouterManagedTag>,\n) {\n // Same semantics as appendUniqueStrings, but uniqueness is based on the\n // serialized asset identity instead of object reference.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target.map(getAssetIdentity))\n let result: Array<RouterManagedTag> | undefined\n\n for (const asset of source) {\n const identity = getAssetIdentity(asset)\n if (seen.has(identity)) {\n continue\n }\n\n seen.add(identity)\n if (!result) {\n result = target.slice()\n }\n result.push(asset)\n }\n\n return result ?? target\n}\n\nfunction getAssetIdentity(asset: RouterManagedTag) {\n return JSON.stringify({\n tag: asset.tag,\n attrs: normalizeAssetAttrs(asset.attrs),\n children: 'children' in asset ? (asset.children ?? null) : null,\n })\n}\n\nfunction normalizeAssetAttrs(attrs: Record<string, any> | undefined) {\n if (!attrs) {\n return null\n }\n\n const entries = Object.entries(attrs)\n if (entries.length === 0) {\n return null\n }\n\n entries.sort(([left], [right]) => left.localeCompare(right))\n return Object.fromEntries(entries)\n}\n\nfunction mergeRouteChunkData(options: {\n route: RouteTreeRoute\n chunk: NormalizedClientChunk\n getChunkCssAssets: (chunk: NormalizedClientChunk) => Array<RouterManagedTag>\n getChunkPreloads: (chunk: NormalizedClientChunk) => Array<string>\n}) {\n const chunkAssets = options.getChunkCssAssets(options.chunk)\n const chunkPreloads = options.getChunkPreloads(options.chunk)\n\n options.route.assets = appendUniqueAssets(options.route.assets, chunkAssets)\n options.route.preloads = appendUniqueStrings(\n options.route.preloads,\n chunkPreloads,\n )\n}\n\nexport function buildStartManifest(options: {\n clientBuild: NormalizedClientBuild\n routeTreeRoutes: RouteTreeRoutes\n basePath: string\n additionalRouteAssets?: Partial<\n Record<string, ReadonlyArray<RouterManagedTag>>\n >\n}): StartManifest {\n const scannedChunks = scanClientChunks(options.clientBuild)\n const assetResolvers = createManifestAssetResolvers(options.basePath)\n\n const routes = buildRouteManifestRoutes({\n routeTreeRoutes: options.routeTreeRoutes,\n routeChunksByFilePath: scannedChunks.routeChunksByFilePath,\n chunksByFileName: scannedChunks.chunksByFileName,\n entryChunk: scannedChunks.entryChunk,\n assetResolvers,\n additionalRouteAssets: options.additionalRouteAssets,\n })\n\n dedupeNestedRouteManifestEntries(rootRouteId, routes[rootRouteId]!, routes)\n\n // Prune routes with no assets or preloads from the manifest\n for (const routeId of Object.keys(routes)) {\n const route = routes[routeId]!\n const hasAssets = route.assets && route.assets.length > 0\n const hasPreloads = route.preloads && route.preloads.length > 0\n if (!hasAssets && !hasPreloads) {\n delete routes[routeId]\n }\n }\n\n return {\n routes,\n clientEntry: assetResolvers.getAssetPath(scannedChunks.entryChunk.fileName),\n }\n}\n\nexport function serializeStartManifest(startManifest: StartManifest) {\n return serialize(startManifest)\n}\n\nexport function scanClientChunks(\n clientBuild: NormalizedClientBuild,\n): ScannedClientChunks {\n const entryChunk = clientBuild.chunksByFileName.get(\n clientBuild.entryChunkFileName,\n )\n\n if (!entryChunk) {\n throw new Error(`Missing entry chunk: ${clientBuild.entryChunkFileName}`)\n }\n\n const routeChunksByFilePath = new Map<string, Array<NormalizedClientChunk>>()\n\n for (const chunk of clientBuild.chunksByFileName.values()) {\n if (chunk.routeFilePaths.length > 0) {\n for (const routeFilePath of chunk.routeFilePaths) {\n let chunks = routeChunksByFilePath.get(routeFilePath)\n if (chunks === undefined) {\n chunks = []\n routeChunksByFilePath.set(routeFilePath, chunks)\n }\n chunks.push(chunk)\n }\n }\n }\n\n return {\n entryChunk,\n chunksByFileName: clientBuild.chunksByFileName,\n routeChunksByFilePath,\n }\n}\n\nexport function createManifestAssetResolvers(\n basePath: string,\n): ManifestAssetResolvers {\n const assetPathByFileName = new Map<string, string>()\n const stylesheetAssetByFileName = new Map<string, RouterManagedTag>()\n const preloadsByChunk = new Map<NormalizedClientChunk, Array<string>>()\n\n const getAssetPath = (fileName: string) => {\n const cachedPath = assetPathByFileName.get(fileName)\n if (cachedPath) {\n return cachedPath\n }\n\n const assetPath = joinURL(basePath, fileName)\n assetPathByFileName.set(fileName, assetPath)\n return assetPath\n }\n\n const getStylesheetAsset = (cssFile: string) => {\n const cachedAsset = stylesheetAssetByFileName.get(cssFile)\n if (cachedAsset) {\n return cachedAsset\n }\n\n const href = getAssetPath(cssFile)\n const asset = {\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href,\n type: 'text/css',\n },\n } satisfies RouterManagedTag\n\n stylesheetAssetByFileName.set(cssFile, asset)\n return asset\n }\n\n const getChunkPreloads = (chunk: NormalizedClientChunk) => {\n const cachedPreloads = preloadsByChunk.get(chunk)\n if (cachedPreloads) {\n return cachedPreloads\n }\n\n const preloads = [getAssetPath(chunk.fileName)]\n\n for (let i = 0; i < chunk.imports.length; i++) {\n preloads.push(getAssetPath(chunk.imports[i]!))\n }\n\n preloadsByChunk.set(chunk, preloads)\n return preloads\n }\n\n return {\n getAssetPath,\n getChunkPreloads,\n getStylesheetAsset,\n }\n}\n\nexport function createChunkCssAssetCollector(options: {\n chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}) {\n const assetsByChunk = new Map<\n NormalizedClientChunk,\n Array<RouterManagedTag>\n >()\n const stateByChunk = new Map<NormalizedClientChunk, number>()\n\n const appendAsset = (\n assets: Array<RouterManagedTag>,\n seenAssets: Set<RouterManagedTag>,\n asset: RouterManagedTag,\n ) => {\n if (seenAssets.has(asset)) {\n return\n }\n\n seenAssets.add(asset)\n assets.push(asset)\n }\n\n const getChunkCssAssets = (\n chunk: NormalizedClientChunk,\n ): Array<RouterManagedTag> => {\n const cachedAssets = assetsByChunk.get(chunk)\n if (cachedAssets) {\n return cachedAssets\n }\n\n if (stateByChunk.get(chunk) === VISITING_CHUNK) {\n return []\n }\n stateByChunk.set(chunk, VISITING_CHUNK)\n\n const assets: Array<RouterManagedTag> = []\n const seenAssets = new Set<RouterManagedTag>()\n\n for (const cssFile of chunk.css) {\n appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))\n }\n\n for (let i = 0; i < chunk.imports.length; i++) {\n const importedChunk = options.chunksByFileName.get(chunk.imports[i]!)\n if (!importedChunk) {\n continue\n }\n\n const importedAssets = getChunkCssAssets(importedChunk)\n for (let j = 0; j < importedAssets.length; j++) {\n appendAsset(assets, seenAssets, importedAssets[j]!)\n }\n }\n\n stateByChunk.delete(chunk)\n assetsByChunk.set(chunk, assets)\n return assets\n }\n\n return { getChunkCssAssets }\n}\n\nexport function buildRouteManifestRoutes(options: {\n routeTreeRoutes: RouteTreeRoutes\n routeChunksByFilePath: ReadonlyMap<\n string,\n ReadonlyArray<NormalizedClientChunk>\n >\n chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>\n entryChunk: NormalizedClientChunk\n assetResolvers: ManifestAssetResolvers\n additionalRouteAssets?: Partial<\n Record<string, ReadonlyArray<RouterManagedTag>>\n >\n}) {\n const routes: Record<string, RouteTreeRoute> = {}\n const getChunkCssAssets = createChunkCssAssetCollector({\n chunksByFileName: options.chunksByFileName,\n getStylesheetAsset: options.assetResolvers.getStylesheetAsset,\n }).getChunkCssAssets\n\n for (const [routeId, route] of Object.entries(options.routeTreeRoutes)) {\n if (!route.filePath) {\n if (routeId === rootRouteId) {\n routes[routeId] = route\n continue\n }\n\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n\n const chunks = options.routeChunksByFilePath.get(route.filePath)\n if (!chunks) {\n routes[routeId] = route\n continue\n }\n\n const existing = routes[routeId]\n const targetRoute = (routes[routeId] = existing ? existing : { ...route })\n\n for (const chunk of chunks) {\n mergeRouteChunkData({\n route: targetRoute,\n chunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n }\n }\n\n const rootRoute = (routes[rootRouteId] = routes[rootRouteId] || {})\n mergeRouteChunkData({\n route: rootRoute,\n chunk: options.entryChunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n\n if (options.additionalRouteAssets) {\n for (const [routeId, assets] of Object.entries(\n options.additionalRouteAssets,\n )) {\n if (!assets || assets.length === 0) {\n continue\n }\n\n if (!(routeId in options.routeTreeRoutes)) {\n throw new Error(\n `expected additionalRouteAssets routeId to exist in routeTreeRoutes: ${routeId}`,\n )\n }\n\n const route = (routes[routeId] = routes[routeId] || {})\n route.assets = appendUniqueAssets(route.assets, [...assets])\n }\n }\n\n return routes\n}\n\nexport {\n getRouteFilePathsFromModuleIds,\n normalizeViteClientBuild,\n normalizeViteClientChunk,\n}\n\nfunction dedupeNestedRouteManifestEntries(\n routeId: string,\n route: DedupeRoute,\n routesById: Record<string, DedupeRoute>,\n seenPreloads = new Set<string>(),\n seenAssets = new Set<string>(),\n) {\n let routePreloads = route.preloads\n let routeAssets = route.assets\n\n if (routePreloads && routePreloads.length > 0) {\n let dedupedPreloads: Array<ManifestAssetLink> | undefined\n\n for (let i = 0; i < routePreloads.length; i++) {\n const preload = routePreloads[i]!\n const preloadHref = resolveManifestAssetLink(preload).href\n\n if (seenPreloads.has(preloadHref)) {\n if (dedupedPreloads === undefined) {\n dedupedPreloads = routePreloads.slice(0, i)\n }\n continue\n }\n\n seenPreloads.add(preloadHref)\n\n if (dedupedPreloads) {\n dedupedPreloads.push(preload)\n }\n }\n\n if (dedupedPreloads) {\n routePreloads = dedupedPreloads\n route.preloads = dedupedPreloads\n }\n }\n\n if (routeAssets && routeAssets.length > 0) {\n let dedupedAssets: Array<RouterManagedTag> | undefined\n\n for (let i = 0; i < routeAssets.length; i++) {\n const asset = routeAssets[i]!\n const identity = getAssetIdentity(asset)\n\n if (seenAssets.has(identity)) {\n if (dedupedAssets === undefined) {\n dedupedAssets = routeAssets.slice(0, i)\n }\n continue\n }\n\n seenAssets.add(identity)\n\n if (dedupedAssets) {\n dedupedAssets.push(asset)\n }\n }\n\n if (dedupedAssets) {\n routeAssets = dedupedAssets\n route.assets = dedupedAssets\n }\n }\n\n if (route.children) {\n for (const childRouteId of route.children) {\n const childRoute = routesById[childRouteId]\n\n if (!childRoute) {\n throw new Error(\n `Route tree references child route ${childRouteId} from ${routeId}, but no route entry was found`,\n )\n }\n\n dedupeNestedRouteManifestEntries(\n childRouteId,\n childRoute,\n routesById,\n seenPreloads,\n seenAssets,\n )\n }\n }\n\n if (routePreloads) {\n for (let i = routePreloads.length - 1; i >= 0; i--) {\n seenPreloads.delete(resolveManifestAssetLink(routePreloads[i]!).href)\n }\n }\n\n if (routeAssets) {\n for (let i = routeAssets.length - 1; i >= 0; i--) {\n seenAssets.delete(getAssetIdentity(routeAssets[i]!))\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manifestBuilder.js","names":[],"sources":["../../../src/start-manifest-plugin/manifestBuilder.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/prefer-for-of */\nimport { serialize } from 'seroval'\nimport { joinURL } from 'ufo'\nimport { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'\nimport {\n getRouteFilePathsFromModuleIds,\n normalizeViteClientBuild,\n normalizeViteClientChunk,\n} from '../vite/start-manifest-plugin/normalized-client-build'\nimport type { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core'\nimport type { NormalizedClientBuild, NormalizedClientChunk } from '../types'\n\nconst VISITING_CHUNK = 1\n\ntype RouteTreeRoute = {\n filePath?: string\n preloads?: Array<string>\n assets?: Array<RouterManagedTag>\n children?: Array<string>\n}\n\ntype RouteTreeRoutes = Record<string, RouteTreeRoute>\n\ninterface ScannedClientChunks {\n entryChunk: NormalizedClientChunk\n chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>\n routeChunksByFilePath: ReadonlyMap<string, Array<NormalizedClientChunk>>\n}\n\ninterface ManifestAssetResolvers {\n getAssetPath: (fileName: string) => string\n getChunkPreloads: (chunk: NormalizedClientChunk) => Array<string>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}\n\ntype DedupeRoute = {\n preloads?: Array<ManifestAssetLink>\n assets?: Array<RouterManagedTag>\n children?: Array<string>\n}\n\nexport interface StartManifest {\n routes: Record<string, RouteTreeRoute>\n clientEntry: string\n}\n\nexport function appendUniqueStrings(\n target: Array<string> | undefined,\n source: Array<string>,\n) {\n // Similar to Set.prototype.union, but for ordered arrays.\n // It preserves first-seen order and returns the original target array when\n // source contributes no new values, which avoids extra allocations.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target)\n let result: Array<string> | undefined\n\n for (const value of source) {\n if (seen.has(value)) {\n continue\n }\n\n seen.add(value)\n if (!result) {\n result = target.slice()\n }\n result.push(value)\n }\n\n return result ?? target\n}\n\nexport function appendUniqueAssets(\n target: Array<RouterManagedTag> | undefined,\n source: Array<RouterManagedTag>,\n) {\n // Same semantics as appendUniqueStrings, but uniqueness is based on the\n // serialized asset identity instead of object reference.\n if (source.length === 0) {\n return target\n }\n\n if (!target || target.length === 0) {\n return source\n }\n\n const seen = new Set(target.map(getAssetIdentity))\n let result: Array<RouterManagedTag> | undefined\n\n for (const asset of source) {\n const identity = getAssetIdentity(asset)\n if (seen.has(identity)) {\n continue\n }\n\n seen.add(identity)\n if (!result) {\n result = target.slice()\n }\n result.push(asset)\n }\n\n return result ?? target\n}\n\nfunction getAssetIdentity(asset: RouterManagedTag) {\n return JSON.stringify({\n tag: asset.tag,\n attrs: normalizeAssetAttrs(asset.attrs),\n children: 'children' in asset ? (asset.children ?? null) : null,\n })\n}\n\nfunction normalizeAssetAttrs(attrs: Record<string, any> | undefined) {\n if (!attrs) {\n return null\n }\n\n const entries = Object.entries(attrs)\n if (entries.length === 0) {\n return null\n }\n\n entries.sort(([left], [right]) => left.localeCompare(right))\n return Object.fromEntries(entries)\n}\n\nfunction mergeRouteChunkData(options: {\n route: RouteTreeRoute\n chunk: NormalizedClientChunk\n getChunkCssAssets: (chunk: NormalizedClientChunk) => Array<RouterManagedTag>\n getChunkPreloads: (chunk: NormalizedClientChunk) => Array<string>\n}) {\n const chunkAssets = options.getChunkCssAssets(options.chunk)\n const chunkPreloads = options.getChunkPreloads(options.chunk)\n\n options.route.assets = appendUniqueAssets(options.route.assets, chunkAssets)\n options.route.preloads = appendUniqueStrings(\n options.route.preloads,\n chunkPreloads,\n )\n}\n\nexport function buildStartManifest(options: {\n clientBuild: NormalizedClientBuild\n routeTreeRoutes: RouteTreeRoutes\n basePath: string\n additionalRouteAssets?: Partial<\n Record<string, ReadonlyArray<RouterManagedTag>>\n >\n}): StartManifest {\n const scannedChunks = scanClientChunks(options.clientBuild)\n const assetResolvers = createManifestAssetResolvers(options.basePath)\n\n const routes = buildRouteManifestRoutes({\n routeTreeRoutes: options.routeTreeRoutes,\n routeChunksByFilePath: scannedChunks.routeChunksByFilePath,\n chunksByFileName: scannedChunks.chunksByFileName,\n entryChunk: scannedChunks.entryChunk,\n assetResolvers,\n additionalRouteAssets: options.additionalRouteAssets,\n })\n\n dedupeNestedRouteManifestEntries(rootRouteId, routes[rootRouteId]!, routes)\n\n // Prune routes with no assets or preloads from the manifest\n for (const routeId of Object.keys(routes)) {\n const route = routes[routeId]!\n const hasAssets = route.assets && route.assets.length > 0\n const hasPreloads = route.preloads && route.preloads.length > 0\n if (!hasAssets && !hasPreloads) {\n delete routes[routeId]\n }\n }\n\n return {\n routes,\n clientEntry: assetResolvers.getAssetPath(scannedChunks.entryChunk.fileName),\n }\n}\n\nexport function serializeStartManifest(startManifest: StartManifest) {\n return serialize(startManifest)\n}\n\nexport function scanClientChunks(\n clientBuild: NormalizedClientBuild,\n): ScannedClientChunks {\n const entryChunk = clientBuild.chunksByFileName.get(\n clientBuild.entryChunkFileName,\n )\n\n if (!entryChunk) {\n throw new Error(`Missing entry chunk: ${clientBuild.entryChunkFileName}`)\n }\n\n const routeChunksByFilePath = new Map<string, Array<NormalizedClientChunk>>()\n\n for (const chunk of clientBuild.chunksByFileName.values()) {\n if (chunk.routeFilePaths.length > 0) {\n for (const routeFilePath of chunk.routeFilePaths) {\n let chunks = routeChunksByFilePath.get(routeFilePath)\n if (chunks === undefined) {\n chunks = []\n routeChunksByFilePath.set(routeFilePath, chunks)\n }\n chunks.push(chunk)\n }\n }\n }\n\n return {\n entryChunk,\n chunksByFileName: clientBuild.chunksByFileName,\n routeChunksByFilePath,\n }\n}\n\nexport function createManifestAssetResolvers(\n basePath: string,\n): ManifestAssetResolvers {\n const assetPathByFileName = new Map<string, string>()\n const stylesheetAssetByFileName = new Map<string, RouterManagedTag>()\n const preloadsByChunk = new Map<NormalizedClientChunk, Array<string>>()\n\n const getAssetPath = (fileName: string) => {\n const cachedPath = assetPathByFileName.get(fileName)\n if (cachedPath) {\n return cachedPath\n }\n\n const assetPath = joinURL(basePath, fileName)\n assetPathByFileName.set(fileName, assetPath)\n return assetPath\n }\n\n const getStylesheetAsset = (cssFile: string) => {\n const cachedAsset = stylesheetAssetByFileName.get(cssFile)\n if (cachedAsset) {\n return cachedAsset\n }\n\n const href = getAssetPath(cssFile)\n const asset = {\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href,\n type: 'text/css',\n },\n } satisfies RouterManagedTag\n\n stylesheetAssetByFileName.set(cssFile, asset)\n return asset\n }\n\n const getChunkPreloads = (chunk: NormalizedClientChunk) => {\n const cachedPreloads = preloadsByChunk.get(chunk)\n if (cachedPreloads) {\n return cachedPreloads\n }\n\n const preloads = [getAssetPath(chunk.fileName)]\n\n for (let i = 0; i < chunk.imports.length; i++) {\n preloads.push(getAssetPath(chunk.imports[i]!))\n }\n\n preloadsByChunk.set(chunk, preloads)\n return preloads\n }\n\n return {\n getAssetPath,\n getChunkPreloads,\n getStylesheetAsset,\n }\n}\n\nexport function createChunkCssAssetCollector(options: {\n chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>\n getStylesheetAsset: (cssFile: string) => RouterManagedTag\n}) {\n const assetsByChunk = new Map<\n NormalizedClientChunk,\n Array<RouterManagedTag>\n >()\n const stateByChunk = new Map<NormalizedClientChunk, number>()\n\n const appendAsset = (\n assets: Array<RouterManagedTag>,\n seenAssets: Set<RouterManagedTag>,\n asset: RouterManagedTag,\n ) => {\n if (seenAssets.has(asset)) {\n return\n }\n\n seenAssets.add(asset)\n assets.push(asset)\n }\n\n const getChunkCssAssets = (\n chunk: NormalizedClientChunk,\n ): Array<RouterManagedTag> => {\n const cachedAssets = assetsByChunk.get(chunk)\n if (cachedAssets) {\n return cachedAssets\n }\n\n if (stateByChunk.get(chunk) === VISITING_CHUNK) {\n return []\n }\n stateByChunk.set(chunk, VISITING_CHUNK)\n\n const assets: Array<RouterManagedTag> = []\n const seenAssets = new Set<RouterManagedTag>()\n\n for (let i = 0; i < chunk.imports.length; i++) {\n const importedChunk = options.chunksByFileName.get(chunk.imports[i]!)\n if (!importedChunk) {\n continue\n }\n\n const importedAssets = getChunkCssAssets(importedChunk)\n for (let j = 0; j < importedAssets.length; j++) {\n appendAsset(assets, seenAssets, importedAssets[j]!)\n }\n }\n\n for (const cssFile of chunk.css) {\n appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))\n }\n\n stateByChunk.delete(chunk)\n assetsByChunk.set(chunk, assets)\n return assets\n }\n\n return { getChunkCssAssets }\n}\n\nexport function buildRouteManifestRoutes(options: {\n routeTreeRoutes: RouteTreeRoutes\n routeChunksByFilePath: ReadonlyMap<\n string,\n ReadonlyArray<NormalizedClientChunk>\n >\n chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>\n entryChunk: NormalizedClientChunk\n assetResolvers: ManifestAssetResolvers\n additionalRouteAssets?: Partial<\n Record<string, ReadonlyArray<RouterManagedTag>>\n >\n}) {\n const routes: Record<string, RouteTreeRoute> = {}\n const getChunkCssAssets = createChunkCssAssetCollector({\n chunksByFileName: options.chunksByFileName,\n getStylesheetAsset: options.assetResolvers.getStylesheetAsset,\n }).getChunkCssAssets\n\n for (const [routeId, route] of Object.entries(options.routeTreeRoutes)) {\n if (!route.filePath) {\n if (routeId === rootRouteId) {\n routes[routeId] = route\n continue\n }\n\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n\n const chunks = options.routeChunksByFilePath.get(route.filePath)\n if (!chunks) {\n routes[routeId] = route\n continue\n }\n\n const existing = routes[routeId]\n const targetRoute = (routes[routeId] = existing ? existing : { ...route })\n\n for (const chunk of chunks) {\n mergeRouteChunkData({\n route: targetRoute,\n chunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n }\n }\n\n const rootRoute = (routes[rootRouteId] = routes[rootRouteId] || {})\n mergeRouteChunkData({\n route: rootRoute,\n chunk: options.entryChunk,\n getChunkCssAssets,\n getChunkPreloads: options.assetResolvers.getChunkPreloads,\n })\n\n if (options.additionalRouteAssets) {\n for (const [routeId, assets] of Object.entries(\n options.additionalRouteAssets,\n )) {\n if (!assets || assets.length === 0) {\n continue\n }\n\n if (!(routeId in options.routeTreeRoutes)) {\n throw new Error(\n `expected additionalRouteAssets routeId to exist in routeTreeRoutes: ${routeId}`,\n )\n }\n\n const route = (routes[routeId] = routes[routeId] || {})\n route.assets = appendUniqueAssets(route.assets, [...assets])\n }\n }\n\n return routes\n}\n\nexport {\n getRouteFilePathsFromModuleIds,\n normalizeViteClientBuild,\n normalizeViteClientChunk,\n}\n\nfunction dedupeNestedRouteManifestEntries(\n routeId: string,\n route: DedupeRoute,\n routesById: Record<string, DedupeRoute>,\n seenPreloads = new Set<string>(),\n seenAssets = new Set<string>(),\n) {\n let routePreloads = route.preloads\n let routeAssets = route.assets\n\n if (routePreloads && routePreloads.length > 0) {\n let dedupedPreloads: Array<ManifestAssetLink> | undefined\n\n for (let i = 0; i < routePreloads.length; i++) {\n const preload = routePreloads[i]!\n const preloadHref = resolveManifestAssetLink(preload).href\n\n if (seenPreloads.has(preloadHref)) {\n if (dedupedPreloads === undefined) {\n dedupedPreloads = routePreloads.slice(0, i)\n }\n continue\n }\n\n seenPreloads.add(preloadHref)\n\n if (dedupedPreloads) {\n dedupedPreloads.push(preload)\n }\n }\n\n if (dedupedPreloads) {\n routePreloads = dedupedPreloads\n route.preloads = dedupedPreloads\n }\n }\n\n if (routeAssets && routeAssets.length > 0) {\n let dedupedAssets: Array<RouterManagedTag> | undefined\n\n for (let i = 0; i < routeAssets.length; i++) {\n const asset = routeAssets[i]!\n const identity = getAssetIdentity(asset)\n\n if (seenAssets.has(identity)) {\n if (dedupedAssets === undefined) {\n dedupedAssets = routeAssets.slice(0, i)\n }\n continue\n }\n\n seenAssets.add(identity)\n\n if (dedupedAssets) {\n dedupedAssets.push(asset)\n }\n }\n\n if (dedupedAssets) {\n routeAssets = dedupedAssets\n route.assets = dedupedAssets\n }\n }\n\n if (route.children) {\n for (const childRouteId of route.children) {\n const childRoute = routesById[childRouteId]\n\n if (!childRoute) {\n throw new Error(\n `Route tree references child route ${childRouteId} from ${routeId}, but no route entry was found`,\n )\n }\n\n dedupeNestedRouteManifestEntries(\n childRouteId,\n childRoute,\n routesById,\n seenPreloads,\n seenAssets,\n )\n }\n }\n\n if (routePreloads) {\n for (let i = routePreloads.length - 1; i >= 0; i--) {\n seenPreloads.delete(resolveManifestAssetLink(routePreloads[i]!).href)\n }\n }\n\n if (routeAssets) {\n for (let i = routeAssets.length - 1; i >= 0; i--) {\n seenAssets.delete(getAssetIdentity(routeAssets[i]!))\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/esm/utils.d.ts
CHANGED
package/dist/esm/utils.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
//#region src/utils.ts
|
|
3
|
+
var isWindows = typeof process !== "undefined" && process.platform === "win32";
|
|
4
|
+
var windowsSlashRE = /\\/g;
|
|
2
5
|
/** Read `build.rollupOptions` or `build.rolldownOptions` from a build config. */
|
|
3
6
|
function getBundlerOptions(build) {
|
|
4
7
|
return build?.rolldownOptions ?? build?.rollupOptions;
|
|
@@ -16,8 +19,11 @@ function createLogger(prefix) {
|
|
|
16
19
|
error: (...args) => console.error(label, ...args)
|
|
17
20
|
};
|
|
18
21
|
}
|
|
19
|
-
function
|
|
20
|
-
return path.replace(
|
|
22
|
+
function slash(path) {
|
|
23
|
+
return path.replace(windowsSlashRE, "/");
|
|
24
|
+
}
|
|
25
|
+
function normalizePath(id) {
|
|
26
|
+
return path.posix.normalize(isWindows ? slash(id) : id);
|
|
21
27
|
}
|
|
22
28
|
//#endregion
|
|
23
29
|
export { createLogger, getBundlerOptions, normalizePath, resolveViteId };
|
package/dist/esm/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../src/utils.ts"],"sourcesContent":["/** Read `build.rollupOptions` or `build.rolldownOptions` from a build config. */\nexport function getBundlerOptions(build: any): any {\n return build?.rolldownOptions ?? build?.rollupOptions\n}\n\nexport function resolveViteId(id: string) {\n return `\\0${id}`\n}\n\nexport function createLogger(prefix: string) {\n const label = `[${prefix}]`\n return {\n log: (...args: any) => console.log(label, ...args),\n debug: (...args: any) => console.debug(label, ...args),\n info: (...args: any) => console.info(label, ...args),\n warn: (...args: any) => console.warn(label, ...args),\n error: (...args: any) => console.error(label, ...args),\n }\n}\n\
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../src/utils.ts"],"sourcesContent":["import path from 'node:path'\n\nconst isWindows: boolean =\n typeof process !== 'undefined' && process.platform === 'win32'\nconst windowsSlashRE = /\\\\/g\n\n/** Read `build.rollupOptions` or `build.rolldownOptions` from a build config. */\nexport function getBundlerOptions(build: any): any {\n return build?.rolldownOptions ?? build?.rollupOptions\n}\n\nexport function resolveViteId(id: string) {\n return `\\0${id}`\n}\n\nexport function createLogger(prefix: string) {\n const label = `[${prefix}]`\n return {\n log: (...args: any) => console.log(label, ...args),\n debug: (...args: any) => console.debug(label, ...args),\n info: (...args: any) => console.info(label, ...args),\n warn: (...args: any) => console.warn(label, ...args),\n error: (...args: any) => console.error(label, ...args),\n }\n}\n\nfunction slash(path: string): string {\n return path.replace(windowsSlashRE, '/')\n}\n\nexport function normalizePath(id: string): string {\n return path.posix.normalize(isWindows ? slash(id) : id)\n}\n"],"mappings":";;AAEA,IAAM,YACJ,OAAO,YAAY,eAAe,QAAQ,aAAa;AACzD,IAAM,iBAAiB;;AAGvB,SAAgB,kBAAkB,OAAiB;AACjD,QAAO,OAAO,mBAAmB,OAAO;;AAG1C,SAAgB,cAAc,IAAY;AACxC,QAAO,KAAK;;AAGd,SAAgB,aAAa,QAAgB;CAC3C,MAAM,QAAQ,IAAI,OAAO;AACzB,QAAO;EACL,MAAM,GAAG,SAAc,QAAQ,IAAI,OAAO,GAAG,KAAK;EAClD,QAAQ,GAAG,SAAc,QAAQ,MAAM,OAAO,GAAG,KAAK;EACtD,OAAO,GAAG,SAAc,QAAQ,KAAK,OAAO,GAAG,KAAK;EACpD,OAAO,GAAG,SAAc,QAAQ,KAAK,OAAO,GAAG,KAAK;EACpD,QAAQ,GAAG,SAAc,QAAQ,MAAM,OAAO,GAAG,KAAK;EACvD;;AAGH,SAAS,MAAM,MAAsB;AACnC,QAAO,KAAK,QAAQ,gBAAgB,IAAI;;AAG1C,SAAgB,cAAc,IAAoB;AAChD,QAAO,KAAK,MAAM,UAAU,YAAY,MAAM,GAAG,GAAG,GAAG"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { TanStackStartVitePluginCoreOptions, ViteRscForwardSsrResolverStrategy, } from './types.js';
|
|
2
|
+
export type { TanStackStartViteInputConfig } from './schema.js';
|
|
3
|
+
export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from '../constants.js';
|
|
4
|
+
export { createVirtualModule } from './createVirtualModule.js';
|
|
5
|
+
export { tanStackStartVite } from './plugin.js';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from "../constants.js";
|
|
2
|
+
import { createVirtualModule } from "./createVirtualModule.js";
|
|
3
|
+
import { tanStackStartVite } from "./plugin.js";
|
|
4
|
+
export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES, createVirtualModule, tanStackStartVite };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.169.1",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,6 +40,18 @@
|
|
|
40
40
|
"default": "./dist/esm/utils.js"
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
|
+
"./vite": {
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./dist/esm/vite/index.d.ts",
|
|
46
|
+
"default": "./dist/esm/vite/index.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"./rsbuild": {
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/esm/rsbuild/index.d.ts",
|
|
52
|
+
"default": "./dist/esm/rsbuild/index.js"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
43
55
|
"./rsbuild/types": {
|
|
44
56
|
"import": {
|
|
45
57
|
"types": "./dist/esm/rsbuild/types.d.ts",
|
|
@@ -95,6 +107,9 @@
|
|
|
95
107
|
"peerDependenciesMeta": {
|
|
96
108
|
"@rsbuild/core": {
|
|
97
109
|
"optional": true
|
|
110
|
+
},
|
|
111
|
+
"vite": {
|
|
112
|
+
"optional": true
|
|
98
113
|
}
|
|
99
114
|
},
|
|
100
115
|
"scripts": {
|
package/src/index.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
1
|
export type { TanStackStartInputConfig } from './schema'
|
|
2
2
|
export type { TanStackStartCoreOptions } from './types'
|
|
3
|
-
export
|
|
4
|
-
TanStackStartVitePluginCoreOptions,
|
|
5
|
-
ViteRscForwardSsrResolverStrategy,
|
|
6
|
-
} from './vite/types'
|
|
7
|
-
export type { TanStackStartViteInputConfig } from './vite/schema'
|
|
8
|
-
export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from './constants'
|
|
9
|
-
export { createVirtualModule } from './vite/createVirtualModule'
|
|
10
|
-
export { tanStackStartVite } from './vite/plugin'
|
|
11
|
-
|
|
12
|
-
export { RSBUILD_ENVIRONMENT_NAMES } from './rsbuild/planning'
|
|
13
|
-
export type { TanStackStartRsbuildPluginCoreOptions } from './rsbuild/types'
|
|
14
|
-
export type { TanStackStartRsbuildInputConfig } from './rsbuild/schema'
|
|
15
|
-
export { tanStackStartRsbuild } from './rsbuild/plugin'
|
|
3
|
+
export { START_ENVIRONMENT_NAMES } from './constants'
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { extname, resolve as resolvePath } from 'node:path'
|
|
2
2
|
|
|
3
|
-
import { normalizePath } from 'vite'
|
|
4
|
-
|
|
5
3
|
import {
|
|
6
4
|
getDefaultImportProtectionRules,
|
|
7
5
|
getMarkerSpecifiers,
|
|
8
6
|
} from '../import-protection/defaults'
|
|
7
|
+
import { normalizePath } from '../utils'
|
|
9
8
|
import { ExtensionlessAbsoluteIdResolver } from '../import-protection/extensionlessAbsoluteIdResolver'
|
|
10
9
|
import { compileMatchers, matchesAny } from '../import-protection/matchers'
|
|
11
10
|
import {
|
|
@@ -323,10 +323,6 @@ export function createChunkCssAssetCollector(options: {
|
|
|
323
323
|
const assets: Array<RouterManagedTag> = []
|
|
324
324
|
const seenAssets = new Set<RouterManagedTag>()
|
|
325
325
|
|
|
326
|
-
for (const cssFile of chunk.css) {
|
|
327
|
-
appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))
|
|
328
|
-
}
|
|
329
|
-
|
|
330
326
|
for (let i = 0; i < chunk.imports.length; i++) {
|
|
331
327
|
const importedChunk = options.chunksByFileName.get(chunk.imports[i]!)
|
|
332
328
|
if (!importedChunk) {
|
|
@@ -339,6 +335,10 @@ export function createChunkCssAssetCollector(options: {
|
|
|
339
335
|
}
|
|
340
336
|
}
|
|
341
337
|
|
|
338
|
+
for (const cssFile of chunk.css) {
|
|
339
|
+
appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))
|
|
340
|
+
}
|
|
341
|
+
|
|
342
342
|
stateByChunk.delete(chunk)
|
|
343
343
|
assetsByChunk.set(chunk, assets)
|
|
344
344
|
return assets
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
|
|
3
|
+
const isWindows: boolean =
|
|
4
|
+
typeof process !== 'undefined' && process.platform === 'win32'
|
|
5
|
+
const windowsSlashRE = /\\/g
|
|
6
|
+
|
|
1
7
|
/** Read `build.rollupOptions` or `build.rolldownOptions` from a build config. */
|
|
2
8
|
export function getBundlerOptions(build: any): any {
|
|
3
9
|
return build?.rolldownOptions ?? build?.rollupOptions
|
|
@@ -18,6 +24,10 @@ export function createLogger(prefix: string) {
|
|
|
18
24
|
}
|
|
19
25
|
}
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
return path.replace(
|
|
27
|
+
function slash(path: string): string {
|
|
28
|
+
return path.replace(windowsSlashRE, '/')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function normalizePath(id: string): string {
|
|
32
|
+
return path.posix.normalize(isWindows ? slash(id) : id)
|
|
23
33
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
TanStackStartVitePluginCoreOptions,
|
|
3
|
+
ViteRscForwardSsrResolverStrategy,
|
|
4
|
+
} from './types'
|
|
5
|
+
export type { TanStackStartViteInputConfig } from './schema'
|
|
6
|
+
export { START_ENVIRONMENT_NAMES, VITE_ENVIRONMENT_NAMES } from '../constants'
|
|
7
|
+
export { createVirtualModule } from './createVirtualModule'
|
|
8
|
+
export { tanStackStartVite } from './plugin'
|