react-doctor 0.9.1-dev.b1b62db → 0.9.2
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/cli.js +216 -74
- package/dist/index.js +213 -71
- package/dist/lsp.js +214 -72
- package/package.json +7 -6
package/dist/lsp.js
CHANGED
|
@@ -10,6 +10,7 @@ import * as Crypto from "node:crypto";
|
|
|
10
10
|
import crypto, { createHash } from "node:crypto";
|
|
11
11
|
import * as NodeChildProcess from "node:child_process";
|
|
12
12
|
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
13
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
13
14
|
import ts from "typescript";
|
|
14
15
|
import { parseJSON5 } from "confbox";
|
|
15
16
|
import * as NodeUrl from "node:url";
|
|
@@ -61845,7 +61846,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
61845
61846
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
61846
61847
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
61847
61848
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
61848
|
-
const CORE_PACKAGE_VERSION = "0.9.
|
|
61849
|
+
const CORE_PACKAGE_VERSION = "0.9.2";
|
|
61849
61850
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
61850
61851
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
61851
61852
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -62095,8 +62096,13 @@ const findMonorepoRoot = (startDirectory) => {
|
|
|
62095
62096
|
* byte-equivalent copy.
|
|
62096
62097
|
*/
|
|
62097
62098
|
const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
|
|
62099
|
+
const unwrapTypescriptExpression = (expression) => {
|
|
62100
|
+
let currentExpression = expression;
|
|
62101
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
62102
|
+
return currentExpression;
|
|
62103
|
+
};
|
|
62098
62104
|
const TSCONFIG_FILENAME = "tsconfig.json";
|
|
62099
|
-
const
|
|
62105
|
+
const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
|
|
62100
62106
|
const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
|
|
62101
62107
|
const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
62102
62108
|
const requireFromConfig = createRequire(Path.join(fromConfigDirectory, "tsconfig.json"));
|
|
@@ -62113,7 +62119,12 @@ const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
|
62113
62119
|
return null;
|
|
62114
62120
|
};
|
|
62115
62121
|
const resolveExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
62116
|
-
if (
|
|
62122
|
+
if (isLocalModuleSpecifier(extendsValue)) {
|
|
62123
|
+
const resolvedPath = Path.resolve(fromConfigDirectory, extendsValue);
|
|
62124
|
+
if (isFile(resolvedPath)) return resolvedPath;
|
|
62125
|
+
const directoryConfigPath = Path.join(resolvedPath, TSCONFIG_FILENAME);
|
|
62126
|
+
return isFile(directoryConfigPath) ? directoryConfigPath : ensureJsonExtension(resolvedPath);
|
|
62127
|
+
}
|
|
62117
62128
|
return resolvePackageExtendsPath(extendsValue, fromConfigDirectory);
|
|
62118
62129
|
};
|
|
62119
62130
|
const normalizeCompilerOptions = (compilerOptions) => {
|
|
@@ -62307,6 +62318,15 @@ const REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS = [
|
|
|
62307
62318
|
".cts",
|
|
62308
62319
|
".json"
|
|
62309
62320
|
];
|
|
62321
|
+
const REACT_COMPILER_CONFIG_RESOLVER = new ResolverFactory({
|
|
62322
|
+
conditionNames: [
|
|
62323
|
+
"import",
|
|
62324
|
+
"require",
|
|
62325
|
+
"node",
|
|
62326
|
+
"default"
|
|
62327
|
+
],
|
|
62328
|
+
extensions: REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS
|
|
62329
|
+
});
|
|
62310
62330
|
const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
|
|
62311
62331
|
const hasCompilerPackage = (packageJson, compilerPackages) => {
|
|
62312
62332
|
const allDependencies = {
|
|
@@ -62330,6 +62350,18 @@ const hasCompilerPackageInAncestors = (directory, compilerPackages) => {
|
|
|
62330
62350
|
return false;
|
|
62331
62351
|
};
|
|
62332
62352
|
const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
62353
|
+
if (!isLocalModuleSpecifier(moduleSpecifier)) {
|
|
62354
|
+
try {
|
|
62355
|
+
const resolvedPath = REACT_COMPILER_CONFIG_RESOLVER.resolveFileSync(fromFilePath, moduleSpecifier).path;
|
|
62356
|
+
if (resolvedPath && isFile(resolvedPath)) return resolvedPath;
|
|
62357
|
+
} catch {}
|
|
62358
|
+
try {
|
|
62359
|
+
const resolvedPath = createRequire(fromFilePath).resolve(moduleSpecifier);
|
|
62360
|
+
return isFile(resolvedPath) ? resolvedPath : null;
|
|
62361
|
+
} catch {
|
|
62362
|
+
return null;
|
|
62363
|
+
}
|
|
62364
|
+
}
|
|
62333
62365
|
const unresolvedPath = Path.resolve(Path.dirname(fromFilePath), moduleSpecifier);
|
|
62334
62366
|
const extension = Path.extname(unresolvedPath);
|
|
62335
62367
|
return (extension ? [unresolvedPath, ...REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS.map((sourceExtension) => `${unresolvedPath.slice(0, -extension.length)}${sourceExtension}`)] : [
|
|
@@ -62355,7 +62387,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
62355
62387
|
const namedBindings = importClause?.namedBindings;
|
|
62356
62388
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
62357
62389
|
}
|
|
62358
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
62390
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
62359
62391
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
62360
62392
|
});
|
|
62361
62393
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -62456,6 +62488,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
62456
62488
|
};
|
|
62457
62489
|
};
|
|
62458
62490
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
62491
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
62492
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
62493
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
62494
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
62495
|
+
if (!ts.isCallExpression(node)) return false;
|
|
62496
|
+
const target = node.expression;
|
|
62497
|
+
if (ts.isIdentifier(target)) {
|
|
62498
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
62499
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
62500
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
62501
|
+
}
|
|
62502
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
62503
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
62504
|
+
const createRequireReceiver = target.expression;
|
|
62505
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
62506
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
62507
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
62508
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
62509
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
62510
|
+
}
|
|
62511
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
62512
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
62513
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
62514
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
62515
|
+
};
|
|
62516
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
62517
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
62518
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
62519
|
+
const target = callExpression.expression;
|
|
62520
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62521
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
62522
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
62523
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
62524
|
+
const resolverIdentifier = target.expression;
|
|
62525
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
62526
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
62527
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
62528
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
62529
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
62530
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
62531
|
+
return moduleSpecifierNode.text;
|
|
62532
|
+
};
|
|
62459
62533
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
62460
62534
|
let bindingScope = null;
|
|
62461
62535
|
let currentNode = identifier;
|
|
@@ -62498,9 +62572,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
|
62498
62572
|
initializer: assignedInitializer
|
|
62499
62573
|
};
|
|
62500
62574
|
};
|
|
62501
|
-
const getStaticConfigValueState = (expression, analysis) => {
|
|
62502
|
-
|
|
62503
|
-
|
|
62575
|
+
const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
62576
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
62577
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
62578
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
62579
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
62504
62580
|
if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
|
|
62505
62581
|
isNullish: true,
|
|
62506
62582
|
isTruthy: false
|
|
@@ -62516,31 +62592,31 @@ const getStaticConfigValueState = (expression, analysis) => {
|
|
|
62516
62592
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
62517
62593
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
62518
62594
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
62519
|
-
return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
|
|
62595
|
+
return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
62520
62596
|
}
|
|
62521
62597
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
62522
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
|
|
62598
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
62523
62599
|
}
|
|
62524
62600
|
if (ts.isConditionalExpression(unwrappedExpression)) {
|
|
62525
|
-
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
|
|
62526
|
-
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
|
|
62527
|
-
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
|
|
62528
|
-
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
|
|
62601
|
+
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
|
|
62602
|
+
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
62603
|
+
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
|
|
62604
|
+
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
62529
62605
|
return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
|
|
62530
62606
|
}
|
|
62531
62607
|
if (ts.isBinaryExpression(unwrappedExpression)) {
|
|
62532
|
-
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
|
|
62608
|
+
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
|
|
62533
62609
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
62534
62610
|
if (leftState === null) return null;
|
|
62535
|
-
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
62611
|
+
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
62536
62612
|
}
|
|
62537
62613
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
62538
62614
|
if (leftState === null) return null;
|
|
62539
|
-
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
|
|
62615
|
+
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
|
|
62540
62616
|
}
|
|
62541
62617
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
62542
62618
|
if (leftState === null) return null;
|
|
62543
|
-
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
62619
|
+
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
62544
62620
|
}
|
|
62545
62621
|
}
|
|
62546
62622
|
return null;
|
|
@@ -62549,25 +62625,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
|
|
|
62549
62625
|
const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
|
|
62550
62626
|
const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
|
|
62551
62627
|
const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
|
|
62552
|
-
const getReactCompilerFlagState = (expression, analysis) => {
|
|
62553
|
-
|
|
62554
|
-
|
|
62628
|
+
const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
62629
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
62630
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
62631
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
62632
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
62555
62633
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
62556
62634
|
const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
|
|
62557
62635
|
if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
|
|
62558
62636
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
62559
62637
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
62560
|
-
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
|
|
62638
|
+
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
62561
62639
|
}
|
|
62562
62640
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
62563
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
|
|
62641
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
62564
62642
|
}
|
|
62565
62643
|
if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
|
|
62566
62644
|
for (const property of [...unwrappedExpression.properties].reverse()) {
|
|
62567
62645
|
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
|
|
62568
62646
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
|
|
62569
62647
|
if (ts.isSpreadAssignment(property)) {
|
|
62570
|
-
const spreadState = getReactCompilerFlagState(property.expression, analysis);
|
|
62648
|
+
const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
|
|
62571
62649
|
if (spreadState) return spreadState;
|
|
62572
62650
|
}
|
|
62573
62651
|
}
|
|
@@ -62739,6 +62817,11 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
|
|
|
62739
62817
|
visitReturns(functionNode.body);
|
|
62740
62818
|
return hasCompiler;
|
|
62741
62819
|
};
|
|
62820
|
+
const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
|
|
62821
|
+
const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
|
|
62822
|
+
if (!importedFilePath) return null;
|
|
62823
|
+
return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList);
|
|
62824
|
+
};
|
|
62742
62825
|
const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
|
|
62743
62826
|
const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
|
|
62744
62827
|
if (assignedReactCompiler.initializer && !isStaticallyDisabledConfigExpression(assignedReactCompiler.initializer, analysis)) return true;
|
|
@@ -62759,30 +62842,62 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
|
|
|
62759
62842
|
const importBinding = getImportBinding(analysis.sourceFile, identifier.text);
|
|
62760
62843
|
if (importBinding) {
|
|
62761
62844
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
62762
|
-
|
|
62763
|
-
|
|
62764
|
-
|
|
62845
|
+
return Boolean(analyzeImportedConfig({
|
|
62846
|
+
analysis,
|
|
62847
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62848
|
+
exportName: importBinding.exportName,
|
|
62849
|
+
allowCompilerTransform
|
|
62850
|
+
}));
|
|
62765
62851
|
}
|
|
62766
62852
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, identifier.text);
|
|
62767
62853
|
return Boolean(topLevelBinding && analyzeConfigNode(topLevelBinding, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
|
|
62768
62854
|
};
|
|
62769
62855
|
const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransform) => {
|
|
62770
62856
|
const target = callExpression.expression;
|
|
62857
|
+
const callableRequiredModuleSpecifier = getRequireModuleSpecifier$1(target);
|
|
62858
|
+
if (callableRequiredModuleSpecifier !== null) {
|
|
62859
|
+
if (ts.isCallExpression(target) && ts.isIdentifier(target.expression) && (analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62860
|
+
if (allowCompilerTransform && isCompilerTransformModule(callableRequiredModuleSpecifier, "default")) return true;
|
|
62861
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62862
|
+
analysis,
|
|
62863
|
+
moduleSpecifier: callableRequiredModuleSpecifier,
|
|
62864
|
+
exportName: "default",
|
|
62865
|
+
allowCompilerTransform,
|
|
62866
|
+
argumentsList: callExpression.arguments
|
|
62867
|
+
});
|
|
62868
|
+
if (isLocalModuleSpecifier(callableRequiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62869
|
+
return null;
|
|
62870
|
+
}
|
|
62771
62871
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62772
62872
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
62773
62873
|
if (propertyName === null) return null;
|
|
62774
62874
|
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
62775
62875
|
if (requiredModuleSpecifier !== null) {
|
|
62776
|
-
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62777
|
-
if (
|
|
62778
|
-
const
|
|
62779
|
-
|
|
62876
|
+
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (analysis.localBindings.has(target.expression.expression.text) || getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62877
|
+
if (allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, propertyName)) return true;
|
|
62878
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62879
|
+
analysis,
|
|
62880
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
62881
|
+
exportName: propertyName,
|
|
62882
|
+
allowCompilerTransform,
|
|
62883
|
+
argumentsList: callExpression.arguments
|
|
62884
|
+
});
|
|
62885
|
+
if (isLocalModuleSpecifier(requiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62886
|
+
return null;
|
|
62780
62887
|
}
|
|
62781
62888
|
if (!ts.isIdentifier(target.expression)) return null;
|
|
62782
|
-
const importBinding = getImportBinding(analysis.sourceFile, target.expression.text);
|
|
62783
|
-
if (importBinding?.isNamespace
|
|
62784
|
-
|
|
62785
|
-
|
|
62889
|
+
const importBinding = analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound ? null : getImportBinding(analysis.sourceFile, target.expression.text);
|
|
62890
|
+
if (importBinding?.isNamespace) {
|
|
62891
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, propertyName)) return true;
|
|
62892
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62893
|
+
analysis,
|
|
62894
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62895
|
+
exportName: propertyName,
|
|
62896
|
+
allowCompilerTransform,
|
|
62897
|
+
argumentsList: callExpression.arguments
|
|
62898
|
+
});
|
|
62899
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62900
|
+
return null;
|
|
62786
62901
|
}
|
|
62787
62902
|
const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
|
|
62788
62903
|
if (selectedProperty === null) return null;
|
|
@@ -62805,9 +62920,13 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62805
62920
|
if (propertyName === "reactCompiler") continue;
|
|
62806
62921
|
if ((propertyName === "plugins" || propertyName === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, propertyName, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === propertyName)) continue;
|
|
62807
62922
|
const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
|
|
62808
|
-
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)
|
|
62809
|
-
|
|
62810
|
-
|
|
62923
|
+
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)) {
|
|
62924
|
+
if (analyzeImportedConfig({
|
|
62925
|
+
analysis,
|
|
62926
|
+
moduleSpecifier: property.initializer.text,
|
|
62927
|
+
exportName: "default",
|
|
62928
|
+
allowCompilerTransform: false
|
|
62929
|
+
})) return true;
|
|
62811
62930
|
}
|
|
62812
62931
|
if (analyzeConfigNode(property.initializer, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
62813
62932
|
} else if (ts.isShorthandPropertyAssignment(property)) {
|
|
@@ -62831,6 +62950,8 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62831
62950
|
});
|
|
62832
62951
|
}
|
|
62833
62952
|
if (ts.isCallExpression(node)) {
|
|
62953
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
62954
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
62834
62955
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
62835
62956
|
if (callTargetResult !== null) return callTargetResult;
|
|
62836
62957
|
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
@@ -62838,16 +62959,27 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62838
62959
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
62839
62960
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
62840
62961
|
if (allowCompilerTransform && isCompilerTransformModule(directModuleSpecifier, "default")) return true;
|
|
62841
|
-
if (
|
|
62842
|
-
|
|
62843
|
-
|
|
62844
|
-
|
|
62962
|
+
if (analyzeImportedConfig({
|
|
62963
|
+
analysis,
|
|
62964
|
+
moduleSpecifier: directModuleSpecifier,
|
|
62965
|
+
exportName: "default",
|
|
62966
|
+
allowCompilerTransform
|
|
62967
|
+
})) return true;
|
|
62845
62968
|
}
|
|
62846
62969
|
if (ts.isIdentifier(node.expression)) {
|
|
62847
|
-
|
|
62848
|
-
|
|
62849
|
-
|
|
62850
|
-
|
|
62970
|
+
if (!analysis.localBindings.has(node.expression.text) && !getScopedConfigBinding(node.expression).wasFound) {
|
|
62971
|
+
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62972
|
+
if (importBinding) {
|
|
62973
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
62974
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62975
|
+
analysis,
|
|
62976
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62977
|
+
exportName: importBinding.exportName,
|
|
62978
|
+
allowCompilerTransform,
|
|
62979
|
+
argumentsList: node.arguments
|
|
62980
|
+
});
|
|
62981
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62982
|
+
}
|
|
62851
62983
|
}
|
|
62852
62984
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, node.expression.text);
|
|
62853
62985
|
if (topLevelBinding && ts.isFunctionLike(topLevelBinding) && analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, node.arguments)) return true;
|
|
@@ -62857,25 +62989,29 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62857
62989
|
if (ts.isPropertyAccessExpression(node)) {
|
|
62858
62990
|
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
62859
62991
|
if (requiredModuleSpecifier) {
|
|
62860
|
-
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62861
|
-
if (
|
|
62862
|
-
|
|
62863
|
-
|
|
62864
|
-
|
|
62992
|
+
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (analysis.localBindings.has(node.expression.expression.text) || getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62993
|
+
if (analyzeImportedConfig({
|
|
62994
|
+
analysis,
|
|
62995
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
62996
|
+
exportName: node.name.text,
|
|
62997
|
+
allowCompilerTransform
|
|
62998
|
+
})) return true;
|
|
62865
62999
|
return allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, node.name.text);
|
|
62866
63000
|
}
|
|
62867
63001
|
if (ts.isIdentifier(node.expression)) {
|
|
62868
|
-
if (analysis.localBindings.has(node.expression.text)) {
|
|
62869
|
-
const
|
|
62870
|
-
return Boolean(
|
|
63002
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
63003
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
63004
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
62871
63005
|
}
|
|
62872
63006
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62873
63007
|
if (importBinding?.isNamespace) {
|
|
62874
63008
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.name.text)) return true;
|
|
62875
|
-
if (
|
|
62876
|
-
|
|
62877
|
-
|
|
62878
|
-
|
|
63009
|
+
if (analyzeImportedConfig({
|
|
63010
|
+
analysis,
|
|
63011
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
63012
|
+
exportName: node.name.text,
|
|
63013
|
+
allowCompilerTransform
|
|
63014
|
+
})) return true;
|
|
62879
63015
|
return false;
|
|
62880
63016
|
}
|
|
62881
63017
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
@@ -62886,13 +63022,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62886
63022
|
}
|
|
62887
63023
|
if (ts.isElementAccessExpression(node) && node.argumentExpression && ts.isStringLiteralLike(node.argumentExpression)) {
|
|
62888
63024
|
if (ts.isIdentifier(node.expression)) {
|
|
63025
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
63026
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
63027
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
63028
|
+
}
|
|
62889
63029
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62890
63030
|
if (importBinding?.isNamespace) {
|
|
62891
63031
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.argumentExpression.text)) return true;
|
|
62892
|
-
|
|
62893
|
-
|
|
62894
|
-
|
|
62895
|
-
|
|
63032
|
+
return Boolean(analyzeImportedConfig({
|
|
63033
|
+
analysis,
|
|
63034
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
63035
|
+
exportName: node.argumentExpression.text,
|
|
63036
|
+
allowCompilerTransform
|
|
63037
|
+
}));
|
|
62896
63038
|
}
|
|
62897
63039
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
62898
63040
|
if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
@@ -62930,14 +63072,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62930
63072
|
};
|
|
62931
63073
|
const hasCompilerInConfigFile = (filePath) => analyzeConfigModuleExport(filePath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
62932
63074
|
const hasCompilerInConfigFiles = (directory, filenames) => filenames.some((filename) => hasCompilerInConfigFile(Path.join(directory, filename)));
|
|
62933
|
-
const hasCompilerInPackageJsonConfig = (
|
|
62934
|
-
|
|
63075
|
+
const hasCompilerInPackageJsonConfig = (directory, packageJson) => {
|
|
63076
|
+
if (!isPlainObject(packageJson.babel)) return false;
|
|
63077
|
+
const packageJsonPath = Path.join(directory, "package.json");
|
|
63078
|
+
return analyzeConfigSourceFileExport(ts.parseJsonText(packageJsonPath, JSON.stringify(packageJson.babel)), packageJsonPath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
63079
|
+
};
|
|
63080
|
+
const hasCompilerConfiguration = (directory, packageJson) => hasCompilerInPackageJsonConfig(directory, packageJson) || hasCompilerInConfigFiles(directory, REACT_COMPILER_CONFIG_FILENAMES);
|
|
62935
63081
|
const hasCompilerConfigurationInAncestors = (directory) => {
|
|
62936
63082
|
if (isProjectBoundary(directory)) return false;
|
|
62937
63083
|
let ancestorDirectory = Path.dirname(directory);
|
|
62938
63084
|
while (ancestorDirectory !== Path.dirname(ancestorDirectory)) {
|
|
62939
63085
|
const ancestorPackagePath = Path.join(ancestorDirectory, "package.json");
|
|
62940
|
-
|
|
63086
|
+
const ancestorPackageJson = isFile(ancestorPackagePath) ? readPackageJson(ancestorPackagePath) : {};
|
|
63087
|
+
if (hasCompilerInPackageJsonConfig(ancestorDirectory, ancestorPackageJson) || hasCompilerInConfigFiles(ancestorDirectory, BABEL_CONFIG_FILENAMES)) return true;
|
|
62941
63088
|
if (isProjectBoundary(ancestorDirectory)) return false;
|
|
62942
63089
|
ancestorDirectory = Path.dirname(ancestorDirectory);
|
|
62943
63090
|
}
|
|
@@ -67121,11 +67268,6 @@ const getTypescriptScriptKind = (fileName) => {
|
|
|
67121
67268
|
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67122
67269
|
return ts.ScriptKind.JS;
|
|
67123
67270
|
};
|
|
67124
|
-
const unwrapTypescriptExpression = (expression) => {
|
|
67125
|
-
let currentExpression = expression;
|
|
67126
|
-
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
67127
|
-
return currentExpression;
|
|
67128
|
-
};
|
|
67129
67271
|
const BABEL_CONFIG_FILE_NAMES$1 = [
|
|
67130
67272
|
"babel.config.js",
|
|
67131
67273
|
"babel.config.cjs",
|
|
@@ -74341,7 +74483,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
|
|
|
74341
74483
|
/** Display name used in client-facing messages and progress titles. */
|
|
74342
74484
|
const SERVER_DISPLAY_NAME = "React Doctor";
|
|
74343
74485
|
/** Server version reported in `serverInfo`; injected at build, `dev` from source. */
|
|
74344
|
-
const SERVER_VERSION = "0.9.
|
|
74486
|
+
const SERVER_VERSION = "0.9.2";
|
|
74345
74487
|
/** `Diagnostic.source` shown next to every published diagnostic. */
|
|
74346
74488
|
const DIAGNOSTIC_SOURCE = "react-doctor";
|
|
74347
74489
|
/**
|
|
@@ -76372,5 +76514,5 @@ const startLanguageServer = () => {
|
|
|
76372
76514
|
};
|
|
76373
76515
|
//#endregion
|
|
76374
76516
|
export { startLanguageServer };
|
|
76375
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
76376
|
-
//# debugId=
|
|
76517
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c691162a-94f2-58c6-9397-fab6dbaa4d44")}catch(e){}}();
|
|
76518
|
+
//# debugId=c691162a-94f2-58c6-9397-fab6dbaa4d44
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"ink-spinner": "^5.0.0",
|
|
62
62
|
"jiti": "^2.7.0",
|
|
63
63
|
"magicast": "^0.5.3",
|
|
64
|
+
"oxc-resolver": "^11.24.2",
|
|
64
65
|
"oxlint": ">=1.74.0 <1.75.0",
|
|
65
66
|
"prompts": "^2.4.2",
|
|
66
67
|
"react": "19.2.5",
|
|
@@ -69,8 +70,8 @@
|
|
|
69
70
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
70
71
|
"vscode-uri": "^3.1.0",
|
|
71
72
|
"yaml": "^2.9.0",
|
|
72
|
-
"deslop-js": "0.9.
|
|
73
|
-
"oxlint-plugin-react-doctor": "0.9.
|
|
73
|
+
"deslop-js": "0.9.2",
|
|
74
|
+
"oxlint-plugin-react-doctor": "0.9.2"
|
|
74
75
|
},
|
|
75
76
|
"devDependencies": {
|
|
76
77
|
"@types/babel__code-frame": "^7.27.0",
|
|
@@ -80,9 +81,9 @@
|
|
|
80
81
|
"commander": "^14.0.3",
|
|
81
82
|
"ink-testing-library": "^4.0.0",
|
|
82
83
|
"ora": "^9.4.0",
|
|
83
|
-
"@react-doctor/api": "0.9.
|
|
84
|
-
"@react-doctor/
|
|
85
|
-
"@react-doctor/
|
|
84
|
+
"@react-doctor/api": "0.9.2",
|
|
85
|
+
"@react-doctor/core": "0.9.2",
|
|
86
|
+
"@react-doctor/language-server": "0.9.2"
|
|
86
87
|
},
|
|
87
88
|
"engines": {
|
|
88
89
|
"node": "^20.19.0 || >=22.13.0"
|