react-doctor 0.0.32 → 0.0.33
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 +0 -2
- package/dist/cli.js +226 -434
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +108 -79
- package/dist/index.js.map +1 -1
- package/dist/react-doctor-plugin.js +41 -10
- package/dist/react-doctor-plugin.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/utils/get-diff-files.ts","../src/index.ts"],"mappings":";KAAY,WAAA;AAAA,KAEA,SAAA;AAAA,UAUK,WAAA;EACf,aAAA;EACA,WAAA;EACA,YAAA;EACA,SAAA,EAAW,SAAA;EACX,aAAA;EACA,gBAAA;EACA,eAAA;AAAA;AAAA,UAiCe,UAAA;EACf,QAAA;EACA,MAAA;EACA,IAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;EACA,MAAA;AAAA;AAAA,UA4Be,WAAA;EACf,KAAA;EACA,KAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/utils/get-diff-files.ts","../src/index.ts"],"mappings":";KAAY,WAAA;AAAA,KAEA,SAAA;AAAA,UAUK,WAAA;EACf,aAAA;EACA,WAAA;EACA,YAAA;EACA,SAAA,EAAW,SAAA;EACX,aAAA;EACA,gBAAA;EACA,eAAA;AAAA;AAAA,UAiCe,UAAA;EACf,QAAA;EACA,MAAA;EACA,IAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;EACA,MAAA;AAAA;AAAA,UA4Be,WAAA;EACf,KAAA;EACA,KAAA;AAAA;AAAA,UAmBe,QAAA;EACf,aAAA;EACA,UAAA;EACA,YAAA;EACA,gBAAA;AAAA;AAAA,UA2Ce,uBAAA;EACf,KAAA;EACA,KAAA;AAAA;AAAA,UAGe,iBAAA;EACf,MAAA,GAAS,uBAAA;EACT,IAAA;EACA,QAAA;EACA,OAAA;EACA,IAAA;EACA,MAAA,GAAS,WAAA;EACT,eAAA;EACA,KAAA;EACA,cAAA;AAAA;;;cC7FW,WAAA,GAAe,SAAA,UAAmB,kBAAA,cAA8B,QAAA;AAAA,cAiBhE,iBAAA,GAAqB,SAAA;;;UClFjB,eAAA;EACf,IAAA;EACA,QAAA;EACA,YAAA;AAAA;AAAA,UAGe,cAAA;EACf,WAAA,EAAa,UAAA;EACb,KAAA,EAAO,WAAA;EACP,OAAA,EAAS,WAAA;EACT,mBAAA;AAAA;AAAA,cAGW,QAAA,GACX,SAAA,UACA,OAAA,GAAS,eAAA,KACR,OAAA,CAAQ,cAAA"}
|
package/dist/index.js
CHANGED
|
@@ -19,20 +19,18 @@ const SCORE_API_URL = "https://www.react.doctor/api/score";
|
|
|
19
19
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
20
20
|
const GIT_LS_FILES_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
21
21
|
const SPAWN_ARGS_MAX_LENGTH_CHARS = 24e3;
|
|
22
|
+
const OXLINT_MAX_FILES_PER_BATCH = 500;
|
|
22
23
|
const DEFAULT_BRANCH_CANDIDATES = ["main", "master"];
|
|
23
24
|
const ERROR_RULE_PENALTY = 1.5;
|
|
24
25
|
const WARNING_RULE_PENALTY = .75;
|
|
25
|
-
const ERROR_ESTIMATED_FIX_RATE = .85;
|
|
26
|
-
const WARNING_ESTIMATED_FIX_RATE = .8;
|
|
27
26
|
const MAX_KNIP_RETRIES = 5;
|
|
27
|
+
const GIT_SHOW_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
28
28
|
const IGNORED_DIRECTORIES = new Set([
|
|
29
29
|
"node_modules",
|
|
30
30
|
"dist",
|
|
31
31
|
"build",
|
|
32
32
|
"coverage"
|
|
33
33
|
]);
|
|
34
|
-
const AMI_WEBSITE_URL = "https://ami.dev";
|
|
35
|
-
const AMI_INSTALL_URL = `${AMI_WEBSITE_URL}/install.sh`;
|
|
36
34
|
|
|
37
35
|
//#endregion
|
|
38
36
|
//#region src/utils/proxy-fetch.ts
|
|
@@ -106,22 +104,12 @@ const scoreFromRuleCounts = (errorRuleCount, warningRuleCount) => {
|
|
|
106
104
|
const penalty = errorRuleCount * ERROR_RULE_PENALTY + warningRuleCount * WARNING_RULE_PENALTY;
|
|
107
105
|
return Math.max(0, Math.round(PERFECT_SCORE - penalty));
|
|
108
106
|
};
|
|
109
|
-
const estimateScoreLocally = (diagnostics) => {
|
|
110
|
-
const { errorRuleCount, warningRuleCount } = countUniqueRules(diagnostics);
|
|
111
|
-
const currentScore = scoreFromRuleCounts(errorRuleCount, warningRuleCount);
|
|
112
|
-
const estimatedScore = scoreFromRuleCounts(Math.round(errorRuleCount * (1 - ERROR_ESTIMATED_FIX_RATE)), Math.round(warningRuleCount * (1 - WARNING_ESTIMATED_FIX_RATE)));
|
|
113
|
-
return {
|
|
114
|
-
currentScore,
|
|
115
|
-
currentLabel: getScoreLabel(currentScore),
|
|
116
|
-
estimatedScore,
|
|
117
|
-
estimatedLabel: getScoreLabel(estimatedScore)
|
|
118
|
-
};
|
|
119
|
-
};
|
|
120
107
|
const calculateScoreLocally = (diagnostics) => {
|
|
121
|
-
const {
|
|
108
|
+
const { errorRuleCount, warningRuleCount } = countUniqueRules(diagnostics);
|
|
109
|
+
const score = scoreFromRuleCounts(errorRuleCount, warningRuleCount);
|
|
122
110
|
return {
|
|
123
|
-
score
|
|
124
|
-
label:
|
|
111
|
+
score,
|
|
112
|
+
label: getScoreLabel(score)
|
|
125
113
|
};
|
|
126
114
|
};
|
|
127
115
|
const calculateScore = async (diagnostics) => {
|
|
@@ -158,6 +146,7 @@ const readPackageJson = (packageJsonPath) => {
|
|
|
158
146
|
try {
|
|
159
147
|
return JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
160
148
|
} catch (error) {
|
|
149
|
+
if (error instanceof SyntaxError) return {};
|
|
161
150
|
if (error instanceof Error && "code" in error) {
|
|
162
151
|
const { code } = error;
|
|
163
152
|
if (code === "EISDIR" || code === "EACCES") return {};
|
|
@@ -253,38 +242,58 @@ const isFileIgnoredByPatterns = (filePath, rootDirectory, patterns) => {
|
|
|
253
242
|
|
|
254
243
|
//#endregion
|
|
255
244
|
//#region src/utils/filter-diagnostics.ts
|
|
256
|
-
const
|
|
257
|
-
const ignoredRules = new Set(Array.isArray(config.ignore?.rules) ? config.ignore.rules : []);
|
|
258
|
-
const ignoredFilePatterns = compileIgnoredFilePatterns(config);
|
|
259
|
-
if (ignoredRules.size === 0 && ignoredFilePatterns.length === 0) return diagnostics;
|
|
260
|
-
return diagnostics.filter((diagnostic) => {
|
|
261
|
-
const ruleIdentifier = `${diagnostic.plugin}/${diagnostic.rule}`;
|
|
262
|
-
if (ignoredRules.has(ruleIdentifier)) return false;
|
|
263
|
-
if (isFileIgnoredByPatterns(diagnostic.filePath, rootDirectory, ignoredFilePatterns)) return false;
|
|
264
|
-
return true;
|
|
265
|
-
});
|
|
266
|
-
};
|
|
245
|
+
const OPENING_TAG_PATTERN = /<([A-Z][\w.]*)/;
|
|
267
246
|
const DISABLE_NEXT_LINE_PATTERN = /\/\/\s*react-doctor-disable-next-line\b(?:\s+(.+))?/;
|
|
268
247
|
const DISABLE_LINE_PATTERN = /\/\/\s*react-doctor-disable-line\b(?:\s+(.+))?/;
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
return
|
|
272
|
-
|
|
273
|
-
const filterInlineSuppressions = (diagnostics, rootDirectory) => {
|
|
274
|
-
const fileLineCache = /* @__PURE__ */ new Map();
|
|
275
|
-
const getFileLines = (filePath) => {
|
|
276
|
-
const cached = fileLineCache.get(filePath);
|
|
248
|
+
const createFileLinesCache = (rootDirectory) => {
|
|
249
|
+
const cache = /* @__PURE__ */ new Map();
|
|
250
|
+
return (filePath) => {
|
|
251
|
+
const cached = cache.get(filePath);
|
|
277
252
|
if (cached !== void 0) return cached;
|
|
278
253
|
const absolutePath = path.isAbsolute(filePath) ? filePath : path.join(rootDirectory, filePath);
|
|
279
254
|
try {
|
|
280
255
|
const lines = fs.readFileSync(absolutePath, "utf-8").split("\n");
|
|
281
|
-
|
|
256
|
+
cache.set(filePath, lines);
|
|
282
257
|
return lines;
|
|
283
258
|
} catch {
|
|
284
|
-
|
|
259
|
+
cache.set(filePath, null);
|
|
285
260
|
return null;
|
|
286
261
|
}
|
|
287
262
|
};
|
|
263
|
+
};
|
|
264
|
+
const isInsideTextComponent = (lines, diagnosticLine, textComponentNames) => {
|
|
265
|
+
for (let lineIndex = diagnosticLine - 1; lineIndex >= 0; lineIndex--) {
|
|
266
|
+
const match = lines[lineIndex].match(OPENING_TAG_PATTERN);
|
|
267
|
+
if (!match) continue;
|
|
268
|
+
const fullTagName = match[1];
|
|
269
|
+
const leafTagName = fullTagName.includes(".") ? fullTagName.split(".").at(-1) ?? fullTagName : fullTagName;
|
|
270
|
+
return textComponentNames.has(fullTagName) || textComponentNames.has(leafTagName);
|
|
271
|
+
}
|
|
272
|
+
return false;
|
|
273
|
+
};
|
|
274
|
+
const isRuleSuppressed = (commentRules, ruleId) => {
|
|
275
|
+
if (!commentRules?.trim()) return true;
|
|
276
|
+
return commentRules.split(/[,\s]+/).some((rule) => rule.trim() === ruleId);
|
|
277
|
+
};
|
|
278
|
+
const filterIgnoredDiagnostics = (diagnostics, config, rootDirectory) => {
|
|
279
|
+
const ignoredRules = new Set(Array.isArray(config.ignore?.rules) ? config.ignore.rules : []);
|
|
280
|
+
const ignoredFilePatterns = compileIgnoredFilePatterns(config);
|
|
281
|
+
const textComponentNames = new Set(Array.isArray(config.textComponents) ? config.textComponents : []);
|
|
282
|
+
const hasTextComponents = textComponentNames.size > 0;
|
|
283
|
+
const getFileLines = createFileLinesCache(rootDirectory);
|
|
284
|
+
return diagnostics.filter((diagnostic) => {
|
|
285
|
+
const ruleIdentifier = `${diagnostic.plugin}/${diagnostic.rule}`;
|
|
286
|
+
if (ignoredRules.has(ruleIdentifier)) return false;
|
|
287
|
+
if (isFileIgnoredByPatterns(diagnostic.filePath, rootDirectory, ignoredFilePatterns)) return false;
|
|
288
|
+
if (hasTextComponents && diagnostic.rule === "rn-no-raw-text" && diagnostic.line > 0) {
|
|
289
|
+
const lines = getFileLines(diagnostic.filePath);
|
|
290
|
+
if (lines && isInsideTextComponent(lines, diagnostic.line, textComponentNames)) return false;
|
|
291
|
+
}
|
|
292
|
+
return true;
|
|
293
|
+
});
|
|
294
|
+
};
|
|
295
|
+
const filterInlineSuppressions = (diagnostics, rootDirectory) => {
|
|
296
|
+
const getFileLines = createFileLinesCache(rootDirectory);
|
|
288
297
|
return diagnostics.filter((diagnostic) => {
|
|
289
298
|
if (diagnostic.line <= 0) return true;
|
|
290
299
|
const lines = getFileLines(diagnostic.filePath);
|
|
@@ -296,9 +305,9 @@ const filterInlineSuppressions = (diagnostics, rootDirectory) => {
|
|
|
296
305
|
if (lineMatch && isRuleSuppressed(lineMatch[1], ruleId)) return false;
|
|
297
306
|
}
|
|
298
307
|
if (diagnostic.line >= 2) {
|
|
299
|
-
const
|
|
300
|
-
if (
|
|
301
|
-
const nextLineMatch =
|
|
308
|
+
const previousLine = lines[diagnostic.line - 2];
|
|
309
|
+
if (previousLine) {
|
|
310
|
+
const nextLineMatch = previousLine.match(DISABLE_NEXT_LINE_PATTERN);
|
|
302
311
|
if (nextLineMatch && isRuleSuppressed(nextLineMatch[1], ruleId)) return false;
|
|
303
312
|
}
|
|
304
313
|
}
|
|
@@ -685,8 +694,8 @@ const discoverProject = (directory) => {
|
|
|
685
694
|
//#region src/utils/load-config.ts
|
|
686
695
|
const CONFIG_FILENAME = "react-doctor.config.json";
|
|
687
696
|
const PACKAGE_JSON_CONFIG_KEY = "reactDoctor";
|
|
688
|
-
const
|
|
689
|
-
const configFilePath = path.join(
|
|
697
|
+
const loadConfigFromDirectory = (directory) => {
|
|
698
|
+
const configFilePath = path.join(directory, CONFIG_FILENAME);
|
|
690
699
|
if (isFile(configFilePath)) try {
|
|
691
700
|
const fileContent = fs.readFileSync(configFilePath, "utf-8");
|
|
692
701
|
const parsed = JSON.parse(fileContent);
|
|
@@ -695,7 +704,7 @@ const loadConfig = (rootDirectory) => {
|
|
|
695
704
|
} catch (error) {
|
|
696
705
|
console.warn(`Warning: Failed to parse ${CONFIG_FILENAME}: ${error instanceof Error ? error.message : String(error)}`);
|
|
697
706
|
}
|
|
698
|
-
const packageJsonPath = path.join(
|
|
707
|
+
const packageJsonPath = path.join(directory, "package.json");
|
|
699
708
|
if (isFile(packageJsonPath)) try {
|
|
700
709
|
const fileContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
701
710
|
const embeddedConfig = JSON.parse(fileContent)[PACKAGE_JSON_CONFIG_KEY];
|
|
@@ -705,6 +714,17 @@ const loadConfig = (rootDirectory) => {
|
|
|
705
714
|
}
|
|
706
715
|
return null;
|
|
707
716
|
};
|
|
717
|
+
const loadConfig = (rootDirectory) => {
|
|
718
|
+
const localConfig = loadConfigFromDirectory(rootDirectory);
|
|
719
|
+
if (localConfig) return localConfig;
|
|
720
|
+
let ancestorDirectory = path.dirname(rootDirectory);
|
|
721
|
+
while (ancestorDirectory !== path.dirname(ancestorDirectory)) {
|
|
722
|
+
const ancestorConfig = loadConfigFromDirectory(ancestorDirectory);
|
|
723
|
+
if (ancestorConfig) return ancestorConfig;
|
|
724
|
+
ancestorDirectory = path.dirname(ancestorDirectory);
|
|
725
|
+
}
|
|
726
|
+
return null;
|
|
727
|
+
};
|
|
708
728
|
|
|
709
729
|
//#endregion
|
|
710
730
|
//#region src/utils/resolve-lint-include-paths.ts
|
|
@@ -915,7 +935,37 @@ const REACT_COMPILER_RULES = {
|
|
|
915
935
|
"react-hooks-js/incompatible-library": "error",
|
|
916
936
|
"react-hooks-js/todo": "error"
|
|
917
937
|
};
|
|
918
|
-
const
|
|
938
|
+
const BUILTIN_REACT_RULES = {
|
|
939
|
+
"react/rules-of-hooks": "error",
|
|
940
|
+
"react/no-direct-mutation-state": "error",
|
|
941
|
+
"react/jsx-no-duplicate-props": "error",
|
|
942
|
+
"react/jsx-key": "error",
|
|
943
|
+
"react/no-children-prop": "warn",
|
|
944
|
+
"react/no-danger": "warn",
|
|
945
|
+
"react/jsx-no-script-url": "error",
|
|
946
|
+
"react/no-render-return-value": "warn",
|
|
947
|
+
"react/no-string-refs": "warn",
|
|
948
|
+
"react/no-is-mounted": "warn",
|
|
949
|
+
"react/require-render-return": "error",
|
|
950
|
+
"react/no-unknown-property": "warn"
|
|
951
|
+
};
|
|
952
|
+
const BUILTIN_A11Y_RULES = {
|
|
953
|
+
"jsx-a11y/alt-text": "error",
|
|
954
|
+
"jsx-a11y/anchor-is-valid": "warn",
|
|
955
|
+
"jsx-a11y/click-events-have-key-events": "warn",
|
|
956
|
+
"jsx-a11y/no-static-element-interactions": "warn",
|
|
957
|
+
"jsx-a11y/role-has-required-aria-props": "error",
|
|
958
|
+
"jsx-a11y/no-autofocus": "warn",
|
|
959
|
+
"jsx-a11y/heading-has-content": "warn",
|
|
960
|
+
"jsx-a11y/html-has-lang": "warn",
|
|
961
|
+
"jsx-a11y/no-redundant-roles": "warn",
|
|
962
|
+
"jsx-a11y/scope": "warn",
|
|
963
|
+
"jsx-a11y/tabindex-no-positive": "warn",
|
|
964
|
+
"jsx-a11y/label-has-associated-control": "warn",
|
|
965
|
+
"jsx-a11y/no-distracting-elements": "error",
|
|
966
|
+
"jsx-a11y/iframe-has-title": "warn"
|
|
967
|
+
};
|
|
968
|
+
const createOxlintConfig = ({ pluginPath, framework, hasReactCompiler, customRulesOnly = false }) => ({
|
|
919
969
|
categories: {
|
|
920
970
|
correctness: "off",
|
|
921
971
|
suspicious: "off",
|
|
@@ -930,39 +980,14 @@ const createOxlintConfig = ({ pluginPath, framework, hasReactCompiler }) => ({
|
|
|
930
980
|
"jsx-a11y",
|
|
931
981
|
...hasReactCompiler ? [] : ["react-perf"]
|
|
932
982
|
],
|
|
933
|
-
jsPlugins: [...hasReactCompiler ? [{
|
|
983
|
+
jsPlugins: [...hasReactCompiler && !customRulesOnly ? [{
|
|
934
984
|
name: "react-hooks-js",
|
|
935
985
|
specifier: esmRequire$1.resolve("eslint-plugin-react-hooks")
|
|
936
986
|
}] : [], pluginPath],
|
|
937
987
|
rules: {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
"react/jsx-key": "error",
|
|
942
|
-
"react/no-children-prop": "warn",
|
|
943
|
-
"react/no-danger": "warn",
|
|
944
|
-
"react/jsx-no-script-url": "error",
|
|
945
|
-
"react/no-render-return-value": "warn",
|
|
946
|
-
"react/no-string-refs": "warn",
|
|
947
|
-
"react/no-is-mounted": "warn",
|
|
948
|
-
"react/require-render-return": "error",
|
|
949
|
-
"react/no-unknown-property": "warn",
|
|
950
|
-
"jsx-a11y/alt-text": "error",
|
|
951
|
-
"jsx-a11y/anchor-is-valid": "warn",
|
|
952
|
-
"jsx-a11y/click-events-have-key-events": "warn",
|
|
953
|
-
"jsx-a11y/no-static-element-interactions": "warn",
|
|
954
|
-
"jsx-a11y/no-noninteractive-element-interactions": "warn",
|
|
955
|
-
"jsx-a11y/role-has-required-aria-props": "error",
|
|
956
|
-
"jsx-a11y/no-autofocus": "warn",
|
|
957
|
-
"jsx-a11y/heading-has-content": "warn",
|
|
958
|
-
"jsx-a11y/html-has-lang": "warn",
|
|
959
|
-
"jsx-a11y/no-redundant-roles": "warn",
|
|
960
|
-
"jsx-a11y/scope": "warn",
|
|
961
|
-
"jsx-a11y/tabindex-no-positive": "warn",
|
|
962
|
-
"jsx-a11y/label-has-associated-control": "warn",
|
|
963
|
-
"jsx-a11y/no-distracting-elements": "error",
|
|
964
|
-
"jsx-a11y/iframe-has-title": "warn",
|
|
965
|
-
...hasReactCompiler ? REACT_COMPILER_RULES : {},
|
|
988
|
+
...customRulesOnly ? {} : BUILTIN_REACT_RULES,
|
|
989
|
+
...customRulesOnly ? {} : BUILTIN_A11Y_RULES,
|
|
990
|
+
...hasReactCompiler && !customRulesOnly ? REACT_COMPILER_RULES : {},
|
|
966
991
|
"react-doctor/no-derived-state-effect": "error",
|
|
967
992
|
"react-doctor/no-fetch-in-effect": "error",
|
|
968
993
|
"react-doctor/no-cascading-set-state": "warn",
|
|
@@ -1233,7 +1258,9 @@ const batchIncludePaths = (baseArgs, includePaths) => {
|
|
|
1233
1258
|
let currentBatchLength = baseArgsLength;
|
|
1234
1259
|
for (const filePath of includePaths) {
|
|
1235
1260
|
const entryLength = filePath.length + 1;
|
|
1236
|
-
|
|
1261
|
+
const exceedsArgLength = currentBatch.length > 0 && currentBatchLength + entryLength > SPAWN_ARGS_MAX_LENGTH_CHARS;
|
|
1262
|
+
const exceedsFileCount = currentBatch.length >= OXLINT_MAX_FILES_PER_BATCH;
|
|
1263
|
+
if (exceedsArgLength || exceedsFileCount) {
|
|
1237
1264
|
batches.push(currentBatch);
|
|
1238
1265
|
currentBatch = [];
|
|
1239
1266
|
currentBatchLength = baseArgsLength;
|
|
@@ -1295,13 +1322,14 @@ const parseOxlintOutput = (stdout) => {
|
|
|
1295
1322
|
};
|
|
1296
1323
|
});
|
|
1297
1324
|
};
|
|
1298
|
-
const runOxlint = async (rootDirectory, hasTypeScript, framework, hasReactCompiler, includePaths, nodeBinaryPath = process.execPath) => {
|
|
1325
|
+
const runOxlint = async (rootDirectory, hasTypeScript, framework, hasReactCompiler, includePaths, nodeBinaryPath = process.execPath, customRulesOnly = false) => {
|
|
1299
1326
|
if (includePaths !== void 0 && includePaths.length === 0) return [];
|
|
1300
1327
|
const configPath = path.join(os.tmpdir(), `react-doctor-oxlintrc-${process.pid}.json`);
|
|
1301
1328
|
const config = createOxlintConfig({
|
|
1302
1329
|
pluginPath: resolvePluginPath(),
|
|
1303
1330
|
framework,
|
|
1304
|
-
hasReactCompiler
|
|
1331
|
+
hasReactCompiler,
|
|
1332
|
+
customRulesOnly
|
|
1305
1333
|
});
|
|
1306
1334
|
const restoreDisableDirectives = neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
1307
1335
|
try {
|
|
@@ -1421,7 +1449,8 @@ const diagnose = async (directory, options = {}) => {
|
|
|
1421
1449
|
if (!projectInfo.reactVersion) throw new Error("No React dependency found in package.json");
|
|
1422
1450
|
const lintIncludePaths = computeJsxIncludePaths(includePaths) ?? resolveLintIncludePaths(resolvedDirectory, userConfig);
|
|
1423
1451
|
const emptyDiagnostics = [];
|
|
1424
|
-
const
|
|
1452
|
+
const effectiveCustomRulesOnly = userConfig?.customRulesOnly ?? false;
|
|
1453
|
+
const lintPromise = effectiveLint ? runOxlint(resolvedDirectory, projectInfo.hasTypeScript, projectInfo.framework, projectInfo.hasReactCompiler, lintIncludePaths, void 0, effectiveCustomRulesOnly).catch((error) => {
|
|
1425
1454
|
console.error("Lint failed:", error);
|
|
1426
1455
|
return emptyDiagnostics;
|
|
1427
1456
|
}) : Promise.resolve(emptyDiagnostics);
|