@tanstack/start-plugin-core 1.169.8 → 1.169.10
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/analysis.js +19 -7
- package/dist/esm/import-protection/analysis.js.map +1 -1
- package/dist/esm/start-compiler/server-fn-resolver-module.js +1 -1
- package/dist/esm/start-compiler/server-fn-resolver-module.js.map +1 -1
- package/package.json +2 -2
- package/src/import-protection/analysis.ts +34 -6
- package/src/start-compiler/server-fn-resolver-module.ts +13 -6
|
@@ -19,6 +19,16 @@ function getStringLiteralValueStart(node) {
|
|
|
19
19
|
if (typeof raw === "string" && (raw.startsWith("'") || raw.startsWith("\""))) return node.start + 1;
|
|
20
20
|
return node.start;
|
|
21
21
|
}
|
|
22
|
+
function isTypeOnlyImportDeclaration(node) {
|
|
23
|
+
if (node.importKind === "type") return true;
|
|
24
|
+
if (node.specifiers.length === 0) return false;
|
|
25
|
+
return node.specifiers.every((specifier) => t.isImportSpecifier(specifier) && specifier.importKind === "type");
|
|
26
|
+
}
|
|
27
|
+
function isTypeOnlyExportNamedDeclaration(node) {
|
|
28
|
+
if (node.exportKind === "type") return true;
|
|
29
|
+
if (!node.source || node.declaration || node.specifiers.length === 0) return false;
|
|
30
|
+
return node.specifiers.every((specifier) => t.isExportSpecifier(specifier) && specifier.exportKind === "type");
|
|
31
|
+
}
|
|
22
32
|
function collectIdentifiersFromPattern(pattern, add) {
|
|
23
33
|
if (t.isIdentifier(pattern)) add(pattern.name);
|
|
24
34
|
else if (t.isObjectPattern(pattern)) for (const prop of pattern.properties) if (t.isRestElement(prop)) collectIdentifiersFromPattern(prop.argument, add);
|
|
@@ -66,8 +76,8 @@ function buildImportAnalysis(result) {
|
|
|
66
76
|
};
|
|
67
77
|
const visit = (node) => {
|
|
68
78
|
if (t.isImportDeclaration(node)) {
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
if (!isTypeOnlyImportDeclaration(node)) {
|
|
80
|
+
addSpecifierLocation(node.source);
|
|
71
81
|
const source = node.source.value;
|
|
72
82
|
const bindingInfo = getBindingInfo(source);
|
|
73
83
|
for (const specifier of node.specifiers) {
|
|
@@ -89,8 +99,9 @@ function buildImportAnalysis(result) {
|
|
|
89
99
|
}
|
|
90
100
|
}
|
|
91
101
|
} else if (t.isExportNamedDeclaration(node)) {
|
|
92
|
-
|
|
93
|
-
if (node.
|
|
102
|
+
const isTypeOnly = isTypeOnlyExportNamedDeclaration(node);
|
|
103
|
+
if (!isTypeOnly && node.source && t.isStringLiteral(node.source)) addSpecifierLocation(node.source);
|
|
104
|
+
if (!isTypeOnly && node.source?.value) {
|
|
94
105
|
const source = node.source.value;
|
|
95
106
|
for (const specifier of node.specifiers) {
|
|
96
107
|
if (!t.isExportSpecifier(specifier)) continue;
|
|
@@ -98,7 +109,7 @@ function buildImportAnalysis(result) {
|
|
|
98
109
|
addMockName(source, getModuleExportName(specifier.local));
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
|
-
if (
|
|
112
|
+
if (!isTypeOnly) {
|
|
102
113
|
if (node.declaration) {
|
|
103
114
|
const decl = node.declaration;
|
|
104
115
|
if (t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) {
|
|
@@ -111,8 +122,9 @@ function buildImportAnalysis(result) {
|
|
|
111
122
|
addNamedExport(getModuleExportName(specifier.exported));
|
|
112
123
|
}
|
|
113
124
|
}
|
|
114
|
-
} else if (t.isExportAllDeclaration(node))
|
|
115
|
-
|
|
125
|
+
} else if (t.isExportAllDeclaration(node)) {
|
|
126
|
+
if (node.exportKind !== "type") addSpecifierLocation(node.source);
|
|
127
|
+
} else if (t.isImportExpression(node)) {
|
|
116
128
|
if (t.isStringLiteral(node.source)) addSpecifierLocation(node.source);
|
|
117
129
|
} else if (t.isCallExpression(node) && t.isImport(node.callee)) {
|
|
118
130
|
const sourceNode = node.arguments[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analysis.js","names":[],"sources":["../../../src/import-protection/analysis.ts"],"sourcesContent":["import * as t from '@babel/types'\n\nimport { parseImportProtectionAst } from './ast'\nimport { buildLineIndex } from './sourceLocation'\nimport { getOrCreate } from './utils'\nimport type { LineIndex, TransformResult } from './sourceLocation'\nimport type { ParsedAst } from './ast'\n\nexport type UsagePos = { line: number; column0: number }\n\ntype BoundaryEnv = 'client' | 'server'\n\ntype ImportBindingInfo = {\n importedLocalNames: Set<string>\n memberBindingToSource: Map<string, string>\n}\n\ntype UsageCacheKey = `${BoundaryEnv | 'post'}::${string}`\n\nexport type ImportAnalysis = {\n ast: ParsedAst\n lineIndex: LineIndex\n importSourcesInOrder: Array<string>\n importSpecifierLocationIndex: Map<string, number>\n importBindingsBySource: Map<string, ImportBindingInfo>\n mockExportNamesBySource: Map<string, Array<string>>\n namedExports: Array<string>\n usageByKey: Map<UsageCacheKey, UsagePos | null>\n}\n\nfunction makeTransientResult(code: string): TransformResult {\n return {\n code,\n map: undefined,\n originalCode: undefined,\n }\n}\n\nfunction getModuleExportName(node: t.Identifier | t.StringLiteral): string {\n return t.isIdentifier(node) ? node.name : node.value\n}\n\nfunction getStringLiteralValueStart(node: t.StringLiteral): number {\n if (node.start == null) {\n return -1\n }\n\n const raw = node.extra?.raw\n if (typeof raw === 'string' && (raw.startsWith(\"'\") || raw.startsWith('\"'))) {\n return node.start + 1\n }\n\n return node.start\n}\n\nfunction collectIdentifiersFromPattern(\n pattern: t.LVal,\n add: (name: string) => void,\n): void {\n if (t.isIdentifier(pattern)) {\n add(pattern.name)\n } else if (t.isObjectPattern(pattern)) {\n for (const prop of pattern.properties) {\n if (t.isRestElement(prop)) {\n collectIdentifiersFromPattern(prop.argument as t.LVal, add)\n } else {\n collectIdentifiersFromPattern(prop.value as t.LVal, add)\n }\n }\n } else if (t.isArrayPattern(pattern)) {\n for (const elem of pattern.elements) {\n if (elem) collectIdentifiersFromPattern(elem as t.LVal, add)\n }\n } else if (t.isAssignmentPattern(pattern)) {\n collectIdentifiersFromPattern(pattern.left, add)\n } else if (t.isRestElement(pattern)) {\n collectIdentifiersFromPattern(pattern.argument as t.LVal, add)\n }\n}\n\nexport function isValidExportName(name: string): boolean {\n if (name === 'default' || name.length === 0) return false\n const first = name.charCodeAt(0)\n if (\n !(\n (first >= 65 && first <= 90) ||\n (first >= 97 && first <= 122) ||\n first === 95 ||\n first === 36\n )\n )\n return false\n for (let i = 1; i < name.length; i++) {\n const ch = name.charCodeAt(i)\n if (\n !(\n (ch >= 65 && ch <= 90) ||\n (ch >= 97 && ch <= 122) ||\n (ch >= 48 && ch <= 57) ||\n ch === 95 ||\n ch === 36\n )\n )\n return false\n }\n return true\n}\n\nfunction buildImportAnalysis(result: TransformResult): ImportAnalysis {\n const ast = result.parsedAst ?? parseImportProtectionAst(result.code)\n result.parsedAst = ast\n\n const importSourcesInOrder: Array<string> = []\n const importSpecifierLocationIndex = new Map<string, number>()\n const importBindingsBySource = new Map<string, ImportBindingInfo>()\n const mockNamesBySource = new Map<string, Set<string>>()\n const namedExports = new Set<string>()\n\n const getBindingInfo = (source: string): ImportBindingInfo =>\n getOrCreate(importBindingsBySource, source, () => ({\n importedLocalNames: new Set<string>(),\n memberBindingToSource: new Map<string, string>(),\n }))\n\n const addSpecifierLocation = (node: t.StringLiteral) => {\n importSourcesInOrder.push(node.value)\n\n const index = getStringLiteralValueStart(node)\n if (index === -1) {\n return\n }\n\n const prev = importSpecifierLocationIndex.get(node.value)\n if (prev == null || index < prev) {\n importSpecifierLocationIndex.set(node.value, index)\n }\n }\n\n const addMockName = (source: string, name: string) => {\n if (name === 'default' || name.length === 0) return\n getOrCreate(mockNamesBySource, source, () => new Set<string>()).add(name)\n }\n\n const addNamedExport = (name: string) => {\n if (name !== 'default' && name.length > 0) {\n namedExports.add(name)\n }\n }\n\n const visit = (node: t.Node): void => {\n if (t.isImportDeclaration(node)) {\n addSpecifierLocation(node.source)\n if (node.importKind !== 'type') {\n const source = node.source.value\n const bindingInfo = getBindingInfo(source)\n for (const specifier of node.specifiers) {\n if (t.isImportNamespaceSpecifier(specifier)) {\n bindingInfo.importedLocalNames.add(specifier.local.name)\n bindingInfo.memberBindingToSource.set(specifier.local.name, source)\n continue\n }\n\n if (t.isImportDefaultSpecifier(specifier)) {\n bindingInfo.importedLocalNames.add(specifier.local.name)\n bindingInfo.memberBindingToSource.set(specifier.local.name, source)\n continue\n }\n\n if (!t.isImportSpecifier(specifier)) continue\n if (specifier.importKind === 'type') continue\n\n bindingInfo.importedLocalNames.add(specifier.local.name)\n const importedName = getModuleExportName(specifier.imported)\n if (importedName !== 'default') {\n addMockName(source, importedName)\n }\n }\n }\n } else if (t.isExportNamedDeclaration(node)) {\n if (node.source && t.isStringLiteral(node.source)) {\n addSpecifierLocation(node.source)\n }\n\n if (node.exportKind !== 'type' && node.source?.value) {\n const source = node.source.value\n for (const specifier of node.specifiers) {\n if (!t.isExportSpecifier(specifier)) continue\n if (specifier.exportKind === 'type') continue\n addMockName(source, getModuleExportName(specifier.local))\n }\n }\n\n if (node.exportKind !== 'type') {\n if (node.declaration) {\n const decl = node.declaration\n if (t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) {\n if (decl.id?.name) addNamedExport(decl.id.name)\n } else if (t.isVariableDeclaration(decl)) {\n for (const d of decl.declarations) {\n collectIdentifiersFromPattern(d.id as t.LVal, addNamedExport)\n }\n }\n }\n\n for (const specifier of node.specifiers) {\n if (!t.isExportSpecifier(specifier)) continue\n if (specifier.exportKind === 'type') continue\n const exportedName = getModuleExportName(specifier.exported)\n addNamedExport(exportedName)\n }\n }\n } else if (t.isExportAllDeclaration(node)) {\n addSpecifierLocation(node.source)\n } else if (t.isImportExpression(node)) {\n if (t.isStringLiteral(node.source)) {\n addSpecifierLocation(node.source)\n }\n } else if (t.isCallExpression(node) && t.isImport(node.callee)) {\n const sourceNode = node.arguments[0]\n if (t.isStringLiteral(sourceNode)) {\n addSpecifierLocation(sourceNode)\n }\n } else if (\n t.isMemberExpression(node) ||\n t.isOptionalMemberExpression(node)\n ) {\n const object = node.object\n if (t.isIdentifier(object)) {\n for (const [source, bindingInfo] of importBindingsBySource) {\n if (!bindingInfo.memberBindingToSource.has(object.name)) {\n continue\n }\n\n const property = node.property\n if (!node.computed && t.isIdentifier(property)) {\n addMockName(source, property.name)\n } else if (node.computed && t.isStringLiteral(property)) {\n addMockName(source, property.value)\n }\n }\n }\n }\n\n const keys = t.VISITOR_KEYS[node.type]\n if (!keys) return\n for (const key of keys) {\n const child = (node as unknown as Record<string, unknown>)[key]\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === 'object' && 'type' in item) {\n visit(item as t.Node)\n }\n }\n } else if (child && typeof child === 'object' && 'type' in child) {\n visit(child as t.Node)\n }\n }\n }\n\n visit(ast.program)\n\n const mockExportNamesBySource = new Map<string, Array<string>>()\n for (const [source, names] of mockNamesBySource) {\n mockExportNamesBySource.set(source, Array.from(names).sort())\n }\n\n const lineIndex = result.lineIndex ?? buildLineIndex(result.code)\n result.lineIndex = lineIndex\n\n const analysis = {\n ast,\n lineIndex,\n importSourcesInOrder,\n importSpecifierLocationIndex,\n importBindingsBySource,\n mockExportNamesBySource,\n namedExports: Array.from(namedExports).sort(),\n usageByKey: new Map(),\n }\n\n return analysis\n}\n\nexport function getOrCreateImportAnalysis(\n result: TransformResult,\n): ImportAnalysis {\n if (!result.analysis) {\n result.analysis = buildImportAnalysis(result)\n }\n\n return result.analysis\n}\n\nexport function getImportSourcesFromResult(\n result: TransformResult,\n): Array<string> {\n return getOrCreateImportAnalysis(result).importSourcesInOrder\n}\n\nexport function getImportSources(code: string): Array<string> {\n return getImportSourcesFromResult(makeTransientResult(code))\n}\n\nexport function getImportSpecifierLocationFromResult(\n result: TransformResult,\n source: string,\n): number {\n return (\n getOrCreateImportAnalysis(result).importSpecifierLocationIndex.get(\n source,\n ) ?? -1\n )\n}\n\nexport function getMockExportNamesBySourceFromResult(\n result: TransformResult,\n): Map<string, Array<string>> {\n return getOrCreateImportAnalysis(result).mockExportNamesBySource\n}\n\nexport function getMockExportNamesBySource(\n code: string,\n): Map<string, Array<string>> {\n return getMockExportNamesBySourceFromResult(makeTransientResult(code))\n}\n\nexport function getNamedExportsFromResult(\n result: TransformResult,\n): Array<string> {\n return getOrCreateImportAnalysis(result).namedExports\n}\n\nexport function getNamedExports(code: string): Array<string> {\n return getNamedExportsFromResult(makeTransientResult(code))\n}\n\nfunction isCompilerSafeBoundaryCall(\n call: t.CallExpression,\n fnNode: t.Function,\n envType: BoundaryEnv,\n): boolean {\n const directArgument = call.arguments.some((arg) => arg === fnNode)\n if (!directArgument) {\n return false\n }\n\n const callee = call.callee\n\n if (t.isIdentifier(callee)) {\n return envType === 'client'\n ? callee.name === 'createServerOnlyFn'\n : callee.name === 'createClientOnlyFn'\n }\n\n if (!t.isMemberExpression(callee) || callee.computed) {\n return false\n }\n\n if (!t.isIdentifier(callee.property)) {\n return false\n }\n\n const prop = callee.property.name\n const rootName = getCalleeRootName(callee.object)\n\n if (envType === 'client') {\n if (prop === 'handler') {\n return rootName === 'createServerFn' || /ServerFn$/.test(rootName ?? '')\n }\n\n if (prop === 'server') {\n return (\n rootName === 'createMiddleware' ||\n rootName === 'createIsomorphicFn' ||\n /Middleware$/.test(rootName ?? '')\n )\n }\n\n return false\n }\n\n if (prop === 'client') {\n return rootName === 'createIsomorphicFn'\n }\n\n return false\n}\n\nfunction getCalleeRootName(\n node: t.Expression | t.Super | t.V8IntrinsicIdentifier,\n): string | undefined {\n if (t.isIdentifier(node)) {\n return node.name\n }\n\n if (t.isCallExpression(node)) {\n return getCalleeRootName(node.callee)\n }\n\n if (t.isMemberExpression(node)) {\n return getCalleeRootName(node.object)\n }\n\n return undefined\n}\n\nfunction getBoundNamesFromPattern(pattern: t.LVal, out: Set<string>): void {\n if (t.isIdentifier(pattern)) {\n out.add(pattern.name)\n } else if (t.isObjectPattern(pattern)) {\n for (const prop of pattern.properties) {\n if (t.isRestElement(prop)) {\n getBoundNamesFromPattern(prop.argument as t.LVal, out)\n } else {\n getBoundNamesFromPattern(prop.value as t.LVal, out)\n }\n }\n } else if (t.isArrayPattern(pattern)) {\n for (const elem of pattern.elements) {\n if (elem) getBoundNamesFromPattern(elem as t.LVal, out)\n }\n } else if (t.isAssignmentPattern(pattern)) {\n getBoundNamesFromPattern(pattern.left, out)\n } else if (t.isRestElement(pattern)) {\n getBoundNamesFromPattern(pattern.argument as t.LVal, out)\n }\n}\n\nfunction addPatternBindingsIfTracked(\n pattern: t.LVal,\n tracked: Set<string>,\n out: Set<string>,\n): void {\n const names = new Set<string>()\n getBoundNamesFromPattern(pattern, names)\n for (const name of names) {\n if (tracked.has(name)) {\n out.add(name)\n }\n }\n}\n\nfunction collectHoistedVarBindings(\n node: t.Node,\n tracked: Set<string>,\n out: Set<string>,\n isRoot = true,\n): void {\n if (!isRoot && t.isFunction(node)) {\n return\n }\n\n if (t.isVariableDeclaration(node) && node.kind === 'var') {\n for (const decl of node.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, tracked, out)\n }\n }\n\n const keys = t.VISITOR_KEYS[node.type]\n if (!keys) return\n for (const key of keys) {\n const child = (node as unknown as Record<string, unknown>)[key]\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === 'object' && 'type' in item) {\n collectHoistedVarBindings(item as t.Node, tracked, out, false)\n }\n }\n } else if (child && typeof child === 'object' && 'type' in child) {\n collectHoistedVarBindings(child as t.Node, tracked, out, false)\n }\n }\n}\n\nfunction collectProgramBindings(\n program: t.Program,\n tracked: Set<string>,\n): Set<string> {\n const bindings = new Set<string>()\n\n for (const node of program.body) {\n if (t.isVariableDeclaration(node)) {\n for (const decl of node.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, tracked, bindings)\n }\n continue\n }\n\n if (t.isFunctionDeclaration(node) || t.isClassDeclaration(node)) {\n if (node.id && tracked.has(node.id.name)) {\n bindings.add(node.id.name)\n }\n }\n }\n\n return bindings\n}\n\nfunction collectBlockBindings(\n block: t.BlockStatement,\n tracked: Set<string>,\n): Set<string> {\n const bindings = new Set<string>()\n\n for (const node of block.body) {\n if (t.isVariableDeclaration(node) && node.kind !== 'var') {\n for (const decl of node.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, tracked, bindings)\n }\n continue\n }\n\n if (t.isFunctionDeclaration(node) || t.isClassDeclaration(node)) {\n if (node.id && tracked.has(node.id.name)) {\n bindings.add(node.id.name)\n }\n }\n }\n\n return bindings\n}\n\nfunction collectFunctionBindings(\n fn: t.Function,\n tracked: Set<string>,\n): Set<string> {\n const bindings = new Set<string>()\n\n if (\n (t.isFunctionDeclaration(fn) || t.isFunctionExpression(fn)) &&\n fn.id &&\n tracked.has(fn.id.name)\n ) {\n bindings.add(fn.id.name)\n }\n\n for (const param of fn.params) {\n addPatternBindingsIfTracked(param as t.LVal, tracked, bindings)\n }\n\n if (t.isBlockStatement(fn.body)) {\n collectHoistedVarBindings(fn.body, tracked, bindings)\n }\n\n return bindings\n}\n\ntype UsageWalkContext = {\n parents: Array<t.Node>\n scopeStack: Array<Set<string>>\n}\n\nfunction isShadowedByScope(\n name: string,\n scopeStack: Array<Set<string>>,\n): boolean {\n for (let i = scopeStack.length - 1; i >= 0; i--) {\n if (scopeStack[i]?.has(name)) {\n return true\n }\n }\n return false\n}\n\nfunction isBindingIdentifierInParent(\n node: t.Identifier,\n parent: t.Node | undefined,\n): boolean {\n if (!parent) return false\n\n if (t.isImportSpecifier(parent) || t.isImportDefaultSpecifier(parent)) {\n return parent.local === node\n }\n if (t.isImportNamespaceSpecifier(parent)) {\n return parent.local === node\n }\n if (t.isFunctionDeclaration(parent) || t.isFunctionExpression(parent)) {\n return (\n parent.id === node || parent.params.includes(node as unknown as t.Pattern)\n )\n }\n if (t.isArrowFunctionExpression(parent)) {\n return parent.params.includes(node as unknown as t.Pattern)\n }\n if (t.isClassDeclaration(parent) || t.isClassExpression(parent)) {\n return parent.id === node\n }\n if (t.isVariableDeclarator(parent)) {\n return parent.id === node\n }\n if (t.isCatchClause(parent)) {\n return parent.param === node\n }\n\n return false\n}\n\nfunction isInsideCompilerSafeBoundaryNodes(\n parents: Array<t.Node>,\n envType: BoundaryEnv,\n): boolean {\n for (let i = parents.length - 1; i >= 0; i--) {\n const node = parents[i]!\n if (!t.isFunction(node)) {\n continue\n }\n\n const call = parents[i - 1]\n if (\n call &&\n t.isCallExpression(call) &&\n isCompilerSafeBoundaryCall(call, node, envType)\n ) {\n return true\n }\n }\n\n return false\n}\n\nfunction findUsagePosInAnalysis(\n result: TransformResult,\n source: string,\n envType?: BoundaryEnv,\n): UsagePos | undefined {\n const analysis = getOrCreateImportAnalysis(result)\n const cacheKey: UsageCacheKey = `${envType ?? 'post'}::${source}`\n if (analysis.usageByKey.has(cacheKey)) {\n return analysis.usageByKey.get(cacheKey) ?? undefined\n }\n\n const imported =\n analysis.importBindingsBySource.get(source)?.importedLocalNames\n if (!imported || imported.size === 0) {\n analysis.usageByKey.set(cacheKey, null)\n return undefined\n }\n\n let preferred: UsagePos | undefined\n let anyUsage: UsagePos | undefined\n\n const visit = (node: t.Node, ctx: UsageWalkContext): void => {\n if (preferred && anyUsage) {\n return\n }\n\n if (t.isProgram(node)) {\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: [...ctx.scopeStack, collectProgramBindings(node, imported)],\n }\n for (const child of node.body) {\n visit(child, nextCtx)\n }\n return\n }\n\n if (t.isFunction(node)) {\n const functionCtx = {\n parents: [...ctx.parents, node],\n scopeStack: [\n ...ctx.scopeStack,\n collectFunctionBindings(node, imported),\n ],\n }\n\n visit(node.body, functionCtx)\n return\n }\n\n if (t.isBlockStatement(node)) {\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: [...ctx.scopeStack, collectBlockBindings(node, imported)],\n }\n for (const child of node.body) {\n visit(child, nextCtx)\n }\n return\n }\n\n if (t.isCatchClause(node)) {\n const bindings = new Set<string>()\n if (node.param) {\n addPatternBindingsIfTracked(node.param as t.LVal, imported, bindings)\n }\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: bindings.size\n ? [...ctx.scopeStack, bindings]\n : ctx.scopeStack,\n }\n visit(node.body, nextCtx)\n return\n }\n\n if (\n t.isForStatement(node) &&\n t.isVariableDeclaration(node.init) &&\n node.init.kind !== 'var'\n ) {\n const bindings = new Set<string>()\n for (const decl of node.init.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, imported, bindings)\n }\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: bindings.size\n ? [...ctx.scopeStack, bindings]\n : ctx.scopeStack,\n }\n visit(node.init, nextCtx)\n if (node.test) visit(node.test, nextCtx)\n if (node.update) visit(node.update, nextCtx)\n visit(node.body, nextCtx)\n return\n }\n\n if (\n (t.isForInStatement(node) || t.isForOfStatement(node)) &&\n t.isVariableDeclaration(node.left) &&\n node.left.kind !== 'var'\n ) {\n const bindings = new Set<string>()\n for (const decl of node.left.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, imported, bindings)\n }\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: bindings.size\n ? [...ctx.scopeStack, bindings]\n : ctx.scopeStack,\n }\n visit(node.left, nextCtx)\n visit(node.right, nextCtx)\n visit(node.body, nextCtx)\n return\n }\n\n const nextParents = [...ctx.parents, node]\n\n if (t.isIdentifier(node)) {\n const parent = ctx.parents[ctx.parents.length - 1]\n if (imported.has(node.name)) {\n if (!isBindingIdentifierInParent(node, parent)) {\n if (\n !(\n t.isObjectProperty(parent) &&\n parent.key === node &&\n !parent.computed &&\n !parent.shorthand\n ) &&\n !(\n t.isObjectMethod(parent) &&\n parent.key === node &&\n !parent.computed\n ) &&\n !(t.isExportSpecifier(parent) && parent.exported === node) &&\n !isShadowedByScope(node.name, ctx.scopeStack) &&\n !(\n envType && isInsideCompilerSafeBoundaryNodes(ctx.parents, envType)\n )\n ) {\n const loc = node.loc?.start\n if (loc) {\n const pos: UsagePos = { line: loc.line, column0: loc.column }\n const isPreferred =\n (t.isCallExpression(parent) && parent.callee === node) ||\n (t.isNewExpression(parent) && parent.callee === node) ||\n ((t.isMemberExpression(parent) ||\n t.isOptionalMemberExpression(parent)) &&\n parent.object === node)\n\n if (isPreferred) {\n preferred ||= pos\n } else {\n anyUsage ||= pos\n }\n }\n }\n }\n }\n }\n\n if (t.isImportDeclaration(node)) {\n return\n }\n\n const keys = t.VISITOR_KEYS[node.type]\n if (!keys) return\n for (const key of keys) {\n const child = (node as unknown as Record<string, unknown>)[key]\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === 'object' && 'type' in item) {\n visit(item as t.Node, {\n parents: nextParents,\n scopeStack: ctx.scopeStack,\n })\n }\n }\n } else if (child && typeof child === 'object' && 'type' in child) {\n visit(child as t.Node, {\n parents: nextParents,\n scopeStack: ctx.scopeStack,\n })\n }\n }\n }\n\n visit(analysis.ast.program, {\n parents: [],\n scopeStack: [],\n })\n\n const pos = preferred ?? anyUsage ?? null\n analysis.usageByKey.set(cacheKey, pos)\n return pos ?? undefined\n}\n\nexport function findPostCompileUsagePosFromResult(\n result: TransformResult,\n source: string,\n): UsagePos | undefined {\n return findUsagePosInAnalysis(result, source)\n}\n\nexport function findPostCompileUsagePos(\n code: string,\n source: string,\n): UsagePos | undefined {\n return findPostCompileUsagePosFromResult(makeTransientResult(code), source)\n}\n\nexport function findOriginalUnsafeUsagePosFromResult(\n result: TransformResult,\n source: string,\n envType: BoundaryEnv,\n): UsagePos | undefined {\n return findUsagePosInAnalysis(result, source, envType)\n}\n\nexport function findOriginalUnsafeUsagePos(\n code: string,\n source: string,\n envType: BoundaryEnv,\n): UsagePos | undefined {\n return findOriginalUnsafeUsagePosFromResult(\n makeTransientResult(code),\n source,\n envType,\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"analysis.js","names":[],"sources":["../../../src/import-protection/analysis.ts"],"sourcesContent":["import * as t from '@babel/types'\n\nimport { parseImportProtectionAst } from './ast'\nimport { buildLineIndex } from './sourceLocation'\nimport { getOrCreate } from './utils'\nimport type { LineIndex, TransformResult } from './sourceLocation'\nimport type { ParsedAst } from './ast'\n\nexport type UsagePos = { line: number; column0: number }\n\ntype BoundaryEnv = 'client' | 'server'\n\ntype ImportBindingInfo = {\n importedLocalNames: Set<string>\n memberBindingToSource: Map<string, string>\n}\n\ntype UsageCacheKey = `${BoundaryEnv | 'post'}::${string}`\n\nexport type ImportAnalysis = {\n ast: ParsedAst\n lineIndex: LineIndex\n importSourcesInOrder: Array<string>\n importSpecifierLocationIndex: Map<string, number>\n importBindingsBySource: Map<string, ImportBindingInfo>\n mockExportNamesBySource: Map<string, Array<string>>\n namedExports: Array<string>\n usageByKey: Map<UsageCacheKey, UsagePos | null>\n}\n\nfunction makeTransientResult(code: string): TransformResult {\n return {\n code,\n map: undefined,\n originalCode: undefined,\n }\n}\n\nfunction getModuleExportName(node: t.Identifier | t.StringLiteral): string {\n return t.isIdentifier(node) ? node.name : node.value\n}\n\nfunction getStringLiteralValueStart(node: t.StringLiteral): number {\n if (node.start == null) {\n return -1\n }\n\n const raw = node.extra?.raw\n if (typeof raw === 'string' && (raw.startsWith(\"'\") || raw.startsWith('\"'))) {\n return node.start + 1\n }\n\n return node.start\n}\n\nfunction isTypeOnlyImportDeclaration(node: t.ImportDeclaration): boolean {\n if (node.importKind === 'type') return true\n if (node.specifiers.length === 0) return false\n\n return node.specifiers.every(\n (specifier) =>\n t.isImportSpecifier(specifier) && specifier.importKind === 'type',\n )\n}\n\nfunction isTypeOnlyExportNamedDeclaration(\n node: t.ExportNamedDeclaration,\n): boolean {\n if (node.exportKind === 'type') return true\n if (!node.source || node.declaration || node.specifiers.length === 0) {\n return false\n }\n\n return node.specifiers.every(\n (specifier) =>\n t.isExportSpecifier(specifier) && specifier.exportKind === 'type',\n )\n}\n\nfunction collectIdentifiersFromPattern(\n pattern: t.LVal,\n add: (name: string) => void,\n): void {\n if (t.isIdentifier(pattern)) {\n add(pattern.name)\n } else if (t.isObjectPattern(pattern)) {\n for (const prop of pattern.properties) {\n if (t.isRestElement(prop)) {\n collectIdentifiersFromPattern(prop.argument as t.LVal, add)\n } else {\n collectIdentifiersFromPattern(prop.value as t.LVal, add)\n }\n }\n } else if (t.isArrayPattern(pattern)) {\n for (const elem of pattern.elements) {\n if (elem) collectIdentifiersFromPattern(elem as t.LVal, add)\n }\n } else if (t.isAssignmentPattern(pattern)) {\n collectIdentifiersFromPattern(pattern.left, add)\n } else if (t.isRestElement(pattern)) {\n collectIdentifiersFromPattern(pattern.argument as t.LVal, add)\n }\n}\n\nexport function isValidExportName(name: string): boolean {\n if (name === 'default' || name.length === 0) return false\n const first = name.charCodeAt(0)\n if (\n !(\n (first >= 65 && first <= 90) ||\n (first >= 97 && first <= 122) ||\n first === 95 ||\n first === 36\n )\n )\n return false\n for (let i = 1; i < name.length; i++) {\n const ch = name.charCodeAt(i)\n if (\n !(\n (ch >= 65 && ch <= 90) ||\n (ch >= 97 && ch <= 122) ||\n (ch >= 48 && ch <= 57) ||\n ch === 95 ||\n ch === 36\n )\n )\n return false\n }\n return true\n}\n\nfunction buildImportAnalysis(result: TransformResult): ImportAnalysis {\n const ast = result.parsedAst ?? parseImportProtectionAst(result.code)\n result.parsedAst = ast\n\n const importSourcesInOrder: Array<string> = []\n const importSpecifierLocationIndex = new Map<string, number>()\n const importBindingsBySource = new Map<string, ImportBindingInfo>()\n const mockNamesBySource = new Map<string, Set<string>>()\n const namedExports = new Set<string>()\n\n const getBindingInfo = (source: string): ImportBindingInfo =>\n getOrCreate(importBindingsBySource, source, () => ({\n importedLocalNames: new Set<string>(),\n memberBindingToSource: new Map<string, string>(),\n }))\n\n const addSpecifierLocation = (node: t.StringLiteral) => {\n importSourcesInOrder.push(node.value)\n\n const index = getStringLiteralValueStart(node)\n if (index === -1) {\n return\n }\n\n const prev = importSpecifierLocationIndex.get(node.value)\n if (prev == null || index < prev) {\n importSpecifierLocationIndex.set(node.value, index)\n }\n }\n\n const addMockName = (source: string, name: string) => {\n if (name === 'default' || name.length === 0) return\n getOrCreate(mockNamesBySource, source, () => new Set<string>()).add(name)\n }\n\n const addNamedExport = (name: string) => {\n if (name !== 'default' && name.length > 0) {\n namedExports.add(name)\n }\n }\n\n const visit = (node: t.Node): void => {\n if (t.isImportDeclaration(node)) {\n const isTypeOnly = isTypeOnlyImportDeclaration(node)\n if (!isTypeOnly) {\n addSpecifierLocation(node.source)\n const source = node.source.value\n const bindingInfo = getBindingInfo(source)\n for (const specifier of node.specifiers) {\n if (t.isImportNamespaceSpecifier(specifier)) {\n bindingInfo.importedLocalNames.add(specifier.local.name)\n bindingInfo.memberBindingToSource.set(specifier.local.name, source)\n continue\n }\n\n if (t.isImportDefaultSpecifier(specifier)) {\n bindingInfo.importedLocalNames.add(specifier.local.name)\n bindingInfo.memberBindingToSource.set(specifier.local.name, source)\n continue\n }\n\n if (!t.isImportSpecifier(specifier)) continue\n if (specifier.importKind === 'type') continue\n\n bindingInfo.importedLocalNames.add(specifier.local.name)\n const importedName = getModuleExportName(specifier.imported)\n if (importedName !== 'default') {\n addMockName(source, importedName)\n }\n }\n }\n } else if (t.isExportNamedDeclaration(node)) {\n const isTypeOnly = isTypeOnlyExportNamedDeclaration(node)\n if (!isTypeOnly && node.source && t.isStringLiteral(node.source)) {\n addSpecifierLocation(node.source)\n }\n\n if (!isTypeOnly && node.source?.value) {\n const source = node.source.value\n for (const specifier of node.specifiers) {\n if (!t.isExportSpecifier(specifier)) continue\n if (specifier.exportKind === 'type') continue\n addMockName(source, getModuleExportName(specifier.local))\n }\n }\n\n if (!isTypeOnly) {\n if (node.declaration) {\n const decl = node.declaration\n if (t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) {\n if (decl.id?.name) addNamedExport(decl.id.name)\n } else if (t.isVariableDeclaration(decl)) {\n for (const d of decl.declarations) {\n collectIdentifiersFromPattern(d.id as t.LVal, addNamedExport)\n }\n }\n }\n\n for (const specifier of node.specifiers) {\n if (!t.isExportSpecifier(specifier)) continue\n if (specifier.exportKind === 'type') continue\n const exportedName = getModuleExportName(specifier.exported)\n addNamedExport(exportedName)\n }\n }\n } else if (t.isExportAllDeclaration(node)) {\n if (node.exportKind !== 'type') {\n addSpecifierLocation(node.source)\n }\n } else if (t.isImportExpression(node)) {\n if (t.isStringLiteral(node.source)) {\n addSpecifierLocation(node.source)\n }\n } else if (t.isCallExpression(node) && t.isImport(node.callee)) {\n const sourceNode = node.arguments[0]\n if (t.isStringLiteral(sourceNode)) {\n addSpecifierLocation(sourceNode)\n }\n } else if (\n t.isMemberExpression(node) ||\n t.isOptionalMemberExpression(node)\n ) {\n const object = node.object\n if (t.isIdentifier(object)) {\n for (const [source, bindingInfo] of importBindingsBySource) {\n if (!bindingInfo.memberBindingToSource.has(object.name)) {\n continue\n }\n\n const property = node.property\n if (!node.computed && t.isIdentifier(property)) {\n addMockName(source, property.name)\n } else if (node.computed && t.isStringLiteral(property)) {\n addMockName(source, property.value)\n }\n }\n }\n }\n\n const keys = t.VISITOR_KEYS[node.type]\n if (!keys) return\n for (const key of keys) {\n const child = (node as unknown as Record<string, unknown>)[key]\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === 'object' && 'type' in item) {\n visit(item as t.Node)\n }\n }\n } else if (child && typeof child === 'object' && 'type' in child) {\n visit(child as t.Node)\n }\n }\n }\n\n visit(ast.program)\n\n const mockExportNamesBySource = new Map<string, Array<string>>()\n for (const [source, names] of mockNamesBySource) {\n mockExportNamesBySource.set(source, Array.from(names).sort())\n }\n\n const lineIndex = result.lineIndex ?? buildLineIndex(result.code)\n result.lineIndex = lineIndex\n\n const analysis = {\n ast,\n lineIndex,\n importSourcesInOrder,\n importSpecifierLocationIndex,\n importBindingsBySource,\n mockExportNamesBySource,\n namedExports: Array.from(namedExports).sort(),\n usageByKey: new Map(),\n }\n\n return analysis\n}\n\nexport function getOrCreateImportAnalysis(\n result: TransformResult,\n): ImportAnalysis {\n if (!result.analysis) {\n result.analysis = buildImportAnalysis(result)\n }\n\n return result.analysis\n}\n\nexport function getImportSourcesFromResult(\n result: TransformResult,\n): Array<string> {\n return getOrCreateImportAnalysis(result).importSourcesInOrder\n}\n\nexport function getImportSources(code: string): Array<string> {\n return getImportSourcesFromResult(makeTransientResult(code))\n}\n\nexport function getImportSpecifierLocationFromResult(\n result: TransformResult,\n source: string,\n): number {\n return (\n getOrCreateImportAnalysis(result).importSpecifierLocationIndex.get(\n source,\n ) ?? -1\n )\n}\n\nexport function getMockExportNamesBySourceFromResult(\n result: TransformResult,\n): Map<string, Array<string>> {\n return getOrCreateImportAnalysis(result).mockExportNamesBySource\n}\n\nexport function getMockExportNamesBySource(\n code: string,\n): Map<string, Array<string>> {\n return getMockExportNamesBySourceFromResult(makeTransientResult(code))\n}\n\nexport function getNamedExportsFromResult(\n result: TransformResult,\n): Array<string> {\n return getOrCreateImportAnalysis(result).namedExports\n}\n\nexport function getNamedExports(code: string): Array<string> {\n return getNamedExportsFromResult(makeTransientResult(code))\n}\n\nfunction isCompilerSafeBoundaryCall(\n call: t.CallExpression,\n fnNode: t.Function,\n envType: BoundaryEnv,\n): boolean {\n const directArgument = call.arguments.some((arg) => arg === fnNode)\n if (!directArgument) {\n return false\n }\n\n const callee = call.callee\n\n if (t.isIdentifier(callee)) {\n return envType === 'client'\n ? callee.name === 'createServerOnlyFn'\n : callee.name === 'createClientOnlyFn'\n }\n\n if (!t.isMemberExpression(callee) || callee.computed) {\n return false\n }\n\n if (!t.isIdentifier(callee.property)) {\n return false\n }\n\n const prop = callee.property.name\n const rootName = getCalleeRootName(callee.object)\n\n if (envType === 'client') {\n if (prop === 'handler') {\n return rootName === 'createServerFn' || /ServerFn$/.test(rootName ?? '')\n }\n\n if (prop === 'server') {\n return (\n rootName === 'createMiddleware' ||\n rootName === 'createIsomorphicFn' ||\n /Middleware$/.test(rootName ?? '')\n )\n }\n\n return false\n }\n\n if (prop === 'client') {\n return rootName === 'createIsomorphicFn'\n }\n\n return false\n}\n\nfunction getCalleeRootName(\n node: t.Expression | t.Super | t.V8IntrinsicIdentifier,\n): string | undefined {\n if (t.isIdentifier(node)) {\n return node.name\n }\n\n if (t.isCallExpression(node)) {\n return getCalleeRootName(node.callee)\n }\n\n if (t.isMemberExpression(node)) {\n return getCalleeRootName(node.object)\n }\n\n return undefined\n}\n\nfunction getBoundNamesFromPattern(pattern: t.LVal, out: Set<string>): void {\n if (t.isIdentifier(pattern)) {\n out.add(pattern.name)\n } else if (t.isObjectPattern(pattern)) {\n for (const prop of pattern.properties) {\n if (t.isRestElement(prop)) {\n getBoundNamesFromPattern(prop.argument as t.LVal, out)\n } else {\n getBoundNamesFromPattern(prop.value as t.LVal, out)\n }\n }\n } else if (t.isArrayPattern(pattern)) {\n for (const elem of pattern.elements) {\n if (elem) getBoundNamesFromPattern(elem as t.LVal, out)\n }\n } else if (t.isAssignmentPattern(pattern)) {\n getBoundNamesFromPattern(pattern.left, out)\n } else if (t.isRestElement(pattern)) {\n getBoundNamesFromPattern(pattern.argument as t.LVal, out)\n }\n}\n\nfunction addPatternBindingsIfTracked(\n pattern: t.LVal,\n tracked: Set<string>,\n out: Set<string>,\n): void {\n const names = new Set<string>()\n getBoundNamesFromPattern(pattern, names)\n for (const name of names) {\n if (tracked.has(name)) {\n out.add(name)\n }\n }\n}\n\nfunction collectHoistedVarBindings(\n node: t.Node,\n tracked: Set<string>,\n out: Set<string>,\n isRoot = true,\n): void {\n if (!isRoot && t.isFunction(node)) {\n return\n }\n\n if (t.isVariableDeclaration(node) && node.kind === 'var') {\n for (const decl of node.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, tracked, out)\n }\n }\n\n const keys = t.VISITOR_KEYS[node.type]\n if (!keys) return\n for (const key of keys) {\n const child = (node as unknown as Record<string, unknown>)[key]\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === 'object' && 'type' in item) {\n collectHoistedVarBindings(item as t.Node, tracked, out, false)\n }\n }\n } else if (child && typeof child === 'object' && 'type' in child) {\n collectHoistedVarBindings(child as t.Node, tracked, out, false)\n }\n }\n}\n\nfunction collectProgramBindings(\n program: t.Program,\n tracked: Set<string>,\n): Set<string> {\n const bindings = new Set<string>()\n\n for (const node of program.body) {\n if (t.isVariableDeclaration(node)) {\n for (const decl of node.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, tracked, bindings)\n }\n continue\n }\n\n if (t.isFunctionDeclaration(node) || t.isClassDeclaration(node)) {\n if (node.id && tracked.has(node.id.name)) {\n bindings.add(node.id.name)\n }\n }\n }\n\n return bindings\n}\n\nfunction collectBlockBindings(\n block: t.BlockStatement,\n tracked: Set<string>,\n): Set<string> {\n const bindings = new Set<string>()\n\n for (const node of block.body) {\n if (t.isVariableDeclaration(node) && node.kind !== 'var') {\n for (const decl of node.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, tracked, bindings)\n }\n continue\n }\n\n if (t.isFunctionDeclaration(node) || t.isClassDeclaration(node)) {\n if (node.id && tracked.has(node.id.name)) {\n bindings.add(node.id.name)\n }\n }\n }\n\n return bindings\n}\n\nfunction collectFunctionBindings(\n fn: t.Function,\n tracked: Set<string>,\n): Set<string> {\n const bindings = new Set<string>()\n\n if (\n (t.isFunctionDeclaration(fn) || t.isFunctionExpression(fn)) &&\n fn.id &&\n tracked.has(fn.id.name)\n ) {\n bindings.add(fn.id.name)\n }\n\n for (const param of fn.params) {\n addPatternBindingsIfTracked(param as t.LVal, tracked, bindings)\n }\n\n if (t.isBlockStatement(fn.body)) {\n collectHoistedVarBindings(fn.body, tracked, bindings)\n }\n\n return bindings\n}\n\ntype UsageWalkContext = {\n parents: Array<t.Node>\n scopeStack: Array<Set<string>>\n}\n\nfunction isShadowedByScope(\n name: string,\n scopeStack: Array<Set<string>>,\n): boolean {\n for (let i = scopeStack.length - 1; i >= 0; i--) {\n if (scopeStack[i]?.has(name)) {\n return true\n }\n }\n return false\n}\n\nfunction isBindingIdentifierInParent(\n node: t.Identifier,\n parent: t.Node | undefined,\n): boolean {\n if (!parent) return false\n\n if (t.isImportSpecifier(parent) || t.isImportDefaultSpecifier(parent)) {\n return parent.local === node\n }\n if (t.isImportNamespaceSpecifier(parent)) {\n return parent.local === node\n }\n if (t.isFunctionDeclaration(parent) || t.isFunctionExpression(parent)) {\n return (\n parent.id === node || parent.params.includes(node as unknown as t.Pattern)\n )\n }\n if (t.isArrowFunctionExpression(parent)) {\n return parent.params.includes(node as unknown as t.Pattern)\n }\n if (t.isClassDeclaration(parent) || t.isClassExpression(parent)) {\n return parent.id === node\n }\n if (t.isVariableDeclarator(parent)) {\n return parent.id === node\n }\n if (t.isCatchClause(parent)) {\n return parent.param === node\n }\n\n return false\n}\n\nfunction isInsideCompilerSafeBoundaryNodes(\n parents: Array<t.Node>,\n envType: BoundaryEnv,\n): boolean {\n for (let i = parents.length - 1; i >= 0; i--) {\n const node = parents[i]!\n if (!t.isFunction(node)) {\n continue\n }\n\n const call = parents[i - 1]\n if (\n call &&\n t.isCallExpression(call) &&\n isCompilerSafeBoundaryCall(call, node, envType)\n ) {\n return true\n }\n }\n\n return false\n}\n\nfunction findUsagePosInAnalysis(\n result: TransformResult,\n source: string,\n envType?: BoundaryEnv,\n): UsagePos | undefined {\n const analysis = getOrCreateImportAnalysis(result)\n const cacheKey: UsageCacheKey = `${envType ?? 'post'}::${source}`\n if (analysis.usageByKey.has(cacheKey)) {\n return analysis.usageByKey.get(cacheKey) ?? undefined\n }\n\n const imported =\n analysis.importBindingsBySource.get(source)?.importedLocalNames\n if (!imported || imported.size === 0) {\n analysis.usageByKey.set(cacheKey, null)\n return undefined\n }\n\n let preferred: UsagePos | undefined\n let anyUsage: UsagePos | undefined\n\n const visit = (node: t.Node, ctx: UsageWalkContext): void => {\n if (preferred && anyUsage) {\n return\n }\n\n if (t.isProgram(node)) {\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: [...ctx.scopeStack, collectProgramBindings(node, imported)],\n }\n for (const child of node.body) {\n visit(child, nextCtx)\n }\n return\n }\n\n if (t.isFunction(node)) {\n const functionCtx = {\n parents: [...ctx.parents, node],\n scopeStack: [\n ...ctx.scopeStack,\n collectFunctionBindings(node, imported),\n ],\n }\n\n visit(node.body, functionCtx)\n return\n }\n\n if (t.isBlockStatement(node)) {\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: [...ctx.scopeStack, collectBlockBindings(node, imported)],\n }\n for (const child of node.body) {\n visit(child, nextCtx)\n }\n return\n }\n\n if (t.isCatchClause(node)) {\n const bindings = new Set<string>()\n if (node.param) {\n addPatternBindingsIfTracked(node.param as t.LVal, imported, bindings)\n }\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: bindings.size\n ? [...ctx.scopeStack, bindings]\n : ctx.scopeStack,\n }\n visit(node.body, nextCtx)\n return\n }\n\n if (\n t.isForStatement(node) &&\n t.isVariableDeclaration(node.init) &&\n node.init.kind !== 'var'\n ) {\n const bindings = new Set<string>()\n for (const decl of node.init.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, imported, bindings)\n }\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: bindings.size\n ? [...ctx.scopeStack, bindings]\n : ctx.scopeStack,\n }\n visit(node.init, nextCtx)\n if (node.test) visit(node.test, nextCtx)\n if (node.update) visit(node.update, nextCtx)\n visit(node.body, nextCtx)\n return\n }\n\n if (\n (t.isForInStatement(node) || t.isForOfStatement(node)) &&\n t.isVariableDeclaration(node.left) &&\n node.left.kind !== 'var'\n ) {\n const bindings = new Set<string>()\n for (const decl of node.left.declarations) {\n addPatternBindingsIfTracked(decl.id as t.LVal, imported, bindings)\n }\n const nextCtx = {\n parents: [...ctx.parents, node],\n scopeStack: bindings.size\n ? [...ctx.scopeStack, bindings]\n : ctx.scopeStack,\n }\n visit(node.left, nextCtx)\n visit(node.right, nextCtx)\n visit(node.body, nextCtx)\n return\n }\n\n const nextParents = [...ctx.parents, node]\n\n if (t.isIdentifier(node)) {\n const parent = ctx.parents[ctx.parents.length - 1]\n if (imported.has(node.name)) {\n if (!isBindingIdentifierInParent(node, parent)) {\n if (\n !(\n t.isObjectProperty(parent) &&\n parent.key === node &&\n !parent.computed &&\n !parent.shorthand\n ) &&\n !(\n t.isObjectMethod(parent) &&\n parent.key === node &&\n !parent.computed\n ) &&\n !(t.isExportSpecifier(parent) && parent.exported === node) &&\n !isShadowedByScope(node.name, ctx.scopeStack) &&\n !(\n envType && isInsideCompilerSafeBoundaryNodes(ctx.parents, envType)\n )\n ) {\n const loc = node.loc?.start\n if (loc) {\n const pos: UsagePos = { line: loc.line, column0: loc.column }\n const isPreferred =\n (t.isCallExpression(parent) && parent.callee === node) ||\n (t.isNewExpression(parent) && parent.callee === node) ||\n ((t.isMemberExpression(parent) ||\n t.isOptionalMemberExpression(parent)) &&\n parent.object === node)\n\n if (isPreferred) {\n preferred ||= pos\n } else {\n anyUsage ||= pos\n }\n }\n }\n }\n }\n }\n\n if (t.isImportDeclaration(node)) {\n return\n }\n\n const keys = t.VISITOR_KEYS[node.type]\n if (!keys) return\n for (const key of keys) {\n const child = (node as unknown as Record<string, unknown>)[key]\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === 'object' && 'type' in item) {\n visit(item as t.Node, {\n parents: nextParents,\n scopeStack: ctx.scopeStack,\n })\n }\n }\n } else if (child && typeof child === 'object' && 'type' in child) {\n visit(child as t.Node, {\n parents: nextParents,\n scopeStack: ctx.scopeStack,\n })\n }\n }\n }\n\n visit(analysis.ast.program, {\n parents: [],\n scopeStack: [],\n })\n\n const pos = preferred ?? anyUsage ?? null\n analysis.usageByKey.set(cacheKey, pos)\n return pos ?? undefined\n}\n\nexport function findPostCompileUsagePosFromResult(\n result: TransformResult,\n source: string,\n): UsagePos | undefined {\n return findUsagePosInAnalysis(result, source)\n}\n\nexport function findPostCompileUsagePos(\n code: string,\n source: string,\n): UsagePos | undefined {\n return findPostCompileUsagePosFromResult(makeTransientResult(code), source)\n}\n\nexport function findOriginalUnsafeUsagePosFromResult(\n result: TransformResult,\n source: string,\n envType: BoundaryEnv,\n): UsagePos | undefined {\n return findUsagePosInAnalysis(result, source, envType)\n}\n\nexport function findOriginalUnsafeUsagePos(\n code: string,\n source: string,\n envType: BoundaryEnv,\n): UsagePos | undefined {\n return findOriginalUnsafeUsagePosFromResult(\n makeTransientResult(code),\n source,\n envType,\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/start-compiler/server-fn-resolver-module.ts
|
|
2
2
|
function getResolverManifestEntries(serverFnsById) {
|
|
3
|
-
return Object.entries(serverFnsById).map(([id, fn]) => ({
|
|
3
|
+
return Object.entries(serverFnsById).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([id, fn]) => ({
|
|
4
4
|
id,
|
|
5
5
|
functionName: fn.functionName,
|
|
6
6
|
extractedFilename: fn.extractedFilename,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-fn-resolver-module.js","names":[],"sources":["../../../src/start-compiler/server-fn-resolver-module.ts"],"sourcesContent":["import type { ServerFn } from './types'\n\ninterface ResolverManifestEntry {\n id: string\n functionName: string\n extractedFilename: string\n isClientReferenced: boolean\n}\n\ninterface GenerateServerFnResolverModuleOptions {\n serverFnsById: Record<string, ServerFn>\n includeClientReferencedCheck: boolean\n useStaticImports?: boolean\n}\n\nfunction getResolverManifestEntries(\n serverFnsById: Record<string, ServerFn>,\n): Array<ResolverManifestEntry> {\n return Object.entries(serverFnsById).map(([id, fn]) => ({\n
|
|
1
|
+
{"version":3,"file":"server-fn-resolver-module.js","names":[],"sources":["../../../src/start-compiler/server-fn-resolver-module.ts"],"sourcesContent":["import type { ServerFn } from './types'\n\ninterface ResolverManifestEntry {\n id: string\n functionName: string\n extractedFilename: string\n isClientReferenced: boolean\n}\n\ninterface GenerateServerFnResolverModuleOptions {\n serverFnsById: Record<string, ServerFn>\n includeClientReferencedCheck: boolean\n useStaticImports?: boolean\n}\n\nfunction getResolverManifestEntries(\n serverFnsById: Record<string, ServerFn>,\n): Array<ResolverManifestEntry> {\n return (\n Object.entries(serverFnsById)\n // Sort entries by ID so that the generated manifest has a stable, deterministic order.\n // Non-deterministic ordering causes the compiled hash of the same source file to change\n // between builds, breaking content-addressed caching and reproducible deployments.\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([id, fn]) => ({\n id,\n functionName: fn.functionName,\n extractedFilename: fn.extractedFilename,\n isClientReferenced: fn.isClientReferenced ?? true,\n }))\n )\n}\n\nfunction getClientReferencedCheck(\n includeClientReferencedCheck: boolean,\n): string {\n if (!includeClientReferencedCheck) {\n return ''\n }\n\n return `\n if (access.origin === 'client' && !serverFnInfo.isClientReferenced) {\n throw new Error('Server function not accessible from client: ' + id)\n }\n`\n}\n\nfunction getResolverBody(): string {\n return `\nexport async function getServerFnById(id, access) {\n const serverFnInfo = manifest[id]\n if (!serverFnInfo) {\n throw new Error('Server function info not found for ' + id)\n }\n__CLIENT_REFERENCED_CHECK__\n const fnModule = serverFnInfo.module ?? (await serverFnInfo.importer())\n if (!fnModule) {\n throw new Error('Server function module not resolved for ' + id)\n }\n const action = fnModule[serverFnInfo.functionName]\n if (!action) {\n throw new Error('Server function module export not resolved for serverFn ID: ' + id)\n }\n return action\n}\n`\n}\n\nfunction getResolverManifestModuleAccess(opts: {\n useStaticImports?: boolean\n extractedFilename: string\n moduleRef: string\n}): string {\n if (opts.useStaticImports) {\n return `module: ${opts.moduleRef}`\n }\n\n return `importer: () => import(${JSON.stringify(opts.extractedFilename)})`\n}\n\nfunction getResolverManifestEntry(opts: {\n entry: ResolverManifestEntry\n moduleAccess: string\n includeClientReferencedCheck: boolean\n}): string {\n const clientReferenced = opts.includeClientReferencedCheck\n ? `,\\n isClientReferenced: ${opts.entry.isClientReferenced}`\n : ''\n\n return `'${opts.entry.id}': {\n functionName: '${opts.entry.functionName}',\n ${opts.moduleAccess}${clientReferenced}\n }`\n}\n\nexport function generateServerFnResolverModule(\n opts: GenerateServerFnResolverModuleOptions,\n): string {\n const manifestEntries = getResolverManifestEntries(opts.serverFnsById)\n const staticImports: Array<string> = []\n\n const manifest = manifestEntries\n .map((entry, index) => {\n const moduleRef = `serverFnModule${index}`\n\n if (opts.useStaticImports) {\n staticImports.push(\n `import * as ${moduleRef} from ${JSON.stringify(entry.extractedFilename)}`,\n )\n }\n\n return getResolverManifestEntry({\n entry,\n moduleAccess: getResolverManifestModuleAccess({\n useStaticImports: opts.useStaticImports,\n extractedFilename: entry.extractedFilename,\n moduleRef,\n }),\n includeClientReferencedCheck: opts.includeClientReferencedCheck,\n })\n })\n .join(',\\n ')\n\n const body = getResolverBody().replace(\n '__CLIENT_REFERENCED_CHECK__',\n getClientReferencedCheck(opts.includeClientReferencedCheck),\n )\n\n return `\n${staticImports.join('\\n')}\nconst manifest = {\n ${manifest}\n}\n${body}\n`\n}\n"],"mappings":";AAeA,SAAS,2BACP,eAC8B;AAC9B,QACE,OAAO,QAAQ,cAAc,CAI1B,MAAM,CAAC,IAAI,CAAC,OAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,EAAG,CAChD,KAAK,CAAC,IAAI,SAAS;EAClB;EACA,cAAc,GAAG;EACjB,mBAAmB,GAAG;EACtB,oBAAoB,GAAG,sBAAsB;EAC9C,EAAE;;AAIT,SAAS,yBACP,8BACQ;AACR,KAAI,CAAC,6BACH,QAAO;AAGT,QAAO;;;;;;AAOT,SAAS,kBAA0B;AACjC,QAAO;;;;;;;;;;;;;;;;;;;AAoBT,SAAS,gCAAgC,MAI9B;AACT,KAAI,KAAK,iBACP,QAAO,WAAW,KAAK;AAGzB,QAAO,0BAA0B,KAAK,UAAU,KAAK,kBAAkB,CAAC;;AAG1E,SAAS,yBAAyB,MAIvB;CACT,MAAM,mBAAmB,KAAK,+BAC1B,8BAA8B,KAAK,MAAM,uBACzC;AAEJ,QAAO,IAAI,KAAK,MAAM,GAAG;qBACN,KAAK,MAAM,aAAa;MACvC,KAAK,eAAe,iBAAiB;;;AAI3C,SAAgB,+BACd,MACQ;CACR,MAAM,kBAAkB,2BAA2B,KAAK,cAAc;CACtE,MAAM,gBAA+B,EAAE;CAEvC,MAAM,WAAW,gBACd,KAAK,OAAO,UAAU;EACrB,MAAM,YAAY,iBAAiB;AAEnC,MAAI,KAAK,iBACP,eAAc,KACZ,eAAe,UAAU,QAAQ,KAAK,UAAU,MAAM,kBAAkB,GACzE;AAGH,SAAO,yBAAyB;GAC9B;GACA,cAAc,gCAAgC;IAC5C,kBAAkB,KAAK;IACvB,mBAAmB,MAAM;IACzB;IACD,CAAC;GACF,8BAA8B,KAAK;GACpC,CAAC;GACF,CACD,KAAK,QAAQ;CAEhB,MAAM,OAAO,iBAAiB,CAAC,QAC7B,+BACA,yBAAyB,KAAK,6BAA6B,CAC5D;AAED,QAAO;EACP,cAAc,KAAK,KAAK,CAAC;;IAEvB,SAAS;;EAEX,KAAK"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.169.
|
|
3
|
+
"version": "1.169.10",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -86,9 +86,9 @@
|
|
|
86
86
|
"vitefu": "^1.1.1",
|
|
87
87
|
"xmlbuilder2": "^4.0.3",
|
|
88
88
|
"zod": "^3.24.2",
|
|
89
|
-
"@tanstack/router-core": "1.169.0",
|
|
90
89
|
"@tanstack/router-generator": "1.166.38",
|
|
91
90
|
"@tanstack/router-plugin": "1.167.30",
|
|
91
|
+
"@tanstack/router-core": "1.169.0",
|
|
92
92
|
"@tanstack/router-utils": "1.161.7",
|
|
93
93
|
"@tanstack/start-client-core": "1.167.22",
|
|
94
94
|
"@tanstack/start-server-core": "1.167.24"
|
|
@@ -53,6 +53,30 @@ function getStringLiteralValueStart(node: t.StringLiteral): number {
|
|
|
53
53
|
return node.start
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
function isTypeOnlyImportDeclaration(node: t.ImportDeclaration): boolean {
|
|
57
|
+
if (node.importKind === 'type') return true
|
|
58
|
+
if (node.specifiers.length === 0) return false
|
|
59
|
+
|
|
60
|
+
return node.specifiers.every(
|
|
61
|
+
(specifier) =>
|
|
62
|
+
t.isImportSpecifier(specifier) && specifier.importKind === 'type',
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isTypeOnlyExportNamedDeclaration(
|
|
67
|
+
node: t.ExportNamedDeclaration,
|
|
68
|
+
): boolean {
|
|
69
|
+
if (node.exportKind === 'type') return true
|
|
70
|
+
if (!node.source || node.declaration || node.specifiers.length === 0) {
|
|
71
|
+
return false
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return node.specifiers.every(
|
|
75
|
+
(specifier) =>
|
|
76
|
+
t.isExportSpecifier(specifier) && specifier.exportKind === 'type',
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
56
80
|
function collectIdentifiersFromPattern(
|
|
57
81
|
pattern: t.LVal,
|
|
58
82
|
add: (name: string) => void,
|
|
@@ -149,8 +173,9 @@ function buildImportAnalysis(result: TransformResult): ImportAnalysis {
|
|
|
149
173
|
|
|
150
174
|
const visit = (node: t.Node): void => {
|
|
151
175
|
if (t.isImportDeclaration(node)) {
|
|
152
|
-
|
|
153
|
-
if (
|
|
176
|
+
const isTypeOnly = isTypeOnlyImportDeclaration(node)
|
|
177
|
+
if (!isTypeOnly) {
|
|
178
|
+
addSpecifierLocation(node.source)
|
|
154
179
|
const source = node.source.value
|
|
155
180
|
const bindingInfo = getBindingInfo(source)
|
|
156
181
|
for (const specifier of node.specifiers) {
|
|
@@ -177,11 +202,12 @@ function buildImportAnalysis(result: TransformResult): ImportAnalysis {
|
|
|
177
202
|
}
|
|
178
203
|
}
|
|
179
204
|
} else if (t.isExportNamedDeclaration(node)) {
|
|
180
|
-
|
|
205
|
+
const isTypeOnly = isTypeOnlyExportNamedDeclaration(node)
|
|
206
|
+
if (!isTypeOnly && node.source && t.isStringLiteral(node.source)) {
|
|
181
207
|
addSpecifierLocation(node.source)
|
|
182
208
|
}
|
|
183
209
|
|
|
184
|
-
if (
|
|
210
|
+
if (!isTypeOnly && node.source?.value) {
|
|
185
211
|
const source = node.source.value
|
|
186
212
|
for (const specifier of node.specifiers) {
|
|
187
213
|
if (!t.isExportSpecifier(specifier)) continue
|
|
@@ -190,7 +216,7 @@ function buildImportAnalysis(result: TransformResult): ImportAnalysis {
|
|
|
190
216
|
}
|
|
191
217
|
}
|
|
192
218
|
|
|
193
|
-
if (
|
|
219
|
+
if (!isTypeOnly) {
|
|
194
220
|
if (node.declaration) {
|
|
195
221
|
const decl = node.declaration
|
|
196
222
|
if (t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) {
|
|
@@ -210,7 +236,9 @@ function buildImportAnalysis(result: TransformResult): ImportAnalysis {
|
|
|
210
236
|
}
|
|
211
237
|
}
|
|
212
238
|
} else if (t.isExportAllDeclaration(node)) {
|
|
213
|
-
|
|
239
|
+
if (node.exportKind !== 'type') {
|
|
240
|
+
addSpecifierLocation(node.source)
|
|
241
|
+
}
|
|
214
242
|
} else if (t.isImportExpression(node)) {
|
|
215
243
|
if (t.isStringLiteral(node.source)) {
|
|
216
244
|
addSpecifierLocation(node.source)
|
|
@@ -16,12 +16,19 @@ interface GenerateServerFnResolverModuleOptions {
|
|
|
16
16
|
function getResolverManifestEntries(
|
|
17
17
|
serverFnsById: Record<string, ServerFn>,
|
|
18
18
|
): Array<ResolverManifestEntry> {
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
return (
|
|
20
|
+
Object.entries(serverFnsById)
|
|
21
|
+
// Sort entries by ID so that the generated manifest has a stable, deterministic order.
|
|
22
|
+
// Non-deterministic ordering causes the compiled hash of the same source file to change
|
|
23
|
+
// between builds, breaking content-addressed caching and reproducible deployments.
|
|
24
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
25
|
+
.map(([id, fn]) => ({
|
|
26
|
+
id,
|
|
27
|
+
functionName: fn.functionName,
|
|
28
|
+
extractedFilename: fn.extractedFilename,
|
|
29
|
+
isClientReferenced: fn.isClientReferenced ?? true,
|
|
30
|
+
}))
|
|
31
|
+
)
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
function getClientReferencedCheck(
|