react-doctor 0.9.2-dev.3f3197f → 0.9.2-dev.86add14
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/dist/cli.js +372 -134
- package/dist/index.d.ts +8 -2
- package/dist/index.js +80 -40
- package/dist/lsp.js +80 -39
- package/package.json +4 -4
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]="2a10a6ef-ec19-5a23-88d5-c2e4d5e30eec")}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";
|
|
@@ -13,11 +13,11 @@ import * as Crypto from "node:crypto";
|
|
|
13
13
|
import crypto, { createHash, randomUUID } from "node:crypto";
|
|
14
14
|
import { ResolverFactory } from "oxc-resolver";
|
|
15
15
|
import ts from "typescript";
|
|
16
|
+
import * as NodeUrl from "node:url";
|
|
17
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
16
18
|
import * as OS from "node:os";
|
|
17
19
|
import os, { tmpdir } from "node:os";
|
|
18
20
|
import { parseJSON5 } from "confbox";
|
|
19
|
-
import * as NodeUrl from "node:url";
|
|
20
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
21
21
|
import { createJiti } from "jiti";
|
|
22
22
|
import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
|
|
23
23
|
import { gzipSync } from "node:zlib";
|
|
@@ -65596,10 +65596,16 @@ const getTopLevelBinding = (sourceFile, bindingName) => {
|
|
|
65596
65596
|
}
|
|
65597
65597
|
return null;
|
|
65598
65598
|
};
|
|
65599
|
-
const getFunctionLocalBindings = (functionNode, argumentsList) => {
|
|
65599
|
+
const getFunctionLocalBindings = (functionNode, argumentsList, argumentAnalysis, functionAnalysis) => {
|
|
65600
65600
|
const localBindings = /* @__PURE__ */ new Map();
|
|
65601
65601
|
functionNode.parameters.forEach((parameter, parameterIndex) => {
|
|
65602
|
-
if (ts.isIdentifier(parameter.name))
|
|
65602
|
+
if (ts.isIdentifier(parameter.name)) {
|
|
65603
|
+
const argument = argumentsList[parameterIndex];
|
|
65604
|
+
localBindings.set(parameter.name.text, {
|
|
65605
|
+
expression: argument ?? parameter.initializer ?? null,
|
|
65606
|
+
analysis: argument ? argumentAnalysis : functionAnalysis
|
|
65607
|
+
});
|
|
65608
|
+
}
|
|
65603
65609
|
});
|
|
65604
65610
|
return localBindings;
|
|
65605
65611
|
};
|
|
@@ -65735,8 +65741,8 @@ const getStaticConfigValueState = (expression, analysis, visitedExpressions = /*
|
|
|
65735
65741
|
};
|
|
65736
65742
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
65737
65743
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
65738
|
-
const
|
|
65739
|
-
return
|
|
65744
|
+
const localReference = analysis.localBindings.get(unwrappedExpression.text);
|
|
65745
|
+
return localReference?.expression ? getStaticConfigValueState(localReference.expression, localReference.analysis, nextVisitedExpressions) : null;
|
|
65740
65746
|
}
|
|
65741
65747
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
65742
65748
|
return topLevelBinding && ts.isExpression(topLevelBinding) ? getStaticConfigValueState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
@@ -65778,8 +65784,8 @@ const getReactCompilerFlagState = (expression, analysis, visitedExpressions = /*
|
|
|
65778
65784
|
const assignedBinding = getAssignedPropertyInitializer(unwrappedExpression, "reactCompiler");
|
|
65779
65785
|
if (assignedBinding.wasFound && assignedBinding.initializer) return { isEnabled: !isStaticallyDisabledConfigExpression(assignedBinding.initializer, analysis) };
|
|
65780
65786
|
if (analysis.localBindings.has(unwrappedExpression.text)) {
|
|
65781
|
-
const
|
|
65782
|
-
return
|
|
65787
|
+
const localReference = analysis.localBindings.get(unwrappedExpression.text);
|
|
65788
|
+
return localReference?.expression ? getReactCompilerFlagState(localReference.expression, localReference.analysis, nextVisitedExpressions) : null;
|
|
65783
65789
|
}
|
|
65784
65790
|
const topLevelBinding = getTopLevelBinding(analysis.sourceFile, unwrappedExpression.text);
|
|
65785
65791
|
return topLevelBinding && ts.isExpression(topLevelBinding) ? getReactCompilerFlagState(topLevelBinding, analysis, nextVisitedExpressions) : null;
|
|
@@ -65802,8 +65808,8 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
|
|
|
65802
65808
|
visitedExpressions.add(resolvedExpression);
|
|
65803
65809
|
if (ts.isIdentifier(resolvedExpression)) {
|
|
65804
65810
|
if (analysis.localBindings.has(resolvedExpression.text)) {
|
|
65805
|
-
const
|
|
65806
|
-
return
|
|
65811
|
+
const localReference = analysis.localBindings.get(resolvedExpression.text);
|
|
65812
|
+
return localReference?.expression ? getSelectedObjectProperty(localReference.expression, propertyName, localReference.analysis, visitedExpressions) : null;
|
|
65807
65813
|
}
|
|
65808
65814
|
const scopedBinding = getScopedConfigBinding(resolvedExpression);
|
|
65809
65815
|
if (scopedBinding.wasFound) return scopedBinding.initializer ? getSelectedObjectProperty(scopedBinding.initializer, propertyName, analysis, visitedExpressions) : null;
|
|
@@ -65812,9 +65818,18 @@ const getSelectedObjectProperty = (expression, propertyName, analysis, visitedEx
|
|
|
65812
65818
|
}
|
|
65813
65819
|
if (!ts.isObjectLiteralExpression(resolvedExpression)) return null;
|
|
65814
65820
|
for (const property of [...resolvedExpression.properties].reverse()) {
|
|
65815
|
-
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return
|
|
65816
|
-
|
|
65817
|
-
|
|
65821
|
+
if (ts.isPropertyAssignment(property) && getStaticPropertyName$2(property.name) === propertyName) return {
|
|
65822
|
+
node: property.initializer,
|
|
65823
|
+
analysis
|
|
65824
|
+
};
|
|
65825
|
+
if (ts.isMethodDeclaration(property) && getStaticPropertyName$2(property.name) === propertyName) return {
|
|
65826
|
+
node: property,
|
|
65827
|
+
analysis
|
|
65828
|
+
};
|
|
65829
|
+
if (ts.isShorthandPropertyAssignment(property) && property.name.text === propertyName) return {
|
|
65830
|
+
node: property.name,
|
|
65831
|
+
analysis
|
|
65832
|
+
};
|
|
65818
65833
|
if (ts.isSpreadAssignment(property)) {
|
|
65819
65834
|
const spreadProperty = getSelectedObjectProperty(property.expression, propertyName, analysis, visitedExpressions);
|
|
65820
65835
|
if (spreadProperty) return spreadProperty;
|
|
@@ -65827,8 +65842,8 @@ const configExpressionMayDefineProperty = (expression, propertyName, analysis) =
|
|
|
65827
65842
|
while (ts.isParenthesizedExpression(resolvedExpression) || ts.isAsExpression(resolvedExpression) || ts.isTypeAssertionExpression(resolvedExpression) || ts.isSatisfiesExpression(resolvedExpression) || ts.isNonNullExpression(resolvedExpression)) resolvedExpression = resolvedExpression.expression;
|
|
65828
65843
|
if (ts.isIdentifier(resolvedExpression)) {
|
|
65829
65844
|
if (analysis.localBindings.has(resolvedExpression.text)) {
|
|
65830
|
-
const
|
|
65831
|
-
return
|
|
65845
|
+
const localReference = analysis.localBindings.get(resolvedExpression.text);
|
|
65846
|
+
return localReference?.expression ? configExpressionMayDefineProperty(localReference.expression, propertyName, localReference.analysis) : true;
|
|
65832
65847
|
}
|
|
65833
65848
|
const scopedBinding = getScopedConfigBinding(resolvedExpression);
|
|
65834
65849
|
if (scopedBinding.wasFound) return scopedBinding.initializer ? configExpressionMayDefineProperty(scopedBinding.initializer, propertyName, analysis) : true;
|
|
@@ -65912,15 +65927,15 @@ const getReExportedConfigModules = (sourceFile, exportName) => {
|
|
|
65912
65927
|
}
|
|
65913
65928
|
return bindings;
|
|
65914
65929
|
};
|
|
65915
|
-
const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = []) => {
|
|
65930
|
+
const analyzeConfigModuleExport = (filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
|
|
65916
65931
|
if (!isFile(filePath) || importDepth > 4) return false;
|
|
65917
65932
|
const moduleVisitKey = `${filePath}:${exportName}:${allowCompilerTransform}`;
|
|
65918
65933
|
if (visitedModules.has(moduleVisitKey)) return false;
|
|
65919
65934
|
const nextVisitedModules = new Set(visitedModules);
|
|
65920
65935
|
nextVisitedModules.add(moduleVisitKey);
|
|
65921
|
-
return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList);
|
|
65936
|
+
return analyzeConfigSourceFileExport(parseConfigSourceFile(filePath, NFS.readFileSync(filePath, "utf-8")), filePath, exportName, allowCompilerTransform, importDepth, nextVisitedModules, argumentsList, argumentAnalysis);
|
|
65922
65937
|
};
|
|
65923
|
-
const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = []) => {
|
|
65938
|
+
const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCompilerTransform, importDepth, visitedModules, argumentsList = [], argumentAnalysis) => {
|
|
65924
65939
|
const analysis = {
|
|
65925
65940
|
filePath,
|
|
65926
65941
|
sourceFile,
|
|
@@ -65930,14 +65945,27 @@ const analyzeConfigSourceFileExport = (sourceFile, filePath, exportName, allowCo
|
|
|
65930
65945
|
localBindings: /* @__PURE__ */ new Map(),
|
|
65931
65946
|
activeFunctions: /* @__PURE__ */ new Set()
|
|
65932
65947
|
};
|
|
65948
|
+
const resolvedArgumentAnalysis = argumentAnalysis ?? analysis;
|
|
65933
65949
|
const exportedConfigNodes = getExportedConfigNodes(sourceFile, exportName);
|
|
65934
|
-
return exportedConfigNodes.some((node) =>
|
|
65950
|
+
return exportedConfigNodes.some((node) => {
|
|
65951
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) return analyzeConfigFunction(node, analysis, allowCompilerTransform, argumentsList, resolvedArgumentAnalysis);
|
|
65952
|
+
if (argumentsList.length > 0 && ts.isIdentifier(node)) {
|
|
65953
|
+
const topLevelBinding = getTopLevelBinding(sourceFile, node.text);
|
|
65954
|
+
if (topLevelBinding && ts.isFunctionLike(topLevelBinding)) return analyzeConfigFunction(topLevelBinding, analysis, allowCompilerTransform, argumentsList, resolvedArgumentAnalysis);
|
|
65955
|
+
const importBinding = getImportBinding(sourceFile, node.text);
|
|
65956
|
+
if (importBinding) {
|
|
65957
|
+
const importedFilePath = resolveImportedConfigFile(filePath, importBinding.moduleSpecifier);
|
|
65958
|
+
return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, importBinding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList, resolvedArgumentAnalysis));
|
|
65959
|
+
}
|
|
65960
|
+
}
|
|
65961
|
+
return analyzeConfigNode(node, analysis, allowCompilerTransform);
|
|
65962
|
+
}) || getReExportedConfigModules(sourceFile, exportName).some((binding) => {
|
|
65935
65963
|
if (exportedConfigNodes.length > 0 && binding.isNamespace) return false;
|
|
65936
65964
|
const importedFilePath = resolveImportedConfigFile(filePath, binding.moduleSpecifier);
|
|
65937
|
-
return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, binding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList));
|
|
65965
|
+
return Boolean(importedFilePath && analyzeConfigModuleExport(importedFilePath, binding.exportName, allowCompilerTransform, importDepth + 1, visitedModules, argumentsList, resolvedArgumentAnalysis));
|
|
65938
65966
|
});
|
|
65939
65967
|
};
|
|
65940
|
-
const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, argumentsList = []) => {
|
|
65968
|
+
const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, argumentsList = [], argumentAnalysis = analysis) => {
|
|
65941
65969
|
if (!functionNode.body) return false;
|
|
65942
65970
|
if (analysis.activeFunctions.has(functionNode.pos)) return false;
|
|
65943
65971
|
const activeFunctions = new Set(analysis.activeFunctions);
|
|
@@ -65945,7 +65973,7 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
|
|
|
65945
65973
|
const functionAnalysis = {
|
|
65946
65974
|
...analysis,
|
|
65947
65975
|
visitedNodes: /* @__PURE__ */ new Set(),
|
|
65948
|
-
localBindings: getFunctionLocalBindings(functionNode, argumentsList),
|
|
65976
|
+
localBindings: getFunctionLocalBindings(functionNode, argumentsList, argumentAnalysis, analysis),
|
|
65949
65977
|
activeFunctions
|
|
65950
65978
|
};
|
|
65951
65979
|
if (!ts.isBlock(functionNode.body)) return analyzeConfigNode(functionNode.body, functionAnalysis, allowCompilerTransform);
|
|
@@ -65964,7 +65992,7 @@ const analyzeConfigFunction = (functionNode, analysis, allowCompilerTransform, a
|
|
|
65964
65992
|
const analyzeImportedConfig = ({ analysis, moduleSpecifier, exportName, allowCompilerTransform, argumentsList }) => {
|
|
65965
65993
|
const importedFilePath = resolveImportedConfigFile(analysis.filePath, moduleSpecifier);
|
|
65966
65994
|
if (!importedFilePath) return null;
|
|
65967
|
-
return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList);
|
|
65995
|
+
return analyzeConfigModuleExport(importedFilePath, exportName, allowCompilerTransform, analysis.importDepth + 1, analysis.visitedModules, argumentsList, analysis);
|
|
65968
65996
|
};
|
|
65969
65997
|
const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, isCompilerTransformCollection, excludedPropertyNames) => {
|
|
65970
65998
|
const assignedReactCompiler = getAssignedPropertyInitializer(identifier, "reactCompiler");
|
|
@@ -65978,8 +66006,8 @@ const analyzeConfigIdentifier = (identifier, analysis, allowCompilerTransform, i
|
|
|
65978
66006
|
if (assignedPlugins.wasFound) overriddenPropertyNames.add("plugins");
|
|
65979
66007
|
if (assignedPresets.wasFound) overriddenPropertyNames.add("presets");
|
|
65980
66008
|
if (analysis.localBindings.has(identifier.text)) {
|
|
65981
|
-
const
|
|
65982
|
-
return Boolean(
|
|
66009
|
+
const localReference = analysis.localBindings.get(identifier.text);
|
|
66010
|
+
return Boolean(localReference?.expression && analyzeConfigNode(localReference.expression, localReference.analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
|
|
65983
66011
|
}
|
|
65984
66012
|
const scopedBinding = getScopedConfigBinding(identifier);
|
|
65985
66013
|
if (scopedBinding.wasFound) return Boolean(scopedBinding.initializer && analyzeConfigNode(scopedBinding.initializer, analysis, allowCompilerTransform, isCompilerTransformCollection, overriddenPropertyNames));
|
|
@@ -66045,7 +66073,7 @@ const analyzeConfigCallTarget = (callExpression, analysis, allowCompilerTransfor
|
|
|
66045
66073
|
}
|
|
66046
66074
|
const selectedProperty = getSelectedObjectProperty(target.expression, propertyName, analysis);
|
|
66047
66075
|
if (selectedProperty === null) return null;
|
|
66048
|
-
return ts.isFunctionLike(selectedProperty) ? analyzeConfigFunction(selectedProperty, analysis, allowCompilerTransform, callExpression.arguments) : analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
66076
|
+
return ts.isFunctionLike(selectedProperty.node) ? analyzeConfigFunction(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform, callExpression.arguments, analysis) : analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
|
|
66049
66077
|
};
|
|
66050
66078
|
const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTransformCollection = false, excludedPropertyNames) => {
|
|
66051
66079
|
const excludedPropertiesVisitKey = excludedPropertyNames ? [...excludedPropertyNames].sort().join(",") : "";
|
|
@@ -66145,7 +66173,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
66145
66173
|
if (ts.isIdentifier(node.expression)) {
|
|
66146
66174
|
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
66147
66175
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
66148
|
-
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
66176
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform));
|
|
66149
66177
|
}
|
|
66150
66178
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
66151
66179
|
if (importBinding?.isNamespace) {
|
|
@@ -66159,7 +66187,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
66159
66187
|
return false;
|
|
66160
66188
|
}
|
|
66161
66189
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.name.text, analysis);
|
|
66162
|
-
if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
66190
|
+
if (selectedProperty) return analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
|
|
66163
66191
|
return false;
|
|
66164
66192
|
}
|
|
66165
66193
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
@@ -66168,7 +66196,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
66168
66196
|
if (ts.isIdentifier(node.expression)) {
|
|
66169
66197
|
if (analysis.localBindings.has(node.expression.text) || getScopedConfigBinding(node.expression).wasFound) {
|
|
66170
66198
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
66171
|
-
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform));
|
|
66199
|
+
return Boolean(selectedProperty && analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform));
|
|
66172
66200
|
}
|
|
66173
66201
|
const importBinding = getImportBinding(analysis.sourceFile, node.expression.text);
|
|
66174
66202
|
if (importBinding?.isNamespace) {
|
|
@@ -66181,7 +66209,7 @@ const analyzeConfigNode = (node, analysis, allowCompilerTransform, isCompilerTra
|
|
|
66181
66209
|
}));
|
|
66182
66210
|
}
|
|
66183
66211
|
const selectedProperty = getSelectedObjectProperty(node.expression, node.argumentExpression.text, analysis);
|
|
66184
|
-
if (selectedProperty) return analyzeConfigNode(selectedProperty, analysis, allowCompilerTransform);
|
|
66212
|
+
if (selectedProperty) return analyzeConfigNode(selectedProperty.node, selectedProperty.analysis, allowCompilerTransform);
|
|
66185
66213
|
return false;
|
|
66186
66214
|
}
|
|
66187
66215
|
return analyzeConfigNode(node.expression, analysis, allowCompilerTransform);
|
|
@@ -68558,6 +68586,7 @@ const classifyPackageRole = (filename) => {
|
|
|
68558
68586
|
* Resolves the absolute path to read for a diagnostic's `filePath`,
|
|
68559
68587
|
* accounting for the various shapes oxlint emits:
|
|
68560
68588
|
*
|
|
68589
|
+
* - `file://` URL — decode to an absolute filesystem path.
|
|
68561
68590
|
* - Absolute POSIX (`/abs/path/file.tsx`) — pass through.
|
|
68562
68591
|
* - Absolute Windows (`C:/...` or `C:\...`) — pass through.
|
|
68563
68592
|
* - `./relative` or bare relative — join against `rootDirectory`.
|
|
@@ -68567,6 +68596,7 @@ const classifyPackageRole = (filename) => {
|
|
|
68567
68596
|
* use one canonical resolution path.
|
|
68568
68597
|
*/
|
|
68569
68598
|
const resolveCandidateReadPath = (rootDirectory, filePath) => {
|
|
68599
|
+
if (filePath.startsWith("file://")) return fileURLToPath(filePath);
|
|
68570
68600
|
const normalizedFile = filePath.replace(/\\/g, "/");
|
|
68571
68601
|
if (normalizedFile.startsWith("/") || /^[a-zA-Z]:\//.test(normalizedFile) || /^[a-zA-Z]:\\/.test(filePath)) return filePath;
|
|
68572
68602
|
return `${rootDirectory.replace(/\\/g, "/").replace(/\/$/, "")}/${normalizedFile.replace(/^\.\//, "")}`;
|
|
@@ -72875,7 +72905,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
72875
72905
|
if (argvLengthChars > spawnArgsLengthCap) return yield* foldSpawnFailure(`spawn ENAMETOOLONG (${argvLengthChars} argv chars exceed ${spawnArgsLengthCap})`);
|
|
72876
72906
|
const handle = yield* spawner.spawn(make$1(input.command, [...input.args], {
|
|
72877
72907
|
cwd: input.directory,
|
|
72878
|
-
env: input.
|
|
72908
|
+
env: input.command === "git" ? {
|
|
72909
|
+
...input.env,
|
|
72910
|
+
GIT_DIR: void 0
|
|
72911
|
+
} : input.env,
|
|
72879
72912
|
extendEnv: true
|
|
72880
72913
|
}));
|
|
72881
72914
|
const maxStdoutBytes = input.maxStdoutBytes;
|
|
@@ -73148,7 +73181,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
73148
73181
|
"--diff-filter=ACMR",
|
|
73149
73182
|
"--relative"
|
|
73150
73183
|
]).pipe(map$3((result) => {
|
|
73151
|
-
if (result.status !== 0) return
|
|
73184
|
+
if (result.status !== 0) return null;
|
|
73152
73185
|
return splitNullSeparated(result.stdout);
|
|
73153
73186
|
})),
|
|
73154
73187
|
showStagedContent: (directory, relativePath, options) => runCommand({
|
|
@@ -77571,10 +77604,14 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
77571
77604
|
materializedFiles.push(relativePath);
|
|
77572
77605
|
}
|
|
77573
77606
|
yield* sync(() => {
|
|
77574
|
-
for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
|
|
77575
|
-
const sourcePath = path.join(input.directory, configFilename);
|
|
77576
|
-
const targetPath = path.
|
|
77577
|
-
if (
|
|
77607
|
+
for (const subdirectory of ["", ...input.configSubdirectories ?? []]) for (const configFilename of STAGED_FILES_PROJECT_CONFIG_FILENAMES) {
|
|
77608
|
+
const sourcePath = path.join(input.directory, subdirectory, configFilename);
|
|
77609
|
+
const targetPath = path.resolve(resolvedTempDirectory, subdirectory, configFilename);
|
|
77610
|
+
if (!isPathInsideDirectory(targetPath, resolvedTempDirectory)) continue;
|
|
77611
|
+
if (fs.existsSync(sourcePath) && !fs.existsSync(targetPath)) {
|
|
77612
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
77613
|
+
fs.cpSync(sourcePath, targetPath);
|
|
77614
|
+
}
|
|
77578
77615
|
}
|
|
77579
77616
|
});
|
|
77580
77617
|
return {
|
|
@@ -77607,15 +77644,17 @@ var StagedFiles = class StagedFiles extends Service()("react-doctor/StagedFiles"
|
|
|
77607
77644
|
static layerNode = effect(StagedFiles, gen(function* () {
|
|
77608
77645
|
const git = yield* Git;
|
|
77609
77646
|
return StagedFiles.of({
|
|
77610
|
-
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
|
|
77611
|
-
materialize: ({ directory, stagedFiles, tempDirectory }) => materializeSourceTree({
|
|
77647
|
+
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries === null ? null : entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
|
|
77648
|
+
materialize: ({ directory, stagedFiles, tempDirectory, configSubdirectories }) => materializeSourceTree({
|
|
77612
77649
|
directory,
|
|
77613
77650
|
files: stagedFiles,
|
|
77614
77651
|
tempDirectory,
|
|
77652
|
+
configSubdirectories,
|
|
77615
77653
|
readContent: (relativePath) => git.showStagedContent(directory, relativePath, { maxBufferBytes: GIT_SHOW_MAX_BUFFER_BYTES })
|
|
77616
77654
|
}).pipe(map$3((tree) => ({
|
|
77617
77655
|
tempDirectory: tree.tempDirectory,
|
|
77618
77656
|
stagedFiles: tree.materializedFiles,
|
|
77657
|
+
unmaterializedFiles: tree.unmaterializedFiles,
|
|
77619
77658
|
cleanup: tree.cleanup
|
|
77620
77659
|
})), withSpan("StagedFiles.materialize"))
|
|
77621
77660
|
});
|
|
@@ -77630,6 +77669,7 @@ var StagedFiles = class StagedFiles extends Service()("react-doctor/StagedFiles"
|
|
|
77630
77669
|
materialize: ({ tempDirectory }) => succeed$2({
|
|
77631
77670
|
tempDirectory,
|
|
77632
77671
|
stagedFiles: snapshot.materializedFiles ?? snapshot.sourceFiles ?? [],
|
|
77672
|
+
unmaterializedFiles: [],
|
|
77633
77673
|
cleanup: () => {}
|
|
77634
77674
|
})
|
|
77635
77675
|
}));
|
|
@@ -78339,6 +78379,7 @@ const METRIC = {
|
|
|
78339
78379
|
cliError: "cli.error",
|
|
78340
78380
|
cliEnvironmentError: "cli.env_error",
|
|
78341
78381
|
stagedSnapshotDivergence: "staged.snapshot_divergence",
|
|
78382
|
+
stagedPerProject: "staged.per_project",
|
|
78342
78383
|
projectDetected: "project.detected",
|
|
78343
78384
|
projectPathSelected: "project.path_selected",
|
|
78344
78385
|
projectConfigSelected: "project.config_selected",
|
|
@@ -78424,7 +78465,7 @@ const makeNoopConsole = () => ({
|
|
|
78424
78465
|
});
|
|
78425
78466
|
//#endregion
|
|
78426
78467
|
//#region src/cli/utils/version.ts
|
|
78427
|
-
const VERSION = "0.9.2-dev.
|
|
78468
|
+
const VERSION = "0.9.2-dev.86add14";
|
|
78428
78469
|
//#endregion
|
|
78429
78470
|
//#region src/cli/utils/json-mode.ts
|
|
78430
78471
|
let context = null;
|
|
@@ -78782,13 +78823,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
78782
78823
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
78783
78824
|
* standard `SENTRY_RELEASE` override.
|
|
78784
78825
|
*/
|
|
78785
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.2-dev.
|
|
78826
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.9.2-dev.86add14`;
|
|
78786
78827
|
/**
|
|
78787
78828
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
78788
78829
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
78789
78830
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
78790
78831
|
*/
|
|
78791
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.2-dev.
|
|
78832
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.9.2-dev.86add14") ? "development" : "production");
|
|
78792
78833
|
/**
|
|
78793
78834
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
78794
78835
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -92245,16 +92286,19 @@ const formatClusterLocation = (cluster, resolveSourceRoot, hyperlinks) => {
|
|
|
92245
92286
|
if (!hyperlinks) return `${location}${contextTag}`;
|
|
92246
92287
|
return `${formatHyperlink(location, pathToFileURL(resolveAbsolutePath(lead.filePath, resolveSourceRoot(lead))).href)}${contextTag}`;
|
|
92247
92288
|
};
|
|
92248
|
-
const buildDiagnosticClusterLines = (cluster, resolveSourceRoot, renderCodeFrame, hyperlinks) => {
|
|
92289
|
+
const buildDiagnosticClusterLines = (cluster, resolveSourceRoot, resolveFrameSourceRoot, renderCodeFrame, hyperlinks) => {
|
|
92249
92290
|
const lead = cluster.diagnostics[0];
|
|
92250
92291
|
const isMultiSite = cluster.diagnostics.length > 1;
|
|
92292
|
+
const sourceRoot = resolveSourceRoot(lead);
|
|
92293
|
+
const frameSourceRoot = resolveFrameSourceRoot(lead);
|
|
92294
|
+
const frameFilePath = Path.isAbsolute(lead.filePath) && sourceRoot !== frameSourceRoot ? Path.relative(sourceRoot, lead.filePath) : lead.filePath;
|
|
92251
92295
|
const lines = ["", highlighter.gray(`${TOP_ERROR_DETAIL_INDENT}${formatClusterLocation(cluster, resolveSourceRoot, hyperlinks)}`)];
|
|
92252
92296
|
const codeFrame = renderCodeFrame ? buildCodeFrame({
|
|
92253
|
-
filePath:
|
|
92297
|
+
filePath: frameFilePath,
|
|
92254
92298
|
line: cluster.startLine,
|
|
92255
92299
|
column: isMultiSite ? 0 : lead.column,
|
|
92256
92300
|
endLine: isMultiSite ? cluster.endLine : void 0,
|
|
92257
|
-
rootDirectory:
|
|
92301
|
+
rootDirectory: frameSourceRoot
|
|
92258
92302
|
}) : null;
|
|
92259
92303
|
if (codeFrame) {
|
|
92260
92304
|
const boxInnerWidth = resolveMeasureWidth(8);
|
|
@@ -92267,7 +92311,7 @@ const buildDiagnosticClusterLines = (cluster, resolveSourceRoot, renderCodeFrame
|
|
|
92267
92311
|
}
|
|
92268
92312
|
return lines;
|
|
92269
92313
|
};
|
|
92270
|
-
const buildRuleDetailBlock = (ruleKey, ruleDiagnostics, resolveSourceRoot, renderEverySite, isAgentEnvironment, hyperlinks) => {
|
|
92314
|
+
const buildRuleDetailBlock = (ruleKey, ruleDiagnostics, resolveSourceRoot, resolveFrameSourceRoot, renderEverySite, isAgentEnvironment, hyperlinks) => {
|
|
92271
92315
|
const representative = pickRepresentativeDiagnostic(ruleDiagnostics);
|
|
92272
92316
|
const { severity } = representative;
|
|
92273
92317
|
const trailingBadge = formatTrailingSiteBadge(ruleDiagnostics.length);
|
|
@@ -92289,7 +92333,7 @@ const buildRuleDetailBlock = (ruleKey, ruleDiagnostics, resolveSourceRoot, rende
|
|
|
92289
92333
|
}
|
|
92290
92334
|
const renderCodeFrame = severity === "error";
|
|
92291
92335
|
const sites = renderEverySite ? ruleDiagnostics : [representative];
|
|
92292
|
-
if (!(isCollapsedWarningGroup && representative.help.includes(representative.filePath))) for (const cluster of clusterNearbyDiagnostics(sites)) lines.push(...buildDiagnosticClusterLines(cluster, resolveSourceRoot, renderCodeFrame, hyperlinks));
|
|
92336
|
+
if (!(isCollapsedWarningGroup && representative.help.includes(representative.filePath))) for (const cluster of clusterNearbyDiagnostics(sites)) lines.push(...buildDiagnosticClusterLines(cluster, resolveSourceRoot, resolveFrameSourceRoot, renderCodeFrame, hyperlinks));
|
|
92293
92337
|
return lines;
|
|
92294
92338
|
};
|
|
92295
92339
|
const selectErrorRuleGroups = (diagnostics, rulePriority) => buildSortedRuleGroups(diagnostics.filter((diagnostic) => diagnostic.severity === "error"), rulePriority);
|
|
@@ -92315,7 +92359,7 @@ const buildMigrationScaleAdvisoryLines = (diagnostics) => {
|
|
|
92315
92359
|
return lines;
|
|
92316
92360
|
};
|
|
92317
92361
|
const getTopErrorRuleKeys = (diagnostics, limit, rulePriority) => new Set(selectTopErrorRuleGroups(diagnostics, limit, rulePriority).map(([ruleKey]) => ruleKey));
|
|
92318
|
-
const buildTopErrorsSection = (diagnostics, resolveSourceRoot, hyperlinks, rulePriority) => {
|
|
92362
|
+
const buildTopErrorsSection = (diagnostics, resolveSourceRoot, resolveFrameSourceRoot, hyperlinks, rulePriority) => {
|
|
92319
92363
|
const topRuleGroups = selectErrorRuleGroups(diagnostics, rulePriority).slice(0, 3);
|
|
92320
92364
|
if (topRuleGroups.length === 0) return {
|
|
92321
92365
|
lines: [],
|
|
@@ -92325,7 +92369,7 @@ const buildTopErrorsSection = (diagnostics, resolveSourceRoot, hyperlinks, ruleP
|
|
|
92325
92369
|
const blockOffsets = [];
|
|
92326
92370
|
for (const [ruleKey, ruleDiagnostics] of topRuleGroups) {
|
|
92327
92371
|
blockOffsets.push(lines.length);
|
|
92328
|
-
lines.push(...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, false, false, hyperlinks));
|
|
92372
|
+
lines.push(...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, resolveFrameSourceRoot, false, false, hyperlinks));
|
|
92329
92373
|
lines.push("");
|
|
92330
92374
|
}
|
|
92331
92375
|
return {
|
|
@@ -92363,18 +92407,19 @@ const buildOverviewHeaderLines = (diagnostics) => {
|
|
|
92363
92407
|
* single Effect.forEach over Console.log so failures or fiber
|
|
92364
92408
|
* interruption produce predictable partial output.
|
|
92365
92409
|
*/
|
|
92366
|
-
const printDiagnostics = (diagnostics, isVerbose, sourceRoot, rulePriority, isAgentEnvironment = false, onboarding = {}, hyperlinks = false) => gen(function* () {
|
|
92410
|
+
const printDiagnostics = (diagnostics, isVerbose, sourceRoot, rulePriority, isAgentEnvironment = false, onboarding = {}, hyperlinks = false, frameSourceRoot = sourceRoot) => gen(function* () {
|
|
92367
92411
|
const sectionPause = onboarding.sectionPause ?? void_;
|
|
92368
92412
|
const animateCountUp = onboarding.animateCountUp ?? false;
|
|
92369
92413
|
const resolveSourceRoot = typeof sourceRoot === "function" ? sourceRoot : () => sourceRoot;
|
|
92414
|
+
const resolveFrameSourceRoot = typeof frameSourceRoot === "function" ? frameSourceRoot : () => frameSourceRoot;
|
|
92370
92415
|
let detailLines;
|
|
92371
92416
|
let topErrorBlockOffsets = [];
|
|
92372
92417
|
if (!isVerbose) {
|
|
92373
|
-
const topErrors = buildTopErrorsSection(diagnostics, resolveSourceRoot, hyperlinks, rulePriority);
|
|
92418
|
+
const topErrors = buildTopErrorsSection(diagnostics, resolveSourceRoot, resolveFrameSourceRoot, hyperlinks, rulePriority);
|
|
92374
92419
|
detailLines = topErrors.lines;
|
|
92375
92420
|
topErrorBlockOffsets = topErrors.blockOffsets;
|
|
92376
92421
|
} else detailLines = buildSortedRuleGroups(diagnostics, rulePriority).flatMap(([ruleKey, ruleDiagnostics]) => {
|
|
92377
|
-
return [...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, true, isAgentEnvironment, hyperlinks), ""];
|
|
92422
|
+
return [...buildRuleDetailBlock(ruleKey, ruleDiagnostics, resolveSourceRoot, resolveFrameSourceRoot, true, isAgentEnvironment, hyperlinks), ""];
|
|
92378
92423
|
});
|
|
92379
92424
|
const overflowLine = isVerbose ? void 0 : buildOverflowSummaryLine(diagnostics, rulePriority);
|
|
92380
92425
|
const categoryTallies = buildCategoryDiagnosticGroups(diagnostics, rulePriority).map(buildCategoryTally);
|
|
@@ -93638,26 +93683,26 @@ const finalizeAndRender = (input) => gen(function* () {
|
|
|
93638
93683
|
//#region src/cli/utils/get-staged-files.ts
|
|
93639
93684
|
const stagedFilesLayer = StagedFiles.layerNode.pipe(provide$2(Git.layerNode));
|
|
93640
93685
|
const getStagedSourceFiles = async (directory) => {
|
|
93686
|
+
let stagedSourceFiles;
|
|
93641
93687
|
try {
|
|
93642
|
-
|
|
93688
|
+
stagedSourceFiles = await runPromise(gen(function* () {
|
|
93643
93689
|
return yield* (yield* StagedFiles).discoverSourceFiles(directory);
|
|
93644
|
-
}).pipe(provide(stagedFilesLayer)))
|
|
93690
|
+
}).pipe(provide(stagedFilesLayer)));
|
|
93645
93691
|
} catch (error) {
|
|
93646
93692
|
cliLogger.warn(`Failed to discover staged files: ${messageFromUnknown(error)}`);
|
|
93647
93693
|
return [];
|
|
93648
93694
|
}
|
|
93695
|
+
if (stagedSourceFiles === null) throw new CliInputError("Could not read the git index to list staged files. Check that git can read the index in this directory.");
|
|
93696
|
+
return [...stagedSourceFiles];
|
|
93649
93697
|
};
|
|
93650
|
-
const materializeStagedFiles = async (
|
|
93698
|
+
const materializeStagedFiles = async (input) => {
|
|
93651
93699
|
const snapshot = await runPromise(gen(function* () {
|
|
93652
|
-
return yield* (yield* StagedFiles).materialize(
|
|
93653
|
-
directory,
|
|
93654
|
-
stagedFiles,
|
|
93655
|
-
tempDirectory
|
|
93656
|
-
});
|
|
93700
|
+
return yield* (yield* StagedFiles).materialize(input);
|
|
93657
93701
|
}).pipe(provide(stagedFilesLayer)));
|
|
93658
93702
|
return {
|
|
93659
93703
|
tempDirectory: snapshot.tempDirectory,
|
|
93660
93704
|
stagedFiles: [...snapshot.stagedFiles],
|
|
93705
|
+
unmaterializedFiles: [...snapshot.unmaterializedFiles],
|
|
93661
93706
|
cleanup: snapshot.cleanup
|
|
93662
93707
|
};
|
|
93663
93708
|
};
|
|
@@ -95531,13 +95576,18 @@ const printMultiProjectSummary = (input) => gen(function* () {
|
|
|
95531
95576
|
const scoreDiagnostics = new Set(filterScansForSurface(completedScans, "score"));
|
|
95532
95577
|
const displayedScoreDiagnostics = displayDiagnostics.filter((diagnostic) => scoreDiagnostics.has(diagnostic));
|
|
95533
95578
|
const projectRootByDiagnostic = /* @__PURE__ */ new WeakMap();
|
|
95534
|
-
|
|
95579
|
+
const frameSourceRootByDiagnostic = /* @__PURE__ */ new WeakMap();
|
|
95580
|
+
for (const scan of completedScans) for (const diagnostic of scan.result.diagnostics) {
|
|
95581
|
+
projectRootByDiagnostic.set(diagnostic, scan.result.project.rootDirectory);
|
|
95582
|
+
frameSourceRootByDiagnostic.set(diagnostic, scan.frameSourceRoot ?? scan.result.project.rootDirectory);
|
|
95583
|
+
}
|
|
95535
95584
|
const resolveDiagnosticSourceRoot = (diagnostic) => projectRootByDiagnostic.get(diagnostic) ?? "";
|
|
95585
|
+
const resolveDiagnosticFrameSourceRoot = (diagnostic) => frameSourceRootByDiagnostic.get(diagnostic) ?? resolveDiagnosticSourceRoot(diagnostic);
|
|
95536
95586
|
const totalScannedFileCount = countUniqueScannedFiles(completedScans.map((scan) => scan.result));
|
|
95537
95587
|
yield* log(`${highlighter.success("✔")} Scanned ${totalScannedFileCount} ${totalScannedFileCount === 1 ? "file" : "files"} in ${formatElapsedTime(totalElapsedMilliseconds)}`);
|
|
95538
95588
|
if (displayDiagnostics.length > 0) {
|
|
95539
95589
|
yield* log("");
|
|
95540
|
-
yield* printDiagnostics(displayDiagnostics, verbose, resolveDiagnosticSourceRoot, buildRulePriorityMap(completedScans.map((scan) => scan.result.score)), isCodingAgentEnvironment(), { animateCountUp: animateRender }, shouldRenderHyperlinks(process.stdout));
|
|
95590
|
+
yield* printDiagnostics(displayDiagnostics, verbose, resolveDiagnosticSourceRoot, buildRulePriorityMap(completedScans.map((scan) => scan.result.score)), isCodingAgentEnvironment(), { animateCountUp: animateRender }, shouldRenderHyperlinks(process.stdout), resolveDiagnosticFrameSourceRoot);
|
|
95541
95591
|
}
|
|
95542
95592
|
const lowestScoredScan = findLowestScoredScan(completedScans);
|
|
95543
95593
|
const aggregateScore = lowestScoredScan?.result.score ?? null;
|
|
@@ -95925,6 +95975,45 @@ const runExplain = async (fileLineArgument, context) => {
|
|
|
95925
95975
|
}
|
|
95926
95976
|
};
|
|
95927
95977
|
//#endregion
|
|
95978
|
+
//#region src/cli/utils/run-project-scan-batch.ts
|
|
95979
|
+
/**
|
|
95980
|
+
* Run one scan per project through the same bounded pool as
|
|
95981
|
+
* `diagnose({ projects })`, with the batch spinner and its progress counter.
|
|
95982
|
+
*
|
|
95983
|
+
* Pool members must not toggle the module-level spinner-silent flag themselves —
|
|
95984
|
+
* overlapping save/restore pairs would race — so the batch owns that toggle once
|
|
95985
|
+
* around the whole run.
|
|
95986
|
+
*
|
|
95987
|
+
* A `scanProject` that returns `null` drops the project from the results: diff
|
|
95988
|
+
* mode skips projects with no changed source.
|
|
95989
|
+
*/
|
|
95990
|
+
const runProjectScanBatch = async (input) => {
|
|
95991
|
+
const startTime = performance$1.now();
|
|
95992
|
+
const projectCount = input.projects.length;
|
|
95993
|
+
const isMultiProject = projectCount > 1;
|
|
95994
|
+
const batchSpinner = isMultiProject && !input.isQuiet ? spinner(`Scanning ${projectCount} projects…`).start() : null;
|
|
95995
|
+
const ownsBatchSpinnerSilence = isMultiProject && input.isSilent;
|
|
95996
|
+
const wasSpinnerSilent = isSpinnerSilent();
|
|
95997
|
+
if (ownsBatchSpinnerSilence) setSpinnerSilent(true);
|
|
95998
|
+
let finishedProjectCount = 0;
|
|
95999
|
+
let scanOutcomes;
|
|
96000
|
+
try {
|
|
96001
|
+
scanOutcomes = await mapWithConcurrency(input.projects, isMultiProject ? 4 : 1, async (project) => {
|
|
96002
|
+
const scanOutcome = await input.scanProject(project);
|
|
96003
|
+
finishedProjectCount += 1;
|
|
96004
|
+
batchSpinner?.update(`Scanning ${projectCount} projects… (${finishedProjectCount}/${projectCount})`);
|
|
96005
|
+
return scanOutcome;
|
|
96006
|
+
});
|
|
96007
|
+
} finally {
|
|
96008
|
+
if (ownsBatchSpinnerSilence) setSpinnerSilent(wasSpinnerSilent);
|
|
96009
|
+
batchSpinner?.stop();
|
|
96010
|
+
}
|
|
96011
|
+
return {
|
|
96012
|
+
completedScans: scanOutcomes.filter((scanOutcome) => scanOutcome !== null),
|
|
96013
|
+
elapsedMilliseconds: performance$1.now() - startTime
|
|
96014
|
+
};
|
|
96015
|
+
};
|
|
96016
|
+
//#endregion
|
|
95928
96017
|
//#region src/cli/utils/project-manifest-changed.ts
|
|
95929
96018
|
const PACKAGE_JSON = "package.json";
|
|
95930
96019
|
/**
|
|
@@ -95941,6 +96030,29 @@ const projectManifestChanged = (rootDirectory, projectDirectory, diffInfo) => {
|
|
|
95941
96030
|
return diffInfo.changedFiles.some((filePath) => toForwardSlashes(filePath) === manifestPath);
|
|
95942
96031
|
};
|
|
95943
96032
|
//#endregion
|
|
96033
|
+
//#region src/cli/utils/select-staged-projects.ts
|
|
96034
|
+
/**
|
|
96035
|
+
* Appended to the reason a `--staged` run could not scan per package. Shared so
|
|
96036
|
+
* both fallback sites word it identically.
|
|
96037
|
+
*/
|
|
96038
|
+
const STAGED_PROJECT_FALLBACK_HINT = "Scanning the staged files at the scan root instead — fix the `projects` entries in your config to scan per package.";
|
|
96039
|
+
/**
|
|
96040
|
+
* Resolve the project directories a `--staged` scan owns. The interactive picker
|
|
96041
|
+
* is always skipped: a commit hook has nobody to answer it.
|
|
96042
|
+
*/
|
|
96043
|
+
const selectStagedProjects = async (input) => {
|
|
96044
|
+
if (input.projectFlag) return selectProjects(input.rootDirectory, input.projectFlag, true, void 0);
|
|
96045
|
+
if (input.configProjects === void 0) return [input.rootDirectory];
|
|
96046
|
+
try {
|
|
96047
|
+
return await selectProjects(input.rootDirectory, void 0, true, input.configProjects);
|
|
96048
|
+
} catch (error) {
|
|
96049
|
+
if (!(error instanceof CliInputError)) throw error;
|
|
96050
|
+
cliLogger.warn(`${error.message} ${STAGED_PROJECT_FALLBACK_HINT}`);
|
|
96051
|
+
cliLogger.break();
|
|
96052
|
+
return [input.rootDirectory];
|
|
96053
|
+
}
|
|
96054
|
+
};
|
|
96055
|
+
//#endregion
|
|
95944
96056
|
//#region src/cli/utils/should-fail-scan-gate.ts
|
|
95945
96057
|
const shouldFailScanGate = (input) => {
|
|
95946
96058
|
if (input.blockingLevel === "none") return false;
|
|
@@ -96162,8 +96274,13 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
|
|
|
96162
96274
|
json: flags.json
|
|
96163
96275
|
});
|
|
96164
96276
|
if (flags.staged) {
|
|
96165
|
-
const
|
|
96166
|
-
|
|
96277
|
+
const configProjectsApply = (userConfig?.projects ?? []).some((projectName) => projectName.trim().length > 0) && scanTarget.requestedDirectory === scanTarget.configSourceDirectory;
|
|
96278
|
+
const projectDirectories = await selectStagedProjects({
|
|
96279
|
+
rootDirectory: resolvedDirectory,
|
|
96280
|
+
projectFlag: flags.project,
|
|
96281
|
+
configProjects: configProjectsApply ? userConfig?.projects : void 0
|
|
96282
|
+
});
|
|
96283
|
+
const reportNothingToScan = (input) => {
|
|
96167
96284
|
if (isJsonMode) writeJsonReport(buildJsonReport({
|
|
96168
96285
|
version: VERSION,
|
|
96169
96286
|
directory: resolvedDirectory,
|
|
@@ -96172,76 +96289,214 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
|
|
|
96172
96289
|
scans: [],
|
|
96173
96290
|
totalElapsedMilliseconds: performance$1.now() - startTime
|
|
96174
96291
|
}));
|
|
96175
|
-
else if (!isScoreOnly)
|
|
96292
|
+
else if (!isScoreOnly) if (input.severity === "warn") {
|
|
96293
|
+
cliLogger.warn(input.reason);
|
|
96294
|
+
cliLogger.break();
|
|
96295
|
+
} else cliLogger.dim(input.reason);
|
|
96296
|
+
};
|
|
96297
|
+
const rootStagedFiles = await getStagedSourceFiles(resolvedDirectory);
|
|
96298
|
+
if (rootStagedFiles.length === 0) {
|
|
96299
|
+
reportNothingToScan({ reason: "No staged source files found." });
|
|
96176
96300
|
return;
|
|
96177
96301
|
}
|
|
96178
|
-
|
|
96179
|
-
|
|
96302
|
+
const buildProjectScanContext = async (projectDirectory) => {
|
|
96303
|
+
const projectScanTarget = projectDirectory === resolvedDirectory ? scanTarget : await resolveScanTarget(projectDirectory, { allowAmbiguous: true });
|
|
96304
|
+
const scanDirectory = projectScanTarget.resolvedDirectory;
|
|
96305
|
+
const treeRelativeDirectory = resolveProjectRelativeDirectory(resolvedDirectory, scanDirectory);
|
|
96306
|
+
if (treeRelativeDirectory === null) return null;
|
|
96307
|
+
return {
|
|
96308
|
+
projectDirectory,
|
|
96309
|
+
scanDirectory,
|
|
96310
|
+
treeRelativeDirectory,
|
|
96311
|
+
projectConfig: projectDirectory === resolvedDirectory ? userConfig : mergeReactDoctorConfigs(userConfig, projectScanTarget.userConfig ?? void 0),
|
|
96312
|
+
projectConfigSourceDirectory: projectScanTarget.userConfig?.plugins === void 0 ? scanTarget.configSourceDirectory : projectScanTarget.configSourceDirectory
|
|
96313
|
+
};
|
|
96314
|
+
};
|
|
96315
|
+
const projectScanContexts = [];
|
|
96316
|
+
const seenScanDirectories = /* @__PURE__ */ new Set();
|
|
96317
|
+
for (const projectDirectory of projectDirectories) {
|
|
96318
|
+
const projectScanContext = await buildProjectScanContext(projectDirectory);
|
|
96319
|
+
if (projectScanContext === null) {
|
|
96320
|
+
if (flags.project) throw new CliInputError(`Project "${toRelativePath(projectDirectory, resolvedDirectory)}" is outside ${resolvedDirectory}, so it holds none of the staged files. Run --staged from a directory that contains the project.`);
|
|
96321
|
+
continue;
|
|
96322
|
+
}
|
|
96323
|
+
if (seenScanDirectories.has(projectScanContext.scanDirectory)) continue;
|
|
96324
|
+
seenScanDirectories.add(projectScanContext.scanDirectory);
|
|
96325
|
+
projectScanContexts.push(projectScanContext);
|
|
96326
|
+
}
|
|
96327
|
+
if (projectScanContexts.length === 0) {
|
|
96328
|
+
cliLogger.warn(`No configured project is inside ${resolvedDirectory}. ${STAGED_PROJECT_FALLBACK_HINT}`);
|
|
96180
96329
|
cliLogger.break();
|
|
96330
|
+
const rootScanContext = await buildProjectScanContext(resolvedDirectory);
|
|
96331
|
+
if (rootScanContext !== null) projectScanContexts.push(rootScanContext);
|
|
96181
96332
|
}
|
|
96182
|
-
const
|
|
96183
|
-
const
|
|
96184
|
-
|
|
96185
|
-
|
|
96186
|
-
|
|
96333
|
+
const contextsByLongestPathFirst = [...projectScanContexts].sort((left, right) => right.treeRelativeDirectory.length - left.treeRelativeDirectory.length);
|
|
96334
|
+
const ownedStagedFiles = /* @__PURE__ */ new Map();
|
|
96335
|
+
for (const stagedFile of rootStagedFiles) {
|
|
96336
|
+
const owner = contextsByLongestPathFirst.find((context) => context.treeRelativeDirectory.length === 0 || stagedFile.startsWith(`${context.treeRelativeDirectory}/`));
|
|
96337
|
+
if (owner === void 0) continue;
|
|
96338
|
+
const ownedFiles = ownedStagedFiles.get(owner.scanDirectory);
|
|
96339
|
+
if (ownedFiles === void 0) ownedStagedFiles.set(owner.scanDirectory, [stagedFile]);
|
|
96340
|
+
else ownedFiles.push(stagedFile);
|
|
96341
|
+
}
|
|
96342
|
+
const stagedProjectScans = [];
|
|
96343
|
+
for (const projectScanContext of projectScanContexts) {
|
|
96344
|
+
const projectStagedFiles = ownedStagedFiles.get(projectScanContext.scanDirectory);
|
|
96345
|
+
if (projectStagedFiles === void 0) continue;
|
|
96346
|
+
stagedProjectScans.push({
|
|
96347
|
+
...projectScanContext,
|
|
96348
|
+
stagedFiles: projectStagedFiles
|
|
96187
96349
|
});
|
|
96188
|
-
|
|
96189
|
-
|
|
96350
|
+
}
|
|
96351
|
+
if (stagedProjectScans.length === 0) {
|
|
96352
|
+
reportNothingToScan({ reason: "No staged source files in the selected projects." });
|
|
96353
|
+
return;
|
|
96354
|
+
}
|
|
96355
|
+
const selectedStagedFiles = stagedProjectScans.flatMap((projectScan) => projectScan.stagedFiles);
|
|
96356
|
+
const stagedFileCount = selectedStagedFiles.length;
|
|
96357
|
+
const unselectedStagedFileCount = rootStagedFiles.length - stagedFileCount;
|
|
96358
|
+
if (!isQuiet) {
|
|
96359
|
+
cliLogger.log(`Scanning ${highlighter.info(`${stagedFileCount}`)} staged files...`);
|
|
96360
|
+
if (unselectedStagedFileCount > 0) cliLogger.dim(`${unselectedStagedFileCount} more staged file${unselectedStagedFileCount === 1 ? "" : "s"} outside the selected projects.`);
|
|
96361
|
+
cliLogger.break();
|
|
96362
|
+
}
|
|
96190
96363
|
const stagedWantsLines = resolveScope(flags, userConfig).scope === "lines";
|
|
96191
96364
|
const stagedLineRanges = stagedWantsLines ? await getChangedLineRanges({
|
|
96192
96365
|
directory: resolvedDirectory,
|
|
96193
96366
|
cached: true,
|
|
96194
|
-
files:
|
|
96367
|
+
files: selectedStagedFiles
|
|
96195
96368
|
}) : null;
|
|
96196
96369
|
if (stagedWantsLines && stagedLineRanges === null && !isQuiet) {
|
|
96197
96370
|
cliLogger.warn("Could not determine staged changed lines; reporting all issues in staged files.");
|
|
96198
96371
|
cliLogger.break();
|
|
96199
96372
|
}
|
|
96200
|
-
|
|
96201
|
-
|
|
96373
|
+
if (stagedProjectScans.some((projectScan) => projectScan.treeRelativeDirectory.length > 0)) recordCount(METRIC.stagedPerProject, 1, { projectCount: stagedProjectScans.length });
|
|
96374
|
+
const tempDirectory = NFS.mkdtempSync(Path.join(tmpdir(), STAGED_FILES_TEMP_DIR_PREFIX));
|
|
96375
|
+
const configSubdirectories = /* @__PURE__ */ new Set();
|
|
96376
|
+
for (const projectScan of stagedProjectScans) {
|
|
96377
|
+
configSubdirectories.add(projectScan.treeRelativeDirectory);
|
|
96378
|
+
const projectRelativeDirectory = resolveProjectRelativeDirectory(resolvedDirectory, projectScan.projectDirectory);
|
|
96379
|
+
if (projectRelativeDirectory !== null) configSubdirectories.add(projectRelativeDirectory);
|
|
96380
|
+
}
|
|
96381
|
+
const snapshot = await materializeStagedFiles({
|
|
96382
|
+
directory: resolvedDirectory,
|
|
96383
|
+
stagedFiles: selectedStagedFiles,
|
|
96384
|
+
tempDirectory,
|
|
96385
|
+
configSubdirectories: [...configSubdirectories]
|
|
96386
|
+
}).catch((error) => {
|
|
96387
|
+
NFS.rmSync(tempDirectory, {
|
|
96388
|
+
recursive: true,
|
|
96389
|
+
force: true
|
|
96390
|
+
});
|
|
96391
|
+
throw error;
|
|
96392
|
+
});
|
|
96393
|
+
const materializedStagedFiles = new Set(snapshot.stagedFiles);
|
|
96394
|
+
const stagedProjectRuns = stagedProjectScans.map((projectScan) => ({
|
|
96395
|
+
projectScan,
|
|
96396
|
+
includePaths: resolveProjectSourceFilePaths(resolvedDirectory, projectScan.scanDirectory, projectScan.stagedFiles.filter((stagedFile) => materializedStagedFiles.has(stagedFile)))
|
|
96397
|
+
})).filter((projectRun) => projectRun.includePaths.length > 0);
|
|
96398
|
+
const isMultiProject = stagedProjectRuns.length > 1;
|
|
96399
|
+
if (stagedProjectRuns.length === 0) {
|
|
96400
|
+
snapshot.cleanup();
|
|
96401
|
+
reportNothingToScan({
|
|
96402
|
+
reason: `Could not read any of the ${stagedFileCount} staged file${stagedFileCount === 1 ? "" : "s"} out of the index, so nothing was scanned. An unusually large staged file is the usual cause.`,
|
|
96403
|
+
severity: "warn"
|
|
96404
|
+
});
|
|
96405
|
+
return;
|
|
96406
|
+
}
|
|
96407
|
+
if (snapshot.unmaterializedFiles.length > 0 && !isQuiet) {
|
|
96408
|
+
const stagedFileLabel = `staged file${stagedFileCount === 1 ? "" : "s"}`;
|
|
96409
|
+
cliLogger.warn(`Skipped ${snapshot.unmaterializedFiles.length} of ${stagedFileCount} ${stagedFileLabel}; they could not be snapshotted from the index.`);
|
|
96410
|
+
cliLogger.break();
|
|
96411
|
+
}
|
|
96412
|
+
const scanStagedProject = async (projectRun) => {
|
|
96413
|
+
const { projectScan, includePaths } = projectRun;
|
|
96414
|
+
const projectTempDirectory = Path.join(snapshot.tempDirectory, projectScan.treeRelativeDirectory);
|
|
96415
|
+
const scanResult = await inspect(projectTempDirectory, {
|
|
96202
96416
|
...scanOptions,
|
|
96203
96417
|
deadlineEpochMs: scanDeadlineEpochMs,
|
|
96204
|
-
includePaths:
|
|
96205
|
-
configOverride:
|
|
96206
|
-
configSourceDirectory:
|
|
96207
|
-
changedLineRanges: stagedLineRanges
|
|
96418
|
+
includePaths: [...includePaths],
|
|
96419
|
+
configOverride: projectScan.projectConfig,
|
|
96420
|
+
configSourceDirectory: projectScan.projectConfigSourceDirectory ?? void 0,
|
|
96421
|
+
changedLineRanges: stagedLineRanges === null ? void 0 : resolveProjectChangedLineRanges(resolvedDirectory, projectScan.scanDirectory, stagedLineRanges),
|
|
96422
|
+
suppressRendering: isMultiProject,
|
|
96423
|
+
concurrentScan: isMultiProject
|
|
96208
96424
|
});
|
|
96209
96425
|
const remappedDiagnostics = scanResult.diagnostics.map((diagnostic) => ({
|
|
96210
96426
|
...diagnostic,
|
|
96211
|
-
filePath: Path.isAbsolute(diagnostic.filePath) ? diagnostic.filePath.replaceAll(
|
|
96427
|
+
filePath: Path.isAbsolute(diagnostic.filePath) ? diagnostic.filePath.replaceAll(projectTempDirectory, () => projectScan.scanDirectory) : diagnostic.filePath
|
|
96212
96428
|
}));
|
|
96213
|
-
|
|
96214
|
-
|
|
96215
|
-
|
|
96216
|
-
|
|
96217
|
-
|
|
96218
|
-
|
|
96219
|
-
project
|
|
96220
|
-
|
|
96221
|
-
|
|
96222
|
-
|
|
96223
|
-
|
|
96224
|
-
|
|
96225
|
-
|
|
96226
|
-
|
|
96227
|
-
|
|
96228
|
-
|
|
96229
|
-
|
|
96230
|
-
|
|
96231
|
-
|
|
96232
|
-
|
|
96233
|
-
|
|
96234
|
-
|
|
96235
|
-
|
|
96236
|
-
|
|
96429
|
+
return {
|
|
96430
|
+
directory: projectScan.scanDirectory,
|
|
96431
|
+
result: {
|
|
96432
|
+
...scanResult,
|
|
96433
|
+
diagnostics: remappedDiagnostics,
|
|
96434
|
+
project: {
|
|
96435
|
+
...scanResult.project,
|
|
96436
|
+
rootDirectory: projectScan.scanDirectory
|
|
96437
|
+
}
|
|
96438
|
+
},
|
|
96439
|
+
config: projectScan.projectConfig,
|
|
96440
|
+
frameSourceRoot: projectTempDirectory
|
|
96441
|
+
};
|
|
96442
|
+
};
|
|
96443
|
+
const stagedBatch = await runProjectScanBatch({
|
|
96444
|
+
projects: stagedProjectRuns,
|
|
96445
|
+
isQuiet,
|
|
96446
|
+
isSilent: scanOptions.silent === true,
|
|
96447
|
+
scanProject: scanStagedProject
|
|
96448
|
+
}).catch((error) => {
|
|
96449
|
+
snapshot.cleanup();
|
|
96450
|
+
throw error;
|
|
96451
|
+
});
|
|
96452
|
+
const completedScans = stagedBatch.completedScans;
|
|
96453
|
+
try {
|
|
96454
|
+
if (!isQuiet && isMultiProject) {
|
|
96455
|
+
const showShareLink = !isShareOptedOut(completedScans, scanOptions.noScore) && !scanOptions.isCi;
|
|
96456
|
+
await runPromise(printMultiProjectSummary({
|
|
96457
|
+
completedScans,
|
|
96458
|
+
categoryFilters,
|
|
96459
|
+
verbose: Boolean(flags.verbose),
|
|
96460
|
+
outputDirectory: flags.outputDir,
|
|
96461
|
+
isOffline: !showShareLink,
|
|
96462
|
+
projectName: Path.basename(resolvedDirectory),
|
|
96463
|
+
totalElapsedMilliseconds: stagedBatch.elapsedMilliseconds
|
|
96464
|
+
}));
|
|
96465
|
+
}
|
|
96466
|
+
if (flags.outputDir && isMultiProject && isQuiet) await runPromise(printDiagnosticsDump(filterDiagnosticsByCategories(filterScansForSurface(completedScans, scanOptions.outputSurface ?? "cli"), categoryFilters), flags.outputDir, false, "stderr"));
|
|
96237
96467
|
} finally {
|
|
96238
96468
|
snapshot.cleanup();
|
|
96239
96469
|
}
|
|
96470
|
+
finalizeScans({
|
|
96471
|
+
completedScans,
|
|
96472
|
+
mode: "staged",
|
|
96473
|
+
diff: null,
|
|
96474
|
+
baselineIntended: false,
|
|
96475
|
+
isJsonMode,
|
|
96476
|
+
isScoreOnly,
|
|
96477
|
+
flags,
|
|
96478
|
+
categoryFilters,
|
|
96479
|
+
userConfig,
|
|
96480
|
+
resolvedDirectory,
|
|
96481
|
+
startTime
|
|
96482
|
+
});
|
|
96240
96483
|
return;
|
|
96241
96484
|
}
|
|
96242
96485
|
const projectDirectories = await selectProjects(resolvedDirectory, flags.project, skipPrompts, userConfig?.projects);
|
|
96243
96486
|
const projectSelectionCompletedTime = performance$1.now();
|
|
96244
|
-
|
|
96487
|
+
let changedFilesDiffInfo = flags.changedFilesFrom ? buildChangedFilesDiffInfo(readChangedFilesFrom(Path.resolve(flags.changedFilesFrom))) : null;
|
|
96488
|
+
if (changedFilesDiffInfo !== null && scanTarget.didRedirectViaRootDir) {
|
|
96489
|
+
const relativeProjectDirectory = resolveProjectRelativeDirectory(requestedDirectory, resolvedDirectory);
|
|
96490
|
+
if (relativeProjectDirectory) {
|
|
96491
|
+
const projectPrefix = `${relativeProjectDirectory}/`;
|
|
96492
|
+
changedFilesDiffInfo = {
|
|
96493
|
+
...changedFilesDiffInfo,
|
|
96494
|
+
changedFiles: changedFilesDiffInfo.changedFiles.flatMap((filePath) => {
|
|
96495
|
+
return filePath.startsWith(projectPrefix) ? [filePath.slice(projectPrefix.length)] : [];
|
|
96496
|
+
})
|
|
96497
|
+
};
|
|
96498
|
+
}
|
|
96499
|
+
}
|
|
96245
96500
|
const requestedScope = resolveScope(flags, userConfig);
|
|
96246
96501
|
const includeUntracked = flags.includeUntracked ?? false;
|
|
96247
96502
|
const scopeRequest = requestedScope.scope === void 0 && changedFilesDiffInfo !== null ? {
|
|
@@ -96289,7 +96544,6 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
|
|
|
96289
96544
|
}
|
|
96290
96545
|
cliLogger.break();
|
|
96291
96546
|
}
|
|
96292
|
-
const completedScans = [];
|
|
96293
96547
|
const isMultiProject = projectDirectories.length > 1;
|
|
96294
96548
|
const scanProject = async (projectDirectory) => {
|
|
96295
96549
|
const projectScanTarget = projectDirectory === resolvedDirectory ? scanTarget : await resolveScanTarget(projectDirectory, { allowAmbiguous: true });
|
|
@@ -96340,29 +96594,13 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
|
|
|
96340
96594
|
config: projectConfig
|
|
96341
96595
|
};
|
|
96342
96596
|
};
|
|
96343
|
-
const
|
|
96344
|
-
|
|
96345
|
-
|
|
96346
|
-
|
|
96347
|
-
|
|
96348
|
-
|
|
96349
|
-
|
|
96350
|
-
let scanOutcomes;
|
|
96351
|
-
try {
|
|
96352
|
-
scanOutcomes = await mapWithConcurrency(projectDirectories, isMultiProject ? 4 : 1, async (projectDirectory) => {
|
|
96353
|
-
const scanOutcome = await scanProject(projectDirectory);
|
|
96354
|
-
finishedProjectCount += 1;
|
|
96355
|
-
batchSpinner?.update(`Scanning ${projectCount} projects… (${finishedProjectCount}/${projectCount})`);
|
|
96356
|
-
return scanOutcome;
|
|
96357
|
-
});
|
|
96358
|
-
} finally {
|
|
96359
|
-
if (ownsBatchSpinnerSilence) setSpinnerSilent(wasSpinnerSilent);
|
|
96360
|
-
batchSpinner?.stop();
|
|
96361
|
-
}
|
|
96362
|
-
for (const scanOutcome of scanOutcomes) {
|
|
96363
|
-
if (scanOutcome === null) continue;
|
|
96364
|
-
completedScans.push(scanOutcome);
|
|
96365
|
-
}
|
|
96597
|
+
const projectBatch = await runProjectScanBatch({
|
|
96598
|
+
projects: projectDirectories,
|
|
96599
|
+
isQuiet,
|
|
96600
|
+
isSilent: scanOptions.silent === true,
|
|
96601
|
+
scanProject
|
|
96602
|
+
});
|
|
96603
|
+
const completedScans = projectBatch.completedScans;
|
|
96366
96604
|
if (!isQuiet && isMultiProject && completedScans.length > 0) {
|
|
96367
96605
|
const showShareLink = !isShareOptedOut(completedScans, scanOptions.noScore) && !scanOptions.isCi;
|
|
96368
96606
|
await runPromise(printMultiProjectSummary({
|
|
@@ -96372,7 +96610,7 @@ const inspectAction = async (directory, flags, invocationCommand = "inspect") =>
|
|
|
96372
96610
|
outputDirectory: flags.outputDir,
|
|
96373
96611
|
isOffline: !showShareLink,
|
|
96374
96612
|
projectName: Path.basename(resolvedDirectory),
|
|
96375
|
-
totalElapsedMilliseconds:
|
|
96613
|
+
totalElapsedMilliseconds: projectBatch.elapsedMilliseconds
|
|
96376
96614
|
}));
|
|
96377
96615
|
}
|
|
96378
96616
|
const selectedSurfaceDiagnostics = filterDiagnosticsByCategories(filterScansForSurface(completedScans, scanOptions.outputSurface ?? "cli"), categoryFilters);
|
|
@@ -97518,7 +97756,7 @@ ${highlighter.dim("Learn more:")}
|
|
|
97518
97756
|
${highlighter.info(CI_URL)}
|
|
97519
97757
|
`;
|
|
97520
97758
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
97521
|
-
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);
|
|
97759
|
+
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 (honors --project and config `projects`; exits 0 when nothing is staged)").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);
|
|
97522
97760
|
program.action(inspectAction);
|
|
97523
97761
|
program.command("design [directory]").description("Run only the focused UI design diagnostics").addHelpText("after", renderDesignHelpEpilog).action((directory, _options, command) => designAction(directory ?? ".", command.optsWithGlobals()));
|
|
97524
97762
|
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));
|
|
@@ -97601,4 +97839,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
97601
97839
|
export { toForwardSlashes as A, getCategoryImpact as B, buildRulePriorityMap as C, resolveBlockingLevel as D, formatLearnMoreLine as E, TUI_REPORT_DETAIL_WIDTH_FRACTION as F, runPromise as G, mapWithConcurrency as H, isCiEnvironment as I, succeed$3 as J, sync as K, DIAGNOSTIC_CATEGORY_BUCKETS as L, isUnicodeSupported as M, METRIC as N, isReactDoctorWorkflowInstalled as O, TUI_REPORT_COMPACT_MAX_ROWS as P, Progress as R, hasLintHardFailure as S, formatFixRecipeLine as T, mergeReactDoctorConfigs as U, highlighter as V, resolveScanTarget 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, void_ 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, Reporter as z };
|
|
97602
97840
|
|
|
97603
97841
|
//# sourceMappingURL=cli.js.map
|
|
97604
|
-
//# debugId=
|
|
97842
|
+
//# debugId=2a10a6ef-ec19-5a23-88d5-c2e4d5e30eec
|