react-doctor 0.9.1 → 0.9.2-dev.3f3197f
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 +1180 -151
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1150 -142
- package/dist/lsp.js +1158 -144
- package/dist/{run-scan-app-DZ5jGWFf.js → run-scan-app-C9MJnVwv.js} +281 -210
- package/package.json +7 -6
package/dist/lsp.js
CHANGED
|
@@ -10,6 +10,7 @@ import * as Crypto from "node:crypto";
|
|
|
10
10
|
import crypto, { createHash } from "node:crypto";
|
|
11
11
|
import * as NodeChildProcess from "node:child_process";
|
|
12
12
|
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
13
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
13
14
|
import ts from "typescript";
|
|
14
15
|
import { parseJSON5 } from "confbox";
|
|
15
16
|
import * as NodeUrl from "node:url";
|
|
@@ -61478,7 +61479,8 @@ var AmbiguousProjectError = class extends Error {
|
|
|
61478
61479
|
}
|
|
61479
61480
|
};
|
|
61480
61481
|
const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
|
|
61481
|
-
const
|
|
61482
|
+
const HTML_FILE_PATTERN = /\.html$/i;
|
|
61483
|
+
const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
|
|
61482
61484
|
const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
|
|
61483
61485
|
const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
|
|
61484
61486
|
const MINIFIED_SNIFF_BYTES = 65536;
|
|
@@ -61844,7 +61846,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
61844
61846
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
61845
61847
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
61846
61848
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
61847
|
-
const CORE_PACKAGE_VERSION = "0.9.
|
|
61849
|
+
const CORE_PACKAGE_VERSION = "0.9.2";
|
|
61848
61850
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
61849
61851
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
61850
61852
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -62094,8 +62096,13 @@ const findMonorepoRoot = (startDirectory) => {
|
|
|
62094
62096
|
* byte-equivalent copy.
|
|
62095
62097
|
*/
|
|
62096
62098
|
const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
|
|
62099
|
+
const unwrapTypescriptExpression = (expression) => {
|
|
62100
|
+
let currentExpression = expression;
|
|
62101
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
62102
|
+
return currentExpression;
|
|
62103
|
+
};
|
|
62097
62104
|
const TSCONFIG_FILENAME = "tsconfig.json";
|
|
62098
|
-
const
|
|
62105
|
+
const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
|
|
62099
62106
|
const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
|
|
62100
62107
|
const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
62101
62108
|
const requireFromConfig = createRequire(Path.join(fromConfigDirectory, "tsconfig.json"));
|
|
@@ -62112,7 +62119,12 @@ const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
|
62112
62119
|
return null;
|
|
62113
62120
|
};
|
|
62114
62121
|
const resolveExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
62115
|
-
if (
|
|
62122
|
+
if (isLocalModuleSpecifier(extendsValue)) {
|
|
62123
|
+
const resolvedPath = Path.resolve(fromConfigDirectory, extendsValue);
|
|
62124
|
+
if (isFile(resolvedPath)) return resolvedPath;
|
|
62125
|
+
const directoryConfigPath = Path.join(resolvedPath, TSCONFIG_FILENAME);
|
|
62126
|
+
return isFile(directoryConfigPath) ? directoryConfigPath : ensureJsonExtension(resolvedPath);
|
|
62127
|
+
}
|
|
62116
62128
|
return resolvePackageExtendsPath(extendsValue, fromConfigDirectory);
|
|
62117
62129
|
};
|
|
62118
62130
|
const normalizeCompilerOptions = (compilerOptions) => {
|
|
@@ -62306,6 +62318,15 @@ const REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS = [
|
|
|
62306
62318
|
".cts",
|
|
62307
62319
|
".json"
|
|
62308
62320
|
];
|
|
62321
|
+
const REACT_COMPILER_CONFIG_RESOLVER = new ResolverFactory({
|
|
62322
|
+
conditionNames: [
|
|
62323
|
+
"import",
|
|
62324
|
+
"require",
|
|
62325
|
+
"node",
|
|
62326
|
+
"default"
|
|
62327
|
+
],
|
|
62328
|
+
extensions: REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS
|
|
62329
|
+
});
|
|
62309
62330
|
const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
|
|
62310
62331
|
const hasCompilerPackage = (packageJson, compilerPackages) => {
|
|
62311
62332
|
const allDependencies = {
|
|
@@ -62329,6 +62350,18 @@ const hasCompilerPackageInAncestors = (directory, compilerPackages) => {
|
|
|
62329
62350
|
return false;
|
|
62330
62351
|
};
|
|
62331
62352
|
const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
62353
|
+
if (!isLocalModuleSpecifier(moduleSpecifier)) {
|
|
62354
|
+
try {
|
|
62355
|
+
const resolvedPath = REACT_COMPILER_CONFIG_RESOLVER.resolveFileSync(fromFilePath, moduleSpecifier).path;
|
|
62356
|
+
if (resolvedPath && isFile(resolvedPath)) return resolvedPath;
|
|
62357
|
+
} catch {}
|
|
62358
|
+
try {
|
|
62359
|
+
const resolvedPath = createRequire(fromFilePath).resolve(moduleSpecifier);
|
|
62360
|
+
return isFile(resolvedPath) ? resolvedPath : null;
|
|
62361
|
+
} catch {
|
|
62362
|
+
return null;
|
|
62363
|
+
}
|
|
62364
|
+
}
|
|
62332
62365
|
const unresolvedPath = Path.resolve(Path.dirname(fromFilePath), moduleSpecifier);
|
|
62333
62366
|
const extension = Path.extname(unresolvedPath);
|
|
62334
62367
|
return (extension ? [unresolvedPath, ...REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS.map((sourceExtension) => `${unresolvedPath.slice(0, -extension.length)}${sourceExtension}`)] : [
|
|
@@ -62338,10 +62371,10 @@ const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
|
62338
62371
|
]).find(isFile) ?? null;
|
|
62339
62372
|
};
|
|
62340
62373
|
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$
|
|
62374
|
+
const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
|
|
62342
62375
|
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
62376
|
const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
|
|
62344
|
-
const getRequireModuleSpecifier = (expression) => {
|
|
62377
|
+
const getRequireModuleSpecifier$1 = (expression) => {
|
|
62345
62378
|
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
|
|
62346
62379
|
const moduleSpecifier = expression.arguments[0];
|
|
62347
62380
|
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
@@ -62354,7 +62387,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
62354
62387
|
const namedBindings = importClause?.namedBindings;
|
|
62355
62388
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
62356
62389
|
}
|
|
62357
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
62390
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
62358
62391
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
62359
62392
|
});
|
|
62360
62393
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -62385,24 +62418,24 @@ const getImportBinding = (sourceFile, bindingName) => {
|
|
|
62385
62418
|
for (const declaration of statement.declarationList.declarations) {
|
|
62386
62419
|
if (!declaration.initializer) continue;
|
|
62387
62420
|
if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
|
|
62388
|
-
const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62421
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62389
62422
|
if (directModuleSpecifier) return {
|
|
62390
62423
|
moduleSpecifier: directModuleSpecifier,
|
|
62391
62424
|
exportName: "default",
|
|
62392
62425
|
isNamespace: true
|
|
62393
62426
|
};
|
|
62394
|
-
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
|
|
62395
|
-
moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
|
|
62427
|
+
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
|
|
62428
|
+
moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
|
|
62396
62429
|
exportName: declaration.initializer.name.text,
|
|
62397
62430
|
isNamespace: false
|
|
62398
62431
|
};
|
|
62399
62432
|
}
|
|
62400
62433
|
if (!ts.isObjectBindingPattern(declaration.name)) continue;
|
|
62401
62434
|
const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
|
|
62402
|
-
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62435
|
+
const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62403
62436
|
if (bindingElement && moduleSpecifier) return {
|
|
62404
62437
|
moduleSpecifier,
|
|
62405
|
-
exportName: bindingElement.propertyName ? getStaticPropertyName$
|
|
62438
|
+
exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
|
|
62406
62439
|
isNamespace: false
|
|
62407
62440
|
};
|
|
62408
62441
|
}
|
|
@@ -62455,6 +62488,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
62455
62488
|
};
|
|
62456
62489
|
};
|
|
62457
62490
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
62491
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
62492
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
62493
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
62494
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
62495
|
+
if (!ts.isCallExpression(node)) return false;
|
|
62496
|
+
const target = node.expression;
|
|
62497
|
+
if (ts.isIdentifier(target)) {
|
|
62498
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
62499
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
62500
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
62501
|
+
}
|
|
62502
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
62503
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
62504
|
+
const createRequireReceiver = target.expression;
|
|
62505
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
62506
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
62507
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
62508
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
62509
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
62510
|
+
}
|
|
62511
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
62512
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
62513
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
62514
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
62515
|
+
};
|
|
62516
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
62517
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
62518
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
62519
|
+
const target = callExpression.expression;
|
|
62520
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62521
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
62522
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
62523
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
62524
|
+
const resolverIdentifier = target.expression;
|
|
62525
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
62526
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
62527
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
62528
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
62529
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
62530
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
62531
|
+
return moduleSpecifierNode.text;
|
|
62532
|
+
};
|
|
62458
62533
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
62459
62534
|
let bindingScope = null;
|
|
62460
62535
|
let currentNode = identifier;
|
|
@@ -62497,9 +62572,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
|
62497
62572
|
initializer: assignedInitializer
|
|
62498
62573
|
};
|
|
62499
62574
|
};
|
|
62500
|
-
const getStaticConfigValueState = (expression, analysis) => {
|
|
62501
|
-
|
|
62502
|
-
|
|
62575
|
+
const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
62576
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
62577
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
62578
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
62579
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
62503
62580
|
if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
|
|
62504
62581
|
isNullish: true,
|
|
62505
62582
|
isTruthy: false
|
|
@@ -62515,31 +62592,31 @@ const getStaticConfigValueState = (expression, analysis) => {
|
|
|
62515
62592
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
62516
62593
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
62517
62594
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
62518
|
-
return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
|
|
62595
|
+
return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
62519
62596
|
}
|
|
62520
62597
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
62521
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
|
|
62598
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
62522
62599
|
}
|
|
62523
62600
|
if (ts.isConditionalExpression(unwrappedExpression)) {
|
|
62524
|
-
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
|
|
62525
|
-
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
|
|
62526
|
-
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
|
|
62527
|
-
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
|
|
62601
|
+
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
|
|
62602
|
+
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
62603
|
+
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
|
|
62604
|
+
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
62528
62605
|
return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
|
|
62529
62606
|
}
|
|
62530
62607
|
if (ts.isBinaryExpression(unwrappedExpression)) {
|
|
62531
|
-
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
|
|
62608
|
+
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
|
|
62532
62609
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
62533
62610
|
if (leftState === null) return null;
|
|
62534
|
-
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
62611
|
+
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
62535
62612
|
}
|
|
62536
62613
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
62537
62614
|
if (leftState === null) return null;
|
|
62538
|
-
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
|
|
62615
|
+
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
|
|
62539
62616
|
}
|
|
62540
62617
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
62541
62618
|
if (leftState === null) return null;
|
|
62542
|
-
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
62619
|
+
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
62543
62620
|
}
|
|
62544
62621
|
}
|
|
62545
62622
|
return null;
|
|
@@ -62548,25 +62625,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
|
|
|
62548
62625
|
const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
|
|
62549
62626
|
const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
|
|
62550
62627
|
const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
|
|
62551
|
-
const getReactCompilerFlagState = (expression, analysis) => {
|
|
62552
|
-
|
|
62553
|
-
|
|
62628
|
+
const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
62629
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
62630
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
62631
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
62632
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
62554
62633
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
62555
62634
|
const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
|
|
62556
62635
|
if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
|
|
62557
62636
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
62558
62637
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
62559
|
-
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
|
|
62638
|
+
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
62560
62639
|
}
|
|
62561
62640
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
62562
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
|
|
62641
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
62563
62642
|
}
|
|
62564
62643
|
if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
|
|
62565
62644
|
for (const property of [...unwrappedExpression.properties].reverse()) {
|
|
62566
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62645
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
|
|
62567
62646
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
|
|
62568
62647
|
if (ts.isSpreadAssignment(property)) {
|
|
62569
|
-
const spreadState = getReactCompilerFlagState(property.expression, analysis);
|
|
62648
|
+
const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
|
|
62570
62649
|
if (spreadState) return spreadState;
|
|
62571
62650
|
}
|
|
62572
62651
|
}
|
|
@@ -62589,8 +62668,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
|
|
|
62589
62668
|
}
|
|
62590
62669
|
if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
|
|
62591
62670
|
for (const property of [...resolvedExpression.properties].reverse()) {
|
|
62592
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62593
|
-
if (ts.isMethodDeclaration(property) && getStaticPropertyName$
|
|
62671
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return property.initializer;
|
|
62672
|
+
if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return property;
|
|
62594
62673
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
|
|
62595
62674
|
if (ts.isSpreadAssignment(property)) {
|
|
62596
62675
|
const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
|
|
@@ -62621,7 +62700,7 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
|
|
|
62621
62700
|
return resolvedExpression.properties.some((property) => {
|
|
62622
62701
|
if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
|
|
62623
62702
|
if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
|
|
62624
|
-
const staticPropertyName = getStaticPropertyName$
|
|
62703
|
+
const staticPropertyName = getStaticPropertyName$2(property.name);
|
|
62625
62704
|
return staticPropertyName === null || staticPropertyName === propertyName;
|
|
62626
62705
|
}
|
|
62627
62706
|
return false;
|
|
@@ -62640,7 +62719,7 @@ const getExportedConfigNodes = (sourceFile, exportName) => {
|
|
|
62640
62719
|
continue;
|
|
62641
62720
|
}
|
|
62642
62721
|
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$
|
|
62722
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === exportName) {
|
|
62644
62723
|
exportedNodes.push(property.initializer);
|
|
62645
62724
|
break;
|
|
62646
62725
|
}
|
|
@@ -62738,6 +62817,11 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
|
|
|
62738
62817
|
visitReturns(functionNode.body);
|
|
62739
62818
|
return hasCompiler;
|
|
62740
62819
|
};
|
|
62820
|
+
const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
|
|
62821
|
+
const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
|
|
62822
|
+
if (!importedFilePath) return null;
|
|
62823
|
+
return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList);
|
|
62824
|
+
};
|
|
62741
62825
|
const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
|
|
62742
62826
|
const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
|
|
62743
62827
|
if (assignedReactCompiler.initializer && !isStaticallyDisabledConfigExpression(assignedReactCompiler.initializer, analysis)) return true;
|
|
@@ -62758,30 +62842,62 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
|
|
|
62758
62842
|
const importBinding = getImportBinding(analysis.sourceFile, identifier.text);
|
|
62759
62843
|
if (importBinding) {
|
|
62760
62844
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
62761
|
-
|
|
62762
|
-
|
|
62763
|
-
|
|
62845
|
+
return Boolean(analyzeImportedConfig({
|
|
62846
|
+
analysis,
|
|
62847
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62848
|
+
exportName: importBinding.exportName,
|
|
62849
|
+
allowCompilerTransform
|
|
62850
|
+
}));
|
|
62764
62851
|
}
|
|
62765
62852
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, identifier.text);
|
|
62766
62853
|
return Boolean(topLevelBinding && analyzeConfigNode(topLevelBinding, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
|
|
62767
62854
|
};
|
|
62768
62855
|
const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransform) => {
|
|
62769
62856
|
const target = callExpression.expression;
|
|
62857
|
+
const callableRequiredModuleSpecifier = getRequireModuleSpecifier$1(target);
|
|
62858
|
+
if (callableRequiredModuleSpecifier !== null) {
|
|
62859
|
+
if (ts.isCallExpression(target) && ts.isIdentifier(target.expression) && (analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62860
|
+
if (allowCompilerTransform && isCompilerTransformModule(callableRequiredModuleSpecifier, "default")) return true;
|
|
62861
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62862
|
+
analysis,
|
|
62863
|
+
moduleSpecifier: callableRequiredModuleSpecifier,
|
|
62864
|
+
exportName: "default",
|
|
62865
|
+
allowCompilerTransform,
|
|
62866
|
+
argumentsList: callExpression.arguments
|
|
62867
|
+
});
|
|
62868
|
+
if (isLocalModuleSpecifier(callableRequiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62869
|
+
return null;
|
|
62870
|
+
}
|
|
62770
62871
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62771
62872
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
62772
62873
|
if (propertyName === null) return null;
|
|
62773
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
|
|
62874
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
62774
62875
|
if (requiredModuleSpecifier !== null) {
|
|
62775
|
-
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62776
|
-
if (
|
|
62777
|
-
const
|
|
62778
|
-
|
|
62876
|
+
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (analysis.localBindings.has(target.expression.expression.text) || getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62877
|
+
if (allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, propertyName)) return true;
|
|
62878
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62879
|
+
analysis,
|
|
62880
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
62881
|
+
exportName: propertyName,
|
|
62882
|
+
allowCompilerTransform,
|
|
62883
|
+
argumentsList: callExpression.arguments
|
|
62884
|
+
});
|
|
62885
|
+
if (isLocalModuleSpecifier(requiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62886
|
+
return null;
|
|
62779
62887
|
}
|
|
62780
62888
|
if (!ts.isIdentifier(target.expression)) return null;
|
|
62781
|
-
const importBinding = getImportBinding(analysis.sourceFile, target.expression.text);
|
|
62782
|
-
if (importBinding?.isNamespace
|
|
62783
|
-
|
|
62784
|
-
|
|
62889
|
+
const importBinding = analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound ? null : getImportBinding(analysis.sourceFile, target.expression.text);
|
|
62890
|
+
if (importBinding?.isNamespace) {
|
|
62891
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, propertyName)) return true;
|
|
62892
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62893
|
+
analysis,
|
|
62894
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62895
|
+
exportName: propertyName,
|
|
62896
|
+
allowCompilerTransform,
|
|
62897
|
+
argumentsList: callExpression.arguments
|
|
62898
|
+
});
|
|
62899
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62900
|
+
return null;
|
|
62785
62901
|
}
|
|
62786
62902
|
const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
|
|
62787
62903
|
if (selectedProperty === null) return null;
|
|
@@ -62799,25 +62915,29 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62799
62915
|
const reactCompilerFlagState = excludedPropertyNames?.has("reactCompiler") ? null : getReactCompilerFlagState(node, analysis);
|
|
62800
62916
|
if (reactCompilerFlagState?.isEnabled) return true;
|
|
62801
62917
|
for (const [propertyIndex, property] of node.properties.entries()) if (ts.isPropertyAssignment(property)) {
|
|
62802
|
-
const propertyName = getStaticPropertyName$
|
|
62918
|
+
const propertyName = getStaticPropertyName$2(property.name);
|
|
62803
62919
|
if (propertyName && excludedPropertyNames?.has(propertyName)) continue;
|
|
62804
62920
|
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$
|
|
62921
|
+
if ((propertyName === "plugins" || propertyName === "presets") && node.properties.slice(propertyIndex + 1).some((laterProperty) => ts.isSpreadAssignment(laterProperty) && configExpressionMayDefineProperty(laterProperty.expression, propertyName, analysis) || (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && getStaticPropertyName$2(laterProperty.name) === propertyName)) continue;
|
|
62806
62922
|
const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
|
|
62807
|
-
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)
|
|
62808
|
-
|
|
62809
|
-
|
|
62923
|
+
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)) {
|
|
62924
|
+
if (analyzeImportedConfig({
|
|
62925
|
+
analysis,
|
|
62926
|
+
moduleSpecifier: property.initializer.text,
|
|
62927
|
+
exportName: "default",
|
|
62928
|
+
allowCompilerTransform: false
|
|
62929
|
+
})) return true;
|
|
62810
62930
|
}
|
|
62811
62931
|
if (analyzeConfigNode(property.initializer, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
62812
62932
|
} else if (ts.isShorthandPropertyAssignment(property)) {
|
|
62813
62933
|
if (excludedPropertyNames?.has(property.name.text)) continue;
|
|
62814
62934
|
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$
|
|
62935
|
+
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
62936
|
const propertyAllowsCompilerTransform = property.name.text === "plugins" || property.name.text === "presets";
|
|
62817
62937
|
if (analyzeConfigNode(property.name, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
62818
62938
|
} else if (ts.isSpreadAssignment(property)) {
|
|
62819
62939
|
if (reactCompilerFlagState && getReactCompilerFlagState(property.expression, analysis) !== null) continue;
|
|
62820
|
-
if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$
|
|
62940
|
+
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
62941
|
if (analyzeConfigNode(property.expression, analysis, allowCompilerTransform, false, excludedPropertyNames)) return true;
|
|
62822
62942
|
}
|
|
62823
62943
|
return false;
|
|
@@ -62830,23 +62950,36 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62830
62950
|
});
|
|
62831
62951
|
}
|
|
62832
62952
|
if (ts.isCallExpression(node)) {
|
|
62953
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
62954
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
62833
62955
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
62834
62956
|
if (callTargetResult !== null) return callTargetResult;
|
|
62835
|
-
const directModuleSpecifier = getRequireModuleSpecifier(node);
|
|
62957
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
62836
62958
|
const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
|
|
62837
62959
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
62838
62960
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
62839
62961
|
if (allowCompilerTransform && isCompilerTransformModule(directModuleSpecifier, "default")) return true;
|
|
62840
|
-
if (
|
|
62841
|
-
|
|
62842
|
-
|
|
62843
|
-
|
|
62962
|
+
if (analyzeImportedConfig({
|
|
62963
|
+
analysis,
|
|
62964
|
+
moduleSpecifier: directModuleSpecifier,
|
|
62965
|
+
exportName: "default",
|
|
62966
|
+
allowCompilerTransform
|
|
62967
|
+
})) return true;
|
|
62844
62968
|
}
|
|
62845
62969
|
if (ts.isIdentifier(node.expression)) {
|
|
62846
|
-
|
|
62847
|
-
|
|
62848
|
-
|
|
62849
|
-
|
|
62970
|
+
if (!analysis.localBindings.has(node.expression.text) && !getScopedConfigBinding(node.expression).wasFound) {
|
|
62971
|
+
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62972
|
+
if (importBinding) {
|
|
62973
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
62974
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62975
|
+
analysis,
|
|
62976
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62977
|
+
exportName: importBinding.exportName,
|
|
62978
|
+
allowCompilerTransform,
|
|
62979
|
+
argumentsList: node.arguments
|
|
62980
|
+
});
|
|
62981
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62982
|
+
}
|
|
62850
62983
|
}
|
|
62851
62984
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, node.expression.text);
|
|
62852
62985
|
if (topLevelBinding && ts.isFunctionLike(topLevelBinding) && analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, node.arguments)) return true;
|
|
@@ -62854,27 +62987,31 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62854
62987
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
|
|
62855
62988
|
}
|
|
62856
62989
|
if (ts.isPropertyAccessExpression(node)) {
|
|
62857
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
|
|
62990
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
62858
62991
|
if (requiredModuleSpecifier) {
|
|
62859
|
-
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62860
|
-
if (
|
|
62861
|
-
|
|
62862
|
-
|
|
62863
|
-
|
|
62992
|
+
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (analysis.localBindings.has(node.expression.expression.text) || getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62993
|
+
if (analyzeImportedConfig({
|
|
62994
|
+
analysis,
|
|
62995
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
62996
|
+
exportName: node.name.text,
|
|
62997
|
+
allowCompilerTransform
|
|
62998
|
+
})) return true;
|
|
62864
62999
|
return allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, node.name.text);
|
|
62865
63000
|
}
|
|
62866
63001
|
if (ts.isIdentifier(node.expression)) {
|
|
62867
|
-
if (analysis.localBindings.has(node.expression.text)) {
|
|
62868
|
-
const
|
|
62869
|
-
return Boolean(
|
|
63002
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
63003
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
63004
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
62870
63005
|
}
|
|
62871
63006
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62872
63007
|
if (importBinding?.isNamespace) {
|
|
62873
63008
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.name.text)) return true;
|
|
62874
|
-
if (
|
|
62875
|
-
|
|
62876
|
-
|
|
62877
|
-
|
|
63009
|
+
if (analyzeImportedConfig({
|
|
63010
|
+
analysis,
|
|
63011
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
63012
|
+
exportName: node.name.text,
|
|
63013
|
+
allowCompilerTransform
|
|
63014
|
+
})) return true;
|
|
62878
63015
|
return false;
|
|
62879
63016
|
}
|
|
62880
63017
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
@@ -62885,13 +63022,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62885
63022
|
}
|
|
62886
63023
|
if (ts.isElementAccessExpression(node) && node.argumentExpression && ts.isStringLiteralLike(node.argumentExpression)) {
|
|
62887
63024
|
if (ts.isIdentifier(node.expression)) {
|
|
63025
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
63026
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
63027
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
63028
|
+
}
|
|
62888
63029
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62889
63030
|
if (importBinding?.isNamespace) {
|
|
62890
63031
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.argumentExpression.text)) return true;
|
|
62891
|
-
|
|
62892
|
-
|
|
62893
|
-
|
|
62894
|
-
|
|
63032
|
+
return Boolean(analyzeImportedConfig({
|
|
63033
|
+
analysis,
|
|
63034
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
63035
|
+
exportName: node.argumentExpression.text,
|
|
63036
|
+
allowCompilerTransform
|
|
63037
|
+
}));
|
|
62895
63038
|
}
|
|
62896
63039
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
62897
63040
|
if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
@@ -62929,14 +63072,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62929
63072
|
};
|
|
62930
63073
|
const hasCompilerInConfigFile = (filePath) => analyzeConfigModuleExport(filePath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
62931
63074
|
const hasCompilerInConfigFiles = (directory, filenames) => filenames.some((filename) => hasCompilerInConfigFile(Path.join(directory, filename)));
|
|
62932
|
-
const hasCompilerInPackageJsonConfig = (
|
|
62933
|
-
|
|
63075
|
+
const hasCompilerInPackageJsonConfig = (directory, packageJson) => {
|
|
63076
|
+
if (!isPlainObject(packageJson.babel)) return false;
|
|
63077
|
+
const packageJsonPath = Path.join(directory, "package.json");
|
|
63078
|
+
return analyzeConfigSourceFileExport(ts.parseJsonText(packageJsonPath, JSON.stringify(packageJson.babel)), packageJsonPath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
63079
|
+
};
|
|
63080
|
+
const hasCompilerConfiguration = (directory, packageJson) => hasCompilerInPackageJsonConfig(directory, packageJson) || hasCompilerInConfigFiles(directory, REACT_COMPILER_CONFIG_FILENAMES);
|
|
62934
63081
|
const hasCompilerConfigurationInAncestors = (directory) => {
|
|
62935
63082
|
if (isProjectBoundary(directory)) return false;
|
|
62936
63083
|
let ancestorDirectory = Path.dirname(directory);
|
|
62937
63084
|
while (ancestorDirectory !== Path.dirname(ancestorDirectory)) {
|
|
62938
63085
|
const ancestorPackagePath = Path.join(ancestorDirectory, "package.json");
|
|
62939
|
-
|
|
63086
|
+
const ancestorPackageJson = isFile(ancestorPackagePath) ? readPackageJson(ancestorPackagePath) : {};
|
|
63087
|
+
if (hasCompilerInPackageJsonConfig(ancestorDirectory, ancestorPackageJson) || hasCompilerInConfigFiles(ancestorDirectory, BABEL_CONFIG_FILENAMES)) return true;
|
|
62940
63088
|
if (isProjectBoundary(ancestorDirectory)) return false;
|
|
62941
63089
|
ancestorDirectory = Path.dirname(ancestorDirectory);
|
|
62942
63090
|
}
|
|
@@ -66165,7 +66313,7 @@ const warn = (message) => {
|
|
|
66165
66313
|
runSync(warn$1(message));
|
|
66166
66314
|
};
|
|
66167
66315
|
const CONFIG_BASENAME = "doctor.config";
|
|
66168
|
-
const CONFIG_EXTENSIONS = [
|
|
66316
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
66169
66317
|
"ts",
|
|
66170
66318
|
"mts",
|
|
66171
66319
|
"cts",
|
|
@@ -66269,7 +66417,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
66269
66417
|
};
|
|
66270
66418
|
const loadConfigFromDirectory = async (directory) => {
|
|
66271
66419
|
let sawBrokenConfigFile = false;
|
|
66272
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
66420
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
66273
66421
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
66274
66422
|
if (!isFile(filePath)) continue;
|
|
66275
66423
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -66956,6 +67104,316 @@ const buildReactNativeDiagnostic = (input) => ({
|
|
|
66956
67104
|
column: input.column ?? 0,
|
|
66957
67105
|
category: input.category ?? "Correctness"
|
|
66958
67106
|
});
|
|
67107
|
+
const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
|
|
67108
|
+
const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
|
|
67109
|
+
const RELEASE_STRING_MARKER = "__RD_RELEASE__";
|
|
67110
|
+
const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
|
|
67111
|
+
const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67112
|
+
const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67113
|
+
const stripGradleComments = (contents) => {
|
|
67114
|
+
let result = "";
|
|
67115
|
+
let index = 0;
|
|
67116
|
+
let quote = null;
|
|
67117
|
+
while (index < contents.length) {
|
|
67118
|
+
const character = contents[index];
|
|
67119
|
+
const nextCharacter = contents[index + 1];
|
|
67120
|
+
if (quote !== null) {
|
|
67121
|
+
result += character;
|
|
67122
|
+
if (character === "\\") {
|
|
67123
|
+
result += nextCharacter ?? "";
|
|
67124
|
+
index += 2;
|
|
67125
|
+
continue;
|
|
67126
|
+
}
|
|
67127
|
+
if (character === quote) quote = null;
|
|
67128
|
+
index += 1;
|
|
67129
|
+
continue;
|
|
67130
|
+
}
|
|
67131
|
+
if (character === "\"" || character === "'") {
|
|
67132
|
+
quote = character;
|
|
67133
|
+
result += character;
|
|
67134
|
+
index += 1;
|
|
67135
|
+
continue;
|
|
67136
|
+
}
|
|
67137
|
+
if (character === "/" && nextCharacter === "/") {
|
|
67138
|
+
while (index < contents.length && contents[index] !== "\n") {
|
|
67139
|
+
result += " ";
|
|
67140
|
+
index += 1;
|
|
67141
|
+
}
|
|
67142
|
+
continue;
|
|
67143
|
+
}
|
|
67144
|
+
if (character === "/" && nextCharacter === "*") {
|
|
67145
|
+
result += " ";
|
|
67146
|
+
index += 2;
|
|
67147
|
+
while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
|
|
67148
|
+
result += contents[index] === "\n" ? "\n" : " ";
|
|
67149
|
+
index += 1;
|
|
67150
|
+
}
|
|
67151
|
+
if (index < contents.length) {
|
|
67152
|
+
result += " ";
|
|
67153
|
+
index += 2;
|
|
67154
|
+
}
|
|
67155
|
+
continue;
|
|
67156
|
+
}
|
|
67157
|
+
result += character;
|
|
67158
|
+
index += 1;
|
|
67159
|
+
}
|
|
67160
|
+
return result;
|
|
67161
|
+
};
|
|
67162
|
+
const maskGradleStrings = (contents) => {
|
|
67163
|
+
let result = "";
|
|
67164
|
+
let index = 0;
|
|
67165
|
+
let quote = null;
|
|
67166
|
+
while (index < contents.length) {
|
|
67167
|
+
const character = contents[index];
|
|
67168
|
+
if (quote === null) {
|
|
67169
|
+
if (character === "\"" || character === "'") {
|
|
67170
|
+
quote = character;
|
|
67171
|
+
result += " ";
|
|
67172
|
+
} else result += character;
|
|
67173
|
+
index += 1;
|
|
67174
|
+
continue;
|
|
67175
|
+
}
|
|
67176
|
+
if (character === "\\") {
|
|
67177
|
+
result += " ";
|
|
67178
|
+
index += 2;
|
|
67179
|
+
continue;
|
|
67180
|
+
}
|
|
67181
|
+
if (character === quote) quote = null;
|
|
67182
|
+
result += character === "\n" ? "\n" : " ";
|
|
67183
|
+
index += 1;
|
|
67184
|
+
}
|
|
67185
|
+
return result;
|
|
67186
|
+
};
|
|
67187
|
+
const findBlockContents = (contents, pattern) => {
|
|
67188
|
+
const blocks = [];
|
|
67189
|
+
pattern.lastIndex = 0;
|
|
67190
|
+
let match = pattern.exec(contents);
|
|
67191
|
+
while (match !== null) {
|
|
67192
|
+
const openingBraceIndex = pattern.lastIndex - 1;
|
|
67193
|
+
let depth = 1;
|
|
67194
|
+
let index = openingBraceIndex + 1;
|
|
67195
|
+
let quote = null;
|
|
67196
|
+
while (index < contents.length && depth > 0) {
|
|
67197
|
+
const character = contents[index];
|
|
67198
|
+
if (quote !== null) {
|
|
67199
|
+
if (character === "\\") {
|
|
67200
|
+
index += 2;
|
|
67201
|
+
continue;
|
|
67202
|
+
}
|
|
67203
|
+
if (character === quote) quote = null;
|
|
67204
|
+
} else if (character === "\"" || character === "'") quote = character;
|
|
67205
|
+
else if (character === "{") depth += 1;
|
|
67206
|
+
else if (character === "}") depth -= 1;
|
|
67207
|
+
index += 1;
|
|
67208
|
+
}
|
|
67209
|
+
if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
|
|
67210
|
+
match = pattern.exec(contents);
|
|
67211
|
+
}
|
|
67212
|
+
return blocks;
|
|
67213
|
+
};
|
|
67214
|
+
const getFinalStaticBoolean = (contents, pattern) => {
|
|
67215
|
+
pattern.lastIndex = 0;
|
|
67216
|
+
let finalValue = null;
|
|
67217
|
+
let match = pattern.exec(contents);
|
|
67218
|
+
while (match !== null) {
|
|
67219
|
+
const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
|
|
67220
|
+
if (staticValue === "true") finalValue = true;
|
|
67221
|
+
else if (staticValue === "false") finalValue = false;
|
|
67222
|
+
else finalValue = null;
|
|
67223
|
+
match = pattern.exec(contents);
|
|
67224
|
+
}
|
|
67225
|
+
return finalValue;
|
|
67226
|
+
};
|
|
67227
|
+
const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
|
|
67228
|
+
const readAndroidReleaseShrinking = (rootDirectory) => {
|
|
67229
|
+
for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
|
|
67230
|
+
const filePath = Path.posix.join("android", "app", buildFileName);
|
|
67231
|
+
const absoluteFilePath = Path.join(rootDirectory, filePath);
|
|
67232
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67233
|
+
let contents;
|
|
67234
|
+
try {
|
|
67235
|
+
contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
|
|
67236
|
+
} catch {
|
|
67237
|
+
return null;
|
|
67238
|
+
}
|
|
67239
|
+
const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
|
|
67240
|
+
const [releaseBlock] = releaseBlocks;
|
|
67241
|
+
if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
|
|
67242
|
+
const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
|
|
67243
|
+
const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
|
|
67244
|
+
if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
|
|
67245
|
+
return {
|
|
67246
|
+
filePath,
|
|
67247
|
+
hasDisabledMinification,
|
|
67248
|
+
hasDisabledResourceShrinking
|
|
67249
|
+
};
|
|
67250
|
+
}
|
|
67251
|
+
return null;
|
|
67252
|
+
};
|
|
67253
|
+
const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
|
|
67254
|
+
const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
|
|
67255
|
+
if (releaseShrinking === null) return [];
|
|
67256
|
+
const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
|
|
67257
|
+
return [buildReactNativeDiagnostic({
|
|
67258
|
+
filePath: releaseShrinking.filePath,
|
|
67259
|
+
rule: "rn-android-release-shrinking-disabled",
|
|
67260
|
+
category: "Performance",
|
|
67261
|
+
message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
|
|
67262
|
+
help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
|
|
67263
|
+
})];
|
|
67264
|
+
};
|
|
67265
|
+
const getTypescriptScriptKind = (fileName) => {
|
|
67266
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
67267
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
67268
|
+
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67269
|
+
return ts.ScriptKind.JS;
|
|
67270
|
+
};
|
|
67271
|
+
const BABEL_CONFIG_FILE_NAMES$1 = [
|
|
67272
|
+
"babel.config.js",
|
|
67273
|
+
"babel.config.cjs",
|
|
67274
|
+
"babel.config.mjs",
|
|
67275
|
+
"babel.config.ts",
|
|
67276
|
+
"babel.config.cts",
|
|
67277
|
+
"babel.config.json",
|
|
67278
|
+
".babelrc",
|
|
67279
|
+
".babelrc.js",
|
|
67280
|
+
".babelrc.cjs",
|
|
67281
|
+
".babelrc.mjs",
|
|
67282
|
+
".babelrc.cts",
|
|
67283
|
+
".babelrc.json"
|
|
67284
|
+
];
|
|
67285
|
+
const readUnknownPluginNames = (value) => {
|
|
67286
|
+
if (!Array.isArray(value)) return null;
|
|
67287
|
+
const pluginNames = [];
|
|
67288
|
+
for (const entry of value) {
|
|
67289
|
+
if (typeof entry === "string") {
|
|
67290
|
+
pluginNames.push(entry);
|
|
67291
|
+
continue;
|
|
67292
|
+
}
|
|
67293
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") {
|
|
67294
|
+
pluginNames.push(entry[0]);
|
|
67295
|
+
continue;
|
|
67296
|
+
}
|
|
67297
|
+
return null;
|
|
67298
|
+
}
|
|
67299
|
+
return pluginNames;
|
|
67300
|
+
};
|
|
67301
|
+
const getStaticPropertyName$1 = (propertyName) => {
|
|
67302
|
+
if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
|
|
67303
|
+
return null;
|
|
67304
|
+
};
|
|
67305
|
+
const getStaticPluginName = (expression) => {
|
|
67306
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
67307
|
+
if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
|
|
67308
|
+
if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
|
|
67309
|
+
const pluginExpression = unwrappedExpression.elements[0];
|
|
67310
|
+
return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
|
|
67311
|
+
};
|
|
67312
|
+
const getPluginNamesFromObject = (objectExpression) => {
|
|
67313
|
+
if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
|
|
67314
|
+
const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
|
|
67315
|
+
if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
|
|
67316
|
+
const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
|
|
67317
|
+
if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
|
|
67318
|
+
const pluginNames = [];
|
|
67319
|
+
for (const element of pluginListExpression.elements) {
|
|
67320
|
+
if (ts.isSpreadElement(element)) return null;
|
|
67321
|
+
const pluginName = getStaticPluginName(element);
|
|
67322
|
+
if (pluginName === null) return null;
|
|
67323
|
+
pluginNames.push(pluginName);
|
|
67324
|
+
}
|
|
67325
|
+
return pluginNames;
|
|
67326
|
+
};
|
|
67327
|
+
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";
|
|
67328
|
+
const getDirectExportedObject = (sourceFile) => {
|
|
67329
|
+
const exportedExpressions = [];
|
|
67330
|
+
for (const statement of sourceFile.statements) {
|
|
67331
|
+
if (ts.isExportAssignment(statement)) {
|
|
67332
|
+
exportedExpressions.push(statement.expression);
|
|
67333
|
+
continue;
|
|
67334
|
+
}
|
|
67335
|
+
if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
|
|
67336
|
+
}
|
|
67337
|
+
if (exportedExpressions.length !== 1) return null;
|
|
67338
|
+
const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
|
|
67339
|
+
return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
|
|
67340
|
+
};
|
|
67341
|
+
const parseConfigPluginNames = (filePath, contents) => {
|
|
67342
|
+
try {
|
|
67343
|
+
const parsedJson = JSON.parse(contents);
|
|
67344
|
+
return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
|
|
67345
|
+
} catch {
|
|
67346
|
+
if (ts.transpileModule(contents, {
|
|
67347
|
+
fileName: filePath,
|
|
67348
|
+
reportDiagnostics: true,
|
|
67349
|
+
compilerOptions: { allowJs: true }
|
|
67350
|
+
}).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
|
|
67351
|
+
const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
|
|
67352
|
+
return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
|
|
67353
|
+
}
|
|
67354
|
+
};
|
|
67355
|
+
const readStaticBabelPluginNames = (rootDirectory) => {
|
|
67356
|
+
for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
|
|
67357
|
+
const absoluteFilePath = Path.join(rootDirectory, fileName);
|
|
67358
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67359
|
+
try {
|
|
67360
|
+
return {
|
|
67361
|
+
filePath: fileName,
|
|
67362
|
+
pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
|
|
67363
|
+
};
|
|
67364
|
+
} catch {
|
|
67365
|
+
return {
|
|
67366
|
+
filePath: fileName,
|
|
67367
|
+
pluginNames: null
|
|
67368
|
+
};
|
|
67369
|
+
}
|
|
67370
|
+
}
|
|
67371
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
67372
|
+
if (!isPlainObject(packageJson.babel)) return null;
|
|
67373
|
+
return {
|
|
67374
|
+
filePath: "package.json",
|
|
67375
|
+
pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
|
|
67376
|
+
};
|
|
67377
|
+
};
|
|
67378
|
+
const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
|
|
67379
|
+
const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
|
|
67380
|
+
const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
|
|
67381
|
+
const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
|
|
67382
|
+
if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
|
|
67383
|
+
return [buildReactNativeDiagnostic({
|
|
67384
|
+
filePath,
|
|
67385
|
+
rule: "rn-react-compiler-plugin-first",
|
|
67386
|
+
category: "Performance",
|
|
67387
|
+
message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
|
|
67388
|
+
help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
|
|
67389
|
+
})];
|
|
67390
|
+
};
|
|
67391
|
+
const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
|
|
67392
|
+
const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
|
|
67393
|
+
if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
|
|
67394
|
+
const diagnostics = [];
|
|
67395
|
+
if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
|
|
67396
|
+
filePath,
|
|
67397
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67398
|
+
category: "Performance",
|
|
67399
|
+
message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
|
|
67400
|
+
help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
|
|
67401
|
+
}));
|
|
67402
|
+
const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
|
|
67403
|
+
if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
|
|
67404
|
+
filePath,
|
|
67405
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67406
|
+
category: "Performance",
|
|
67407
|
+
message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
|
|
67408
|
+
help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
|
|
67409
|
+
}));
|
|
67410
|
+
return diagnostics;
|
|
67411
|
+
};
|
|
67412
|
+
const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
|
|
67413
|
+
const babelPlugins = readStaticBabelPluginNames(rootDirectory);
|
|
67414
|
+
if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
|
|
67415
|
+
return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
|
|
67416
|
+
};
|
|
66959
67417
|
const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
|
|
66960
67418
|
const isBuilderBobLibrary = (packageJson) => {
|
|
66961
67419
|
const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
|
|
@@ -67032,7 +67490,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
67032
67490
|
const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
|
|
67033
67491
|
const checkReactNativeProject = (rootDirectory, project) => {
|
|
67034
67492
|
if (!isReactNativeProject(project)) return [];
|
|
67035
|
-
return [
|
|
67493
|
+
return [
|
|
67494
|
+
...checkReactNativeMetroBabelPreset(rootDirectory),
|
|
67495
|
+
...checkReactNativeBabelPluginOrder(rootDirectory, project),
|
|
67496
|
+
...checkReactNativeAndroidReleaseShrinking(rootDirectory),
|
|
67497
|
+
...checkReactNativeLibraryDependencies(rootDirectory)
|
|
67498
|
+
];
|
|
67036
67499
|
};
|
|
67037
67500
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
67038
67501
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
@@ -67183,17 +67646,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
|
|
|
67183
67646
|
}
|
|
67184
67647
|
return diagnostics;
|
|
67185
67648
|
};
|
|
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
67649
|
const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
|
|
67198
67650
|
isAnimationFunction: false,
|
|
67199
67651
|
isMotionComponent: false,
|
|
@@ -67749,7 +68201,11 @@ const buildCapabilities = (project) => {
|
|
|
67749
68201
|
capabilities.add(project.framework);
|
|
67750
68202
|
if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
|
|
67751
68203
|
if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
|
|
67752
|
-
if (project.expoVersion !== null)
|
|
68204
|
+
if (project.expoVersion !== null) {
|
|
68205
|
+
capabilities.add("expo");
|
|
68206
|
+
const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
|
|
68207
|
+
if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
|
|
68208
|
+
}
|
|
67753
68209
|
if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
|
|
67754
68210
|
if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
|
|
67755
68211
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
@@ -67813,6 +68269,11 @@ const buildCapabilities = (project) => {
|
|
|
67813
68269
|
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
67814
68270
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
67815
68271
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
68272
|
+
if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
|
|
68273
|
+
capabilities.add("reanimated");
|
|
68274
|
+
const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
|
|
68275
|
+
if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
|
|
68276
|
+
}
|
|
67816
68277
|
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
67817
68278
|
if (project.styledComponentsVersion) {
|
|
67818
68279
|
capabilities.add("styled-components");
|
|
@@ -69710,7 +70171,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
69710
70171
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
69711
70172
|
const normalizeConfigForHash = (config) => {
|
|
69712
70173
|
const clone = JSON.parse(JSON.stringify(config));
|
|
69713
|
-
if (clone?.settings?.["react-doctor"])
|
|
70174
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
70175
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
70176
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
70177
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
70178
|
+
}
|
|
69714
70179
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
69715
70180
|
return clone;
|
|
69716
70181
|
};
|
|
@@ -69869,13 +70334,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
69869
70334
|
}
|
|
69870
70335
|
return enabled;
|
|
69871
70336
|
};
|
|
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 }) => {
|
|
70337
|
+
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
70338
|
const hasIncludedTags = includedTags.size > 0;
|
|
69874
70339
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
69875
70340
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
69876
70341
|
const jsPlugins = [];
|
|
69877
70342
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
69878
70343
|
const capabilities = getCapabilities(project);
|
|
70344
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
69879
70345
|
const enabledReactDoctorRules = {};
|
|
69880
70346
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
69881
70347
|
const rule = reactDoctorPlugin.rules[registryEntry.id];
|
|
@@ -69921,8 +70387,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69921
70387
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
69922
70388
|
settings: { "react-doctor": {
|
|
69923
70389
|
framework: project.framework,
|
|
69924
|
-
rootDirectory:
|
|
70390
|
+
rootDirectory: settingsRootDirectory,
|
|
69925
70391
|
capabilities: [...capabilities].sort(),
|
|
70392
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
70393
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
70394
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
70395
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
70396
|
+
directory: scope.directory,
|
|
70397
|
+
names: [...scope.names]
|
|
70398
|
+
}))
|
|
70399
|
+
} : {},
|
|
69926
70400
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
69927
70401
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
69928
70402
|
} },
|
|
@@ -69933,6 +70407,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69933
70407
|
}
|
|
69934
70408
|
};
|
|
69935
70409
|
};
|
|
70410
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
70411
|
+
const CONFIG_BASENAMES = [
|
|
70412
|
+
"astro.config",
|
|
70413
|
+
"esbuild.config",
|
|
70414
|
+
"rollup.config",
|
|
70415
|
+
"rolldown.config",
|
|
70416
|
+
"rspack.config",
|
|
70417
|
+
"vite.config",
|
|
70418
|
+
"webpack.config"
|
|
70419
|
+
];
|
|
70420
|
+
const CONFIG_EXTENSIONS = [
|
|
70421
|
+
".cjs",
|
|
70422
|
+
".cts",
|
|
70423
|
+
".js",
|
|
70424
|
+
".mjs",
|
|
70425
|
+
".mts",
|
|
70426
|
+
".ts"
|
|
70427
|
+
];
|
|
70428
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
70429
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
70430
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
70431
|
+
true,
|
|
70432
|
+
false,
|
|
70433
|
+
"readable",
|
|
70434
|
+
"readonly",
|
|
70435
|
+
"writable",
|
|
70436
|
+
"writeable"
|
|
70437
|
+
]);
|
|
70438
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
70439
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
70440
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
70441
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
70442
|
+
}) ?? null;
|
|
70443
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
70444
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
70445
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
70446
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
70447
|
+
};
|
|
70448
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
70449
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70450
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
70451
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
70452
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
70453
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
70454
|
+
};
|
|
70455
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
70456
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70457
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
70458
|
+
};
|
|
70459
|
+
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");
|
|
70460
|
+
const isTopLevelExpression = (node) => {
|
|
70461
|
+
let ancestor = node.parent;
|
|
70462
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70463
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
70464
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
70465
|
+
ancestor = ancestor.parent;
|
|
70466
|
+
}
|
|
70467
|
+
return false;
|
|
70468
|
+
};
|
|
70469
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
70470
|
+
let ancestor = node.parent;
|
|
70471
|
+
let didFindConfigProperty = false;
|
|
70472
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70473
|
+
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;
|
|
70474
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
70475
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
70476
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
70477
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
70478
|
+
didFindConfigProperty = true;
|
|
70479
|
+
ancestor = ancestor.parent;
|
|
70480
|
+
continue;
|
|
70481
|
+
}
|
|
70482
|
+
if (didFindConfigProperty) {
|
|
70483
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
70484
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
70485
|
+
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);
|
|
70486
|
+
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;
|
|
70487
|
+
}
|
|
70488
|
+
ancestor = ancestor.parent;
|
|
70489
|
+
}
|
|
70490
|
+
return false;
|
|
70491
|
+
};
|
|
70492
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
70493
|
+
const optionsExpression = callExpression.arguments[0];
|
|
70494
|
+
if (!optionsExpression) return null;
|
|
70495
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
70496
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
70497
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
70498
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
70499
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
70500
|
+
if (!eslintrcProperty) return null;
|
|
70501
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
70502
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
70503
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
70504
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
70505
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
70506
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
70507
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
70508
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
70509
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
70510
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
70511
|
+
};
|
|
70512
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
70513
|
+
let sourceText;
|
|
70514
|
+
try {
|
|
70515
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
70516
|
+
} catch {
|
|
70517
|
+
return {
|
|
70518
|
+
didFindActiveAutoImport: false,
|
|
70519
|
+
globalsPaths: []
|
|
70520
|
+
};
|
|
70521
|
+
}
|
|
70522
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
70523
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
70524
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
70525
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
70526
|
+
for (const statement of sourceFile.statements) {
|
|
70527
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
70528
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
70529
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70530
|
+
const defaultBinding = statement.importClause?.name;
|
|
70531
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
70532
|
+
}
|
|
70533
|
+
if (moduleSpecifier === "esbuild") {
|
|
70534
|
+
const defaultBinding = statement.importClause?.name;
|
|
70535
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
70536
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
70537
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
70538
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
70539
|
+
}
|
|
70540
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
70541
|
+
}
|
|
70542
|
+
}
|
|
70543
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
70544
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
70545
|
+
if (!declaration.initializer) continue;
|
|
70546
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
70547
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
70548
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
70549
|
+
if (moduleSpecifier === "esbuild") {
|
|
70550
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
70551
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
70552
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
70553
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
70554
|
+
}
|
|
70555
|
+
}
|
|
70556
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
70557
|
+
}
|
|
70558
|
+
}
|
|
70559
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
70560
|
+
let didFindActiveAutoImport = false;
|
|
70561
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
70562
|
+
const visit = (node) => {
|
|
70563
|
+
if (ts.isCallExpression(node)) {
|
|
70564
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
70565
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70566
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
70567
|
+
didFindActiveAutoImport = true;
|
|
70568
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
70569
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
70570
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
70571
|
+
}
|
|
70572
|
+
}
|
|
70573
|
+
}
|
|
70574
|
+
ts.forEachChild(node, visit);
|
|
70575
|
+
};
|
|
70576
|
+
visit(sourceFile);
|
|
70577
|
+
return {
|
|
70578
|
+
didFindActiveAutoImport,
|
|
70579
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
70580
|
+
};
|
|
70581
|
+
};
|
|
70582
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
70583
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
70584
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
70585
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
70586
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
70587
|
+
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();
|
|
70588
|
+
};
|
|
70589
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
70590
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
70591
|
+
const visitedDirectories = [];
|
|
70592
|
+
while (true) {
|
|
70593
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
70594
|
+
if (cachedDirectory !== void 0) {
|
|
70595
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
70596
|
+
return cachedDirectory;
|
|
70597
|
+
}
|
|
70598
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
70599
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
70600
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70601
|
+
return null;
|
|
70602
|
+
}
|
|
70603
|
+
visitedDirectories.push(currentDirectory);
|
|
70604
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
70605
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
70606
|
+
return currentDirectory;
|
|
70607
|
+
}
|
|
70608
|
+
if (currentDirectory === rootDirectory) {
|
|
70609
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70610
|
+
return null;
|
|
70611
|
+
}
|
|
70612
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
70613
|
+
}
|
|
70614
|
+
};
|
|
70615
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
70616
|
+
let directoryEntries;
|
|
70617
|
+
try {
|
|
70618
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
70619
|
+
} catch {
|
|
70620
|
+
return [];
|
|
70621
|
+
}
|
|
70622
|
+
const configuredGlobalsPaths = [];
|
|
70623
|
+
for (const entry of directoryEntries) {
|
|
70624
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
70625
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
70626
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
70627
|
+
}
|
|
70628
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
70629
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
70630
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
70631
|
+
const names = /* @__PURE__ */ new Set();
|
|
70632
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
70633
|
+
return [...names].sort();
|
|
70634
|
+
};
|
|
70635
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
70636
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
70637
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
70638
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
70639
|
+
for (const candidateFile of candidateFiles) {
|
|
70640
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
70641
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
70642
|
+
}
|
|
70643
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
70644
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
70645
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
70646
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
70647
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
70648
|
+
};
|
|
69936
70649
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
69937
70650
|
const decodeFileDiagnostics = (raw) => {
|
|
69938
70651
|
if (!Array.isArray(raw)) return null;
|
|
@@ -70255,6 +70968,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
70255
70968
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
70256
70969
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
70257
70970
|
};
|
|
70971
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
70972
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
70973
|
+
let lineStartOffset = boundedOffset;
|
|
70974
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
70975
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
70976
|
+
};
|
|
70258
70977
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
70259
70978
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
70260
70979
|
const KNOWN_SECRET_RULES = [
|
|
@@ -70970,7 +71689,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
70970
71689
|
* with empty text still carry a useful jump target, so they're kept
|
|
70971
71690
|
* with a neutral message.
|
|
70972
71691
|
*/
|
|
70973
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
71692
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
70974
71693
|
if (labels.length <= 1) return [];
|
|
70975
71694
|
const related = [];
|
|
70976
71695
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -70978,8 +71697,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
70978
71697
|
if (!label?.span) continue;
|
|
70979
71698
|
related.push({
|
|
70980
71699
|
filePath,
|
|
70981
|
-
line: label.span.line ?? 0,
|
|
70982
|
-
column: label.span.column ?? 0,
|
|
71700
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
71701
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
70983
71702
|
offset: label.span.offset,
|
|
70984
71703
|
length: label.span.length,
|
|
70985
71704
|
message: label.label ?? ""
|
|
@@ -70999,7 +71718,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
|
|
|
70999
71718
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
71000
71719
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
71001
71720
|
*/
|
|
71002
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
71721
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
|
|
71003
71722
|
if (!stdout) return [];
|
|
71004
71723
|
const jsonStart = stdout.indexOf("{");
|
|
71005
71724
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -71016,8 +71735,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71016
71735
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
71017
71736
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
71018
71737
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
71738
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
71739
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
71019
71740
|
const readSourceBuffer = (filename) => {
|
|
71020
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71741
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71021
71742
|
const cached = sourceBufferCache.get(absolutePath);
|
|
71022
71743
|
if (cached !== void 0) return cached;
|
|
71023
71744
|
let sourceBuffer;
|
|
@@ -71030,7 +71751,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71030
71751
|
return sourceBuffer;
|
|
71031
71752
|
};
|
|
71032
71753
|
const readSourceLines = (filename) => {
|
|
71033
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71754
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71034
71755
|
const cached = sourceLinesCache.get(absolutePath);
|
|
71035
71756
|
if (cached !== void 0) return cached;
|
|
71036
71757
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -71039,27 +71760,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71039
71760
|
return sourceLines;
|
|
71040
71761
|
};
|
|
71041
71762
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
71042
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71763
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71043
71764
|
const cached = minifiedFileCache.get(absolutePath);
|
|
71044
71765
|
if (cached !== void 0) return cached;
|
|
71045
71766
|
const minified = isMinifiedSource(absolutePath);
|
|
71046
71767
|
minifiedFileCache.set(absolutePath, minified);
|
|
71047
71768
|
return minified;
|
|
71048
71769
|
};
|
|
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) => {
|
|
71770
|
+
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
71771
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71051
71772
|
const primaryLabel = diagnostic.labels[0];
|
|
71052
71773
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
71053
|
-
const
|
|
71774
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
71775
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
71054
71776
|
const primarySpan = primaryLabel?.span;
|
|
71055
71777
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
71056
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
71778
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
71057
71779
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
71058
71780
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
71059
71781
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
71060
|
-
const
|
|
71782
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
71783
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
71784
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
71061
71785
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
71062
|
-
const primaryColumnIndex = primarySpan ?
|
|
71786
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
71063
71787
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
71064
71788
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
71065
71789
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -71072,8 +71796,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71072
71796
|
message: cleaned.message,
|
|
71073
71797
|
help: cleaned.help,
|
|
71074
71798
|
url: diagnostic.url,
|
|
71075
|
-
line:
|
|
71076
|
-
column:
|
|
71799
|
+
line: primaryLineNumber,
|
|
71800
|
+
column: primaryColumnNumber,
|
|
71077
71801
|
...primarySpan ? {
|
|
71078
71802
|
offset: primarySpan.offset,
|
|
71079
71803
|
length: primarySpan.length,
|
|
@@ -71261,7 +71985,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
71261
71985
|
* loop with a slimmer config in that case.
|
|
71262
71986
|
*/
|
|
71263
71987
|
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;
|
|
71988
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
71989
|
+
const resolveSourcePath = (filePath) => {
|
|
71990
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
71991
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
71992
|
+
};
|
|
71265
71993
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
71266
71994
|
let rescueDeadlineEpochMs;
|
|
71267
71995
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -71281,7 +72009,7 @@ const spawnLintBatches = async (input) => {
|
|
|
71281
72009
|
}
|
|
71282
72010
|
const batchArgs = [...baseArgs, ...batch];
|
|
71283
72011
|
try {
|
|
71284
|
-
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
|
|
72012
|
+
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
|
|
71285
72013
|
} catch (error) {
|
|
71286
72014
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
71287
72015
|
if (isPastDeadline()) {
|
|
@@ -71387,10 +72115,12 @@ const spawnLintBatches = async (input) => {
|
|
|
71387
72115
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
71388
72116
|
};
|
|
71389
72117
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
71390
|
-
|
|
71391
|
-
|
|
72118
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
72119
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
72120
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
72121
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
71392
72122
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
71393
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
72123
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
71394
72124
|
return dedupeDiagnostics(diagnostics);
|
|
71395
72125
|
};
|
|
71396
72126
|
let didValidate = false;
|
|
@@ -71489,6 +72219,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
71489
72219
|
}
|
|
71490
72220
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
71491
72221
|
};
|
|
72222
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
72223
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
72224
|
+
const COMMENT_OPEN = "<!--";
|
|
72225
|
+
const COMMENT_CLOSE = "-->";
|
|
72226
|
+
const FRONTMATTER_FENCE = "---";
|
|
72227
|
+
const SCRIPT_TAG_NAME = "script";
|
|
72228
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
72229
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
72230
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
72231
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
72232
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
72233
|
+
"application/ecmascript",
|
|
72234
|
+
"application/javascript",
|
|
72235
|
+
"application/x-ecmascript",
|
|
72236
|
+
"application/x-javascript",
|
|
72237
|
+
"text/ecmascript",
|
|
72238
|
+
"text/javascript",
|
|
72239
|
+
"text/javascript1.0",
|
|
72240
|
+
"text/javascript1.1",
|
|
72241
|
+
"text/javascript1.2",
|
|
72242
|
+
"text/javascript1.3",
|
|
72243
|
+
"text/javascript1.4",
|
|
72244
|
+
"text/javascript1.5",
|
|
72245
|
+
"text/jscript",
|
|
72246
|
+
"text/livescript",
|
|
72247
|
+
"text/x-ecmascript",
|
|
72248
|
+
"text/x-javascript"
|
|
72249
|
+
]);
|
|
72250
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
72251
|
+
"iframe",
|
|
72252
|
+
"noembed",
|
|
72253
|
+
"noframes",
|
|
72254
|
+
"noscript",
|
|
72255
|
+
"style",
|
|
72256
|
+
"textarea",
|
|
72257
|
+
"title",
|
|
72258
|
+
"xmp"
|
|
72259
|
+
]);
|
|
72260
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
72261
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
72262
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
72263
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
72264
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
72265
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
72266
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
72267
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
72268
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
72269
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
72270
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
72271
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
72272
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
72273
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
72274
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
72275
|
+
}
|
|
72276
|
+
return true;
|
|
72277
|
+
};
|
|
72278
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
72279
|
+
const isPotentialTagStart = (byte) => {
|
|
72280
|
+
if (byte === void 0) return false;
|
|
72281
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
72282
|
+
};
|
|
72283
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
72284
|
+
let byteIndex = lineStartByte;
|
|
72285
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
72286
|
+
return byteIndex;
|
|
72287
|
+
};
|
|
72288
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
72289
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72290
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
72291
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
72292
|
+
};
|
|
72293
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
72294
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
72295
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72296
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
72297
|
+
return true;
|
|
72298
|
+
};
|
|
72299
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
72300
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
72301
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
72302
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
72303
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
72304
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
72305
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
72306
|
+
}
|
|
72307
|
+
return openingFenceEndByte;
|
|
72308
|
+
};
|
|
72309
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
72310
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
72311
|
+
const byte = maskedBuffer[byteIndex];
|
|
72312
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
72313
|
+
}
|
|
72314
|
+
};
|
|
72315
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
72316
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
72317
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
72318
|
+
let nameEndByte = tagStartByte + 2;
|
|
72319
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
72320
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
72321
|
+
};
|
|
72322
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
72323
|
+
let quoteByte = null;
|
|
72324
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
72325
|
+
const byte = sourceBuffer[byteIndex];
|
|
72326
|
+
if (quoteByte !== null) {
|
|
72327
|
+
if (byte === quoteByte) quoteByte = null;
|
|
72328
|
+
continue;
|
|
72329
|
+
}
|
|
72330
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72331
|
+
quoteByte = byte;
|
|
72332
|
+
continue;
|
|
72333
|
+
}
|
|
72334
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
72335
|
+
}
|
|
72336
|
+
return sourceBuffer.length;
|
|
72337
|
+
};
|
|
72338
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
72339
|
+
let byteIndex = attributesStartByte;
|
|
72340
|
+
let hasSource = false;
|
|
72341
|
+
let language = null;
|
|
72342
|
+
let scriptType = null;
|
|
72343
|
+
while (byteIndex < tagEndByte) {
|
|
72344
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
72345
|
+
const attributeNameStartByte = byteIndex;
|
|
72346
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72347
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
72348
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72349
|
+
let attributeValue = "";
|
|
72350
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
72351
|
+
byteIndex++;
|
|
72352
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72353
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
72354
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72355
|
+
const valueStartByte = byteIndex + 1;
|
|
72356
|
+
byteIndex = valueStartByte;
|
|
72357
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
72358
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72359
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
72360
|
+
} else {
|
|
72361
|
+
const valueStartByte = byteIndex;
|
|
72362
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72363
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72364
|
+
}
|
|
72365
|
+
}
|
|
72366
|
+
if (attributeName === "src") hasSource = true;
|
|
72367
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
72368
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
72369
|
+
}
|
|
72370
|
+
return {
|
|
72371
|
+
hasSource,
|
|
72372
|
+
language,
|
|
72373
|
+
type: scriptType
|
|
72374
|
+
};
|
|
72375
|
+
};
|
|
72376
|
+
const isExecutableScript = (attributes) => {
|
|
72377
|
+
if (attributes.hasSource) return false;
|
|
72378
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
72379
|
+
if (type !== "") {
|
|
72380
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
72381
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
72382
|
+
}
|
|
72383
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
72384
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
72385
|
+
};
|
|
72386
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
72387
|
+
const closeTagStart = `</${tagName}`;
|
|
72388
|
+
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;
|
|
72389
|
+
return sourceBuffer.length;
|
|
72390
|
+
};
|
|
72391
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
72392
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
72393
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
72394
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
72395
|
+
const executableScriptBodies = [];
|
|
72396
|
+
let byteIndex = frontmatterEndByte;
|
|
72397
|
+
let templateDepth = 0;
|
|
72398
|
+
while (byteIndex < sourceBuffer.length) {
|
|
72399
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
72400
|
+
byteIndex++;
|
|
72401
|
+
continue;
|
|
72402
|
+
}
|
|
72403
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
72404
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
72405
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
72406
|
+
continue;
|
|
72407
|
+
}
|
|
72408
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
72409
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
72410
|
+
if (templateDepth > 0) templateDepth--;
|
|
72411
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72412
|
+
continue;
|
|
72413
|
+
}
|
|
72414
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
72415
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
72416
|
+
byteIndex++;
|
|
72417
|
+
continue;
|
|
72418
|
+
}
|
|
72419
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
72420
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
72421
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
72422
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
72423
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
72424
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
72425
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
72426
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
72427
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72428
|
+
continue;
|
|
72429
|
+
}
|
|
72430
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72431
|
+
continue;
|
|
72432
|
+
}
|
|
72433
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
72434
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
72435
|
+
const bodyStartByte = tagEndByte + 1;
|
|
72436
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
72437
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
72438
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
72439
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
72440
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
72441
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
72442
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
72443
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
72444
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72445
|
+
}
|
|
72446
|
+
return {
|
|
72447
|
+
executableScriptBodies,
|
|
72448
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
72449
|
+
};
|
|
72450
|
+
};
|
|
72451
|
+
const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
72452
|
+
const lintFiles = [];
|
|
72453
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
72454
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
72455
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
72456
|
+
let htmlFileIndex = 0;
|
|
72457
|
+
let hasThreeModuleImport = false;
|
|
72458
|
+
for (const candidateFile of candidateFiles) {
|
|
72459
|
+
if (!HTML_FILE_PATTERN.test(candidateFile)) {
|
|
72460
|
+
lintFiles.push(candidateFile);
|
|
72461
|
+
continue;
|
|
72462
|
+
}
|
|
72463
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
72464
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
72465
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
72466
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
72467
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
72468
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
72469
|
+
lintFiles.push(lintPath);
|
|
72470
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
72471
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
72472
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
72473
|
+
htmlFileIndex++;
|
|
72474
|
+
}
|
|
72475
|
+
return {
|
|
72476
|
+
lintFiles,
|
|
72477
|
+
sourcePathByLintPath,
|
|
72478
|
+
sizeByLintPath,
|
|
72479
|
+
hasThreeModuleImport
|
|
72480
|
+
};
|
|
72481
|
+
};
|
|
71492
72482
|
/**
|
|
71493
72483
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
71494
72484
|
* the runner: once for the primary scan, once for the
|
|
@@ -71649,6 +72639,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
71649
72639
|
const runOxlint = async (options) => {
|
|
71650
72640
|
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
72641
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72642
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72643
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
71652
72644
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
71653
72645
|
validateRuleRegistration();
|
|
71654
72646
|
resetManifestCaches();
|
|
@@ -71662,21 +72654,6 @@ const runOxlint = async (options) => {
|
|
|
71662
72654
|
const pluginPath = resolvePluginPath();
|
|
71663
72655
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
71664
72656
|
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
72657
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
71681
72658
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
71682
72659
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -71712,7 +72689,36 @@ const runOxlint = async (options) => {
|
|
|
71712
72689
|
await yieldToEventLoop();
|
|
71713
72690
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
71714
72691
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
72692
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
72693
|
+
rootDirectory,
|
|
72694
|
+
candidateFiles
|
|
72695
|
+
});
|
|
72696
|
+
const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
72697
|
+
const lintFiles = preparedHtmlSources.lintFiles;
|
|
72698
|
+
const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
|
|
72699
|
+
const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
|
|
72700
|
+
...project,
|
|
72701
|
+
hasThree: true
|
|
72702
|
+
} : project;
|
|
72703
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
72704
|
+
pluginPath,
|
|
72705
|
+
project: lintProject,
|
|
72706
|
+
customRulesOnly,
|
|
72707
|
+
extendsPaths: overrides.extendsPaths,
|
|
72708
|
+
ignoredTags,
|
|
72709
|
+
includedTags,
|
|
72710
|
+
includeTagDefaults,
|
|
72711
|
+
runtimeGlobals,
|
|
72712
|
+
unpluginAutoImportGlobalScopes,
|
|
72713
|
+
serverAuthFunctionNames,
|
|
72714
|
+
severityControls,
|
|
72715
|
+
userPlugins,
|
|
72716
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
72717
|
+
ruleSelection: overrides.ruleSelection,
|
|
72718
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
72719
|
+
});
|
|
71715
72720
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
72721
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
71716
72722
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
71717
72723
|
baseArgs: passBaseArgs,
|
|
71718
72724
|
files: passFiles,
|
|
@@ -71741,7 +72747,8 @@ const runOxlint = async (options) => {
|
|
|
71741
72747
|
fileBatches: passFileBatches,
|
|
71742
72748
|
rootDirectory,
|
|
71743
72749
|
nodeBinaryPath,
|
|
71744
|
-
project,
|
|
72750
|
+
project: lintProject,
|
|
72751
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
71745
72752
|
onPartialFailure: reportPartialFailure,
|
|
71746
72753
|
onAnalyzedFiles: (filePaths) => {
|
|
71747
72754
|
analyzedFiles = filePaths;
|
|
@@ -71776,7 +72783,7 @@ const runOxlint = async (options) => {
|
|
|
71776
72783
|
};
|
|
71777
72784
|
}
|
|
71778
72785
|
};
|
|
71779
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
72786
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
|
|
71780
72787
|
const rulesetHash = computeRulesetHash({
|
|
71781
72788
|
config: buildConfig({
|
|
71782
72789
|
extendsPaths: [],
|
|
@@ -71934,14 +72941,15 @@ const runOxlint = async (options) => {
|
|
|
71934
72941
|
]);
|
|
71935
72942
|
}
|
|
71936
72943
|
const baseArgs = makeBaseArgs(configPath);
|
|
71937
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
72944
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
71938
72945
|
let analyzedFiles = [];
|
|
71939
72946
|
const runBatches = () => spawnLintBatches({
|
|
71940
72947
|
baseArgs,
|
|
71941
72948
|
fileBatches,
|
|
71942
72949
|
rootDirectory,
|
|
71943
72950
|
nodeBinaryPath,
|
|
71944
|
-
project,
|
|
72951
|
+
project: lintProject,
|
|
72952
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
71945
72953
|
onPartialFailure,
|
|
71946
72954
|
onAnalyzedFiles: (filePaths) => {
|
|
71947
72955
|
analyzedFiles = filePaths;
|
|
@@ -73475,7 +74483,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
|
|
|
73475
74483
|
/** Display name used in client-facing messages and progress titles. */
|
|
73476
74484
|
const SERVER_DISPLAY_NAME = "React Doctor";
|
|
73477
74485
|
/** Server version reported in `serverInfo`; injected at build, `dev` from source. */
|
|
73478
|
-
const SERVER_VERSION = "0.9.
|
|
74486
|
+
const SERVER_VERSION = "0.9.2";
|
|
73479
74487
|
/** `Diagnostic.source` shown next to every published diagnostic. */
|
|
73480
74488
|
const DIAGNOSTIC_SOURCE = "react-doctor";
|
|
73481
74489
|
/**
|
|
@@ -73517,7 +74525,8 @@ const SCANNABLE_EXTENSIONS = [
|
|
|
73517
74525
|
".js",
|
|
73518
74526
|
".jsx",
|
|
73519
74527
|
".mts",
|
|
73520
|
-
".mjs"
|
|
74528
|
+
".mjs",
|
|
74529
|
+
".html"
|
|
73521
74530
|
];
|
|
73522
74531
|
const SILENT_LOGGER = {
|
|
73523
74532
|
info: () => {},
|
|
@@ -75173,6 +76182,7 @@ const METRIC = {
|
|
|
75173
76182
|
projectConfigSelected: "project.config_selected",
|
|
75174
76183
|
scanCompleted: "scan.completed",
|
|
75175
76184
|
scanDuration: "scan.duration",
|
|
76185
|
+
scanFeedbackDelay: "scan.feedback_delay",
|
|
75176
76186
|
scanPhaseDuration: "scan.phase_duration",
|
|
75177
76187
|
scanFiles: "scan.files",
|
|
75178
76188
|
scanScore: "scan.score",
|
|
@@ -75204,6 +76214,10 @@ const METRIC = {
|
|
|
75204
76214
|
lspScanCompleted: "lsp.scan.completed",
|
|
75205
76215
|
lspScanDuration: "lsp.scan.duration",
|
|
75206
76216
|
lspScanDiagnostics: "lsp.scan.diagnostics",
|
|
76217
|
+
tuiActionMenuOpened: "tui.action_menu_opened",
|
|
76218
|
+
tuiCompactReportShown: "tui.compact_report_shown",
|
|
76219
|
+
tuiFindingNavigated: "tui.finding_navigated",
|
|
76220
|
+
tuiStackedReportCapped: "tui.stacked_report_capped",
|
|
75207
76221
|
aiTrainingWarningShown: "ai.training.warning_shown",
|
|
75208
76222
|
jsonOutUsed: "json.out_used"
|
|
75209
76223
|
};
|
|
@@ -75505,5 +76519,5 @@ const startLanguageServer = () => {
|
|
|
75505
76519
|
};
|
|
75506
76520
|
//#endregion
|
|
75507
76521
|
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=
|
|
76522
|
+
!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]="26eb6ceb-bf30-5c1a-b80b-534117e1557d")}catch(e){}}();
|
|
76523
|
+
//# debugId=26eb6ceb-bf30-5c1a-b80b-534117e1557d
|