react-doctor 0.9.1-dev.54ba416 → 0.9.1-dev.7ee59d3
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/README.md +2 -0
- package/dist/cli.js +995 -84
- package/dist/index.d.ts +2 -2
- package/dist/index.js +989 -79
- package/dist/lsp.js +991 -80
- package/package.json +5 -5
package/dist/lsp.js
CHANGED
|
@@ -61478,7 +61478,8 @@ var AmbiguousProjectError = class extends Error {
|
|
|
61478
61478
|
}
|
|
61479
61479
|
};
|
|
61480
61480
|
const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
|
|
61481
|
-
const
|
|
61481
|
+
const HTML_FILE_PATTERN = /\.html$/i;
|
|
61482
|
+
const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
|
|
61482
61483
|
const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
|
|
61483
61484
|
const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
|
|
61484
61485
|
const MINIFIED_SNIFF_BYTES = 65536;
|
|
@@ -62338,10 +62339,10 @@ const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
|
62338
62339
|
]).find(isFile) ?? null;
|
|
62339
62340
|
};
|
|
62340
62341
|
const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json") || Path.basename(filePath) === ".babelrc" ? ts.parseJsonText(filePath, content) : ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
62341
|
-
const getStaticPropertyName$
|
|
62342
|
+
const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
|
|
62342
62343
|
const isCommonJsConfigExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
|
|
62343
62344
|
const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
|
|
62344
|
-
const getRequireModuleSpecifier = (expression) => {
|
|
62345
|
+
const getRequireModuleSpecifier$1 = (expression) => {
|
|
62345
62346
|
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
|
|
62346
62347
|
const moduleSpecifier = expression.arguments[0];
|
|
62347
62348
|
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
@@ -62354,7 +62355,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
62354
62355
|
const namedBindings = importClause?.namedBindings;
|
|
62355
62356
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
62356
62357
|
}
|
|
62357
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
62358
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
62358
62359
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
62359
62360
|
});
|
|
62360
62361
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -62385,24 +62386,24 @@ const getImportBinding = (sourceFile, bindingName) => {
|
|
|
62385
62386
|
for (const declaration of statement.declarationList.declarations) {
|
|
62386
62387
|
if (!declaration.initializer) continue;
|
|
62387
62388
|
if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
|
|
62388
|
-
const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62389
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62389
62390
|
if (directModuleSpecifier) return {
|
|
62390
62391
|
moduleSpecifier: directModuleSpecifier,
|
|
62391
62392
|
exportName: "default",
|
|
62392
62393
|
isNamespace: true
|
|
62393
62394
|
};
|
|
62394
|
-
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
|
|
62395
|
-
moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
|
|
62395
|
+
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
|
|
62396
|
+
moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
|
|
62396
62397
|
exportName: declaration.initializer.name.text,
|
|
62397
62398
|
isNamespace: false
|
|
62398
62399
|
};
|
|
62399
62400
|
}
|
|
62400
62401
|
if (!ts.isObjectBindingPattern(declaration.name)) continue;
|
|
62401
62402
|
const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
|
|
62402
|
-
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62403
|
+
const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62403
62404
|
if (bindingElement && moduleSpecifier) return {
|
|
62404
62405
|
moduleSpecifier,
|
|
62405
|
-
exportName: bindingElement.propertyName ? getStaticPropertyName$
|
|
62406
|
+
exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
|
|
62406
62407
|
isNamespace: false
|
|
62407
62408
|
};
|
|
62408
62409
|
}
|
|
@@ -62455,6 +62456,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
62455
62456
|
};
|
|
62456
62457
|
};
|
|
62457
62458
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
62459
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
62460
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
62461
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
62462
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
62463
|
+
if (!ts.isCallExpression(node)) return false;
|
|
62464
|
+
const target = node.expression;
|
|
62465
|
+
if (ts.isIdentifier(target)) {
|
|
62466
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
62467
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
62468
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
62469
|
+
}
|
|
62470
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
62471
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
62472
|
+
const createRequireReceiver = target.expression;
|
|
62473
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
62474
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
62475
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
62476
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
62477
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
62478
|
+
}
|
|
62479
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
62480
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
62481
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
62482
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
62483
|
+
};
|
|
62484
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
62485
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
62486
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
62487
|
+
const target = callExpression.expression;
|
|
62488
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62489
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
62490
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
62491
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
62492
|
+
const resolverIdentifier = target.expression;
|
|
62493
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
62494
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
62495
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
62496
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
62497
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
62498
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
62499
|
+
return moduleSpecifierNode.text;
|
|
62500
|
+
};
|
|
62458
62501
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
62459
62502
|
let bindingScope = null;
|
|
62460
62503
|
let currentNode = identifier;
|
|
@@ -62563,7 +62606,7 @@ const getReactCompilerFlagState = (expression, analysis) => {
|
|
|
62563
62606
|
}
|
|
62564
62607
|
if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
|
|
62565
62608
|
for (const property of [...unwrappedExpression.properties].reverse()) {
|
|
62566
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62609
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
|
|
62567
62610
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
|
|
62568
62611
|
if (ts.isSpreadAssignment(property)) {
|
|
62569
62612
|
const spreadState = getReactCompilerFlagState(property.expression, analysis);
|
|
@@ -62589,8 +62632,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
|
|
|
62589
62632
|
}
|
|
62590
62633
|
if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
|
|
62591
62634
|
for (const property of [...resolvedExpression.properties].reverse()) {
|
|
62592
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62593
|
-
if (ts.isMethodDeclaration(property) && getStaticPropertyName$
|
|
62635
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return property.initializer;
|
|
62636
|
+
if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return property;
|
|
62594
62637
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
|
|
62595
62638
|
if (ts.isSpreadAssignment(property)) {
|
|
62596
62639
|
const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
|
|
@@ -62621,7 +62664,7 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
|
|
|
62621
62664
|
return resolvedExpression.properties.some((property) => {
|
|
62622
62665
|
if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
|
|
62623
62666
|
if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
|
|
62624
|
-
const staticPropertyName = getStaticPropertyName$
|
|
62667
|
+
const staticPropertyName = getStaticPropertyName$2(property.name);
|
|
62625
62668
|
return staticPropertyName === null || staticPropertyName === propertyName;
|
|
62626
62669
|
}
|
|
62627
62670
|
return false;
|
|
@@ -62640,7 +62683,7 @@ const getExportedConfigNodes = (sourceFile, exportName) => {
|
|
|
62640
62683
|
continue;
|
|
62641
62684
|
}
|
|
62642
62685
|
if (ts.isExpressionStatement(statement) && isCommonJsConfigExportAssignment(statement.expression, sourceFile) && exportName !== "default" && ts.isObjectLiteralExpression(statement.expression.right)) for (const property of [...statement.expression.right.properties].reverse()) {
|
|
62643
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62686
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === exportName) {
|
|
62644
62687
|
exportedNodes.push(property.initializer);
|
|
62645
62688
|
break;
|
|
62646
62689
|
}
|
|
@@ -62770,7 +62813,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
|
|
|
62770
62813
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62771
62814
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
62772
62815
|
if (propertyName === null) return null;
|
|
62773
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
|
|
62816
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
62774
62817
|
if (requiredModuleSpecifier !== null) {
|
|
62775
62818
|
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62776
62819
|
if (!requiredModuleSpecifier.startsWith(".")) return null;
|
|
@@ -62799,10 +62842,10 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62799
62842
|
const reactCompilerFlagState = excludedPropertyNames?.has("reactCompiler") ? null : getReactCompilerFlagState(node, analysis);
|
|
62800
62843
|
if (reactCompilerFlagState?.isEnabled) return true;
|
|
62801
62844
|
for (const [propertyIndex, property] of node.properties.entries()) if (ts.isPropertyAssignment(property)) {
|
|
62802
|
-
const propertyName = getStaticPropertyName$
|
|
62845
|
+
const propertyName = getStaticPropertyName$2(property.name);
|
|
62803
62846
|
if (propertyName && excludedPropertyNames?.has(propertyName)) continue;
|
|
62804
62847
|
if (propertyName === "reactCompiler") continue;
|
|
62805
|
-
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$
|
|
62848
|
+
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;
|
|
62806
62849
|
const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
|
|
62807
62850
|
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer) && property.initializer.text.startsWith(".")) {
|
|
62808
62851
|
const extendedFilePath = resolveImportedConfigFile(analysis.filePath, property.initializer.text);
|
|
@@ -62812,12 +62855,12 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62812
62855
|
} else if (ts.isShorthandPropertyAssignment(property)) {
|
|
62813
62856
|
if (excludedPropertyNames?.has(property.name.text)) continue;
|
|
62814
62857
|
if (property.name.text === "reactCompiler") continue;
|
|
62815
|
-
if ((property.name.text === "plugins" || property.name.text === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, property.name.text, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$
|
|
62858
|
+
if ((property.name.text === "plugins" || property.name.text === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, property.name.text, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === property.name.text)) continue;
|
|
62816
62859
|
const propertyAllowsCompilerTransform = property.name.text === "plugins" || property.name.text === "presets";
|
|
62817
62860
|
if (analyzeConfigNode(property.name, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
62818
62861
|
} else if (ts.isSpreadAssignment(property)) {
|
|
62819
62862
|
if (reactCompilerFlagState && getReactCompilerFlagState(property.expression, analysis) !== null) continue;
|
|
62820
|
-
if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$
|
|
62863
|
+
if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$2(laterProperty.name) === "plugins" || getStaticPropertyName$2(laterProperty.name) === "presets"))) continue;
|
|
62821
62864
|
if (analyzeConfigNode(property.expression, analysis, allowCompilerTransform, false, excludedPropertyNames)) return true;
|
|
62822
62865
|
}
|
|
62823
62866
|
return false;
|
|
@@ -62830,9 +62873,11 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62830
62873
|
});
|
|
62831
62874
|
}
|
|
62832
62875
|
if (ts.isCallExpression(node)) {
|
|
62876
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
62877
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
62833
62878
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
62834
62879
|
if (callTargetResult !== null) return callTargetResult;
|
|
62835
|
-
const directModuleSpecifier = getRequireModuleSpecifier(node);
|
|
62880
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
62836
62881
|
const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
|
|
62837
62882
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
62838
62883
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
@@ -62854,7 +62899,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62854
62899
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
|
|
62855
62900
|
}
|
|
62856
62901
|
if (ts.isPropertyAccessExpression(node)) {
|
|
62857
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
|
|
62902
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
62858
62903
|
if (requiredModuleSpecifier) {
|
|
62859
62904
|
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62860
62905
|
if (requiredModuleSpecifier.startsWith(".")) {
|
|
@@ -66165,7 +66210,7 @@ const warn = (message) => {
|
|
|
66165
66210
|
runSync(warn$1(message));
|
|
66166
66211
|
};
|
|
66167
66212
|
const CONFIG_BASENAME = "doctor.config";
|
|
66168
|
-
const CONFIG_EXTENSIONS = [
|
|
66213
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
66169
66214
|
"ts",
|
|
66170
66215
|
"mts",
|
|
66171
66216
|
"cts",
|
|
@@ -66269,7 +66314,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
66269
66314
|
};
|
|
66270
66315
|
const loadConfigFromDirectory = async (directory) => {
|
|
66271
66316
|
let sawBrokenConfigFile = false;
|
|
66272
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
66317
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
66273
66318
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
66274
66319
|
if (!isFile(filePath)) continue;
|
|
66275
66320
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -66956,6 +67001,321 @@ const buildReactNativeDiagnostic = (input) => ({
|
|
|
66956
67001
|
column: input.column ?? 0,
|
|
66957
67002
|
category: input.category ?? "Correctness"
|
|
66958
67003
|
});
|
|
67004
|
+
const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
|
|
67005
|
+
const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
|
|
67006
|
+
const RELEASE_STRING_MARKER = "__RD_RELEASE__";
|
|
67007
|
+
const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
|
|
67008
|
+
const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67009
|
+
const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67010
|
+
const stripGradleComments = (contents) => {
|
|
67011
|
+
let result = "";
|
|
67012
|
+
let index = 0;
|
|
67013
|
+
let quote = null;
|
|
67014
|
+
while (index < contents.length) {
|
|
67015
|
+
const character = contents[index];
|
|
67016
|
+
const nextCharacter = contents[index + 1];
|
|
67017
|
+
if (quote !== null) {
|
|
67018
|
+
result += character;
|
|
67019
|
+
if (character === "\\") {
|
|
67020
|
+
result += nextCharacter ?? "";
|
|
67021
|
+
index += 2;
|
|
67022
|
+
continue;
|
|
67023
|
+
}
|
|
67024
|
+
if (character === quote) quote = null;
|
|
67025
|
+
index += 1;
|
|
67026
|
+
continue;
|
|
67027
|
+
}
|
|
67028
|
+
if (character === "\"" || character === "'") {
|
|
67029
|
+
quote = character;
|
|
67030
|
+
result += character;
|
|
67031
|
+
index += 1;
|
|
67032
|
+
continue;
|
|
67033
|
+
}
|
|
67034
|
+
if (character === "/" && nextCharacter === "/") {
|
|
67035
|
+
while (index < contents.length && contents[index] !== "\n") {
|
|
67036
|
+
result += " ";
|
|
67037
|
+
index += 1;
|
|
67038
|
+
}
|
|
67039
|
+
continue;
|
|
67040
|
+
}
|
|
67041
|
+
if (character === "/" && nextCharacter === "*") {
|
|
67042
|
+
result += " ";
|
|
67043
|
+
index += 2;
|
|
67044
|
+
while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
|
|
67045
|
+
result += contents[index] === "\n" ? "\n" : " ";
|
|
67046
|
+
index += 1;
|
|
67047
|
+
}
|
|
67048
|
+
if (index < contents.length) {
|
|
67049
|
+
result += " ";
|
|
67050
|
+
index += 2;
|
|
67051
|
+
}
|
|
67052
|
+
continue;
|
|
67053
|
+
}
|
|
67054
|
+
result += character;
|
|
67055
|
+
index += 1;
|
|
67056
|
+
}
|
|
67057
|
+
return result;
|
|
67058
|
+
};
|
|
67059
|
+
const maskGradleStrings = (contents) => {
|
|
67060
|
+
let result = "";
|
|
67061
|
+
let index = 0;
|
|
67062
|
+
let quote = null;
|
|
67063
|
+
while (index < contents.length) {
|
|
67064
|
+
const character = contents[index];
|
|
67065
|
+
if (quote === null) {
|
|
67066
|
+
if (character === "\"" || character === "'") {
|
|
67067
|
+
quote = character;
|
|
67068
|
+
result += " ";
|
|
67069
|
+
} else result += character;
|
|
67070
|
+
index += 1;
|
|
67071
|
+
continue;
|
|
67072
|
+
}
|
|
67073
|
+
if (character === "\\") {
|
|
67074
|
+
result += " ";
|
|
67075
|
+
index += 2;
|
|
67076
|
+
continue;
|
|
67077
|
+
}
|
|
67078
|
+
if (character === quote) quote = null;
|
|
67079
|
+
result += character === "\n" ? "\n" : " ";
|
|
67080
|
+
index += 1;
|
|
67081
|
+
}
|
|
67082
|
+
return result;
|
|
67083
|
+
};
|
|
67084
|
+
const findBlockContents = (contents, pattern) => {
|
|
67085
|
+
const blocks = [];
|
|
67086
|
+
pattern.lastIndex = 0;
|
|
67087
|
+
let match = pattern.exec(contents);
|
|
67088
|
+
while (match !== null) {
|
|
67089
|
+
const openingBraceIndex = pattern.lastIndex - 1;
|
|
67090
|
+
let depth = 1;
|
|
67091
|
+
let index = openingBraceIndex + 1;
|
|
67092
|
+
let quote = null;
|
|
67093
|
+
while (index < contents.length && depth > 0) {
|
|
67094
|
+
const character = contents[index];
|
|
67095
|
+
if (quote !== null) {
|
|
67096
|
+
if (character === "\\") {
|
|
67097
|
+
index += 2;
|
|
67098
|
+
continue;
|
|
67099
|
+
}
|
|
67100
|
+
if (character === quote) quote = null;
|
|
67101
|
+
} else if (character === "\"" || character === "'") quote = character;
|
|
67102
|
+
else if (character === "{") depth += 1;
|
|
67103
|
+
else if (character === "}") depth -= 1;
|
|
67104
|
+
index += 1;
|
|
67105
|
+
}
|
|
67106
|
+
if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
|
|
67107
|
+
match = pattern.exec(contents);
|
|
67108
|
+
}
|
|
67109
|
+
return blocks;
|
|
67110
|
+
};
|
|
67111
|
+
const getFinalStaticBoolean = (contents, pattern) => {
|
|
67112
|
+
pattern.lastIndex = 0;
|
|
67113
|
+
let finalValue = null;
|
|
67114
|
+
let match = pattern.exec(contents);
|
|
67115
|
+
while (match !== null) {
|
|
67116
|
+
const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
|
|
67117
|
+
if (staticValue === "true") finalValue = true;
|
|
67118
|
+
else if (staticValue === "false") finalValue = false;
|
|
67119
|
+
else finalValue = null;
|
|
67120
|
+
match = pattern.exec(contents);
|
|
67121
|
+
}
|
|
67122
|
+
return finalValue;
|
|
67123
|
+
};
|
|
67124
|
+
const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
|
|
67125
|
+
const readAndroidReleaseShrinking = (rootDirectory) => {
|
|
67126
|
+
for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
|
|
67127
|
+
const filePath = Path.posix.join("android", "app", buildFileName);
|
|
67128
|
+
const absoluteFilePath = Path.join(rootDirectory, filePath);
|
|
67129
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67130
|
+
let contents;
|
|
67131
|
+
try {
|
|
67132
|
+
contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
|
|
67133
|
+
} catch {
|
|
67134
|
+
return null;
|
|
67135
|
+
}
|
|
67136
|
+
const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
|
|
67137
|
+
const [releaseBlock] = releaseBlocks;
|
|
67138
|
+
if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
|
|
67139
|
+
const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
|
|
67140
|
+
const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
|
|
67141
|
+
if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
|
|
67142
|
+
return {
|
|
67143
|
+
filePath,
|
|
67144
|
+
hasDisabledMinification,
|
|
67145
|
+
hasDisabledResourceShrinking
|
|
67146
|
+
};
|
|
67147
|
+
}
|
|
67148
|
+
return null;
|
|
67149
|
+
};
|
|
67150
|
+
const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
|
|
67151
|
+
const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
|
|
67152
|
+
if (releaseShrinking === null) return [];
|
|
67153
|
+
const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
|
|
67154
|
+
return [buildReactNativeDiagnostic({
|
|
67155
|
+
filePath: releaseShrinking.filePath,
|
|
67156
|
+
rule: "rn-android-release-shrinking-disabled",
|
|
67157
|
+
category: "Performance",
|
|
67158
|
+
message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
|
|
67159
|
+
help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
|
|
67160
|
+
})];
|
|
67161
|
+
};
|
|
67162
|
+
const getTypescriptScriptKind = (fileName) => {
|
|
67163
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
67164
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
67165
|
+
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67166
|
+
return ts.ScriptKind.JS;
|
|
67167
|
+
};
|
|
67168
|
+
const unwrapTypescriptExpression = (expression) => {
|
|
67169
|
+
let currentExpression = expression;
|
|
67170
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
67171
|
+
return currentExpression;
|
|
67172
|
+
};
|
|
67173
|
+
const BABEL_CONFIG_FILE_NAMES$1 = [
|
|
67174
|
+
"babel.config.js",
|
|
67175
|
+
"babel.config.cjs",
|
|
67176
|
+
"babel.config.mjs",
|
|
67177
|
+
"babel.config.ts",
|
|
67178
|
+
"babel.config.cts",
|
|
67179
|
+
"babel.config.json",
|
|
67180
|
+
".babelrc",
|
|
67181
|
+
".babelrc.js",
|
|
67182
|
+
".babelrc.cjs",
|
|
67183
|
+
".babelrc.mjs",
|
|
67184
|
+
".babelrc.cts",
|
|
67185
|
+
".babelrc.json"
|
|
67186
|
+
];
|
|
67187
|
+
const readUnknownPluginNames = (value) => {
|
|
67188
|
+
if (!Array.isArray(value)) return null;
|
|
67189
|
+
const pluginNames = [];
|
|
67190
|
+
for (const entry of value) {
|
|
67191
|
+
if (typeof entry === "string") {
|
|
67192
|
+
pluginNames.push(entry);
|
|
67193
|
+
continue;
|
|
67194
|
+
}
|
|
67195
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") {
|
|
67196
|
+
pluginNames.push(entry[0]);
|
|
67197
|
+
continue;
|
|
67198
|
+
}
|
|
67199
|
+
return null;
|
|
67200
|
+
}
|
|
67201
|
+
return pluginNames;
|
|
67202
|
+
};
|
|
67203
|
+
const getStaticPropertyName$1 = (propertyName) => {
|
|
67204
|
+
if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
|
|
67205
|
+
return null;
|
|
67206
|
+
};
|
|
67207
|
+
const getStaticPluginName = (expression) => {
|
|
67208
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
67209
|
+
if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
|
|
67210
|
+
if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
|
|
67211
|
+
const pluginExpression = unwrappedExpression.elements[0];
|
|
67212
|
+
return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
|
|
67213
|
+
};
|
|
67214
|
+
const getPluginNamesFromObject = (objectExpression) => {
|
|
67215
|
+
if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
|
|
67216
|
+
const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
|
|
67217
|
+
if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
|
|
67218
|
+
const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
|
|
67219
|
+
if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
|
|
67220
|
+
const pluginNames = [];
|
|
67221
|
+
for (const element of pluginListExpression.elements) {
|
|
67222
|
+
if (ts.isSpreadElement(element)) return null;
|
|
67223
|
+
const pluginName = getStaticPluginName(element);
|
|
67224
|
+
if (pluginName === null) return null;
|
|
67225
|
+
pluginNames.push(pluginName);
|
|
67226
|
+
}
|
|
67227
|
+
return pluginNames;
|
|
67228
|
+
};
|
|
67229
|
+
const isModuleExports = (expression) => ts.isPropertyAccessExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "module" && expression.name.text === "exports" || ts.isElementAccessExpression(expression) && ts.isIdentifier(expression.expression) && expression.expression.text === "module" && expression.argumentExpression !== void 0 && ts.isStringLiteralLike(expression.argumentExpression) && expression.argumentExpression.text === "exports";
|
|
67230
|
+
const getDirectExportedObject = (sourceFile) => {
|
|
67231
|
+
const exportedExpressions = [];
|
|
67232
|
+
for (const statement of sourceFile.statements) {
|
|
67233
|
+
if (ts.isExportAssignment(statement)) {
|
|
67234
|
+
exportedExpressions.push(statement.expression);
|
|
67235
|
+
continue;
|
|
67236
|
+
}
|
|
67237
|
+
if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
|
|
67238
|
+
}
|
|
67239
|
+
if (exportedExpressions.length !== 1) return null;
|
|
67240
|
+
const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
|
|
67241
|
+
return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
|
|
67242
|
+
};
|
|
67243
|
+
const parseConfigPluginNames = (filePath, contents) => {
|
|
67244
|
+
try {
|
|
67245
|
+
const parsedJson = JSON.parse(contents);
|
|
67246
|
+
return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
|
|
67247
|
+
} catch {
|
|
67248
|
+
if (ts.transpileModule(contents, {
|
|
67249
|
+
fileName: filePath,
|
|
67250
|
+
reportDiagnostics: true,
|
|
67251
|
+
compilerOptions: { allowJs: true }
|
|
67252
|
+
}).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
|
|
67253
|
+
const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
|
|
67254
|
+
return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
|
|
67255
|
+
}
|
|
67256
|
+
};
|
|
67257
|
+
const readStaticBabelPluginNames = (rootDirectory) => {
|
|
67258
|
+
for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
|
|
67259
|
+
const absoluteFilePath = Path.join(rootDirectory, fileName);
|
|
67260
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67261
|
+
try {
|
|
67262
|
+
return {
|
|
67263
|
+
filePath: fileName,
|
|
67264
|
+
pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
|
|
67265
|
+
};
|
|
67266
|
+
} catch {
|
|
67267
|
+
return {
|
|
67268
|
+
filePath: fileName,
|
|
67269
|
+
pluginNames: null
|
|
67270
|
+
};
|
|
67271
|
+
}
|
|
67272
|
+
}
|
|
67273
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
67274
|
+
if (!isPlainObject(packageJson.babel)) return null;
|
|
67275
|
+
return {
|
|
67276
|
+
filePath: "package.json",
|
|
67277
|
+
pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
|
|
67278
|
+
};
|
|
67279
|
+
};
|
|
67280
|
+
const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
|
|
67281
|
+
const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
|
|
67282
|
+
const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
|
|
67283
|
+
const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
|
|
67284
|
+
if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
|
|
67285
|
+
return [buildReactNativeDiagnostic({
|
|
67286
|
+
filePath,
|
|
67287
|
+
rule: "rn-react-compiler-plugin-first",
|
|
67288
|
+
category: "Performance",
|
|
67289
|
+
message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
|
|
67290
|
+
help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
|
|
67291
|
+
})];
|
|
67292
|
+
};
|
|
67293
|
+
const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
|
|
67294
|
+
const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
|
|
67295
|
+
if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
|
|
67296
|
+
const diagnostics = [];
|
|
67297
|
+
if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
|
|
67298
|
+
filePath,
|
|
67299
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67300
|
+
category: "Performance",
|
|
67301
|
+
message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
|
|
67302
|
+
help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
|
|
67303
|
+
}));
|
|
67304
|
+
const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
|
|
67305
|
+
if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
|
|
67306
|
+
filePath,
|
|
67307
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67308
|
+
category: "Performance",
|
|
67309
|
+
message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
|
|
67310
|
+
help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
|
|
67311
|
+
}));
|
|
67312
|
+
return diagnostics;
|
|
67313
|
+
};
|
|
67314
|
+
const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
|
|
67315
|
+
const babelPlugins = readStaticBabelPluginNames(rootDirectory);
|
|
67316
|
+
if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
|
|
67317
|
+
return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
|
|
67318
|
+
};
|
|
66959
67319
|
const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
|
|
66960
67320
|
const isBuilderBobLibrary = (packageJson) => {
|
|
66961
67321
|
const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
|
|
@@ -67032,7 +67392,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
67032
67392
|
const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
|
|
67033
67393
|
const checkReactNativeProject = (rootDirectory, project) => {
|
|
67034
67394
|
if (!isReactNativeProject(project)) return [];
|
|
67035
|
-
return [
|
|
67395
|
+
return [
|
|
67396
|
+
...checkReactNativeMetroBabelPreset(rootDirectory),
|
|
67397
|
+
...checkReactNativeBabelPluginOrder(rootDirectory, project),
|
|
67398
|
+
...checkReactNativeAndroidReleaseShrinking(rootDirectory),
|
|
67399
|
+
...checkReactNativeLibraryDependencies(rootDirectory)
|
|
67400
|
+
];
|
|
67036
67401
|
};
|
|
67037
67402
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
67038
67403
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
@@ -67183,17 +67548,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
|
|
|
67183
67548
|
}
|
|
67184
67549
|
return diagnostics;
|
|
67185
67550
|
};
|
|
67186
|
-
const getTypescriptScriptKind = (fileName) => {
|
|
67187
|
-
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
67188
|
-
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
67189
|
-
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67190
|
-
return ts.ScriptKind.JS;
|
|
67191
|
-
};
|
|
67192
|
-
const unwrapTypescriptExpression = (expression) => {
|
|
67193
|
-
let currentExpression = expression;
|
|
67194
|
-
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
67195
|
-
return currentExpression;
|
|
67196
|
-
};
|
|
67197
67551
|
const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
|
|
67198
67552
|
isAnimationFunction: false,
|
|
67199
67553
|
isMotionComponent: false,
|
|
@@ -67749,7 +68103,11 @@ const buildCapabilities = (project) => {
|
|
|
67749
68103
|
capabilities.add(project.framework);
|
|
67750
68104
|
if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
|
|
67751
68105
|
if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
|
|
67752
|
-
if (project.expoVersion !== null)
|
|
68106
|
+
if (project.expoVersion !== null) {
|
|
68107
|
+
capabilities.add("expo");
|
|
68108
|
+
const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
|
|
68109
|
+
if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
|
|
68110
|
+
}
|
|
67753
68111
|
if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
|
|
67754
68112
|
if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
|
|
67755
68113
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
@@ -67813,6 +68171,11 @@ const buildCapabilities = (project) => {
|
|
|
67813
68171
|
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
67814
68172
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
67815
68173
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
68174
|
+
if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
|
|
68175
|
+
capabilities.add("reanimated");
|
|
68176
|
+
const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
|
|
68177
|
+
if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
|
|
68178
|
+
}
|
|
67816
68179
|
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
67817
68180
|
if (project.styledComponentsVersion) {
|
|
67818
68181
|
capabilities.add("styled-components");
|
|
@@ -69710,7 +70073,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
69710
70073
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
69711
70074
|
const normalizeConfigForHash = (config) => {
|
|
69712
70075
|
const clone = JSON.parse(JSON.stringify(config));
|
|
69713
|
-
if (clone?.settings?.["react-doctor"])
|
|
70076
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
70077
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
70078
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
70079
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
70080
|
+
}
|
|
69714
70081
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
69715
70082
|
return clone;
|
|
69716
70083
|
};
|
|
@@ -69869,13 +70236,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
69869
70236
|
}
|
|
69870
70237
|
return enabled;
|
|
69871
70238
|
};
|
|
69872
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
70239
|
+
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, runtimeGlobals, unpluginAutoImportGlobalScopes, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
69873
70240
|
const hasIncludedTags = includedTags.size > 0;
|
|
69874
70241
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
69875
70242
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
69876
70243
|
const jsPlugins = [];
|
|
69877
70244
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
69878
70245
|
const capabilities = getCapabilities(project);
|
|
70246
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
69879
70247
|
const enabledReactDoctorRules = {};
|
|
69880
70248
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
69881
70249
|
const rule = reactDoctorPlugin.rules[registryEntry.id];
|
|
@@ -69921,8 +70289,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69921
70289
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
69922
70290
|
settings: { "react-doctor": {
|
|
69923
70291
|
framework: project.framework,
|
|
69924
|
-
rootDirectory:
|
|
70292
|
+
rootDirectory: settingsRootDirectory,
|
|
69925
70293
|
capabilities: [...capabilities].sort(),
|
|
70294
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
70295
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
70296
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
70297
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
70298
|
+
directory: scope.directory,
|
|
70299
|
+
names: [...scope.names]
|
|
70300
|
+
}))
|
|
70301
|
+
} : {},
|
|
69926
70302
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
69927
70303
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
69928
70304
|
} },
|
|
@@ -69933,6 +70309,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69933
70309
|
}
|
|
69934
70310
|
};
|
|
69935
70311
|
};
|
|
70312
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
70313
|
+
const CONFIG_BASENAMES = [
|
|
70314
|
+
"astro.config",
|
|
70315
|
+
"esbuild.config",
|
|
70316
|
+
"rollup.config",
|
|
70317
|
+
"rolldown.config",
|
|
70318
|
+
"rspack.config",
|
|
70319
|
+
"vite.config",
|
|
70320
|
+
"webpack.config"
|
|
70321
|
+
];
|
|
70322
|
+
const CONFIG_EXTENSIONS = [
|
|
70323
|
+
".cjs",
|
|
70324
|
+
".cts",
|
|
70325
|
+
".js",
|
|
70326
|
+
".mjs",
|
|
70327
|
+
".mts",
|
|
70328
|
+
".ts"
|
|
70329
|
+
];
|
|
70330
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
70331
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
70332
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
70333
|
+
true,
|
|
70334
|
+
false,
|
|
70335
|
+
"readable",
|
|
70336
|
+
"readonly",
|
|
70337
|
+
"writable",
|
|
70338
|
+
"writeable"
|
|
70339
|
+
]);
|
|
70340
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
70341
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
70342
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
70343
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
70344
|
+
}) ?? null;
|
|
70345
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
70346
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
70347
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
70348
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
70349
|
+
};
|
|
70350
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
70351
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70352
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
70353
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
70354
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
70355
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
70356
|
+
};
|
|
70357
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
70358
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70359
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
70360
|
+
};
|
|
70361
|
+
const isCommonJsExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
|
|
70362
|
+
const isTopLevelExpression = (node) => {
|
|
70363
|
+
let ancestor = node.parent;
|
|
70364
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70365
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
70366
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
70367
|
+
ancestor = ancestor.parent;
|
|
70368
|
+
}
|
|
70369
|
+
return false;
|
|
70370
|
+
};
|
|
70371
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
70372
|
+
let ancestor = node.parent;
|
|
70373
|
+
let didFindConfigProperty = false;
|
|
70374
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70375
|
+
if (!didFindConfigProperty && !ts.isArrayLiteralExpression(ancestor) && !ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isPropertyAssignment(ancestor)) return false;
|
|
70376
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
70377
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
70378
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
70379
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
70380
|
+
didFindConfigProperty = true;
|
|
70381
|
+
ancestor = ancestor.parent;
|
|
70382
|
+
continue;
|
|
70383
|
+
}
|
|
70384
|
+
if (didFindConfigProperty) {
|
|
70385
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
70386
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
70387
|
+
if (propertyName === "plugins" && ts.isCallExpression(ancestor) && (ts.isIdentifier(ancestor.expression) ? esbuildBindings.has(ancestor.expression.text) : ts.isPropertyAccessExpression(ancestor.expression) && ancestor.expression.name.text === "build" && (ts.isIdentifier(ancestor.expression.expression) && esbuildNamespaceBindings.has(ancestor.expression.expression.text) || getRequireModuleSpecifier(ancestor.expression.expression) === "esbuild"))) return isTopLevelExpression(ancestor);
|
|
70388
|
+
if (!(ts.isObjectLiteralExpression(ancestor) || ts.isParenthesizedExpression(ancestor) || ts.isAsExpression(ancestor) || ts.isSatisfiesExpression(ancestor) || ts.isNonNullExpression(ancestor) || ts.isTypeAssertionExpression(ancestor) || ts.isCallExpression(ancestor) && ts.isIdentifier(ancestor.expression) && ancestor.expression.text === "defineConfig")) return false;
|
|
70389
|
+
}
|
|
70390
|
+
ancestor = ancestor.parent;
|
|
70391
|
+
}
|
|
70392
|
+
return false;
|
|
70393
|
+
};
|
|
70394
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
70395
|
+
const optionsExpression = callExpression.arguments[0];
|
|
70396
|
+
if (!optionsExpression) return null;
|
|
70397
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
70398
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
70399
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
70400
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
70401
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
70402
|
+
if (!eslintrcProperty) return null;
|
|
70403
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
70404
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
70405
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
70406
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
70407
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
70408
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
70409
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
70410
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
70411
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
70412
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
70413
|
+
};
|
|
70414
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
70415
|
+
let sourceText;
|
|
70416
|
+
try {
|
|
70417
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
70418
|
+
} catch {
|
|
70419
|
+
return {
|
|
70420
|
+
didFindActiveAutoImport: false,
|
|
70421
|
+
globalsPaths: []
|
|
70422
|
+
};
|
|
70423
|
+
}
|
|
70424
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
70425
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
70426
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
70427
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
70428
|
+
for (const statement of sourceFile.statements) {
|
|
70429
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
70430
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
70431
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70432
|
+
const defaultBinding = statement.importClause?.name;
|
|
70433
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
70434
|
+
}
|
|
70435
|
+
if (moduleSpecifier === "esbuild") {
|
|
70436
|
+
const defaultBinding = statement.importClause?.name;
|
|
70437
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
70438
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
70439
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
70440
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
70441
|
+
}
|
|
70442
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
70443
|
+
}
|
|
70444
|
+
}
|
|
70445
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
70446
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
70447
|
+
if (!declaration.initializer) continue;
|
|
70448
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
70449
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
70450
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
70451
|
+
if (moduleSpecifier === "esbuild") {
|
|
70452
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
70453
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
70454
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
70455
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
70456
|
+
}
|
|
70457
|
+
}
|
|
70458
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
70459
|
+
}
|
|
70460
|
+
}
|
|
70461
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
70462
|
+
let didFindActiveAutoImport = false;
|
|
70463
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
70464
|
+
const visit = (node) => {
|
|
70465
|
+
if (ts.isCallExpression(node)) {
|
|
70466
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
70467
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70468
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
70469
|
+
didFindActiveAutoImport = true;
|
|
70470
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
70471
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
70472
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
70473
|
+
}
|
|
70474
|
+
}
|
|
70475
|
+
}
|
|
70476
|
+
ts.forEachChild(node, visit);
|
|
70477
|
+
};
|
|
70478
|
+
visit(sourceFile);
|
|
70479
|
+
return {
|
|
70480
|
+
didFindActiveAutoImport,
|
|
70481
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
70482
|
+
};
|
|
70483
|
+
};
|
|
70484
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
70485
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
70486
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
70487
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
70488
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
70489
|
+
return Object.entries(parsed.globals).filter((entry) => entry[0].length > 0 && (typeof entry[1] === "boolean" || typeof entry[1] === "string") && SUPPORTED_GLOBAL_VALUES.has(entry[1])).map(([name]) => name).sort();
|
|
70490
|
+
};
|
|
70491
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
70492
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
70493
|
+
const visitedDirectories = [];
|
|
70494
|
+
while (true) {
|
|
70495
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
70496
|
+
if (cachedDirectory !== void 0) {
|
|
70497
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
70498
|
+
return cachedDirectory;
|
|
70499
|
+
}
|
|
70500
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
70501
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
70502
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70503
|
+
return null;
|
|
70504
|
+
}
|
|
70505
|
+
visitedDirectories.push(currentDirectory);
|
|
70506
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
70507
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
70508
|
+
return currentDirectory;
|
|
70509
|
+
}
|
|
70510
|
+
if (currentDirectory === rootDirectory) {
|
|
70511
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70512
|
+
return null;
|
|
70513
|
+
}
|
|
70514
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
70515
|
+
}
|
|
70516
|
+
};
|
|
70517
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
70518
|
+
let directoryEntries;
|
|
70519
|
+
try {
|
|
70520
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
70521
|
+
} catch {
|
|
70522
|
+
return [];
|
|
70523
|
+
}
|
|
70524
|
+
const configuredGlobalsPaths = [];
|
|
70525
|
+
for (const entry of directoryEntries) {
|
|
70526
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
70527
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
70528
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
70529
|
+
}
|
|
70530
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
70531
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
70532
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
70533
|
+
const names = /* @__PURE__ */ new Set();
|
|
70534
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
70535
|
+
return [...names].sort();
|
|
70536
|
+
};
|
|
70537
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
70538
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
70539
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
70540
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
70541
|
+
for (const candidateFile of candidateFiles) {
|
|
70542
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
70543
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
70544
|
+
}
|
|
70545
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
70546
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
70547
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
70548
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
70549
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
70550
|
+
};
|
|
69936
70551
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
69937
70552
|
const decodeFileDiagnostics = (raw) => {
|
|
69938
70553
|
if (!Array.isArray(raw)) return null;
|
|
@@ -70255,6 +70870,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
70255
70870
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
70256
70871
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
70257
70872
|
};
|
|
70873
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
70874
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
70875
|
+
let lineStartOffset = boundedOffset;
|
|
70876
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
70877
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
70878
|
+
};
|
|
70258
70879
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
70259
70880
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
70260
70881
|
const KNOWN_SECRET_RULES = [
|
|
@@ -70970,7 +71591,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
70970
71591
|
* with empty text still carry a useful jump target, so they're kept
|
|
70971
71592
|
* with a neutral message.
|
|
70972
71593
|
*/
|
|
70973
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
71594
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
70974
71595
|
if (labels.length <= 1) return [];
|
|
70975
71596
|
const related = [];
|
|
70976
71597
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -70978,8 +71599,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
70978
71599
|
if (!label?.span) continue;
|
|
70979
71600
|
related.push({
|
|
70980
71601
|
filePath,
|
|
70981
|
-
line: label.span.line ?? 0,
|
|
70982
|
-
column: label.span.column ?? 0,
|
|
71602
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
71603
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
70983
71604
|
offset: label.span.offset,
|
|
70984
71605
|
length: label.span.length,
|
|
70985
71606
|
message: label.label ?? ""
|
|
@@ -70999,7 +71620,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
|
|
|
70999
71620
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
71000
71621
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
71001
71622
|
*/
|
|
71002
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
71623
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
|
|
71003
71624
|
if (!stdout) return [];
|
|
71004
71625
|
const jsonStart = stdout.indexOf("{");
|
|
71005
71626
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -71016,8 +71637,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71016
71637
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
71017
71638
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
71018
71639
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
71640
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
71641
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
71019
71642
|
const readSourceBuffer = (filename) => {
|
|
71020
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71643
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71021
71644
|
const cached = sourceBufferCache.get(absolutePath);
|
|
71022
71645
|
if (cached !== void 0) return cached;
|
|
71023
71646
|
let sourceBuffer;
|
|
@@ -71030,7 +71653,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71030
71653
|
return sourceBuffer;
|
|
71031
71654
|
};
|
|
71032
71655
|
const readSourceLines = (filename) => {
|
|
71033
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71656
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71034
71657
|
const cached = sourceLinesCache.get(absolutePath);
|
|
71035
71658
|
if (cached !== void 0) return cached;
|
|
71036
71659
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -71039,27 +71662,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71039
71662
|
return sourceLines;
|
|
71040
71663
|
};
|
|
71041
71664
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
71042
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71665
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71043
71666
|
const cached = minifiedFileCache.get(absolutePath);
|
|
71044
71667
|
if (cached !== void 0) return cached;
|
|
71045
71668
|
const minified = isMinifiedSource(absolutePath);
|
|
71046
71669
|
minifiedFileCache.set(absolutePath, minified);
|
|
71047
71670
|
return minified;
|
|
71048
71671
|
};
|
|
71049
|
-
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71672
|
+
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71050
71673
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71051
71674
|
const primaryLabel = diagnostic.labels[0];
|
|
71052
71675
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
71053
|
-
const
|
|
71676
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
71677
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
71054
71678
|
const primarySpan = primaryLabel?.span;
|
|
71055
71679
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
71056
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
71680
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
71057
71681
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
71058
71682
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
71059
71683
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
71060
|
-
const
|
|
71684
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
71685
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
71686
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
71061
71687
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
71062
|
-
const primaryColumnIndex = primarySpan ?
|
|
71688
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
71063
71689
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
71064
71690
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
71065
71691
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -71072,8 +71698,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71072
71698
|
message: cleaned.message,
|
|
71073
71699
|
help: cleaned.help,
|
|
71074
71700
|
url: diagnostic.url,
|
|
71075
|
-
line:
|
|
71076
|
-
column:
|
|
71701
|
+
line: primaryLineNumber,
|
|
71702
|
+
column: primaryColumnNumber,
|
|
71077
71703
|
...primarySpan ? {
|
|
71078
71704
|
offset: primarySpan.offset,
|
|
71079
71705
|
length: primarySpan.length,
|
|
@@ -71261,7 +71887,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
71261
71887
|
* loop with a slimmer config in that case.
|
|
71262
71888
|
*/
|
|
71263
71889
|
const spawnLintBatches = async (input) => {
|
|
71264
|
-
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
71890
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
71891
|
+
const resolveSourcePath = (filePath) => {
|
|
71892
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
71893
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
71894
|
+
};
|
|
71265
71895
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
71266
71896
|
let rescueDeadlineEpochMs;
|
|
71267
71897
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -71281,7 +71911,7 @@ const spawnLintBatches = async (input) => {
|
|
|
71281
71911
|
}
|
|
71282
71912
|
const batchArgs = [...baseArgs, ...batch];
|
|
71283
71913
|
try {
|
|
71284
|
-
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
|
|
71914
|
+
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
|
|
71285
71915
|
} catch (error) {
|
|
71286
71916
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
71287
71917
|
if (isPastDeadline()) {
|
|
@@ -71387,10 +72017,12 @@ const spawnLintBatches = async (input) => {
|
|
|
71387
72017
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
71388
72018
|
};
|
|
71389
72019
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
71390
|
-
|
|
71391
|
-
|
|
72020
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
72021
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
72022
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
72023
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
71392
72024
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
71393
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
72025
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
71394
72026
|
return dedupeDiagnostics(diagnostics);
|
|
71395
72027
|
};
|
|
71396
72028
|
let didValidate = false;
|
|
@@ -71489,6 +72121,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
71489
72121
|
}
|
|
71490
72122
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
71491
72123
|
};
|
|
72124
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
72125
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
72126
|
+
const COMMENT_OPEN = "<!--";
|
|
72127
|
+
const COMMENT_CLOSE = "-->";
|
|
72128
|
+
const FRONTMATTER_FENCE = "---";
|
|
72129
|
+
const SCRIPT_TAG_NAME = "script";
|
|
72130
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
72131
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
72132
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
72133
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
72134
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
72135
|
+
"application/ecmascript",
|
|
72136
|
+
"application/javascript",
|
|
72137
|
+
"application/x-ecmascript",
|
|
72138
|
+
"application/x-javascript",
|
|
72139
|
+
"text/ecmascript",
|
|
72140
|
+
"text/javascript",
|
|
72141
|
+
"text/javascript1.0",
|
|
72142
|
+
"text/javascript1.1",
|
|
72143
|
+
"text/javascript1.2",
|
|
72144
|
+
"text/javascript1.3",
|
|
72145
|
+
"text/javascript1.4",
|
|
72146
|
+
"text/javascript1.5",
|
|
72147
|
+
"text/jscript",
|
|
72148
|
+
"text/livescript",
|
|
72149
|
+
"text/x-ecmascript",
|
|
72150
|
+
"text/x-javascript"
|
|
72151
|
+
]);
|
|
72152
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
72153
|
+
"iframe",
|
|
72154
|
+
"noembed",
|
|
72155
|
+
"noframes",
|
|
72156
|
+
"noscript",
|
|
72157
|
+
"style",
|
|
72158
|
+
"textarea",
|
|
72159
|
+
"title",
|
|
72160
|
+
"xmp"
|
|
72161
|
+
]);
|
|
72162
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
72163
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
72164
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
72165
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
72166
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
72167
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
72168
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
72169
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
72170
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
72171
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
72172
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
72173
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
72174
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
72175
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
72176
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
72177
|
+
}
|
|
72178
|
+
return true;
|
|
72179
|
+
};
|
|
72180
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
72181
|
+
const isPotentialTagStart = (byte) => {
|
|
72182
|
+
if (byte === void 0) return false;
|
|
72183
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
72184
|
+
};
|
|
72185
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
72186
|
+
let byteIndex = lineStartByte;
|
|
72187
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
72188
|
+
return byteIndex;
|
|
72189
|
+
};
|
|
72190
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
72191
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72192
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
72193
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
72194
|
+
};
|
|
72195
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
72196
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
72197
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72198
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
72199
|
+
return true;
|
|
72200
|
+
};
|
|
72201
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
72202
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
72203
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
72204
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
72205
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
72206
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
72207
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
72208
|
+
}
|
|
72209
|
+
return openingFenceEndByte;
|
|
72210
|
+
};
|
|
72211
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
72212
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
72213
|
+
const byte = maskedBuffer[byteIndex];
|
|
72214
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
72215
|
+
}
|
|
72216
|
+
};
|
|
72217
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
72218
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
72219
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
72220
|
+
let nameEndByte = tagStartByte + 2;
|
|
72221
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
72222
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
72223
|
+
};
|
|
72224
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
72225
|
+
let quoteByte = null;
|
|
72226
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
72227
|
+
const byte = sourceBuffer[byteIndex];
|
|
72228
|
+
if (quoteByte !== null) {
|
|
72229
|
+
if (byte === quoteByte) quoteByte = null;
|
|
72230
|
+
continue;
|
|
72231
|
+
}
|
|
72232
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72233
|
+
quoteByte = byte;
|
|
72234
|
+
continue;
|
|
72235
|
+
}
|
|
72236
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
72237
|
+
}
|
|
72238
|
+
return sourceBuffer.length;
|
|
72239
|
+
};
|
|
72240
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
72241
|
+
let byteIndex = attributesStartByte;
|
|
72242
|
+
let hasSource = false;
|
|
72243
|
+
let language = null;
|
|
72244
|
+
let scriptType = null;
|
|
72245
|
+
while (byteIndex < tagEndByte) {
|
|
72246
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
72247
|
+
const attributeNameStartByte = byteIndex;
|
|
72248
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72249
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
72250
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72251
|
+
let attributeValue = "";
|
|
72252
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
72253
|
+
byteIndex++;
|
|
72254
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72255
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
72256
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72257
|
+
const valueStartByte = byteIndex + 1;
|
|
72258
|
+
byteIndex = valueStartByte;
|
|
72259
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
72260
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72261
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
72262
|
+
} else {
|
|
72263
|
+
const valueStartByte = byteIndex;
|
|
72264
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72265
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72266
|
+
}
|
|
72267
|
+
}
|
|
72268
|
+
if (attributeName === "src") hasSource = true;
|
|
72269
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
72270
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
72271
|
+
}
|
|
72272
|
+
return {
|
|
72273
|
+
hasSource,
|
|
72274
|
+
language,
|
|
72275
|
+
type: scriptType
|
|
72276
|
+
};
|
|
72277
|
+
};
|
|
72278
|
+
const isExecutableScript = (attributes) => {
|
|
72279
|
+
if (attributes.hasSource) return false;
|
|
72280
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
72281
|
+
if (type !== "") {
|
|
72282
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
72283
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
72284
|
+
}
|
|
72285
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
72286
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
72287
|
+
};
|
|
72288
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
72289
|
+
const closeTagStart = `</${tagName}`;
|
|
72290
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) if (sourceBuffer[byteIndex] === TAG_OPEN_UTF8_BYTE && matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, closeTagStart) && isTagBoundary(sourceBuffer[byteIndex + closeTagStart.length])) return byteIndex;
|
|
72291
|
+
return sourceBuffer.length;
|
|
72292
|
+
};
|
|
72293
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
72294
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
72295
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
72296
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
72297
|
+
const executableScriptBodies = [];
|
|
72298
|
+
let byteIndex = frontmatterEndByte;
|
|
72299
|
+
let templateDepth = 0;
|
|
72300
|
+
while (byteIndex < sourceBuffer.length) {
|
|
72301
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
72302
|
+
byteIndex++;
|
|
72303
|
+
continue;
|
|
72304
|
+
}
|
|
72305
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
72306
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
72307
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
72308
|
+
continue;
|
|
72309
|
+
}
|
|
72310
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
72311
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
72312
|
+
if (templateDepth > 0) templateDepth--;
|
|
72313
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72314
|
+
continue;
|
|
72315
|
+
}
|
|
72316
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
72317
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
72318
|
+
byteIndex++;
|
|
72319
|
+
continue;
|
|
72320
|
+
}
|
|
72321
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
72322
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
72323
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
72324
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
72325
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
72326
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
72327
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
72328
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
72329
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72330
|
+
continue;
|
|
72331
|
+
}
|
|
72332
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72333
|
+
continue;
|
|
72334
|
+
}
|
|
72335
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
72336
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
72337
|
+
const bodyStartByte = tagEndByte + 1;
|
|
72338
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
72339
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
72340
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
72341
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
72342
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
72343
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
72344
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
72345
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
72346
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72347
|
+
}
|
|
72348
|
+
return {
|
|
72349
|
+
executableScriptBodies,
|
|
72350
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
72351
|
+
};
|
|
72352
|
+
};
|
|
72353
|
+
const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
72354
|
+
const lintFiles = [];
|
|
72355
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
72356
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
72357
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
72358
|
+
let htmlFileIndex = 0;
|
|
72359
|
+
let hasThreeModuleImport = false;
|
|
72360
|
+
for (const candidateFile of candidateFiles) {
|
|
72361
|
+
if (!HTML_FILE_PATTERN.test(candidateFile)) {
|
|
72362
|
+
lintFiles.push(candidateFile);
|
|
72363
|
+
continue;
|
|
72364
|
+
}
|
|
72365
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
72366
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
72367
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
72368
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
72369
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
72370
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
72371
|
+
lintFiles.push(lintPath);
|
|
72372
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
72373
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
72374
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
72375
|
+
htmlFileIndex++;
|
|
72376
|
+
}
|
|
72377
|
+
return {
|
|
72378
|
+
lintFiles,
|
|
72379
|
+
sourcePathByLintPath,
|
|
72380
|
+
sizeByLintPath,
|
|
72381
|
+
hasThreeModuleImport
|
|
72382
|
+
};
|
|
72383
|
+
};
|
|
71492
72384
|
/**
|
|
71493
72385
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
71494
72386
|
* the runner: once for the primary scan, once for the
|
|
@@ -71649,6 +72541,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
71649
72541
|
const runOxlint = async (options) => {
|
|
71650
72542
|
const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
|
|
71651
72543
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72544
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72545
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
71652
72546
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
71653
72547
|
validateRuleRegistration();
|
|
71654
72548
|
resetManifestCaches();
|
|
@@ -71662,21 +72556,6 @@ const runOxlint = async (options) => {
|
|
|
71662
72556
|
const pluginPath = resolvePluginPath();
|
|
71663
72557
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
71664
72558
|
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
71665
|
-
const buildConfig = (overrides) => createOxlintConfig({
|
|
71666
|
-
pluginPath,
|
|
71667
|
-
project,
|
|
71668
|
-
customRulesOnly,
|
|
71669
|
-
extendsPaths: overrides.extendsPaths,
|
|
71670
|
-
ignoredTags,
|
|
71671
|
-
includedTags,
|
|
71672
|
-
includeTagDefaults,
|
|
71673
|
-
serverAuthFunctionNames,
|
|
71674
|
-
severityControls,
|
|
71675
|
-
userPlugins,
|
|
71676
|
-
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
71677
|
-
ruleSelection: overrides.ruleSelection,
|
|
71678
|
-
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
71679
|
-
});
|
|
71680
72559
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
71681
72560
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
71682
72561
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -71712,7 +72591,36 @@ const runOxlint = async (options) => {
|
|
|
71712
72591
|
await yieldToEventLoop();
|
|
71713
72592
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
71714
72593
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
72594
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
72595
|
+
rootDirectory,
|
|
72596
|
+
candidateFiles
|
|
72597
|
+
});
|
|
72598
|
+
const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
72599
|
+
const lintFiles = preparedHtmlSources.lintFiles;
|
|
72600
|
+
const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
|
|
72601
|
+
const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
|
|
72602
|
+
...project,
|
|
72603
|
+
hasThree: true
|
|
72604
|
+
} : project;
|
|
72605
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
72606
|
+
pluginPath,
|
|
72607
|
+
project: lintProject,
|
|
72608
|
+
customRulesOnly,
|
|
72609
|
+
extendsPaths: overrides.extendsPaths,
|
|
72610
|
+
ignoredTags,
|
|
72611
|
+
includedTags,
|
|
72612
|
+
includeTagDefaults,
|
|
72613
|
+
runtimeGlobals,
|
|
72614
|
+
unpluginAutoImportGlobalScopes,
|
|
72615
|
+
serverAuthFunctionNames,
|
|
72616
|
+
severityControls,
|
|
72617
|
+
userPlugins,
|
|
72618
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
72619
|
+
ruleSelection: overrides.ruleSelection,
|
|
72620
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
72621
|
+
});
|
|
71715
72622
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
72623
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
71716
72624
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
71717
72625
|
baseArgs: passBaseArgs,
|
|
71718
72626
|
files: passFiles,
|
|
@@ -71741,7 +72649,8 @@ const runOxlint = async (options) => {
|
|
|
71741
72649
|
fileBatches: passFileBatches,
|
|
71742
72650
|
rootDirectory,
|
|
71743
72651
|
nodeBinaryPath,
|
|
71744
|
-
project,
|
|
72652
|
+
project: lintProject,
|
|
72653
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
71745
72654
|
onPartialFailure: reportPartialFailure,
|
|
71746
72655
|
onAnalyzedFiles: (filePaths) => {
|
|
71747
72656
|
analyzedFiles = filePaths;
|
|
@@ -71776,7 +72685,7 @@ const runOxlint = async (options) => {
|
|
|
71776
72685
|
};
|
|
71777
72686
|
}
|
|
71778
72687
|
};
|
|
71779
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
72688
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
|
|
71780
72689
|
const rulesetHash = computeRulesetHash({
|
|
71781
72690
|
config: buildConfig({
|
|
71782
72691
|
extendsPaths: [],
|
|
@@ -71934,14 +72843,15 @@ const runOxlint = async (options) => {
|
|
|
71934
72843
|
]);
|
|
71935
72844
|
}
|
|
71936
72845
|
const baseArgs = makeBaseArgs(configPath);
|
|
71937
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
72846
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
71938
72847
|
let analyzedFiles = [];
|
|
71939
72848
|
const runBatches = () => spawnLintBatches({
|
|
71940
72849
|
baseArgs,
|
|
71941
72850
|
fileBatches,
|
|
71942
72851
|
rootDirectory,
|
|
71943
72852
|
nodeBinaryPath,
|
|
71944
|
-
project,
|
|
72853
|
+
project: lintProject,
|
|
72854
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
71945
72855
|
onPartialFailure,
|
|
71946
72856
|
onAnalyzedFiles: (filePaths) => {
|
|
71947
72857
|
analyzedFiles = filePaths;
|
|
@@ -73517,7 +74427,8 @@ const SCANNABLE_EXTENSIONS = [
|
|
|
73517
74427
|
".js",
|
|
73518
74428
|
".jsx",
|
|
73519
74429
|
".mts",
|
|
73520
|
-
".mjs"
|
|
74430
|
+
".mjs",
|
|
74431
|
+
".html"
|
|
73521
74432
|
];
|
|
73522
74433
|
const SILENT_LOGGER = {
|
|
73523
74434
|
info: () => {},
|
|
@@ -75505,5 +76416,5 @@ const startLanguageServer = () => {
|
|
|
75505
76416
|
};
|
|
75506
76417
|
//#endregion
|
|
75507
76418
|
export { startLanguageServer };
|
|
75508
|
-
!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]="
|
|
75509
|
-
//# debugId=
|
|
76419
|
+
!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]="6a2a246a-da30-59c5-aa97-af8188206b96")}catch(e){}}();
|
|
76420
|
+
//# debugId=6a2a246a-da30-59c5-aa97-af8188206b96
|