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/index.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]="41e39010-e2d7-5e6b-9bba-626bf64affe5")}catch(e){}}();
|
|
3
3
|
import { i as __toESM$1, r as __require, t as __commonJSMin$1 } from "./chunk-ChKA3wi6.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
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";
|
|
@@ -11,6 +11,7 @@ import * as Path from "node:path";
|
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import * as NodeChildProcess from "node:child_process";
|
|
13
13
|
import { execFileSync, spawn, spawnSync } from "node:child_process";
|
|
14
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
14
15
|
import ts from "typescript";
|
|
15
16
|
import * as OS from "node:os";
|
|
16
17
|
import os from "node:os";
|
|
@@ -61448,7 +61449,8 @@ var AmbiguousProjectError = class extends Error {
|
|
|
61448
61449
|
}
|
|
61449
61450
|
};
|
|
61450
61451
|
const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
|
|
61451
|
-
const
|
|
61452
|
+
const HTML_FILE_PATTERN = /\.html$/i;
|
|
61453
|
+
const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
|
|
61452
61454
|
const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
|
|
61453
61455
|
const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
|
|
61454
61456
|
const MINIFIED_SNIFF_BYTES = 65536;
|
|
@@ -61791,7 +61793,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
61791
61793
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
61792
61794
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
61793
61795
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
61794
|
-
const CORE_PACKAGE_VERSION = "0.9.
|
|
61796
|
+
const CORE_PACKAGE_VERSION = "0.9.2";
|
|
61795
61797
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
61796
61798
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
61797
61799
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -62041,8 +62043,13 @@ const findMonorepoRoot = (startDirectory) => {
|
|
|
62041
62043
|
* byte-equivalent copy.
|
|
62042
62044
|
*/
|
|
62043
62045
|
const isProjectBoundary = (directory) => NFS.existsSync(Path.join(directory, ".git")) || isMonorepoRoot(directory);
|
|
62046
|
+
const unwrapTypescriptExpression = (expression) => {
|
|
62047
|
+
let currentExpression = expression;
|
|
62048
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
62049
|
+
return currentExpression;
|
|
62050
|
+
};
|
|
62044
62051
|
const TSCONFIG_FILENAME = "tsconfig.json";
|
|
62045
|
-
const
|
|
62052
|
+
const isLocalModuleSpecifier = (moduleSpecifier) => moduleSpecifier === "." || moduleSpecifier === ".." || moduleSpecifier.startsWith("./") || moduleSpecifier.startsWith("../") || Path.isAbsolute(moduleSpecifier);
|
|
62046
62053
|
const ensureJsonExtension = (filePath) => Path.extname(filePath) === "" ? `${filePath}.json` : filePath;
|
|
62047
62054
|
const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
62048
62055
|
const requireFromConfig = createRequire(Path.join(fromConfigDirectory, "tsconfig.json"));
|
|
@@ -62059,7 +62066,12 @@ const resolvePackageExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
|
62059
62066
|
return null;
|
|
62060
62067
|
};
|
|
62061
62068
|
const resolveExtendsPath = (extendsValue, fromConfigDirectory) => {
|
|
62062
|
-
if (
|
|
62069
|
+
if (isLocalModuleSpecifier(extendsValue)) {
|
|
62070
|
+
const resolvedPath = Path.resolve(fromConfigDirectory, extendsValue);
|
|
62071
|
+
if (isFile(resolvedPath)) return resolvedPath;
|
|
62072
|
+
const directoryConfigPath = Path.join(resolvedPath, TSCONFIG_FILENAME);
|
|
62073
|
+
return isFile(directoryConfigPath) ? directoryConfigPath : ensureJsonExtension(resolvedPath);
|
|
62074
|
+
}
|
|
62063
62075
|
return resolvePackageExtendsPath(extendsValue, fromConfigDirectory);
|
|
62064
62076
|
};
|
|
62065
62077
|
const normalizeCompilerOptions = (compilerOptions) => {
|
|
@@ -62253,6 +62265,15 @@ const REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS = [
|
|
|
62253
62265
|
".cts",
|
|
62254
62266
|
".json"
|
|
62255
62267
|
];
|
|
62268
|
+
const REACT_COMPILER_CONFIG_RESOLVER = new ResolverFactory({
|
|
62269
|
+
conditionNames: [
|
|
62270
|
+
"import",
|
|
62271
|
+
"require",
|
|
62272
|
+
"node",
|
|
62273
|
+
"default"
|
|
62274
|
+
],
|
|
62275
|
+
extensions: REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS
|
|
62276
|
+
});
|
|
62256
62277
|
const STATIC_EXPORT_OUTPUT_PATTERN = /(?:^|[^.\w])["']?output["']?\s*:\s*["']export["']/m;
|
|
62257
62278
|
const hasCompilerPackage = (packageJson, compilerPackages) => {
|
|
62258
62279
|
const allDependencies = {
|
|
@@ -62276,6 +62297,18 @@ const hasCompilerPackageInAncestors = (directory, compilerPackages) => {
|
|
|
62276
62297
|
return false;
|
|
62277
62298
|
};
|
|
62278
62299
|
const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
62300
|
+
if (!isLocalModuleSpecifier(moduleSpecifier)) {
|
|
62301
|
+
try {
|
|
62302
|
+
const resolvedPath = REACT_COMPILER_CONFIG_RESOLVER.resolveFileSync(fromFilePath, moduleSpecifier).path;
|
|
62303
|
+
if (resolvedPath && isFile(resolvedPath)) return resolvedPath;
|
|
62304
|
+
} catch {}
|
|
62305
|
+
try {
|
|
62306
|
+
const resolvedPath = createRequire(fromFilePath).resolve(moduleSpecifier);
|
|
62307
|
+
return isFile(resolvedPath) ? resolvedPath : null;
|
|
62308
|
+
} catch {
|
|
62309
|
+
return null;
|
|
62310
|
+
}
|
|
62311
|
+
}
|
|
62279
62312
|
const unresolvedPath = Path.resolve(Path.dirname(fromFilePath), moduleSpecifier);
|
|
62280
62313
|
const extension = Path.extname(unresolvedPath);
|
|
62281
62314
|
return (extension ? [unresolvedPath, ...REACT_COMPILER_CONFIG_SOURCE_EXTENSIONS.map((sourceExtension) => `${unresolvedPath.slice(0, -extension.length)}${sourceExtension}`)] : [
|
|
@@ -62285,10 +62318,10 @@ const resolveImportedConfigFile = (fromFilePath, moduleSpecifier) => {
|
|
|
62285
62318
|
]).find(isFile) ?? null;
|
|
62286
62319
|
};
|
|
62287
62320
|
const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json") || Path.basename(filePath) === ".babelrc" ? ts.parseJsonText(filePath, content) : ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);
|
|
62288
|
-
const getStaticPropertyName$
|
|
62321
|
+
const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
|
|
62289
62322
|
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");
|
|
62290
62323
|
const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
|
|
62291
|
-
const getRequireModuleSpecifier = (expression) => {
|
|
62324
|
+
const getRequireModuleSpecifier$1 = (expression) => {
|
|
62292
62325
|
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
|
|
62293
62326
|
const moduleSpecifier = expression.arguments[0];
|
|
62294
62327
|
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
@@ -62301,7 +62334,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
62301
62334
|
const namedBindings = importClause?.namedBindings;
|
|
62302
62335
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
62303
62336
|
}
|
|
62304
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
62337
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
62305
62338
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
62306
62339
|
});
|
|
62307
62340
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -62332,24 +62365,24 @@ const getImportBinding = (sourceFile, bindingName) => {
|
|
|
62332
62365
|
for (const declaration of statement.declarationList.declarations) {
|
|
62333
62366
|
if (!declaration.initializer) continue;
|
|
62334
62367
|
if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
|
|
62335
|
-
const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62368
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62336
62369
|
if (directModuleSpecifier) return {
|
|
62337
62370
|
moduleSpecifier: directModuleSpecifier,
|
|
62338
62371
|
exportName: "default",
|
|
62339
62372
|
isNamespace: true
|
|
62340
62373
|
};
|
|
62341
|
-
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
|
|
62342
|
-
moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
|
|
62374
|
+
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
|
|
62375
|
+
moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
|
|
62343
62376
|
exportName: declaration.initializer.name.text,
|
|
62344
62377
|
isNamespace: false
|
|
62345
62378
|
};
|
|
62346
62379
|
}
|
|
62347
62380
|
if (!ts.isObjectBindingPattern(declaration.name)) continue;
|
|
62348
62381
|
const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
|
|
62349
|
-
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62382
|
+
const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62350
62383
|
if (bindingElement && moduleSpecifier) return {
|
|
62351
62384
|
moduleSpecifier,
|
|
62352
|
-
exportName: bindingElement.propertyName ? getStaticPropertyName$
|
|
62385
|
+
exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
|
|
62353
62386
|
isNamespace: false
|
|
62354
62387
|
};
|
|
62355
62388
|
}
|
|
@@ -62402,6 +62435,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
62402
62435
|
};
|
|
62403
62436
|
};
|
|
62404
62437
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
62438
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
62439
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
62440
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
62441
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
62442
|
+
if (!ts.isCallExpression(node)) return false;
|
|
62443
|
+
const target = node.expression;
|
|
62444
|
+
if (ts.isIdentifier(target)) {
|
|
62445
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
62446
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
62447
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
62448
|
+
}
|
|
62449
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
62450
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
62451
|
+
const createRequireReceiver = target.expression;
|
|
62452
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
62453
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
62454
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
62455
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
62456
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
62457
|
+
}
|
|
62458
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
62459
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
62460
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
62461
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
62462
|
+
};
|
|
62463
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
62464
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
62465
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
62466
|
+
const target = callExpression.expression;
|
|
62467
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62468
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
62469
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
62470
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
62471
|
+
const resolverIdentifier = target.expression;
|
|
62472
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
62473
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
62474
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
62475
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
62476
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
62477
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
62478
|
+
return moduleSpecifierNode.text;
|
|
62479
|
+
};
|
|
62405
62480
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
62406
62481
|
let bindingScope = null;
|
|
62407
62482
|
let currentNode = identifier;
|
|
@@ -62444,9 +62519,11 @@ const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
|
62444
62519
|
initializer: assignedInitializer
|
|
62445
62520
|
};
|
|
62446
62521
|
};
|
|
62447
|
-
const getStaticConfigValueState = (expression, analysis) => {
|
|
62448
|
-
|
|
62449
|
-
|
|
62522
|
+
const getStaticConfigValueState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
62523
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
62524
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
62525
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
62526
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
62450
62527
|
if (unwrappedExpression.kind === ts.SyntaxKind.NullKeyword || ts.isIdentifier(unwrappedExpression) && unwrappedExpression.text === "undefined") return {
|
|
62451
62528
|
isNullish: true,
|
|
62452
62529
|
isTruthy: false
|
|
@@ -62462,31 +62539,31 @@ const getStaticConfigValueState = (expression, analysis) => {
|
|
|
62462
62539
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
62463
62540
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
62464
62541
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
62465
|
-
return localInitializer ? getStaticConfigValueState(localInitializer, analysis) : null;
|
|
62542
|
+
return localInitializer ? getStaticConfigValueState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
62466
62543
|
}
|
|
62467
62544
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
62468
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis) : null;
|
|
62545
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
62469
62546
|
}
|
|
62470
62547
|
if (ts.isConditionalExpression(unwrappedExpression)) {
|
|
62471
|
-
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis);
|
|
62472
|
-
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis);
|
|
62473
|
-
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis);
|
|
62474
|
-
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis);
|
|
62548
|
+
const conditionState = getStaticConfigValueState(unwrappedExpression.condition, analysis, nextVisitedExpressions);
|
|
62549
|
+
if (conditionState !== null) return getStaticConfigValueState(conditionState.isTruthy ? unwrappedExpression.whenTrue : unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
62550
|
+
const whenTrueState = getStaticConfigValueState(unwrappedExpression.whenTrue, analysis, nextVisitedExpressions);
|
|
62551
|
+
const whenFalseState = getStaticConfigValueState(unwrappedExpression.whenFalse, analysis, nextVisitedExpressions);
|
|
62475
62552
|
return whenTrueState !== null && whenFalseState !== null && whenTrueState.isNullish === whenFalseState.isNullish && whenTrueState.isTruthy === whenFalseState.isTruthy ? whenTrueState : null;
|
|
62476
62553
|
}
|
|
62477
62554
|
if (ts.isBinaryExpression(unwrappedExpression)) {
|
|
62478
|
-
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis);
|
|
62555
|
+
const leftState = getStaticConfigValueState(unwrappedExpression.left, analysis, nextVisitedExpressions);
|
|
62479
62556
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
62480
62557
|
if (leftState === null) return null;
|
|
62481
|
-
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
62558
|
+
return leftState.isTruthy ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
62482
62559
|
}
|
|
62483
62560
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.BarBarToken) {
|
|
62484
62561
|
if (leftState === null) return null;
|
|
62485
|
-
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis);
|
|
62562
|
+
return leftState.isTruthy ? leftState : getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions);
|
|
62486
62563
|
}
|
|
62487
62564
|
if (unwrappedExpression.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken) {
|
|
62488
62565
|
if (leftState === null) return null;
|
|
62489
|
-
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis) : leftState;
|
|
62566
|
+
return leftState.isNullish ? getStaticConfigValueState(unwrappedExpression.right, analysis, nextVisitedExpressions) : leftState;
|
|
62490
62567
|
}
|
|
62491
62568
|
}
|
|
62492
62569
|
return null;
|
|
@@ -62495,25 +62572,27 @@ const isStaticallyDisabledConfigExpression = (expression, analysis) => getStatic
|
|
|
62495
62572
|
const isStaticallyTruthyConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isTruthy === true;
|
|
62496
62573
|
const isStaticallyNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === true;
|
|
62497
62574
|
const isStaticallyNonNullishConfigExpression = (expression, analysis) => getStaticConfigValueState(expression, analysis)?.isNullish === false;
|
|
62498
|
-
const getReactCompilerFlagState = (expression, analysis) => {
|
|
62499
|
-
|
|
62500
|
-
|
|
62575
|
+
const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /* @__PURE__ */ new Set()) => {
|
|
62576
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
62577
|
+
if (visitedExpressions.has(unwrappedExpression)) return null;
|
|
62578
|
+
const nextVisitedExpressions = new Set(visitedExpressions);
|
|
62579
|
+
nextVisitedExpressions.add(unwrappedExpression);
|
|
62501
62580
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
62502
62581
|
const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
|
|
62503
62582
|
if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
|
|
62504
62583
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
62505
62584
|
const localInitializer = analysis.localBindings.get(unwrappedExpression.text);
|
|
62506
|
-
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis) : null;
|
|
62585
|
+
return localInitializer ? getReactCompilerFlagState(localInitializer, analysis, nextVisitedExpressions) : null;
|
|
62507
62586
|
}
|
|
62508
62587
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
62509
|
-
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis) : null;
|
|
62588
|
+
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
62510
62589
|
}
|
|
62511
62590
|
if (!ts.isObjectLiteralExpression(unwrappedExpression)) return null;
|
|
62512
62591
|
for (const property of [...unwrappedExpression.properties].reverse()) {
|
|
62513
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62592
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.initializer, analysis) };
|
|
62514
62593
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === "reactCompiler") return { isEnabled: !isStaticallyDisabledConfigExpression(property.name, analysis) };
|
|
62515
62594
|
if (ts.isSpreadAssignment(property)) {
|
|
62516
|
-
const spreadState = getReactCompilerFlagState(property.expression, analysis);
|
|
62595
|
+
const spreadState = getReactCompilerFlagState(property.expression, analysis, nextVisitedExpressions);
|
|
62517
62596
|
if (spreadState) return spreadState;
|
|
62518
62597
|
}
|
|
62519
62598
|
}
|
|
@@ -62536,8 +62615,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
|
|
|
62536
62615
|
}
|
|
62537
62616
|
if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
|
|
62538
62617
|
for (const property of [...resolvedExpression.properties].reverse()) {
|
|
62539
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62540
|
-
if (ts.isMethodDeclaration(property) && getStaticPropertyName$
|
|
62618
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return property.initializer;
|
|
62619
|
+
if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return property;
|
|
62541
62620
|
if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return property.name;
|
|
62542
62621
|
if (ts.isSpreadAssignment(property)) {
|
|
62543
62622
|
const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
|
|
@@ -62568,7 +62647,7 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
|
|
|
62568
62647
|
return resolvedExpression.properties.some((property) => {
|
|
62569
62648
|
if (ts.isSpreadAssignment(property)) return configExpressionMayDefineProperty(property.expression, propertyName, analysis);
|
|
62570
62649
|
if (ts.isPropertyAssignment(property) || ts.isShorthandPropertyAssignment(property) || ts.isMethodDeclaration(property) || ts.isGetAccessorDeclaration(property) || ts.isSetAccessorDeclaration(property)) {
|
|
62571
|
-
const staticPropertyName = getStaticPropertyName$
|
|
62650
|
+
const staticPropertyName = getStaticPropertyName$2(property.name);
|
|
62572
62651
|
return staticPropertyName === null || staticPropertyName === propertyName;
|
|
62573
62652
|
}
|
|
62574
62653
|
return false;
|
|
@@ -62587,7 +62666,7 @@ const getExportedConfigNodes = (sourceFile, exportName) => {
|
|
|
62587
62666
|
continue;
|
|
62588
62667
|
}
|
|
62589
62668
|
if (ts.isExpressionStatement(statement) && isCommonJsConfigExportAssignment(statement.expression, sourceFile) && exportName !== "default" && ts.isObjectLiteralExpression(statement.expression.right)) for (const property of [...statement.expression.right.properties].reverse()) {
|
|
62590
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$
|
|
62669
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === exportName) {
|
|
62591
62670
|
exportedNodes.push(property.initializer);
|
|
62592
62671
|
break;
|
|
62593
62672
|
}
|
|
@@ -62685,6 +62764,11 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
|
|
|
62685
62764
|
visitReturns(functionNode.body);
|
|
62686
62765
|
return hasCompiler;
|
|
62687
62766
|
};
|
|
62767
|
+
const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
|
|
62768
|
+
const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
|
|
62769
|
+
if (!importedFilePath) return null;
|
|
62770
|
+
return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList);
|
|
62771
|
+
};
|
|
62688
62772
|
const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
|
|
62689
62773
|
const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
|
|
62690
62774
|
if (assignedReactCompiler.initializer && !isStaticallyDisabledConfigExpression(assignedReactCompiler.initializer, analysis)) return true;
|
|
@@ -62705,30 +62789,62 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
|
|
|
62705
62789
|
const importBinding = getImportBinding(analysis.sourceFile, identifier.text);
|
|
62706
62790
|
if (importBinding) {
|
|
62707
62791
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
62708
|
-
|
|
62709
|
-
|
|
62710
|
-
|
|
62792
|
+
return Boolean(analyzeImportedConfig({
|
|
62793
|
+
analysis,
|
|
62794
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62795
|
+
exportName: importBinding.exportName,
|
|
62796
|
+
allowCompilerTransform
|
|
62797
|
+
}));
|
|
62711
62798
|
}
|
|
62712
62799
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, identifier.text);
|
|
62713
62800
|
return Boolean(topLevelBinding && analyzeConfigNode(topLevelBinding, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
|
|
62714
62801
|
};
|
|
62715
62802
|
const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransform) => {
|
|
62716
62803
|
const target = callExpression.expression;
|
|
62804
|
+
const callableRequiredModuleSpecifier = getRequireModuleSpecifier$1(target);
|
|
62805
|
+
if (callableRequiredModuleSpecifier !== null) {
|
|
62806
|
+
if (ts.isCallExpression(target) && ts.isIdentifier(target.expression) && (analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62807
|
+
if (allowCompilerTransform && isCompilerTransformModule(callableRequiredModuleSpecifier, "default")) return true;
|
|
62808
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62809
|
+
analysis,
|
|
62810
|
+
moduleSpecifier: callableRequiredModuleSpecifier,
|
|
62811
|
+
exportName: "default",
|
|
62812
|
+
allowCompilerTransform,
|
|
62813
|
+
argumentsList: callExpression.arguments
|
|
62814
|
+
});
|
|
62815
|
+
if (isLocalModuleSpecifier(callableRequiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62816
|
+
return null;
|
|
62817
|
+
}
|
|
62717
62818
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62718
62819
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
62719
62820
|
if (propertyName === null) return null;
|
|
62720
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
|
|
62821
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
62721
62822
|
if (requiredModuleSpecifier !== null) {
|
|
62722
|
-
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62723
|
-
if (
|
|
62724
|
-
const
|
|
62725
|
-
|
|
62823
|
+
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;
|
|
62824
|
+
if (allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, propertyName)) return true;
|
|
62825
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62826
|
+
analysis,
|
|
62827
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
62828
|
+
exportName: propertyName,
|
|
62829
|
+
allowCompilerTransform,
|
|
62830
|
+
argumentsList: callExpression.arguments
|
|
62831
|
+
});
|
|
62832
|
+
if (isLocalModuleSpecifier(requiredModuleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62833
|
+
return null;
|
|
62726
62834
|
}
|
|
62727
62835
|
if (!ts.isIdentifier(target.expression)) return null;
|
|
62728
|
-
const importBinding = getImportBinding(analysis.sourceFile, target.expression.text);
|
|
62729
|
-
if (importBinding?.isNamespace
|
|
62730
|
-
|
|
62731
|
-
|
|
62836
|
+
const importBinding = analysis.localBindings.has(target.expression.text) || getScopedConfigBinding(target.expression).wasFound ? null : getImportBinding(analysis.sourceFile, target.expression.text);
|
|
62837
|
+
if (importBinding?.isNamespace) {
|
|
62838
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, propertyName)) return true;
|
|
62839
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62840
|
+
analysis,
|
|
62841
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62842
|
+
exportName: propertyName,
|
|
62843
|
+
allowCompilerTransform,
|
|
62844
|
+
argumentsList: callExpression.arguments
|
|
62845
|
+
});
|
|
62846
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62847
|
+
return null;
|
|
62732
62848
|
}
|
|
62733
62849
|
const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
|
|
62734
62850
|
if (selectedProperty === null) return null;
|
|
@@ -62746,25 +62862,29 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62746
62862
|
const reactCompilerFlagState = excludedPropertyNames?.has("reactCompiler") ? null : getReactCompilerFlagState(node, analysis);
|
|
62747
62863
|
if (reactCompilerFlagState?.isEnabled) return true;
|
|
62748
62864
|
for (const [propertyIndex, property] of node.properties.entries()) if (ts.isPropertyAssignment(property)) {
|
|
62749
|
-
const propertyName = getStaticPropertyName$
|
|
62865
|
+
const propertyName = getStaticPropertyName$2(property.name);
|
|
62750
62866
|
if (propertyName && excludedPropertyNames?.has(propertyName)) continue;
|
|
62751
62867
|
if (propertyName === "reactCompiler") continue;
|
|
62752
|
-
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$
|
|
62868
|
+
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;
|
|
62753
62869
|
const propertyAllowsCompilerTransform = propertyName === "plugins" || propertyName === "presets";
|
|
62754
|
-
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)
|
|
62755
|
-
|
|
62756
|
-
|
|
62870
|
+
if (propertyName === "extends" && ts.isStringLiteralLike(property.initializer)) {
|
|
62871
|
+
if (analyzeImportedConfig({
|
|
62872
|
+
analysis,
|
|
62873
|
+
moduleSpecifier: property.initializer.text,
|
|
62874
|
+
exportName: "default",
|
|
62875
|
+
allowCompilerTransform: false
|
|
62876
|
+
})) return true;
|
|
62757
62877
|
}
|
|
62758
62878
|
if (analyzeConfigNode(property.initializer, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
62759
62879
|
} else if (ts.isShorthandPropertyAssignment(property)) {
|
|
62760
62880
|
if (excludedPropertyNames?.has(property.name.text)) continue;
|
|
62761
62881
|
if (property.name.text === "reactCompiler") continue;
|
|
62762
|
-
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$
|
|
62882
|
+
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;
|
|
62763
62883
|
const propertyAllowsCompilerTransform = property.name.text === "plugins" || property.name.text === "presets";
|
|
62764
62884
|
if (analyzeConfigNode(property.name, analysis, propertyAllowsCompilerTransform, propertyAllowsCompilerTransform)) return true;
|
|
62765
62885
|
} else if (ts.isSpreadAssignment(property)) {
|
|
62766
62886
|
if (reactCompilerFlagState && getReactCompilerFlagState(property.expression, analysis) !== null) continue;
|
|
62767
|
-
if (node.properties.slice(propertyIndex + 1).some((laterProperty) => (ts.isPropertyAssignment(laterProperty) || ts.isShorthandPropertyAssignment(laterProperty)) && (getStaticPropertyName$
|
|
62887
|
+
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;
|
|
62768
62888
|
if (analyzeConfigNode(property.expression, analysis, allowCompilerTransform, false, excludedPropertyNames)) return true;
|
|
62769
62889
|
}
|
|
62770
62890
|
return false;
|
|
@@ -62777,23 +62897,36 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62777
62897
|
});
|
|
62778
62898
|
}
|
|
62779
62899
|
if (ts.isCallExpression(node)) {
|
|
62900
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
62901
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
62780
62902
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
62781
62903
|
if (callTargetResult !== null) return callTargetResult;
|
|
62782
|
-
const directModuleSpecifier = getRequireModuleSpecifier(node);
|
|
62904
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
62783
62905
|
const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
|
|
62784
62906
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
62785
62907
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
62786
62908
|
if (allowCompilerTransform && isCompilerTransformModule(directModuleSpecifier, "default")) return true;
|
|
62787
|
-
if (
|
|
62788
|
-
|
|
62789
|
-
|
|
62790
|
-
|
|
62909
|
+
if (analyzeImportedConfig({
|
|
62910
|
+
analysis,
|
|
62911
|
+
moduleSpecifier: directModuleSpecifier,
|
|
62912
|
+
exportName: "default",
|
|
62913
|
+
allowCompilerTransform
|
|
62914
|
+
})) return true;
|
|
62791
62915
|
}
|
|
62792
62916
|
if (ts.isIdentifier(node.expression)) {
|
|
62793
|
-
|
|
62794
|
-
|
|
62795
|
-
|
|
62796
|
-
|
|
62917
|
+
if (!analysis.localBindings.has(node.expression.text) && !getScopedConfigBinding(node.expression).wasFound) {
|
|
62918
|
+
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62919
|
+
if (importBinding) {
|
|
62920
|
+
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, importBinding.exportName)) return true;
|
|
62921
|
+
const hasCompilerTransform = analyzeImportedConfig({
|
|
62922
|
+
analysis,
|
|
62923
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62924
|
+
exportName: importBinding.exportName,
|
|
62925
|
+
allowCompilerTransform,
|
|
62926
|
+
argumentsList: node.arguments
|
|
62927
|
+
});
|
|
62928
|
+
if (isLocalModuleSpecifier(importBinding.moduleSpecifier) || hasCompilerTransform !== null) return Boolean(hasCompilerTransform);
|
|
62929
|
+
}
|
|
62797
62930
|
}
|
|
62798
62931
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, node.expression.text);
|
|
62799
62932
|
if (topLevelBinding && ts.isFunctionLike(topLevelBinding) && analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, node.arguments)) return true;
|
|
@@ -62801,27 +62934,31 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62801
62934
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
|
|
62802
62935
|
}
|
|
62803
62936
|
if (ts.isPropertyAccessExpression(node)) {
|
|
62804
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
|
|
62937
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
62805
62938
|
if (requiredModuleSpecifier) {
|
|
62806
|
-
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62807
|
-
if (
|
|
62808
|
-
|
|
62809
|
-
|
|
62810
|
-
|
|
62939
|
+
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;
|
|
62940
|
+
if (analyzeImportedConfig({
|
|
62941
|
+
analysis,
|
|
62942
|
+
moduleSpecifier: requiredModuleSpecifier,
|
|
62943
|
+
exportName: node.name.text,
|
|
62944
|
+
allowCompilerTransform
|
|
62945
|
+
})) return true;
|
|
62811
62946
|
return allowCompilerTransform && isCompilerTransformModule(requiredModuleSpecifier, node.name.text);
|
|
62812
62947
|
}
|
|
62813
62948
|
if (ts.isIdentifier(node.expression)) {
|
|
62814
|
-
if (analysis.localBindings.has(node.expression.text)) {
|
|
62815
|
-
const
|
|
62816
|
-
return Boolean(
|
|
62949
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
62950
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
62951
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
62817
62952
|
}
|
|
62818
62953
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62819
62954
|
if (importBinding?.isNamespace) {
|
|
62820
62955
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.name.text)) return true;
|
|
62821
|
-
if (
|
|
62822
|
-
|
|
62823
|
-
|
|
62824
|
-
|
|
62956
|
+
if (analyzeImportedConfig({
|
|
62957
|
+
analysis,
|
|
62958
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62959
|
+
exportName: node.name.text,
|
|
62960
|
+
allowCompilerTransform
|
|
62961
|
+
})) return true;
|
|
62825
62962
|
return false;
|
|
62826
62963
|
}
|
|
62827
62964
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
@@ -62832,13 +62969,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62832
62969
|
}
|
|
62833
62970
|
if (ts.isElementAccessExpression(node) && node.argumentExpression && ts.isStringLiteralLike(node.argumentExpression)) {
|
|
62834
62971
|
if (ts.isIdentifier(node.expression)) {
|
|
62972
|
+
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
62973
|
+
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
62974
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
62975
|
+
}
|
|
62835
62976
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
62836
62977
|
if (importBinding?.isNamespace) {
|
|
62837
62978
|
if (allowCompilerTransform && isCompilerTransformModule(importBinding.moduleSpecifier, node.argumentExpression.text)) return true;
|
|
62838
|
-
|
|
62839
|
-
|
|
62840
|
-
|
|
62841
|
-
|
|
62979
|
+
return Boolean(analyzeImportedConfig({
|
|
62980
|
+
analysis,
|
|
62981
|
+
moduleSpecifier: importBinding.moduleSpecifier,
|
|
62982
|
+
exportName: node.argumentExpression.text,
|
|
62983
|
+
allowCompilerTransform
|
|
62984
|
+
}));
|
|
62842
62985
|
}
|
|
62843
62986
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
62844
62987
|
if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
@@ -62876,14 +63019,19 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62876
63019
|
};
|
|
62877
63020
|
const hasCompilerInConfigFile = (filePath) => analyzeConfigModuleExport(filePath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
62878
63021
|
const hasCompilerInConfigFiles = (directory, filenames) => filenames.some((filename) => hasCompilerInConfigFile(Path.join(directory, filename)));
|
|
62879
|
-
const hasCompilerInPackageJsonConfig = (
|
|
62880
|
-
|
|
63022
|
+
const hasCompilerInPackageJsonConfig = (directory, packageJson) => {
|
|
63023
|
+
if (!isPlainObject(packageJson.babel)) return false;
|
|
63024
|
+
const packageJsonPath = Path.join(directory, "package.json");
|
|
63025
|
+
return analyzeConfigSourceFileExport(ts.parseJsonText(packageJsonPath, JSON.stringify(packageJson.babel)), packageJsonPath, "default", false, 0, /* @__PURE__ */ new Set());
|
|
63026
|
+
};
|
|
63027
|
+
const hasCompilerConfiguration = (directory, packageJson) => hasCompilerInPackageJsonConfig(directory, packageJson) || hasCompilerInConfigFiles(directory, REACT_COMPILER_CONFIG_FILENAMES);
|
|
62881
63028
|
const hasCompilerConfigurationInAncestors = (directory) => {
|
|
62882
63029
|
if (isProjectBoundary(directory)) return false;
|
|
62883
63030
|
let ancestorDirectory = Path.dirname(directory);
|
|
62884
63031
|
while (ancestorDirectory !== Path.dirname(ancestorDirectory)) {
|
|
62885
63032
|
const ancestorPackagePath = Path.join(ancestorDirectory, "package.json");
|
|
62886
|
-
|
|
63033
|
+
const ancestorPackageJson = isFile(ancestorPackagePath) ? readPackageJson(ancestorPackagePath) : {};
|
|
63034
|
+
if (hasCompilerInPackageJsonConfig(ancestorDirectory, ancestorPackageJson) || hasCompilerInConfigFiles(ancestorDirectory, BABEL_CONFIG_FILENAMES)) return true;
|
|
62887
63035
|
if (isProjectBoundary(ancestorDirectory)) return false;
|
|
62888
63036
|
ancestorDirectory = Path.dirname(ancestorDirectory);
|
|
62889
63037
|
}
|
|
@@ -66138,7 +66286,7 @@ const warn = (message) => {
|
|
|
66138
66286
|
runSync(warn$1(message));
|
|
66139
66287
|
};
|
|
66140
66288
|
const CONFIG_BASENAME = "doctor.config";
|
|
66141
|
-
const CONFIG_EXTENSIONS = [
|
|
66289
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
66142
66290
|
"ts",
|
|
66143
66291
|
"mts",
|
|
66144
66292
|
"cts",
|
|
@@ -66242,7 +66390,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
66242
66390
|
};
|
|
66243
66391
|
const loadConfigFromDirectory = async (directory) => {
|
|
66244
66392
|
let sawBrokenConfigFile = false;
|
|
66245
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
66393
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
66246
66394
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
66247
66395
|
if (!isFile(filePath)) continue;
|
|
66248
66396
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -66977,6 +67125,316 @@ const buildReactNativeDiagnostic = (input) => ({
|
|
|
66977
67125
|
column: input.column ?? 0,
|
|
66978
67126
|
category: input.category ?? "Correctness"
|
|
66979
67127
|
});
|
|
67128
|
+
const ANDROID_APP_BUILD_FILE_NAMES = ["build.gradle", "build.gradle.kts"];
|
|
67129
|
+
const BUILD_TYPES_BLOCK_PATTERN = /\bbuildTypes\s*\{/g;
|
|
67130
|
+
const RELEASE_STRING_MARKER = "__RD_RELEASE__";
|
|
67131
|
+
const RELEASE_BLOCK_PATTERNS = [/\brelease\s*\{/g, /\b(?:getByName|named)\s*\(\s*(?:["']release["']|__RD_RELEASE__)\s*\)\s*\{/g];
|
|
67132
|
+
const MINIFY_ASSIGNMENT_PATTERN = /\b(?:isMinifyEnabled|minifyEnabled)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67133
|
+
const SHRINK_RESOURCES_ASSIGNMENT_PATTERN = /\b(?:isShrinkResources|shrinkResources)\b\s*(?:\(\s*|=\s*|\s+)([^;}\r\n]+)/g;
|
|
67134
|
+
const stripGradleComments = (contents) => {
|
|
67135
|
+
let result = "";
|
|
67136
|
+
let index = 0;
|
|
67137
|
+
let quote = null;
|
|
67138
|
+
while (index < contents.length) {
|
|
67139
|
+
const character = contents[index];
|
|
67140
|
+
const nextCharacter = contents[index + 1];
|
|
67141
|
+
if (quote !== null) {
|
|
67142
|
+
result += character;
|
|
67143
|
+
if (character === "\\") {
|
|
67144
|
+
result += nextCharacter ?? "";
|
|
67145
|
+
index += 2;
|
|
67146
|
+
continue;
|
|
67147
|
+
}
|
|
67148
|
+
if (character === quote) quote = null;
|
|
67149
|
+
index += 1;
|
|
67150
|
+
continue;
|
|
67151
|
+
}
|
|
67152
|
+
if (character === "\"" || character === "'") {
|
|
67153
|
+
quote = character;
|
|
67154
|
+
result += character;
|
|
67155
|
+
index += 1;
|
|
67156
|
+
continue;
|
|
67157
|
+
}
|
|
67158
|
+
if (character === "/" && nextCharacter === "/") {
|
|
67159
|
+
while (index < contents.length && contents[index] !== "\n") {
|
|
67160
|
+
result += " ";
|
|
67161
|
+
index += 1;
|
|
67162
|
+
}
|
|
67163
|
+
continue;
|
|
67164
|
+
}
|
|
67165
|
+
if (character === "/" && nextCharacter === "*") {
|
|
67166
|
+
result += " ";
|
|
67167
|
+
index += 2;
|
|
67168
|
+
while (index < contents.length && !(contents[index] === "*" && contents[index + 1] === "/")) {
|
|
67169
|
+
result += contents[index] === "\n" ? "\n" : " ";
|
|
67170
|
+
index += 1;
|
|
67171
|
+
}
|
|
67172
|
+
if (index < contents.length) {
|
|
67173
|
+
result += " ";
|
|
67174
|
+
index += 2;
|
|
67175
|
+
}
|
|
67176
|
+
continue;
|
|
67177
|
+
}
|
|
67178
|
+
result += character;
|
|
67179
|
+
index += 1;
|
|
67180
|
+
}
|
|
67181
|
+
return result;
|
|
67182
|
+
};
|
|
67183
|
+
const maskGradleStrings = (contents) => {
|
|
67184
|
+
let result = "";
|
|
67185
|
+
let index = 0;
|
|
67186
|
+
let quote = null;
|
|
67187
|
+
while (index < contents.length) {
|
|
67188
|
+
const character = contents[index];
|
|
67189
|
+
if (quote === null) {
|
|
67190
|
+
if (character === "\"" || character === "'") {
|
|
67191
|
+
quote = character;
|
|
67192
|
+
result += " ";
|
|
67193
|
+
} else result += character;
|
|
67194
|
+
index += 1;
|
|
67195
|
+
continue;
|
|
67196
|
+
}
|
|
67197
|
+
if (character === "\\") {
|
|
67198
|
+
result += " ";
|
|
67199
|
+
index += 2;
|
|
67200
|
+
continue;
|
|
67201
|
+
}
|
|
67202
|
+
if (character === quote) quote = null;
|
|
67203
|
+
result += character === "\n" ? "\n" : " ";
|
|
67204
|
+
index += 1;
|
|
67205
|
+
}
|
|
67206
|
+
return result;
|
|
67207
|
+
};
|
|
67208
|
+
const findBlockContents = (contents, pattern) => {
|
|
67209
|
+
const blocks = [];
|
|
67210
|
+
pattern.lastIndex = 0;
|
|
67211
|
+
let match = pattern.exec(contents);
|
|
67212
|
+
while (match !== null) {
|
|
67213
|
+
const openingBraceIndex = pattern.lastIndex - 1;
|
|
67214
|
+
let depth = 1;
|
|
67215
|
+
let index = openingBraceIndex + 1;
|
|
67216
|
+
let quote = null;
|
|
67217
|
+
while (index < contents.length && depth > 0) {
|
|
67218
|
+
const character = contents[index];
|
|
67219
|
+
if (quote !== null) {
|
|
67220
|
+
if (character === "\\") {
|
|
67221
|
+
index += 2;
|
|
67222
|
+
continue;
|
|
67223
|
+
}
|
|
67224
|
+
if (character === quote) quote = null;
|
|
67225
|
+
} else if (character === "\"" || character === "'") quote = character;
|
|
67226
|
+
else if (character === "{") depth += 1;
|
|
67227
|
+
else if (character === "}") depth -= 1;
|
|
67228
|
+
index += 1;
|
|
67229
|
+
}
|
|
67230
|
+
if (depth === 0) blocks.push(contents.slice(openingBraceIndex + 1, index - 1));
|
|
67231
|
+
match = pattern.exec(contents);
|
|
67232
|
+
}
|
|
67233
|
+
return blocks;
|
|
67234
|
+
};
|
|
67235
|
+
const getFinalStaticBoolean = (contents, pattern) => {
|
|
67236
|
+
pattern.lastIndex = 0;
|
|
67237
|
+
let finalValue = null;
|
|
67238
|
+
let match = pattern.exec(contents);
|
|
67239
|
+
while (match !== null) {
|
|
67240
|
+
const staticValue = match[1]?.trim().replace(/\)$/, "").trim();
|
|
67241
|
+
if (staticValue === "true") finalValue = true;
|
|
67242
|
+
else if (staticValue === "false") finalValue = false;
|
|
67243
|
+
else finalValue = null;
|
|
67244
|
+
match = pattern.exec(contents);
|
|
67245
|
+
}
|
|
67246
|
+
return finalValue;
|
|
67247
|
+
};
|
|
67248
|
+
const getReleaseBlocks = (contents) => findBlockContents(contents, BUILD_TYPES_BLOCK_PATTERN).flatMap((buildTypesBlock) => RELEASE_BLOCK_PATTERNS.flatMap((pattern) => findBlockContents(buildTypesBlock, pattern)));
|
|
67249
|
+
const readAndroidReleaseShrinking = (rootDirectory) => {
|
|
67250
|
+
for (const buildFileName of ANDROID_APP_BUILD_FILE_NAMES) {
|
|
67251
|
+
const filePath = Path.posix.join("android", "app", buildFileName);
|
|
67252
|
+
const absoluteFilePath = Path.join(rootDirectory, filePath);
|
|
67253
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67254
|
+
let contents;
|
|
67255
|
+
try {
|
|
67256
|
+
contents = stripGradleComments(NFS.readFileSync(absoluteFilePath, "utf-8"));
|
|
67257
|
+
} catch {
|
|
67258
|
+
return null;
|
|
67259
|
+
}
|
|
67260
|
+
const releaseBlocks = getReleaseBlocks(maskGradleStrings(contents.replace(/(["'])release\1/g, RELEASE_STRING_MARKER)));
|
|
67261
|
+
const [releaseBlock] = releaseBlocks;
|
|
67262
|
+
if (releaseBlock === void 0 || releaseBlocks.length !== 1) return null;
|
|
67263
|
+
const hasDisabledMinification = getFinalStaticBoolean(releaseBlock, MINIFY_ASSIGNMENT_PATTERN) === false;
|
|
67264
|
+
const hasDisabledResourceShrinking = getFinalStaticBoolean(releaseBlock, SHRINK_RESOURCES_ASSIGNMENT_PATTERN) === false;
|
|
67265
|
+
if (!hasDisabledMinification && !hasDisabledResourceShrinking) return null;
|
|
67266
|
+
return {
|
|
67267
|
+
filePath,
|
|
67268
|
+
hasDisabledMinification,
|
|
67269
|
+
hasDisabledResourceShrinking
|
|
67270
|
+
};
|
|
67271
|
+
}
|
|
67272
|
+
return null;
|
|
67273
|
+
};
|
|
67274
|
+
const checkReactNativeAndroidReleaseShrinking = (rootDirectory) => {
|
|
67275
|
+
const releaseShrinking = readAndroidReleaseShrinking(rootDirectory);
|
|
67276
|
+
if (releaseShrinking === null) return [];
|
|
67277
|
+
const disabledFeatures = [releaseShrinking.hasDisabledMinification ? "code minification" : null, releaseShrinking.hasDisabledResourceShrinking ? "resource shrinking" : null].filter((feature) => feature !== null);
|
|
67278
|
+
return [buildReactNativeDiagnostic({
|
|
67279
|
+
filePath: releaseShrinking.filePath,
|
|
67280
|
+
rule: "rn-android-release-shrinking-disabled",
|
|
67281
|
+
category: "Performance",
|
|
67282
|
+
message: `The Android release build explicitly disables ${disabledFeatures.join(" and ")}, leaving unreachable code or resources in the shipped app.`,
|
|
67283
|
+
help: "Enable release code minification and resource shrinking, then test the optimized build and add keep rules for libraries that require them."
|
|
67284
|
+
})];
|
|
67285
|
+
};
|
|
67286
|
+
const getTypescriptScriptKind = (fileName) => {
|
|
67287
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
67288
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
67289
|
+
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67290
|
+
return ts.ScriptKind.JS;
|
|
67291
|
+
};
|
|
67292
|
+
const BABEL_CONFIG_FILE_NAMES$1 = [
|
|
67293
|
+
"babel.config.js",
|
|
67294
|
+
"babel.config.cjs",
|
|
67295
|
+
"babel.config.mjs",
|
|
67296
|
+
"babel.config.ts",
|
|
67297
|
+
"babel.config.cts",
|
|
67298
|
+
"babel.config.json",
|
|
67299
|
+
".babelrc",
|
|
67300
|
+
".babelrc.js",
|
|
67301
|
+
".babelrc.cjs",
|
|
67302
|
+
".babelrc.mjs",
|
|
67303
|
+
".babelrc.cts",
|
|
67304
|
+
".babelrc.json"
|
|
67305
|
+
];
|
|
67306
|
+
const readUnknownPluginNames = (value) => {
|
|
67307
|
+
if (!Array.isArray(value)) return null;
|
|
67308
|
+
const pluginNames = [];
|
|
67309
|
+
for (const entry of value) {
|
|
67310
|
+
if (typeof entry === "string") {
|
|
67311
|
+
pluginNames.push(entry);
|
|
67312
|
+
continue;
|
|
67313
|
+
}
|
|
67314
|
+
if (Array.isArray(entry) && typeof entry[0] === "string") {
|
|
67315
|
+
pluginNames.push(entry[0]);
|
|
67316
|
+
continue;
|
|
67317
|
+
}
|
|
67318
|
+
return null;
|
|
67319
|
+
}
|
|
67320
|
+
return pluginNames;
|
|
67321
|
+
};
|
|
67322
|
+
const getStaticPropertyName$1 = (propertyName) => {
|
|
67323
|
+
if (ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName)) return propertyName.text;
|
|
67324
|
+
return null;
|
|
67325
|
+
};
|
|
67326
|
+
const getStaticPluginName = (expression) => {
|
|
67327
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
67328
|
+
if (ts.isStringLiteralLike(unwrappedExpression)) return unwrappedExpression.text;
|
|
67329
|
+
if (!ts.isArrayLiteralExpression(unwrappedExpression)) return null;
|
|
67330
|
+
const pluginExpression = unwrappedExpression.elements[0];
|
|
67331
|
+
return pluginExpression && ts.isStringLiteralLike(pluginExpression) ? pluginExpression.text : null;
|
|
67332
|
+
};
|
|
67333
|
+
const getPluginNamesFromObject = (objectExpression) => {
|
|
67334
|
+
if (objectExpression.properties.some((property) => ts.isSpreadAssignment(property))) return null;
|
|
67335
|
+
const pluginProperties = objectExpression.properties.filter((property) => ts.isPropertyAssignment(property) && getStaticPropertyName$1(property.name) === "plugins");
|
|
67336
|
+
if (pluginProperties.length !== 1) return pluginProperties.length === 0 ? [] : null;
|
|
67337
|
+
const pluginListExpression = unwrapTypescriptExpression(pluginProperties[0].initializer);
|
|
67338
|
+
if (!ts.isArrayLiteralExpression(pluginListExpression)) return null;
|
|
67339
|
+
const pluginNames = [];
|
|
67340
|
+
for (const element of pluginListExpression.elements) {
|
|
67341
|
+
if (ts.isSpreadElement(element)) return null;
|
|
67342
|
+
const pluginName = getStaticPluginName(element);
|
|
67343
|
+
if (pluginName === null) return null;
|
|
67344
|
+
pluginNames.push(pluginName);
|
|
67345
|
+
}
|
|
67346
|
+
return pluginNames;
|
|
67347
|
+
};
|
|
67348
|
+
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";
|
|
67349
|
+
const getDirectExportedObject = (sourceFile) => {
|
|
67350
|
+
const exportedExpressions = [];
|
|
67351
|
+
for (const statement of sourceFile.statements) {
|
|
67352
|
+
if (ts.isExportAssignment(statement)) {
|
|
67353
|
+
exportedExpressions.push(statement.expression);
|
|
67354
|
+
continue;
|
|
67355
|
+
}
|
|
67356
|
+
if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && isModuleExports(statement.expression.left)) exportedExpressions.push(statement.expression.right);
|
|
67357
|
+
}
|
|
67358
|
+
if (exportedExpressions.length !== 1) return null;
|
|
67359
|
+
const exportedExpression = unwrapTypescriptExpression(exportedExpressions[0]);
|
|
67360
|
+
return ts.isObjectLiteralExpression(exportedExpression) ? exportedExpression : null;
|
|
67361
|
+
};
|
|
67362
|
+
const parseConfigPluginNames = (filePath, contents) => {
|
|
67363
|
+
try {
|
|
67364
|
+
const parsedJson = JSON.parse(contents);
|
|
67365
|
+
return isPlainObject(parsedJson) ? readUnknownPluginNames(parsedJson.plugins) : null;
|
|
67366
|
+
} catch {
|
|
67367
|
+
if (ts.transpileModule(contents, {
|
|
67368
|
+
fileName: filePath,
|
|
67369
|
+
reportDiagnostics: true,
|
|
67370
|
+
compilerOptions: { allowJs: true }
|
|
67371
|
+
}).diagnostics?.some((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error)) return null;
|
|
67372
|
+
const exportedObject = getDirectExportedObject(ts.createSourceFile(filePath, contents, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filePath)));
|
|
67373
|
+
return exportedObject === null ? null : getPluginNamesFromObject(exportedObject);
|
|
67374
|
+
}
|
|
67375
|
+
};
|
|
67376
|
+
const readStaticBabelPluginNames = (rootDirectory) => {
|
|
67377
|
+
for (const fileName of BABEL_CONFIG_FILE_NAMES$1) {
|
|
67378
|
+
const absoluteFilePath = Path.join(rootDirectory, fileName);
|
|
67379
|
+
if (!isFile(absoluteFilePath)) continue;
|
|
67380
|
+
try {
|
|
67381
|
+
return {
|
|
67382
|
+
filePath: fileName,
|
|
67383
|
+
pluginNames: parseConfigPluginNames(fileName, NFS.readFileSync(absoluteFilePath, "utf-8"))
|
|
67384
|
+
};
|
|
67385
|
+
} catch {
|
|
67386
|
+
return {
|
|
67387
|
+
filePath: fileName,
|
|
67388
|
+
pluginNames: null
|
|
67389
|
+
};
|
|
67390
|
+
}
|
|
67391
|
+
}
|
|
67392
|
+
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
67393
|
+
if (!isPlainObject(packageJson.babel)) return null;
|
|
67394
|
+
return {
|
|
67395
|
+
filePath: "package.json",
|
|
67396
|
+
pluginNames: readUnknownPluginNames(packageJson.babel.plugins)
|
|
67397
|
+
};
|
|
67398
|
+
};
|
|
67399
|
+
const REACT_COMPILER_PLUGIN_NAMES = new Set(["babel-plugin-react-compiler", "react-compiler"]);
|
|
67400
|
+
const REANIMATED_PLUGIN_NAME = "react-native-reanimated/plugin";
|
|
67401
|
+
const WORKLETS_PLUGIN_NAME = "react-native-worklets/plugin";
|
|
67402
|
+
const checkReactCompilerPluginOrder = (filePath, pluginNames) => {
|
|
67403
|
+
if (pluginNames.findIndex((pluginName) => REACT_COMPILER_PLUGIN_NAMES.has(pluginName)) <= 0) return [];
|
|
67404
|
+
return [buildReactNativeDiagnostic({
|
|
67405
|
+
filePath,
|
|
67406
|
+
rule: "rn-react-compiler-plugin-first",
|
|
67407
|
+
category: "Performance",
|
|
67408
|
+
message: "The React Compiler Babel plugin is not first, so an earlier transform can change component or hook code before the compiler analyzes it.",
|
|
67409
|
+
help: "Move `babel-plugin-react-compiler` to the first entry in the Babel `plugins` array."
|
|
67410
|
+
})];
|
|
67411
|
+
};
|
|
67412
|
+
const checkReanimatedPluginOrder = (project, filePath, pluginNames) => {
|
|
67413
|
+
const reanimatedMajorVersion = project.reanimatedVersion === null || project.reanimatedVersion === void 0 ? null : getLowestDependencyMajor(project.reanimatedVersion);
|
|
67414
|
+
if (reanimatedMajorVersion === null || reanimatedMajorVersion < 4) return [];
|
|
67415
|
+
const diagnostics = [];
|
|
67416
|
+
if (pluginNames.includes(REANIMATED_PLUGIN_NAME)) diagnostics.push(buildReactNativeDiagnostic({
|
|
67417
|
+
filePath,
|
|
67418
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67419
|
+
category: "Performance",
|
|
67420
|
+
message: "This Reanimated 4 project still uses `react-native-reanimated/plugin`, which was renamed to the Worklets Babel plugin.",
|
|
67421
|
+
help: "Replace it with `react-native-worklets/plugin` and keep that plugin last in the Babel `plugins` array."
|
|
67422
|
+
}));
|
|
67423
|
+
const workletsPluginIndex = pluginNames.lastIndexOf(WORKLETS_PLUGIN_NAME);
|
|
67424
|
+
if (workletsPluginIndex !== -1 && workletsPluginIndex !== pluginNames.length - 1) diagnostics.push(buildReactNativeDiagnostic({
|
|
67425
|
+
filePath,
|
|
67426
|
+
rule: "rn-reanimated-worklets-plugin-last",
|
|
67427
|
+
category: "Performance",
|
|
67428
|
+
message: "`react-native-worklets/plugin` is not last in the Babel `plugins` array, so later transforms can prevent worklets from being compiled correctly.",
|
|
67429
|
+
help: "Move `react-native-worklets/plugin` to the final entry in the Babel `plugins` array."
|
|
67430
|
+
}));
|
|
67431
|
+
return diagnostics;
|
|
67432
|
+
};
|
|
67433
|
+
const checkReactNativeBabelPluginOrder = (rootDirectory, project) => {
|
|
67434
|
+
const babelPlugins = readStaticBabelPluginNames(rootDirectory);
|
|
67435
|
+
if (babelPlugins === null || babelPlugins.pluginNames === null) return [];
|
|
67436
|
+
return [...checkReactCompilerPluginOrder(babelPlugins.filePath, babelPlugins.pluginNames), ...checkReanimatedPluginOrder(project, babelPlugins.filePath, babelPlugins.pluginNames)];
|
|
67437
|
+
};
|
|
66980
67438
|
const BUILDER_BOB_PACKAGE = "react-native-builder-bob";
|
|
66981
67439
|
const isBuilderBobLibrary = (packageJson) => {
|
|
66982
67440
|
const bobConfig = packageJson[BUILDER_BOB_PACKAGE];
|
|
@@ -67053,7 +67511,12 @@ const checkReactNativeMetroBabelPreset = (rootDirectory) => {
|
|
|
67053
67511
|
const isReactNativeProject = (project) => project.framework === "react-native" || project.framework === "expo" || project.hasReactNativeWorkspace || project.expoVersion !== null;
|
|
67054
67512
|
const checkReactNativeProject = (rootDirectory, project) => {
|
|
67055
67513
|
if (!isReactNativeProject(project)) return [];
|
|
67056
|
-
return [
|
|
67514
|
+
return [
|
|
67515
|
+
...checkReactNativeMetroBabelPreset(rootDirectory),
|
|
67516
|
+
...checkReactNativeBabelPluginOrder(rootDirectory, project),
|
|
67517
|
+
...checkReactNativeAndroidReleaseShrinking(rootDirectory),
|
|
67518
|
+
...checkReactNativeLibraryDependencies(rootDirectory)
|
|
67519
|
+
];
|
|
67057
67520
|
};
|
|
67058
67521
|
const RULE_KEY = "no-vulnerable-react-server-components";
|
|
67059
67522
|
const REACT_RSC_ADVISORIES_BY_MINOR = {
|
|
@@ -67204,17 +67667,6 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
|
|
|
67204
67667
|
}
|
|
67205
67668
|
return diagnostics;
|
|
67206
67669
|
};
|
|
67207
|
-
const getTypescriptScriptKind = (fileName) => {
|
|
67208
|
-
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
67209
|
-
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
67210
|
-
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
67211
|
-
return ts.ScriptKind.JS;
|
|
67212
|
-
};
|
|
67213
|
-
const unwrapTypescriptExpression = (expression) => {
|
|
67214
|
-
let currentExpression = expression;
|
|
67215
|
-
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
67216
|
-
return currentExpression;
|
|
67217
|
-
};
|
|
67218
67670
|
const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
|
|
67219
67671
|
isAnimationFunction: false,
|
|
67220
67672
|
isMotionComponent: false,
|
|
@@ -67770,7 +68222,11 @@ const buildCapabilities = (project) => {
|
|
|
67770
68222
|
capabilities.add(project.framework);
|
|
67771
68223
|
if (project.reactVersion !== null || project.preactVersion !== null) capabilities.add("react");
|
|
67772
68224
|
if (project.framework === "expo" || project.framework === "react-native" || project.hasReactNativeWorkspace) capabilities.add("react-native");
|
|
67773
|
-
if (project.expoVersion !== null)
|
|
68225
|
+
if (project.expoVersion !== null) {
|
|
68226
|
+
capabilities.add("expo");
|
|
68227
|
+
const expoSdkMajorVersion = getLowestDependencyMajor(project.expoVersion);
|
|
68228
|
+
if (expoSdkMajorVersion !== null && expoSdkMajorVersion >= 54) capabilities.add("expo:54");
|
|
68229
|
+
}
|
|
67774
68230
|
if ((project.framework === "nextjs" || project.framework === "tanstack-start" || project.framework === "remix") && !project.isStaticExport) capabilities.add("server-actions");
|
|
67775
68231
|
if (SSR_FRAMEWORKS.has(project.framework) || project.hasSsrDependency) capabilities.add("ssr");
|
|
67776
68232
|
if (CLIENT_ONLY_FRAMEWORKS.has(project.framework)) capabilities.add("client-only");
|
|
@@ -67834,6 +68290,11 @@ const buildCapabilities = (project) => {
|
|
|
67834
68290
|
if (project.zustandMajorVersion !== void 0 && project.zustandMajorVersion !== null && project.zustandMajorVersion >= 1 && project.zustandMajorVersion <= 5) addVersionCapabilityLadder(capabilities, "zustand", project.zustandMajorVersion, 1, 5);
|
|
67835
68291
|
if (project.isPreES2023Target) capabilities.add("pre-es2023");
|
|
67836
68292
|
if (project.hasReactCompiler) capabilities.add("react-compiler");
|
|
68293
|
+
if (project.reanimatedVersion !== void 0 && project.reanimatedVersion !== null) {
|
|
68294
|
+
capabilities.add("reanimated");
|
|
68295
|
+
const reanimatedMajorVersion = getLowestDependencyMajor(project.reanimatedVersion);
|
|
68296
|
+
if (reanimatedMajorVersion !== null && reanimatedMajorVersion >= 4) capabilities.add("reanimated:4");
|
|
68297
|
+
}
|
|
67837
68298
|
if (Boolean(project.hasTanStackQuery) || Boolean(project.tanstackQueryVersion)) capabilities.add("tanstack-query");
|
|
67838
68299
|
if (project.styledComponentsVersion) {
|
|
67839
68300
|
capabilities.add("styled-components");
|
|
@@ -69731,7 +70192,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
69731
70192
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
69732
70193
|
const normalizeConfigForHash = (config) => {
|
|
69733
70194
|
const clone = JSON.parse(JSON.stringify(config));
|
|
69734
|
-
if (clone?.settings?.["react-doctor"])
|
|
70195
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
70196
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
70197
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
70198
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
70199
|
+
}
|
|
69735
70200
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
69736
70201
|
return clone;
|
|
69737
70202
|
};
|
|
@@ -69890,13 +70355,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
69890
70355
|
}
|
|
69891
70356
|
return enabled;
|
|
69892
70357
|
};
|
|
69893
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
70358
|
+
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 }) => {
|
|
69894
70359
|
const hasIncludedTags = includedTags.size > 0;
|
|
69895
70360
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
69896
70361
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
69897
70362
|
const jsPlugins = [];
|
|
69898
70363
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
69899
70364
|
const capabilities = getCapabilities(project);
|
|
70365
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
69900
70366
|
const enabledReactDoctorRules = {};
|
|
69901
70367
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
69902
70368
|
const rule = reactDoctorPlugin.rules[registryEntry.id];
|
|
@@ -69942,8 +70408,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69942
70408
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
69943
70409
|
settings: { "react-doctor": {
|
|
69944
70410
|
framework: project.framework,
|
|
69945
|
-
rootDirectory:
|
|
70411
|
+
rootDirectory: settingsRootDirectory,
|
|
69946
70412
|
capabilities: [...capabilities].sort(),
|
|
70413
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
70414
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
70415
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
70416
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
70417
|
+
directory: scope.directory,
|
|
70418
|
+
names: [...scope.names]
|
|
70419
|
+
}))
|
|
70420
|
+
} : {},
|
|
69947
70421
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
69948
70422
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
69949
70423
|
} },
|
|
@@ -69954,6 +70428,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
69954
70428
|
}
|
|
69955
70429
|
};
|
|
69956
70430
|
};
|
|
70431
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
70432
|
+
const CONFIG_BASENAMES = [
|
|
70433
|
+
"astro.config",
|
|
70434
|
+
"esbuild.config",
|
|
70435
|
+
"rollup.config",
|
|
70436
|
+
"rolldown.config",
|
|
70437
|
+
"rspack.config",
|
|
70438
|
+
"vite.config",
|
|
70439
|
+
"webpack.config"
|
|
70440
|
+
];
|
|
70441
|
+
const CONFIG_EXTENSIONS = [
|
|
70442
|
+
".cjs",
|
|
70443
|
+
".cts",
|
|
70444
|
+
".js",
|
|
70445
|
+
".mjs",
|
|
70446
|
+
".mts",
|
|
70447
|
+
".ts"
|
|
70448
|
+
];
|
|
70449
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
70450
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
70451
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
70452
|
+
true,
|
|
70453
|
+
false,
|
|
70454
|
+
"readable",
|
|
70455
|
+
"readonly",
|
|
70456
|
+
"writable",
|
|
70457
|
+
"writeable"
|
|
70458
|
+
]);
|
|
70459
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
70460
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
70461
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
70462
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
70463
|
+
}) ?? null;
|
|
70464
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
70465
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
70466
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
70467
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
70468
|
+
};
|
|
70469
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
70470
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70471
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
70472
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
70473
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
70474
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
70475
|
+
};
|
|
70476
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
70477
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70478
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
70479
|
+
};
|
|
70480
|
+
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");
|
|
70481
|
+
const isTopLevelExpression = (node) => {
|
|
70482
|
+
let ancestor = node.parent;
|
|
70483
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70484
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
70485
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
70486
|
+
ancestor = ancestor.parent;
|
|
70487
|
+
}
|
|
70488
|
+
return false;
|
|
70489
|
+
};
|
|
70490
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
70491
|
+
let ancestor = node.parent;
|
|
70492
|
+
let didFindConfigProperty = false;
|
|
70493
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70494
|
+
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;
|
|
70495
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
70496
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
70497
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
70498
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
70499
|
+
didFindConfigProperty = true;
|
|
70500
|
+
ancestor = ancestor.parent;
|
|
70501
|
+
continue;
|
|
70502
|
+
}
|
|
70503
|
+
if (didFindConfigProperty) {
|
|
70504
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
70505
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
70506
|
+
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);
|
|
70507
|
+
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;
|
|
70508
|
+
}
|
|
70509
|
+
ancestor = ancestor.parent;
|
|
70510
|
+
}
|
|
70511
|
+
return false;
|
|
70512
|
+
};
|
|
70513
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
70514
|
+
const optionsExpression = callExpression.arguments[0];
|
|
70515
|
+
if (!optionsExpression) return null;
|
|
70516
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
70517
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
70518
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
70519
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
70520
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
70521
|
+
if (!eslintrcProperty) return null;
|
|
70522
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
70523
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
70524
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
70525
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
70526
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
70527
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
70528
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
70529
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
70530
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
70531
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
70532
|
+
};
|
|
70533
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
70534
|
+
let sourceText;
|
|
70535
|
+
try {
|
|
70536
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
70537
|
+
} catch {
|
|
70538
|
+
return {
|
|
70539
|
+
didFindActiveAutoImport: false,
|
|
70540
|
+
globalsPaths: []
|
|
70541
|
+
};
|
|
70542
|
+
}
|
|
70543
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
70544
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
70545
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
70546
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
70547
|
+
for (const statement of sourceFile.statements) {
|
|
70548
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
70549
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
70550
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70551
|
+
const defaultBinding = statement.importClause?.name;
|
|
70552
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
70553
|
+
}
|
|
70554
|
+
if (moduleSpecifier === "esbuild") {
|
|
70555
|
+
const defaultBinding = statement.importClause?.name;
|
|
70556
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
70557
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
70558
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
70559
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
70560
|
+
}
|
|
70561
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
70562
|
+
}
|
|
70563
|
+
}
|
|
70564
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
70565
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
70566
|
+
if (!declaration.initializer) continue;
|
|
70567
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
70568
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
70569
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
70570
|
+
if (moduleSpecifier === "esbuild") {
|
|
70571
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
70572
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
70573
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
70574
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
70575
|
+
}
|
|
70576
|
+
}
|
|
70577
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
70578
|
+
}
|
|
70579
|
+
}
|
|
70580
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
70581
|
+
let didFindActiveAutoImport = false;
|
|
70582
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
70583
|
+
const visit = (node) => {
|
|
70584
|
+
if (ts.isCallExpression(node)) {
|
|
70585
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
70586
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70587
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
70588
|
+
didFindActiveAutoImport = true;
|
|
70589
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
70590
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
70591
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
70592
|
+
}
|
|
70593
|
+
}
|
|
70594
|
+
}
|
|
70595
|
+
ts.forEachChild(node, visit);
|
|
70596
|
+
};
|
|
70597
|
+
visit(sourceFile);
|
|
70598
|
+
return {
|
|
70599
|
+
didFindActiveAutoImport,
|
|
70600
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
70601
|
+
};
|
|
70602
|
+
};
|
|
70603
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
70604
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
70605
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
70606
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
70607
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
70608
|
+
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();
|
|
70609
|
+
};
|
|
70610
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
70611
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
70612
|
+
const visitedDirectories = [];
|
|
70613
|
+
while (true) {
|
|
70614
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
70615
|
+
if (cachedDirectory !== void 0) {
|
|
70616
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
70617
|
+
return cachedDirectory;
|
|
70618
|
+
}
|
|
70619
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
70620
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
70621
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70622
|
+
return null;
|
|
70623
|
+
}
|
|
70624
|
+
visitedDirectories.push(currentDirectory);
|
|
70625
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
70626
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
70627
|
+
return currentDirectory;
|
|
70628
|
+
}
|
|
70629
|
+
if (currentDirectory === rootDirectory) {
|
|
70630
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70631
|
+
return null;
|
|
70632
|
+
}
|
|
70633
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
70634
|
+
}
|
|
70635
|
+
};
|
|
70636
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
70637
|
+
let directoryEntries;
|
|
70638
|
+
try {
|
|
70639
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
70640
|
+
} catch {
|
|
70641
|
+
return [];
|
|
70642
|
+
}
|
|
70643
|
+
const configuredGlobalsPaths = [];
|
|
70644
|
+
for (const entry of directoryEntries) {
|
|
70645
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
70646
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
70647
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
70648
|
+
}
|
|
70649
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
70650
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
70651
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
70652
|
+
const names = /* @__PURE__ */ new Set();
|
|
70653
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
70654
|
+
return [...names].sort();
|
|
70655
|
+
};
|
|
70656
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
70657
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
70658
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
70659
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
70660
|
+
for (const candidateFile of candidateFiles) {
|
|
70661
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
70662
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
70663
|
+
}
|
|
70664
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
70665
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
70666
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
70667
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
70668
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
70669
|
+
};
|
|
69957
70670
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
69958
70671
|
const decodeFileDiagnostics = (raw) => {
|
|
69959
70672
|
if (!Array.isArray(raw)) return null;
|
|
@@ -70276,6 +70989,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
70276
70989
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
70277
70990
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
70278
70991
|
};
|
|
70992
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
70993
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
70994
|
+
let lineStartOffset = boundedOffset;
|
|
70995
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
70996
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
70997
|
+
};
|
|
70279
70998
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
70280
70999
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
70281
71000
|
const KNOWN_SECRET_RULES = [
|
|
@@ -70991,7 +71710,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
70991
71710
|
* with empty text still carry a useful jump target, so they're kept
|
|
70992
71711
|
* with a neutral message.
|
|
70993
71712
|
*/
|
|
70994
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
71713
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
70995
71714
|
if (labels.length <= 1) return [];
|
|
70996
71715
|
const related = [];
|
|
70997
71716
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -70999,8 +71718,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
70999
71718
|
if (!label?.span) continue;
|
|
71000
71719
|
related.push({
|
|
71001
71720
|
filePath,
|
|
71002
|
-
line: label.span.line ?? 0,
|
|
71003
|
-
column: label.span.column ?? 0,
|
|
71721
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
71722
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
71004
71723
|
offset: label.span.offset,
|
|
71005
71724
|
length: label.span.length,
|
|
71006
71725
|
message: label.label ?? ""
|
|
@@ -71020,7 +71739,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
|
|
|
71020
71739
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
71021
71740
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
71022
71741
|
*/
|
|
71023
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
71742
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
|
|
71024
71743
|
if (!stdout) return [];
|
|
71025
71744
|
const jsonStart = stdout.indexOf("{");
|
|
71026
71745
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -71037,8 +71756,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71037
71756
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
71038
71757
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
71039
71758
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
71759
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
71760
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
71040
71761
|
const readSourceBuffer = (filename) => {
|
|
71041
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71762
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71042
71763
|
const cached = sourceBufferCache.get(absolutePath);
|
|
71043
71764
|
if (cached !== void 0) return cached;
|
|
71044
71765
|
let sourceBuffer;
|
|
@@ -71051,7 +71772,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71051
71772
|
return sourceBuffer;
|
|
71052
71773
|
};
|
|
71053
71774
|
const readSourceLines = (filename) => {
|
|
71054
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71775
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71055
71776
|
const cached = sourceLinesCache.get(absolutePath);
|
|
71056
71777
|
if (cached !== void 0) return cached;
|
|
71057
71778
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -71060,27 +71781,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71060
71781
|
return sourceLines;
|
|
71061
71782
|
};
|
|
71062
71783
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
71063
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71784
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71064
71785
|
const cached = minifiedFileCache.get(absolutePath);
|
|
71065
71786
|
if (cached !== void 0) return cached;
|
|
71066
71787
|
const minified = isMinifiedSource(absolutePath);
|
|
71067
71788
|
minifiedFileCache.set(absolutePath, minified);
|
|
71068
71789
|
return minified;
|
|
71069
71790
|
};
|
|
71070
|
-
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) => {
|
|
71791
|
+
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) => {
|
|
71071
71792
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71072
71793
|
const primaryLabel = diagnostic.labels[0];
|
|
71073
71794
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
71074
|
-
const
|
|
71795
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
71796
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
71075
71797
|
const primarySpan = primaryLabel?.span;
|
|
71076
71798
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
71077
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
71799
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
71078
71800
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
71079
71801
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
71080
71802
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
71081
|
-
const
|
|
71803
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
71804
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
71805
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
71082
71806
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
71083
|
-
const primaryColumnIndex = primarySpan ?
|
|
71807
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
71084
71808
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
71085
71809
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
71086
71810
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -71093,8 +71817,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71093
71817
|
message: cleaned.message,
|
|
71094
71818
|
help: cleaned.help,
|
|
71095
71819
|
url: diagnostic.url,
|
|
71096
|
-
line:
|
|
71097
|
-
column:
|
|
71820
|
+
line: primaryLineNumber,
|
|
71821
|
+
column: primaryColumnNumber,
|
|
71098
71822
|
...primarySpan ? {
|
|
71099
71823
|
offset: primarySpan.offset,
|
|
71100
71824
|
length: primarySpan.length,
|
|
@@ -71282,7 +72006,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
71282
72006
|
* loop with a slimmer config in that case.
|
|
71283
72007
|
*/
|
|
71284
72008
|
const spawnLintBatches = async (input) => {
|
|
71285
|
-
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
72009
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
72010
|
+
const resolveSourcePath = (filePath) => {
|
|
72011
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
72012
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
72013
|
+
};
|
|
71286
72014
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
71287
72015
|
let rescueDeadlineEpochMs;
|
|
71288
72016
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -71302,7 +72030,7 @@ const spawnLintBatches = async (input) => {
|
|
|
71302
72030
|
}
|
|
71303
72031
|
const batchArgs = [...baseArgs, ...batch];
|
|
71304
72032
|
try {
|
|
71305
|
-
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
|
|
72033
|
+
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
|
|
71306
72034
|
} catch (error) {
|
|
71307
72035
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
71308
72036
|
if (isPastDeadline()) {
|
|
@@ -71408,10 +72136,12 @@ const spawnLintBatches = async (input) => {
|
|
|
71408
72136
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
71409
72137
|
};
|
|
71410
72138
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
71411
|
-
|
|
71412
|
-
|
|
72139
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
72140
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
72141
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
72142
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
71413
72143
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
71414
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
72144
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
71415
72145
|
return dedupeDiagnostics(diagnostics);
|
|
71416
72146
|
};
|
|
71417
72147
|
let didValidate = false;
|
|
@@ -71510,6 +72240,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
71510
72240
|
}
|
|
71511
72241
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
71512
72242
|
};
|
|
72243
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
72244
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
72245
|
+
const COMMENT_OPEN = "<!--";
|
|
72246
|
+
const COMMENT_CLOSE = "-->";
|
|
72247
|
+
const FRONTMATTER_FENCE = "---";
|
|
72248
|
+
const SCRIPT_TAG_NAME = "script";
|
|
72249
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
72250
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
72251
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
72252
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
72253
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
72254
|
+
"application/ecmascript",
|
|
72255
|
+
"application/javascript",
|
|
72256
|
+
"application/x-ecmascript",
|
|
72257
|
+
"application/x-javascript",
|
|
72258
|
+
"text/ecmascript",
|
|
72259
|
+
"text/javascript",
|
|
72260
|
+
"text/javascript1.0",
|
|
72261
|
+
"text/javascript1.1",
|
|
72262
|
+
"text/javascript1.2",
|
|
72263
|
+
"text/javascript1.3",
|
|
72264
|
+
"text/javascript1.4",
|
|
72265
|
+
"text/javascript1.5",
|
|
72266
|
+
"text/jscript",
|
|
72267
|
+
"text/livescript",
|
|
72268
|
+
"text/x-ecmascript",
|
|
72269
|
+
"text/x-javascript"
|
|
72270
|
+
]);
|
|
72271
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
72272
|
+
"iframe",
|
|
72273
|
+
"noembed",
|
|
72274
|
+
"noframes",
|
|
72275
|
+
"noscript",
|
|
72276
|
+
"style",
|
|
72277
|
+
"textarea",
|
|
72278
|
+
"title",
|
|
72279
|
+
"xmp"
|
|
72280
|
+
]);
|
|
72281
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
72282
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
72283
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
72284
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
72285
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
72286
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
72287
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
72288
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
72289
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
72290
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
72291
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
72292
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
72293
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
72294
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
72295
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
72296
|
+
}
|
|
72297
|
+
return true;
|
|
72298
|
+
};
|
|
72299
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
72300
|
+
const isPotentialTagStart = (byte) => {
|
|
72301
|
+
if (byte === void 0) return false;
|
|
72302
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
72303
|
+
};
|
|
72304
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
72305
|
+
let byteIndex = lineStartByte;
|
|
72306
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
72307
|
+
return byteIndex;
|
|
72308
|
+
};
|
|
72309
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
72310
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72311
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
72312
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
72313
|
+
};
|
|
72314
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
72315
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
72316
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72317
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
72318
|
+
return true;
|
|
72319
|
+
};
|
|
72320
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
72321
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
72322
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
72323
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
72324
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
72325
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
72326
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
72327
|
+
}
|
|
72328
|
+
return openingFenceEndByte;
|
|
72329
|
+
};
|
|
72330
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
72331
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
72332
|
+
const byte = maskedBuffer[byteIndex];
|
|
72333
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
72334
|
+
}
|
|
72335
|
+
};
|
|
72336
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
72337
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
72338
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
72339
|
+
let nameEndByte = tagStartByte + 2;
|
|
72340
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
72341
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
72342
|
+
};
|
|
72343
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
72344
|
+
let quoteByte = null;
|
|
72345
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
72346
|
+
const byte = sourceBuffer[byteIndex];
|
|
72347
|
+
if (quoteByte !== null) {
|
|
72348
|
+
if (byte === quoteByte) quoteByte = null;
|
|
72349
|
+
continue;
|
|
72350
|
+
}
|
|
72351
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72352
|
+
quoteByte = byte;
|
|
72353
|
+
continue;
|
|
72354
|
+
}
|
|
72355
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
72356
|
+
}
|
|
72357
|
+
return sourceBuffer.length;
|
|
72358
|
+
};
|
|
72359
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
72360
|
+
let byteIndex = attributesStartByte;
|
|
72361
|
+
let hasSource = false;
|
|
72362
|
+
let language = null;
|
|
72363
|
+
let scriptType = null;
|
|
72364
|
+
while (byteIndex < tagEndByte) {
|
|
72365
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
72366
|
+
const attributeNameStartByte = byteIndex;
|
|
72367
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72368
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
72369
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72370
|
+
let attributeValue = "";
|
|
72371
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
72372
|
+
byteIndex++;
|
|
72373
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72374
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
72375
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72376
|
+
const valueStartByte = byteIndex + 1;
|
|
72377
|
+
byteIndex = valueStartByte;
|
|
72378
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
72379
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72380
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
72381
|
+
} else {
|
|
72382
|
+
const valueStartByte = byteIndex;
|
|
72383
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72384
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72385
|
+
}
|
|
72386
|
+
}
|
|
72387
|
+
if (attributeName === "src") hasSource = true;
|
|
72388
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
72389
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
72390
|
+
}
|
|
72391
|
+
return {
|
|
72392
|
+
hasSource,
|
|
72393
|
+
language,
|
|
72394
|
+
type: scriptType
|
|
72395
|
+
};
|
|
72396
|
+
};
|
|
72397
|
+
const isExecutableScript = (attributes) => {
|
|
72398
|
+
if (attributes.hasSource) return false;
|
|
72399
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
72400
|
+
if (type !== "") {
|
|
72401
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
72402
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
72403
|
+
}
|
|
72404
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
72405
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
72406
|
+
};
|
|
72407
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
72408
|
+
const closeTagStart = `</${tagName}`;
|
|
72409
|
+
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;
|
|
72410
|
+
return sourceBuffer.length;
|
|
72411
|
+
};
|
|
72412
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
72413
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
72414
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
72415
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
72416
|
+
const executableScriptBodies = [];
|
|
72417
|
+
let byteIndex = frontmatterEndByte;
|
|
72418
|
+
let templateDepth = 0;
|
|
72419
|
+
while (byteIndex < sourceBuffer.length) {
|
|
72420
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
72421
|
+
byteIndex++;
|
|
72422
|
+
continue;
|
|
72423
|
+
}
|
|
72424
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
72425
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
72426
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
72427
|
+
continue;
|
|
72428
|
+
}
|
|
72429
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
72430
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
72431
|
+
if (templateDepth > 0) templateDepth--;
|
|
72432
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72433
|
+
continue;
|
|
72434
|
+
}
|
|
72435
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
72436
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
72437
|
+
byteIndex++;
|
|
72438
|
+
continue;
|
|
72439
|
+
}
|
|
72440
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
72441
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
72442
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
72443
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
72444
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
72445
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
72446
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
72447
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
72448
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72449
|
+
continue;
|
|
72450
|
+
}
|
|
72451
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72452
|
+
continue;
|
|
72453
|
+
}
|
|
72454
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
72455
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
72456
|
+
const bodyStartByte = tagEndByte + 1;
|
|
72457
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
72458
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
72459
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
72460
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
72461
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
72462
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
72463
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
72464
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
72465
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72466
|
+
}
|
|
72467
|
+
return {
|
|
72468
|
+
executableScriptBodies,
|
|
72469
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
72470
|
+
};
|
|
72471
|
+
};
|
|
72472
|
+
const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
72473
|
+
const lintFiles = [];
|
|
72474
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
72475
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
72476
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
72477
|
+
let htmlFileIndex = 0;
|
|
72478
|
+
let hasThreeModuleImport = false;
|
|
72479
|
+
for (const candidateFile of candidateFiles) {
|
|
72480
|
+
if (!HTML_FILE_PATTERN.test(candidateFile)) {
|
|
72481
|
+
lintFiles.push(candidateFile);
|
|
72482
|
+
continue;
|
|
72483
|
+
}
|
|
72484
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
72485
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
72486
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
72487
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
72488
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
72489
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
72490
|
+
lintFiles.push(lintPath);
|
|
72491
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
72492
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
72493
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
72494
|
+
htmlFileIndex++;
|
|
72495
|
+
}
|
|
72496
|
+
return {
|
|
72497
|
+
lintFiles,
|
|
72498
|
+
sourcePathByLintPath,
|
|
72499
|
+
sizeByLintPath,
|
|
72500
|
+
hasThreeModuleImport
|
|
72501
|
+
};
|
|
72502
|
+
};
|
|
71513
72503
|
/**
|
|
71514
72504
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
71515
72505
|
* the runner: once for the primary scan, once for the
|
|
@@ -71670,6 +72660,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
71670
72660
|
const runOxlint = async (options) => {
|
|
71671
72661
|
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;
|
|
71672
72662
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72663
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72664
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
71673
72665
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
71674
72666
|
validateRuleRegistration();
|
|
71675
72667
|
resetManifestCaches();
|
|
@@ -71683,21 +72675,6 @@ const runOxlint = async (options) => {
|
|
|
71683
72675
|
const pluginPath = resolvePluginPath();
|
|
71684
72676
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
71685
72677
|
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
71686
|
-
const buildConfig = (overrides) => createOxlintConfig({
|
|
71687
|
-
pluginPath,
|
|
71688
|
-
project,
|
|
71689
|
-
customRulesOnly,
|
|
71690
|
-
extendsPaths: overrides.extendsPaths,
|
|
71691
|
-
ignoredTags,
|
|
71692
|
-
includedTags,
|
|
71693
|
-
includeTagDefaults,
|
|
71694
|
-
serverAuthFunctionNames,
|
|
71695
|
-
severityControls,
|
|
71696
|
-
userPlugins,
|
|
71697
|
-
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
71698
|
-
ruleSelection: overrides.ruleSelection,
|
|
71699
|
-
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
71700
|
-
});
|
|
71701
72678
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
71702
72679
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
71703
72680
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -71733,7 +72710,36 @@ const runOxlint = async (options) => {
|
|
|
71733
72710
|
await yieldToEventLoop();
|
|
71734
72711
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
71735
72712
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
72713
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
72714
|
+
rootDirectory,
|
|
72715
|
+
candidateFiles
|
|
72716
|
+
});
|
|
72717
|
+
const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
72718
|
+
const lintFiles = preparedHtmlSources.lintFiles;
|
|
72719
|
+
const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
|
|
72720
|
+
const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
|
|
72721
|
+
...project,
|
|
72722
|
+
hasThree: true
|
|
72723
|
+
} : project;
|
|
72724
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
72725
|
+
pluginPath,
|
|
72726
|
+
project: lintProject,
|
|
72727
|
+
customRulesOnly,
|
|
72728
|
+
extendsPaths: overrides.extendsPaths,
|
|
72729
|
+
ignoredTags,
|
|
72730
|
+
includedTags,
|
|
72731
|
+
includeTagDefaults,
|
|
72732
|
+
runtimeGlobals,
|
|
72733
|
+
unpluginAutoImportGlobalScopes,
|
|
72734
|
+
serverAuthFunctionNames,
|
|
72735
|
+
severityControls,
|
|
72736
|
+
userPlugins,
|
|
72737
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
72738
|
+
ruleSelection: overrides.ruleSelection,
|
|
72739
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
72740
|
+
});
|
|
71736
72741
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
72742
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
71737
72743
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
71738
72744
|
baseArgs: passBaseArgs,
|
|
71739
72745
|
files: passFiles,
|
|
@@ -71762,7 +72768,8 @@ const runOxlint = async (options) => {
|
|
|
71762
72768
|
fileBatches: passFileBatches,
|
|
71763
72769
|
rootDirectory,
|
|
71764
72770
|
nodeBinaryPath,
|
|
71765
|
-
project,
|
|
72771
|
+
project: lintProject,
|
|
72772
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
71766
72773
|
onPartialFailure: reportPartialFailure,
|
|
71767
72774
|
onAnalyzedFiles: (filePaths) => {
|
|
71768
72775
|
analyzedFiles = filePaths;
|
|
@@ -71797,7 +72804,7 @@ const runOxlint = async (options) => {
|
|
|
71797
72804
|
};
|
|
71798
72805
|
}
|
|
71799
72806
|
};
|
|
71800
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
72807
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
|
|
71801
72808
|
const rulesetHash = computeRulesetHash({
|
|
71802
72809
|
config: buildConfig({
|
|
71803
72810
|
extendsPaths: [],
|
|
@@ -71955,14 +72962,15 @@ const runOxlint = async (options) => {
|
|
|
71955
72962
|
]);
|
|
71956
72963
|
}
|
|
71957
72964
|
const baseArgs = makeBaseArgs(configPath);
|
|
71958
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
72965
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
71959
72966
|
let analyzedFiles = [];
|
|
71960
72967
|
const runBatches = () => spawnLintBatches({
|
|
71961
72968
|
baseArgs,
|
|
71962
72969
|
fileBatches,
|
|
71963
72970
|
rootDirectory,
|
|
71964
72971
|
nodeBinaryPath,
|
|
71965
|
-
project,
|
|
72972
|
+
project: lintProject,
|
|
72973
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
71966
72974
|
onPartialFailure,
|
|
71967
72975
|
onAnalyzedFiles: (filePaths) => {
|
|
71968
72976
|
analyzedFiles = filePaths;
|
|
@@ -73884,4 +74892,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
73884
74892
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
73885
74893
|
|
|
73886
74894
|
//# sourceMappingURL=index.js.map
|
|
73887
|
-
//# debugId=
|
|
74895
|
+
//# debugId=41e39010-e2d7-5e6b-9bba-626bf64affe5
|