react-doctor 0.5.6-dev.93b796d → 0.5.6-dev.a9d2713
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 +341 -181
- package/dist/index.d.ts +19 -0
- package/dist/index.js +257 -166
- package/dist/lsp.js +269 -178
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4ecd915d-c650-5f04-bc07-b82e872a8962")}catch(e){}}();
|
|
3
3
|
import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as NFS from "node:fs";
|
|
@@ -17,6 +17,7 @@ import * as NodeUrl from "node:url";
|
|
|
17
17
|
import { fileURLToPath } from "node:url";
|
|
18
18
|
import { createJiti } from "jiti";
|
|
19
19
|
import * as Crypto from "node:crypto";
|
|
20
|
+
import { createHash } from "node:crypto";
|
|
20
21
|
import { gzipSync } from "node:zlib";
|
|
21
22
|
//#region ../../node_modules/.pnpm/effect@4.0.0-beta.70/node_modules/effect/dist/Pipeable.js
|
|
22
23
|
/**
|
|
@@ -19256,7 +19257,8 @@ var Diagnostic = class extends Class("Diagnostic")({
|
|
|
19256
19257
|
category: String$1,
|
|
19257
19258
|
fileContext: optional(Literals(["test", "story"])),
|
|
19258
19259
|
suppressionHint: optional(String$1),
|
|
19259
|
-
relatedLocations: optional(ArraySchema(DiagnosticRelatedLocation))
|
|
19260
|
+
relatedLocations: optional(ArraySchema(DiagnosticRelatedLocation)),
|
|
19261
|
+
fixGroupId: optional(String$1)
|
|
19260
19262
|
}) {};
|
|
19261
19263
|
const JsonReportMode = Literals([
|
|
19262
19264
|
"full",
|
|
@@ -19298,6 +19300,7 @@ var JsonReportProjectEntry = class extends Class("JsonReportProjectEntry")({
|
|
|
19298
19300
|
score: Unknown,
|
|
19299
19301
|
skippedChecks: ArraySchema(String$1),
|
|
19300
19302
|
skippedCheckReasons: optional(Record$1(String$1, String$1)),
|
|
19303
|
+
scannedFileCount: optional(Number$1),
|
|
19301
19304
|
elapsedMilliseconds: Number$1
|
|
19302
19305
|
}) {};
|
|
19303
19306
|
/**
|
|
@@ -32724,6 +32727,7 @@ const isLargeMinifiedFile = (absolutePath) => {
|
|
|
32724
32727
|
if (sizeBytes < 2e4) return false;
|
|
32725
32728
|
return isMinifiedSource(absolutePath);
|
|
32726
32729
|
};
|
|
32730
|
+
const isErrnoException = (error) => error instanceof Error && "code" in error;
|
|
32727
32731
|
const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
32728
32732
|
"EACCES",
|
|
32729
32733
|
"EPERM",
|
|
@@ -32733,11 +32737,7 @@ const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
|
32733
32737
|
"ELOOP",
|
|
32734
32738
|
"ENAMETOOLONG"
|
|
32735
32739
|
]);
|
|
32736
|
-
const isIgnorableReaddirError = (error) =>
|
|
32737
|
-
if (typeof error !== "object" || error === null) return false;
|
|
32738
|
-
const errorCode = error.code;
|
|
32739
|
-
return typeof errorCode === "string" && IGNORABLE_READDIR_ERROR_CODES.has(errorCode);
|
|
32740
|
-
};
|
|
32740
|
+
const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
|
|
32741
32741
|
const readDirectoryEntries = (directoryPath) => {
|
|
32742
32742
|
try {
|
|
32743
32743
|
return NFS.readdirSync(directoryPath, { withFileTypes: true });
|
|
@@ -32787,7 +32787,7 @@ const readPackageJsonUncached = (packageJsonPath) => {
|
|
|
32787
32787
|
return JSON.parse(NFS.readFileSync(packageJsonPath, "utf-8"));
|
|
32788
32788
|
} catch (error) {
|
|
32789
32789
|
if (error instanceof SyntaxError) return {};
|
|
32790
|
-
if (error
|
|
32790
|
+
if (isErrnoException(error)) {
|
|
32791
32791
|
const { code } = error;
|
|
32792
32792
|
if (code === "EISDIR" || code === "EACCES" || code === "EPERM" || code === "ENOENT") return {};
|
|
32793
32793
|
}
|
|
@@ -33512,17 +33512,13 @@ const isPackageJsonReactNativeAware = (packageJson) => {
|
|
|
33512
33512
|
return false;
|
|
33513
33513
|
};
|
|
33514
33514
|
const hasReactNativeWorkspaceAnywhere = (rootDirectory, rootPackageJson) => someWorkspacePackageJson(rootDirectory, rootPackageJson, isPackageJsonReactNativeAware);
|
|
33515
|
-
const
|
|
33516
|
-
const spec = packageJson.dependencies?.
|
|
33515
|
+
const getDependencySpec = (packageJson, packageName) => {
|
|
33516
|
+
const spec = packageJson.dependencies?.[packageName] ?? packageJson.devDependencies?.[packageName] ?? packageJson.peerDependencies?.[packageName] ?? packageJson.optionalDependencies?.[packageName];
|
|
33517
33517
|
return typeof spec === "string" ? spec : null;
|
|
33518
33518
|
};
|
|
33519
|
-
const findExpoVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson,
|
|
33519
|
+
const findExpoVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, "expo"));
|
|
33520
33520
|
const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
|
|
33521
|
-
const
|
|
33522
|
-
const spec = packageJson.dependencies?.["@shopify/flash-list"] ?? packageJson.devDependencies?.["@shopify/flash-list"] ?? packageJson.peerDependencies?.["@shopify/flash-list"] ?? packageJson.optionalDependencies?.["@shopify/flash-list"];
|
|
33523
|
-
return typeof spec === "string" ? spec : null;
|
|
33524
|
-
};
|
|
33525
|
-
const findShopifyFlashListVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, getShopifyFlashListDependencySpec);
|
|
33521
|
+
const findShopifyFlashListVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, SHOPIFY_FLASH_LIST_PACKAGE_NAME));
|
|
33526
33522
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
33527
33523
|
if (version === null || !isCatalogReference(version)) return version;
|
|
33528
33524
|
const catalogName = extractCatalogName(version);
|
|
@@ -33534,11 +33530,7 @@ const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson,
|
|
|
33534
33530
|
if (!isFile(monorepoPackageJsonPath)) return version;
|
|
33535
33531
|
return resolveCatalogVersion(readPackageJson(monorepoPackageJsonPath), packageName, monorepoRoot, catalogName) ?? version;
|
|
33536
33532
|
};
|
|
33537
|
-
const
|
|
33538
|
-
const spec = packageJson.dependencies?.next ?? packageJson.devDependencies?.next ?? packageJson.peerDependencies?.next ?? packageJson.optionalDependencies?.next;
|
|
33539
|
-
return typeof spec === "string" ? spec : null;
|
|
33540
|
-
};
|
|
33541
|
-
const findNextjsVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, getNextjsDependencySpec);
|
|
33533
|
+
const findNextjsVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, "next"));
|
|
33542
33534
|
const getPreactVersion = (packageJson) => {
|
|
33543
33535
|
return {
|
|
33544
33536
|
...packageJson.peerDependencies,
|
|
@@ -33671,6 +33663,13 @@ const APP_ONLY_RULE_KEYS = new Set([
|
|
|
33671
33663
|
]);
|
|
33672
33664
|
const COMPILER_CLEANUP_BUCKET = "compiler-cleanup";
|
|
33673
33665
|
const COMPILER_CLEANUP_RULE_KEYS = new Set(["react-doctor/react-compiler-no-manual-memoization"]);
|
|
33666
|
+
const ROOT_CAUSE_GROUPABLE_RULE_KEYS = new Set([
|
|
33667
|
+
"react-doctor/no-derived-state",
|
|
33668
|
+
"react-doctor/no-derived-state-effect",
|
|
33669
|
+
"react-doctor/no-derived-useState",
|
|
33670
|
+
"react-doctor/no-adjust-state-on-prop-change",
|
|
33671
|
+
"react-doctor/no-reset-all-state-on-prop-change"
|
|
33672
|
+
]);
|
|
33674
33673
|
const MAX_GLOB_PATTERN_LENGTH_CHARS = 1024;
|
|
33675
33674
|
const CONFIG_CACHE_TTL_MS = 300 * 1e3;
|
|
33676
33675
|
const SOCKET_FREE_PURL_API_BASE = "https://firewall-api.socket.dev/purl";
|
|
@@ -34123,6 +34122,7 @@ const isTailwindAtLeast = (detected, required) => {
|
|
|
34123
34122
|
if (detected.major !== required.major) return detected.major > required.major;
|
|
34124
34123
|
return detected.minor >= required.minor;
|
|
34125
34124
|
};
|
|
34125
|
+
const messageFromUnknown = (error) => error instanceof Error ? error.message : String(error);
|
|
34126
34126
|
var InvalidGlobPatternError = class extends Error {
|
|
34127
34127
|
pattern;
|
|
34128
34128
|
reason;
|
|
@@ -34151,7 +34151,7 @@ const compileGlobPattern = (rawPattern) => {
|
|
|
34151
34151
|
try {
|
|
34152
34152
|
return import_picomatch.default.makeRe(normalizeGlobPattern(rawPattern), PICOMATCH_OPTIONS);
|
|
34153
34153
|
} catch (caughtError) {
|
|
34154
|
-
throw new InvalidGlobPatternError(rawPattern,
|
|
34154
|
+
throw new InvalidGlobPatternError(rawPattern, messageFromUnknown(caughtError));
|
|
34155
34155
|
}
|
|
34156
34156
|
};
|
|
34157
34157
|
const compileGlobPatternsLenient = (patterns, onInvalid) => {
|
|
@@ -34247,115 +34247,6 @@ const buildRuleSeverityControls = (config) => {
|
|
|
34247
34247
|
...config.buckets !== void 0 ? { buckets: config.buckets } : {}
|
|
34248
34248
|
};
|
|
34249
34249
|
};
|
|
34250
|
-
const JSX_OPENER_TAG_PATTERN = /<[A-Za-z][\w.]*/g;
|
|
34251
|
-
const JSX_TAG_NAME_FOLLOW = /[A-Za-z]/;
|
|
34252
|
-
const isOpenerMatchInsideLineComment = (line, openerCharIndex) => {
|
|
34253
|
-
let stringDelimiter = null;
|
|
34254
|
-
for (let charIndex = 0; charIndex < openerCharIndex; charIndex++) {
|
|
34255
|
-
const character = line[charIndex];
|
|
34256
|
-
if (stringDelimiter !== null) {
|
|
34257
|
-
if (character === "\\") {
|
|
34258
|
-
charIndex++;
|
|
34259
|
-
continue;
|
|
34260
|
-
}
|
|
34261
|
-
if (character === stringDelimiter) stringDelimiter = null;
|
|
34262
|
-
continue;
|
|
34263
|
-
}
|
|
34264
|
-
if (character === "\"" || character === "'" || character === "`") {
|
|
34265
|
-
stringDelimiter = character;
|
|
34266
|
-
continue;
|
|
34267
|
-
}
|
|
34268
|
-
if (character === "/" && line[charIndex + 1] === "/") return true;
|
|
34269
|
-
}
|
|
34270
|
-
return false;
|
|
34271
|
-
};
|
|
34272
|
-
const findOpenerTagOnLine = (line) => {
|
|
34273
|
-
for (const match of line.matchAll(JSX_OPENER_TAG_PATTERN)) {
|
|
34274
|
-
if (match.index === void 0) continue;
|
|
34275
|
-
if (!isOpenerMatchInsideLineComment(line, match.index)) return { startCharIndex: match.index + match[0].length };
|
|
34276
|
-
}
|
|
34277
|
-
return null;
|
|
34278
|
-
};
|
|
34279
|
-
const findJsxOpenerSpan = (lines, openerLineIndex) => {
|
|
34280
|
-
const openerLine = lines[openerLineIndex];
|
|
34281
|
-
if (openerLine === void 0) return null;
|
|
34282
|
-
const opener = findOpenerTagOnLine(openerLine);
|
|
34283
|
-
if (!opener) return null;
|
|
34284
|
-
const lookaheadLimit = Math.min(lines.length, openerLineIndex + 32);
|
|
34285
|
-
let braceDepth = 0;
|
|
34286
|
-
let innerAngleDepth = 0;
|
|
34287
|
-
let stringDelimiter = null;
|
|
34288
|
-
for (let lineIndex = openerLineIndex; lineIndex < lookaheadLimit; lineIndex++) {
|
|
34289
|
-
const currentLine = lines[lineIndex];
|
|
34290
|
-
const startCharForLine = lineIndex === openerLineIndex ? opener.startCharIndex : 0;
|
|
34291
|
-
for (let charIndex = startCharForLine; charIndex < currentLine.length; charIndex++) {
|
|
34292
|
-
const character = currentLine[charIndex];
|
|
34293
|
-
if (stringDelimiter !== null) {
|
|
34294
|
-
if (character === "\\") {
|
|
34295
|
-
charIndex++;
|
|
34296
|
-
continue;
|
|
34297
|
-
}
|
|
34298
|
-
if (character === stringDelimiter) stringDelimiter = null;
|
|
34299
|
-
continue;
|
|
34300
|
-
}
|
|
34301
|
-
if (character === "\"" || character === "'" || character === "`") {
|
|
34302
|
-
stringDelimiter = character;
|
|
34303
|
-
continue;
|
|
34304
|
-
}
|
|
34305
|
-
if (character === "{") {
|
|
34306
|
-
braceDepth++;
|
|
34307
|
-
continue;
|
|
34308
|
-
}
|
|
34309
|
-
if (character === "}") {
|
|
34310
|
-
braceDepth--;
|
|
34311
|
-
continue;
|
|
34312
|
-
}
|
|
34313
|
-
if (braceDepth !== 0) continue;
|
|
34314
|
-
if (character === "<") {
|
|
34315
|
-
const followCharacter = currentLine[charIndex + 1];
|
|
34316
|
-
if (followCharacter !== void 0 && JSX_TAG_NAME_FOLLOW.test(followCharacter)) innerAngleDepth++;
|
|
34317
|
-
continue;
|
|
34318
|
-
}
|
|
34319
|
-
if (character !== ">") continue;
|
|
34320
|
-
const previousCharacter = currentLine[charIndex - 1];
|
|
34321
|
-
const nextCharacter = currentLine[charIndex + 1];
|
|
34322
|
-
if (previousCharacter === "=" || nextCharacter === "=") continue;
|
|
34323
|
-
if (innerAngleDepth > 0) {
|
|
34324
|
-
innerAngleDepth--;
|
|
34325
|
-
continue;
|
|
34326
|
-
}
|
|
34327
|
-
return lineIndex;
|
|
34328
|
-
}
|
|
34329
|
-
}
|
|
34330
|
-
return null;
|
|
34331
|
-
};
|
|
34332
|
-
const findEnclosingMultilineJsxOpenerStart = (lines, diagnosticLineIndex) => {
|
|
34333
|
-
for (let candidateIndex = diagnosticLineIndex - 1; candidateIndex >= 0 && diagnosticLineIndex - candidateIndex <= 32; candidateIndex--) {
|
|
34334
|
-
const openerCloseIndex = findJsxOpenerSpan(lines, candidateIndex);
|
|
34335
|
-
if (openerCloseIndex !== null && openerCloseIndex >= diagnosticLineIndex) return candidateIndex;
|
|
34336
|
-
}
|
|
34337
|
-
return null;
|
|
34338
|
-
};
|
|
34339
|
-
const DISABLE_NEXT_LINE_PATTERN = /(?:\/\/|\/\*)\s*react-doctor-disable-next-line\b(?:\s+([^\r\n]*?))?\s*(?:\*\/)?\s*\}?\s*$/;
|
|
34340
|
-
const findStackedDisableCommentsAbove = (lines, anchorIndex) => {
|
|
34341
|
-
const collected = [];
|
|
34342
|
-
let isStillInChain = true;
|
|
34343
|
-
for (let candidateIndex = anchorIndex - 1; candidateIndex >= 0 && anchorIndex - candidateIndex <= 10; candidateIndex--) {
|
|
34344
|
-
const candidateLine = lines[candidateIndex];
|
|
34345
|
-
if (candidateLine === void 0) break;
|
|
34346
|
-
const match = candidateLine.match(DISABLE_NEXT_LINE_PATTERN);
|
|
34347
|
-
if (match) {
|
|
34348
|
-
collected.push({
|
|
34349
|
-
commentLineIndex: candidateIndex,
|
|
34350
|
-
ruleList: match[1],
|
|
34351
|
-
isInChain: isStillInChain
|
|
34352
|
-
});
|
|
34353
|
-
continue;
|
|
34354
|
-
}
|
|
34355
|
-
isStillInChain = false;
|
|
34356
|
-
}
|
|
34357
|
-
return collected;
|
|
34358
|
-
};
|
|
34359
34250
|
const LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY = {
|
|
34360
34251
|
"effect/no-adjust-state-on-prop-change": "react-doctor/no-adjust-state-on-prop-change",
|
|
34361
34252
|
"effect/no-chain-state-updates": "react-doctor/no-chain-state-updates",
|
|
@@ -34480,7 +34371,13 @@ for (const [legacyRuleKey, nativeRuleKey] of Object.entries(LEGACY_RULE_KEY_TO_N
|
|
|
34480
34371
|
}
|
|
34481
34372
|
const getLegacyRuleKeysForNative = (ruleKey) => NATIVE_RULE_KEY_TO_LEGACY_RULE_KEYS.get(ruleKey) ?? [];
|
|
34482
34373
|
const canonicalizeRuleKey = (ruleKey) => LEGACY_RULE_KEY_TO_NATIVE_RULE_KEY[ruleKey] ?? ruleKey;
|
|
34483
|
-
const
|
|
34374
|
+
const isReactDoctorShortIdOf = (bareRuleKey, qualifiedRuleKey) => !bareRuleKey.includes("/") && qualifiedRuleKey === `react-doctor/${bareRuleKey}`;
|
|
34375
|
+
const isSameRuleKey = (candidateRuleKey, targetRuleKey) => {
|
|
34376
|
+
const canonicalCandidate = canonicalizeRuleKey(candidateRuleKey);
|
|
34377
|
+
const canonicalTarget = canonicalizeRuleKey(targetRuleKey);
|
|
34378
|
+
if (canonicalCandidate === canonicalTarget) return true;
|
|
34379
|
+
return isReactDoctorShortIdOf(canonicalCandidate, canonicalTarget) || isReactDoctorShortIdOf(canonicalTarget, canonicalCandidate);
|
|
34380
|
+
};
|
|
34484
34381
|
const getEquivalentRuleKeys = (ruleKey) => {
|
|
34485
34382
|
const nativeRuleKey = canonicalizeRuleKey(ruleKey);
|
|
34486
34383
|
return [nativeRuleKey, ...getLegacyRuleKeysForNative(nativeRuleKey)];
|
|
@@ -34490,12 +34387,182 @@ const stripDescriptionTail = (ruleList) => {
|
|
|
34490
34387
|
if (!descriptionMatch || descriptionMatch.index === void 0) return ruleList;
|
|
34491
34388
|
return ruleList.slice(0, descriptionMatch.index);
|
|
34492
34389
|
};
|
|
34493
|
-
const
|
|
34390
|
+
const tokenizeRuleList = (ruleList) => {
|
|
34494
34391
|
const trimmed = ruleList?.trim();
|
|
34495
|
-
if (!trimmed) return
|
|
34392
|
+
if (!trimmed) return [];
|
|
34496
34393
|
const ruleSection = stripDescriptionTail(trimmed).trim();
|
|
34497
|
-
if (!ruleSection) return
|
|
34498
|
-
return ruleSection.split(/[,\s]+/).
|
|
34394
|
+
if (!ruleSection) return [];
|
|
34395
|
+
return ruleSection.split(/[,\s]+/).map((token) => token.trim()).filter(Boolean);
|
|
34396
|
+
};
|
|
34397
|
+
const FOREIGN_INLINE_DISABLE_PATTERN = /(?:\/\/|\/\*)[ \t]*(eslint|oxlint)-disable-(next-line|line)(?![\w-])([^\r\n]*)/;
|
|
34398
|
+
const FOREIGN_BLOCK_DISABLE_PATTERN = /\/\*[ \t]*(eslint|oxlint)-disable(?![\w-])([^*\r\n]*)/;
|
|
34399
|
+
const FOREIGN_BLOCK_ENABLE_PATTERN = /\/\*[ \t]*(?:eslint|oxlint)-enable(?![\w-])([^*\r\n]*)/;
|
|
34400
|
+
const buildHint = (tool, token, ruleId) => `oxlint matches plugin rules only by their full name, so \`${token}\` in your ${tool}-disable comment does not silence \`${ruleId}\` — change it to \`${ruleId}\`.`;
|
|
34401
|
+
const tokenMisnamesRule = (token, ruleId) => token !== ruleId && isSameRuleKey(token, ruleId);
|
|
34402
|
+
const detectInlineNearMiss = (lines, diagnosticLineIndex, ruleId) => {
|
|
34403
|
+
const candidates = [{
|
|
34404
|
+
line: lines[diagnosticLineIndex],
|
|
34405
|
+
requiredScope: "line"
|
|
34406
|
+
}, {
|
|
34407
|
+
line: lines[diagnosticLineIndex - 1],
|
|
34408
|
+
requiredScope: "next-line"
|
|
34409
|
+
}];
|
|
34410
|
+
for (const { line, requiredScope } of candidates) {
|
|
34411
|
+
const match = line?.match(FOREIGN_INLINE_DISABLE_PATTERN);
|
|
34412
|
+
if (!match) continue;
|
|
34413
|
+
const [, tool, scope, ruleList] = match;
|
|
34414
|
+
if (scope !== requiredScope) continue;
|
|
34415
|
+
const tokens = tokenizeRuleList(ruleList);
|
|
34416
|
+
if (tokens.includes(ruleId)) continue;
|
|
34417
|
+
for (const token of tokens) if (tokenMisnamesRule(token, ruleId)) return buildHint(tool, token, ruleId);
|
|
34418
|
+
}
|
|
34419
|
+
return null;
|
|
34420
|
+
};
|
|
34421
|
+
const detectBlockNearMiss = (lines, diagnosticLineIndex, ruleId) => {
|
|
34422
|
+
let openMisname = null;
|
|
34423
|
+
const lastLineIndex = Math.min(diagnosticLineIndex, lines.length - 1);
|
|
34424
|
+
for (let lineIndex = 0; lineIndex <= lastLineIndex; lineIndex++) {
|
|
34425
|
+
const line = lines[lineIndex];
|
|
34426
|
+
if (line === void 0 || !line.includes("-disable") && !line.includes("-enable")) continue;
|
|
34427
|
+
const disableMatch = line.match(FOREIGN_BLOCK_DISABLE_PATTERN);
|
|
34428
|
+
if (disableMatch) {
|
|
34429
|
+
const [, tool, ruleList] = disableMatch;
|
|
34430
|
+
const tokens = tokenizeRuleList(ruleList);
|
|
34431
|
+
if (tokens.includes(ruleId)) openMisname = null;
|
|
34432
|
+
else {
|
|
34433
|
+
const misnamed = tokens.find((token) => tokenMisnamesRule(token, ruleId));
|
|
34434
|
+
if (misnamed) openMisname = {
|
|
34435
|
+
tool,
|
|
34436
|
+
token: misnamed
|
|
34437
|
+
};
|
|
34438
|
+
}
|
|
34439
|
+
continue;
|
|
34440
|
+
}
|
|
34441
|
+
const enableMatch = line.match(FOREIGN_BLOCK_ENABLE_PATTERN);
|
|
34442
|
+
if (enableMatch) {
|
|
34443
|
+
const enabledRules = tokenizeRuleList(enableMatch[1]);
|
|
34444
|
+
if (enabledRules.length === 0 || enabledRules.some((rule) => isSameRuleKey(rule, ruleId))) openMisname = null;
|
|
34445
|
+
}
|
|
34446
|
+
}
|
|
34447
|
+
return openMisname ? buildHint(openMisname.tool, openMisname.token, ruleId) : null;
|
|
34448
|
+
};
|
|
34449
|
+
const detectForeignDisableNearMiss = (lines, diagnosticLineIndex, ruleId) => {
|
|
34450
|
+
if (!ruleId.startsWith("react-doctor/")) return null;
|
|
34451
|
+
return detectInlineNearMiss(lines, diagnosticLineIndex, ruleId) ?? detectBlockNearMiss(lines, diagnosticLineIndex, ruleId);
|
|
34452
|
+
};
|
|
34453
|
+
const JSX_OPENER_TAG_PATTERN = /<[A-Za-z][\w.]*/g;
|
|
34454
|
+
const JSX_TAG_NAME_FOLLOW = /[A-Za-z]/;
|
|
34455
|
+
const isOpenerMatchInsideLineComment = (line, openerCharIndex) => {
|
|
34456
|
+
let stringDelimiter = null;
|
|
34457
|
+
for (let charIndex = 0; charIndex < openerCharIndex; charIndex++) {
|
|
34458
|
+
const character = line[charIndex];
|
|
34459
|
+
if (stringDelimiter !== null) {
|
|
34460
|
+
if (character === "\\") {
|
|
34461
|
+
charIndex++;
|
|
34462
|
+
continue;
|
|
34463
|
+
}
|
|
34464
|
+
if (character === stringDelimiter) stringDelimiter = null;
|
|
34465
|
+
continue;
|
|
34466
|
+
}
|
|
34467
|
+
if (character === "\"" || character === "'" || character === "`") {
|
|
34468
|
+
stringDelimiter = character;
|
|
34469
|
+
continue;
|
|
34470
|
+
}
|
|
34471
|
+
if (character === "/" && line[charIndex + 1] === "/") return true;
|
|
34472
|
+
}
|
|
34473
|
+
return false;
|
|
34474
|
+
};
|
|
34475
|
+
const findOpenerTagOnLine = (line) => {
|
|
34476
|
+
for (const match of line.matchAll(JSX_OPENER_TAG_PATTERN)) {
|
|
34477
|
+
if (match.index === void 0) continue;
|
|
34478
|
+
if (!isOpenerMatchInsideLineComment(line, match.index)) return { startCharIndex: match.index + match[0].length };
|
|
34479
|
+
}
|
|
34480
|
+
return null;
|
|
34481
|
+
};
|
|
34482
|
+
const findJsxOpenerSpan = (lines, openerLineIndex) => {
|
|
34483
|
+
const openerLine = lines[openerLineIndex];
|
|
34484
|
+
if (openerLine === void 0) return null;
|
|
34485
|
+
const opener = findOpenerTagOnLine(openerLine);
|
|
34486
|
+
if (!opener) return null;
|
|
34487
|
+
const lookaheadLimit = Math.min(lines.length, openerLineIndex + 32);
|
|
34488
|
+
let braceDepth = 0;
|
|
34489
|
+
let innerAngleDepth = 0;
|
|
34490
|
+
let stringDelimiter = null;
|
|
34491
|
+
for (let lineIndex = openerLineIndex; lineIndex < lookaheadLimit; lineIndex++) {
|
|
34492
|
+
const currentLine = lines[lineIndex];
|
|
34493
|
+
const startCharForLine = lineIndex === openerLineIndex ? opener.startCharIndex : 0;
|
|
34494
|
+
for (let charIndex = startCharForLine; charIndex < currentLine.length; charIndex++) {
|
|
34495
|
+
const character = currentLine[charIndex];
|
|
34496
|
+
if (stringDelimiter !== null) {
|
|
34497
|
+
if (character === "\\") {
|
|
34498
|
+
charIndex++;
|
|
34499
|
+
continue;
|
|
34500
|
+
}
|
|
34501
|
+
if (character === stringDelimiter) stringDelimiter = null;
|
|
34502
|
+
continue;
|
|
34503
|
+
}
|
|
34504
|
+
if (character === "\"" || character === "'" || character === "`") {
|
|
34505
|
+
stringDelimiter = character;
|
|
34506
|
+
continue;
|
|
34507
|
+
}
|
|
34508
|
+
if (character === "{") {
|
|
34509
|
+
braceDepth++;
|
|
34510
|
+
continue;
|
|
34511
|
+
}
|
|
34512
|
+
if (character === "}") {
|
|
34513
|
+
braceDepth--;
|
|
34514
|
+
continue;
|
|
34515
|
+
}
|
|
34516
|
+
if (braceDepth !== 0) continue;
|
|
34517
|
+
if (character === "<") {
|
|
34518
|
+
const followCharacter = currentLine[charIndex + 1];
|
|
34519
|
+
if (followCharacter !== void 0 && JSX_TAG_NAME_FOLLOW.test(followCharacter)) innerAngleDepth++;
|
|
34520
|
+
continue;
|
|
34521
|
+
}
|
|
34522
|
+
if (character !== ">") continue;
|
|
34523
|
+
const previousCharacter = currentLine[charIndex - 1];
|
|
34524
|
+
const nextCharacter = currentLine[charIndex + 1];
|
|
34525
|
+
if (previousCharacter === "=" || nextCharacter === "=") continue;
|
|
34526
|
+
if (innerAngleDepth > 0) {
|
|
34527
|
+
innerAngleDepth--;
|
|
34528
|
+
continue;
|
|
34529
|
+
}
|
|
34530
|
+
return lineIndex;
|
|
34531
|
+
}
|
|
34532
|
+
}
|
|
34533
|
+
return null;
|
|
34534
|
+
};
|
|
34535
|
+
const findEnclosingMultilineJsxOpenerStart = (lines, diagnosticLineIndex) => {
|
|
34536
|
+
for (let candidateIndex = diagnosticLineIndex - 1; candidateIndex >= 0 && diagnosticLineIndex - candidateIndex <= 32; candidateIndex--) {
|
|
34537
|
+
const openerCloseIndex = findJsxOpenerSpan(lines, candidateIndex);
|
|
34538
|
+
if (openerCloseIndex !== null && openerCloseIndex >= diagnosticLineIndex) return candidateIndex;
|
|
34539
|
+
}
|
|
34540
|
+
return null;
|
|
34541
|
+
};
|
|
34542
|
+
const DISABLE_NEXT_LINE_PATTERN = /(?:\/\/|\/\*)\s*react-doctor-disable-next-line\b(?:\s+([^\r\n]*?))?\s*(?:\*\/)?\s*\}?\s*$/;
|
|
34543
|
+
const findStackedDisableCommentsAbove = (lines, anchorIndex) => {
|
|
34544
|
+
const collected = [];
|
|
34545
|
+
let isStillInChain = true;
|
|
34546
|
+
for (let candidateIndex = anchorIndex - 1; candidateIndex >= 0 && anchorIndex - candidateIndex <= 10; candidateIndex--) {
|
|
34547
|
+
const candidateLine = lines[candidateIndex];
|
|
34548
|
+
if (candidateLine === void 0) break;
|
|
34549
|
+
const match = candidateLine.match(DISABLE_NEXT_LINE_PATTERN);
|
|
34550
|
+
if (match) {
|
|
34551
|
+
collected.push({
|
|
34552
|
+
commentLineIndex: candidateIndex,
|
|
34553
|
+
ruleList: match[1],
|
|
34554
|
+
isInChain: isStillInChain
|
|
34555
|
+
});
|
|
34556
|
+
continue;
|
|
34557
|
+
}
|
|
34558
|
+
isStillInChain = false;
|
|
34559
|
+
}
|
|
34560
|
+
return collected;
|
|
34561
|
+
};
|
|
34562
|
+
const isRuleListedInComment = (ruleList, ruleId) => {
|
|
34563
|
+
const tokens = tokenizeRuleList(ruleList);
|
|
34564
|
+
if (tokens.length === 0) return true;
|
|
34565
|
+
return tokens.some((token) => isSameRuleKey(token, ruleId));
|
|
34499
34566
|
};
|
|
34500
34567
|
const DISABLE_LINE_PATTERN = /(?:\/\/|\/\*)\s*react-doctor-disable-line\b(?:\s+([^\r\n]*?))?\s*(?:\*\/)?\s*\}?\s*$/;
|
|
34501
34568
|
const formatLineGap = (gapLineCount) => `${gapLineCount} line${gapLineCount === 1 ? "" : "s"}`;
|
|
@@ -34539,7 +34606,7 @@ const evaluateSuppression = (lines, diagnosticLineIndex, ruleId) => {
|
|
|
34539
34606
|
};
|
|
34540
34607
|
return {
|
|
34541
34608
|
isSuppressed: false,
|
|
34542
|
-
nearMissHint: classifyFromComments([directComments, openerComments], diagnosticLineIndex, ruleId)
|
|
34609
|
+
nearMissHint: classifyFromComments([directComments, openerComments], diagnosticLineIndex, ruleId) ?? detectForeignDisableNearMiss(lines, diagnosticLineIndex, ruleId)
|
|
34543
34610
|
};
|
|
34544
34611
|
};
|
|
34545
34612
|
/**
|
|
@@ -35333,7 +35400,6 @@ const PACKAGE_JSON_FILENAME = "package.json";
|
|
|
35333
35400
|
const PACKAGE_JSON_CONFIG_KEY = "reactDoctor";
|
|
35334
35401
|
const LEGACY_CONFIG_FILENAME = "react-doctor.config.json";
|
|
35335
35402
|
const jiti = createJiti(import.meta.url);
|
|
35336
|
-
const formatError = (error) => error instanceof Error ? error.message : String(error);
|
|
35337
35403
|
const importDefaultExport = async (jitiInstance, filePath) => {
|
|
35338
35404
|
const imported = await jitiInstance.import(filePath);
|
|
35339
35405
|
return imported?.default ?? imported;
|
|
@@ -35365,7 +35431,7 @@ const loadModuleConfig = async (filePath) => {
|
|
|
35365
35431
|
try {
|
|
35366
35432
|
return await importDefaultExport(aliasJiti, filePath);
|
|
35367
35433
|
} catch (retryError) {
|
|
35368
|
-
throw new Error(`${
|
|
35434
|
+
throw new Error(`${messageFromUnknown(error)} (retry with ${SELF_PACKAGE_IMPORT_SPECIFIER} aliased to the running react-doctor package also failed: ${messageFromUnknown(retryError)})`, { cause: retryError });
|
|
35369
35435
|
}
|
|
35370
35436
|
}
|
|
35371
35437
|
};
|
|
@@ -35414,7 +35480,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
35414
35480
|
}
|
|
35415
35481
|
warn(`${LEGACY_CONFIG_FILENAME} must contain an object, ignoring.`);
|
|
35416
35482
|
} catch (error) {
|
|
35417
|
-
warn(`Failed to load ${LEGACY_CONFIG_FILENAME}: ${
|
|
35483
|
+
warn(`Failed to load ${LEGACY_CONFIG_FILENAME}: ${messageFromUnknown(error)}`);
|
|
35418
35484
|
}
|
|
35419
35485
|
return {
|
|
35420
35486
|
status: "invalid",
|
|
@@ -35441,7 +35507,7 @@ const loadConfigFromDirectory = async (directory) => {
|
|
|
35441
35507
|
warn(`${CONFIG_BASENAME}.${extension} must export an object, ignoring.`);
|
|
35442
35508
|
sawBrokenConfigFile = true;
|
|
35443
35509
|
} catch (error) {
|
|
35444
|
-
warn(`Failed to load ${CONFIG_BASENAME}.${extension}: ${
|
|
35510
|
+
warn(`Failed to load ${CONFIG_BASENAME}.${extension}: ${messageFromUnknown(error)}`);
|
|
35445
35511
|
sawBrokenConfigFile = true;
|
|
35446
35512
|
}
|
|
35447
35513
|
}
|
|
@@ -35543,6 +35609,29 @@ const resolveScanTarget = async (requestedDirectory, options = {}) => {
|
|
|
35543
35609
|
didRedirectViaRootDir: redirectedDirectory !== null
|
|
35544
35610
|
};
|
|
35545
35611
|
};
|
|
35612
|
+
const buildFixGroupId = (diagnostic) => createHash("sha1").update(JSON.stringify([
|
|
35613
|
+
diagnostic.filePath,
|
|
35614
|
+
`${diagnostic.plugin}/${diagnostic.rule}`,
|
|
35615
|
+
diagnostic.message
|
|
35616
|
+
])).digest("hex").slice(0, 16);
|
|
35617
|
+
const isGroupableRule = (diagnostic) => ROOT_CAUSE_GROUPABLE_RULE_KEYS.has(`${diagnostic.plugin}/${diagnostic.rule}`);
|
|
35618
|
+
const assignFixGroups = (diagnostics) => {
|
|
35619
|
+
const siteCountByGroupId = /* @__PURE__ */ new Map();
|
|
35620
|
+
for (const diagnostic of diagnostics) {
|
|
35621
|
+
if (!isGroupableRule(diagnostic)) continue;
|
|
35622
|
+
const groupId = buildFixGroupId(diagnostic);
|
|
35623
|
+
siteCountByGroupId.set(groupId, (siteCountByGroupId.get(groupId) ?? 0) + 1);
|
|
35624
|
+
}
|
|
35625
|
+
return diagnostics.map((diagnostic) => {
|
|
35626
|
+
if (!isGroupableRule(diagnostic)) return diagnostic;
|
|
35627
|
+
const groupId = buildFixGroupId(diagnostic);
|
|
35628
|
+
if ((siteCountByGroupId.get(groupId) ?? 0) < 2) return diagnostic;
|
|
35629
|
+
return {
|
|
35630
|
+
...diagnostic,
|
|
35631
|
+
fixGroupId: groupId
|
|
35632
|
+
};
|
|
35633
|
+
});
|
|
35634
|
+
};
|
|
35546
35635
|
const getDirectDependencyNames = (packageJson) => new Set([...Object.keys(packageJson.dependencies ?? {}), ...Object.keys(packageJson.devDependencies ?? {})]);
|
|
35547
35636
|
const buildExpoCheckContext = (rootDirectory, expoVersion) => {
|
|
35548
35637
|
const packageJson = readPackageJson(Path.join(rootDirectory, "package.json"));
|
|
@@ -36669,7 +36758,7 @@ const readIgnoreFile = (filePath) => {
|
|
|
36669
36758
|
try {
|
|
36670
36759
|
content = NFS.readFileSync(filePath, "utf-8");
|
|
36671
36760
|
} catch (error) {
|
|
36672
|
-
const errnoCode = error
|
|
36761
|
+
const errnoCode = isErrnoException(error) ? error.code : void 0;
|
|
36673
36762
|
if (errnoCode && errnoCode !== "ENOENT") runSync(warn$1(`Could not read ignore file ${filePath}: ${errnoCode}`));
|
|
36674
36763
|
return [];
|
|
36675
36764
|
}
|
|
@@ -37228,15 +37317,13 @@ var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
|
37228
37317
|
})()) }));
|
|
37229
37318
|
static layerOf = (diagnostics) => succeed$3(DeadCode, DeadCode.of({ run: () => fromIterable$1(diagnostics) }));
|
|
37230
37319
|
};
|
|
37231
|
-
const createNodeReadFileLinesSync = (rootDirectory) => {
|
|
37232
|
-
|
|
37233
|
-
|
|
37234
|
-
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
|
|
37238
|
-
}
|
|
37239
|
-
};
|
|
37320
|
+
const createNodeReadFileLinesSync = (rootDirectory) => (filePath) => {
|
|
37321
|
+
const absolutePath = Path.isAbsolute(filePath) ? filePath : Path.join(rootDirectory, filePath);
|
|
37322
|
+
try {
|
|
37323
|
+
return NFS.readFileSync(absolutePath, "utf-8").split("\n");
|
|
37324
|
+
} catch {
|
|
37325
|
+
return null;
|
|
37326
|
+
}
|
|
37240
37327
|
};
|
|
37241
37328
|
var Files = class Files extends Service()("react-doctor/Files") {
|
|
37242
37329
|
static layerNode = succeed$3(Files, Files.of({
|
|
@@ -37447,7 +37534,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37447
37534
|
directory: input.directory,
|
|
37448
37535
|
cause
|
|
37449
37536
|
}) });
|
|
37450
|
-
})
|
|
37537
|
+
}), withSpan("git.exec", { attributes: {
|
|
37538
|
+
"git.command": input.command,
|
|
37539
|
+
"git.subcommand": input.args[0] ?? ""
|
|
37540
|
+
} }));
|
|
37451
37541
|
const runGit = (directory, args) => runCommand({
|
|
37452
37542
|
command: "git",
|
|
37453
37543
|
args,
|
|
@@ -37475,7 +37565,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37475
37565
|
]);
|
|
37476
37566
|
if (candidates.status !== 0) return null;
|
|
37477
37567
|
return trimOrNull(candidates.stdout.split("\n")[0] ?? "");
|
|
37478
|
-
});
|
|
37568
|
+
}).pipe(withSpan("Git.defaultBranch"));
|
|
37479
37569
|
const branchExists = (directory, branch) => runGit(directory, [
|
|
37480
37570
|
"rev-parse",
|
|
37481
37571
|
"--verify",
|
|
@@ -37522,7 +37612,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37522
37612
|
const result = resultOption.value;
|
|
37523
37613
|
if (result.status !== 0) return null;
|
|
37524
37614
|
return parseGithubViewerPermission(result.stdout);
|
|
37525
|
-
}).pipe(catch_$1(() => succeed$2(null)));
|
|
37615
|
+
}).pipe(catch_$1(() => succeed$2(null)), withSpan("Git.githubViewerPermission"));
|
|
37526
37616
|
/**
|
|
37527
37617
|
* Resolves a `--diff A..B` / `A...B` commit range into a changed-file
|
|
37528
37618
|
* selection. Each endpoint is validated with `isSafeGitRevision`
|
|
@@ -37636,7 +37726,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37636
37726
|
changedFiles: splitNullSeparated(diff.stdout),
|
|
37637
37727
|
isCurrentChanges: false
|
|
37638
37728
|
};
|
|
37639
|
-
}),
|
|
37729
|
+
}).pipe(withSpan("Git.diffSelection")),
|
|
37640
37730
|
stagedFilePaths: (directory) => runGit(directory, [
|
|
37641
37731
|
"diff",
|
|
37642
37732
|
"--cached",
|
|
@@ -37678,7 +37768,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37678
37768
|
status: result.status,
|
|
37679
37769
|
stdout: result.stdout
|
|
37680
37770
|
};
|
|
37681
|
-
}),
|
|
37771
|
+
}).pipe(withSpan("Git.grep")),
|
|
37682
37772
|
changedLineRanges: ({ directory, baseRef, cached, files }) => gen(function* () {
|
|
37683
37773
|
if (files.length === 0) return [];
|
|
37684
37774
|
if (baseRef !== void 0 && !isSafeGitRevision(baseRef)) return null;
|
|
@@ -37694,7 +37784,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37694
37784
|
]);
|
|
37695
37785
|
if (result.status !== 0) return null;
|
|
37696
37786
|
return parseChangedLineRanges(result.stdout);
|
|
37697
|
-
})
|
|
37787
|
+
}).pipe(withSpan("Git.changedLineRanges"))
|
|
37698
37788
|
});
|
|
37699
37789
|
})).pipe(provide$2(layer$2.pipe(provide$2(mergeAll$1(layer$1, layer)))));
|
|
37700
37790
|
/**
|
|
@@ -37909,7 +37999,7 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
37909
37999
|
for (const [absolutePath, originalContent] of originalContents) try {
|
|
37910
38000
|
NFS.writeFileSync(absolutePath, originalContent);
|
|
37911
38001
|
} catch (error) {
|
|
37912
|
-
process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${
|
|
38002
|
+
process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${messageFromUnknown(error)}\n[react-doctor] Run: git checkout -- ${absolutePath}\n`);
|
|
37913
38003
|
}
|
|
37914
38004
|
};
|
|
37915
38005
|
const onExit = () => restore();
|
|
@@ -38015,7 +38105,7 @@ const resolveUserPlugin = (spec, configSourceDirectory) => {
|
|
|
38015
38105
|
try {
|
|
38016
38106
|
resolvedSpecifier = isRelative ? Path.resolve(configSourceDirectory, spec) : candidateRequire.resolve(spec);
|
|
38017
38107
|
} catch (error) {
|
|
38018
|
-
warnConfigIssue(`config.plugins entry "${spec}" could not be resolved from ${configSourceDirectory}: ${
|
|
38108
|
+
warnConfigIssue(`config.plugins entry "${spec}" could not be resolved from ${configSourceDirectory}: ${messageFromUnknown(error)}`);
|
|
38019
38109
|
return null;
|
|
38020
38110
|
}
|
|
38021
38111
|
const { name, ruleNames } = readPluginShape(resolvedSpecifier, (target) => candidateRequire(target));
|
|
@@ -38861,7 +38951,7 @@ const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLIN
|
|
|
38861
38951
|
child.kill("SIGKILL");
|
|
38862
38952
|
reject(new ReactDoctorError({ reason: new OxlintBatchExceeded({
|
|
38863
38953
|
kind: "timeout",
|
|
38864
|
-
detail: `${spawnTimeoutMs /
|
|
38954
|
+
detail: `${spawnTimeoutMs / MILLISECONDS_PER_SECOND}s budget exceeded`
|
|
38865
38955
|
}) }));
|
|
38866
38956
|
}, spawnTimeoutMs);
|
|
38867
38957
|
timeoutHandle.unref?.();
|
|
@@ -39983,17 +40073,17 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
39983
40073
|
}))))))));
|
|
39984
40074
|
const deadCodeFailureState = yield* get$2(deadCodeFailure);
|
|
39985
40075
|
const scanElapsedMilliseconds = Date.now() - scanStartTime;
|
|
39986
|
-
const scanElapsedSeconds = (scanElapsedMilliseconds /
|
|
40076
|
+
const scanElapsedSeconds = (scanElapsedMilliseconds / MILLISECONDS_PER_SECOND).toFixed(1);
|
|
39987
40077
|
if (!lintFailureState.didFail) if (deadCodeFailureState.didFail) yield* scanProgress.fail(DEAD_CODE_FAIL_TEXT);
|
|
39988
40078
|
else if (input.suppressScanSummary) yield* scanProgress.stop();
|
|
39989
40079
|
else yield* scanProgress.succeed(`Scanned ${scannedFilesLabel} in ${scanElapsedSeconds}s${workerCountSuffix}`);
|
|
39990
40080
|
yield* reporterService.finalize;
|
|
39991
|
-
const finalDiagnostics = [
|
|
40081
|
+
const finalDiagnostics = assignFixGroups([
|
|
39992
40082
|
...envCollected,
|
|
39993
40083
|
...supplyChainCollected,
|
|
39994
40084
|
...lintCollected,
|
|
39995
40085
|
...deadCodeCollected
|
|
39996
|
-
];
|
|
40086
|
+
]);
|
|
39997
40087
|
const githubViewerPermission = yield* join(githubViewerPermissionFiber);
|
|
39998
40088
|
const scoreMetadata = {
|
|
39999
40089
|
...repo !== null ? { repo } : {},
|
|
@@ -40197,7 +40287,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
40197
40287
|
static layerNode = effect(StagedFiles, gen(function* () {
|
|
40198
40288
|
const git = yield* Git;
|
|
40199
40289
|
return StagedFiles.of({
|
|
40200
|
-
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile))),
|
|
40290
|
+
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
|
|
40201
40291
|
materialize: ({ directory, stagedFiles, tempDirectory }) => materializeSourceTree({
|
|
40202
40292
|
directory,
|
|
40203
40293
|
files: stagedFiles,
|
|
@@ -40207,7 +40297,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
40207
40297
|
tempDirectory: tree.tempDirectory,
|
|
40208
40298
|
stagedFiles: tree.materializedFiles,
|
|
40209
40299
|
cleanup: tree.cleanup
|
|
40210
|
-
})))
|
|
40300
|
+
})), withSpan("StagedFiles.materialize"))
|
|
40211
40301
|
});
|
|
40212
40302
|
}));
|
|
40213
40303
|
/**
|
|
@@ -40339,6 +40429,7 @@ const buildJsonReport = (input) => {
|
|
|
40339
40429
|
score: result.score,
|
|
40340
40430
|
skippedChecks: result.skippedChecks,
|
|
40341
40431
|
...result.skippedCheckReasons ? { skippedCheckReasons: result.skippedCheckReasons } : {},
|
|
40432
|
+
...typeof result.scannedFileCount === "number" ? { scannedFileCount: result.scannedFileCount } : {},
|
|
40342
40433
|
elapsedMilliseconds: result.elapsedMilliseconds
|
|
40343
40434
|
}));
|
|
40344
40435
|
const flattenedDiagnostics = projects.flatMap((entry) => entry.diagnostics);
|
|
@@ -40605,4 +40696,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
40605
40696
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
40606
40697
|
|
|
40607
40698
|
//# sourceMappingURL=index.js.map
|
|
40608
|
-
//# debugId=
|
|
40699
|
+
//# debugId=4ecd915d-c650-5f04-bc07-b82e872a8962
|