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/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7f26fa62-fe0c-5ae0-bc9c-97a0deb50b43")}catch(e){}}();
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import * as NodeChildProcess from "node:child_process";
|
|
5
5
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
@@ -64616,7 +64616,8 @@ var AmbiguousProjectError = class extends Error {
|
|
|
64616
64616
|
}
|
|
64617
64617
|
};
|
|
64618
64618
|
const isProjectDiscoveryError = (value) => value instanceof ProjectNotFoundError || value instanceof NoReactDependencyError || value instanceof PackageJsonNotFoundError || value instanceof NotADirectoryError || value instanceof AmbiguousProjectError;
|
|
64619
|
-
const
|
|
64619
|
+
const HTML_FILE_PATTERN = /\.html$/i;
|
|
64620
|
+
const SOURCE_FILE_PATTERN = /\.(?:tsx?|jsx?|mts|mjs|[hH][tT][mM][lL])$/;
|
|
64620
64621
|
const GENERATED_BUNDLE_FILE_PATTERN = /\.(iife|umd|global|min)\.m?js$/i;
|
|
64621
64622
|
const GENERATED_SOURCE_DIRECTORY_PATTERN = /(?:^|\/)__generated__\//;
|
|
64622
64623
|
const MINIFIED_SNIFF_BYTES = 65536;
|
|
@@ -65485,7 +65486,7 @@ const parseConfigSourceFile = (filePath, content) => filePath.endsWith(".json")
|
|
|
65485
65486
|
const getStaticPropertyName$2 = (propertyName) => ts.isIdentifier(propertyName) || ts.isStringLiteralLike(propertyName) ? propertyName.text : ts.isComputedPropertyName(propertyName) && ts.isStringLiteralLike(propertyName.expression) ? propertyName.expression.text : null;
|
|
65486
65487
|
const isCommonJsConfigExportAssignment = (node, sourceFile) => ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && (node.left.getText(sourceFile) === "module.exports" || node.left.getText(sourceFile) === "exports.default");
|
|
65487
65488
|
const hasExportModifier = (node) => ts.canHaveModifiers(node) && Boolean(ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword));
|
|
65488
|
-
const getRequireModuleSpecifier = (expression) => {
|
|
65489
|
+
const getRequireModuleSpecifier$1 = (expression) => {
|
|
65489
65490
|
if (!ts.isCallExpression(expression) || !ts.isIdentifier(expression.expression) || expression.expression.text !== "require" || expression.arguments.length !== 1) return null;
|
|
65490
65491
|
const moduleSpecifier = expression.arguments[0];
|
|
65491
65492
|
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
@@ -65498,7 +65499,7 @@ const hasTopLevelValueBinding = (sourceFile, bindingName) => sourceFile.statemen
|
|
|
65498
65499
|
const namedBindings = importClause?.namedBindings;
|
|
65499
65500
|
return namedBindings ? ts.isNamespaceImport(namedBindings) ? namedBindings.name.text === bindingName : namedBindings.elements.some((element) => element.name.text === bindingName) : false;
|
|
65500
65501
|
}
|
|
65501
|
-
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) =>
|
|
65502
|
+
if (ts.isVariableStatement(statement)) return statement.declarationList.declarations.some((declaration) => bindingNameContainsIdentifier(declaration.name, bindingName));
|
|
65502
65503
|
return (ts.isFunctionDeclaration(statement) || ts.isClassDeclaration(statement)) && statement.name?.text === bindingName;
|
|
65503
65504
|
});
|
|
65504
65505
|
const getImportBinding = (sourceFile, bindingName) => {
|
|
@@ -65529,21 +65530,21 @@ const getImportBinding = (sourceFile, bindingName) => {
|
|
|
65529
65530
|
for (const declaration of statement.declarationList.declarations) {
|
|
65530
65531
|
if (!declaration.initializer) continue;
|
|
65531
65532
|
if (ts.isIdentifier(declaration.name) && declaration.name.text === bindingName) {
|
|
65532
|
-
const directModuleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
65533
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
65533
65534
|
if (directModuleSpecifier) return {
|
|
65534
65535
|
moduleSpecifier: directModuleSpecifier,
|
|
65535
65536
|
exportName: "default",
|
|
65536
65537
|
isNamespace: true
|
|
65537
65538
|
};
|
|
65538
|
-
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier(declaration.initializer.expression) !== null) return {
|
|
65539
|
-
moduleSpecifier: getRequireModuleSpecifier(declaration.initializer.expression) ?? "",
|
|
65539
|
+
if (ts.isPropertyAccessExpression(declaration.initializer) && getRequireModuleSpecifier$1(declaration.initializer.expression) !== null) return {
|
|
65540
|
+
moduleSpecifier: getRequireModuleSpecifier$1(declaration.initializer.expression) ?? "",
|
|
65540
65541
|
exportName: declaration.initializer.name.text,
|
|
65541
65542
|
isNamespace: false
|
|
65542
65543
|
};
|
|
65543
65544
|
}
|
|
65544
65545
|
if (!ts.isObjectBindingPattern(declaration.name)) continue;
|
|
65545
65546
|
const bindingElement = declaration.name.elements.find((element) => ts.isIdentifier(element.name) && element.name.text === bindingName);
|
|
65546
|
-
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
65547
|
+
const moduleSpecifier = getRequireModuleSpecifier$1(declaration.initializer);
|
|
65547
65548
|
if (bindingElement && moduleSpecifier) return {
|
|
65548
65549
|
moduleSpecifier,
|
|
65549
65550
|
exportName: bindingElement.propertyName ? getStaticPropertyName$2(bindingElement.propertyName) ?? bindingElement.propertyName.getText(sourceFile) : bindingElement.name.getText(sourceFile),
|
|
@@ -65599,6 +65600,48 @@ const getScopedConfigBinding = (identifier) => {
|
|
|
65599
65600
|
};
|
|
65600
65601
|
};
|
|
65601
65602
|
const isCompilerTransformModule = (moduleSpecifier, exportName) => moduleSpecifier === "babel-plugin-react-compiler" && exportName === "default" || moduleSpecifier === "@vitejs/plugin-react" && exportName === "reactCompilerPreset";
|
|
65603
|
+
const NODE_MODULE_SPECIFIERS = new Set(["module", "node:module"]);
|
|
65604
|
+
const isConstantVariableInitializer = (node) => ts.isExpression(node) && ts.isVariableDeclaration(node.parent) && ts.isVariableDeclarationList(node.parent.parent) && Boolean(node.parent.parent.flags & ts.NodeFlags.Const);
|
|
65605
|
+
const isNodeCreateRequireCall = (node, analysis) => {
|
|
65606
|
+
if (ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isTypeAssertionExpression(node) || ts.isSatisfiesExpression(node) || ts.isNonNullExpression(node) || ts.isAwaitExpression(node)) return isNodeCreateRequireCall(node.expression, analysis);
|
|
65607
|
+
if (!ts.isCallExpression(node)) return false;
|
|
65608
|
+
const target = node.expression;
|
|
65609
|
+
if (ts.isIdentifier(target)) {
|
|
65610
|
+
if (analysis.localBindings.has(target.text) || getScopedConfigBinding(target).wasFound) return false;
|
|
65611
|
+
const importBinding = getImportBinding(analysis.sourceFile, target.text);
|
|
65612
|
+
return Boolean(importBinding && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier) && importBinding.exportName === "createRequire");
|
|
65613
|
+
}
|
|
65614
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return false;
|
|
65615
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "createRequire") return false;
|
|
65616
|
+
const createRequireReceiver = target.expression;
|
|
65617
|
+
if (ts.isCallExpression(createRequireReceiver)) {
|
|
65618
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(createRequireReceiver);
|
|
65619
|
+
if (requiredModuleSpecifier === null || !NODE_MODULE_SPECIFIERS.has(requiredModuleSpecifier) || !ts.isIdentifier(createRequireReceiver.expression)) return false;
|
|
65620
|
+
const requireIdentifier = createRequireReceiver.expression;
|
|
65621
|
+
return !analysis.localBindings.has(requireIdentifier.text) && !getScopedConfigBinding(requireIdentifier).wasFound && !hasTopLevelValueBinding(analysis.sourceFile, requireIdentifier.text);
|
|
65622
|
+
}
|
|
65623
|
+
if (!ts.isIdentifier(createRequireReceiver)) return false;
|
|
65624
|
+
if (analysis.localBindings.has(createRequireReceiver.text) || getScopedConfigBinding(createRequireReceiver).wasFound) return false;
|
|
65625
|
+
const importBinding = getImportBinding(analysis.sourceFile, createRequireReceiver.text);
|
|
65626
|
+
return Boolean(importBinding?.isNamespace && NODE_MODULE_SPECIFIERS.has(importBinding.moduleSpecifier));
|
|
65627
|
+
};
|
|
65628
|
+
const getNodeRequireResolveModuleSpecifier = (callExpression, analysis) => {
|
|
65629
|
+
const [moduleSpecifierNode] = callExpression.arguments;
|
|
65630
|
+
if (!moduleSpecifierNode || !ts.isStringLiteralLike(moduleSpecifierNode)) return null;
|
|
65631
|
+
const target = callExpression.expression;
|
|
65632
|
+
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
65633
|
+
if ((ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null) !== "resolve") return null;
|
|
65634
|
+
if (isNodeCreateRequireCall(target.expression, analysis)) return moduleSpecifierNode.text;
|
|
65635
|
+
if (!ts.isIdentifier(target.expression)) return null;
|
|
65636
|
+
const resolverIdentifier = target.expression;
|
|
65637
|
+
if (analysis.localBindings.has(resolverIdentifier.text)) return null;
|
|
65638
|
+
const scopedBinding = getScopedConfigBinding(resolverIdentifier);
|
|
65639
|
+
const topLevelBinding = scopedBinding.wasFound ? null : getTopLevelBinding(analysis.sourceFile, resolverIdentifier.text);
|
|
65640
|
+
const resolverInitializer = scopedBinding.wasFound ? scopedBinding.initializer : topLevelBinding;
|
|
65641
|
+
if (resolverInitializer === null && !scopedBinding.wasFound && resolverIdentifier.text === "require" && !hasTopLevelValueBinding(analysis.sourceFile, resolverIdentifier.text) && getImportBinding(analysis.sourceFile, resolverIdentifier.text) === null) return moduleSpecifierNode.text;
|
|
65642
|
+
if (!resolverInitializer || !isConstantVariableInitializer(resolverInitializer) || !isNodeCreateRequireCall(resolverInitializer, analysis)) return null;
|
|
65643
|
+
return moduleSpecifierNode.text;
|
|
65644
|
+
};
|
|
65602
65645
|
const getAssignedPropertyInitializer = (identifier, propertyName) => {
|
|
65603
65646
|
let bindingScope = null;
|
|
65604
65647
|
let currentNode = identifier;
|
|
@@ -65914,7 +65957,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
|
|
|
65914
65957
|
if (!ts.isPropertyAccessExpression(target) && !ts.isElementAccessExpression(target)) return null;
|
|
65915
65958
|
const propertyName = ts.isPropertyAccessExpression(target) ? target.name.text : target.argumentExpression && ts.isStringLiteralLike(target.argumentExpression) ? target.argumentExpression.text : null;
|
|
65916
65959
|
if (propertyName === null) return null;
|
|
65917
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(target.expression);
|
|
65960
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(target.expression);
|
|
65918
65961
|
if (requiredModuleSpecifier !== null) {
|
|
65919
65962
|
if (ts.isCallExpression(target.expression) && ts.isIdentifier(target.expression.expression) && (getScopedConfigBinding(target.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
65920
65963
|
if (!requiredModuleSpecifier.startsWith(".")) return null;
|
|
@@ -65974,9 +66017,11 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
65974
66017
|
});
|
|
65975
66018
|
}
|
|
65976
66019
|
if (ts.isCallExpression(node)) {
|
|
66020
|
+
const resolvedModuleSpecifier = getNodeRequireResolveModuleSpecifier(node, analysis);
|
|
66021
|
+
if (resolvedModuleSpecifier !== null) return allowCompilerTransform && isCompilerTransformModule(resolvedModuleSpecifier, "default");
|
|
65977
66022
|
const callTargetResult = analyzeConfigCallTarget(node, analysis, allowCompilerTransform);
|
|
65978
66023
|
if (callTargetResult !== null) return callTargetResult;
|
|
65979
|
-
const directModuleSpecifier = getRequireModuleSpecifier(node);
|
|
66024
|
+
const directModuleSpecifier = getRequireModuleSpecifier$1(node);
|
|
65980
66025
|
const isRequireShadowed = analysis.localBindings.has("require") || ts.isIdentifier(node.expression) && getScopedConfigBinding(node.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require");
|
|
65981
66026
|
if (directModuleSpecifier && isRequireShadowed) return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
65982
66027
|
if (directModuleSpecifier && !isRequireShadowed) {
|
|
@@ -65998,7 +66043,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
65998
66043
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform) || node.arguments.some((argument) => analyzeConfigNode(argument, analysis, false));
|
|
65999
66044
|
}
|
|
66000
66045
|
if (ts.isPropertyAccessExpression(node)) {
|
|
66001
|
-
const requiredModuleSpecifier = getRequireModuleSpecifier(node.expression);
|
|
66046
|
+
const requiredModuleSpecifier = getRequireModuleSpecifier$1(node.expression);
|
|
66002
66047
|
if (requiredModuleSpecifier) {
|
|
66003
66048
|
if (ts.isCallExpression(node.expression) && ts.isIdentifier(node.expression.expression) && (getScopedConfigBinding(node.expression.expression).wasFound || hasTopLevelValueBinding(analysis.sourceFile, "require"))) return false;
|
|
66004
66049
|
if (requiredModuleSpecifier.startsWith(".")) {
|
|
@@ -69335,7 +69380,7 @@ const warn = (message) => {
|
|
|
69335
69380
|
runSync(warn$1(message));
|
|
69336
69381
|
};
|
|
69337
69382
|
const CONFIG_BASENAME = "doctor.config";
|
|
69338
|
-
const CONFIG_EXTENSIONS = [
|
|
69383
|
+
const CONFIG_EXTENSIONS$1 = [
|
|
69339
69384
|
"ts",
|
|
69340
69385
|
"mts",
|
|
69341
69386
|
"cts",
|
|
@@ -69439,7 +69484,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
69439
69484
|
};
|
|
69440
69485
|
const loadConfigFromDirectory = async (directory) => {
|
|
69441
69486
|
let sawBrokenConfigFile = false;
|
|
69442
|
-
for (const extension of CONFIG_EXTENSIONS) {
|
|
69487
|
+
for (const extension of CONFIG_EXTENSIONS$1) {
|
|
69443
69488
|
const filePath = Path.join(directory, `${CONFIG_BASENAME}.${extension}`);
|
|
69444
69489
|
if (!isFile(filePath)) continue;
|
|
69445
69490
|
const isDataFile = DATA_CONFIG_EXTENSIONS.has(extension);
|
|
@@ -69498,7 +69543,7 @@ const loadConfigWithSource = (rootDirectory) => {
|
|
|
69498
69543
|
return loadPromise;
|
|
69499
69544
|
};
|
|
69500
69545
|
const directoryHasCurrentConfig = (directory) => {
|
|
69501
|
-
for (const extension of CONFIG_EXTENSIONS) if (isFile(Path.join(directory, `${CONFIG_BASENAME}.${extension}`))) return true;
|
|
69546
|
+
for (const extension of CONFIG_EXTENSIONS$1) if (isFile(Path.join(directory, `${CONFIG_BASENAME}.${extension}`))) return true;
|
|
69502
69547
|
return readEmbeddedPackageJsonConfig(directory) !== null;
|
|
69503
69548
|
};
|
|
69504
69549
|
/**
|
|
@@ -73290,7 +73335,11 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
73290
73335
|
const ROOT_DIRECTORY_PLACEHOLDER = "<root>";
|
|
73291
73336
|
const normalizeConfigForHash = (config) => {
|
|
73292
73337
|
const clone = JSON.parse(JSON.stringify(config));
|
|
73293
|
-
if (clone?.settings?.["react-doctor"])
|
|
73338
|
+
if (clone?.settings?.["react-doctor"]) {
|
|
73339
|
+
const reactDoctorSettings = clone.settings["react-doctor"];
|
|
73340
|
+
reactDoctorSettings.rootDirectory = ROOT_DIRECTORY_PLACEHOLDER;
|
|
73341
|
+
if (Array.isArray(reactDoctorSettings.unpluginAutoImportRootDirectories)) reactDoctorSettings.unpluginAutoImportRootDirectories = [ROOT_DIRECTORY_PLACEHOLDER];
|
|
73342
|
+
}
|
|
73294
73343
|
if (Array.isArray(clone?.jsPlugins)) clone.jsPlugins = clone.jsPlugins.map((_, index) => `<plugin:${index}>`);
|
|
73295
73344
|
return clone;
|
|
73296
73345
|
};
|
|
@@ -73449,13 +73498,14 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
73449
73498
|
}
|
|
73450
73499
|
return enabled;
|
|
73451
73500
|
};
|
|
73452
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), includedTags = /* @__PURE__ */ new Set(), includeTagDefaults = false, serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false, ruleSelection, sidecarRuleIdFilter }) => {
|
|
73501
|
+
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 }) => {
|
|
73453
73502
|
const hasIncludedTags = includedTags.size > 0;
|
|
73454
73503
|
const reactHooksJsPlugin = disableReactHooksJsPlugin || ruleSelection === "sidecar" || hasIncludedTags ? null : resolveReactHooksJsPlugin(project.hasReactCompiler || project.hasReactCompilerLintPlugin === true, customRulesOnly);
|
|
73455
73504
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
73456
73505
|
const jsPlugins = [];
|
|
73457
73506
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
73458
73507
|
const capabilities = getCapabilities(project);
|
|
73508
|
+
const settingsRootDirectory = resolveSettingsRootDirectory(project.rootDirectory);
|
|
73459
73509
|
const enabledReactDoctorRules = {};
|
|
73460
73510
|
for (const registryEntry of REACT_DOCTOR_RULES) {
|
|
73461
73511
|
const rule = reactDoctorPlugin.rules[registryEntry.id];
|
|
@@ -73501,8 +73551,16 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
73501
73551
|
jsPlugins: [...jsPlugins, pluginPath],
|
|
73502
73552
|
settings: { "react-doctor": {
|
|
73503
73553
|
framework: project.framework,
|
|
73504
|
-
rootDirectory:
|
|
73554
|
+
rootDirectory: settingsRootDirectory,
|
|
73505
73555
|
capabilities: [...capabilities].sort(),
|
|
73556
|
+
...runtimeGlobals && runtimeGlobals.length > 0 ? { runtimeGlobals: [...runtimeGlobals] } : {},
|
|
73557
|
+
...unpluginAutoImportGlobalScopes && unpluginAutoImportGlobalScopes.length > 0 ? {
|
|
73558
|
+
unpluginAutoImportRootDirectories: [...new Set([settingsRootDirectory, project.rootDirectory])],
|
|
73559
|
+
unpluginAutoImportGlobalScopes: unpluginAutoImportGlobalScopes.map((scope) => ({
|
|
73560
|
+
directory: scope.directory,
|
|
73561
|
+
names: [...scope.names]
|
|
73562
|
+
}))
|
|
73563
|
+
} : {},
|
|
73506
73564
|
...project.shopifyFlashListMajorVersion !== null ? { shopifyFlashListMajorVersion: project.shopifyFlashListMajorVersion } : {},
|
|
73507
73565
|
...serverAuthFunctionNames && serverAuthFunctionNames.length > 0 ? { serverAuthFunctionNames: [...serverAuthFunctionNames] } : {}
|
|
73508
73566
|
} },
|
|
@@ -73513,6 +73571,245 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
73513
73571
|
}
|
|
73514
73572
|
};
|
|
73515
73573
|
};
|
|
73574
|
+
const AUTO_IMPORT_ADAPTER_PATTERN = /^unplugin-auto-import\/(?:astro|esbuild|rollup|rolldown|rspack|vite|webpack)$/;
|
|
73575
|
+
const CONFIG_BASENAMES = [
|
|
73576
|
+
"astro.config",
|
|
73577
|
+
"esbuild.config",
|
|
73578
|
+
"rollup.config",
|
|
73579
|
+
"rolldown.config",
|
|
73580
|
+
"rspack.config",
|
|
73581
|
+
"vite.config",
|
|
73582
|
+
"webpack.config"
|
|
73583
|
+
];
|
|
73584
|
+
const CONFIG_EXTENSIONS = [
|
|
73585
|
+
".cjs",
|
|
73586
|
+
".cts",
|
|
73587
|
+
".js",
|
|
73588
|
+
".mjs",
|
|
73589
|
+
".mts",
|
|
73590
|
+
".ts"
|
|
73591
|
+
];
|
|
73592
|
+
const CONFIG_FILENAMES = new Set(CONFIG_BASENAMES.flatMap((basename) => CONFIG_EXTENSIONS.map((extension) => `${basename}${extension}`)));
|
|
73593
|
+
const DEFAULT_ESLINT_GLOBALS_PATH = ".eslintrc-auto-import.json";
|
|
73594
|
+
const SUPPORTED_GLOBAL_VALUES = new Set([
|
|
73595
|
+
true,
|
|
73596
|
+
false,
|
|
73597
|
+
"readable",
|
|
73598
|
+
"readonly",
|
|
73599
|
+
"writable",
|
|
73600
|
+
"writeable"
|
|
73601
|
+
]);
|
|
73602
|
+
const getStaticProperty = (objectExpression, propertyName) => objectExpression.properties.find((property) => {
|
|
73603
|
+
if (ts.isSpreadAssignment(property)) return false;
|
|
73604
|
+
const name = ts.isComputedPropertyName(property.name) ? unwrapTypescriptExpression(property.name.expression) : property.name;
|
|
73605
|
+
return (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) && name.text === propertyName;
|
|
73606
|
+
}) ?? null;
|
|
73607
|
+
const hasNonLiteralComputedProperty = (objectExpression) => objectExpression.properties.some((property) => !ts.isSpreadAssignment(property) && ts.isComputedPropertyName(property.name) && !ts.isStringLiteralLike(unwrapTypescriptExpression(property.name.expression)));
|
|
73608
|
+
const getStaticPropertyAssignment = (objectExpression, propertyName) => {
|
|
73609
|
+
const property = getStaticProperty(objectExpression, propertyName);
|
|
73610
|
+
return property && ts.isPropertyAssignment(property) ? property : null;
|
|
73611
|
+
};
|
|
73612
|
+
const getRequireModuleSpecifier = (expression) => {
|
|
73613
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
73614
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === "default") return getRequireModuleSpecifier(unwrappedExpression.expression);
|
|
73615
|
+
if (!ts.isCallExpression(unwrappedExpression) || !ts.isIdentifier(unwrappedExpression.expression) || unwrappedExpression.expression.text !== "require" || unwrappedExpression.arguments.length !== 1) return null;
|
|
73616
|
+
const moduleSpecifier = unwrappedExpression.arguments[0];
|
|
73617
|
+
return moduleSpecifier && ts.isStringLiteralLike(moduleSpecifier) ? moduleSpecifier.text : null;
|
|
73618
|
+
};
|
|
73619
|
+
const getRequiredPropertyModuleSpecifier = (expression, propertyName) => {
|
|
73620
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
73621
|
+
return ts.isPropertyAccessExpression(unwrappedExpression) && unwrappedExpression.name.text === propertyName ? getRequireModuleSpecifier(unwrappedExpression.expression) : null;
|
|
73622
|
+
};
|
|
73623
|
+
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");
|
|
73624
|
+
const isTopLevelExpression = (node) => {
|
|
73625
|
+
let ancestor = node.parent;
|
|
73626
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
73627
|
+
if (ts.isExpressionStatement(ancestor)) return ts.isSourceFile(ancestor.parent);
|
|
73628
|
+
if (!ts.isParenthesizedExpression(ancestor) && !ts.isAsExpression(ancestor) && !ts.isSatisfiesExpression(ancestor) && !ts.isNonNullExpression(ancestor) && !ts.isTypeAssertionExpression(ancestor) && !ts.isAwaitExpression(ancestor)) return false;
|
|
73629
|
+
ancestor = ancestor.parent;
|
|
73630
|
+
}
|
|
73631
|
+
return false;
|
|
73632
|
+
};
|
|
73633
|
+
const isInsideActiveConfigProperty = (node, propertyName, sourceFile, esbuildBindings, esbuildNamespaceBindings) => {
|
|
73634
|
+
let ancestor = node.parent;
|
|
73635
|
+
let didFindConfigProperty = false;
|
|
73636
|
+
while (ancestor && !ts.isSourceFile(ancestor)) {
|
|
73637
|
+
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;
|
|
73638
|
+
if (ts.isPropertyAssignment(ancestor)) {
|
|
73639
|
+
const isConfigProperty = (ts.isIdentifier(ancestor.name) || ts.isStringLiteralLike(ancestor.name)) && ancestor.name.text === propertyName;
|
|
73640
|
+
if (didFindConfigProperty || !isConfigProperty) return false;
|
|
73641
|
+
if (!ts.isObjectLiteralExpression(ancestor.parent) || ancestor.parent.properties.some(ts.isSpreadAssignment)) return false;
|
|
73642
|
+
didFindConfigProperty = true;
|
|
73643
|
+
ancestor = ancestor.parent;
|
|
73644
|
+
continue;
|
|
73645
|
+
}
|
|
73646
|
+
if (didFindConfigProperty) {
|
|
73647
|
+
if (ts.isExportAssignment(ancestor)) return true;
|
|
73648
|
+
if (isCommonJsExportAssignment(ancestor, sourceFile)) return isTopLevelExpression(ancestor);
|
|
73649
|
+
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);
|
|
73650
|
+
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;
|
|
73651
|
+
}
|
|
73652
|
+
ancestor = ancestor.parent;
|
|
73653
|
+
}
|
|
73654
|
+
return false;
|
|
73655
|
+
};
|
|
73656
|
+
const getGlobalsPathFromActiveAutoImportCall = (callExpression, packageDirectory) => {
|
|
73657
|
+
const optionsExpression = callExpression.arguments[0];
|
|
73658
|
+
if (!optionsExpression) return null;
|
|
73659
|
+
const unwrappedOptions = unwrapTypescriptExpression(optionsExpression);
|
|
73660
|
+
if (!ts.isObjectLiteralExpression(unwrappedOptions)) return null;
|
|
73661
|
+
if (unwrappedOptions.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(unwrappedOptions)) return null;
|
|
73662
|
+
if (getStaticProperty(unwrappedOptions, "include") || getStaticProperty(unwrappedOptions, "exclude")) return null;
|
|
73663
|
+
const eslintrcProperty = getStaticPropertyAssignment(unwrappedOptions, "eslintrc");
|
|
73664
|
+
if (!eslintrcProperty) return null;
|
|
73665
|
+
const eslintrcExpression = unwrapTypescriptExpression(eslintrcProperty.initializer);
|
|
73666
|
+
if (!ts.isObjectLiteralExpression(eslintrcExpression)) return null;
|
|
73667
|
+
if (eslintrcExpression.properties.some(ts.isSpreadAssignment) || hasNonLiteralComputedProperty(eslintrcExpression)) return null;
|
|
73668
|
+
const enabledProperty = getStaticPropertyAssignment(eslintrcExpression, "enabled");
|
|
73669
|
+
if (!enabledProperty || unwrapTypescriptExpression(enabledProperty.initializer).kind !== ts.SyntaxKind.TrueKeyword) return null;
|
|
73670
|
+
const filepathProperty = getStaticProperty(eslintrcExpression, "filepath");
|
|
73671
|
+
if (!filepathProperty) return Path.join(packageDirectory, DEFAULT_ESLINT_GLOBALS_PATH);
|
|
73672
|
+
if (!ts.isPropertyAssignment(filepathProperty)) return null;
|
|
73673
|
+
const filepathExpression = unwrapTypescriptExpression(filepathProperty.initializer);
|
|
73674
|
+
return ts.isStringLiteralLike(filepathExpression) ? Path.resolve(packageDirectory, filepathExpression.text) : null;
|
|
73675
|
+
};
|
|
73676
|
+
const collectGlobalsPathsFromConfig = (configPath, packageDirectory) => {
|
|
73677
|
+
let sourceText;
|
|
73678
|
+
try {
|
|
73679
|
+
sourceText = NFS.readFileSync(configPath, "utf8");
|
|
73680
|
+
} catch {
|
|
73681
|
+
return {
|
|
73682
|
+
didFindActiveAutoImport: false,
|
|
73683
|
+
globalsPaths: []
|
|
73684
|
+
};
|
|
73685
|
+
}
|
|
73686
|
+
const sourceFile = ts.createSourceFile(configPath, sourceText, ts.ScriptTarget.Latest, true);
|
|
73687
|
+
const autoImportBindings = /* @__PURE__ */ new Map();
|
|
73688
|
+
const esbuildBindings = /* @__PURE__ */ new Set();
|
|
73689
|
+
const esbuildNamespaceBindings = /* @__PURE__ */ new Set();
|
|
73690
|
+
for (const statement of sourceFile.statements) {
|
|
73691
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteralLike(statement.moduleSpecifier)) {
|
|
73692
|
+
const moduleSpecifier = statement.moduleSpecifier.text;
|
|
73693
|
+
if (AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
73694
|
+
const defaultBinding = statement.importClause?.name;
|
|
73695
|
+
if (defaultBinding) autoImportBindings.set(defaultBinding.text, moduleSpecifier);
|
|
73696
|
+
}
|
|
73697
|
+
if (moduleSpecifier === "esbuild") {
|
|
73698
|
+
const defaultBinding = statement.importClause?.name;
|
|
73699
|
+
if (defaultBinding) esbuildNamespaceBindings.add(defaultBinding.text);
|
|
73700
|
+
const namedBindings = statement.importClause?.namedBindings;
|
|
73701
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
73702
|
+
for (const importSpecifier of namedBindings.elements) if ((importSpecifier.propertyName ?? importSpecifier.name).text === "build") esbuildBindings.add(importSpecifier.name.text);
|
|
73703
|
+
}
|
|
73704
|
+
if (namedBindings && ts.isNamespaceImport(namedBindings)) esbuildNamespaceBindings.add(namedBindings.name.text);
|
|
73705
|
+
}
|
|
73706
|
+
}
|
|
73707
|
+
if (!ts.isVariableStatement(statement)) continue;
|
|
73708
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
73709
|
+
if (!declaration.initializer) continue;
|
|
73710
|
+
const declarationName = ts.isIdentifier(declaration.name) ? declaration.name.text : null;
|
|
73711
|
+
const moduleSpecifier = getRequireModuleSpecifier(declaration.initializer);
|
|
73712
|
+
if (declarationName && moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) autoImportBindings.set(declarationName, moduleSpecifier);
|
|
73713
|
+
if (moduleSpecifier === "esbuild") {
|
|
73714
|
+
if (declarationName) esbuildNamespaceBindings.add(declarationName);
|
|
73715
|
+
if (ts.isObjectBindingPattern(declaration.name)) for (const bindingElement of declaration.name.elements) {
|
|
73716
|
+
const importedName = bindingElement.propertyName ?? bindingElement.name;
|
|
73717
|
+
if (ts.isIdentifier(importedName) && importedName.text === "build" && ts.isIdentifier(bindingElement.name)) esbuildBindings.add(bindingElement.name.text);
|
|
73718
|
+
}
|
|
73719
|
+
}
|
|
73720
|
+
if (declarationName && getRequiredPropertyModuleSpecifier(declaration.initializer, "build") === "esbuild") esbuildBindings.add(declarationName);
|
|
73721
|
+
}
|
|
73722
|
+
}
|
|
73723
|
+
const globalsPaths = /* @__PURE__ */ new Set();
|
|
73724
|
+
let didFindActiveAutoImport = false;
|
|
73725
|
+
let didFindUnsafeActiveAutoImport = false;
|
|
73726
|
+
const visit = (node) => {
|
|
73727
|
+
if (ts.isCallExpression(node)) {
|
|
73728
|
+
const moduleSpecifier = ts.isIdentifier(node.expression) ? autoImportBindings.get(node.expression.text) : getRequireModuleSpecifier(node.expression);
|
|
73729
|
+
if (moduleSpecifier && AUTO_IMPORT_ADAPTER_PATTERN.test(moduleSpecifier)) {
|
|
73730
|
+
if (isInsideActiveConfigProperty(node, moduleSpecifier.endsWith("/astro") ? "integrations" : "plugins", sourceFile, esbuildBindings, esbuildNamespaceBindings)) {
|
|
73731
|
+
didFindActiveAutoImport = true;
|
|
73732
|
+
const globalsPath = getGlobalsPathFromActiveAutoImportCall(node, packageDirectory);
|
|
73733
|
+
if (globalsPath) globalsPaths.add(globalsPath);
|
|
73734
|
+
else didFindUnsafeActiveAutoImport = true;
|
|
73735
|
+
}
|
|
73736
|
+
}
|
|
73737
|
+
}
|
|
73738
|
+
ts.forEachChild(node, visit);
|
|
73739
|
+
};
|
|
73740
|
+
visit(sourceFile);
|
|
73741
|
+
return {
|
|
73742
|
+
didFindActiveAutoImport,
|
|
73743
|
+
globalsPaths: didFindUnsafeActiveAutoImport ? [] : [...globalsPaths]
|
|
73744
|
+
};
|
|
73745
|
+
};
|
|
73746
|
+
const collectGeneratedGlobalNames = (globalsPath, rootDirectory) => {
|
|
73747
|
+
const relativePath = Path.relative(rootDirectory, globalsPath);
|
|
73748
|
+
if (relativePath.startsWith("..") || Path.isAbsolute(relativePath)) return [];
|
|
73749
|
+
const parsed = failOpenReadJson(globalsPath, null);
|
|
73750
|
+
if (!isPlainObject(parsed) || !isPlainObject(parsed.globals)) return [];
|
|
73751
|
+
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();
|
|
73752
|
+
};
|
|
73753
|
+
const findOwningPackageDirectory = (absoluteFilePath, rootDirectory, cache) => {
|
|
73754
|
+
let currentDirectory = Path.dirname(absoluteFilePath);
|
|
73755
|
+
const visitedDirectories = [];
|
|
73756
|
+
while (true) {
|
|
73757
|
+
const cachedDirectory = cache.get(currentDirectory);
|
|
73758
|
+
if (cachedDirectory !== void 0) {
|
|
73759
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, cachedDirectory);
|
|
73760
|
+
return cachedDirectory;
|
|
73761
|
+
}
|
|
73762
|
+
const relativeDirectory = Path.relative(rootDirectory, currentDirectory);
|
|
73763
|
+
if (relativeDirectory.startsWith("..") || Path.isAbsolute(relativeDirectory)) {
|
|
73764
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
73765
|
+
return null;
|
|
73766
|
+
}
|
|
73767
|
+
visitedDirectories.push(currentDirectory);
|
|
73768
|
+
if (NFS.existsSync(Path.join(currentDirectory, "package.json"))) {
|
|
73769
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, currentDirectory);
|
|
73770
|
+
return currentDirectory;
|
|
73771
|
+
}
|
|
73772
|
+
if (currentDirectory === rootDirectory) {
|
|
73773
|
+
for (const visitedDirectory of visitedDirectories) cache.set(visitedDirectory, null);
|
|
73774
|
+
return null;
|
|
73775
|
+
}
|
|
73776
|
+
currentDirectory = Path.dirname(currentDirectory);
|
|
73777
|
+
}
|
|
73778
|
+
};
|
|
73779
|
+
const collectPackageGlobalNames = (packageDirectory, rootDirectory) => {
|
|
73780
|
+
let directoryEntries;
|
|
73781
|
+
try {
|
|
73782
|
+
directoryEntries = NFS.readdirSync(packageDirectory, { withFileTypes: true });
|
|
73783
|
+
} catch {
|
|
73784
|
+
return [];
|
|
73785
|
+
}
|
|
73786
|
+
const configuredGlobalsPaths = [];
|
|
73787
|
+
for (const entry of directoryEntries) {
|
|
73788
|
+
if (!entry.isFile() && !entry.isSymbolicLink() || !CONFIG_FILENAMES.has(entry.name)) continue;
|
|
73789
|
+
const configGlobalsPaths = collectGlobalsPathsFromConfig(Path.join(packageDirectory, entry.name), packageDirectory);
|
|
73790
|
+
if (configGlobalsPaths.didFindActiveAutoImport) configuredGlobalsPaths.push(configGlobalsPaths.globalsPaths.toSorted());
|
|
73791
|
+
}
|
|
73792
|
+
if (configuredGlobalsPaths.length === 0) return [];
|
|
73793
|
+
const globalsPaths = configuredGlobalsPaths[0];
|
|
73794
|
+
if (configuredGlobalsPaths.some((candidatePaths) => candidatePaths.length !== globalsPaths.length || candidatePaths.some((candidatePath, index) => candidatePath !== globalsPaths[index]))) return [];
|
|
73795
|
+
const names = /* @__PURE__ */ new Set();
|
|
73796
|
+
for (const globalsPath of globalsPaths) for (const name of collectGeneratedGlobalNames(globalsPath, rootDirectory)) names.add(name);
|
|
73797
|
+
return [...names].sort();
|
|
73798
|
+
};
|
|
73799
|
+
const collectUnpluginAutoImportGlobalScopes = ({ rootDirectory, candidateFiles }) => {
|
|
73800
|
+
const absoluteRootDirectory = Path.resolve(rootDirectory);
|
|
73801
|
+
const packageDirectoryCache = /* @__PURE__ */ new Map();
|
|
73802
|
+
const packageDirectories = /* @__PURE__ */ new Set();
|
|
73803
|
+
for (const candidateFile of candidateFiles) {
|
|
73804
|
+
const packageDirectory = findOwningPackageDirectory(Path.resolve(absoluteRootDirectory, candidateFile), absoluteRootDirectory, packageDirectoryCache);
|
|
73805
|
+
if (packageDirectory) packageDirectories.add(packageDirectory);
|
|
73806
|
+
}
|
|
73807
|
+
const scopes = [...packageDirectories].map((packageDirectory) => ({
|
|
73808
|
+
directory: Path.relative(absoluteRootDirectory, packageDirectory).replaceAll("\\", "/"),
|
|
73809
|
+
names: collectPackageGlobalNames(packageDirectory, absoluteRootDirectory)
|
|
73810
|
+
})).sort((firstScope, secondScope) => firstScope.directory.localeCompare(secondScope.directory));
|
|
73811
|
+
return scopes.some((scope) => scope.names.length > 0) ? scopes : [];
|
|
73812
|
+
};
|
|
73516
73813
|
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
73517
73814
|
const decodeFileDiagnostics = (raw) => {
|
|
73518
73815
|
if (!Array.isArray(raw)) return null;
|
|
@@ -73835,6 +74132,12 @@ const appendReanimatedSharedValueHint = (help, rule, project) => {
|
|
|
73835
74132
|
if (!help) return REANIMATED_SHARED_VALUE_HINT;
|
|
73836
74133
|
return `${help}\n\n${REANIMATED_SHARED_VALUE_HINT}`;
|
|
73837
74134
|
};
|
|
74135
|
+
const columnOfUtf8Offset = (sourceBuffer, utf8Offset) => {
|
|
74136
|
+
const boundedOffset = Math.min(Math.max(utf8Offset, 0), sourceBuffer.length);
|
|
74137
|
+
let lineStartOffset = boundedOffset;
|
|
74138
|
+
while (lineStartOffset > 0 && sourceBuffer[lineStartOffset - 1] !== 10) lineStartOffset--;
|
|
74139
|
+
return sourceBuffer.subarray(lineStartOffset, boundedOffset).toString("utf8").length + 1;
|
|
74140
|
+
};
|
|
73838
74141
|
const REDACTED_PLACEHOLDER = "<redacted>";
|
|
73839
74142
|
const KEEP_PREFIX = `$1${REDACTED_PLACEHOLDER}`;
|
|
73840
74143
|
const KNOWN_SECRET_RULES = [
|
|
@@ -74550,7 +74853,7 @@ const resolveMatchByOccurrence = (rule, category) => OCCURRENCE_MATCHED_CATEGORI
|
|
|
74550
74853
|
* with empty text still carry a useful jump target, so they're kept
|
|
74551
74854
|
* with a neutral message.
|
|
74552
74855
|
*/
|
|
74553
|
-
const buildRelatedLocations = (labels, filePath) => {
|
|
74856
|
+
const buildRelatedLocations = (labels, filePath, sourceBuffer) => {
|
|
74554
74857
|
if (labels.length <= 1) return [];
|
|
74555
74858
|
const related = [];
|
|
74556
74859
|
for (let labelIndex = 1; labelIndex < labels.length; labelIndex++) {
|
|
@@ -74558,8 +74861,8 @@ const buildRelatedLocations = (labels, filePath) => {
|
|
|
74558
74861
|
if (!label?.span) continue;
|
|
74559
74862
|
related.push({
|
|
74560
74863
|
filePath,
|
|
74561
|
-
line: label.span.line ?? 0,
|
|
74562
|
-
column: label.span.column ?? 0,
|
|
74864
|
+
line: sourceBuffer === null ? label.span.line ?? 0 : lineOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
74865
|
+
column: sourceBuffer === null ? label.span.column ?? 0 : columnOfUtf8Offset(sourceBuffer, label.span.offset),
|
|
74563
74866
|
offset: label.span.offset,
|
|
74564
74867
|
length: label.span.length,
|
|
74565
74868
|
message: label.label ?? ""
|
|
@@ -74579,7 +74882,7 @@ const isOxlintOutput = (value) => isRecord$1(value) && Array.isArray(value.diagn
|
|
|
74579
74882
|
* to the first `{`. Raises `OxlintOutputUnparseable` when the
|
|
74580
74883
|
* stdout isn't valid JSON or doesn't carry a `diagnostics` array.
|
|
74581
74884
|
*/
|
|
74582
|
-
const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
74885
|
+
const parseOxlintOutput = (stdout, project, rootDirectory, sourcePathByLintPath) => {
|
|
74583
74886
|
if (!stdout) return [];
|
|
74584
74887
|
const jsonStart = stdout.indexOf("{");
|
|
74585
74888
|
const sanitizedStdout = jsonStart > 0 ? stdout.slice(jsonStart) : stdout;
|
|
@@ -74596,8 +74899,10 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74596
74899
|
const sourceBufferCache = /* @__PURE__ */ new Map();
|
|
74597
74900
|
const sourceLinesCache = /* @__PURE__ */ new Map();
|
|
74598
74901
|
const resolveAbsolutePath = (filename) => Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
74902
|
+
const resolveMappedSourceFilename = (filename) => sourcePathByLintPath?.get(Path.normalize(resolveAbsolutePath(filename)));
|
|
74903
|
+
const resolveSourceFilename = (filename) => resolveMappedSourceFilename(filename) ?? filename;
|
|
74599
74904
|
const readSourceBuffer = (filename) => {
|
|
74600
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
74905
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
74601
74906
|
const cached = sourceBufferCache.get(absolutePath);
|
|
74602
74907
|
if (cached !== void 0) return cached;
|
|
74603
74908
|
let sourceBuffer;
|
|
@@ -74610,7 +74915,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74610
74915
|
return sourceBuffer;
|
|
74611
74916
|
};
|
|
74612
74917
|
const readSourceLines = (filename) => {
|
|
74613
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
74918
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
74614
74919
|
const cached = sourceLinesCache.get(absolutePath);
|
|
74615
74920
|
if (cached !== void 0) return cached;
|
|
74616
74921
|
const sourceBuffer = readSourceBuffer(filename);
|
|
@@ -74619,27 +74924,30 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74619
74924
|
return sourceLines;
|
|
74620
74925
|
};
|
|
74621
74926
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
74622
|
-
const absolutePath = resolveAbsolutePath(filename);
|
|
74927
|
+
const absolutePath = resolveAbsolutePath(resolveSourceFilename(filename));
|
|
74623
74928
|
const cached = minifiedFileCache.get(absolutePath);
|
|
74624
74929
|
if (cached !== void 0) return cached;
|
|
74625
74930
|
const minified = isMinifiedSource(absolutePath);
|
|
74626
74931
|
minifiedFileCache.set(absolutePath, minified);
|
|
74627
74932
|
return minified;
|
|
74628
74933
|
};
|
|
74629
|
-
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) => {
|
|
74934
|
+
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) => {
|
|
74630
74935
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
74631
74936
|
const primaryLabel = diagnostic.labels[0];
|
|
74632
74937
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
74633
|
-
const
|
|
74938
|
+
const mappedSourceFilename = resolveMappedSourceFilename(diagnostic.filename);
|
|
74939
|
+
const normalizedFilePath = (mappedSourceFilename ?? diagnostic.filename).replaceAll("\\", "/");
|
|
74634
74940
|
const primarySpan = primaryLabel?.span;
|
|
74635
74941
|
const sourceBuffer = primarySpan ? readSourceBuffer(diagnostic.filename) : null;
|
|
74636
|
-
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath);
|
|
74942
|
+
const relatedLocations = buildRelatedLocations(diagnostic.labels, normalizedFilePath, mappedSourceFilename === void 0 ? null : sourceBuffer);
|
|
74637
74943
|
const category = resolveDiagnosticCategory(plugin, rule);
|
|
74638
74944
|
const matchByOccurrence = resolveMatchByOccurrence(rule, category);
|
|
74639
74945
|
const sourceLines = primarySpan ? readSourceLines(diagnostic.filename) : null;
|
|
74640
|
-
const
|
|
74946
|
+
const primaryLineNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.line ?? 0;
|
|
74947
|
+
const primaryColumnNumber = primarySpan && mappedSourceFilename !== void 0 && sourceBuffer !== null ? columnOfUtf8Offset(sourceBuffer, primarySpan.offset) : primarySpan?.column ?? 0;
|
|
74948
|
+
const primaryLineIndex = primarySpan ? primaryLineNumber - 1 : -1;
|
|
74641
74949
|
const primaryLine = sourceLines?.[primaryLineIndex];
|
|
74642
|
-
const primaryColumnIndex = primarySpan ?
|
|
74950
|
+
const primaryColumnIndex = primarySpan ? primaryColumnNumber - 1 : -1;
|
|
74643
74951
|
const isJsxTagLabel = primaryLine !== void 0 && primaryColumnIndex >= 0 && (primaryLine[primaryColumnIndex] === "<" || primaryLine[primaryColumnIndex - 1] === "<");
|
|
74644
74952
|
const jsxOpenerEndLineIndex = sourceLines && isJsxTagLabel ? findJsxOpenerSpan(sourceLines, primaryLineIndex) : null;
|
|
74645
74953
|
const primarySpanEndLine = jsxOpenerEndLineIndex !== null ? jsxOpenerEndLineIndex + 1 : primarySpan && sourceBuffer ? lineOfUtf8Offset(sourceBuffer, primarySpan.offset + Math.max(primarySpan.length - 1, 0)) : void 0;
|
|
@@ -74652,8 +74960,8 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74652
74960
|
message: cleaned.message,
|
|
74653
74961
|
help: cleaned.help,
|
|
74654
74962
|
url: diagnostic.url,
|
|
74655
|
-
line:
|
|
74656
|
-
column:
|
|
74963
|
+
line: primaryLineNumber,
|
|
74964
|
+
column: primaryColumnNumber,
|
|
74657
74965
|
...primarySpan ? {
|
|
74658
74966
|
offset: primarySpan.offset,
|
|
74659
74967
|
length: primarySpan.length,
|
|
@@ -74841,7 +75149,11 @@ const isParallelismRelatedSpawnError = (error) => {
|
|
|
74841
75149
|
* loop with a slimmer config in that case.
|
|
74842
75150
|
*/
|
|
74843
75151
|
const spawnLintBatches = async (input) => {
|
|
74844
|
-
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
75152
|
+
const { baseArgs, fileBatches, rootDirectory, nodeBinaryPath, project, sourcePathByLintPath, onPartialFailure, onFileProgress, spawnTimeoutMs, outputMaxBytes, splitTotalBudgetMs = OXLINT_SPLIT_TOTAL_BUDGET_MS, splitMaxDepth = 8, signal, deadlineEpochMs } = input;
|
|
75153
|
+
const resolveSourcePath = (filePath) => {
|
|
75154
|
+
const absoluteFilePath = Path.isAbsolute(filePath) ? filePath : Path.resolve(rootDirectory, filePath);
|
|
75155
|
+
return sourcePathByLintPath?.get(Path.normalize(absoluteFilePath)) ?? filePath;
|
|
75156
|
+
};
|
|
74845
75157
|
const requestedConcurrency = resolveScanConcurrency(input.concurrency ?? 1);
|
|
74846
75158
|
let rescueDeadlineEpochMs;
|
|
74847
75159
|
const isPastDeadline = () => deadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(deadlineEpochMs) === 0 || rescueDeadlineEpochMs !== void 0 && remainingDeadlineBudgetMs(rescueDeadlineEpochMs) === 0;
|
|
@@ -74861,7 +75173,7 @@ const spawnLintBatches = async (input) => {
|
|
|
74861
75173
|
}
|
|
74862
75174
|
const batchArgs = [...baseArgs, ...batch];
|
|
74863
75175
|
try {
|
|
74864
|
-
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory);
|
|
75176
|
+
return parseOxlintOutput(await spawnOxlint(batchArgs, rootDirectory, nodeBinaryPath, spawnTimeoutMs, outputMaxBytes, signal), project, rootDirectory, sourcePathByLintPath);
|
|
74865
75177
|
} catch (error) {
|
|
74866
75178
|
if (!isSplittableReactDoctorError(error)) throw error;
|
|
74867
75179
|
if (isPastDeadline()) {
|
|
@@ -74967,10 +75279,12 @@ const spawnLintBatches = async (input) => {
|
|
|
74967
75279
|
onPartialFailure(buildMessage(`${skippedFiles.slice(0, 3).join(", ")}${skippedFiles.length > 3 ? `, +${skippedFiles.length - 3} more` : ""}`));
|
|
74968
75280
|
};
|
|
74969
75281
|
const reasonHint = firstDropReason ? ` — first failure: ${firstDropReason}` : "";
|
|
74970
|
-
|
|
74971
|
-
|
|
75282
|
+
const droppedSourceFiles = [...new Set(droppedFiles.map(resolveSourcePath))];
|
|
75283
|
+
const deadlineSkippedSourceFiles = [...new Set(outcome.deadlineSkippedFiles.map(resolveSourcePath))];
|
|
75284
|
+
reportSkippedFiles(droppedSourceFiles, (fileListPreview) => `${droppedSourceFiles.length} file(s) failed to lint and were skipped (${fileListPreview})${reasonHint}`);
|
|
75285
|
+
reportSkippedFiles(deadlineSkippedSourceFiles, (fileListPreview) => `${deadlineSkippedSourceFiles.length} file(s) skipped — max scan duration reached before they were linted (${fileListPreview})`);
|
|
74972
75286
|
const unavailableFiles = new Set([...droppedFiles, ...outcome.deadlineSkippedFiles]);
|
|
74973
|
-
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)))].sort());
|
|
75287
|
+
input.onAnalyzedFiles?.([...new Set(fileBatches.flat().filter((filePath) => !unavailableFiles.has(filePath)).map(resolveSourcePath))].sort());
|
|
74974
75288
|
return dedupeDiagnostics(diagnostics);
|
|
74975
75289
|
};
|
|
74976
75290
|
let didValidate = false;
|
|
@@ -75069,6 +75383,266 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
75069
75383
|
}
|
|
75070
75384
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
75071
75385
|
};
|
|
75386
|
+
const THREE_MODULE_IMPORT_PATTERN = /\b(?:from\s*|import\s*(?:\(\s*)?|require\s*\(\s*)["']three(?:\/[^"']*)?["']/;
|
|
75387
|
+
const containsThreeModuleImport = (sourceText) => THREE_MODULE_IMPORT_PATTERN.test(sourceText);
|
|
75388
|
+
const COMMENT_OPEN = "<!--";
|
|
75389
|
+
const COMMENT_CLOSE = "-->";
|
|
75390
|
+
const FRONTMATTER_FENCE = "---";
|
|
75391
|
+
const SCRIPT_TAG_NAME = "script";
|
|
75392
|
+
const SCRIPT_OPEN = `<${SCRIPT_TAG_NAME}`;
|
|
75393
|
+
const SCRIPT_CLOSE = `</${SCRIPT_TAG_NAME}`;
|
|
75394
|
+
const TEMPLATE_TAG_NAME = "template";
|
|
75395
|
+
const TEMPLATE_CLOSE = `</${TEMPLATE_TAG_NAME}`;
|
|
75396
|
+
const JAVASCRIPT_MIME_TYPES = new Set([
|
|
75397
|
+
"application/ecmascript",
|
|
75398
|
+
"application/javascript",
|
|
75399
|
+
"application/x-ecmascript",
|
|
75400
|
+
"application/x-javascript",
|
|
75401
|
+
"text/ecmascript",
|
|
75402
|
+
"text/javascript",
|
|
75403
|
+
"text/javascript1.0",
|
|
75404
|
+
"text/javascript1.1",
|
|
75405
|
+
"text/javascript1.2",
|
|
75406
|
+
"text/javascript1.3",
|
|
75407
|
+
"text/javascript1.4",
|
|
75408
|
+
"text/javascript1.5",
|
|
75409
|
+
"text/jscript",
|
|
75410
|
+
"text/livescript",
|
|
75411
|
+
"text/x-ecmascript",
|
|
75412
|
+
"text/x-javascript"
|
|
75413
|
+
]);
|
|
75414
|
+
const RAW_TEXT_TAG_NAMES = new Set([
|
|
75415
|
+
"iframe",
|
|
75416
|
+
"noembed",
|
|
75417
|
+
"noframes",
|
|
75418
|
+
"noscript",
|
|
75419
|
+
"style",
|
|
75420
|
+
"textarea",
|
|
75421
|
+
"title",
|
|
75422
|
+
"xmp"
|
|
75423
|
+
]);
|
|
75424
|
+
const PLAINTEXT_TAG_NAME = "plaintext";
|
|
75425
|
+
const TAG_OPEN_UTF8_BYTE = "<".charCodeAt(0);
|
|
75426
|
+
const TAG_CLOSE_UTF8_BYTE = ">".charCodeAt(0);
|
|
75427
|
+
const SINGLE_QUOTE_UTF8_BYTE = "'".charCodeAt(0);
|
|
75428
|
+
const DOUBLE_QUOTE_UTF8_BYTE = "\"".charCodeAt(0);
|
|
75429
|
+
const ATTRIBUTE_ASSIGNMENT_UTF8_BYTE = "=".charCodeAt(0);
|
|
75430
|
+
const TAG_SELF_CLOSE_UTF8_BYTE = "/".charCodeAt(0);
|
|
75431
|
+
const TAB_UTF8_BYTE = " ".charCodeAt(0);
|
|
75432
|
+
const FORM_FEED_UTF8_BYTE = "\f".charCodeAt(0);
|
|
75433
|
+
const isHtmlWhitespace = (byte) => byte === TAB_UTF8_BYTE || byte === 10 || byte === FORM_FEED_UTF8_BYTE || byte === 13 || byte === 32;
|
|
75434
|
+
const matchesAsciiCaseInsensitive = (sourceBuffer, startByte, expected) => {
|
|
75435
|
+
if (startByte + expected.length > sourceBuffer.length) return false;
|
|
75436
|
+
for (let expectedIndex = 0; expectedIndex < expected.length; expectedIndex++) {
|
|
75437
|
+
const sourceByte = sourceBuffer[startByte + expectedIndex];
|
|
75438
|
+
if (sourceByte === void 0 || String.fromCharCode(sourceByte).toLowerCase() !== expected[expectedIndex]) return false;
|
|
75439
|
+
}
|
|
75440
|
+
return true;
|
|
75441
|
+
};
|
|
75442
|
+
const isTagBoundary = (byte) => byte === TAG_CLOSE_UTF8_BYTE || byte === TAG_SELF_CLOSE_UTF8_BYTE || isHtmlWhitespace(byte);
|
|
75443
|
+
const isPotentialTagStart = (byte) => {
|
|
75444
|
+
if (byte === void 0) return false;
|
|
75445
|
+
return /[A-Za-z!/?]/.test(String.fromCharCode(byte));
|
|
75446
|
+
};
|
|
75447
|
+
const findLineEnd = (sourceBuffer, lineStartByte) => {
|
|
75448
|
+
let byteIndex = lineStartByte;
|
|
75449
|
+
while (byteIndex < sourceBuffer.length && sourceBuffer[byteIndex] !== 10 && sourceBuffer[byteIndex] !== 13) byteIndex++;
|
|
75450
|
+
return byteIndex;
|
|
75451
|
+
};
|
|
75452
|
+
const findNextLineStart = (sourceBuffer, lineStartByte) => {
|
|
75453
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
75454
|
+
if (sourceBuffer[lineEndByte] === 13 && sourceBuffer[lineEndByte + 1] === 10) return lineEndByte + 2;
|
|
75455
|
+
return Math.min(lineEndByte + 1, sourceBuffer.length);
|
|
75456
|
+
};
|
|
75457
|
+
const isFrontmatterFenceLine = (sourceBuffer, lineStartByte) => {
|
|
75458
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, lineStartByte, FRONTMATTER_FENCE)) return false;
|
|
75459
|
+
const lineEndByte = findLineEnd(sourceBuffer, lineStartByte);
|
|
75460
|
+
for (let byteIndex = lineStartByte + 3; byteIndex < lineEndByte; byteIndex++) if (!isHtmlWhitespace(sourceBuffer[byteIndex])) return false;
|
|
75461
|
+
return true;
|
|
75462
|
+
};
|
|
75463
|
+
const findFrontmatterEnd = (sourceBuffer) => {
|
|
75464
|
+
if (!isFrontmatterFenceLine(sourceBuffer, 0)) return 0;
|
|
75465
|
+
const openingFenceEndByte = findLineEnd(sourceBuffer, 0);
|
|
75466
|
+
let lineStartByte = findNextLineStart(sourceBuffer, 0);
|
|
75467
|
+
while (lineStartByte < sourceBuffer.length) {
|
|
75468
|
+
if (isFrontmatterFenceLine(sourceBuffer, lineStartByte)) return findLineEnd(sourceBuffer, lineStartByte);
|
|
75469
|
+
lineStartByte = findNextLineStart(sourceBuffer, lineStartByte);
|
|
75470
|
+
}
|
|
75471
|
+
return openingFenceEndByte;
|
|
75472
|
+
};
|
|
75473
|
+
const maskByteRange = (maskedBuffer, startByte, endByte) => {
|
|
75474
|
+
for (let byteIndex = startByte; byteIndex < endByte; byteIndex++) {
|
|
75475
|
+
const byte = maskedBuffer[byteIndex];
|
|
75476
|
+
if (byte !== 10 && byte !== 13) maskedBuffer[byteIndex] = 32;
|
|
75477
|
+
}
|
|
75478
|
+
};
|
|
75479
|
+
const readStartTagName = (sourceBuffer, tagStartByte) => {
|
|
75480
|
+
const firstNameByte = sourceBuffer[tagStartByte + 1];
|
|
75481
|
+
if (firstNameByte === void 0 || !/[A-Za-z]/.test(String.fromCharCode(firstNameByte))) return null;
|
|
75482
|
+
let nameEndByte = tagStartByte + 2;
|
|
75483
|
+
while (nameEndByte < sourceBuffer.length && /[A-Za-z0-9:-]/.test(String.fromCharCode(sourceBuffer[nameEndByte] ?? 32))) nameEndByte++;
|
|
75484
|
+
return sourceBuffer.subarray(tagStartByte + 1, nameEndByte).toString("ascii").toLowerCase();
|
|
75485
|
+
};
|
|
75486
|
+
const findTagEnd = (sourceBuffer, startByte) => {
|
|
75487
|
+
let quoteByte = null;
|
|
75488
|
+
for (let byteIndex = startByte; byteIndex < sourceBuffer.length; byteIndex++) {
|
|
75489
|
+
const byte = sourceBuffer[byteIndex];
|
|
75490
|
+
if (quoteByte !== null) {
|
|
75491
|
+
if (byte === quoteByte) quoteByte = null;
|
|
75492
|
+
continue;
|
|
75493
|
+
}
|
|
75494
|
+
if (byte === SINGLE_QUOTE_UTF8_BYTE || byte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
75495
|
+
quoteByte = byte;
|
|
75496
|
+
continue;
|
|
75497
|
+
}
|
|
75498
|
+
if (byte === TAG_CLOSE_UTF8_BYTE) return byteIndex;
|
|
75499
|
+
}
|
|
75500
|
+
return sourceBuffer.length;
|
|
75501
|
+
};
|
|
75502
|
+
const parseScriptAttributes = (sourceBuffer, attributesStartByte, tagEndByte) => {
|
|
75503
|
+
let byteIndex = attributesStartByte;
|
|
75504
|
+
let hasSource = false;
|
|
75505
|
+
let language = null;
|
|
75506
|
+
let scriptType = null;
|
|
75507
|
+
while (byteIndex < tagEndByte) {
|
|
75508
|
+
while (byteIndex < tagEndByte && (isHtmlWhitespace(sourceBuffer[byteIndex]) || sourceBuffer[byteIndex] === TAG_SELF_CLOSE_UTF8_BYTE)) byteIndex++;
|
|
75509
|
+
const attributeNameStartByte = byteIndex;
|
|
75510
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== ATTRIBUTE_ASSIGNMENT_UTF8_BYTE && sourceBuffer[byteIndex] !== TAG_SELF_CLOSE_UTF8_BYTE) byteIndex++;
|
|
75511
|
+
const attributeName = sourceBuffer.subarray(attributeNameStartByte, byteIndex).toString("ascii").toLowerCase();
|
|
75512
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
75513
|
+
let attributeValue = "";
|
|
75514
|
+
if (sourceBuffer[byteIndex] === ATTRIBUTE_ASSIGNMENT_UTF8_BYTE) {
|
|
75515
|
+
byteIndex++;
|
|
75516
|
+
while (byteIndex < tagEndByte && isHtmlWhitespace(sourceBuffer[byteIndex])) byteIndex++;
|
|
75517
|
+
const quoteByte = sourceBuffer[byteIndex];
|
|
75518
|
+
if (quoteByte === SINGLE_QUOTE_UTF8_BYTE || quoteByte === DOUBLE_QUOTE_UTF8_BYTE) {
|
|
75519
|
+
const valueStartByte = byteIndex + 1;
|
|
75520
|
+
byteIndex = valueStartByte;
|
|
75521
|
+
while (byteIndex < tagEndByte && sourceBuffer[byteIndex] !== quoteByte) byteIndex++;
|
|
75522
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
75523
|
+
if (byteIndex < tagEndByte) byteIndex++;
|
|
75524
|
+
} else {
|
|
75525
|
+
const valueStartByte = byteIndex;
|
|
75526
|
+
while (byteIndex < tagEndByte && !isHtmlWhitespace(sourceBuffer[byteIndex]) && sourceBuffer[byteIndex] !== TAG_CLOSE_UTF8_BYTE) byteIndex++;
|
|
75527
|
+
attributeValue = sourceBuffer.subarray(valueStartByte, byteIndex).toString("utf8");
|
|
75528
|
+
}
|
|
75529
|
+
}
|
|
75530
|
+
if (attributeName === "src") hasSource = true;
|
|
75531
|
+
else if (attributeName === "type" && scriptType === null) scriptType = attributeValue;
|
|
75532
|
+
else if (attributeName === "language" && language === null) language = attributeValue;
|
|
75533
|
+
}
|
|
75534
|
+
return {
|
|
75535
|
+
hasSource,
|
|
75536
|
+
language,
|
|
75537
|
+
type: scriptType
|
|
75538
|
+
};
|
|
75539
|
+
};
|
|
75540
|
+
const isExecutableScript = (attributes) => {
|
|
75541
|
+
if (attributes.hasSource) return false;
|
|
75542
|
+
const type = attributes.type?.trim().toLowerCase() ?? "";
|
|
75543
|
+
if (type !== "") {
|
|
75544
|
+
const mimeType = type.split(";")[0]?.trim() ?? "";
|
|
75545
|
+
return mimeType === "module" || JAVASCRIPT_MIME_TYPES.has(mimeType);
|
|
75546
|
+
}
|
|
75547
|
+
const language = attributes.language?.trim().toLowerCase() ?? "";
|
|
75548
|
+
return language === "" || JAVASCRIPT_MIME_TYPES.has(`text/${language}`);
|
|
75549
|
+
};
|
|
75550
|
+
const findElementClose = (sourceBuffer, startByte, tagName) => {
|
|
75551
|
+
const closeTagStart = `</${tagName}`;
|
|
75552
|
+
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;
|
|
75553
|
+
return sourceBuffer.length;
|
|
75554
|
+
};
|
|
75555
|
+
const prepareHtmlScriptSource = (sourceBuffer) => {
|
|
75556
|
+
const frontmatterEndByte = findFrontmatterEnd(sourceBuffer);
|
|
75557
|
+
let maskedBuffer = frontmatterEndByte > 0 ? Buffer.from(sourceBuffer) : null;
|
|
75558
|
+
if (maskedBuffer !== null) maskByteRange(maskedBuffer, 0, frontmatterEndByte);
|
|
75559
|
+
const executableScriptBodies = [];
|
|
75560
|
+
let byteIndex = frontmatterEndByte;
|
|
75561
|
+
let templateDepth = 0;
|
|
75562
|
+
while (byteIndex < sourceBuffer.length) {
|
|
75563
|
+
if (sourceBuffer[byteIndex] !== TAG_OPEN_UTF8_BYTE) {
|
|
75564
|
+
byteIndex++;
|
|
75565
|
+
continue;
|
|
75566
|
+
}
|
|
75567
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, COMMENT_OPEN)) {
|
|
75568
|
+
const commentEndByte = sourceBuffer.indexOf(COMMENT_CLOSE, byteIndex + 4);
|
|
75569
|
+
byteIndex = commentEndByte === -1 ? sourceBuffer.length : commentEndByte + 3;
|
|
75570
|
+
continue;
|
|
75571
|
+
}
|
|
75572
|
+
if (matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, TEMPLATE_CLOSE) && isTagBoundary(sourceBuffer[byteIndex + TEMPLATE_CLOSE.length])) {
|
|
75573
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + TEMPLATE_CLOSE.length);
|
|
75574
|
+
if (templateDepth > 0) templateDepth--;
|
|
75575
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
75576
|
+
continue;
|
|
75577
|
+
}
|
|
75578
|
+
if (!matchesAsciiCaseInsensitive(sourceBuffer, byteIndex, SCRIPT_OPEN) || !isTagBoundary(sourceBuffer[byteIndex + SCRIPT_OPEN.length])) {
|
|
75579
|
+
if (!isPotentialTagStart(sourceBuffer[byteIndex + 1])) {
|
|
75580
|
+
byteIndex++;
|
|
75581
|
+
continue;
|
|
75582
|
+
}
|
|
75583
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + 1);
|
|
75584
|
+
const tagName = readStartTagName(sourceBuffer, byteIndex);
|
|
75585
|
+
if (tagName === PLAINTEXT_TAG_NAME) break;
|
|
75586
|
+
if (tagName === TEMPLATE_TAG_NAME) templateDepth++;
|
|
75587
|
+
if (tagName !== null && RAW_TEXT_TAG_NAMES.has(tagName)) {
|
|
75588
|
+
const closeTagStartByte = findElementClose(sourceBuffer, tagEndByte + 1, tagName);
|
|
75589
|
+
if (closeTagStartByte === sourceBuffer.length) break;
|
|
75590
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, closeTagStartByte + tagName.length + 2);
|
|
75591
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
75592
|
+
continue;
|
|
75593
|
+
}
|
|
75594
|
+
byteIndex = Math.min(tagEndByte + 1, sourceBuffer.length);
|
|
75595
|
+
continue;
|
|
75596
|
+
}
|
|
75597
|
+
const tagEndByte = findTagEnd(sourceBuffer, byteIndex + SCRIPT_OPEN.length);
|
|
75598
|
+
if (tagEndByte === sourceBuffer.length) break;
|
|
75599
|
+
const bodyStartByte = tagEndByte + 1;
|
|
75600
|
+
const bodyEndByte = findElementClose(sourceBuffer, bodyStartByte, SCRIPT_TAG_NAME);
|
|
75601
|
+
const attributes = parseScriptAttributes(sourceBuffer, byteIndex + SCRIPT_OPEN.length, tagEndByte);
|
|
75602
|
+
if (attributes.hasSource || templateDepth > 0) {
|
|
75603
|
+
maskedBuffer ??= Buffer.from(sourceBuffer);
|
|
75604
|
+
maskByteRange(maskedBuffer, bodyStartByte, bodyEndByte);
|
|
75605
|
+
} else if (isExecutableScript(attributes)) executableScriptBodies.push(sourceBuffer.subarray(bodyStartByte, bodyEndByte));
|
|
75606
|
+
if (bodyEndByte === sourceBuffer.length) break;
|
|
75607
|
+
const closeTagEndByte = findTagEnd(sourceBuffer, bodyEndByte + SCRIPT_CLOSE.length);
|
|
75608
|
+
byteIndex = Math.min(closeTagEndByte + 1, sourceBuffer.length);
|
|
75609
|
+
}
|
|
75610
|
+
return {
|
|
75611
|
+
executableScriptBodies,
|
|
75612
|
+
lintBuffer: maskedBuffer ?? sourceBuffer
|
|
75613
|
+
};
|
|
75614
|
+
};
|
|
75615
|
+
const prepareHtmlLintSources = (rootDirectory, temporaryDirectory, candidateFiles) => {
|
|
75616
|
+
const lintFiles = [];
|
|
75617
|
+
const sourcePathByLintPath = /* @__PURE__ */ new Map();
|
|
75618
|
+
const sizeByLintPath = /* @__PURE__ */ new Map();
|
|
75619
|
+
const htmlSourcesDirectory = Path.join(temporaryDirectory, "html-sources");
|
|
75620
|
+
let htmlFileIndex = 0;
|
|
75621
|
+
let hasThreeModuleImport = false;
|
|
75622
|
+
for (const candidateFile of candidateFiles) {
|
|
75623
|
+
if (!HTML_FILE_PATTERN.test(candidateFile)) {
|
|
75624
|
+
lintFiles.push(candidateFile);
|
|
75625
|
+
continue;
|
|
75626
|
+
}
|
|
75627
|
+
const absoluteSourcePath = Path.isAbsolute(candidateFile) ? candidateFile : Path.resolve(rootDirectory, candidateFile);
|
|
75628
|
+
const sourceBuffer = NFS.readFileSync(absoluteSourcePath);
|
|
75629
|
+
const { executableScriptBodies, lintBuffer } = prepareHtmlScriptSource(sourceBuffer);
|
|
75630
|
+
if (htmlFileIndex === 0) NFS.mkdirSync(htmlSourcesDirectory, { recursive: true });
|
|
75631
|
+
const lintPath = Path.join(htmlSourcesDirectory, `${htmlFileIndex}.astro`);
|
|
75632
|
+
NFS.writeFileSync(lintPath, lintBuffer);
|
|
75633
|
+
lintFiles.push(lintPath);
|
|
75634
|
+
sourcePathByLintPath.set(Path.resolve(lintPath), candidateFile);
|
|
75635
|
+
sizeByLintPath.set(lintPath, sourceBuffer.length);
|
|
75636
|
+
hasThreeModuleImport ||= executableScriptBodies.some((scriptBody) => containsThreeModuleImport(scriptBody.toString("utf8")));
|
|
75637
|
+
htmlFileIndex++;
|
|
75638
|
+
}
|
|
75639
|
+
return {
|
|
75640
|
+
lintFiles,
|
|
75641
|
+
sourcePathByLintPath,
|
|
75642
|
+
sizeByLintPath,
|
|
75643
|
+
hasThreeModuleImport
|
|
75644
|
+
};
|
|
75645
|
+
};
|
|
75072
75646
|
/**
|
|
75073
75647
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
75074
75648
|
* the runner: once for the primary scan, once for the
|
|
@@ -75229,6 +75803,8 @@ const reactHooksJsPluginDropNote = (error) => {
|
|
|
75229
75803
|
const runOxlint = async (options) => {
|
|
75230
75804
|
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;
|
|
75231
75805
|
const serverAuthFunctionNames = Array.isArray(userConfig?.serverAuthFunctionNames) ? userConfig.serverAuthFunctionNames.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
75806
|
+
const runtimeGlobals = Array.isArray(userConfig?.runtimeGlobals) ? userConfig.runtimeGlobals.filter((entry) => typeof entry === "string" && entry.length > 0) : void 0;
|
|
75807
|
+
let unpluginAutoImportGlobalScopes = [];
|
|
75232
75808
|
const severityControls = buildRuleSeverityControls(userConfig);
|
|
75233
75809
|
validateRuleRegistration();
|
|
75234
75810
|
resetManifestCaches();
|
|
@@ -75242,21 +75818,6 @@ const runOxlint = async (options) => {
|
|
|
75242
75818
|
const pluginPath = resolvePluginPath();
|
|
75243
75819
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
75244
75820
|
const userPlugins = includedTags.size > 0 ? [] : resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
75245
|
-
const buildConfig = (overrides) => createOxlintConfig({
|
|
75246
|
-
pluginPath,
|
|
75247
|
-
project,
|
|
75248
|
-
customRulesOnly,
|
|
75249
|
-
extendsPaths: overrides.extendsPaths,
|
|
75250
|
-
ignoredTags,
|
|
75251
|
-
includedTags,
|
|
75252
|
-
includeTagDefaults,
|
|
75253
|
-
serverAuthFunctionNames,
|
|
75254
|
-
severityControls,
|
|
75255
|
-
userPlugins,
|
|
75256
|
-
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
75257
|
-
ruleSelection: overrides.ruleSelection,
|
|
75258
|
-
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
75259
|
-
});
|
|
75260
75821
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
75261
75822
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
75262
75823
|
const configPath = Path.join(configDirectory, "oxlintrc.json");
|
|
@@ -75292,7 +75853,36 @@ const runOxlint = async (options) => {
|
|
|
75292
75853
|
await yieldToEventLoop();
|
|
75293
75854
|
const sizedScanFiles = includePaths === void 0 ? listSourceFilesWithSize(rootDirectory) : null;
|
|
75294
75855
|
const candidateFiles = includePaths !== void 0 ? includePaths : (sizedScanFiles ?? []).map((entry) => entry.path);
|
|
75856
|
+
unpluginAutoImportGlobalScopes = collectUnpluginAutoImportGlobalScopes({
|
|
75857
|
+
rootDirectory,
|
|
75858
|
+
candidateFiles
|
|
75859
|
+
});
|
|
75860
|
+
const preparedHtmlSources = prepareHtmlLintSources(rootDirectory, configDirectory, candidateFiles);
|
|
75861
|
+
const lintFiles = preparedHtmlSources.lintFiles;
|
|
75862
|
+
const hasHtmlFiles = preparedHtmlSources.sourcePathByLintPath.size > 0;
|
|
75863
|
+
const lintProject = !project.hasThree && preparedHtmlSources.hasThreeModuleImport ? {
|
|
75864
|
+
...project,
|
|
75865
|
+
hasThree: true
|
|
75866
|
+
} : project;
|
|
75867
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
75868
|
+
pluginPath,
|
|
75869
|
+
project: lintProject,
|
|
75870
|
+
customRulesOnly,
|
|
75871
|
+
extendsPaths: overrides.extendsPaths,
|
|
75872
|
+
ignoredTags,
|
|
75873
|
+
includedTags,
|
|
75874
|
+
includeTagDefaults,
|
|
75875
|
+
runtimeGlobals,
|
|
75876
|
+
unpluginAutoImportGlobalScopes,
|
|
75877
|
+
serverAuthFunctionNames,
|
|
75878
|
+
severityControls,
|
|
75879
|
+
userPlugins,
|
|
75880
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin,
|
|
75881
|
+
ruleSelection: overrides.ruleSelection,
|
|
75882
|
+
sidecarRuleIdFilter: overrides.sidecarRuleIdFilter
|
|
75883
|
+
});
|
|
75295
75884
|
const sizeByFile = sizedScanFiles !== null && lintBatchOrdering === "cost" ? new Map(sizedScanFiles.map((entry) => [entry.path, entry.sizeBytes])) : null;
|
|
75885
|
+
if (sizeByFile !== null) for (const [lintPath, sizeBytes] of preparedHtmlSources.sizeByLintPath) sizeByFile.set(lintPath, sizeBytes);
|
|
75296
75886
|
const buildFileBatches = (passBaseArgs, passFiles) => sizeByFile !== null ? planLintBatches({
|
|
75297
75887
|
baseArgs: passBaseArgs,
|
|
75298
75888
|
files: passFiles,
|
|
@@ -75321,7 +75911,8 @@ const runOxlint = async (options) => {
|
|
|
75321
75911
|
fileBatches: passFileBatches,
|
|
75322
75912
|
rootDirectory,
|
|
75323
75913
|
nodeBinaryPath,
|
|
75324
|
-
project,
|
|
75914
|
+
project: lintProject,
|
|
75915
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
75325
75916
|
onPartialFailure: reportPartialFailure,
|
|
75326
75917
|
onAnalyzedFiles: (filePaths) => {
|
|
75327
75918
|
analyzedFiles = filePaths;
|
|
@@ -75356,7 +75947,7 @@ const runOxlint = async (options) => {
|
|
|
75356
75947
|
};
|
|
75357
75948
|
}
|
|
75358
75949
|
};
|
|
75359
|
-
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0) {
|
|
75950
|
+
if (perFileLintCacheEnabled && !project.hasReactCompiler && project.hasReactCompilerLintPlugin !== true && extendsPaths.length === 0 && userPlugins.length === 0 && !hasHtmlFiles) {
|
|
75360
75951
|
const rulesetHash = computeRulesetHash({
|
|
75361
75952
|
config: buildConfig({
|
|
75362
75953
|
extendsPaths: [],
|
|
@@ -75514,14 +76105,15 @@ const runOxlint = async (options) => {
|
|
|
75514
76105
|
]);
|
|
75515
76106
|
}
|
|
75516
76107
|
const baseArgs = makeBaseArgs(configPath);
|
|
75517
|
-
const fileBatches = buildFileBatches(baseArgs,
|
|
76108
|
+
const fileBatches = buildFileBatches(baseArgs, lintFiles);
|
|
75518
76109
|
let analyzedFiles = [];
|
|
75519
76110
|
const runBatches = () => spawnLintBatches({
|
|
75520
76111
|
baseArgs,
|
|
75521
76112
|
fileBatches,
|
|
75522
76113
|
rootDirectory,
|
|
75523
76114
|
nodeBinaryPath,
|
|
75524
|
-
project,
|
|
76115
|
+
project: lintProject,
|
|
76116
|
+
sourcePathByLintPath: preparedHtmlSources.sourcePathByLintPath,
|
|
75525
76117
|
onPartialFailure,
|
|
75526
76118
|
onAnalyzedFiles: (filePaths) => {
|
|
75527
76119
|
analyzedFiles = filePaths;
|
|
@@ -77728,7 +78320,7 @@ const makeNoopConsole = () => ({
|
|
|
77728
78320
|
});
|
|
77729
78321
|
//#endregion
|
|
77730
78322
|
//#region src/cli/utils/version.ts
|
|
77731
|
-
const VERSION = "0.9.1-dev.
|
|
78323
|
+
const VERSION = "0.9.1-dev.7ee59d3";
|
|
77732
78324
|
//#endregion
|
|
77733
78325
|
//#region src/cli/utils/json-mode.ts
|
|
77734
78326
|
let context = null;
|
|
@@ -78086,13 +78678,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
78086
78678
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
78087
78679
|
* standard `SENTRY_RELEASE` override.
|
|
78088
78680
|
*/
|
|
78089
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.1-dev.
|
|
78681
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.1-dev.7ee59d3`;
|
|
78090
78682
|
/**
|
|
78091
78683
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
78092
78684
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
78093
78685
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
78094
78686
|
*/
|
|
78095
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.1-dev.
|
|
78687
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.1-dev.7ee59d3") ? "development" : "production");
|
|
78096
78688
|
/**
|
|
78097
78689
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
78098
78690
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -90757,6 +91349,7 @@ const buildScanAttributes = (input) => {
|
|
|
90757
91349
|
rulesDisabled: ruleKeys.filter((key) => ruleOverrides[key] === "off").length,
|
|
90758
91350
|
fileCount: input.result?.scannedFileCount ?? null,
|
|
90759
91351
|
nonJsxFileCount: input.result?.analyzedFiles?.filter((filePath) => !JSX_FILE_PATTERN.test(filePath)).length ?? null,
|
|
91352
|
+
htmlFileCount: input.result?.analyzedFiles?.filter((filePath) => HTML_FILE_PATTERN.test(filePath)).length ?? null,
|
|
90760
91353
|
multilineDiagnosticCount: input.result?.diagnostics.filter((diagnostic) => (diagnostic.endLine ?? diagnostic.line) > diagnostic.line).length ?? null
|
|
90761
91354
|
});
|
|
90762
91355
|
};
|
|
@@ -96810,7 +97403,7 @@ ${highlighter.dim("Learn more:")}
|
|
|
96810
97403
|
${highlighter.info(CI_URL)}
|
|
96811
97404
|
`;
|
|
96812
97405
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
96813
|
-
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
|
|
97406
|
+
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much supported JS/TS and inline HTML script source to scan/report: full (default), files, changed (only new issues vs base), or lines (issues whose source spans touch changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").option("--include-untracked", "with --scope files/changed/lines, also scan ordinary untracked files (respects .gitignore)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
|
|
96814
97407
|
program.action(inspectAction);
|
|
96815
97408
|
program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
|
|
96816
97409
|
program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action((location, options) => whyAction(location, options));
|
|
@@ -96890,4 +97483,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
96890
97483
|
export { toForwardSlashes as A, highlighter as B, buildRulePriorityMap as C, resolveBlockingLevel as D, formatLearnMoreLine as E, isCiEnvironment as F, sync as G, mergeReactDoctorConfigs as H, DIAGNOSTIC_CATEGORY_BUCKETS as I, void_ as K, Progress as L, isUnicodeSupported as M, METRIC as N, isReactDoctorWorkflowInstalled as O, TUI_REPORT_DETAIL_WIDTH_FRACTION as P, Reporter as R, hasLintHardFailure as S, formatFixRecipeLine as T, resolveScanTarget as U, mapWithConcurrency as V, runPromise as W, canAnimateOnboarding as _, resolveCliInspectOptions as a, buildCodeFrame as b, detectLaunchableAgents as c, launchCliAgent as d, isShareOptedOut as f, doctorFace as g, easeOutCubic as h, selectProjects as i, findNearestPackageDirectory as j, recordCount as k, CLI_AGENT_BINARIES as l, printFooter as m, shouldFailScanGate as n, countUniqueScannedFiles as o, inspect as p, succeed$3 as q, discoverWorkspacePackages as r, setUpGitHubActions as s, exitGracefully as t, copyToClipboard as u, computeProjectedScore as v, buildSortedRuleGroups as w, buildNoScoreMessage as x, formatElapsedTime as y, getCategoryImpact as z };
|
|
96891
97484
|
|
|
96892
97485
|
//# sourceMappingURL=cli.js.map
|
|
96893
|
-
//# debugId=
|
|
97486
|
+
//# debugId=7f26fa62-fe0c-5ae0-bc9c-97a0deb50b43
|