react-doctor 0.5.6-dev.451beeb → 0.5.6-dev.50999f4
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 +468 -260
- package/dist/index.js +94 -70
- package/dist/lsp.js +113 -92
- package/package.json +2 -2
package/dist/lsp.js
CHANGED
|
@@ -32761,6 +32761,7 @@ const isLargeMinifiedFile = (absolutePath) => {
|
|
|
32761
32761
|
if (sizeBytes < 2e4) return false;
|
|
32762
32762
|
return isMinifiedSource(absolutePath);
|
|
32763
32763
|
};
|
|
32764
|
+
const isErrnoException = (error) => error instanceof Error && "code" in error;
|
|
32764
32765
|
const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
32765
32766
|
"EACCES",
|
|
32766
32767
|
"EPERM",
|
|
@@ -32770,11 +32771,7 @@ const IGNORABLE_READDIR_ERROR_CODES = new Set([
|
|
|
32770
32771
|
"ELOOP",
|
|
32771
32772
|
"ENAMETOOLONG"
|
|
32772
32773
|
]);
|
|
32773
|
-
const isIgnorableReaddirError = (error) =>
|
|
32774
|
-
if (typeof error !== "object" || error === null) return false;
|
|
32775
|
-
const errorCode = error.code;
|
|
32776
|
-
return typeof errorCode === "string" && IGNORABLE_READDIR_ERROR_CODES.has(errorCode);
|
|
32777
|
-
};
|
|
32774
|
+
const isIgnorableReaddirError = (error) => isErrnoException(error) && typeof error.code === "string" && IGNORABLE_READDIR_ERROR_CODES.has(error.code);
|
|
32778
32775
|
const readDirectoryEntries = (directoryPath) => {
|
|
32779
32776
|
try {
|
|
32780
32777
|
return NFS.readdirSync(directoryPath, { withFileTypes: true });
|
|
@@ -32824,7 +32821,7 @@ const readPackageJsonUncached = (packageJsonPath) => {
|
|
|
32824
32821
|
return JSON.parse(NFS.readFileSync(packageJsonPath, "utf-8"));
|
|
32825
32822
|
} catch (error) {
|
|
32826
32823
|
if (error instanceof SyntaxError) return {};
|
|
32827
|
-
if (error
|
|
32824
|
+
if (isErrnoException(error)) {
|
|
32828
32825
|
const { code } = error;
|
|
32829
32826
|
if (code === "EISDIR" || code === "EACCES" || code === "EPERM" || code === "ENOENT") return {};
|
|
32830
32827
|
}
|
|
@@ -33549,17 +33546,13 @@ const isPackageJsonReactNativeAware = (packageJson) => {
|
|
|
33549
33546
|
return false;
|
|
33550
33547
|
};
|
|
33551
33548
|
const hasReactNativeWorkspaceAnywhere = (rootDirectory, rootPackageJson) => someWorkspacePackageJson(rootDirectory, rootPackageJson, isPackageJsonReactNativeAware);
|
|
33552
|
-
const
|
|
33553
|
-
const spec = packageJson.dependencies?.
|
|
33549
|
+
const getDependencySpec = (packageJson, packageName) => {
|
|
33550
|
+
const spec = packageJson.dependencies?.[packageName] ?? packageJson.devDependencies?.[packageName] ?? packageJson.peerDependencies?.[packageName] ?? packageJson.optionalDependencies?.[packageName];
|
|
33554
33551
|
return typeof spec === "string" ? spec : null;
|
|
33555
33552
|
};
|
|
33556
|
-
const findExpoVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson,
|
|
33553
|
+
const findExpoVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, "expo"));
|
|
33557
33554
|
const SHOPIFY_FLASH_LIST_PACKAGE_NAME = "@shopify/flash-list";
|
|
33558
|
-
const
|
|
33559
|
-
const spec = packageJson.dependencies?.["@shopify/flash-list"] ?? packageJson.devDependencies?.["@shopify/flash-list"] ?? packageJson.peerDependencies?.["@shopify/flash-list"] ?? packageJson.optionalDependencies?.["@shopify/flash-list"];
|
|
33560
|
-
return typeof spec === "string" ? spec : null;
|
|
33561
|
-
};
|
|
33562
|
-
const findShopifyFlashListVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, getShopifyFlashListDependencySpec);
|
|
33555
|
+
const findShopifyFlashListVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, SHOPIFY_FLASH_LIST_PACKAGE_NAME));
|
|
33563
33556
|
const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson, packageName, version }) => {
|
|
33564
33557
|
if (version === null || !isCatalogReference(version)) return version;
|
|
33565
33558
|
const catalogName = extractCatalogName(version);
|
|
@@ -33571,11 +33564,7 @@ const resolveCatalogBackedDependencyVersion = ({ rootDirectory, rootPackageJson,
|
|
|
33571
33564
|
if (!isFile(monorepoPackageJsonPath)) return version;
|
|
33572
33565
|
return resolveCatalogVersion(readPackageJson(monorepoPackageJsonPath), packageName, monorepoRoot, catalogName) ?? version;
|
|
33573
33566
|
};
|
|
33574
|
-
const
|
|
33575
|
-
const spec = packageJson.dependencies?.next ?? packageJson.devDependencies?.next ?? packageJson.peerDependencies?.next ?? packageJson.optionalDependencies?.next;
|
|
33576
|
-
return typeof spec === "string" ? spec : null;
|
|
33577
|
-
};
|
|
33578
|
-
const findNextjsVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, getNextjsDependencySpec);
|
|
33567
|
+
const findNextjsVersion = (rootDirectory, rootPackageJson) => findInWorkspacePackageJsons(rootDirectory, rootPackageJson, (packageJson) => getDependencySpec(packageJson, "next"));
|
|
33579
33568
|
const getPreactVersion = (packageJson) => {
|
|
33580
33569
|
return {
|
|
33581
33570
|
...packageJson.peerDependencies,
|
|
@@ -33657,6 +33646,11 @@ const ES_TARGET_YEAR_BY_NAME = {
|
|
|
33657
33646
|
esnext: 9999
|
|
33658
33647
|
};
|
|
33659
33648
|
/**
|
|
33649
|
+
* tsconfig filenames probed when resolving a project's TypeScript
|
|
33650
|
+
* compiler options — the root config first, then a monorepo base config.
|
|
33651
|
+
*/
|
|
33652
|
+
const TSCONFIG_FILENAMES = ["tsconfig.json", "tsconfig.base.json"];
|
|
33653
|
+
/**
|
|
33660
33654
|
* Project-config files that `StagedFiles.materialize` copies into
|
|
33661
33655
|
* the temp directory alongside staged sources so oxlint resolves
|
|
33662
33656
|
* `tsconfig` / `package.json` / lint configs the same way it would
|
|
@@ -34178,6 +34172,7 @@ const isTailwindAtLeast = (detected, required) => {
|
|
|
34178
34172
|
if (detected.major !== required.major) return detected.major > required.major;
|
|
34179
34173
|
return detected.minor >= required.minor;
|
|
34180
34174
|
};
|
|
34175
|
+
const messageFromUnknown = (error) => error instanceof Error ? error.message : String(error);
|
|
34181
34176
|
var InvalidGlobPatternError = class extends Error {
|
|
34182
34177
|
pattern;
|
|
34183
34178
|
reason;
|
|
@@ -34206,7 +34201,7 @@ const compileGlobPattern = (rawPattern) => {
|
|
|
34206
34201
|
try {
|
|
34207
34202
|
return import_picomatch.default.makeRe(normalizeGlobPattern(rawPattern), PICOMATCH_OPTIONS);
|
|
34208
34203
|
} catch (caughtError) {
|
|
34209
|
-
throw new InvalidGlobPatternError(rawPattern,
|
|
34204
|
+
throw new InvalidGlobPatternError(rawPattern, messageFromUnknown(caughtError));
|
|
34210
34205
|
}
|
|
34211
34206
|
};
|
|
34212
34207
|
const compileGlobPatternsLenient = (patterns, onInvalid) => {
|
|
@@ -35362,7 +35357,6 @@ const PACKAGE_JSON_FILENAME = "package.json";
|
|
|
35362
35357
|
const PACKAGE_JSON_CONFIG_KEY = "reactDoctor";
|
|
35363
35358
|
const LEGACY_CONFIG_FILENAME = "react-doctor.config.json";
|
|
35364
35359
|
const jiti = createJiti(import.meta.url);
|
|
35365
|
-
const formatError = (error) => error instanceof Error ? error.message : String(error);
|
|
35366
35360
|
const importDefaultExport = async (jitiInstance, filePath) => {
|
|
35367
35361
|
const imported = await jitiInstance.import(filePath);
|
|
35368
35362
|
return imported?.default ?? imported;
|
|
@@ -35394,7 +35388,7 @@ const loadModuleConfig = async (filePath) => {
|
|
|
35394
35388
|
try {
|
|
35395
35389
|
return await importDefaultExport(aliasJiti, filePath);
|
|
35396
35390
|
} catch (retryError) {
|
|
35397
|
-
throw new Error(`${
|
|
35391
|
+
throw new Error(`${messageFromUnknown(error)} (retry with ${SELF_PACKAGE_IMPORT_SPECIFIER} aliased to the running react-doctor package also failed: ${messageFromUnknown(retryError)})`, { cause: retryError });
|
|
35398
35392
|
}
|
|
35399
35393
|
}
|
|
35400
35394
|
};
|
|
@@ -35443,7 +35437,7 @@ const loadLegacyConfig = (directory) => {
|
|
|
35443
35437
|
}
|
|
35444
35438
|
warn(`${LEGACY_CONFIG_FILENAME} must contain an object, ignoring.`);
|
|
35445
35439
|
} catch (error) {
|
|
35446
|
-
warn(`Failed to load ${LEGACY_CONFIG_FILENAME}: ${
|
|
35440
|
+
warn(`Failed to load ${LEGACY_CONFIG_FILENAME}: ${messageFromUnknown(error)}`);
|
|
35447
35441
|
}
|
|
35448
35442
|
return {
|
|
35449
35443
|
status: "invalid",
|
|
@@ -35470,7 +35464,7 @@ const loadConfigFromDirectory = async (directory) => {
|
|
|
35470
35464
|
warn(`${CONFIG_BASENAME}.${extension} must export an object, ignoring.`);
|
|
35471
35465
|
sawBrokenConfigFile = true;
|
|
35472
35466
|
} catch (error) {
|
|
35473
|
-
warn(`Failed to load ${CONFIG_BASENAME}.${extension}: ${
|
|
35467
|
+
warn(`Failed to load ${CONFIG_BASENAME}.${extension}: ${messageFromUnknown(error)}`);
|
|
35474
35468
|
sawBrokenConfigFile = true;
|
|
35475
35469
|
}
|
|
35476
35470
|
}
|
|
@@ -36650,7 +36644,7 @@ const readIgnoreFile = (filePath) => {
|
|
|
36650
36644
|
try {
|
|
36651
36645
|
content = NFS.readFileSync(filePath, "utf-8");
|
|
36652
36646
|
} catch (error) {
|
|
36653
|
-
const errnoCode = error
|
|
36647
|
+
const errnoCode = isErrnoException(error) ? error.code : void 0;
|
|
36654
36648
|
if (errnoCode && errnoCode !== "ENOENT") runSync(warn$1(`Could not read ignore file ${filePath}: ${errnoCode}`));
|
|
36655
36649
|
return [];
|
|
36656
36650
|
}
|
|
@@ -36691,8 +36685,8 @@ const collectIgnorePatterns = (rootDirectory) => {
|
|
|
36691
36685
|
cachedPatternsByRoot.set(rootDirectory, patterns);
|
|
36692
36686
|
return patterns;
|
|
36693
36687
|
};
|
|
36688
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36694
36689
|
const KNIP_JSON_FILENAME = "knip.json";
|
|
36695
|
-
const isRecord$1 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36696
36690
|
const readJsonFileSafe = (filePath) => {
|
|
36697
36691
|
let rawContents;
|
|
36698
36692
|
try {
|
|
@@ -36708,10 +36702,10 @@ const readJsonFileSafe = (filePath) => {
|
|
|
36708
36702
|
};
|
|
36709
36703
|
const readKnipConfig = (rootDirectory) => {
|
|
36710
36704
|
const knipJson = readJsonFileSafe(path.join(rootDirectory, KNIP_JSON_FILENAME));
|
|
36711
|
-
if (isRecord
|
|
36705
|
+
if (isRecord(knipJson)) return knipJson;
|
|
36712
36706
|
const packageJson = readJsonFileSafe(path.join(rootDirectory, "package.json"));
|
|
36713
|
-
const packageKnipConfig = isRecord
|
|
36714
|
-
return isRecord
|
|
36707
|
+
const packageKnipConfig = isRecord(packageJson) ? packageJson.knip : null;
|
|
36708
|
+
return isRecord(packageKnipConfig) ? packageKnipConfig : null;
|
|
36715
36709
|
};
|
|
36716
36710
|
const normalizePatternList = (value) => {
|
|
36717
36711
|
if (typeof value === "string" && value.length > 0) return [value];
|
|
@@ -36723,10 +36717,10 @@ const prefixWorkspacePatterns = (workspacePattern, patterns) => {
|
|
|
36723
36717
|
return patterns.map((pattern) => pattern.startsWith("!") ? `!${normalizedWorkspacePattern}/${pattern.slice(1)}` : `${normalizedWorkspacePattern}/${pattern}`);
|
|
36724
36718
|
};
|
|
36725
36719
|
const collectKnipWorkspacePatterns = (workspaces, settingName) => {
|
|
36726
|
-
if (!isRecord
|
|
36720
|
+
if (!isRecord(workspaces)) return [];
|
|
36727
36721
|
const patterns = [];
|
|
36728
36722
|
for (const [workspacePattern, workspaceConfig] of Object.entries(workspaces)) {
|
|
36729
|
-
if (!isRecord
|
|
36723
|
+
if (!isRecord(workspaceConfig)) continue;
|
|
36730
36724
|
patterns.push(...prefixWorkspacePatterns(workspacePattern, normalizePatternList(workspaceConfig[settingName])));
|
|
36731
36725
|
}
|
|
36732
36726
|
return patterns;
|
|
@@ -36771,8 +36765,6 @@ const toCanonicalPath = (filePath) => {
|
|
|
36771
36765
|
};
|
|
36772
36766
|
const DEAD_CODE_PLUGIN = "deslop";
|
|
36773
36767
|
const DEAD_CODE_CATEGORY = "Maintainability";
|
|
36774
|
-
const TSCONFIG_FILENAMES$1 = ["tsconfig.json", "tsconfig.base.json"];
|
|
36775
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
36776
36768
|
const DEAD_CODE_WORKER_SCRIPT = `
|
|
36777
36769
|
const inputChunks = [];
|
|
36778
36770
|
process.stdin.on("data", (chunk) => inputChunks.push(chunk));
|
|
@@ -36830,7 +36822,7 @@ process.stdin.on("end", () => {
|
|
|
36830
36822
|
});
|
|
36831
36823
|
`;
|
|
36832
36824
|
const resolveTsConfigPath = (rootDirectory) => {
|
|
36833
|
-
for (const filename of TSCONFIG_FILENAMES
|
|
36825
|
+
for (const filename of TSCONFIG_FILENAMES) {
|
|
36834
36826
|
const candidate = Path.join(rootDirectory, filename);
|
|
36835
36827
|
if (NFS.existsSync(candidate)) return candidate;
|
|
36836
36828
|
}
|
|
@@ -37211,15 +37203,13 @@ var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
|
37211
37203
|
})()) }));
|
|
37212
37204
|
static layerOf = (diagnostics) => succeed$3(DeadCode, DeadCode.of({ run: () => fromIterable$1(diagnostics) }));
|
|
37213
37205
|
};
|
|
37214
|
-
const createNodeReadFileLinesSync = (rootDirectory) => {
|
|
37215
|
-
|
|
37216
|
-
|
|
37217
|
-
|
|
37218
|
-
|
|
37219
|
-
|
|
37220
|
-
|
|
37221
|
-
}
|
|
37222
|
-
};
|
|
37206
|
+
const createNodeReadFileLinesSync = (rootDirectory) => (filePath) => {
|
|
37207
|
+
const absolutePath = Path.isAbsolute(filePath) ? filePath : Path.join(rootDirectory, filePath);
|
|
37208
|
+
try {
|
|
37209
|
+
return NFS.readFileSync(absolutePath, "utf-8").split("\n");
|
|
37210
|
+
} catch {
|
|
37211
|
+
return null;
|
|
37212
|
+
}
|
|
37223
37213
|
};
|
|
37224
37214
|
var Files = class Files extends Service()("react-doctor/Files") {
|
|
37225
37215
|
static layerNode = succeed$3(Files, Files.of({
|
|
@@ -37430,7 +37420,10 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37430
37420
|
directory: input.directory,
|
|
37431
37421
|
cause
|
|
37432
37422
|
}) });
|
|
37433
|
-
})
|
|
37423
|
+
}), withSpan("git.exec", { attributes: {
|
|
37424
|
+
"git.command": input.command,
|
|
37425
|
+
"git.subcommand": input.args[0] ?? ""
|
|
37426
|
+
} }));
|
|
37434
37427
|
const runGit = (directory, args) => runCommand({
|
|
37435
37428
|
command: "git",
|
|
37436
37429
|
args,
|
|
@@ -37458,7 +37451,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37458
37451
|
]);
|
|
37459
37452
|
if (candidates.status !== 0) return null;
|
|
37460
37453
|
return trimOrNull(candidates.stdout.split("\n")[0] ?? "");
|
|
37461
|
-
});
|
|
37454
|
+
}).pipe(withSpan("Git.defaultBranch"));
|
|
37462
37455
|
const branchExists = (directory, branch) => runGit(directory, [
|
|
37463
37456
|
"rev-parse",
|
|
37464
37457
|
"--verify",
|
|
@@ -37505,7 +37498,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37505
37498
|
const result = resultOption.value;
|
|
37506
37499
|
if (result.status !== 0) return null;
|
|
37507
37500
|
return parseGithubViewerPermission(result.stdout);
|
|
37508
|
-
}).pipe(catch_$1(() => succeed$2(null)));
|
|
37501
|
+
}).pipe(catch_$1(() => succeed$2(null)), withSpan("Git.githubViewerPermission"));
|
|
37509
37502
|
/**
|
|
37510
37503
|
* Resolves a `--diff A..B` / `A...B` commit range into a changed-file
|
|
37511
37504
|
* selection. Each endpoint is validated with `isSafeGitRevision`
|
|
@@ -37619,7 +37612,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37619
37612
|
changedFiles: splitNullSeparated(diff.stdout),
|
|
37620
37613
|
isCurrentChanges: false
|
|
37621
37614
|
};
|
|
37622
|
-
}),
|
|
37615
|
+
}).pipe(withSpan("Git.diffSelection")),
|
|
37623
37616
|
stagedFilePaths: (directory) => runGit(directory, [
|
|
37624
37617
|
"diff",
|
|
37625
37618
|
"--cached",
|
|
@@ -37661,7 +37654,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37661
37654
|
status: result.status,
|
|
37662
37655
|
stdout: result.stdout
|
|
37663
37656
|
};
|
|
37664
|
-
}),
|
|
37657
|
+
}).pipe(withSpan("Git.grep")),
|
|
37665
37658
|
changedLineRanges: ({ directory, baseRef, cached, files }) => gen(function* () {
|
|
37666
37659
|
if (files.length === 0) return [];
|
|
37667
37660
|
if (baseRef !== void 0 && !isSafeGitRevision(baseRef)) return null;
|
|
@@ -37677,7 +37670,7 @@ var Git = class Git extends Service()("react-doctor/Git") {
|
|
|
37677
37670
|
]);
|
|
37678
37671
|
if (result.status !== 0) return null;
|
|
37679
37672
|
return parseChangedLineRanges(result.stdout);
|
|
37680
|
-
})
|
|
37673
|
+
}).pipe(withSpan("Git.changedLineRanges"))
|
|
37681
37674
|
});
|
|
37682
37675
|
})).pipe(provide$2(layer$2.pipe(provide$2(mergeAll$1(layer$1, layer)))));
|
|
37683
37676
|
/**
|
|
@@ -37892,7 +37885,7 @@ const neutralizeDisableDirectives = async (rootDirectory, includePaths) => {
|
|
|
37892
37885
|
for (const [absolutePath, originalContent] of originalContents) try {
|
|
37893
37886
|
NFS.writeFileSync(absolutePath, originalContent);
|
|
37894
37887
|
} catch (error) {
|
|
37895
|
-
process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${
|
|
37888
|
+
process.stderr.write(`[react-doctor] Failed to restore inline disable directives in ${absolutePath}: ${messageFromUnknown(error)}\n[react-doctor] Run: git checkout -- ${absolutePath}\n`);
|
|
37896
37889
|
}
|
|
37897
37890
|
};
|
|
37898
37891
|
const onExit = () => restore();
|
|
@@ -37998,7 +37991,7 @@ const resolveUserPlugin = (spec, configSourceDirectory) => {
|
|
|
37998
37991
|
try {
|
|
37999
37992
|
resolvedSpecifier = isRelative ? Path.resolve(configSourceDirectory, spec) : candidateRequire.resolve(spec);
|
|
38000
37993
|
} catch (error) {
|
|
38001
|
-
warnConfigIssue(`config.plugins entry "${spec}" could not be resolved from ${configSourceDirectory}: ${
|
|
37994
|
+
warnConfigIssue(`config.plugins entry "${spec}" could not be resolved from ${configSourceDirectory}: ${messageFromUnknown(error)}`);
|
|
38002
37995
|
return null;
|
|
38003
37996
|
}
|
|
38004
37997
|
const { name, ruleNames } = readPluginShape(resolvedSpecifier, (target) => candidateRequire(target));
|
|
@@ -38070,8 +38063,8 @@ const buildUserPluginRules = (userPlugin, severityControls) => {
|
|
|
38070
38063
|
}
|
|
38071
38064
|
return enabled;
|
|
38072
38065
|
};
|
|
38073
|
-
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [] }) => {
|
|
38074
|
-
const reactHooksJsPlugin = resolveReactHooksJsPlugin(project.hasReactCompiler, customRulesOnly);
|
|
38066
|
+
const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, extendsPaths = [], ignoredTags = /* @__PURE__ */ new Set(), serverAuthFunctionNames, severityControls, userPlugins = [], disableReactHooksJsPlugin = false }) => {
|
|
38067
|
+
const reactHooksJsPlugin = disableReactHooksJsPlugin ? null : resolveReactHooksJsPlugin(project.hasReactCompiler, customRulesOnly);
|
|
38075
38068
|
const reactCompilerRules = reactHooksJsPlugin ? applyRuleSeverityControls(filterRulesToAvailable(REACT_COMPILER_RULES, "react-hooks-js", reactHooksJsPlugin.availableRuleNames), severityControls) : {};
|
|
38076
38069
|
const jsPlugins = [];
|
|
38077
38070
|
if (reactHooksJsPlugin) jsPlugins.push(reactHooksJsPlugin.entry);
|
|
@@ -38131,7 +38124,6 @@ const resolveOxlintBinary = () => {
|
|
|
38131
38124
|
return Path.join(oxlintPackageDirectory, "bin", "oxlint");
|
|
38132
38125
|
};
|
|
38133
38126
|
const resolvePluginPath = () => esmRequire.resolve("oxlint-plugin-react-doctor");
|
|
38134
|
-
const TSCONFIG_FILENAMES = ["tsconfig.json", "tsconfig.base.json"];
|
|
38135
38127
|
const resolveTsConfigRelativePath = (rootDirectory) => {
|
|
38136
38128
|
for (const filename of TSCONFIG_FILENAMES) if (NFS.existsSync(Path.join(rootDirectory, filename))) return `./${filename}`;
|
|
38137
38129
|
return null;
|
|
@@ -38503,7 +38495,7 @@ const scopeContainsNonImportBinding = (node, scopeNode, identifierName) => {
|
|
|
38503
38495
|
const isIdentifierShadowedByLocalBinding = (identifier, sourceFile) => {
|
|
38504
38496
|
let currentNode = identifier.parent;
|
|
38505
38497
|
while (currentNode) {
|
|
38506
|
-
if (
|
|
38498
|
+
if (isScopeBoundary(currentNode)) {
|
|
38507
38499
|
if (scopeContainsNonImportBinding(currentNode, currentNode, identifier.text)) return true;
|
|
38508
38500
|
}
|
|
38509
38501
|
if (currentNode === sourceFile) return false;
|
|
@@ -38594,11 +38586,10 @@ const findResolutionInScope = (scopeNode, identifierName, reactImportBindings, s
|
|
|
38594
38586
|
});
|
|
38595
38587
|
return resolution;
|
|
38596
38588
|
};
|
|
38597
|
-
const isScopeNode = isScopeBoundary;
|
|
38598
38589
|
const resolveIdentifierBinding = (identifier, reactImportBindings, sourceFile, visitedDeclarations = /* @__PURE__ */ new Set()) => {
|
|
38599
38590
|
let currentNode = identifier.parent;
|
|
38600
38591
|
while (currentNode) {
|
|
38601
|
-
if (
|
|
38592
|
+
if (isScopeBoundary(currentNode)) {
|
|
38602
38593
|
const resolution = findResolutionInScope(currentNode, identifier.text, reactImportBindings, sourceFile, visitedDeclarations);
|
|
38603
38594
|
if (resolution) return resolution;
|
|
38604
38595
|
}
|
|
@@ -38768,9 +38759,9 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
38768
38759
|
try {
|
|
38769
38760
|
parsed = JSON.parse(sanitizedStdout);
|
|
38770
38761
|
} catch {
|
|
38771
|
-
throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0,
|
|
38762
|
+
throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0, 600) }) });
|
|
38772
38763
|
}
|
|
38773
|
-
if (!isOxlintOutput(parsed)) throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0,
|
|
38764
|
+
if (!isOxlintOutput(parsed)) throw new ReactDoctorError({ reason: new OxlintOutputUnparseable({ preview: stdout.slice(0, 600) }) });
|
|
38774
38765
|
const minifiedFileCache = /* @__PURE__ */ new Map();
|
|
38775
38766
|
const isMinifiedDiagnosticFile = (filename) => {
|
|
38776
38767
|
const absolutePath = Path.isAbsolute(filename) ? filename : Path.resolve(rootDirectory || ".", filename);
|
|
@@ -38846,7 +38837,7 @@ const spawnOxlint = (args, rootDirectory, nodeBinaryPath, spawnTimeoutMs = OXLIN
|
|
|
38846
38837
|
child.kill("SIGKILL");
|
|
38847
38838
|
reject(new ReactDoctorError({ reason: new OxlintBatchExceeded({
|
|
38848
38839
|
kind: "timeout",
|
|
38849
|
-
detail: `${spawnTimeoutMs /
|
|
38840
|
+
detail: `${spawnTimeoutMs / MILLISECONDS_PER_SECOND}s budget exceeded`
|
|
38850
38841
|
}) }));
|
|
38851
38842
|
}, spawnTimeoutMs);
|
|
38852
38843
|
timeoutHandle.unref?.();
|
|
@@ -39061,6 +39052,28 @@ const writeOxlintConfig = (configPath, configToWrite) => {
|
|
|
39061
39052
|
NFS.closeSync(fileHandle);
|
|
39062
39053
|
}
|
|
39063
39054
|
};
|
|
39055
|
+
const REACT_HOOKS_JS_DROP_PREFIX = "React Compiler rules (react-hooks-js/*) skipped — eslint-plugin-react-hooks failed to load in this environment";
|
|
39056
|
+
/**
|
|
39057
|
+
* Detects an oxlint config-load crash caused by the optional
|
|
39058
|
+
* `react-hooks-js` (eslint-plugin-react-hooks) React Compiler plugin and
|
|
39059
|
+
* builds the partial-failure note for it; returns `null` when the failure
|
|
39060
|
+
* was anything else.
|
|
39061
|
+
*
|
|
39062
|
+
* oxlint prints a framed error to stdout (not stderr) and exits non-zero
|
|
39063
|
+
* when a `jsPlugins` entry can't be imported; that non-JSON stdout
|
|
39064
|
+
* surfaces as `OxlintOutputUnparseable`. Because oxlint fails the WHOLE
|
|
39065
|
+
* config load on it, leaving the plugin in would drop every curated
|
|
39066
|
+
* react-doctor diagnostic too — so the caller retries with the plugin
|
|
39067
|
+
* stripped (issue #833). Both markers sit at the start of oxlint's
|
|
39068
|
+
* message, so they survive the `preview` slice even for deep pnpm paths.
|
|
39069
|
+
*/
|
|
39070
|
+
const reactHooksJsPluginDropNote = (error) => {
|
|
39071
|
+
if (!(error instanceof ReactDoctorError) || error.reason._tag !== "OxlintOutputUnparseable") return null;
|
|
39072
|
+
const { preview } = error.reason;
|
|
39073
|
+
if (!preview.includes("Failed to load JS plugin") || !preview.includes("eslint-plugin-react-hooks")) return null;
|
|
39074
|
+
const underlyingReason = preview.match(/Error:[^\n]*/)?.[0]?.trim();
|
|
39075
|
+
return `${REACT_HOOKS_JS_DROP_PREFIX}${underlyingReason ? `: ${underlyingReason}` : ""}. Other rules ran normally.`;
|
|
39076
|
+
};
|
|
39064
39077
|
/**
|
|
39065
39078
|
* The oxlint runner. Composed of three pieces in `runners/oxlint/`:
|
|
39066
39079
|
*
|
|
@@ -39088,15 +39101,16 @@ const runOxlint = async (options) => {
|
|
|
39088
39101
|
const pluginPath = resolvePluginPath();
|
|
39089
39102
|
const extendsPaths = (adoptExistingLintConfig && !customRulesOnly ? detectUserLintConfigPaths(rootDirectory) : []).filter(canOxlintExtendConfig);
|
|
39090
39103
|
const userPlugins = resolveUserPlugins(userConfig?.plugins, configSourceDirectory);
|
|
39091
|
-
const buildConfig = (
|
|
39104
|
+
const buildConfig = (overrides) => createOxlintConfig({
|
|
39092
39105
|
pluginPath,
|
|
39093
39106
|
project,
|
|
39094
39107
|
customRulesOnly,
|
|
39095
|
-
extendsPaths:
|
|
39108
|
+
extendsPaths: overrides.extendsPaths,
|
|
39096
39109
|
ignoredTags,
|
|
39097
39110
|
serverAuthFunctionNames,
|
|
39098
39111
|
severityControls,
|
|
39099
|
-
userPlugins
|
|
39112
|
+
userPlugins,
|
|
39113
|
+
disableReactHooksJsPlugin: overrides.disableReactHooksJsPlugin
|
|
39100
39114
|
});
|
|
39101
39115
|
const restoreDisableDirectives = respectInlineDisables ? () => {} : await neutralizeDisableDirectives(rootDirectory, includePaths);
|
|
39102
39116
|
const configDirectory = NFS.mkdtempSync(Path.join(os.tmpdir(), "react-doctor-oxlintrc-"));
|
|
@@ -39132,12 +39146,22 @@ const runOxlint = async (options) => {
|
|
|
39132
39146
|
outputMaxBytes,
|
|
39133
39147
|
concurrency: options.concurrency
|
|
39134
39148
|
});
|
|
39135
|
-
writeOxlintConfig(configPath, buildConfig(extendsPaths));
|
|
39149
|
+
writeOxlintConfig(configPath, buildConfig({ extendsPaths }));
|
|
39136
39150
|
try {
|
|
39137
39151
|
return await runBatches();
|
|
39138
39152
|
} catch (error) {
|
|
39153
|
+
const reactHooksJsDropNote = reactHooksJsPluginDropNote(error);
|
|
39154
|
+
if (reactHooksJsDropNote !== null) {
|
|
39155
|
+
writeOxlintConfig(configPath, buildConfig({
|
|
39156
|
+
extendsPaths,
|
|
39157
|
+
disableReactHooksJsPlugin: true
|
|
39158
|
+
}));
|
|
39159
|
+
const diagnostics = await runBatches();
|
|
39160
|
+
onPartialFailure?.(reactHooksJsDropNote);
|
|
39161
|
+
return diagnostics;
|
|
39162
|
+
}
|
|
39139
39163
|
if (extendsPaths.length === 0) throw error;
|
|
39140
|
-
writeOxlintConfig(configPath, buildConfig([]));
|
|
39164
|
+
writeOxlintConfig(configPath, buildConfig({ extendsPaths: [] }));
|
|
39141
39165
|
return await runBatches();
|
|
39142
39166
|
}
|
|
39143
39167
|
} finally {
|
|
@@ -39935,7 +39959,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
39935
39959
|
}))))))));
|
|
39936
39960
|
const deadCodeFailureState = yield* get$2(deadCodeFailure);
|
|
39937
39961
|
const scanElapsedMilliseconds = Date.now() - scanStartTime;
|
|
39938
|
-
const scanElapsedSeconds = (scanElapsedMilliseconds /
|
|
39962
|
+
const scanElapsedSeconds = (scanElapsedMilliseconds / MILLISECONDS_PER_SECOND).toFixed(1);
|
|
39939
39963
|
if (!lintFailureState.didFail) if (deadCodeFailureState.didFail) yield* scanProgress.fail(DEAD_CODE_FAIL_TEXT);
|
|
39940
39964
|
else if (input.suppressScanSummary) yield* scanProgress.stop();
|
|
39941
39965
|
else yield* scanProgress.succeed(`Scanned ${scannedFilesLabel} in ${scanElapsedSeconds}s${workerCountSuffix}`);
|
|
@@ -40149,7 +40173,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
40149
40173
|
static layerNode = effect(StagedFiles, gen(function* () {
|
|
40150
40174
|
const git = yield* Git;
|
|
40151
40175
|
return StagedFiles.of({
|
|
40152
|
-
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile))),
|
|
40176
|
+
discoverSourceFiles: (directory) => git.stagedFilePaths(directory).pipe(map$3((entries) => entries.filter(isLintableSourceFile)), withSpan("StagedFiles.discoverSourceFiles")),
|
|
40153
40177
|
materialize: ({ directory, stagedFiles, tempDirectory }) => materializeSourceTree({
|
|
40154
40178
|
directory,
|
|
40155
40179
|
files: stagedFiles,
|
|
@@ -40159,7 +40183,7 @@ const materializeSourceTree = (input) => gen(function* () {
|
|
|
40159
40183
|
tempDirectory: tree.tempDirectory,
|
|
40160
40184
|
stagedFiles: tree.materializedFiles,
|
|
40161
40185
|
cleanup: tree.cleanup
|
|
40162
|
-
})))
|
|
40186
|
+
})), withSpan("StagedFiles.materialize"))
|
|
40163
40187
|
});
|
|
40164
40188
|
}));
|
|
40165
40189
|
/**
|
|
@@ -40227,7 +40251,10 @@ const runEditorScan = async (input) => {
|
|
|
40227
40251
|
isCi: false,
|
|
40228
40252
|
resolveLocalGithubViewerPermission: false,
|
|
40229
40253
|
skipJsxIncludeFilter: true
|
|
40230
|
-
}).pipe(
|
|
40254
|
+
}).pipe(withSpan("runEditorScan", { attributes: {
|
|
40255
|
+
"editor.lint": lint,
|
|
40256
|
+
"editor.runDeadCode": runDeadCode
|
|
40257
|
+
} }), provide(layers), provide(layerOtlp)));
|
|
40231
40258
|
if (isSuccess(exit)) {
|
|
40232
40259
|
const output = exit.value;
|
|
40233
40260
|
return {
|
|
@@ -40257,7 +40284,7 @@ const runEditorScan = async (input) => {
|
|
|
40257
40284
|
didDeadCodeFail: false,
|
|
40258
40285
|
deadCodeFailureReason: null,
|
|
40259
40286
|
lintPartialFailures: [],
|
|
40260
|
-
error:
|
|
40287
|
+
error: messageFromUnknown(error)
|
|
40261
40288
|
};
|
|
40262
40289
|
};
|
|
40263
40290
|
/**
|
|
@@ -40539,7 +40566,6 @@ const toLspDiagnostic = (input) => {
|
|
|
40539
40566
|
data
|
|
40540
40567
|
};
|
|
40541
40568
|
};
|
|
40542
|
-
const toUri = (absoluteFilePath) => fsPathToUri(absoluteFilePath);
|
|
40543
40569
|
/**
|
|
40544
40570
|
* Owns the published-diagnostic state. Maps scan outcomes to LSP
|
|
40545
40571
|
* diagnostics, publishes complete per-URI replacement sets (so the
|
|
@@ -40569,7 +40595,7 @@ var DiagnosticsManager = class {
|
|
|
40569
40595
|
const isProtectedPath = (fsPath) => protectOpen && this.isOpen(fsPath);
|
|
40570
40596
|
for (const [fsPath, coreDiagnostics] of outcome.byFile) {
|
|
40571
40597
|
if (isProtectedPath(fsPath)) continue;
|
|
40572
|
-
const uri =
|
|
40598
|
+
const uri = fsPathToUri(fsPath);
|
|
40573
40599
|
const text = this.textProvider(fsPath);
|
|
40574
40600
|
const lspDiagnostics = coreDiagnostics.map((diagnostic) => toLspDiagnostic({
|
|
40575
40601
|
diagnostic,
|
|
@@ -40591,7 +40617,7 @@ var DiagnosticsManager = class {
|
|
|
40591
40617
|
for (const fsPath of outcome.requestedPaths) {
|
|
40592
40618
|
if (isProtectedPath(fsPath)) continue;
|
|
40593
40619
|
if (outcome.byFile.has(fsPath)) continue;
|
|
40594
|
-
const uri =
|
|
40620
|
+
const uri = fsPathToUri(fsPath);
|
|
40595
40621
|
if (this.byUri.has(uri)) this.byUri.delete(uri);
|
|
40596
40622
|
this.publish(uri, []);
|
|
40597
40623
|
}
|
|
@@ -40616,7 +40642,7 @@ var DiagnosticsManager = class {
|
|
|
40616
40642
|
const set = this.projectUris.get(project) ?? /* @__PURE__ */ new Set();
|
|
40617
40643
|
for (const uri of liveUris) set.add(uri);
|
|
40618
40644
|
for (const fsPath of outcome.requestedPaths) {
|
|
40619
|
-
const uri =
|
|
40645
|
+
const uri = fsPathToUri(fsPath);
|
|
40620
40646
|
if (!liveUris.has(uri)) set.delete(uri);
|
|
40621
40647
|
}
|
|
40622
40648
|
this.projectUris.set(project, set);
|
|
@@ -40644,7 +40670,7 @@ var DiagnosticsManager = class {
|
|
|
40644
40670
|
const tracked = this.projectUris.get(project);
|
|
40645
40671
|
if (!tracked) return;
|
|
40646
40672
|
const liveUris = /* @__PURE__ */ new Set();
|
|
40647
|
-
for (const fsPath of liveFsPaths) liveUris.add(
|
|
40673
|
+
for (const fsPath of liveFsPaths) liveUris.add(fsPathToUri(fsPath));
|
|
40648
40674
|
for (const uri of [...tracked]) {
|
|
40649
40675
|
if (liveUris.has(uri)) continue;
|
|
40650
40676
|
this.byUri.delete(uri);
|
|
@@ -40941,7 +40967,7 @@ const createProjectGraph = (options) => {
|
|
|
40941
40967
|
});
|
|
40942
40968
|
}
|
|
40943
40969
|
} catch (error) {
|
|
40944
|
-
logger.warn(`Project discovery failed for ${root}: ${
|
|
40970
|
+
logger.warn(`Project discovery failed for ${root}: ${messageFromUnknown(error)}`);
|
|
40945
40971
|
}
|
|
40946
40972
|
return [...seen.values()].sort((first, second) => second.directory.length - first.directory.length);
|
|
40947
40973
|
};
|
|
@@ -40969,6 +40995,11 @@ const createProjectGraph = (options) => {
|
|
|
40969
40995
|
}
|
|
40970
40996
|
};
|
|
40971
40997
|
};
|
|
40998
|
+
const toProjectRelative = (projectDirectory, filePath) => {
|
|
40999
|
+
const relative = Path.relative(projectDirectory, filePath).replace(/\\/g, "/");
|
|
41000
|
+
if (relative.length === 0 || relative.startsWith("../") || Path.isAbsolute(relative)) return null;
|
|
41001
|
+
return relative;
|
|
41002
|
+
};
|
|
40972
41003
|
const resolveCacheFilePath = (projectDirectory) => {
|
|
40973
41004
|
const nodeModules = path.join(projectDirectory, "node_modules");
|
|
40974
41005
|
if (fs.existsSync(nodeModules)) return path.join(nodeModules, ".cache", "react-doctor", "lint-cache.json");
|
|
@@ -41003,7 +41034,7 @@ const createLintCache = (input) => {
|
|
|
41003
41034
|
fs.writeFileSync(tempPath, JSON.stringify(payload));
|
|
41004
41035
|
fs.renameSync(tempPath, cacheFilePath);
|
|
41005
41036
|
} catch (error) {
|
|
41006
|
-
logger.warn(`Failed to persist lint cache: ${
|
|
41037
|
+
logger.warn(`Failed to persist lint cache: ${messageFromUnknown(error)}`);
|
|
41007
41038
|
}
|
|
41008
41039
|
};
|
|
41009
41040
|
return {
|
|
@@ -41029,11 +41060,6 @@ const createLintCache = (input) => {
|
|
|
41029
41060
|
};
|
|
41030
41061
|
const OVERLAY_TEMP_PREFIX = "react-doctor-lsp-";
|
|
41031
41062
|
const OVERLAY_CONFIG_FILENAMES = [...new Set([...STAGED_FILES_PROJECT_CONFIG_FILENAMES, ...ADOPTABLE_LINT_CONFIG_FILENAMES])];
|
|
41032
|
-
const toProjectRelative$1 = (projectDirectory, filePath) => {
|
|
41033
|
-
const relative = path.relative(projectDirectory, filePath).replace(/\\/g, "/");
|
|
41034
|
-
if (relative.length === 0 || relative.startsWith("../") || path.isAbsolute(relative)) return null;
|
|
41035
|
-
return relative;
|
|
41036
|
-
};
|
|
41037
41063
|
/**
|
|
41038
41064
|
* Writes the live (possibly unsaved) content of the target files into a
|
|
41039
41065
|
* throwaway temp tree that mirrors the project, alongside the well-known
|
|
@@ -41047,7 +41073,7 @@ const materializeOverlay = (input) => {
|
|
|
41047
41073
|
const relativePaths = [];
|
|
41048
41074
|
try {
|
|
41049
41075
|
for (const filePath of input.files) {
|
|
41050
|
-
const relative = toProjectRelative
|
|
41076
|
+
const relative = toProjectRelative(input.projectDirectory, filePath);
|
|
41051
41077
|
if (relative === null) continue;
|
|
41052
41078
|
const content = input.readText(filePath);
|
|
41053
41079
|
if (content === null) continue;
|
|
@@ -41095,11 +41121,6 @@ const materializeOverlay = (input) => {
|
|
|
41095
41121
|
throw error;
|
|
41096
41122
|
}
|
|
41097
41123
|
};
|
|
41098
|
-
const toProjectRelative = (projectDirectory, filePath) => {
|
|
41099
|
-
const relative = path.relative(projectDirectory, filePath).replace(/\\/g, "/");
|
|
41100
|
-
if (relative.length === 0 || relative.startsWith("../") || path.isAbsolute(relative)) return null;
|
|
41101
|
-
return relative;
|
|
41102
|
-
};
|
|
41103
41124
|
/**
|
|
41104
41125
|
* Resolves a diagnostic's (possibly relative, possibly overlay-temp)
|
|
41105
41126
|
* file path back to the canonical absolute path inside the real project.
|
|
@@ -41321,7 +41342,7 @@ const createScheduler = (options) => {
|
|
|
41321
41342
|
if (outcome && !token.isCancelled) options.onResult(outcome);
|
|
41322
41343
|
}).catch((error) => {
|
|
41323
41344
|
if (options.onError) options.onError(error, request);
|
|
41324
|
-
else logger.error(`Scan failed: ${
|
|
41345
|
+
else logger.error(`Scan failed: ${messageFromUnknown(error)}`);
|
|
41325
41346
|
}).finally(() => {
|
|
41326
41347
|
running -= 1;
|
|
41327
41348
|
if (isBackground) runningBackground -= 1;
|
|
@@ -41708,7 +41729,7 @@ const createServer = (connection, options = {}) => {
|
|
|
41708
41729
|
maybeWarnLintUnavailable(outcome);
|
|
41709
41730
|
if (outcome.request.priority === "background") scanTelemetry.accumulate(outcome);
|
|
41710
41731
|
},
|
|
41711
|
-
onError: (error, request) => logger.error(`Scan of ${request.projectDirectory} threw: ${
|
|
41732
|
+
onError: (error, request) => logger.error(`Scan of ${request.projectDirectory} threw: ${messageFromUnknown(error)}`),
|
|
41712
41733
|
onIdleChange: (idle) => {
|
|
41713
41734
|
setBusy(!idle);
|
|
41714
41735
|
if (idle) scanTelemetry.finish();
|
|
@@ -42356,5 +42377,5 @@ const startLanguageServer = () => {
|
|
|
42356
42377
|
};
|
|
42357
42378
|
//#endregion
|
|
42358
42379
|
export { startLanguageServer };
|
|
42359
|
-
!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]="
|
|
42360
|
-
//# debugId=
|
|
42380
|
+
!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]="7b102472-d01e-5d6a-9975-91795fe8abc5")}catch(e){}}();
|
|
42381
|
+
//# debugId=7b102472-d01e-5d6a-9975-91795fe8abc5
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.5.6-dev.
|
|
3
|
+
"version": "0.5.6-dev.50999f4",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"vscode-languageserver": "^9.0.1",
|
|
65
65
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
66
66
|
"vscode-uri": "^3.1.0",
|
|
67
|
-
"oxlint-plugin-react-doctor": "0.5.6-dev.
|
|
67
|
+
"oxlint-plugin-react-doctor": "0.5.6-dev.50999f4"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
70
|
"@types/babel__code-frame": "^7.27.0",
|