react-doctor 0.9.1-dev.5d2f66d → 0.9.1-dev.7ee59d3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/cli.js +653 -60
- package/dist/index.d.ts +2 -2
- package/dist/index.js +647 -55
- package/dist/lsp.js +649 -56
- package/package.json +2 -2
package/dist/lsp.js
CHANGED
|
@@ -61478,7 +61478,8 @@ var AmbiguousProjectError = class extends Error {
|
|
|
61478
61478
|
}
|
|
61479
61479
|
};
|
|
61480
61480
|
const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
|
|
61481
|
-
const
|
|
61481
|
+
const HTML_FILE_PATTERN = /\.html$/i;
|
|
61482
|
+
const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
|
|
61482
61483
|
const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
|
|
61483
61484
|
const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
|
|
61484
61485
|
const MINIFIED_SNIFF_BYTES = 65536;
|
|
@@ -62341,7 +62342,7 @@ const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json")
|
|
|
62341
62342
|
const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
|
|
62342
62343
|
const isCommonJsConfigExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
|
|
62343
62344
|
const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
|
|
62344
|
-
const getRequireModuleSpecifier = (expression) => {
|
|
62345
|
+
const getRequireModuleSpecifier$1 = (expression) => {
|
|
62345
62346
|
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
|
|
62346
62347
|
const moduleSpecifier = expression.arguments[0];
|
|
62347
62348
|
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
@@ -62354,7 +62355,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
62354
62355
|
const namedBindings = importClause?.namedBindings;
|
|
62355
62356
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
62356
62357
|
}
|
|
62357
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
62358
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
62358
62359
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
62359
62360
|
});
|
|
62360
62361
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -62385,21 +62386,21 @@ const getImportBinding = (sourceFile, bindingName) => {
|
|
|
62385
62386
|
for (const declaration of statement.declarationList.declarations) {
|
|
62386
62387
|
if (!declaration.initializer) continue;
|
|
62387
62388
|
if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
|
|
62388
|
-
const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62389
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62389
62390
|
if (directModuleSpecifier) return {
|
|
62390
62391
|
moduleSpecifier: directModuleSpecifier,
|
|
62391
62392
|
exportName: "default",
|
|
62392
62393
|
isNamespace: true
|
|
62393
62394
|
};
|
|
62394
|
-
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
|
|
62395
|
-
moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
|
|
62395
|
+
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
|
|
62396
|
+
moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
|
|
62396
62397
|
exportName: declaration.initializer.name.text,
|
|
62397
62398
|
isNamespace: false
|
|
62398
62399
|
};
|
|
62399
62400
|
}
|
|
62400
62401
|
if (!ts.isObjectBindingPattern(declaration.name)) continue;
|
|
62401
62402
|
const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
|
|
62402
|
-
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
62403
|
+
const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
62403
62404
|
if (bindingElement && moduleSpecifier) return {
|
|
62404
62405
|
moduleSpecifier,
|
|
62405
62406
|
exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
|
|
@@ -62455,6 +62456,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
62455
62456
|
};
|
|
62456
62457
|
};
|
|
62457
62458
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
62459
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
62460
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
62461
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
62462
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
62463
|
+
if (!ts.isCallExpression(node)) return false;
|
|
62464
|
+
const target = node.expression;
|
|
62465
|
+
if (ts.isIdentifier(target)) {
|
|
62466
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
62467
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
62468
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
62469
|
+
}
|
|
62470
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
62471
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
62472
|
+
const createRequireReceiver = target.expression;
|
|
62473
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
62474
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
62475
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
62476
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
62477
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
62478
|
+
}
|
|
62479
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
62480
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
62481
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
62482
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
62483
|
+
};
|
|
62484
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
62485
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
62486
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
62487
|
+
const target = callExpression.expression;
|
|
62488
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62489
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
62490
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
62491
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
62492
|
+
const resolverIdentifier = target.expression;
|
|
62493
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
62494
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
62495
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
62496
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
62497
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
62498
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
62499
|
+
return moduleSpecifierNode.text;
|
|
62500
|
+
};
|
|
62458
62501
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
62459
62502
|
let bindingScope = null;
|
|
62460
62503
|
let currentNode = identifier;
|
|
@@ -62770,7 +62813,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
|
|
|
62770
62813
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
62771
62814
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
62772
62815
|
if (propertyName === null) return null;
|
|
62773
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
|
|
62816
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
62774
62817
|
if (requiredModuleSpecifier !== null) {
|
|
62775
62818
|
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62776
62819
|
if (!requiredModuleSpecifier.startsWith(".")) return null;
|
|
@@ -62830,9 +62873,11 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62830
62873
|
});
|
|
62831
62874
|
}
|
|
62832
62875
|
if (ts.isCallExpression(node)) {
|
|
62876
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
62877
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
62833
62878
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
62834
62879
|
if (callTargetResult !== null) return callTargetResult;
|
|
62835
|
-
const directModuleSpecifier = getRequireModuleSpecifier(node);
|
|
62880
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
62836
62881
|
const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
|
|
62837
62882
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
62838
62883
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
@@ -62854,7 +62899,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
62854
62899
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
|
|
62855
62900
|
}
|
|
62856
62901
|
if (ts.isPropertyAccessExpression(node)) {
|
|
62857
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
|
|
62902
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
62858
62903
|
if (requiredModuleSpecifier) {
|
|
62859
62904
|
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
62860
62905
|
if (requiredModuleSpecifier.startsWith(".")) {
|
|
@@ -66165,7 +66210,7 @@ const warn = (message) => {
|
|
|
66165
66210
|
runSync(warn$1(message));
|
|
66166
66211
|
};
|
|
66167
66212
|
const CONFIG_BASENAME = "doctor.config";
|
|
66168
|
-
const CONFIG_EXTENSIONS = [
|
|
66213
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
66169
66214
|
"ts",
|
|
66170
66215
|
"mts",
|
|
66171
66216
|
"cts",
|
|
@@ -66269,7 +66314,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
66269
66314
|
};
|
|
66270
66315
|
const loadConfigFromDirectory = async (directory) => {
|
|
66271
66316
|
let sawBrokenConfigFile = false;
|
|
66272
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
66317
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
66273
66318
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
66274
66319
|
if (!isFile(filePath)) continue;
|
|
66275
66320
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -70028,7 +70073,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
70028
70073
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
70029
70074
|
const normalizeConfigForHash = (config) => {
|
|
70030
70075
|
const clone = JSON.parse(JSON.stringify(config));
|
|
70031
|
-
if (clone?.settings?.["react-doctor"])
|
|
70076
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
70077
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
70078
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
70079
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
70080
|
+
}
|
|
70032
70081
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
70033
70082
|
return clone;
|
|
70034
70083
|
};
|
|
@@ -70187,13 +70236,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
70187
70236
|
}
|
|
70188
70237
|
return enabled;
|
|
70189
70238
|
};
|
|
70190
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
70239
|
+
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, runtimeGlobals, unpluginAutoImportGlobalScopes, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
70191
70240
|
const hasIncludedTags = includedTags.size > 0;
|
|
70192
70241
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
70193
70242
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
70194
70243
|
const jsPlugins = [];
|
|
70195
70244
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
70196
70245
|
const capabilities = getCapabilities(project);
|
|
70246
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
70197
70247
|
const enabledReactDoctorRules = {};
|
|
70198
70248
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
70199
70249
|
const rule = reactDoctorPlugin.rules[registryEntry.id];
|
|
@@ -70239,8 +70289,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
70239
70289
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
70240
70290
|
settings: { "react-doctor": {
|
|
70241
70291
|
framework: project.framework,
|
|
70242
|
-
rootDirectory:
|
|
70292
|
+
rootDirectory: settingsRootDirectory,
|
|
70243
70293
|
capabilities: [...capabilities].sort(),
|
|
70294
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
70295
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
70296
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
70297
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
70298
|
+
directory: scope.directory,
|
|
70299
|
+
names: [...scope.names]
|
|
70300
|
+
}))
|
|
70301
|
+
} : {},
|
|
70244
70302
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
70245
70303
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
70246
70304
|
} },
|
|
@@ -70251,6 +70309,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
70251
70309
|
}
|
|
70252
70310
|
};
|
|
70253
70311
|
};
|
|
70312
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
70313
|
+
const CONFIG_BASENAMES = [
|
|
70314
|
+
"astro.config",
|
|
70315
|
+
"esbuild.config",
|
|
70316
|
+
"rollup.config",
|
|
70317
|
+
"rolldown.config",
|
|
70318
|
+
"rspack.config",
|
|
70319
|
+
"vite.config",
|
|
70320
|
+
"webpack.config"
|
|
70321
|
+
];
|
|
70322
|
+
const CONFIG_EXTENSIONS = [
|
|
70323
|
+
".cjs",
|
|
70324
|
+
".cts",
|
|
70325
|
+
".js",
|
|
70326
|
+
".mjs",
|
|
70327
|
+
".mts",
|
|
70328
|
+
".ts"
|
|
70329
|
+
];
|
|
70330
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
70331
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
70332
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
70333
|
+
true,
|
|
70334
|
+
false,
|
|
70335
|
+
"readable",
|
|
70336
|
+
"readonly",
|
|
70337
|
+
"writable",
|
|
70338
|
+
"writeable"
|
|
70339
|
+
]);
|
|
70340
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
70341
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
70342
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
70343
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
70344
|
+
}) ?? null;
|
|
70345
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
70346
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
70347
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
70348
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
70349
|
+
};
|
|
70350
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
70351
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70352
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
70353
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
70354
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
70355
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
70356
|
+
};
|
|
70357
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
70358
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
70359
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
70360
|
+
};
|
|
70361
|
+
const isCommonJsExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
|
|
70362
|
+
const isTopLevelExpression = (node) => {
|
|
70363
|
+
let ancestor = node.parent;
|
|
70364
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70365
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
70366
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
70367
|
+
ancestor = ancestor.parent;
|
|
70368
|
+
}
|
|
70369
|
+
return false;
|
|
70370
|
+
};
|
|
70371
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
70372
|
+
let ancestor = node.parent;
|
|
70373
|
+
let didFindConfigProperty = false;
|
|
70374
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
70375
|
+
if (!didFindConfigProperty && !ts.isArrayLiteralExpression(ancestor) && !ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isPropertyAssignment(ancestor)) return false;
|
|
70376
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
70377
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
70378
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
70379
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
70380
|
+
didFindConfigProperty = true;
|
|
70381
|
+
ancestor = ancestor.parent;
|
|
70382
|
+
continue;
|
|
70383
|
+
}
|
|
70384
|
+
if (didFindConfigProperty) {
|
|
70385
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
70386
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
70387
|
+
if (propertyName === "plugins" && ts.isCallExpression(ancestor) && (ts.isIdentifier(ancestor.expression) ? esbuildBindings.has(ancestor.expression.text) : ts.isPropertyAccessExpression(ancestor.expression) && ancestor.expression.name.text === "build" && (ts.isIdentifier(ancestor.expression.expression) && esbuildNamespaceBindings.has(ancestor.expression.expression.text) || getRequireModuleSpecifier(ancestor.expression.expression) === "esbuild"))) return isTopLevelExpression(ancestor);
|
|
70388
|
+
if (!(ts.isObjectLiteralExpression(ancestor) || ts.isParenthesizedExpression(ancestor) || ts.isAsExpression(ancestor) || ts.isSatisfiesExpression(ancestor) || ts.isNonNullExpression(ancestor) || ts.isTypeAssertionExpression(ancestor) || ts.isCallExpression(ancestor) && ts.isIdentifier(ancestor.expression) && ancestor.expression.text === "defineConfig")) return false;
|
|
70389
|
+
}
|
|
70390
|
+
ancestor = ancestor.parent;
|
|
70391
|
+
}
|
|
70392
|
+
return false;
|
|
70393
|
+
};
|
|
70394
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
70395
|
+
const optionsExpression = callExpression.arguments[0];
|
|
70396
|
+
if (!optionsExpression) return null;
|
|
70397
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
70398
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
70399
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
70400
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
70401
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
70402
|
+
if (!eslintrcProperty) return null;
|
|
70403
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
70404
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
70405
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
70406
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
70407
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
70408
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
70409
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
70410
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
70411
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
70412
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
70413
|
+
};
|
|
70414
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
70415
|
+
let sourceText;
|
|
70416
|
+
try {
|
|
70417
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
70418
|
+
} catch {
|
|
70419
|
+
return {
|
|
70420
|
+
didFindActiveAutoImport: false,
|
|
70421
|
+
globalsPaths: []
|
|
70422
|
+
};
|
|
70423
|
+
}
|
|
70424
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
70425
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
70426
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
70427
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
70428
|
+
for (const statement of sourceFile.statements) {
|
|
70429
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
70430
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
70431
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70432
|
+
const defaultBinding = statement.importClause?.name;
|
|
70433
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
70434
|
+
}
|
|
70435
|
+
if (moduleSpecifier === "esbuild") {
|
|
70436
|
+
const defaultBinding = statement.importClause?.name;
|
|
70437
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
70438
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
70439
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
70440
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
70441
|
+
}
|
|
70442
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
70443
|
+
}
|
|
70444
|
+
}
|
|
70445
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
70446
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
70447
|
+
if (!declaration.initializer) continue;
|
|
70448
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
70449
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
70450
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
70451
|
+
if (moduleSpecifier === "esbuild") {
|
|
70452
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
70453
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
70454
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
70455
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
70456
|
+
}
|
|
70457
|
+
}
|
|
70458
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
70459
|
+
}
|
|
70460
|
+
}
|
|
70461
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
70462
|
+
let didFindActiveAutoImport = false;
|
|
70463
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
70464
|
+
const visit = (node) => {
|
|
70465
|
+
if (ts.isCallExpression(node)) {
|
|
70466
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
70467
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
70468
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
70469
|
+
didFindActiveAutoImport = true;
|
|
70470
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
70471
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
70472
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
70473
|
+
}
|
|
70474
|
+
}
|
|
70475
|
+
}
|
|
70476
|
+
ts.forEachChild(node, visit);
|
|
70477
|
+
};
|
|
70478
|
+
visit(sourceFile);
|
|
70479
|
+
return {
|
|
70480
|
+
didFindActiveAutoImport,
|
|
70481
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
70482
|
+
};
|
|
70483
|
+
};
|
|
70484
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
70485
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
70486
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
70487
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
70488
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
70489
|
+
return Object.entries(parsed.globals).filter((entry) => entry[0].length > 0 && (typeof entry[1] === "boolean" || typeof entry[1] === "string") && SUPPORTED_GLOBAL_VALUES.has(entry[1])).map(([name]) => name).sort();
|
|
70490
|
+
};
|
|
70491
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
70492
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
70493
|
+
const visitedDirectories = [];
|
|
70494
|
+
while (true) {
|
|
70495
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
70496
|
+
if (cachedDirectory !== void 0) {
|
|
70497
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
70498
|
+
return cachedDirectory;
|
|
70499
|
+
}
|
|
70500
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
70501
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
70502
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70503
|
+
return null;
|
|
70504
|
+
}
|
|
70505
|
+
visitedDirectories.push(currentDirectory);
|
|
70506
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
70507
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
70508
|
+
return currentDirectory;
|
|
70509
|
+
}
|
|
70510
|
+
if (currentDirectory === rootDirectory) {
|
|
70511
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
70512
|
+
return null;
|
|
70513
|
+
}
|
|
70514
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
70515
|
+
}
|
|
70516
|
+
};
|
|
70517
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
70518
|
+
let directoryEntries;
|
|
70519
|
+
try {
|
|
70520
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
70521
|
+
} catch {
|
|
70522
|
+
return [];
|
|
70523
|
+
}
|
|
70524
|
+
const configuredGlobalsPaths = [];
|
|
70525
|
+
for (const entry of directoryEntries) {
|
|
70526
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
70527
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
70528
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
70529
|
+
}
|
|
70530
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
70531
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
70532
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
70533
|
+
const names = /* @__PURE__ */ new Set();
|
|
70534
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
70535
|
+
return [...names].sort();
|
|
70536
|
+
};
|
|
70537
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
70538
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
70539
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
70540
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
70541
|
+
for (const candidateFile of candidateFiles) {
|
|
70542
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
70543
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
70544
|
+
}
|
|
70545
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
70546
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
70547
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
70548
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
70549
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
70550
|
+
};
|
|
70254
70551
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
70255
70552
|
const decodeFileDiagnostics = (raw) => {
|
|
70256
70553
|
if (!Array.isArray(raw)) return null;
|
|
@@ -70573,6 +70870,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
70573
70870
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
70574
70871
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
70575
70872
|
};
|
|
70873
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
70874
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
70875
|
+
let lineStartOffset = boundedOffset;
|
|
70876
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
70877
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
70878
|
+
};
|
|
70576
70879
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
70577
70880
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
70578
70881
|
const KNOWN_SECRET_RULES = [
|
|
@@ -71288,7 +71591,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
71288
71591
|
* with empty text still carry a useful jump target, so they're kept
|
|
71289
71592
|
* with a neutral message.
|
|
71290
71593
|
*/
|
|
71291
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
71594
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
71292
71595
|
if (labels.length <= 1) return [];
|
|
71293
71596
|
const related = [];
|
|
71294
71597
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -71296,8 +71599,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
71296
71599
|
if (!label?.span) continue;
|
|
71297
71600
|
related.push({
|
|
71298
71601
|
filePath,
|
|
71299
|
-
line: label.span.line ?? 0,
|
|
71300
|
-
column: label.span.column ?? 0,
|
|
71602
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
71603
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
71301
71604
|
offset: label.span.offset,
|
|
71302
71605
|
length: label.span.length,
|
|
71303
71606
|
message: label.label ?? ""
|
|
@@ -71317,7 +71620,7 @@ const isOxlintOutput = (value) => isRecord(value) && Array.isArray(value.diagnos
|
|
|
71317
71620
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
71318
71621
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
71319
71622
|
*/
|
|
71320
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
71623
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
|
|
71321
71624
|
if (!stdout) return [];
|
|
71322
71625
|
const jsonStart = stdout.indexOf("{");
|
|
71323
71626
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -71334,8 +71637,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71334
71637
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
71335
71638
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
71336
71639
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
71640
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
71641
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
71337
71642
|
const readSourceBuffer = (filename) => {
|
|
71338
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71643
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71339
71644
|
const cached = sourceBufferCache.get(absolutePath);
|
|
71340
71645
|
if (cached !== void 0) return cached;
|
|
71341
71646
|
let sourceBuffer;
|
|
@@ -71348,7 +71653,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71348
71653
|
return sourceBuffer;
|
|
71349
71654
|
};
|
|
71350
71655
|
const readSourceLines = (filename) => {
|
|
71351
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71656
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71352
71657
|
const cached = sourceLinesCache.get(absolutePath);
|
|
71353
71658
|
if (cached !== void 0) return cached;
|
|
71354
71659
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -71357,27 +71662,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71357
71662
|
return sourceLines;
|
|
71358
71663
|
};
|
|
71359
71664
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
71360
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
71665
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
71361
71666
|
const cached = minifiedFileCache.get(absolutePath);
|
|
71362
71667
|
if (cached !== void 0) return cached;
|
|
71363
71668
|
const minified = isMinifiedSource(absolutePath);
|
|
71364
71669
|
minifiedFileCache.set(absolutePath, minified);
|
|
71365
71670
|
return minified;
|
|
71366
71671
|
};
|
|
71367
|
-
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71672
|
+
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(resolveSourceFilename(diagnostic.filename)) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71368
71673
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71369
71674
|
const primaryLabel = diagnostic.labels[0];
|
|
71370
71675
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
71371
|
-
const
|
|
71676
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
71677
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
71372
71678
|
const primarySpan = primaryLabel?.span;
|
|
71373
71679
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
71374
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
71680
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
71375
71681
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
71376
71682
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
71377
71683
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
71378
|
-
const
|
|
71684
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
71685
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
71686
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
71379
71687
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
71380
|
-
const primaryColumnIndex = primarySpan ?
|
|
71688
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
71381
71689
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
71382
71690
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
71383
71691
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -71390,8 +71698,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71390
71698
|
message: cleaned.message,
|
|
71391
71699
|
help: cleaned.help,
|
|
71392
71700
|
url: diagnostic.url,
|
|
71393
|
-
line:
|
|
71394
|
-
column:
|
|
71701
|
+
line: primaryLineNumber,
|
|
71702
|
+
column: primaryColumnNumber,
|
|
71395
71703
|
...primarySpan ? {
|
|
71396
71704
|
offset: primarySpan.offset,
|
|
71397
71705
|
length: primarySpan.length,
|
|
@@ -71579,7 +71887,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
71579
71887
|
* loop with a slimmer config in that case.
|
|
71580
71888
|
*/
|
|
71581
71889
|
const spawnLintBatches = async (input) => {
|
|
71582
|
-
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
71890
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
71891
|
+
const resolveSourcePath = (filePath) => {
|
|
71892
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
71893
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
71894
|
+
};
|
|
71583
71895
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
71584
71896
|
let rescueDeadlineEpochMs;
|
|
71585
71897
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -71599,7 +71911,7 @@ const spawnLintBatches = async (input) => {
|
|
|
71599
71911
|
}
|
|
71600
71912
|
const batchArgs = [...baseArgs, ...batch];
|
|
71601
71913
|
try {
|
|
71602
|
-
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
|
|
71914
|
+
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
|
|
71603
71915
|
} catch (error) {
|
|
71604
71916
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
71605
71917
|
if (isPastDeadline()) {
|
|
@@ -71705,10 +72017,12 @@ const spawnLintBatches = async (input) => {
|
|
|
71705
72017
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
71706
72018
|
};
|
|
71707
72019
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
71708
|
-
|
|
71709
|
-
|
|
72020
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
72021
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
72022
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
72023
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
71710
72024
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
71711
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
72025
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
71712
72026
|
return dedupeDiagnostics(diagnostics);
|
|
71713
72027
|
};
|
|
71714
72028
|
let didValidate = false;
|
|
@@ -71807,6 +72121,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
71807
72121
|
}
|
|
71808
72122
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
71809
72123
|
};
|
|
72124
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
72125
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
72126
|
+
const COMMENT_OPEN = "<!--";
|
|
72127
|
+
const COMMENT_CLOSE = "-->";
|
|
72128
|
+
const FRONTMATTER_FENCE = "---";
|
|
72129
|
+
const SCRIPT_TAG_NAME = "script";
|
|
72130
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
72131
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
72132
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
72133
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
72134
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
72135
|
+
"application/ecmascript",
|
|
72136
|
+
"application/javascript",
|
|
72137
|
+
"application/x-ecmascript",
|
|
72138
|
+
"application/x-javascript",
|
|
72139
|
+
"text/ecmascript",
|
|
72140
|
+
"text/javascript",
|
|
72141
|
+
"text/javascript1.0",
|
|
72142
|
+
"text/javascript1.1",
|
|
72143
|
+
"text/javascript1.2",
|
|
72144
|
+
"text/javascript1.3",
|
|
72145
|
+
"text/javascript1.4",
|
|
72146
|
+
"text/javascript1.5",
|
|
72147
|
+
"text/jscript",
|
|
72148
|
+
"text/livescript",
|
|
72149
|
+
"text/x-ecmascript",
|
|
72150
|
+
"text/x-javascript"
|
|
72151
|
+
]);
|
|
72152
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
72153
|
+
"iframe",
|
|
72154
|
+
"noembed",
|
|
72155
|
+
"noframes",
|
|
72156
|
+
"noscript",
|
|
72157
|
+
"style",
|
|
72158
|
+
"textarea",
|
|
72159
|
+
"title",
|
|
72160
|
+
"xmp"
|
|
72161
|
+
]);
|
|
72162
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
72163
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
72164
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
72165
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
72166
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
72167
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
72168
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
72169
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
72170
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
72171
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
72172
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
72173
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
72174
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
72175
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
72176
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
72177
|
+
}
|
|
72178
|
+
return true;
|
|
72179
|
+
};
|
|
72180
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
72181
|
+
const isPotentialTagStart = (byte) => {
|
|
72182
|
+
if (byte === void 0) return false;
|
|
72183
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
72184
|
+
};
|
|
72185
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
72186
|
+
let byteIndex = lineStartByte;
|
|
72187
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
72188
|
+
return byteIndex;
|
|
72189
|
+
};
|
|
72190
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
72191
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72192
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
72193
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
72194
|
+
};
|
|
72195
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
72196
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
72197
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
72198
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
72199
|
+
return true;
|
|
72200
|
+
};
|
|
72201
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
72202
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
72203
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
72204
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
72205
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
72206
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
72207
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
72208
|
+
}
|
|
72209
|
+
return openingFenceEndByte;
|
|
72210
|
+
};
|
|
72211
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
72212
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
72213
|
+
const byte = maskedBuffer[byteIndex];
|
|
72214
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
72215
|
+
}
|
|
72216
|
+
};
|
|
72217
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
72218
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
72219
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
72220
|
+
let nameEndByte = tagStartByte + 2;
|
|
72221
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
72222
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
72223
|
+
};
|
|
72224
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
72225
|
+
let quoteByte = null;
|
|
72226
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
72227
|
+
const byte = sourceBuffer[byteIndex];
|
|
72228
|
+
if (quoteByte !== null) {
|
|
72229
|
+
if (byte === quoteByte) quoteByte = null;
|
|
72230
|
+
continue;
|
|
72231
|
+
}
|
|
72232
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72233
|
+
quoteByte = byte;
|
|
72234
|
+
continue;
|
|
72235
|
+
}
|
|
72236
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
72237
|
+
}
|
|
72238
|
+
return sourceBuffer.length;
|
|
72239
|
+
};
|
|
72240
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
72241
|
+
let byteIndex = attributesStartByte;
|
|
72242
|
+
let hasSource = false;
|
|
72243
|
+
let language = null;
|
|
72244
|
+
let scriptType = null;
|
|
72245
|
+
while (byteIndex < tagEndByte) {
|
|
72246
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
72247
|
+
const attributeNameStartByte = byteIndex;
|
|
72248
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72249
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
72250
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72251
|
+
let attributeValue = "";
|
|
72252
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
72253
|
+
byteIndex++;
|
|
72254
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
72255
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
72256
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
72257
|
+
const valueStartByte = byteIndex + 1;
|
|
72258
|
+
byteIndex = valueStartByte;
|
|
72259
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
72260
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72261
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
72262
|
+
} else {
|
|
72263
|
+
const valueStartByte = byteIndex;
|
|
72264
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
72265
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
72266
|
+
}
|
|
72267
|
+
}
|
|
72268
|
+
if (attributeName === "src") hasSource = true;
|
|
72269
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
72270
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
72271
|
+
}
|
|
72272
|
+
return {
|
|
72273
|
+
hasSource,
|
|
72274
|
+
language,
|
|
72275
|
+
type: scriptType
|
|
72276
|
+
};
|
|
72277
|
+
};
|
|
72278
|
+
const isExecutableScript = (attributes) => {
|
|
72279
|
+
if (attributes.hasSource) return false;
|
|
72280
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
72281
|
+
if (type !== "") {
|
|
72282
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
72283
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
72284
|
+
}
|
|
72285
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
72286
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
72287
|
+
};
|
|
72288
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
72289
|
+
const closeTagStart = `</${tagName}`;
|
|
72290
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) if (sourceBuffer[byteIndex] === TAG_OPEN_UTF8_BYTE && matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, closeTagStart) && isTagBoundary(sourceBuffer[byteIndex + closeTagStart.length])) return byteIndex;
|
|
72291
|
+
return sourceBuffer.length;
|
|
72292
|
+
};
|
|
72293
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
72294
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
72295
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
72296
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
72297
|
+
const executableScriptBodies = [];
|
|
72298
|
+
let byteIndex = frontmatterEndByte;
|
|
72299
|
+
let templateDepth = 0;
|
|
72300
|
+
while (byteIndex < sourceBuffer.length) {
|
|
72301
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
72302
|
+
byteIndex++;
|
|
72303
|
+
continue;
|
|
72304
|
+
}
|
|
72305
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
72306
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
72307
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
72308
|
+
continue;
|
|
72309
|
+
}
|
|
72310
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
72311
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
72312
|
+
if (templateDepth > 0) templateDepth--;
|
|
72313
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72314
|
+
continue;
|
|
72315
|
+
}
|
|
72316
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
72317
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
72318
|
+
byteIndex++;
|
|
72319
|
+
continue;
|
|
72320
|
+
}
|
|
72321
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
72322
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
72323
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
72324
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
72325
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
72326
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
72327
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
72328
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
72329
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72330
|
+
continue;
|
|
72331
|
+
}
|
|
72332
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
72333
|
+
continue;
|
|
72334
|
+
}
|
|
72335
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
72336
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
72337
|
+
const bodyStartByte = tagEndByte + 1;
|
|
72338
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
72339
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
72340
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
72341
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
72342
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
72343
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
72344
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
72345
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
72346
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
72347
|
+
}
|
|
72348
|
+
return {
|
|
72349
|
+
executableScriptBodies,
|
|
72350
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
72351
|
+
};
|
|
72352
|
+
};
|
|
72353
|
+
const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
72354
|
+
const lintFiles = [];
|
|
72355
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
72356
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
72357
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
72358
|
+
let htmlFileIndex = 0;
|
|
72359
|
+
let hasThreeModuleImport = false;
|
|
72360
|
+
for (const candidateFile of candidateFiles) {
|
|
72361
|
+
if (!HTML_FILE_PATTERN.test(candidateFile)) {
|
|
72362
|
+
lintFiles.push(candidateFile);
|
|
72363
|
+
continue;
|
|
72364
|
+
}
|
|
72365
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
72366
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
72367
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
72368
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
72369
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
72370
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
72371
|
+
lintFiles.push(lintPath);
|
|
72372
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
72373
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
72374
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
72375
|
+
htmlFileIndex++;
|
|
72376
|
+
}
|
|
72377
|
+
return {
|
|
72378
|
+
lintFiles,
|
|
72379
|
+
sourcePathByLintPath,
|
|
72380
|
+
sizeByLintPath,
|
|
72381
|
+
hasThreeModuleImport
|
|
72382
|
+
};
|
|
72383
|
+
};
|
|
71810
72384
|
/**
|
|
71811
72385
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
71812
72386
|
* the runner: once for the primary scan, once for the
|
|
@@ -71967,6 +72541,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
71967
72541
|
const runOxlint = async (options) => {
|
|
71968
72542
|
const { rootDirectory, project, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false, respectInlineDisables = true, adoptExistingLintConfig = true, ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, userConfig, configSourceDirectory = rootDirectory, onPartialFailure, onFileCoverage, perFileLintCacheEnabled = false, sidecarLintCacheEnabled = false, onCacheStats, onSidecarStats, spawnTimeoutMs, outputMaxBytes, lintBatchOrdering = "cost" } = options;
|
|
71969
72543
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72544
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
72545
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
71970
72546
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
71971
72547
|
validateRuleRegistration();
|
|
71972
72548
|
resetManifestCaches();
|
|
@@ -71980,21 +72556,6 @@ const runOxlint = async (options) => {
|
|
|
71980
72556
|
const pluginPath = resolvePluginPath();
|
|
71981
72557
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
71982
72558
|
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
71983
|
-
const buildConfig = (overrides) => createOxlintConfig({
|
|
71984
|
-
pluginPath,
|
|
71985
|
-
project,
|
|
71986
|
-
customRulesOnly,
|
|
71987
|
-
extendsPaths: overrides.extendsPaths,
|
|
71988
|
-
ignoredTags,
|
|
71989
|
-
includedTags,
|
|
71990
|
-
includeTagDefaults,
|
|
71991
|
-
serverAuthFunctionNames,
|
|
71992
|
-
severityControls,
|
|
71993
|
-
userPlugins,
|
|
71994
|
-
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
71995
|
-
ruleSelection: overrides.ruleSelection,
|
|
71996
|
-
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
71997
|
-
});
|
|
71998
72559
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
71999
72560
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
72000
72561
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -72030,7 +72591,36 @@ const runOxlint = async (options) => {
|
|
|
72030
72591
|
await yieldToEventLoop();
|
|
72031
72592
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
72032
72593
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
72594
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
72595
|
+
rootDirectory,
|
|
72596
|
+
candidateFiles
|
|
72597
|
+
});
|
|
72598
|
+
const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
72599
|
+
const lintFiles = preparedHtmlSources.lintFiles;
|
|
72600
|
+
const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
|
|
72601
|
+
const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
|
|
72602
|
+
...project,
|
|
72603
|
+
hasThree: true
|
|
72604
|
+
} : project;
|
|
72605
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
72606
|
+
pluginPath,
|
|
72607
|
+
project: lintProject,
|
|
72608
|
+
customRulesOnly,
|
|
72609
|
+
extendsPaths: overrides.extendsPaths,
|
|
72610
|
+
ignoredTags,
|
|
72611
|
+
includedTags,
|
|
72612
|
+
includeTagDefaults,
|
|
72613
|
+
runtimeGlobals,
|
|
72614
|
+
unpluginAutoImportGlobalScopes,
|
|
72615
|
+
serverAuthFunctionNames,
|
|
72616
|
+
severityControls,
|
|
72617
|
+
userPlugins,
|
|
72618
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
72619
|
+
ruleSelection: overrides.ruleSelection,
|
|
72620
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
72621
|
+
});
|
|
72033
72622
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
72623
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
72034
72624
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
72035
72625
|
baseArgs: passBaseArgs,
|
|
72036
72626
|
files: passFiles,
|
|
@@ -72059,7 +72649,8 @@ const runOxlint = async (options) => {
|
|
|
72059
72649
|
fileBatches: passFileBatches,
|
|
72060
72650
|
rootDirectory,
|
|
72061
72651
|
nodeBinaryPath,
|
|
72062
|
-
project,
|
|
72652
|
+
project: lintProject,
|
|
72653
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
72063
72654
|
onPartialFailure: reportPartialFailure,
|
|
72064
72655
|
onAnalyzedFiles: (filePaths) => {
|
|
72065
72656
|
analyzedFiles = filePaths;
|
|
@@ -72094,7 +72685,7 @@ const runOxlint = async (options) => {
|
|
|
72094
72685
|
};
|
|
72095
72686
|
}
|
|
72096
72687
|
};
|
|
72097
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
72688
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
|
|
72098
72689
|
const rulesetHash = computeRulesetHash({
|
|
72099
72690
|
config: buildConfig({
|
|
72100
72691
|
extendsPaths: [],
|
|
@@ -72252,14 +72843,15 @@ const runOxlint = async (options) => {
|
|
|
72252
72843
|
]);
|
|
72253
72844
|
}
|
|
72254
72845
|
const baseArgs = makeBaseArgs(configPath);
|
|
72255
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
72846
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
72256
72847
|
let analyzedFiles = [];
|
|
72257
72848
|
const runBatches = () => spawnLintBatches({
|
|
72258
72849
|
baseArgs,
|
|
72259
72850
|
fileBatches,
|
|
72260
72851
|
rootDirectory,
|
|
72261
72852
|
nodeBinaryPath,
|
|
72262
|
-
project,
|
|
72853
|
+
project: lintProject,
|
|
72854
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
72263
72855
|
onPartialFailure,
|
|
72264
72856
|
onAnalyzedFiles: (filePaths) => {
|
|
72265
72857
|
analyzedFiles = filePaths;
|
|
@@ -73835,7 +74427,8 @@ const SCANNABLE_EXTENSIONS = [
|
|
|
73835
74427
|
".js",
|
|
73836
74428
|
".jsx",
|
|
73837
74429
|
".mts",
|
|
73838
|
-
".mjs"
|
|
74430
|
+
".mjs",
|
|
74431
|
+
".html"
|
|
73839
74432
|
];
|
|
73840
74433
|
const SILENT_LOGGER = {
|
|
73841
74434
|
info: () => {},
|
|
@@ -75823,5 +76416,5 @@ const startLanguageServer = () => {
|
|
|
75823
76416
|
};
|
|
75824
76417
|
//#endregion
|
|
75825
76418
|
export { startLanguageServer };
|
|
75826
|
-
!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]="
|
|
75827
|
-
//# debugId=
|
|
76419
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="6a2a246a-da30-59c5-aa97-af8188206b96")}catch(e){}}();
|
|
76420
|
+
//# debugId=6a2a246a-da30-59c5-aa97-af8188206b96
|