react-doctor 0.5.6-dev.5b742fa → 0.5.6-dev.5d1347e
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 +399 -250
- package/dist/index.js +95 -76
- package/dist/lsp.js +114 -98
- 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]="ff319d21-ecce-5f79-a822-8cb00c30fea1")}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";
|
|
@@ -32724,6 +32724,7 @@ const isLargeMinifiedFile = (absolutePath) => {
|
|
|
32724
32724
|
if (sizeBytes < 2e4) return false;
|
|
32725
32725
|
return isMinifiedSource(absolutePath);
|
|
32726
32726
|
};
|
|
32727
|
+
const isErrnoException = (error) => error instanceof Error && "code" in error;
|
|
32727
32728
|
const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
32728
32729
|
"EACCES",
|
|
32729
32730
|
"EPERM",
|
|
@@ -32733,11 +32734,7 @@ const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
|
32733
32734
|
"ELOOP",
|
|
32734
32735
|
"ENAMETOOLONG"
|
|
32735
32736
|
]);
|
|
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
|
-
};
|
|
32737
|
+
const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
|
|
32741
32738
|
const readDirectoryEntries = (directoryPath) => {
|
|
32742
32739
|
try {
|
|
32743
32740
|
return NFS.readdirSync(directoryPath, { withFileTypes: true });
|
|
@@ -32787,7 +32784,7 @@ const readPackageJsonUncached = (packageJsonPath) => {
|
|
|
32787
32784
|
return JSON.parse(NFS.readFileSync(packageJsonPath, "utf-8"));
|
|
32788
32785
|
} catch (error) {
|
|
32789
32786
|
if (error instanceof SyntaxError) return {};
|
|
32790
|
-
if (error
|
|
32787
|
+
if (isErrnoException(error)) {
|
|
32791
32788
|
const { code } = error;
|
|
32792
32789
|
if (code === "EISDIR" || code === "EACCES" || code === "EPERM" || code === "ENOENT") return {};
|
|
32793
32790
|
}
|
|
@@ -33512,17 +33509,13 @@ const isPackageJsonReactNativeAware = (packageJson) => {
|
|
|
33512
33509
|
return false;
|
|
33513
33510
|
};
|
|
33514
33511
|
const hasReactNativeWorkspaceAnywhere = (rootDirectory, rootPackageJson) => someWorkspacePackageJson(rootDirectory, rootPackageJson, isPackageJsonReactNativeAware);
|
|
33515
|
-
const
|
|
33516
|
-
const spec = packageJson.dependencies?.
|
|
33512
|
+
const getDependencySpec = (packageJson, packageName) => {
|
|
33513
|
+
const spec = packageJson.dependencies?.[packageName] ?? packageJson.devDependencies?.[packageName] ?? packageJson.peerDependencies?.[packageName] ?? packageJson.optionalDependencies?.[packageName];
|
|
33517
33514
|
return typeof spec === "string" ? spec : null;
|
|
33518
33515
|
};
|
|
33519
|
-
const findExpoVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson,
|
|
33516
|
+
const findExpoVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, "expo"));
|
|
33520
33517
|
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);
|
|
33518
|
+
const findShopifyFlashListVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, SHOPIFY_FLASH_LIST_PACKAGE_NAME));
|
|
33526
33519
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
33527
33520
|
if (version === null || !isCatalogReference(version)) return version;
|
|
33528
33521
|
const catalogName = extractCatalogName(version);
|
|
@@ -33534,11 +33527,7 @@ const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson,
|
|
|
33534
33527
|
if (!isFile(monorepoPackageJsonPath)) return version;
|
|
33535
33528
|
return resolveCatalogVersion(readPackageJson(monorepoPackageJsonPath), packageName, monorepoRoot, catalogName) ?? version;
|
|
33536
33529
|
};
|
|
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);
|
|
33530
|
+
const findNextjsVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, "next"));
|
|
33542
33531
|
const getPreactVersion = (packageJson) => {
|
|
33543
33532
|
return {
|
|
33544
33533
|
...packageJson.peerDependencies,
|
|
@@ -33620,6 +33609,11 @@ const ES_TARGET_YEAR_BY_NAME = {
|
|
|
33620
33609
|
esnext: 9999
|
|
33621
33610
|
};
|
|
33622
33611
|
/**
|
|
33612
|
+
* tsconfig filenames probed when resolving a project's TypeScript
|
|
33613
|
+
* compiler options — the root config first, then a monorepo base config.
|
|
33614
|
+
*/
|
|
33615
|
+
const TSCONFIG_FILENAMES = ["tsconfig.json", "tsconfig.base.json"];
|
|
33616
|
+
/**
|
|
33623
33617
|
* Project-config files that `StagedFiles.materialize` copies into
|
|
33624
33618
|
* the temp directory alongside staged sources so oxlint resolves
|
|
33625
33619
|
* `tsconfig` / `package.json` / lint configs the same way it would
|
|
@@ -34118,6 +34112,7 @@ const isTailwindAtLeast = (detected, required) => {
|
|
|
34118
34112
|
if (detected.major !== required.major) return detected.major > required.major;
|
|
34119
34113
|
return detected.minor >= required.minor;
|
|
34120
34114
|
};
|
|
34115
|
+
const messageFromUnknown = (error) => error instanceof Error ? error.message : String(error);
|
|
34121
34116
|
var InvalidGlobPatternError = class extends Error {
|
|
34122
34117
|
pattern;
|
|
34123
34118
|
reason;
|
|
@@ -34146,7 +34141,7 @@ const compileGlobPattern = (rawPattern) => {
|
|
|
34146
34141
|
try {
|
|
34147
34142
|
return import_picomatch.default.makeRe(normalizeGlobPattern(rawPattern), PICOMATCH_OPTIONS);
|
|
34148
34143
|
} catch (caughtError) {
|
|
34149
|
-
throw new InvalidGlobPatternError(rawPattern,
|
|
34144
|
+
throw new InvalidGlobPatternError(rawPattern, messageFromUnknown(caughtError));
|
|
34150
34145
|
}
|
|
34151
34146
|
};
|
|
34152
34147
|
const compileGlobPatternsLenient = (patterns, onInvalid) => {
|
|
@@ -35328,7 +35323,6 @@ const PACKAGE_JSON_FILENAME = "package.json";
|
|
|
35328
35323
|
const PACKAGE_JSON_CONFIG_KEY = "reactDoctor";
|
|
35329
35324
|
const LEGACY_CONFIG_FILENAME = "react-doctor.config.json";
|
|
35330
35325
|
const jiti = createJiti(import.meta.url);
|
|
35331
|
-
const formatError = (error) => error instanceof Error ? error.message : String(error);
|
|
35332
35326
|
const importDefaultExport = async (jitiInstance, filePath) => {
|
|
35333
35327
|
const imported = await jitiInstance.import(filePath);
|
|
35334
35328
|
return imported?.default ?? imported;
|
|
@@ -35360,7 +35354,7 @@ const loadModuleConfig = async (filePath) => {
|
|
|
35360
35354
|
try {
|
|
35361
35355
|
return await importDefaultExport(aliasJiti, filePath);
|
|
35362
35356
|
} catch (retryError) {
|
|
35363
|
-
throw new Error(`${
|
|
35357
|
+
throw new Error(`${messageFromUnknown(error)} (retry with ${SELF_PACKAGE_IMPORT_SPECIFIER} aliased to the running react-doctor package also failed: ${messageFromUnknown(retryError)})`, { cause: retryError });
|
|
35364
35358
|
}
|
|
35365
35359
|
}
|
|
35366
35360
|
};
|
|
@@ -35409,7 +35403,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
35409
35403
|
}
|
|
35410
35404
|
warn(`${LEGACY_CONFIG_FILENAME} must contain an object, ignoring.`);
|
|
35411
35405
|
} catch (error) {
|
|
35412
|
-
warn(`Failed to load ${LEGACY_CONFIG_FILENAME}: ${
|
|
35406
|
+
warn(`Failed to load ${LEGACY_CONFIG_FILENAME}: ${messageFromUnknown(error)}`);
|
|
35413
35407
|
}
|
|
35414
35408
|
return {
|
|
35415
35409
|
status: "invalid",
|
|
@@ -35436,7 +35430,7 @@ const loadConfigFromDirectory = async (directory) => {
|
|
|
35436
35430
|
warn(`${CONFIG_BASENAME}.${extension} must export an object, ignoring.`);
|
|
35437
35431
|
sawBrokenConfigFile = true;
|
|
35438
35432
|
} catch (error) {
|
|
35439
|
-
warn(`Failed to load ${CONFIG_BASENAME}.${extension}: ${
|
|
35433
|
+
warn(`Failed to load ${CONFIG_BASENAME}.${extension}: ${messageFromUnknown(error)}`);
|
|
35440
35434
|
sawBrokenConfigFile = true;
|
|
35441
35435
|
}
|
|
35442
35436
|
}
|
|
@@ -36472,15 +36466,10 @@ const buildCapabilities = (project) => {
|
|
|
36472
36466
|
}
|
|
36473
36467
|
if (project.tailwindVersion !== null) {
|
|
36474
36468
|
capabilities.add("tailwind");
|
|
36475
|
-
|
|
36476
|
-
if (isTailwindAtLeast(tailwind, {
|
|
36469
|
+
if (isTailwindAtLeast(parseTailwindMajorMinor(project.tailwindVersion), {
|
|
36477
36470
|
major: 3,
|
|
36478
36471
|
minor: 4
|
|
36479
36472
|
})) capabilities.add("tailwind:3.4");
|
|
36480
|
-
if (tailwind !== null && isTailwindAtLeast(tailwind, {
|
|
36481
|
-
major: 4,
|
|
36482
|
-
minor: 0
|
|
36483
|
-
})) capabilities.add("tailwind:4");
|
|
36484
36473
|
}
|
|
36485
36474
|
if (project.zodVersion !== null) {
|
|
36486
36475
|
capabilities.add("zod");
|
|
@@ -36669,7 +36658,7 @@ const readIgnoreFile = (filePath) => {
|
|
|
36669
36658
|
try {
|
|
36670
36659
|
content = NFS.readFileSync(filePath, "utf-8");
|
|
36671
36660
|
} catch (error) {
|
|
36672
|
-
const errnoCode = error
|
|
36661
|
+
const errnoCode = isErrnoException(error) ? error.code : void 0;
|
|
36673
36662
|
if (errnoCode && errnoCode !== "ENOENT") runSync(warn$1(`Could not read ignore file ${filePath}: ${errnoCode}`));
|
|
36674
36663
|
return [];
|
|
36675
36664
|
}
|
|
@@ -36710,8 +36699,8 @@ const collectIgnorePatterns = (rootDirectory) => {
|
|
|
36710
36699
|
cachedPatternsByRoot.set(rootDirectory, patterns);
|
|
36711
36700
|
return patterns;
|
|
36712
36701
|
};
|
|
36702
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36713
36703
|
const KNIP_JSON_FILENAME = "knip.json";
|
|
36714
|
-
const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36715
36704
|
const readJsonFileSafe = (filePath) => {
|
|
36716
36705
|
let rawContents;
|
|
36717
36706
|
try {
|
|
@@ -36727,10 +36716,10 @@ const readJsonFileSafe = (filePath) => {
|
|
|
36727
36716
|
};
|
|
36728
36717
|
const readKnipConfig = (rootDirectory) => {
|
|
36729
36718
|
const knipJson = readJsonFileSafe(path.join(rootDirectory, KNIP_JSON_FILENAME));
|
|
36730
|
-
if (isRecord
|
|
36719
|
+
if (isRecord(knipJson)) return knipJson;
|
|
36731
36720
|
const packageJson = readJsonFileSafe(path.join(rootDirectory, "package.json"));
|
|
36732
|
-
const packageKnipConfig = isRecord
|
|
36733
|
-
return isRecord
|
|
36721
|
+
const packageKnipConfig = isRecord(packageJson) ? packageJson.knip : null;
|
|
36722
|
+
return isRecord(packageKnipConfig) ? packageKnipConfig : null;
|
|
36734
36723
|
};
|
|
36735
36724
|
const normalizePatternList = (value) => {
|
|
36736
36725
|
if (typeof value === "string" && value.length > 0) return [value];
|
|
@@ -36742,10 +36731,10 @@ const prefixWorkspacePatterns = (workspacePattern, patterns) => {
|
|
|
36742
36731
|
return patterns.map((pattern) => pattern.startsWith("!") ? `!${normalizedWorkspacePattern}/${pattern.slice(1)}` : `${normalizedWorkspacePattern}/${pattern}`);
|
|
36743
36732
|
};
|
|
36744
36733
|
const collectKnipWorkspacePatterns = (workspaces, settingName) => {
|
|
36745
|
-
if (!isRecord
|
|
36734
|
+
if (!isRecord(workspaces)) return [];
|
|
36746
36735
|
const patterns = [];
|
|
36747
36736
|
for (const [workspacePattern, workspaceConfig] of Object.entries(workspaces)) {
|
|
36748
|
-
if (!isRecord
|
|
36737
|
+
if (!isRecord(workspaceConfig)) continue;
|
|
36749
36738
|
patterns.push(...prefixWorkspacePatterns(workspacePattern, normalizePatternList(workspaceConfig[settingName])));
|
|
36750
36739
|
}
|
|
36751
36740
|
return patterns;
|
|
@@ -36790,8 +36779,6 @@ const toCanonicalPath = (filePath) => {
|
|
|
36790
36779
|
};
|
|
36791
36780
|
const DEAD_CODE_PLUGIN = "deslop";
|
|
36792
36781
|
const DEAD_CODE_CATEGORY = "Maintainability";
|
|
36793
|
-
const TSCONFIG_FILENAMES$1 = ["tsconfig.json", "tsconfig.base.json"];
|
|
36794
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36795
36782
|
const DEAD_CODE_WORKER_SCRIPT = `
|
|
36796
36783
|
const inputChunks = [];
|
|
36797
36784
|
process.stdin.on("data", (chunk) => inputChunks.push(chunk));
|
|
@@ -36849,7 +36836,7 @@ process.stdin.on("end", () => {
|
|
|
36849
36836
|
});
|
|
36850
36837
|
`;
|
|
36851
36838
|
const resolveTsConfigPath = (rootDirectory) => {
|
|
36852
|
-
for (const filename of TSCONFIG_FILENAMES
|
|
36839
|
+
for (const filename of TSCONFIG_FILENAMES) {
|
|
36853
36840
|
const candidate = Path.join(rootDirectory, filename);
|
|
36854
36841
|
if (NFS.existsSync(candidate)) return candidate;
|
|
36855
36842
|
}
|
|
@@ -37230,15 +37217,13 @@ var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
|
37230
37217
|
})()) }));
|
|
37231
37218
|
static layerOf = (diagnostics) => succeed$3(DeadCode, DeadCode.of({ run: () => fromIterable$1(diagnostics) }));
|
|
37232
37219
|
};
|
|
37233
|
-
const createNodeReadFileLinesSync = (rootDirectory) => {
|
|
37234
|
-
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
|
|
37238
|
-
|
|
37239
|
-
|
|
37240
|
-
}
|
|
37241
|
-
};
|
|
37220
|
+
const createNodeReadFileLinesSync = (rootDirectory) => (filePath) => {
|
|
37221
|
+
const absolutePath = Path.isAbsolute(filePath) ? filePath : Path.join(rootDirectory, filePath);
|
|
37222
|
+
try {
|
|
37223
|
+
return NFS.readFileSync(absolutePath, "utf-8").split("\n");
|
|
37224
|
+
} catch {
|
|
37225
|
+
return null;
|
|
37226
|
+
}
|
|
37242
37227
|
};
|
|
37243
37228
|
var Files = class Files extends Service()("react-doctor/Files") {
|
|
37244
37229
|
static layerNode = succeed$3(Files, Files.of({
|
|
@@ -37449,7 +37434,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37449
37434
|
directory: input.directory,
|
|
37450
37435
|
cause
|
|
37451
37436
|
}) });
|
|
37452
|
-
})
|
|
37437
|
+
}), withSpan("git.exec", { attributes: {
|
|
37438
|
+
"git.command": input.command,
|
|
37439
|
+
"git.subcommand": input.args[0] ?? ""
|
|
37440
|
+
} }));
|
|
37453
37441
|
const runGit = (directory, args) => runCommand({
|
|
37454
37442
|
command: "git",
|
|
37455
37443
|
args,
|
|
@@ -37477,7 +37465,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37477
37465
|
]);
|
|
37478
37466
|
if (candidates.status !== 0) return null;
|
|
37479
37467
|
return trimOrNull(candidates.stdout.split("\n")[0] ?? "");
|
|
37480
|
-
});
|
|
37468
|
+
}).pipe(withSpan("Git.defaultBranch"));
|
|
37481
37469
|
const branchExists = (directory, branch) => runGit(directory, [
|
|
37482
37470
|
"rev-parse",
|
|
37483
37471
|
"--verify",
|
|
@@ -37524,7 +37512,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37524
37512
|
const result = resultOption.value;
|
|
37525
37513
|
if (result.status !== 0) return null;
|
|
37526
37514
|
return parseGithubViewerPermission(result.stdout);
|
|
37527
|
-
}).pipe(catch_$1(() => succeed$2(null)));
|
|
37515
|
+
}).pipe(catch_$1(() => succeed$2(null)), withSpan("Git.githubViewerPermission"));
|
|
37528
37516
|
/**
|
|
37529
37517
|
* Resolves a `--diff A..B` / `A...B` commit range into a changed-file
|
|
37530
37518
|
* selection. Each endpoint is validated with `isSafeGitRevision`
|
|
@@ -37638,7 +37626,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37638
37626
|
changedFiles: splitNullSeparated(diff.stdout),
|
|
37639
37627
|
isCurrentChanges: false
|
|
37640
37628
|
};
|
|
37641
|
-
}),
|
|
37629
|
+
}).pipe(withSpan("Git.diffSelection")),
|
|
37642
37630
|
stagedFilePaths: (directory) => runGit(directory, [
|
|
37643
37631
|
"diff",
|
|
37644
37632
|
"--cached",
|
|
@@ -37680,7 +37668,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37680
37668
|
status: result.status,
|
|
37681
37669
|
stdout: result.stdout
|
|
37682
37670
|
};
|
|
37683
|
-
}),
|
|
37671
|
+
}).pipe(withSpan("Git.grep")),
|
|
37684
37672
|
changedLineRanges: ({ directory, baseRef, cached, files }) => gen(function* () {
|
|
37685
37673
|
if (files.length === 0) return [];
|
|
37686
37674
|
if (baseRef !== void 0 && !isSafeGitRevision(baseRef)) return null;
|
|
@@ -37696,7 +37684,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37696
37684
|
]);
|
|
37697
37685
|
if (result.status !== 0) return null;
|
|
37698
37686
|
return parseChangedLineRanges(result.stdout);
|
|
37699
|
-
})
|
|
37687
|
+
}).pipe(withSpan("Git.changedLineRanges"))
|
|
37700
37688
|
});
|
|
37701
37689
|
})).pipe(provide$2(layer$2.pipe(provide$2(mergeAll$1(layer$1, layer)))));
|
|
37702
37690
|
/**
|
|
@@ -37911,7 +37899,7 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
37911
37899
|
for (const [absolutePath, originalContent] of originalContents) try {
|
|
37912
37900
|
NFS.writeFileSync(absolutePath, originalContent);
|
|
37913
37901
|
} catch (error) {
|
|
37914
|
-
process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${
|
|
37902
|
+
process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${messageFromUnknown(error)}\n[react-doctor] Run: git checkout -- ${absolutePath}\n`);
|
|
37915
37903
|
}
|
|
37916
37904
|
};
|
|
37917
37905
|
const onExit = () => restore();
|
|
@@ -38017,7 +38005,7 @@ const resolveUserPlugin = (spec, configSourceDirectory) => {
|
|
|
38017
38005
|
try {
|
|
38018
38006
|
resolvedSpecifier = isRelative ? Path.resolve(configSourceDirectory, spec) : candidateRequire.resolve(spec);
|
|
38019
38007
|
} catch (error) {
|
|
38020
|
-
warnConfigIssue(`config.plugins entry "${spec}" could not be resolved from ${configSourceDirectory}: ${
|
|
38008
|
+
warnConfigIssue(`config.plugins entry "${spec}" could not be resolved from ${configSourceDirectory}: ${messageFromUnknown(error)}`);
|
|
38021
38009
|
return null;
|
|
38022
38010
|
}
|
|
38023
38011
|
const { name, ruleNames } = readPluginShape(resolvedSpecifier, (target) => candidateRequire(target));
|
|
@@ -38089,8 +38077,8 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
38089
38077
|
}
|
|
38090
38078
|
return enabled;
|
|
38091
38079
|
};
|
|
38092
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [] }) => {
|
|
38093
|
-
const reactHooksJsPlugin = resolveReactHooksJsPlugin(project.hasReactCompiler, customRulesOnly);
|
|
38080
|
+
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false }) => {
|
|
38081
|
+
const reactHooksJsPlugin = disableReactHooksJsPlugin ? null : resolveReactHooksJsPlugin(project.hasReactCompiler, customRulesOnly);
|
|
38094
38082
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
38095
38083
|
const jsPlugins = [];
|
|
38096
38084
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
@@ -38150,7 +38138,6 @@ const resolveOxlintBinary = () => {
|
|
|
38150
38138
|
return Path.join(oxlintPackageDirectory, "bin", "oxlint");
|
|
38151
38139
|
};
|
|
38152
38140
|
const resolvePluginPath = () => esmRequire.resolve("oxlint-plugin-react-doctor");
|
|
38153
|
-
const TSCONFIG_FILENAMES = ["tsconfig.json", "tsconfig.base.json"];
|
|
38154
38141
|
const resolveTsConfigRelativePath = (rootDirectory) => {
|
|
38155
38142
|
for (const filename of TSCONFIG_FILENAMES) if (NFS.existsSync(Path.join(rootDirectory, filename))) return `./${filename}`;
|
|
38156
38143
|
return null;
|
|
@@ -38522,7 +38509,7 @@ const scopeContainsNonImportBinding = (node, scopeNode, identifierName) => {
|
|
|
38522
38509
|
const isIdentifierShadowedByLocalBinding = (identifier, sourceFile) => {
|
|
38523
38510
|
let currentNode = identifier.parent;
|
|
38524
38511
|
while (currentNode) {
|
|
38525
|
-
if (
|
|
38512
|
+
if (isScopeBoundary(currentNode)) {
|
|
38526
38513
|
if (scopeContainsNonImportBinding(currentNode, currentNode, identifier.text)) return true;
|
|
38527
38514
|
}
|
|
38528
38515
|
if (currentNode === sourceFile) return false;
|
|
@@ -38613,11 +38600,10 @@ const findResolutionInScope = (scopeNode, identifierName, reactImportBindings, s
|
|
|
38613
38600
|
});
|
|
38614
38601
|
return resolution;
|
|
38615
38602
|
};
|
|
38616
|
-
const isScopeNode = isScopeBoundary;
|
|
38617
38603
|
const resolveIdentifierBinding = (identifier, reactImportBindings, sourceFile, visitedDeclarations = /* @__PURE__ */ new Set()) => {
|
|
38618
38604
|
let currentNode = identifier.parent;
|
|
38619
38605
|
while (currentNode) {
|
|
38620
|
-
if (
|
|
38606
|
+
if (isScopeBoundary(currentNode)) {
|
|
38621
38607
|
const resolution = findResolutionInScope(currentNode, identifier.text, reactImportBindings, sourceFile, visitedDeclarations);
|
|
38622
38608
|
if (resolution) return resolution;
|
|
38623
38609
|
}
|
|
@@ -38787,9 +38773,9 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
38787
38773
|
try {
|
|
38788
38774
|
parsed = JSON.parse(sanitizedStdout);
|
|
38789
38775
|
} catch {
|
|
38790
|
-
throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0,
|
|
38776
|
+
throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0, 600) }) });
|
|
38791
38777
|
}
|
|
38792
|
-
if (!isOxlintOutput(parsed)) throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0,
|
|
38778
|
+
if (!isOxlintOutput(parsed)) throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0, 600) }) });
|
|
38793
38779
|
const minifiedFileCache = /* @__PURE__ */ new Map();
|
|
38794
38780
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
38795
38781
|
const absolutePath = Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
@@ -38865,7 +38851,7 @@ const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLIN
|
|
|
38865
38851
|
child.kill("SIGKILL");
|
|
38866
38852
|
reject(new ReactDoctorError({ reason: new OxlintBatchExceeded({
|
|
38867
38853
|
kind: "timeout",
|
|
38868
|
-
detail: `${spawnTimeoutMs /
|
|
38854
|
+
detail: `${spawnTimeoutMs / MILLISECONDS_PER_SECOND}s budget exceeded`
|
|
38869
38855
|
}) }));
|
|
38870
38856
|
}, spawnTimeoutMs);
|
|
38871
38857
|
timeoutHandle.unref?.();
|
|
@@ -39080,6 +39066,28 @@ const writeOxlintConfig = (configPath, configToWrite) => {
|
|
|
39080
39066
|
NFS.closeSync(fileHandle);
|
|
39081
39067
|
}
|
|
39082
39068
|
};
|
|
39069
|
+
const REACT_HOOKS_JS_DROP_PREFIX = "React Compiler rules (react-hooks-js/*) skipped — eslint-plugin-react-hooks failed to load in this environment";
|
|
39070
|
+
/**
|
|
39071
|
+
* Detects an oxlint config-load crash caused by the optional
|
|
39072
|
+
* `react-hooks-js` (eslint-plugin-react-hooks) React Compiler plugin and
|
|
39073
|
+
* builds the partial-failure note for it; returns `null` when the failure
|
|
39074
|
+
* was anything else.
|
|
39075
|
+
*
|
|
39076
|
+
* oxlint prints a framed error to stdout (not stderr) and exits non-zero
|
|
39077
|
+
* when a `jsPlugins` entry can't be imported; that non-JSON stdout
|
|
39078
|
+
* surfaces as `OxlintOutputUnparseable`. Because oxlint fails the WHOLE
|
|
39079
|
+
* config load on it, leaving the plugin in would drop every curated
|
|
39080
|
+
* react-doctor diagnostic too — so the caller retries with the plugin
|
|
39081
|
+
* stripped (issue #833). Both markers sit at the start of oxlint's
|
|
39082
|
+
* message, so they survive the `preview` slice even for deep pnpm paths.
|
|
39083
|
+
*/
|
|
39084
|
+
const reactHooksJsPluginDropNote = (error) => {
|
|
39085
|
+
if (!(error instanceof ReactDoctorError) || error.reason._tag !== "OxlintOutputUnparseable") return null;
|
|
39086
|
+
const { preview } = error.reason;
|
|
39087
|
+
if (!preview.includes("Failed to load JS plugin") || !preview.includes("eslint-plugin-react-hooks")) return null;
|
|
39088
|
+
const underlyingReason = preview.match(/Error:[^\n]*/)?.[0]?.trim();
|
|
39089
|
+
return `${REACT_HOOKS_JS_DROP_PREFIX}${underlyingReason ? `: ${underlyingReason}` : ""}. Other rules ran normally.`;
|
|
39090
|
+
};
|
|
39083
39091
|
/**
|
|
39084
39092
|
* The oxlint runner. Composed of three pieces in `runners/oxlint/`:
|
|
39085
39093
|
*
|
|
@@ -39107,15 +39115,16 @@ const runOxlint = async (options) => {
|
|
|
39107
39115
|
const pluginPath = resolvePluginPath();
|
|
39108
39116
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
39109
39117
|
const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
39110
|
-
const buildConfig = (
|
|
39118
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
39111
39119
|
pluginPath,
|
|
39112
39120
|
project,
|
|
39113
39121
|
customRulesOnly,
|
|
39114
|
-
extendsPaths:
|
|
39122
|
+
extendsPaths: overrides.extendsPaths,
|
|
39115
39123
|
ignoredTags,
|
|
39116
39124
|
serverAuthFunctionNames,
|
|
39117
39125
|
severityControls,
|
|
39118
|
-
userPlugins
|
|
39126
|
+
userPlugins,
|
|
39127
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin
|
|
39119
39128
|
});
|
|
39120
39129
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
39121
39130
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
@@ -39151,12 +39160,22 @@ const runOxlint = async (options) => {
|
|
|
39151
39160
|
outputMaxBytes,
|
|
39152
39161
|
concurrency: options.concurrency
|
|
39153
39162
|
});
|
|
39154
|
-
writeOxlintConfig(configPath, buildConfig(extendsPaths));
|
|
39163
|
+
writeOxlintConfig(configPath, buildConfig({ extendsPaths }));
|
|
39155
39164
|
try {
|
|
39156
39165
|
return await runBatches();
|
|
39157
39166
|
} catch (error) {
|
|
39167
|
+
const reactHooksJsDropNote = reactHooksJsPluginDropNote(error);
|
|
39168
|
+
if (reactHooksJsDropNote !== null) {
|
|
39169
|
+
writeOxlintConfig(configPath, buildConfig({
|
|
39170
|
+
extendsPaths,
|
|
39171
|
+
disableReactHooksJsPlugin: true
|
|
39172
|
+
}));
|
|
39173
|
+
const diagnostics = await runBatches();
|
|
39174
|
+
onPartialFailure?.(reactHooksJsDropNote);
|
|
39175
|
+
return diagnostics;
|
|
39176
|
+
}
|
|
39158
39177
|
if (extendsPaths.length === 0) throw error;
|
|
39159
|
-
writeOxlintConfig(configPath, buildConfig([]));
|
|
39178
|
+
writeOxlintConfig(configPath, buildConfig({ extendsPaths: [] }));
|
|
39160
39179
|
return await runBatches();
|
|
39161
39180
|
}
|
|
39162
39181
|
} finally {
|
|
@@ -39954,7 +39973,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
39954
39973
|
}))))))));
|
|
39955
39974
|
const deadCodeFailureState = yield* get$2(deadCodeFailure);
|
|
39956
39975
|
const scanElapsedMilliseconds = Date.now() - scanStartTime;
|
|
39957
|
-
const scanElapsedSeconds = (scanElapsedMilliseconds /
|
|
39976
|
+
const scanElapsedSeconds = (scanElapsedMilliseconds / MILLISECONDS_PER_SECOND).toFixed(1);
|
|
39958
39977
|
if (!lintFailureState.didFail) if (deadCodeFailureState.didFail) yield* scanProgress.fail(DEAD_CODE_FAIL_TEXT);
|
|
39959
39978
|
else if (input.suppressScanSummary) yield* scanProgress.stop();
|
|
39960
39979
|
else yield* scanProgress.succeed(`Scanned ${scannedFilesLabel} in ${scanElapsedSeconds}s${workerCountSuffix}`);
|
|
@@ -40168,7 +40187,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
40168
40187
|
static layerNode = effect(StagedFiles, gen(function* () {
|
|
40169
40188
|
const git = yield* Git;
|
|
40170
40189
|
return StagedFiles.of({
|
|
40171
|
-
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile))),
|
|
40190
|
+
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
|
|
40172
40191
|
materialize: ({ directory, stagedFiles, tempDirectory }) => materializeSourceTree({
|
|
40173
40192
|
directory,
|
|
40174
40193
|
files: stagedFiles,
|
|
@@ -40178,7 +40197,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
40178
40197
|
tempDirectory: tree.tempDirectory,
|
|
40179
40198
|
stagedFiles: tree.materializedFiles,
|
|
40180
40199
|
cleanup: tree.cleanup
|
|
40181
|
-
})))
|
|
40200
|
+
})), withSpan("StagedFiles.materialize"))
|
|
40182
40201
|
});
|
|
40183
40202
|
}));
|
|
40184
40203
|
/**
|
|
@@ -40576,4 +40595,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
40576
40595
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
40577
40596
|
|
|
40578
40597
|
//# sourceMappingURL=index.js.map
|
|
40579
|
-
//# debugId=
|
|
40598
|
+
//# debugId=ff319d21-ecce-5f79-a822-8cb00c30fea1
|