react-doctor 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/cli.js +1156 -147
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1150 -142
- package/dist/lsp.js +1153 -144
- package/package.json +7 -6
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!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]="
|
|
2
|
+
!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]="c86de9ea-b858-5528-89a8-6ff4d377c873")}catch(e){}}();
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import * as NodeChildProcess from "node:child_process";
|
|
5
5
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
@@ -11,6 +11,7 @@ import process$1 from "node:process";
|
|
|
11
11
|
import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
|
|
12
12
|
import * as Crypto from "node:crypto";
|
|
13
13
|
import crypto, { createHash, randomUUID } from "node:crypto";
|
|
14
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
14
15
|
import ts from "typescript";
|
|
15
16
|
import * as OS from "node:os";
|
|
16
17
|
import os, { tmpdir } from "node:os";
|
|
@@ -64616,7 +64617,8 @@ var AmbiguousProjectError = class extends Error {
|
|
|
64616
64617
|
}
|
|
64617
64618
|
};
|
|
64618
64619
|
const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
|
|
64619
|
-
const
|
|
64620
|
+
const HTML_FILE_PATTERN = /\.html$/i;
|
|
64621
|
+
const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
|
|
64620
64622
|
const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
|
|
64621
64623
|
const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
|
|
64622
64624
|
const MINIFIED_SNIFF_BYTES = 65536;
|
|
@@ -64994,7 +64996,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
64994
64996
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
64995
64997
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
64996
64998
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
64997
|
-
const CORE_PACKAGE_VERSION = "0.9.
|
|
64999
|
+
const CORE_PACKAGE_VERSION = "0.9.2";
|
|
64998
65000
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
64999
65001
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
65000
65002
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -65238,8 +65240,13 @@ const findMonorepoRoot = (startDirectory) => {
|
|
|
65238
65240
|
* byte-equivalent copy.
|
|
65239
65241
|
*/
|
|
65240
65242
|
const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
|
|
65243
|
+
const unwrapTypescriptExpression = (expression) => {
|
|
65244
|
+
let currentExpression = expression;
|
|
65245
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
65246
|
+
return currentExpression;
|
|
65247
|
+
};
|
|
65241
65248
|
const TSCONFIG_FILENAME = "tsconfig.json";
|
|
65242
|
-
const
|
|
65249
|
+
const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
|
|
65243
65250
|
const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
|
|
65244
65251
|
const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
65245
65252
|
const requireFromConfig = createRequire(Path.join(fromConfigDirectory, "tsconfig.json"));
|
|
@@ -65256,7 +65263,12 @@ const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
|
65256
65263
|
return null;
|
|
65257
65264
|
};
|
|
65258
65265
|
const resolveExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
65259
|
-
if (
|
|
65266
|
+
if (isLocalModuleSpecifier(extendsValue)) {
|
|
65267
|
+
const resolvedPath = Path.resolve(fromConfigDirectory, extendsValue);
|
|
65268
|
+
if (isFile(resolvedPath)) return resolvedPath;
|
|
65269
|
+
const directoryConfigPath = Path.join(resolvedPath, TSCONFIG_FILENAME);
|
|
65270
|
+
return isFile(directoryConfigPath) ? directoryConfigPath : ensureJsonExtension(resolvedPath);
|
|
65271
|
+
}
|
|
65260
65272
|
return resolvePackageExtendsPath(extendsValue, fromConfigDirectory);
|
|
65261
65273
|
};
|
|
65262
65274
|
const normalizeCompilerOptions = (compilerOptions) => {
|
|
@@ -65450,6 +65462,15 @@ const REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS = [
|
|
|
65450
65462
|
".cts",
|
|
65451
65463
|
".json"
|
|
65452
65464
|
];
|
|
65465
|
+
const REACT_COMPILER_CONFIG_RESOLVER = new ResolverFactory({
|
|
65466
|
+
conditionNames: [
|
|
65467
|
+
"import",
|
|
65468
|
+
"require",
|
|
65469
|
+
"node",
|
|
65470
|
+
"default"
|
|
65471
|
+
],
|
|
65472
|
+
extensions: REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS
|
|
65473
|
+
});
|
|
65453
65474
|
const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
|
|
65454
65475
|
const hasCompilerPackage = (packageJson, compilerPackages) => {
|
|
65455
65476
|
const allDependencies = {
|
|
@@ -65473,6 +65494,18 @@ const hasCompilerPackageInAncestors = (directory, compilerPackages) => {
|
|
|
65473
65494
|
return false;
|
|
65474
65495
|
};
|
|
65475
65496
|
const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
65497
|
+
if (!isLocalModuleSpecifier(moduleSpecifier)) {
|
|
65498
|
+
try {
|
|
65499
|
+
const resolvedPath = REACT_COMPILER_CONFIG_RESOLVER.resolveFileSync(fromFilePath, moduleSpecifier).path;
|
|
65500
|
+
if (resolvedPath && isFile(resolvedPath)) return resolvedPath;
|
|
65501
|
+
} catch {}
|
|
65502
|
+
try {
|
|
65503
|
+
const resolvedPath = createRequire(fromFilePath).resolve(moduleSpecifier);
|
|
65504
|
+
return isFile(resolvedPath) ? resolvedPath : null;
|
|
65505
|
+
} catch {
|
|
65506
|
+
return null;
|
|
65507
|
+
}
|
|
65508
|
+
}
|
|
65476
65509
|
const unresolvedPath = Path.resolve(Path.dirname(fromFilePath), moduleSpecifier);
|
|
65477
65510
|
const extension = Path.extname(unresolvedPath);
|
|
65478
65511
|
return (extension ? [unresolvedPath, ...REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS.map((sourceExtension) => `${unresolvedPath.slice(0, -extension.length)}${sourceExtension}`)] : [
|
|
@@ -65482,10 +65515,10 @@ const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
|
65482
65515
|
]).find(isFile) ?? null;
|
|
65483
65516
|
};
|
|
65484
65517
|
const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json") || Path.basename(filePath) === ".babelrc" ? ts.parseJsonText(filePath, content) : ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
65485
|
-
const getStaticPropertyName$
|
|
65518
|
+
const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
|
|
65486
65519
|
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");
|
|
65487
65520
|
const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
|
|
65488
|
-
const getRequireModuleSpecifier = (expression) => {
|
|
65521
|
+
const getRequireModuleSpecifier$1 = (expression) => {
|
|
65489
65522
|
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
|
|
65490
65523
|
const moduleSpecifier = expression.arguments[0];
|
|
65491
65524
|
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
@@ -65498,7 +65531,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
65498
65531
|
const namedBindings = importClause?.namedBindings;
|
|
65499
65532
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
65500
65533
|
}
|
|
65501
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
65534
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
65502
65535
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
65503
65536
|
});
|
|
65504
65537
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -65529,24 +65562,24 @@ const getImportBinding = (sourceFile, bindingName) => {
|
|
|
65529
65562
|
for (const declaration of statement.declarationList.declarations) {
|
|
65530
65563
|
if (!declaration.initializer) continue;
|
|
65531
65564
|
if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
|
|
65532
|
-
const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
65565
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
65533
65566
|
if (directModuleSpecifier) return {
|
|
65534
65567
|
moduleSpecifier: directModuleSpecifier,
|
|
65535
65568
|
exportName: "default",
|
|
65536
65569
|
isNamespace: true
|
|
65537
65570
|
};
|
|
65538
|
-
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
|
|
65539
|
-
moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
|
|
65571
|
+
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
|
|
65572
|
+
moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
|
|
65540
65573
|
exportName: declaration.initializer.name.text,
|
|
65541
65574
|
isNamespace: false
|
|
65542
65575
|
};
|
|
65543
65576
|
}
|
|
65544
65577
|
if (!ts.isObjectBindingPattern(declaration.name)) continue;
|
|
65545
65578
|
const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
|
|
65546
|
-
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
65579
|
+
const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
65547
65580
|
if (bindingElement && moduleSpecifier) return {
|
|
65548
65581
|
moduleSpecifier,
|
|
65549
|
-
exportName: bindingElement.propertyName ? getStaticPropertyName$
|
|
65582
|
+
exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
|
|
65550
65583
|
isNamespace: false
|
|
65551
65584
|
};
|
|
65552
65585
|
}
|
|
@@ -65599,6 +65632,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
65599
65632
|
};
|
|
65600
65633
|
};
|
|
65601
65634
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
65635
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
65636
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
65637
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
65638
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
65639
|
+
if (!ts.isCallExpression(node)) return false;
|
|
65640
|
+
const target = node.expression;
|
|
65641
|
+
if (ts.isIdentifier(target)) {
|
|
65642
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
65643
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
65644
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
65645
|
+
}
|
|
65646
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
65647
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
65648
|
+
const createRequireReceiver = target.expression;
|
|
65649
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
65650
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
65651
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
65652
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
65653
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
65654
|
+
}
|
|
65655
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
65656
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
65657
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
65658
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
65659
|
+
};
|
|
65660
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
65661
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
65662
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
65663
|
+
const target = callExpression.expression;
|
|
65664
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
65665
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
65666
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
65667
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
65668
|
+
const resolverIdentifier = target.expression;
|
|
65669
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
65670
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
65671
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
65672
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
65673
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
65674
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
65675
|
+
return moduleSpecifierNode.text;
|
|
65676
|
+
};
|
|
65602
65677
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
65603
65678
|
let bindingScope = null;
|
|
65604
65679
|
let currentNode = identifier;
|
|
@@ -65641,9 +65716,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
|
65641
65716
|
initializer: assignedInitializer
|
|
65642
65717
|
};
|
|
65643
65718
|
};
|
|
65644
|
-
const getStaticConfigValueState = (expression, analysis) => {
|
|
65645
|
-
|
|
65646
|
-
|
|
65719
|
+
const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
65720
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
65721
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
65722
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
65723
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
65647
65724
|
if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
|
|
65648
65725
|
isNullish: true,
|
|
65649
65726
|
isTruthy: false
|
|
@@ -65659,31 +65736,31 @@ const getStaticConfigValueState = (expression, analysis) => {
|
|
|
65659
65736
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
65660
65737
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
65661
65738
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
65662
|
-
return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
|
|
65739
|
+
return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
65663
65740
|
}
|
|
65664
65741
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
65665
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
|
|
65742
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
65666
65743
|
}
|
|
65667
65744
|
if (ts.isConditionalExpression(unwrappedExpression)) {
|
|
65668
|
-
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
|
|
65669
|
-
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
|
|
65670
|
-
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
|
|
65671
|
-
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
|
|
65745
|
+
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
|
|
65746
|
+
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
65747
|
+
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
|
|
65748
|
+
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
65672
65749
|
return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
|
|
65673
65750
|
}
|
|
65674
65751
|
if (ts.isBinaryExpression(unwrappedExpression)) {
|
|
65675
|
-
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
|
|
65752
|
+
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
|
|
65676
65753
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
65677
65754
|
if (leftState === null) return null;
|
|
65678
|
-
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
65755
|
+
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
65679
65756
|
}
|
|
65680
65757
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
65681
65758
|
if (leftState === null) return null;
|
|
65682
|
-
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
|
|
65759
|
+
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
|
|
65683
65760
|
}
|
|
65684
65761
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
65685
65762
|
if (leftState === null) return null;
|
|
65686
|
-
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
65763
|
+
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
65687
65764
|
}
|
|
65688
65765
|
}
|
|
65689
65766
|
return null;
|
|
@@ -65692,25 +65769,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
|
|
|
65692
65769
|
const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
|
|
65693
65770
|
const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
|
|
65694
65771
|
const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
|
|
65695
|
-
const getReactCompilerFlagState = (expression, analysis) => {
|
|
65696
|
-
|
|
65697
|
-
|
|
65772
|
+
const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
65773
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
65774
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
65775
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
65776
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
65698
65777
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
65699
65778
|
const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
|
|
65700
65779
|
if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
|
|
65701
65780
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
65702
65781
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
65703
|
-
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
|
|
65782
|
+
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
65704
65783
|
}
|
|
65705
65784
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
65706
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
|
|
65785
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
65707
65786
|
}
|
|
65708
65787
|
if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
|
|
65709
65788
|
for (const property of [...unwrappedExpression.properties].reverse()) {
|
|
65710
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
65789
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
|
|
65711
65790
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
|
|
65712
65791
|
if (ts.isSpreadAssignment(property)) {
|
|
65713
|
-
const spreadState = getReactCompilerFlagState(property.expression, analysis);
|
|
65792
|
+
const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
|
|
65714
65793
|
if (spreadState) return spreadState;
|
|
65715
65794
|
}
|
|
65716
65795
|
}
|
|
@@ -65733,8 +65812,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
|
|
|
65733
65812
|
}
|
|
65734
65813
|
if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
|
|
65735
65814
|
for (const property of [...resolvedExpression.properties].reverse()) {
|
|
65736
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
65737
|
-
if (ts.isMethodDeclaration(property) && getStaticPropertyName$
|
|
65815
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return property.initializer;
|
|
65816
|
+
if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return property;
|
|
65738
65817
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
|
|
65739
65818
|
if (ts.isSpreadAssignment(property)) {
|
|
65740
65819
|
const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
|
|
@@ -65765,7 +65844,7 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
|
|
|
65765
65844
|
return resolvedExpression.properties.some((property) => {
|
|
65766
65845
|
if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
|
|
65767
65846
|
if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
|
|
65768
|
-
const staticPropertyName = getStaticPropertyName$
|
|
65847
|
+
const staticPropertyName = getStaticPropertyName$2(property.name);
|
|
65769
65848
|
return staticPropertyName === null || staticPropertyName === propertyName;
|
|
65770
65849
|
}
|
|
65771
65850
|
return false;
|
|
@@ -65784,7 +65863,7 @@ const getExportedConfigNodes = (sourceFile, exportName) => {
|
|
|
65784
65863
|
continue;
|
|
65785
65864
|
}
|
|
65786
65865
|
if (ts.isExpressionStatement(statement) && isCommonJsConfigExportAssignment(statement.expression, sourceFile) && exportName !== "default" && ts.isObjectLiteralExpression(statement.expression.right)) for (const property of [...statement.expression.right.properties].reverse()) {
|
|
65787
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
65866
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === exportName) {
|
|
65788
65867
|
exportedNodes.push(property.initializer);
|
|
65789
65868
|
break;
|
|
65790
65869
|
}
|
|
@@ -65882,6 +65961,11 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
|
|
|
65882
65961
|
visitReturns(functionNode.body);
|
|
65883
65962
|
return hasCompiler;
|
|
65884
65963
|
};
|
|
65964
|
+
const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
|
|
65965
|
+
const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
|
|
65966
|
+
if (!importedFilePath) return null;
|
|
65967
|
+
return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList);
|
|
65968
|
+
};
|
|
65885
65969
|
const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
|
|
65886
65970
|
const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
|
|
65887
65971
|
if (assignedReactCompiler.initializer && !isStaticallyDisabledConfigExpression(assignedReactCompiler.initializer, analysis)) return true;
|
|
@@ -65902,30 +65986,62 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
|
|
|
65902
65986
|
const importBinding = getImportBinding(analysis.sourceFile, identifier.text);
|
|
65903
65987
|
if (importBinding) {
|
|
65904
65988
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
65905
|
-
|
|
65906
|
-
|
|
65907
|
-
|
|
65989
|
+
return Boolean(analyzeImportedConfig({
|
|
65990
|
+
analysis,
|
|
65991
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
65992
|
+
exportName: importBinding.exportName,
|
|
65993
|
+
allowCompilerTransform
|
|
65994
|
+
}));
|
|
65908
65995
|
}
|
|
65909
65996
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, identifier.text);
|
|
65910
65997
|
return Boolean(topLevelBinding && analyzeConfigNode(topLevelBinding, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
|
|
65911
65998
|
};
|
|
65912
65999
|
const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransform) => {
|
|
65913
66000
|
const target = callExpression.expression;
|
|
66001
|
+
const callableRequiredModuleSpecifier = getRequireModuleSpecifier$1(target);
|
|
66002
|
+
if (callableRequiredModuleSpecifier !== null) {
|
|
66003
|
+
if (ts.isCallExpression(target) && ts.isIdentifier(target.expression) && (analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
66004
|
+
if (allowCompilerTransform && isCompilerTransformModule(callableRequiredModuleSpecifier, "default")) return true;
|
|
66005
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
66006
|
+
analysis,
|
|
66007
|
+
moduleSpecifier: callableRequiredModuleSpecifier,
|
|
66008
|
+
exportName: "default",
|
|
66009
|
+
allowCompilerTransform,
|
|
66010
|
+
argumentsList: callExpression.arguments
|
|
66011
|
+
});
|
|
66012
|
+
if (isLocalModuleSpecifier(callableRequiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
66013
|
+
return null;
|
|
66014
|
+
}
|
|
65914
66015
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
65915
66016
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
65916
66017
|
if (propertyName === null) return null;
|
|
65917
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
|
|
66018
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
65918
66019
|
if (requiredModuleSpecifier !== null) {
|
|
65919
|
-
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
65920
|
-
if (
|
|
65921
|
-
const
|
|
65922
|
-
|
|
66020
|
+
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;
|
|
66021
|
+
if (allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, propertyName)) return true;
|
|
66022
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
66023
|
+
analysis,
|
|
66024
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
66025
|
+
exportName: propertyName,
|
|
66026
|
+
allowCompilerTransform,
|
|
66027
|
+
argumentsList: callExpression.arguments
|
|
66028
|
+
});
|
|
66029
|
+
if (isLocalModuleSpecifier(requiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
66030
|
+
return null;
|
|
65923
66031
|
}
|
|
65924
66032
|
if (!ts.isIdentifier(target.expression)) return null;
|
|
65925
|
-
const importBinding = getImportBinding(analysis.sourceFile, target.expression.text);
|
|
65926
|
-
if (importBinding?.isNamespace
|
|
65927
|
-
|
|
65928
|
-
|
|
66033
|
+
const importBinding = analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound ? null : getImportBinding(analysis.sourceFile, target.expression.text);
|
|
66034
|
+
if (importBinding?.isNamespace) {
|
|
66035
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, propertyName)) return true;
|
|
66036
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
66037
|
+
analysis,
|
|
66038
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
66039
|
+
exportName: propertyName,
|
|
66040
|
+
allowCompilerTransform,
|
|
66041
|
+
argumentsList: callExpression.arguments
|
|
66042
|
+
});
|
|
66043
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
66044
|
+
return null;
|
|
65929
66045
|
}
|
|
65930
66046
|
const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
|
|
65931
66047
|
if (selectedProperty === null) return null;
|
|
@@ -65943,25 +66059,29 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
65943
66059
|
const reactCompilerFlagState = excludedPropertyNames?.has("reactCompiler") ? null : getReactCompilerFlagState(node, analysis);
|
|
65944
66060
|
if (reactCompilerFlagState?.isEnabled) return true;
|
|
65945
66061
|
for (const [propertyIndex, property] of node.properties.entries()) if (ts.isPropertyAssignment(property)) {
|
|
65946
|
-
const propertyName = getStaticPropertyName$
|
|
66062
|
+
const propertyName = getStaticPropertyName$2(property.name);
|
|
65947
66063
|
if (propertyName && excludedPropertyNames?.has(propertyName)) continue;
|
|
65948
66064
|
if (propertyName === "reactCompiler") continue;
|
|
65949
|
-
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$
|
|
66065
|
+
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;
|
|
65950
66066
|
const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
|
|
65951
|
-
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)
|
|
65952
|
-
|
|
65953
|
-
|
|
66067
|
+
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)) {
|
|
66068
|
+
if (analyzeImportedConfig({
|
|
66069
|
+
analysis,
|
|
66070
|
+
moduleSpecifier: property.initializer.text,
|
|
66071
|
+
exportName: "default",
|
|
66072
|
+
allowCompilerTransform: false
|
|
66073
|
+
})) return true;
|
|
65954
66074
|
}
|
|
65955
66075
|
if (analyzeConfigNode(property.initializer, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
65956
66076
|
} else if (ts.isShorthandPropertyAssignment(property)) {
|
|
65957
66077
|
if (excludedPropertyNames?.has(property.name.text)) continue;
|
|
65958
66078
|
if (property.name.text === "reactCompiler") continue;
|
|
65959
|
-
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$
|
|
66079
|
+
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;
|
|
65960
66080
|
const propertyAllowsCompilerTransform = property.name.text === "plugins" || property.name.text === "presets";
|
|
65961
66081
|
if (analyzeConfigNode(property.name, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
65962
66082
|
} else if (ts.isSpreadAssignment(property)) {
|
|
65963
66083
|
if (reactCompilerFlagState && getReactCompilerFlagState(property.expression, analysis) !== null) continue;
|
|
65964
|
-
if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$
|
|
66084
|
+
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;
|
|
65965
66085
|
if (analyzeConfigNode(property.expression, analysis, allowCompilerTransform, false, excludedPropertyNames)) return true;
|
|
65966
66086
|
}
|
|
65967
66087
|
return false;
|
|
@@ -65974,23 +66094,36 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
65974
66094
|
});
|
|
65975
66095
|
}
|
|
65976
66096
|
if (ts.isCallExpression(node)) {
|
|
66097
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
66098
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
65977
66099
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
65978
66100
|
if (callTargetResult !== null) return callTargetResult;
|
|
65979
|
-
const directModuleSpecifier = getRequireModuleSpecifier(node);
|
|
66101
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
65980
66102
|
const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
|
|
65981
66103
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
65982
66104
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
65983
66105
|
if (allowCompilerTransform && isCompilerTransformModule(directModuleSpecifier, "default")) return true;
|
|
65984
|
-
if (
|
|
65985
|
-
|
|
65986
|
-
|
|
65987
|
-
|
|
66106
|
+
if (analyzeImportedConfig({
|
|
66107
|
+
analysis,
|
|
66108
|
+
moduleSpecifier: directModuleSpecifier,
|
|
66109
|
+
exportName: "default",
|
|
66110
|
+
allowCompilerTransform
|
|
66111
|
+
})) return true;
|
|
65988
66112
|
}
|
|
65989
66113
|
if (ts.isIdentifier(node.expression)) {
|
|
65990
|
-
|
|
65991
|
-
|
|
65992
|
-
|
|
65993
|
-
|
|
66114
|
+
if (!analysis.localBindings.has(node.expression.text) && !getScopedConfigBinding(node.expression).wasFound) {
|
|
66115
|
+
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
66116
|
+
if (importBinding) {
|
|
66117
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
66118
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
66119
|
+
analysis,
|
|
66120
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
66121
|
+
exportName: importBinding.exportName,
|
|
66122
|
+
allowCompilerTransform,
|
|
66123
|
+
argumentsList: node.arguments
|
|
66124
|
+
});
|
|
66125
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
66126
|
+
}
|
|
65994
66127
|
}
|
|
65995
66128
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, node.expression.text);
|
|
65996
66129
|
if (topLevelBinding && ts.isFunctionLike(topLevelBinding) && analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, node.arguments)) return true;
|
|
@@ -65998,27 +66131,31 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
65998
66131
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
|
|
65999
66132
|
}
|
|
66000
66133
|
if (ts.isPropertyAccessExpression(node)) {
|
|
66001
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
|
|
66134
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
66002
66135
|
if (requiredModuleSpecifier) {
|
|
66003
|
-
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
66004
|
-
if (
|
|
66005
|
-
|
|
66006
|
-
|
|
66007
|
-
|
|
66136
|
+
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;
|
|
66137
|
+
if (analyzeImportedConfig({
|
|
66138
|
+
analysis,
|
|
66139
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
66140
|
+
exportName: node.name.text,
|
|
66141
|
+
allowCompilerTransform
|
|
66142
|
+
})) return true;
|
|
66008
66143
|
return allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, node.name.text);
|
|
66009
66144
|
}
|
|
66010
66145
|
if (ts.isIdentifier(node.expression)) {
|
|
66011
|
-
if (analysis.localBindings.has(node.expression.text)) {
|
|
66012
|
-
const
|
|
66013
|
-
return Boolean(
|
|
66146
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
66147
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
66148
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
66014
66149
|
}
|
|
66015
66150
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
66016
66151
|
if (importBinding?.isNamespace) {
|
|
66017
66152
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.name.text)) return true;
|
|
66018
|
-
if (
|
|
66019
|
-
|
|
66020
|
-
|
|
66021
|
-
|
|
66153
|
+
if (analyzeImportedConfig({
|
|
66154
|
+
analysis,
|
|
66155
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
66156
|
+
exportName: node.name.text,
|
|
66157
|
+
allowCompilerTransform
|
|
66158
|
+
})) return true;
|
|
66022
66159
|
return false;
|
|
66023
66160
|
}
|
|
66024
66161
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
@@ -66029,13 +66166,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
66029
66166
|
}
|
|
66030
66167
|
if (ts.isElementAccessExpression(node) && node.argumentExpression && ts.isStringLiteralLike(node.argumentExpression)) {
|
|
66031
66168
|
if (ts.isIdentifier(node.expression)) {
|
|
66169
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
66170
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
66171
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
66172
|
+
}
|
|
66032
66173
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
66033
66174
|
if (importBinding?.isNamespace) {
|
|
66034
66175
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.argumentExpression.text)) return true;
|
|
66035
|
-
|
|
66036
|
-
|
|
66037
|
-
|
|
66038
|
-
|
|
66176
|
+
return Boolean(analyzeImportedConfig({
|
|
66177
|
+
analysis,
|
|
66178
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
66179
|
+
exportName: node.argumentExpression.text,
|
|
66180
|
+
allowCompilerTransform
|
|
66181
|
+
}));
|
|
66039
66182
|
}
|
|
66040
66183
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
66041
66184
|
if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
@@ -66073,14 +66216,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
66073
66216
|
};
|
|
66074
66217
|
const hasCompilerInConfigFile = (filePath) => analyzeConfigModuleExport(filePath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
66075
66218
|
const hasCompilerInConfigFiles = (directory, filenames) => filenames.some((filename) => hasCompilerInConfigFile(Path.join(directory, filename)));
|
|
66076
|
-
const hasCompilerInPackageJsonConfig = (
|
|
66077
|
-
|
|
66219
|
+
const hasCompilerInPackageJsonConfig = (directory, packageJson) => {
|
|
66220
|
+
if (!isPlainObject(packageJson.babel)) return false;
|
|
66221
|
+
const packageJsonPath = Path.join(directory, "package.json");
|
|
66222
|
+
return analyzeConfigSourceFileExport(ts.parseJsonText(packageJsonPath, JSON.stringify(packageJson.babel)), packageJsonPath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
66223
|
+
};
|
|
66224
|
+
const hasCompilerConfiguration = (directory, packageJson) => hasCompilerInPackageJsonConfig(directory, packageJson) || hasCompilerInConfigFiles(directory, REACT_COMPILER_CONFIG_FILENAMES);
|
|
66078
66225
|
const hasCompilerConfigurationInAncestors = (directory) => {
|
|
66079
66226
|
if (isProjectBoundary(directory)) return false;
|
|
66080
66227
|
let ancestorDirectory = Path.dirname(directory);
|
|
66081
66228
|
while (ancestorDirectory !== Path.dirname(ancestorDirectory)) {
|
|
66082
66229
|
const ancestorPackagePath = Path.join(ancestorDirectory, "package.json");
|
|
66083
|
-
|
|
66230
|
+
const ancestorPackageJson = isFile(ancestorPackagePath) ? readPackageJson$1(ancestorPackagePath) : {};
|
|
66231
|
+
if (hasCompilerInPackageJsonConfig(ancestorDirectory, ancestorPackageJson) || hasCompilerInConfigFiles(ancestorDirectory, BABEL_CONFIG_FILENAMES)) return true;
|
|
66084
66232
|
if (isProjectBoundary(ancestorDirectory)) return false;
|
|
66085
66233
|
ancestorDirectory = Path.dirname(ancestorDirectory);
|
|
66086
66234
|
}
|
|
@@ -69335,7 +69483,7 @@ const warn = (message) => {
|
|
|
69335
69483
|
runSync(warn$1(message));
|
|
69336
69484
|
};
|
|
69337
69485
|
const CONFIG_BASENAME = "doctor.config";
|
|
69338
|
-
const CONFIG_EXTENSIONS = [
|
|
69486
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
69339
69487
|
"ts",
|
|
69340
69488
|
"mts",
|
|
69341
69489
|
"cts",
|
|
@@ -69439,7 +69587,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
69439
69587
|
};
|
|
69440
69588
|
const loadConfigFromDirectory = async (directory) => {
|
|
69441
69589
|
let sawBrokenConfigFile = false;
|
|
69442
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
69590
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
69443
69591
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
69444
69592
|
if (!isFile(filePath)) continue;
|
|
69445
69593
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -69498,7 +69646,7 @@ const loadConfigWithSource = (rootDirectory) => {
|
|
|
69498
69646
|
return loadPromise;
|
|
69499
69647
|
};
|
|
69500
69648
|
const directoryHasCurrentConfig = (directory) => {
|
|
69501
|
-
for (const extension of CONFIG_EXTENSIONS) if (isFile(Path.join(directory, `${CONFIG_BASENAME}.${extension}`))) return true;
|
|
69649
|
+
for (const extension of CONFIG_EXTENSIONS$1) if (isFile(Path.join(directory, `${CONFIG_BASENAME}.${extension}`))) return true;
|
|
69502
69650
|
return readEmbeddedPackageJsonConfig(directory) !== null;
|
|
69503
69651
|
};
|
|
69504
69652
|
/**
|
|
@@ -70202,6 +70350,316 @@ const buildReactNativeDiagnostic = (input) => ({
|
|
|
70202
70350
|
column: input.column ?? 0,
|
|
70203
70351
|
category: input.category ?? "Correctness"
|
|
70204
70352
|
});
|
|
70353
|
+
const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
|
|
70354
|
+
const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
|
|
70355
|
+
const RELEASE_STRING_MARKER = "__RD_RELEASE__";
|
|
70356
|
+
const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
|
|
70357
|
+
const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
70358
|
+
const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
70359
|
+
const stripGradleComments = (contents) => {
|
|
70360
|
+
let result = "";
|
|
70361
|
+
let index = 0;
|
|
70362
|
+
let quote = null;
|
|
70363
|
+
while (index < contents.length) {
|
|
70364
|
+
const character = contents[index];
|
|
70365
|
+
const nextCharacter = contents[index + 1];
|
|
70366
|
+
if (quote !== null) {
|
|
70367
|
+
result += character;
|
|
70368
|
+
if (character === "\\") {
|
|
70369
|
+
result += nextCharacter ?? "";
|
|
70370
|
+
index += 2;
|
|
70371
|
+
continue;
|
|
70372
|
+
}
|
|
70373
|
+
if (character === quote) quote = null;
|
|
70374
|
+
index += 1;
|
|
70375
|
+
continue;
|
|
70376
|
+
}
|
|
70377
|
+
if (character === "\"" || character === "'") {
|
|
70378
|
+
quote = character;
|
|
70379
|
+
result += character;
|
|
70380
|
+
index += 1;
|
|
70381
|
+
continue;
|
|
70382
|
+
}
|
|
70383
|
+
if (character === "/" && nextCharacter === "/") {
|
|
70384
|
+
while (index < contents.length && contents[index] !== "\n") {
|
|
70385
|
+
result += " ";
|
|
70386
|
+
index += 1;
|
|
70387
|
+
}
|
|
70388
|
+
continue;
|
|
70389
|
+
}
|
|
70390
|
+
if (character === "/" && nextCharacter === "*") {
|
|
70391
|
+
result += " ";
|
|
70392
|
+
index += 2;
|
|
70393
|
+
while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
|
|
70394
|
+
result += contents[index] === "\n" ? "\n" : " ";
|
|
70395
|
+
index += 1;
|
|
70396
|
+
}
|
|
70397
|
+
if (index < contents.length) {
|
|
70398
|
+
result += " ";
|
|
70399
|
+
index += 2;
|
|
70400
|
+
}
|
|
70401
|
+
continue;
|
|
70402
|
+
}
|
|
70403
|
+
result += character;
|
|
70404
|
+
index += 1;
|
|
70405
|
+
}
|
|
70406
|
+
return result;
|
|
70407
|
+
};
|
|
70408
|
+
const maskGradleStrings = (contents) => {
|
|
70409
|
+
let result = "";
|
|
70410
|
+
let index = 0;
|
|
70411
|
+
let quote = null;
|
|
70412
|
+
while (index < contents.length) {
|
|
70413
|
+
const character = contents[index];
|
|
70414
|
+
if (quote === null) {
|
|
70415
|
+
if (character === "\"" || character === "'") {
|
|
70416
|
+
quote = character;
|
|
70417
|
+
result += " ";
|
|
70418
|
+
} else result += character;
|
|
70419
|
+
index += 1;
|
|
70420
|
+
continue;
|
|
70421
|
+
}
|
|
70422
|
+
if (character === "\\") {
|
|
70423
|
+
result += " ";
|
|
70424
|
+
index += 2;
|
|
70425
|
+
continue;
|
|
70426
|
+
}
|
|
70427
|
+
if (character === quote) quote = null;
|
|
70428
|
+
result += character === "\n" ? "\n" : " ";
|
|
70429
|
+
index += 1;
|
|
70430
|
+
}
|
|
70431
|
+
return result;
|
|
70432
|
+
};
|
|
70433
|
+
const findBlockContents = (contents, pattern) => {
|
|
70434
|
+
const blocks = [];
|
|
70435
|
+
pattern.lastIndex = 0;
|
|
70436
|
+
let match = pattern.exec(contents);
|
|
70437
|
+
while (match !== null) {
|
|
70438
|
+
const openingBraceIndex = pattern.lastIndex - 1;
|
|
70439
|
+
let depth = 1;
|
|
70440
|
+
let index = openingBraceIndex + 1;
|
|
70441
|
+
let quote = null;
|
|
70442
|
+
while (index < contents.length && depth > 0) {
|
|
70443
|
+
const character = contents[index];
|
|
70444
|
+
if (quote !== null) {
|
|
70445
|
+
if (character === "\\") {
|
|
70446
|
+
index += 2;
|
|
70447
|
+
continue;
|
|
70448
|
+
}
|
|
70449
|
+
if (character === quote) quote = null;
|
|
70450
|
+
} else if (character === "\"" || character === "'") quote = character;
|
|
70451
|
+
else if (character === "{") depth += 1;
|
|
70452
|
+
else if (character === "}") depth -= 1;
|
|
70453
|
+
index += 1;
|
|
70454
|
+
}
|
|
70455
|
+
if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
|
|
70456
|
+
match = pattern.exec(contents);
|
|
70457
|
+
}
|
|
70458
|
+
return blocks;
|
|
70459
|
+
};
|
|
70460
|
+
const getFinalStaticBoolean = (contents, pattern) => {
|
|
70461
|
+
pattern.lastIndex = 0;
|
|
70462
|
+
let finalValue = null;
|
|
70463
|
+
let match = pattern.exec(contents);
|
|
70464
|
+
while (match !== null) {
|
|
70465
|
+
const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
|
|
70466
|
+
if (staticValue === "true") finalValue = true;
|
|
70467
|
+
else if (staticValue === "false") finalValue = false;
|
|
70468
|
+
else finalValue = null;
|
|
70469
|
+
match = pattern.exec(contents);
|
|
70470
|
+
}
|
|
70471
|
+
return finalValue;
|
|
70472
|
+
};
|
|
70473
|
+
const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
|
|
70474
|
+
const readAndroidReleaseShrinking = (rootDirectory) => {
|
|
70475
|
+
for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
|
|
70476
|
+
const filePath = Path.posix.join("android", "app", buildFileName);
|
|
70477
|
+
const absoluteFilePath = Path.join(rootDirectory, filePath);
|
|
70478
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
70479
|
+
let contents;
|
|
70480
|
+
try {
|
|
70481
|
+
contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
|
|
70482
|
+
} catch {
|
|
70483
|
+
return null;
|
|
70484
|
+
}
|
|
70485
|
+
const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
|
|
70486
|
+
const [releaseBlock] = releaseBlocks;
|
|
70487
|
+
if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
|
|
70488
|
+
const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
|
|
70489
|
+
const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
|
|
70490
|
+
if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
|
|
70491
|
+
return {
|
|
70492
|
+
filePath,
|
|
70493
|
+
hasDisabledMinification,
|
|
70494
|
+
hasDisabledResourceShrinking
|
|
70495
|
+
};
|
|
70496
|
+
}
|
|
70497
|
+
return null;
|
|
70498
|
+
};
|
|
70499
|
+
const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
|
|
70500
|
+
const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
|
|
70501
|
+
if (releaseShrinking === null) return [];
|
|
70502
|
+
const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
|
|
70503
|
+
return [buildReactNativeDiagnostic({
|
|
70504
|
+
filePath: releaseShrinking.filePath,
|
|
70505
|
+
rule: "rn-android-release-shrinking-disabled",
|
|
70506
|
+
category: "Performance",
|
|
70507
|
+
message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
|
|
70508
|
+
help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
|
|
70509
|
+
})];
|
|
70510
|
+
};
|
|
70511
|
+
const getTypescriptScriptKind = (fileName) => {
|
|
70512
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
70513
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
70514
|
+
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
70515
|
+
return ts.ScriptKind.JS;
|
|
70516
|
+
};
|
|
70517
|
+
const BABEL_CONFIG_FILE_NAMES$1 = [
|
|
70518
|
+
"babel.config.js",
|
|
70519
|
+
"babel.config.cjs",
|
|
70520
|
+
"babel.config.mjs",
|
|
70521
|
+
"babel.config.ts",
|
|
70522
|
+
"babel.config.cts",
|
|
70523
|
+
"babel.config.json",
|
|
70524
|
+
".babelrc",
|
|
70525
|
+
".babelrc.js",
|
|
70526
|
+
".babelrc.cjs",
|
|
70527
|
+
".babelrc.mjs",
|
|
70528
|
+
".babelrc.cts",
|
|
70529
|
+
".babelrc.json"
|
|
70530
|
+
];
|
|
70531
|
+
const readUnknownPluginNames = (value) => {
|
|
70532
|
+
if (!Array.isArray(value)) return null;
|
|
70533
|
+
const pluginNames = [];
|
|
70534
|
+
for (const entry of value) {
|
|
70535
|
+
if (typeof entry === "string") {
|
|
70536
|
+
pluginNames.push(entry);
|
|
70537
|
+
continue;
|
|
70538
|
+
}
|
|
70539
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") {
|
|
70540
|
+
pluginNames.push(entry[0]);
|
|
70541
|
+
continue;
|
|
70542
|
+
}
|
|
70543
|
+
return null;
|
|
70544
|
+
}
|
|
70545
|
+
return pluginNames;
|
|
70546
|
+
};
|
|
70547
|
+
const getStaticPropertyName$1 = (propertyName) => {
|
|
70548
|
+
if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
|
|
70549
|
+
return null;
|
|
70550
|
+
};
|
|
70551
|
+
const getStaticPluginName = (expression) => {
|
|
70552
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70553
|
+
if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
|
|
70554
|
+
if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
|
|
70555
|
+
const pluginExpression = unwrappedExpression.elements[0];
|
|
70556
|
+
return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
|
|
70557
|
+
};
|
|
70558
|
+
const getPluginNamesFromObject = (objectExpression) => {
|
|
70559
|
+
if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
|
|
70560
|
+
const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
|
|
70561
|
+
if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
|
|
70562
|
+
const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
|
|
70563
|
+
if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
|
|
70564
|
+
const pluginNames = [];
|
|
70565
|
+
for (const element of pluginListExpression.elements) {
|
|
70566
|
+
if (ts.isSpreadElement(element)) return null;
|
|
70567
|
+
const pluginName = getStaticPluginName(element);
|
|
70568
|
+
if (pluginName === null) return null;
|
|
70569
|
+
pluginNames.push(pluginName);
|
|
70570
|
+
}
|
|
70571
|
+
return pluginNames;
|
|
70572
|
+
};
|
|
70573
|
+
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";
|
|
70574
|
+
const getDirectExportedObject = (sourceFile) => {
|
|
70575
|
+
const exportedExpressions = [];
|
|
70576
|
+
for (const statement of sourceFile.statements) {
|
|
70577
|
+
if (ts.isExportAssignment(statement)) {
|
|
70578
|
+
exportedExpressions.push(statement.expression);
|
|
70579
|
+
continue;
|
|
70580
|
+
}
|
|
70581
|
+
if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
|
|
70582
|
+
}
|
|
70583
|
+
if (exportedExpressions.length !== 1) return null;
|
|
70584
|
+
const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
|
|
70585
|
+
return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
|
|
70586
|
+
};
|
|
70587
|
+
const parseConfigPluginNames = (filePath, contents) => {
|
|
70588
|
+
try {
|
|
70589
|
+
const parsedJson = JSON.parse(contents);
|
|
70590
|
+
return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
|
|
70591
|
+
} catch {
|
|
70592
|
+
if (ts.transpileModule(contents, {
|
|
70593
|
+
fileName: filePath,
|
|
70594
|
+
reportDiagnostics: true,
|
|
70595
|
+
compilerOptions: { allowJs: true }
|
|
70596
|
+
}).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
|
|
70597
|
+
const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
|
|
70598
|
+
return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
|
|
70599
|
+
}
|
|
70600
|
+
};
|
|
70601
|
+
const readStaticBabelPluginNames = (rootDirectory) => {
|
|
70602
|
+
for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
|
|
70603
|
+
const absoluteFilePath = Path.join(rootDirectory, fileName);
|
|
70604
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
70605
|
+
try {
|
|
70606
|
+
return {
|
|
70607
|
+
filePath: fileName,
|
|
70608
|
+
pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
|
|
70609
|
+
};
|
|
70610
|
+
} catch {
|
|
70611
|
+
return {
|
|
70612
|
+
filePath: fileName,
|
|
70613
|
+
pluginNames: null
|
|
70614
|
+
};
|
|
70615
|
+
}
|
|
70616
|
+
}
|
|
70617
|
+
const packageJson = readPackageJson$1(Path.join(rootDirectory, "package.json"));
|
|
70618
|
+
if (!isPlainObject(packageJson.babel)) return null;
|
|
70619
|
+
return {
|
|
70620
|
+
filePath: "package.json",
|
|
70621
|
+
pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
|
|
70622
|
+
};
|
|
70623
|
+
};
|
|
70624
|
+
const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
|
|
70625
|
+
const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
|
|
70626
|
+
const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
|
|
70627
|
+
const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
|
|
70628
|
+
if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
|
|
70629
|
+
return [buildReactNativeDiagnostic({
|
|
70630
|
+
filePath,
|
|
70631
|
+
rule: "rn-react-compiler-plugin-first",
|
|
70632
|
+
category: "Performance",
|
|
70633
|
+
message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
|
|
70634
|
+
help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
|
|
70635
|
+
})];
|
|
70636
|
+
};
|
|
70637
|
+
const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
|
|
70638
|
+
const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
|
|
70639
|
+
if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
|
|
70640
|
+
const diagnostics = [];
|
|
70641
|
+
if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
|
|
70642
|
+
filePath,
|
|
70643
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
70644
|
+
category: "Performance",
|
|
70645
|
+
message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
|
|
70646
|
+
help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
|
|
70647
|
+
}));
|
|
70648
|
+
const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
|
|
70649
|
+
if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
|
|
70650
|
+
filePath,
|
|
70651
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
70652
|
+
category: "Performance",
|
|
70653
|
+
message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
|
|
70654
|
+
help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
|
|
70655
|
+
}));
|
|
70656
|
+
return diagnostics;
|
|
70657
|
+
};
|
|
70658
|
+
const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
|
|
70659
|
+
const babelPlugins = readStaticBabelPluginNames(rootDirectory);
|
|
70660
|
+
if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
|
|
70661
|
+
return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
|
|
70662
|
+
};
|
|
70205
70663
|
const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
|
|
70206
70664
|
const isBuilderBobLibrary = (packageJson) => {
|
|
70207
70665
|
const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
|
|
@@ -70278,7 +70736,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
70278
70736
|
const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
|
|
70279
70737
|
const checkReactNativeProject = (rootDirectory, project) => {
|
|
70280
70738
|
if (!isReactNativeProject(project)) return [];
|
|
70281
|
-
return [
|
|
70739
|
+
return [
|
|
70740
|
+
...checkReactNativeMetroBabelPreset(rootDirectory),
|
|
70741
|
+
...checkReactNativeBabelPluginOrder(rootDirectory, project),
|
|
70742
|
+
...checkReactNativeAndroidReleaseShrinking(rootDirectory),
|
|
70743
|
+
...checkReactNativeLibraryDependencies(rootDirectory)
|
|
70744
|
+
];
|
|
70282
70745
|
};
|
|
70283
70746
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
70284
70747
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
@@ -70429,17 +70892,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
|
|
|
70429
70892
|
}
|
|
70430
70893
|
return diagnostics;
|
|
70431
70894
|
};
|
|
70432
|
-
const getTypescriptScriptKind = (fileName) => {
|
|
70433
|
-
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
70434
|
-
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
70435
|
-
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
70436
|
-
return ts.ScriptKind.JS;
|
|
70437
|
-
};
|
|
70438
|
-
const unwrapTypescriptExpression = (expression) => {
|
|
70439
|
-
let currentExpression = expression;
|
|
70440
|
-
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
70441
|
-
return currentExpression;
|
|
70442
|
-
};
|
|
70443
70895
|
const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
|
|
70444
70896
|
isAnimationFunction: false,
|
|
70445
70897
|
isMotionComponent: false,
|
|
@@ -70995,7 +71447,11 @@ const buildCapabilities = (project) => {
|
|
|
70995
71447
|
capabilities.add(project.framework);
|
|
70996
71448
|
if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
|
|
70997
71449
|
if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
|
|
70998
|
-
if (project.expoVersion !== null)
|
|
71450
|
+
if (project.expoVersion !== null) {
|
|
71451
|
+
capabilities.add("expo");
|
|
71452
|
+
const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
|
|
71453
|
+
if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
|
|
71454
|
+
}
|
|
70999
71455
|
if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
|
|
71000
71456
|
if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
|
|
71001
71457
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
@@ -71059,6 +71515,11 @@ const buildCapabilities = (project) => {
|
|
|
71059
71515
|
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
71060
71516
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
71061
71517
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
71518
|
+
if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
|
|
71519
|
+
capabilities.add("reanimated");
|
|
71520
|
+
const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
|
|
71521
|
+
if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
|
|
71522
|
+
}
|
|
71062
71523
|
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
71063
71524
|
if (project.styledComponentsVersion) {
|
|
71064
71525
|
capabilities.add("styled-components");
|
|
@@ -72972,7 +73433,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
72972
73433
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
72973
73434
|
const normalizeConfigForHash = (config) => {
|
|
72974
73435
|
const clone = JSON.parse(JSON.stringify(config));
|
|
72975
|
-
if (clone?.settings?.["react-doctor"])
|
|
73436
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
73437
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
73438
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
73439
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
73440
|
+
}
|
|
72976
73441
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
72977
73442
|
return clone;
|
|
72978
73443
|
};
|
|
@@ -73131,13 +73596,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
73131
73596
|
}
|
|
73132
73597
|
return enabled;
|
|
73133
73598
|
};
|
|
73134
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
73599
|
+
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 }) => {
|
|
73135
73600
|
const hasIncludedTags = includedTags.size > 0;
|
|
73136
73601
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
73137
73602
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
73138
73603
|
const jsPlugins = [];
|
|
73139
73604
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
73140
73605
|
const capabilities = getCapabilities(project);
|
|
73606
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
73141
73607
|
const enabledReactDoctorRules = {};
|
|
73142
73608
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
73143
73609
|
const rule = reactDoctorPlugin.rules[registryEntry.id];
|
|
@@ -73183,8 +73649,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
73183
73649
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
73184
73650
|
settings: { "react-doctor": {
|
|
73185
73651
|
framework: project.framework,
|
|
73186
|
-
rootDirectory:
|
|
73652
|
+
rootDirectory: settingsRootDirectory,
|
|
73187
73653
|
capabilities: [...capabilities].sort(),
|
|
73654
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
73655
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
73656
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
73657
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
73658
|
+
directory: scope.directory,
|
|
73659
|
+
names: [...scope.names]
|
|
73660
|
+
}))
|
|
73661
|
+
} : {},
|
|
73188
73662
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
73189
73663
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
73190
73664
|
} },
|
|
@@ -73195,6 +73669,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
73195
73669
|
}
|
|
73196
73670
|
};
|
|
73197
73671
|
};
|
|
73672
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
73673
|
+
const CONFIG_BASENAMES = [
|
|
73674
|
+
"astro.config",
|
|
73675
|
+
"esbuild.config",
|
|
73676
|
+
"rollup.config",
|
|
73677
|
+
"rolldown.config",
|
|
73678
|
+
"rspack.config",
|
|
73679
|
+
"vite.config",
|
|
73680
|
+
"webpack.config"
|
|
73681
|
+
];
|
|
73682
|
+
const CONFIG_EXTENSIONS = [
|
|
73683
|
+
".cjs",
|
|
73684
|
+
".cts",
|
|
73685
|
+
".js",
|
|
73686
|
+
".mjs",
|
|
73687
|
+
".mts",
|
|
73688
|
+
".ts"
|
|
73689
|
+
];
|
|
73690
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
73691
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
73692
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
73693
|
+
true,
|
|
73694
|
+
false,
|
|
73695
|
+
"readable",
|
|
73696
|
+
"readonly",
|
|
73697
|
+
"writable",
|
|
73698
|
+
"writeable"
|
|
73699
|
+
]);
|
|
73700
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
73701
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
73702
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
73703
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
73704
|
+
}) ?? null;
|
|
73705
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
73706
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
73707
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
73708
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
73709
|
+
};
|
|
73710
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
73711
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
73712
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
73713
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
73714
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
73715
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
73716
|
+
};
|
|
73717
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
73718
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
73719
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
73720
|
+
};
|
|
73721
|
+
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");
|
|
73722
|
+
const isTopLevelExpression = (node) => {
|
|
73723
|
+
let ancestor = node.parent;
|
|
73724
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
73725
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
73726
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
73727
|
+
ancestor = ancestor.parent;
|
|
73728
|
+
}
|
|
73729
|
+
return false;
|
|
73730
|
+
};
|
|
73731
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
73732
|
+
let ancestor = node.parent;
|
|
73733
|
+
let didFindConfigProperty = false;
|
|
73734
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
73735
|
+
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;
|
|
73736
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
73737
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
73738
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
73739
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
73740
|
+
didFindConfigProperty = true;
|
|
73741
|
+
ancestor = ancestor.parent;
|
|
73742
|
+
continue;
|
|
73743
|
+
}
|
|
73744
|
+
if (didFindConfigProperty) {
|
|
73745
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
73746
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
73747
|
+
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);
|
|
73748
|
+
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;
|
|
73749
|
+
}
|
|
73750
|
+
ancestor = ancestor.parent;
|
|
73751
|
+
}
|
|
73752
|
+
return false;
|
|
73753
|
+
};
|
|
73754
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
73755
|
+
const optionsExpression = callExpression.arguments[0];
|
|
73756
|
+
if (!optionsExpression) return null;
|
|
73757
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
73758
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
73759
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
73760
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
73761
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
73762
|
+
if (!eslintrcProperty) return null;
|
|
73763
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
73764
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
73765
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
73766
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
73767
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
73768
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
73769
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
73770
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
73771
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
73772
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
73773
|
+
};
|
|
73774
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
73775
|
+
let sourceText;
|
|
73776
|
+
try {
|
|
73777
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
73778
|
+
} catch {
|
|
73779
|
+
return {
|
|
73780
|
+
didFindActiveAutoImport: false,
|
|
73781
|
+
globalsPaths: []
|
|
73782
|
+
};
|
|
73783
|
+
}
|
|
73784
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
73785
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
73786
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
73787
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
73788
|
+
for (const statement of sourceFile.statements) {
|
|
73789
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
73790
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
73791
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
73792
|
+
const defaultBinding = statement.importClause?.name;
|
|
73793
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
73794
|
+
}
|
|
73795
|
+
if (moduleSpecifier === "esbuild") {
|
|
73796
|
+
const defaultBinding = statement.importClause?.name;
|
|
73797
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
73798
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
73799
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
73800
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
73801
|
+
}
|
|
73802
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
73803
|
+
}
|
|
73804
|
+
}
|
|
73805
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
73806
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
73807
|
+
if (!declaration.initializer) continue;
|
|
73808
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
73809
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
73810
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
73811
|
+
if (moduleSpecifier === "esbuild") {
|
|
73812
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
73813
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
73814
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
73815
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
73816
|
+
}
|
|
73817
|
+
}
|
|
73818
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
73819
|
+
}
|
|
73820
|
+
}
|
|
73821
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
73822
|
+
let didFindActiveAutoImport = false;
|
|
73823
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
73824
|
+
const visit = (node) => {
|
|
73825
|
+
if (ts.isCallExpression(node)) {
|
|
73826
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
73827
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
73828
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
73829
|
+
didFindActiveAutoImport = true;
|
|
73830
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
73831
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
73832
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
73833
|
+
}
|
|
73834
|
+
}
|
|
73835
|
+
}
|
|
73836
|
+
ts.forEachChild(node, visit);
|
|
73837
|
+
};
|
|
73838
|
+
visit(sourceFile);
|
|
73839
|
+
return {
|
|
73840
|
+
didFindActiveAutoImport,
|
|
73841
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
73842
|
+
};
|
|
73843
|
+
};
|
|
73844
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
73845
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
73846
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
73847
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
73848
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
73849
|
+
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();
|
|
73850
|
+
};
|
|
73851
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
73852
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
73853
|
+
const visitedDirectories = [];
|
|
73854
|
+
while (true) {
|
|
73855
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
73856
|
+
if (cachedDirectory !== void 0) {
|
|
73857
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
73858
|
+
return cachedDirectory;
|
|
73859
|
+
}
|
|
73860
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
73861
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
73862
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
73863
|
+
return null;
|
|
73864
|
+
}
|
|
73865
|
+
visitedDirectories.push(currentDirectory);
|
|
73866
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
73867
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
73868
|
+
return currentDirectory;
|
|
73869
|
+
}
|
|
73870
|
+
if (currentDirectory === rootDirectory) {
|
|
73871
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
73872
|
+
return null;
|
|
73873
|
+
}
|
|
73874
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
73875
|
+
}
|
|
73876
|
+
};
|
|
73877
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
73878
|
+
let directoryEntries;
|
|
73879
|
+
try {
|
|
73880
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
73881
|
+
} catch {
|
|
73882
|
+
return [];
|
|
73883
|
+
}
|
|
73884
|
+
const configuredGlobalsPaths = [];
|
|
73885
|
+
for (const entry of directoryEntries) {
|
|
73886
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
73887
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
73888
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
73889
|
+
}
|
|
73890
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
73891
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
73892
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
73893
|
+
const names = /* @__PURE__ */ new Set();
|
|
73894
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
73895
|
+
return [...names].sort();
|
|
73896
|
+
};
|
|
73897
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
73898
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
73899
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
73900
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
73901
|
+
for (const candidateFile of candidateFiles) {
|
|
73902
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
73903
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
73904
|
+
}
|
|
73905
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
73906
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
73907
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
73908
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
73909
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
73910
|
+
};
|
|
73198
73911
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
73199
73912
|
const decodeFileDiagnostics = (raw) => {
|
|
73200
73913
|
if (!Array.isArray(raw)) return null;
|
|
@@ -73517,6 +74230,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
73517
74230
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
73518
74231
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
73519
74232
|
};
|
|
74233
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
74234
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
74235
|
+
let lineStartOffset = boundedOffset;
|
|
74236
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
74237
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
74238
|
+
};
|
|
73520
74239
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
73521
74240
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
73522
74241
|
const KNOWN_SECRET_RULES = [
|
|
@@ -74232,7 +74951,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
74232
74951
|
* with empty text still carry a useful jump target, so they're kept
|
|
74233
74952
|
* with a neutral message.
|
|
74234
74953
|
*/
|
|
74235
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
74954
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
74236
74955
|
if (labels.length <= 1) return [];
|
|
74237
74956
|
const related = [];
|
|
74238
74957
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -74240,8 +74959,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
74240
74959
|
if (!label?.span) continue;
|
|
74241
74960
|
related.push({
|
|
74242
74961
|
filePath,
|
|
74243
|
-
line: label.span.line ?? 0,
|
|
74244
|
-
column: label.span.column ?? 0,
|
|
74962
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
74963
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
74245
74964
|
offset: label.span.offset,
|
|
74246
74965
|
length: label.span.length,
|
|
74247
74966
|
message: label.label ?? ""
|
|
@@ -74261,7 +74980,7 @@ const isOxlintOutput = (value) => isRecord$1(value) && Array.isArray(value.diagn
|
|
|
74261
74980
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
74262
74981
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
74263
74982
|
*/
|
|
74264
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
74983
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
|
|
74265
74984
|
if (!stdout) return [];
|
|
74266
74985
|
const jsonStart = stdout.indexOf("{");
|
|
74267
74986
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -74278,8 +74997,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74278
74997
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
74279
74998
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
74280
74999
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
75000
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
75001
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
74281
75002
|
const readSourceBuffer = (filename) => {
|
|
74282
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
75003
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
74283
75004
|
const cached = sourceBufferCache.get(absolutePath);
|
|
74284
75005
|
if (cached !== void 0) return cached;
|
|
74285
75006
|
let sourceBuffer;
|
|
@@ -74292,7 +75013,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74292
75013
|
return sourceBuffer;
|
|
74293
75014
|
};
|
|
74294
75015
|
const readSourceLines = (filename) => {
|
|
74295
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
75016
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
74296
75017
|
const cached = sourceLinesCache.get(absolutePath);
|
|
74297
75018
|
if (cached !== void 0) return cached;
|
|
74298
75019
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -74301,27 +75022,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74301
75022
|
return sourceLines;
|
|
74302
75023
|
};
|
|
74303
75024
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
74304
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
75025
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
74305
75026
|
const cached = minifiedFileCache.get(absolutePath);
|
|
74306
75027
|
if (cached !== void 0) return cached;
|
|
74307
75028
|
const minified = isMinifiedSource(absolutePath);
|
|
74308
75029
|
minifiedFileCache.set(absolutePath, minified);
|
|
74309
75030
|
return minified;
|
|
74310
75031
|
};
|
|
74311
|
-
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) => {
|
|
75032
|
+
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) => {
|
|
74312
75033
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
74313
75034
|
const primaryLabel = diagnostic.labels[0];
|
|
74314
75035
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
74315
|
-
const
|
|
75036
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
75037
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
74316
75038
|
const primarySpan = primaryLabel?.span;
|
|
74317
75039
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
74318
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
75040
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
74319
75041
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
74320
75042
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
74321
75043
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
74322
|
-
const
|
|
75044
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
75045
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
75046
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
74323
75047
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
74324
|
-
const primaryColumnIndex = primarySpan ?
|
|
75048
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
74325
75049
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
74326
75050
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
74327
75051
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -74334,8 +75058,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74334
75058
|
message: cleaned.message,
|
|
74335
75059
|
help: cleaned.help,
|
|
74336
75060
|
url: diagnostic.url,
|
|
74337
|
-
line:
|
|
74338
|
-
column:
|
|
75061
|
+
line: primaryLineNumber,
|
|
75062
|
+
column: primaryColumnNumber,
|
|
74339
75063
|
...primarySpan ? {
|
|
74340
75064
|
offset: primarySpan.offset,
|
|
74341
75065
|
length: primarySpan.length,
|
|
@@ -74523,7 +75247,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
74523
75247
|
* loop with a slimmer config in that case.
|
|
74524
75248
|
*/
|
|
74525
75249
|
const spawnLintBatches = async (input) => {
|
|
74526
|
-
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
75250
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
75251
|
+
const resolveSourcePath = (filePath) => {
|
|
75252
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
75253
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
75254
|
+
};
|
|
74527
75255
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
74528
75256
|
let rescueDeadlineEpochMs;
|
|
74529
75257
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -74543,7 +75271,7 @@ const spawnLintBatches = async (input) => {
|
|
|
74543
75271
|
}
|
|
74544
75272
|
const batchArgs = [...baseArgs, ...batch];
|
|
74545
75273
|
try {
|
|
74546
|
-
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
|
|
75274
|
+
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
|
|
74547
75275
|
} catch (error) {
|
|
74548
75276
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
74549
75277
|
if (isPastDeadline()) {
|
|
@@ -74649,10 +75377,12 @@ const spawnLintBatches = async (input) => {
|
|
|
74649
75377
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
74650
75378
|
};
|
|
74651
75379
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
74652
|
-
|
|
74653
|
-
|
|
75380
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
75381
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
75382
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
75383
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
74654
75384
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
74655
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
75385
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
74656
75386
|
return dedupeDiagnostics(diagnostics);
|
|
74657
75387
|
};
|
|
74658
75388
|
let didValidate = false;
|
|
@@ -74751,6 +75481,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
74751
75481
|
}
|
|
74752
75482
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
74753
75483
|
};
|
|
75484
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
75485
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
75486
|
+
const COMMENT_OPEN = "<!--";
|
|
75487
|
+
const COMMENT_CLOSE = "-->";
|
|
75488
|
+
const FRONTMATTER_FENCE = "---";
|
|
75489
|
+
const SCRIPT_TAG_NAME = "script";
|
|
75490
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
75491
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
75492
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
75493
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
75494
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
75495
|
+
"application/ecmascript",
|
|
75496
|
+
"application/javascript",
|
|
75497
|
+
"application/x-ecmascript",
|
|
75498
|
+
"application/x-javascript",
|
|
75499
|
+
"text/ecmascript",
|
|
75500
|
+
"text/javascript",
|
|
75501
|
+
"text/javascript1.0",
|
|
75502
|
+
"text/javascript1.1",
|
|
75503
|
+
"text/javascript1.2",
|
|
75504
|
+
"text/javascript1.3",
|
|
75505
|
+
"text/javascript1.4",
|
|
75506
|
+
"text/javascript1.5",
|
|
75507
|
+
"text/jscript",
|
|
75508
|
+
"text/livescript",
|
|
75509
|
+
"text/x-ecmascript",
|
|
75510
|
+
"text/x-javascript"
|
|
75511
|
+
]);
|
|
75512
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
75513
|
+
"iframe",
|
|
75514
|
+
"noembed",
|
|
75515
|
+
"noframes",
|
|
75516
|
+
"noscript",
|
|
75517
|
+
"style",
|
|
75518
|
+
"textarea",
|
|
75519
|
+
"title",
|
|
75520
|
+
"xmp"
|
|
75521
|
+
]);
|
|
75522
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
75523
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
75524
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
75525
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
75526
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
75527
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
75528
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
75529
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
75530
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
75531
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
75532
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
75533
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
75534
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
75535
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
75536
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
75537
|
+
}
|
|
75538
|
+
return true;
|
|
75539
|
+
};
|
|
75540
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
75541
|
+
const isPotentialTagStart = (byte) => {
|
|
75542
|
+
if (byte === void 0) return false;
|
|
75543
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
75544
|
+
};
|
|
75545
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
75546
|
+
let byteIndex = lineStartByte;
|
|
75547
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
75548
|
+
return byteIndex;
|
|
75549
|
+
};
|
|
75550
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
75551
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
75552
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
75553
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
75554
|
+
};
|
|
75555
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
75556
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
75557
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
75558
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
75559
|
+
return true;
|
|
75560
|
+
};
|
|
75561
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
75562
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
75563
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
75564
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
75565
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
75566
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
75567
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
75568
|
+
}
|
|
75569
|
+
return openingFenceEndByte;
|
|
75570
|
+
};
|
|
75571
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
75572
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
75573
|
+
const byte = maskedBuffer[byteIndex];
|
|
75574
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
75575
|
+
}
|
|
75576
|
+
};
|
|
75577
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
75578
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
75579
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
75580
|
+
let nameEndByte = tagStartByte + 2;
|
|
75581
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
75582
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
75583
|
+
};
|
|
75584
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
75585
|
+
let quoteByte = null;
|
|
75586
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
75587
|
+
const byte = sourceBuffer[byteIndex];
|
|
75588
|
+
if (quoteByte !== null) {
|
|
75589
|
+
if (byte === quoteByte) quoteByte = null;
|
|
75590
|
+
continue;
|
|
75591
|
+
}
|
|
75592
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
75593
|
+
quoteByte = byte;
|
|
75594
|
+
continue;
|
|
75595
|
+
}
|
|
75596
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
75597
|
+
}
|
|
75598
|
+
return sourceBuffer.length;
|
|
75599
|
+
};
|
|
75600
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
75601
|
+
let byteIndex = attributesStartByte;
|
|
75602
|
+
let hasSource = false;
|
|
75603
|
+
let language = null;
|
|
75604
|
+
let scriptType = null;
|
|
75605
|
+
while (byteIndex < tagEndByte) {
|
|
75606
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
75607
|
+
const attributeNameStartByte = byteIndex;
|
|
75608
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
75609
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
75610
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
75611
|
+
let attributeValue = "";
|
|
75612
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
75613
|
+
byteIndex++;
|
|
75614
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
75615
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
75616
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
75617
|
+
const valueStartByte = byteIndex + 1;
|
|
75618
|
+
byteIndex = valueStartByte;
|
|
75619
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
75620
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
75621
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
75622
|
+
} else {
|
|
75623
|
+
const valueStartByte = byteIndex;
|
|
75624
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
75625
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
75626
|
+
}
|
|
75627
|
+
}
|
|
75628
|
+
if (attributeName === "src") hasSource = true;
|
|
75629
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
75630
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
75631
|
+
}
|
|
75632
|
+
return {
|
|
75633
|
+
hasSource,
|
|
75634
|
+
language,
|
|
75635
|
+
type: scriptType
|
|
75636
|
+
};
|
|
75637
|
+
};
|
|
75638
|
+
const isExecutableScript = (attributes) => {
|
|
75639
|
+
if (attributes.hasSource) return false;
|
|
75640
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
75641
|
+
if (type !== "") {
|
|
75642
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
75643
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
75644
|
+
}
|
|
75645
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
75646
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
75647
|
+
};
|
|
75648
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
75649
|
+
const closeTagStart = `</${tagName}`;
|
|
75650
|
+
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;
|
|
75651
|
+
return sourceBuffer.length;
|
|
75652
|
+
};
|
|
75653
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
75654
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
75655
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
75656
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
75657
|
+
const executableScriptBodies = [];
|
|
75658
|
+
let byteIndex = frontmatterEndByte;
|
|
75659
|
+
let templateDepth = 0;
|
|
75660
|
+
while (byteIndex < sourceBuffer.length) {
|
|
75661
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
75662
|
+
byteIndex++;
|
|
75663
|
+
continue;
|
|
75664
|
+
}
|
|
75665
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
75666
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
75667
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
75668
|
+
continue;
|
|
75669
|
+
}
|
|
75670
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
75671
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
75672
|
+
if (templateDepth > 0) templateDepth--;
|
|
75673
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
75674
|
+
continue;
|
|
75675
|
+
}
|
|
75676
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
75677
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
75678
|
+
byteIndex++;
|
|
75679
|
+
continue;
|
|
75680
|
+
}
|
|
75681
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
75682
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
75683
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
75684
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
75685
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
75686
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
75687
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
75688
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
75689
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
75690
|
+
continue;
|
|
75691
|
+
}
|
|
75692
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
75693
|
+
continue;
|
|
75694
|
+
}
|
|
75695
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
75696
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
75697
|
+
const bodyStartByte = tagEndByte + 1;
|
|
75698
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
75699
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
75700
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
75701
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
75702
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
75703
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
75704
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
75705
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
75706
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
75707
|
+
}
|
|
75708
|
+
return {
|
|
75709
|
+
executableScriptBodies,
|
|
75710
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
75711
|
+
};
|
|
75712
|
+
};
|
|
75713
|
+
const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
75714
|
+
const lintFiles = [];
|
|
75715
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
75716
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
75717
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
75718
|
+
let htmlFileIndex = 0;
|
|
75719
|
+
let hasThreeModuleImport = false;
|
|
75720
|
+
for (const candidateFile of candidateFiles) {
|
|
75721
|
+
if (!HTML_FILE_PATTERN.test(candidateFile)) {
|
|
75722
|
+
lintFiles.push(candidateFile);
|
|
75723
|
+
continue;
|
|
75724
|
+
}
|
|
75725
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
75726
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
75727
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
75728
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
75729
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
75730
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
75731
|
+
lintFiles.push(lintPath);
|
|
75732
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
75733
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
75734
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
75735
|
+
htmlFileIndex++;
|
|
75736
|
+
}
|
|
75737
|
+
return {
|
|
75738
|
+
lintFiles,
|
|
75739
|
+
sourcePathByLintPath,
|
|
75740
|
+
sizeByLintPath,
|
|
75741
|
+
hasThreeModuleImport
|
|
75742
|
+
};
|
|
75743
|
+
};
|
|
74754
75744
|
/**
|
|
74755
75745
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
74756
75746
|
* the runner: once for the primary scan, once for the
|
|
@@ -74911,6 +75901,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
74911
75901
|
const runOxlint = async (options) => {
|
|
74912
75902
|
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;
|
|
74913
75903
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
75904
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
75905
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
74914
75906
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
74915
75907
|
validateRuleRegistration();
|
|
74916
75908
|
resetManifestCaches();
|
|
@@ -74924,21 +75916,6 @@ const runOxlint = async (options) => {
|
|
|
74924
75916
|
const pluginPath = resolvePluginPath();
|
|
74925
75917
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
74926
75918
|
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
74927
|
-
const buildConfig = (overrides) => createOxlintConfig({
|
|
74928
|
-
pluginPath,
|
|
74929
|
-
project,
|
|
74930
|
-
customRulesOnly,
|
|
74931
|
-
extendsPaths: overrides.extendsPaths,
|
|
74932
|
-
ignoredTags,
|
|
74933
|
-
includedTags,
|
|
74934
|
-
includeTagDefaults,
|
|
74935
|
-
serverAuthFunctionNames,
|
|
74936
|
-
severityControls,
|
|
74937
|
-
userPlugins,
|
|
74938
|
-
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
74939
|
-
ruleSelection: overrides.ruleSelection,
|
|
74940
|
-
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
74941
|
-
});
|
|
74942
75919
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
74943
75920
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
74944
75921
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -74974,7 +75951,36 @@ const runOxlint = async (options) => {
|
|
|
74974
75951
|
await yieldToEventLoop();
|
|
74975
75952
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
74976
75953
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
75954
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
75955
|
+
rootDirectory,
|
|
75956
|
+
candidateFiles
|
|
75957
|
+
});
|
|
75958
|
+
const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
75959
|
+
const lintFiles = preparedHtmlSources.lintFiles;
|
|
75960
|
+
const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
|
|
75961
|
+
const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
|
|
75962
|
+
...project,
|
|
75963
|
+
hasThree: true
|
|
75964
|
+
} : project;
|
|
75965
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
75966
|
+
pluginPath,
|
|
75967
|
+
project: lintProject,
|
|
75968
|
+
customRulesOnly,
|
|
75969
|
+
extendsPaths: overrides.extendsPaths,
|
|
75970
|
+
ignoredTags,
|
|
75971
|
+
includedTags,
|
|
75972
|
+
includeTagDefaults,
|
|
75973
|
+
runtimeGlobals,
|
|
75974
|
+
unpluginAutoImportGlobalScopes,
|
|
75975
|
+
serverAuthFunctionNames,
|
|
75976
|
+
severityControls,
|
|
75977
|
+
userPlugins,
|
|
75978
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
75979
|
+
ruleSelection: overrides.ruleSelection,
|
|
75980
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
75981
|
+
});
|
|
74977
75982
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
75983
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
74978
75984
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
74979
75985
|
baseArgs: passBaseArgs,
|
|
74980
75986
|
files: passFiles,
|
|
@@ -75003,7 +76009,8 @@ const runOxlint = async (options) => {
|
|
|
75003
76009
|
fileBatches: passFileBatches,
|
|
75004
76010
|
rootDirectory,
|
|
75005
76011
|
nodeBinaryPath,
|
|
75006
|
-
project,
|
|
76012
|
+
project: lintProject,
|
|
76013
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
75007
76014
|
onPartialFailure: reportPartialFailure,
|
|
75008
76015
|
onAnalyzedFiles: (filePaths) => {
|
|
75009
76016
|
analyzedFiles = filePaths;
|
|
@@ -75038,7 +76045,7 @@ const runOxlint = async (options) => {
|
|
|
75038
76045
|
};
|
|
75039
76046
|
}
|
|
75040
76047
|
};
|
|
75041
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
76048
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
|
|
75042
76049
|
const rulesetHash = computeRulesetHash({
|
|
75043
76050
|
config: buildConfig({
|
|
75044
76051
|
extendsPaths: [],
|
|
@@ -75196,14 +76203,15 @@ const runOxlint = async (options) => {
|
|
|
75196
76203
|
]);
|
|
75197
76204
|
}
|
|
75198
76205
|
const baseArgs = makeBaseArgs(configPath);
|
|
75199
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
76206
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
75200
76207
|
let analyzedFiles = [];
|
|
75201
76208
|
const runBatches = () => spawnLintBatches({
|
|
75202
76209
|
baseArgs,
|
|
75203
76210
|
fileBatches,
|
|
75204
76211
|
rootDirectory,
|
|
75205
76212
|
nodeBinaryPath,
|
|
75206
|
-
project,
|
|
76213
|
+
project: lintProject,
|
|
76214
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
75207
76215
|
onPartialFailure,
|
|
75208
76216
|
onAnalyzedFiles: (filePaths) => {
|
|
75209
76217
|
analyzedFiles = filePaths;
|
|
@@ -77410,7 +78418,7 @@ const makeNoopConsole = () => ({
|
|
|
77410
78418
|
});
|
|
77411
78419
|
//#endregion
|
|
77412
78420
|
//#region src/cli/utils/version.ts
|
|
77413
|
-
const VERSION = "0.9.
|
|
78421
|
+
const VERSION = "0.9.2";
|
|
77414
78422
|
//#endregion
|
|
77415
78423
|
//#region src/cli/utils/json-mode.ts
|
|
77416
78424
|
let context = null;
|
|
@@ -77768,13 +78776,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
77768
78776
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
77769
78777
|
* standard `SENTRY_RELEASE` override.
|
|
77770
78778
|
*/
|
|
77771
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.
|
|
78779
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.2`;
|
|
77772
78780
|
/**
|
|
77773
78781
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
77774
78782
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
77775
78783
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
77776
78784
|
*/
|
|
77777
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.
|
|
78785
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.2") ? "development" : "production");
|
|
77778
78786
|
/**
|
|
77779
78787
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
77780
78788
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -90439,6 +91447,7 @@ const buildScanAttributes = (input) => {
|
|
|
90439
91447
|
rulesDisabled: ruleKeys.filter((key) => ruleOverrides[key] === "off").length,
|
|
90440
91448
|
fileCount: input.result?.scannedFileCount ?? null,
|
|
90441
91449
|
nonJsxFileCount: input.result?.analyzedFiles?.filter((filePath) => !JSX_FILE_PATTERN.test(filePath)).length ?? null,
|
|
91450
|
+
htmlFileCount: input.result?.analyzedFiles?.filter((filePath) => HTML_FILE_PATTERN.test(filePath)).length ?? null,
|
|
90442
91451
|
multilineDiagnosticCount: input.result?.diagnostics.filter((diagnostic) => (diagnostic.endLine ?? diagnostic.line) > diagnostic.line).length ?? null
|
|
90443
91452
|
});
|
|
90444
91453
|
};
|
|
@@ -96492,7 +97501,7 @@ ${highlighter.dim("Learn more:")}
|
|
|
96492
97501
|
${highlighter.info(CI_URL)}
|
|
96493
97502
|
`;
|
|
96494
97503
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
96495
|
-
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
|
|
97504
|
+
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS and inline HTML script source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
|
|
96496
97505
|
program.action(inspectAction);
|
|
96497
97506
|
program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
|
|
96498
97507
|
program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action((location, options) => whyAction(location, options));
|
|
@@ -96572,4 +97581,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
96572
97581
|
export { toForwardSlashes as A, highlighter as B, buildRulePriorityMap as C, resolveBlockingLevel as D, formatLearnMoreLine as E, isCiEnvironment as F, sync as G, mergeReactDoctorConfigs as H, DIAGNOSTIC_CATEGORY_BUCKETS as I, void_ as K, Progress as L, isUnicodeSupported as M, METRIC as N, isReactDoctorWorkflowInstalled as O, TUI_REPORT_DETAIL_WIDTH_FRACTION as P, Reporter as R, hasLintHardFailure as S, formatFixRecipeLine as T, resolveScanTarget as U, mapWithConcurrency as V, runPromise as W, canAnimateOnboarding as _, resolveCliInspectOptions as a, buildCodeFrame as b, detectLaunchableAgents as c, launchCliAgent as d, isShareOptedOut as f, doctorFace as g, easeOutCubic as h, selectProjects as i, findNearestPackageDirectory as j, recordCount as k, CLI_AGENT_BINARIES as l, printFooter as m, shouldFailScanGate as n, countUniqueScannedFiles as o, inspect as p, succeed$3 as q, discoverWorkspacePackages as r, setUpGitHubActions as s, exitGracefully as t, copyToClipboard as u, computeProjectedScore as v, buildSortedRuleGroups as w, buildNoScoreMessage as x, formatElapsedTime as y, getCategoryImpact as z };
|
|
96573
97582
|
|
|
96574
97583
|
//# sourceMappingURL=cli.js.map
|
|
96575
|
-
//# debugId=
|
|
97584
|
+
//# debugId=c86de9ea-b858-5528-89a8-6ff4d377c873
|