react-doctor 0.7.6-dev.e026a23 → 0.7.6-dev.e877ca7
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 +14 -13
- package/dist/index.d.ts +3 -4
- package/dist/index.js +9 -6
- package/dist/lsp.js +35 -25
- package/package.json +4 -4
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="63b8a227-543e-5501-a998-58c03a1fb10e")}catch(e){}}();
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import * as NodeChildProcess from "node:child_process";
|
|
5
5
|
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
@@ -40762,7 +40762,9 @@ const setColorEnabled = (enabled) => {
|
|
|
40762
40762
|
highlighter.gray = colors.gray;
|
|
40763
40763
|
highlighter.bold = colors.bold;
|
|
40764
40764
|
};
|
|
40765
|
-
const
|
|
40765
|
+
const NEXT_ENTRY_FILE_PATTERN = /^(?:\.\/)?(?:src\/)?(?:middleware|proxy)\.(?:tsx?|jsx?|mts|mjs)$/;
|
|
40766
|
+
const shouldIncludeExplicitLintPath = (filePath, project) => JSX_FILE_PATTERN.test(filePath) || project?.framework === "nextjs" && NEXT_ENTRY_FILE_PATTERN.test(filePath);
|
|
40767
|
+
const computeExplicitLintIncludePaths = (includePaths, project) => includePaths.length > 0 ? includePaths.filter((filePath) => shouldIncludeExplicitLintPath(filePath, project)) : void 0;
|
|
40766
40768
|
const LINGUIST_ATTRIBUTE_PATTERN = /^linguist-(?:vendored|generated)(?:=([a-zA-Z0-9]+))?$/i;
|
|
40767
40769
|
const FALSY_VALUES = new Set([
|
|
40768
40770
|
"false",
|
|
@@ -41601,11 +41603,11 @@ const resolveDeadCodeTimeout = (input) => {
|
|
|
41601
41603
|
phaseTimeoutMs: workerTimeoutMs + DEAD_CODE_PHASE_TIMEOUT_OVER_WORKER_MS
|
|
41602
41604
|
};
|
|
41603
41605
|
};
|
|
41604
|
-
const resolveLintIncludePaths = (rootDirectory, userConfig) => {
|
|
41606
|
+
const resolveLintIncludePaths = (rootDirectory, userConfig, project) => {
|
|
41605
41607
|
if (!Array.isArray(userConfig?.ignore?.files) || userConfig.ignore.files.length === 0) return;
|
|
41606
41608
|
const ignoredPatterns = compileIgnoredFilePatterns(userConfig);
|
|
41607
41609
|
return listSourceFiles(rootDirectory).filter((filePath) => {
|
|
41608
|
-
if (!
|
|
41610
|
+
if (!shouldIncludeExplicitLintPath(filePath, project)) return false;
|
|
41609
41611
|
return !isFileIgnoredByPatterns(filePath, rootDirectory, ignoredPatterns);
|
|
41610
41612
|
});
|
|
41611
41613
|
};
|
|
@@ -45487,7 +45489,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
45487
45489
|
directory: scanDirectory,
|
|
45488
45490
|
repo
|
|
45489
45491
|
}).pipe(orElseSucceed(() => null)) : succeed$2(null));
|
|
45490
|
-
const lintIncludePaths = (input.
|
|
45492
|
+
const lintIncludePaths = (input.skipJsxIncludeFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths], project)) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, project);
|
|
45491
45493
|
const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
|
|
45492
45494
|
const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
|
|
45493
45495
|
const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
|
|
@@ -46665,7 +46667,7 @@ const makeNoopConsole = () => ({
|
|
|
46665
46667
|
});
|
|
46666
46668
|
//#endregion
|
|
46667
46669
|
//#region src/cli/utils/version.ts
|
|
46668
|
-
const VERSION = "0.7.6-dev.
|
|
46670
|
+
const VERSION = "0.7.6-dev.e877ca7";
|
|
46669
46671
|
//#endregion
|
|
46670
46672
|
//#region src/cli/utils/json-mode.ts
|
|
46671
46673
|
let context = null;
|
|
@@ -47034,13 +47036,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
47034
47036
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
47035
47037
|
* standard `SENTRY_RELEASE` override.
|
|
47036
47038
|
*/
|
|
47037
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.7.6-dev.
|
|
47039
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.7.6-dev.e877ca7`;
|
|
47038
47040
|
/**
|
|
47039
47041
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
47040
47042
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
47041
47043
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
47042
47044
|
*/
|
|
47043
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.7.6-dev.
|
|
47045
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.7.6-dev.e877ca7") ? "development" : "production");
|
|
47044
47046
|
/**
|
|
47045
47047
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
47046
47048
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -59200,7 +59202,7 @@ const buildDirtyPathContentFingerprint = (absolutePath, statusCode) => {
|
|
|
59200
59202
|
return null;
|
|
59201
59203
|
}
|
|
59202
59204
|
if (!stats.isFile()) return null;
|
|
59203
|
-
if (stats.size > 10485760) return
|
|
59205
|
+
if (stats.size > 10485760) return `stat:${stats.mtimeMs}:${stats.size}`;
|
|
59204
59206
|
return hashFileContents(absolutePath);
|
|
59205
59207
|
};
|
|
59206
59208
|
const buildWorktreeFingerprint = (projectDirectory) => {
|
|
@@ -59674,8 +59676,7 @@ const buildScanAttributes = (input) => {
|
|
|
59674
59676
|
hasCustomConfig: input.hasCustomConfig,
|
|
59675
59677
|
rulesConfigured: ruleKeys.length,
|
|
59676
59678
|
rulesDisabled: ruleKeys.filter((key) => ruleOverrides[key] === "off").length,
|
|
59677
|
-
fileCount: input.result?.scannedFileCount ?? null
|
|
59678
|
-
nonJsxFileCount: input.result?.analyzedFiles?.filter((filePath) => !JSX_FILE_PATTERN.test(filePath)).length ?? null
|
|
59679
|
+
fileCount: input.result?.scannedFileCount ?? null
|
|
59679
59680
|
});
|
|
59680
59681
|
};
|
|
59681
59682
|
/**
|
|
@@ -65180,7 +65181,7 @@ ${highlighter.dim("Learn more:")}
|
|
|
65180
65181
|
${highlighter.info(CI_URL)}
|
|
65181
65182
|
`;
|
|
65182
65183
|
const collectCategoryOption = (value, previousValues) => [...previousValues ?? [], value];
|
|
65183
|
-
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much
|
|
65184
|
+
const program = new Command().name("react-doctor").description("Diagnose React codebase health").version(VERSION, "-v, --version", "display the version number").argument("[directory]", "project directory to scan", ".").option("--lint", "enable linting").option("--no-lint", "skip linting").option("--dead-code", "enable dead-code analysis (default)").option("--no-dead-code", "skip dead-code analysis (unused files / exports / dependencies, circular imports)").option("--supply-chain", "enable the dependency supply-chain scan (default)").option("--no-supply-chain", "skip the dependency supply-chain scan (Socket.dev dependency health checks)").option("--verbose", "show every rule and per-file details (default shows top 3 rules)").option("--debug", "force a Sentry trace and print its id at the end (paste it into a bug report)").option("--output-dir <dir>", "directory for the full diagnostics dump (default: a temp folder)").option("--score", "output only the score").option("--json", "output a single structured JSON report (suppresses other output)").option("--json-compact", "with --json, emit compact JSON (no indentation)").option("--json-out <path>", "with --json, write the report to a file instead of stdout").option("-y, --yes", "skip prompts, scan all workspace projects").option("--no-parallel", "lint serially with one worker (default: parallel across CPU cores; set the worker count with REACT_DOCTOR_PARALLEL)").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple); overrides the `projects` config field").option("--scope <value>", "how much to scan/report: full (default), files, changed (only new issues vs base), or lines (only changed lines)").option("--base <ref>", "base git ref for files/changed/lines scope (auto-detected when omitted)").addOption(new Option("--diff [base]", "[deprecated] alias for --scope changed (pass `false` to force a full scan)").hideHelp()).addOption(new Option("--changed-files-from <file>", "scan source files listed in a newline-delimited changed-files file").hideHelp()).option("--no-score", "skip the score API, the share URL, and crash reporting").addOption(new Option("--category <category>", "only show diagnostics in a category (repeatable; e.g. Security)").argParser(collectCategoryOption)).option("--no-telemetry", "alias for --no-score (skip the score API, share URL, and crash reporting)").option("--staged", "scan only staged (git index) files for pre-commit hooks").option("--max-duration <seconds>", "scan time budget for the whole run, shared across workspace projects: past it, remaining lint batches and dead-code are skipped and partial results are reported (skipped files are listed in the JSON report)").option("--blocking <level>", "severity that fails CI: error (default), warning, or none (advisory)").addOption(new Option("--fail-on <level>", "[deprecated] alias for --blocking <level>").hideHelp()).option("--no-respect-inline-disables", "audit mode: neutralize inline lint suppressions before scanning").option("--warnings", "show warning-severity diagnostics (default)").option("--no-warnings", "hide warning-severity diagnostics (errors only)").option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderRootHelpEpilog);
|
|
65184
65185
|
program.action(inspectAction);
|
|
65185
65186
|
program.command("why <location>").description("Explain why a rule fired (or why a suppression didn't apply) at a file:line").option("--project <name>", "select projects: workspace names or directory paths (comma-separated for multiple)").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").action((location, options) => whyAction(location, options));
|
|
65186
65187
|
program.command("install").alias("setup").description("Install the react-doctor skill into your coding agents and optional git hook").option("-y, --yes", "skip prompts, install for all detected agents").option("--dry-run", "show what would be installed without writing files").option("--agent-hooks", "install native non-blocking agent hooks for Claude Code and Cursor").option("-c, --cwd <cwd>", "working directory", process.cwd()).option("--color", "force colored output").option("--no-color", "disable colored output (also honors NO_COLOR)").addHelpText("after", renderInstallHelpEpilog).action(installAction);
|
|
@@ -65230,4 +65231,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
65230
65231
|
export {};
|
|
65231
65232
|
|
|
65232
65233
|
//# sourceMappingURL=cli.js.map
|
|
65233
|
-
//# debugId=
|
|
65234
|
+
//# debugId=63b8a227-543e-5501-a998-58c03a1fb10e
|
package/dist/index.d.ts
CHANGED
|
@@ -9654,7 +9654,6 @@ interface DiagnoseOptions {
|
|
|
9654
9654
|
/** See `ReactDoctorConfig.deadCode`. Ignored in diff mode. */
|
|
9655
9655
|
deadCode?: boolean;
|
|
9656
9656
|
verbose?: boolean;
|
|
9657
|
-
/** Restrict linting to these supported JS/TS source files. */
|
|
9658
9657
|
includePaths?: string[];
|
|
9659
9658
|
/**
|
|
9660
9659
|
* Per-call override for `ReactDoctorConfig.respectInlineDisables`.
|
|
@@ -9916,9 +9915,9 @@ interface JsonReportProjectEntry {
|
|
|
9916
9915
|
skippedCheckReasons?: Record<string, string>;
|
|
9917
9916
|
/**
|
|
9918
9917
|
* Number of source files this scan's linter examined. In diff / changed
|
|
9919
|
-
* mode it's the count of changed
|
|
9920
|
-
* scan it's the whole source tree. `0`
|
|
9921
|
-
* files held nothing React Doctor lints —
|
|
9918
|
+
* mode it's the count of changed React-eligible files (`.tsx`/`.jsx` plus
|
|
9919
|
+
* framework entry files); in a full scan it's the whole source tree. `0`
|
|
9920
|
+
* in a diff scan means the changed files held nothing React Doctor lints —
|
|
9922
9921
|
* the GitHub Action reads that as "nothing to report" (skips the PR comment;
|
|
9923
9922
|
* the commit status says "skipped"). Optional: absent on reports from
|
|
9924
9923
|
* constructors that don't track it (e.g. `toJsonReport`).
|
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]="7a10d23c-04fd-53e1-a623-a3dc5d6d0830")}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 reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
|
|
@@ -32930,6 +32930,7 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
32930
32930
|
"out",
|
|
32931
32931
|
"storybook-static"
|
|
32932
32932
|
]);
|
|
32933
|
+
const JSX_FILE_PATTERN = /\.(tsx|jsx)$/;
|
|
32933
32934
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
32934
32935
|
const SCORE_API_URL = "https://www.react.doctor/api/score";
|
|
32935
32936
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
@@ -37515,7 +37516,9 @@ const highlighter = {
|
|
|
37515
37516
|
gray: import_picocolors.default.gray,
|
|
37516
37517
|
bold: import_picocolors.default.bold
|
|
37517
37518
|
};
|
|
37518
|
-
const
|
|
37519
|
+
const NEXT_ENTRY_FILE_PATTERN = /^(?:\.\/)?(?:src\/)?(?:middleware|proxy)\.(?:tsx?|jsx?|mts|mjs)$/;
|
|
37520
|
+
const shouldIncludeExplicitLintPath = (filePath, project) => JSX_FILE_PATTERN.test(filePath) || project?.framework === "nextjs" && NEXT_ENTRY_FILE_PATTERN.test(filePath);
|
|
37521
|
+
const computeExplicitLintIncludePaths = (includePaths, project) => includePaths.length > 0 ? includePaths.filter((filePath) => shouldIncludeExplicitLintPath(filePath, project)) : void 0;
|
|
37519
37522
|
const LINGUIST_ATTRIBUTE_PATTERN = /^linguist-(?:vendored|generated)(?:=([a-zA-Z0-9]+))?$/i;
|
|
37520
37523
|
const FALSY_VALUES = new Set([
|
|
37521
37524
|
"false",
|
|
@@ -38357,11 +38360,11 @@ const resolveDeadCodeTimeout = (input) => {
|
|
|
38357
38360
|
phaseTimeoutMs: workerTimeoutMs + DEAD_CODE_PHASE_TIMEOUT_OVER_WORKER_MS
|
|
38358
38361
|
};
|
|
38359
38362
|
};
|
|
38360
|
-
const resolveLintIncludePaths = (rootDirectory, userConfig) => {
|
|
38363
|
+
const resolveLintIncludePaths = (rootDirectory, userConfig, project) => {
|
|
38361
38364
|
if (!Array.isArray(userConfig?.ignore?.files) || userConfig.ignore.files.length === 0) return;
|
|
38362
38365
|
const ignoredPatterns = compileIgnoredFilePatterns(userConfig);
|
|
38363
38366
|
return listSourceFiles(rootDirectory).filter((filePath) => {
|
|
38364
|
-
if (!
|
|
38367
|
+
if (!shouldIncludeExplicitLintPath(filePath, project)) return false;
|
|
38365
38368
|
return !isFileIgnoredByPatterns(filePath, rootDirectory, ignoredPatterns);
|
|
38366
38369
|
});
|
|
38367
38370
|
};
|
|
@@ -42243,7 +42246,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
42243
42246
|
directory: scanDirectory,
|
|
42244
42247
|
repo
|
|
42245
42248
|
}).pipe(orElseSucceed(() => null)) : succeed$2(null));
|
|
42246
|
-
const lintIncludePaths = (input.
|
|
42249
|
+
const lintIncludePaths = (input.skipJsxIncludeFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths], project)) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, project);
|
|
42247
42250
|
const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
|
|
42248
42251
|
const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
|
|
42249
42252
|
const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
|
|
@@ -43207,4 +43210,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
43207
43210
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
43208
43211
|
|
|
43209
43212
|
//# sourceMappingURL=index.js.map
|
|
43210
|
-
//# debugId=
|
|
43213
|
+
//# debugId=7a10d23c-04fd-53e1-a623-a3dc5d6d0830
|
package/dist/lsp.js
CHANGED
|
@@ -32959,6 +32959,7 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
32959
32959
|
"out",
|
|
32960
32960
|
"storybook-static"
|
|
32961
32961
|
]);
|
|
32962
|
+
const JSX_FILE_PATTERN = /\.(tsx|jsx)$/;
|
|
32962
32963
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
32963
32964
|
const SCORE_API_URL = "https://www.react.doctor/api/score";
|
|
32964
32965
|
const FETCH_TIMEOUT_MS = 1e4;
|
|
@@ -37493,7 +37494,9 @@ const highlighter = {
|
|
|
37493
37494
|
gray: import_picocolors.default.gray,
|
|
37494
37495
|
bold: import_picocolors.default.bold
|
|
37495
37496
|
};
|
|
37496
|
-
const
|
|
37497
|
+
const NEXT_ENTRY_FILE_PATTERN = /^(?:\.\/)?(?:src\/)?(?:middleware|proxy)\.(?:tsx?|jsx?|mts|mjs)$/;
|
|
37498
|
+
const shouldIncludeExplicitLintPath = (filePath, project) => JSX_FILE_PATTERN.test(filePath) || project?.framework === "nextjs" && NEXT_ENTRY_FILE_PATTERN.test(filePath);
|
|
37499
|
+
const computeExplicitLintIncludePaths = (includePaths, project) => includePaths.length > 0 ? includePaths.filter((filePath) => shouldIncludeExplicitLintPath(filePath, project)) : void 0;
|
|
37497
37500
|
const LINGUIST_ATTRIBUTE_PATTERN = /^linguist-(?:vendored|generated)(?:=([a-zA-Z0-9]+))?$/i;
|
|
37498
37501
|
const FALSY_VALUES = new Set([
|
|
37499
37502
|
"false",
|
|
@@ -38335,11 +38338,11 @@ const resolveDeadCodeTimeout = (input) => {
|
|
|
38335
38338
|
phaseTimeoutMs: workerTimeoutMs + DEAD_CODE_PHASE_TIMEOUT_OVER_WORKER_MS
|
|
38336
38339
|
};
|
|
38337
38340
|
};
|
|
38338
|
-
const resolveLintIncludePaths = (rootDirectory, userConfig) => {
|
|
38341
|
+
const resolveLintIncludePaths = (rootDirectory, userConfig, project) => {
|
|
38339
38342
|
if (!Array.isArray(userConfig?.ignore?.files) || userConfig.ignore.files.length === 0) return;
|
|
38340
38343
|
const ignoredPatterns = compileIgnoredFilePatterns(userConfig);
|
|
38341
38344
|
return listSourceFiles(rootDirectory).filter((filePath) => {
|
|
38342
|
-
if (!
|
|
38345
|
+
if (!shouldIncludeExplicitLintPath(filePath, project)) return false;
|
|
38343
38346
|
return !isFileIgnoredByPatterns(filePath, rootDirectory, ignoredPatterns);
|
|
38344
38347
|
});
|
|
38345
38348
|
};
|
|
@@ -42221,7 +42224,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
42221
42224
|
directory: scanDirectory,
|
|
42222
42225
|
repo
|
|
42223
42226
|
}).pipe(orElseSucceed(() => null)) : succeed$2(null));
|
|
42224
|
-
const lintIncludePaths = (input.
|
|
42227
|
+
const lintIncludePaths = (input.skipJsxIncludeFilter ? input.includePaths.length > 0 ? [...input.includePaths] : void 0 : computeExplicitLintIncludePaths([...input.includePaths], project)) ?? resolveLintIncludePaths(scanDirectory, resolvedConfig.config, project);
|
|
42225
42228
|
const fallbackScannedFilePaths = input.suppressScanSummary ? (lintIncludePaths ?? (yield* filesService.listSourceFiles(scanDirectory))).map((relativePath) => Path.resolve(scanDirectory, relativePath)) : [];
|
|
42226
42229
|
const beforeLint = hooks.beforeLint ?? NO_HOOKS.beforeLint;
|
|
42227
42230
|
const afterLint = hooks.afterLint ?? NO_HOOKS.afterLint;
|
|
@@ -42716,7 +42719,7 @@ const runEditorScan = async (input) => {
|
|
|
42716
42719
|
warnings,
|
|
42717
42720
|
isCi: false,
|
|
42718
42721
|
resolveLocalGithubViewerPermission: false,
|
|
42719
|
-
|
|
42722
|
+
skipJsxIncludeFilter: true
|
|
42720
42723
|
}).pipe(withSpan("runEditorScan", { attributes: {
|
|
42721
42724
|
"editor.lint": lint,
|
|
42722
42725
|
"editor.runDeadCode": runDeadCode
|
|
@@ -43479,7 +43482,7 @@ const createLintCache = (input) => {
|
|
|
43479
43482
|
let persistTimer = null;
|
|
43480
43483
|
try {
|
|
43481
43484
|
const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
|
|
43482
|
-
if (parsed.version ===
|
|
43485
|
+
if (parsed.version === 1 && parsed.fingerprint === input.fingerprint) for (const [fsPath, entry] of Object.entries(parsed.entries)) entries.set(fsPath, entry);
|
|
43483
43486
|
} catch {}
|
|
43484
43487
|
const persist = () => {
|
|
43485
43488
|
if (persistTimer) {
|
|
@@ -43490,7 +43493,7 @@ const createLintCache = (input) => {
|
|
|
43490
43493
|
dirty = false;
|
|
43491
43494
|
try {
|
|
43492
43495
|
const payload = {
|
|
43493
|
-
version:
|
|
43496
|
+
version: 1,
|
|
43494
43497
|
fingerprint: input.fingerprint,
|
|
43495
43498
|
entries: Object.fromEntries(entries)
|
|
43496
43499
|
};
|
|
@@ -43503,14 +43506,14 @@ const createLintCache = (input) => {
|
|
|
43503
43506
|
}
|
|
43504
43507
|
};
|
|
43505
43508
|
return {
|
|
43506
|
-
lookup: (fsPath,
|
|
43509
|
+
lookup: (fsPath, stat) => {
|
|
43507
43510
|
const entry = entries.get(fsPath);
|
|
43508
|
-
if (entry !== void 0 && entry.
|
|
43511
|
+
if (entry !== void 0 && entry.mtimeMs === stat.mtimeMs && entry.size === stat.size) return entry.diagnostics;
|
|
43509
43512
|
return null;
|
|
43510
43513
|
},
|
|
43511
|
-
store: (fsPath,
|
|
43514
|
+
store: (fsPath, stat, diagnostics) => {
|
|
43512
43515
|
entries.set(fsPath, {
|
|
43513
|
-
...
|
|
43516
|
+
...stat,
|
|
43514
43517
|
diagnostics
|
|
43515
43518
|
});
|
|
43516
43519
|
dirty = true;
|
|
@@ -43599,9 +43602,16 @@ const resolveDiagnosticFsPath = (rawFilePath, scanDirectory, projectDirectory, o
|
|
|
43599
43602
|
}
|
|
43600
43603
|
return normalizeFsPath(absolute);
|
|
43601
43604
|
};
|
|
43602
|
-
const
|
|
43603
|
-
|
|
43604
|
-
|
|
43605
|
+
const statSafe = (fsPath) => {
|
|
43606
|
+
try {
|
|
43607
|
+
const stat = fs.statSync(fsPath);
|
|
43608
|
+
return {
|
|
43609
|
+
mtimeMs: stat.mtimeMs,
|
|
43610
|
+
size: stat.size
|
|
43611
|
+
};
|
|
43612
|
+
} catch {
|
|
43613
|
+
return null;
|
|
43614
|
+
}
|
|
43605
43615
|
};
|
|
43606
43616
|
/**
|
|
43607
43617
|
* Outcome for a per-file request served without running oxlint (every
|
|
@@ -43627,7 +43637,7 @@ const outcomeWithoutScan = (request, byFile, requestedPaths) => ({
|
|
|
43627
43637
|
* overlay tree (unsaved buffers) or disk, groups diagnostics by canonical
|
|
43628
43638
|
* absolute path, and reports stale-detection metadata.
|
|
43629
43639
|
*
|
|
43630
|
-
* A persistent per-file lint cache (keyed by
|
|
43640
|
+
* A persistent per-file lint cache (keyed by mtime + size, namespaced by a
|
|
43631
43641
|
* config fingerprint) short-circuits unchanged files so a re-opened editor
|
|
43632
43642
|
* or repeated workspace scan skips the oxlint subprocess for everything it
|
|
43633
43643
|
* hasn't edited. The cache applies only to disk-based, lint-only, per-file
|
|
@@ -43657,15 +43667,15 @@ const createScanRunner = (options) => {
|
|
|
43657
43667
|
const requestedPaths = request.priority === "background" && !request.useOverlay && options.isOpen ? allRequested.filter((fsPath) => !options.isOpen?.(fsPath)) : allRequested;
|
|
43658
43668
|
const cache = cacheEnabled && !isWholeProject && !request.useOverlay && !request.runDeadCode ? getCache(projectDirectory) : null;
|
|
43659
43669
|
const byFile = /* @__PURE__ */ new Map();
|
|
43660
|
-
const
|
|
43670
|
+
const statByPath = /* @__PURE__ */ new Map();
|
|
43661
43671
|
let filesToScan = requestedPaths;
|
|
43662
43672
|
if (cache) {
|
|
43663
43673
|
const uncached = [];
|
|
43664
43674
|
for (const fsPath of requestedPaths) {
|
|
43665
|
-
const
|
|
43666
|
-
if (
|
|
43667
|
-
|
|
43668
|
-
const hit = cache.lookup(fsPath,
|
|
43675
|
+
const stat = statSafe(fsPath);
|
|
43676
|
+
if (stat) {
|
|
43677
|
+
statByPath.set(fsPath, stat);
|
|
43678
|
+
const hit = cache.lookup(fsPath, stat);
|
|
43669
43679
|
if (hit !== null) {
|
|
43670
43680
|
if (hit.length > 0) byFile.set(fsPath, hit);
|
|
43671
43681
|
continue;
|
|
@@ -43708,9 +43718,9 @@ const createScanRunner = (options) => {
|
|
|
43708
43718
|
}
|
|
43709
43719
|
if (cache && result.ok && !result.skipped && !result.didLintFail && result.lintPartialFailures.length === 0) {
|
|
43710
43720
|
for (const fsPath of filesToScan) {
|
|
43711
|
-
const
|
|
43712
|
-
if (!
|
|
43713
|
-
cache.store(fsPath,
|
|
43721
|
+
const stat = statByPath.get(fsPath);
|
|
43722
|
+
if (!stat) continue;
|
|
43723
|
+
cache.store(fsPath, stat, byFile.get(fsPath) ?? []);
|
|
43714
43724
|
}
|
|
43715
43725
|
cache.schedulePersist();
|
|
43716
43726
|
}
|
|
@@ -44844,5 +44854,5 @@ const startLanguageServer = () => {
|
|
|
44844
44854
|
};
|
|
44845
44855
|
//#endregion
|
|
44846
44856
|
export { startLanguageServer };
|
|
44847
|
-
!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]="
|
|
44848
|
-
//# debugId=
|
|
44857
|
+
!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]="b77898db-d8e8-531a-a32b-9de2d1a63635")}catch(e){}}();
|
|
44858
|
+
//# debugId=b77898db-d8e8-531a-a32b-9de2d1a63635
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.7.6-dev.
|
|
3
|
+
"version": "0.7.6-dev.e877ca7",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
66
66
|
"vscode-uri": "^3.1.0",
|
|
67
67
|
"yaml": "^2.9.0",
|
|
68
|
-
"
|
|
69
|
-
"
|
|
68
|
+
"deslop-js": "0.7.6",
|
|
69
|
+
"oxlint-plugin-react-doctor": "0.7.6-dev.e877ca7"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/babel__code-frame": "^7.27.0",
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
"@xterm/headless": "^6.0.0",
|
|
75
75
|
"commander": "^14.0.3",
|
|
76
76
|
"ora": "^9.4.0",
|
|
77
|
-
"@react-doctor/core": "0.7.6",
|
|
78
77
|
"@react-doctor/api": "0.7.6",
|
|
78
|
+
"@react-doctor/core": "0.7.6",
|
|
79
79
|
"@react-doctor/language-server": "0.7.6"
|
|
80
80
|
},
|
|
81
81
|
"engines": {
|