react-doctor 0.8.2 → 0.8.3-dev.3d7ea66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -21
- package/dist/cli.js +29 -22
- package/dist/index.js +19 -12
- package/dist/lsp.js +22 -15
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -27,17 +27,7 @@ npx react-doctor@latest
|
|
|
27
27
|
|
|
28
28
|
https://github.com/user-attachments/assets/07cc88d9-9589-44c3-aa73-5d603cb1c570
|
|
29
29
|
|
|
30
|
-
### 2.
|
|
31
|
-
|
|
32
|
-
Use the design command when you only want UI composition, typography, interaction, accessibility, and motion findings:
|
|
33
|
-
|
|
34
|
-
```bash
|
|
35
|
-
npx react-doctor@latest design
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
This activates the complete design rule family, including focused rules that stay opt-in during a general health scan, and skips unrelated dead-code, supply-chain, custom-plugin, and health-score passes. It accepts the normal scan flags, including `--scope`, `--project`, `--verbose`, and `--json`.
|
|
39
|
-
|
|
40
|
-
### 3. Install for agents
|
|
30
|
+
### 2. Install for agents
|
|
41
31
|
|
|
42
32
|
Once you have an audit, you can install the skill for your coding agent to learn from the issues and fix them in the future.
|
|
43
33
|
|
|
@@ -47,7 +37,7 @@ npx react-doctor@latest install
|
|
|
47
37
|
|
|
48
38
|
Works with Claude Code, Cursor, Codex, OpenCode, and many more.
|
|
49
39
|
|
|
50
|
-
###
|
|
40
|
+
### 3. Run in CI
|
|
51
41
|
|
|
52
42
|
React Doctor reviews every pull request and reports only the issues your change introduced, not your existing backlog. Set it up with one command:
|
|
53
43
|
|
|
@@ -59,20 +49,12 @@ This adds the workflow, scans every pull request, and posts a summary comment. C
|
|
|
59
49
|
|
|
60
50
|
[CI docs →](https://react.doctor/ci)
|
|
61
51
|
|
|
62
|
-
###
|
|
52
|
+
### 4. Configure rules
|
|
63
53
|
|
|
64
54
|
You can configure which rules to run and how to run them in `doctor.config.ts`.
|
|
65
55
|
|
|
66
56
|
[Learn more →](https://react.doctor/docs/configuration/config-files)
|
|
67
57
|
|
|
68
|
-
### 6. Consume JSON
|
|
69
|
-
|
|
70
|
-
Use `--json` for stdout or `--json-out <path>` for a file. The default
|
|
71
|
-
`schemaVersion: 3` report includes deterministic diagnostic IDs and exact
|
|
72
|
-
per-project scan coverage.
|
|
73
|
-
|
|
74
|
-
[JSON report contract →](./docs/json-report.md)
|
|
75
|
-
|
|
76
58
|
## Telemetry
|
|
77
59
|
|
|
78
60
|
The CLI reports crashes, basic run traces, and anonymous usage counters to [Sentry](https://sentry.io/) to help us fix bugs and prioritize work.
|
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]="729213e0-f120-5159-8212-e0a881c2cf17")}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";
|
|
@@ -64656,6 +64656,13 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
64656
64656
|
"storybook-static"
|
|
64657
64657
|
]);
|
|
64658
64658
|
const JSX_FILE_PATTERN = /\.(tsx|jsx)$/;
|
|
64659
|
+
const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
|
|
64660
|
+
const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
|
|
64661
|
+
"TS(1036)",
|
|
64662
|
+
"TS(1038)",
|
|
64663
|
+
"TS(1183)",
|
|
64664
|
+
"TS(1319)"
|
|
64665
|
+
]);
|
|
64659
64666
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
64660
64667
|
const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
|
|
64661
64668
|
{
|
|
@@ -64979,7 +64986,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
64979
64986
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
64980
64987
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
64981
64988
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
64982
|
-
const CORE_PACKAGE_VERSION = "0.8.
|
|
64989
|
+
const CORE_PACKAGE_VERSION = "0.8.3";
|
|
64983
64990
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
64984
64991
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
64985
64992
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -73188,13 +73195,13 @@ const decodeFileDiagnostics = (raw) => {
|
|
|
73188
73195
|
}
|
|
73189
73196
|
};
|
|
73190
73197
|
const emptyCache$1 = () => ({
|
|
73191
|
-
version:
|
|
73198
|
+
version: 2,
|
|
73192
73199
|
rulesets: {}
|
|
73193
73200
|
});
|
|
73194
73201
|
const loadRulesetEntries$1 = (cacheFilePath, rulesetHash) => {
|
|
73195
73202
|
const entries = /* @__PURE__ */ new Map();
|
|
73196
73203
|
const persisted = failOpenReadJson(cacheFilePath, emptyCache$1());
|
|
73197
|
-
if (persisted.version !==
|
|
73204
|
+
if (persisted.version !== 2 || !isRecord$1(persisted.rulesets)) return entries;
|
|
73198
73205
|
const bucket = persisted.rulesets[rulesetHash];
|
|
73199
73206
|
if (!isRecord$1(bucket) || !isRecord$1(bucket.files)) return entries;
|
|
73200
73207
|
for (const [fileKey, rawDiagnostics] of Object.entries(bucket.files)) {
|
|
@@ -73214,7 +73221,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
73214
73221
|
},
|
|
73215
73222
|
persist: () => {
|
|
73216
73223
|
const onDisk = failOpenReadJson(cacheFilePath, emptyCache$1());
|
|
73217
|
-
const rulesets = onDisk.version ===
|
|
73224
|
+
const rulesets = onDisk.version === 2 && isRecord$1(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
|
|
73218
73225
|
const existingBucket = rulesets[rulesetHash];
|
|
73219
73226
|
const existingFiles = isRecord$1(existingBucket) && isRecord$1(existingBucket.files) ? existingBucket.files : {};
|
|
73220
73227
|
const ourFiles = {};
|
|
@@ -73228,7 +73235,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
73228
73235
|
files: Object.fromEntries(cappedEntries)
|
|
73229
73236
|
};
|
|
73230
73237
|
atomicWriteJson(cacheFilePath, {
|
|
73231
|
-
version:
|
|
73238
|
+
version: 2,
|
|
73232
73239
|
rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord$1(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
|
|
73233
73240
|
});
|
|
73234
73241
|
}
|
|
@@ -73317,13 +73324,13 @@ const encodeSidecarFileEntry = (entry) => ({
|
|
|
73317
73324
|
diagnostics: entry.diagnostics
|
|
73318
73325
|
});
|
|
73319
73326
|
const emptyCache = () => ({
|
|
73320
|
-
version:
|
|
73327
|
+
version: 3,
|
|
73321
73328
|
rulesets: {}
|
|
73322
73329
|
});
|
|
73323
73330
|
const loadRulesetEntries = (cacheFilePath, rulesetHash) => {
|
|
73324
73331
|
const entries = /* @__PURE__ */ new Map();
|
|
73325
73332
|
const persisted = failOpenReadJson(cacheFilePath, emptyCache());
|
|
73326
|
-
if (persisted.version !==
|
|
73333
|
+
if (persisted.version !== 3 || !isRecord$1(persisted.rulesets)) return entries;
|
|
73327
73334
|
const bucket = persisted.rulesets[rulesetHash];
|
|
73328
73335
|
if (!isRecord$1(bucket) || !isRecord$1(bucket.files)) return entries;
|
|
73329
73336
|
for (const [fileKey, rawEntry] of Object.entries(bucket.files)) {
|
|
@@ -73343,7 +73350,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
73343
73350
|
},
|
|
73344
73351
|
persist: () => {
|
|
73345
73352
|
const onDisk = failOpenReadJson(cacheFilePath, emptyCache());
|
|
73346
|
-
const rulesets = onDisk.version ===
|
|
73353
|
+
const rulesets = onDisk.version === 3 && isRecord$1(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
|
|
73347
73354
|
const existingBucket = rulesets[rulesetHash];
|
|
73348
73355
|
const existingFiles = isRecord$1(existingBucket) && isRecord$1(existingBucket.files) ? existingBucket.files : {};
|
|
73349
73356
|
const ourFiles = {};
|
|
@@ -73357,7 +73364,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
73357
73364
|
files: Object.fromEntries(cappedEntries)
|
|
73358
73365
|
};
|
|
73359
73366
|
atomicWriteJson(cacheFilePath, {
|
|
73360
|
-
version:
|
|
73367
|
+
version: 3,
|
|
73361
73368
|
rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord$1(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
|
|
73362
73369
|
});
|
|
73363
73370
|
}
|
|
@@ -74290,7 +74297,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
74290
74297
|
minifiedFileCache.set(absolutePath, minified);
|
|
74291
74298
|
return minified;
|
|
74292
74299
|
};
|
|
74293
|
-
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
74300
|
+
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
74294
74301
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
74295
74302
|
const primaryLabel = diagnostic.labels[0];
|
|
74296
74303
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
@@ -77391,7 +77398,7 @@ const makeNoopConsole = () => ({
|
|
|
77391
77398
|
});
|
|
77392
77399
|
//#endregion
|
|
77393
77400
|
//#region src/cli/utils/version.ts
|
|
77394
|
-
const VERSION = "0.8.
|
|
77401
|
+
const VERSION = "0.8.3-dev.3d7ea66";
|
|
77395
77402
|
//#endregion
|
|
77396
77403
|
//#region src/cli/utils/json-mode.ts
|
|
77397
77404
|
let context = null;
|
|
@@ -77749,13 +77756,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
77749
77756
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
77750
77757
|
* standard `SENTRY_RELEASE` override.
|
|
77751
77758
|
*/
|
|
77752
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.
|
|
77759
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.8.3-dev.3d7ea66`;
|
|
77753
77760
|
/**
|
|
77754
77761
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
77755
77762
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
77756
77763
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
77757
77764
|
*/
|
|
77758
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.
|
|
77765
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.8.3-dev.3d7ea66") ? "development" : "production");
|
|
77759
77766
|
/**
|
|
77760
77767
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
77761
77768
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -89977,12 +89984,12 @@ const resolveCacheFilePath = (projectDirectory) => path.join(resolveReactDoctorC
|
|
|
89977
89984
|
const readPersistedCache = (cacheFilePath) => {
|
|
89978
89985
|
try {
|
|
89979
89986
|
const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
|
|
89980
|
-
if (!isRecord(parsed) || parsed.version !==
|
|
89981
|
-
version:
|
|
89987
|
+
if (!isRecord(parsed) || parsed.version !== 6) return {
|
|
89988
|
+
version: 6,
|
|
89982
89989
|
entries: []
|
|
89983
89990
|
};
|
|
89984
89991
|
if (!Array.isArray(parsed.entries)) return {
|
|
89985
|
-
version:
|
|
89992
|
+
version: 6,
|
|
89986
89993
|
entries: []
|
|
89987
89994
|
};
|
|
89988
89995
|
const entries = [];
|
|
@@ -89992,12 +89999,12 @@ const readPersistedCache = (cacheFilePath) => {
|
|
|
89992
89999
|
entries.push(entry);
|
|
89993
90000
|
}
|
|
89994
90001
|
return {
|
|
89995
|
-
version:
|
|
90002
|
+
version: 6,
|
|
89996
90003
|
entries
|
|
89997
90004
|
};
|
|
89998
90005
|
} catch {
|
|
89999
90006
|
return {
|
|
90000
|
-
version:
|
|
90007
|
+
version: 6,
|
|
90001
90008
|
entries: []
|
|
90002
90009
|
};
|
|
90003
90010
|
}
|
|
@@ -90059,7 +90066,7 @@ const buildScanResultCacheKey = (input) => {
|
|
|
90059
90066
|
if (headSha === null) return null;
|
|
90060
90067
|
if (stringifyStableJson(input.userConfig) === null) return null;
|
|
90061
90068
|
const cacheKeyJson = stringifyStableJson({
|
|
90062
|
-
schemaVersion:
|
|
90069
|
+
schemaVersion: 6,
|
|
90063
90070
|
projectIdentity: resolveProjectIdentity(input.projectDirectory),
|
|
90064
90071
|
headSha,
|
|
90065
90072
|
worktreeFingerprint,
|
|
@@ -90102,7 +90109,7 @@ const createScanResultCache = (projectDirectory) => {
|
|
|
90102
90109
|
for (const entry of persistedCache.entries) entries.set(entry.key, entry);
|
|
90103
90110
|
const persist = () => {
|
|
90104
90111
|
writePersistedCache(cacheFilePath, {
|
|
90105
|
-
version:
|
|
90112
|
+
version: 6,
|
|
90106
90113
|
entries: [...entries.values()].sort((firstEntry, secondEntry) => secondEntry.createdAtMs - firstEntry.createdAtMs).slice(0, 20)
|
|
90107
90114
|
});
|
|
90108
90115
|
};
|
|
@@ -96476,4 +96483,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
96476
96483
|
export {};
|
|
96477
96484
|
|
|
96478
96485
|
//# sourceMappingURL=cli.js.map
|
|
96479
|
-
//# debugId=
|
|
96486
|
+
//# debugId=729213e0-f120-5159-8212-e0a881c2cf17
|
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]="cf84418d-5713-5c93-95cf-6a6747b9f247")}catch(e){}}();
|
|
3
3
|
import { i as __toESM$1, r as __require, t as __commonJSMin$1 } from "./chunk-ChKA3wi6.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";
|
|
@@ -61487,6 +61487,13 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
61487
61487
|
"out",
|
|
61488
61488
|
"storybook-static"
|
|
61489
61489
|
]);
|
|
61490
|
+
const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
|
|
61491
|
+
const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
|
|
61492
|
+
"TS(1036)",
|
|
61493
|
+
"TS(1038)",
|
|
61494
|
+
"TS(1183)",
|
|
61495
|
+
"TS(1319)"
|
|
61496
|
+
]);
|
|
61490
61497
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
61491
61498
|
const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
|
|
61492
61499
|
{
|
|
@@ -61777,7 +61784,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
61777
61784
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
61778
61785
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
61779
61786
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
61780
|
-
const CORE_PACKAGE_VERSION = "0.8.
|
|
61787
|
+
const CORE_PACKAGE_VERSION = "0.8.3";
|
|
61781
61788
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
61782
61789
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
61783
61790
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -69948,13 +69955,13 @@ const decodeFileDiagnostics = (raw) => {
|
|
|
69948
69955
|
}
|
|
69949
69956
|
};
|
|
69950
69957
|
const emptyCache$1 = () => ({
|
|
69951
|
-
version:
|
|
69958
|
+
version: 2,
|
|
69952
69959
|
rulesets: {}
|
|
69953
69960
|
});
|
|
69954
69961
|
const loadRulesetEntries$1 = (cacheFilePath, rulesetHash) => {
|
|
69955
69962
|
const entries = /* @__PURE__ */ new Map();
|
|
69956
69963
|
const persisted = failOpenReadJson(cacheFilePath, emptyCache$1());
|
|
69957
|
-
if (persisted.version !==
|
|
69964
|
+
if (persisted.version !== 2 || !isRecord(persisted.rulesets)) return entries;
|
|
69958
69965
|
const bucket = persisted.rulesets[rulesetHash];
|
|
69959
69966
|
if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
|
|
69960
69967
|
for (const [fileKey, rawDiagnostics] of Object.entries(bucket.files)) {
|
|
@@ -69974,7 +69981,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
69974
69981
|
},
|
|
69975
69982
|
persist: () => {
|
|
69976
69983
|
const onDisk = failOpenReadJson(cacheFilePath, emptyCache$1());
|
|
69977
|
-
const rulesets = onDisk.version ===
|
|
69984
|
+
const rulesets = onDisk.version === 2 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
|
|
69978
69985
|
const existingBucket = rulesets[rulesetHash];
|
|
69979
69986
|
const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
|
|
69980
69987
|
const ourFiles = {};
|
|
@@ -69988,7 +69995,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
69988
69995
|
files: Object.fromEntries(cappedEntries)
|
|
69989
69996
|
};
|
|
69990
69997
|
atomicWriteJson(cacheFilePath, {
|
|
69991
|
-
version:
|
|
69998
|
+
version: 2,
|
|
69992
69999
|
rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
|
|
69993
70000
|
});
|
|
69994
70001
|
}
|
|
@@ -70077,13 +70084,13 @@ const encodeSidecarFileEntry = (entry) => ({
|
|
|
70077
70084
|
diagnostics: entry.diagnostics
|
|
70078
70085
|
});
|
|
70079
70086
|
const emptyCache = () => ({
|
|
70080
|
-
version:
|
|
70087
|
+
version: 3,
|
|
70081
70088
|
rulesets: {}
|
|
70082
70089
|
});
|
|
70083
70090
|
const loadRulesetEntries = (cacheFilePath, rulesetHash) => {
|
|
70084
70091
|
const entries = /* @__PURE__ */ new Map();
|
|
70085
70092
|
const persisted = failOpenReadJson(cacheFilePath, emptyCache());
|
|
70086
|
-
if (persisted.version !==
|
|
70093
|
+
if (persisted.version !== 3 || !isRecord(persisted.rulesets)) return entries;
|
|
70087
70094
|
const bucket = persisted.rulesets[rulesetHash];
|
|
70088
70095
|
if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
|
|
70089
70096
|
for (const [fileKey, rawEntry] of Object.entries(bucket.files)) {
|
|
@@ -70103,7 +70110,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
70103
70110
|
},
|
|
70104
70111
|
persist: () => {
|
|
70105
70112
|
const onDisk = failOpenReadJson(cacheFilePath, emptyCache());
|
|
70106
|
-
const rulesets = onDisk.version ===
|
|
70113
|
+
const rulesets = onDisk.version === 3 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
|
|
70107
70114
|
const existingBucket = rulesets[rulesetHash];
|
|
70108
70115
|
const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
|
|
70109
70116
|
const ourFiles = {};
|
|
@@ -70117,7 +70124,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
70117
70124
|
files: Object.fromEntries(cappedEntries)
|
|
70118
70125
|
};
|
|
70119
70126
|
atomicWriteJson(cacheFilePath, {
|
|
70120
|
-
version:
|
|
70127
|
+
version: 3,
|
|
70121
70128
|
rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
|
|
70122
70129
|
});
|
|
70123
70130
|
}
|
|
@@ -71050,7 +71057,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71050
71057
|
minifiedFileCache.set(absolutePath, minified);
|
|
71051
71058
|
return minified;
|
|
71052
71059
|
};
|
|
71053
|
-
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71060
|
+
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71054
71061
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71055
71062
|
const primaryLabel = diagnostic.labels[0];
|
|
71056
71063
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
@@ -73867,4 +73874,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
73867
73874
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
73868
73875
|
|
|
73869
73876
|
//# sourceMappingURL=index.js.map
|
|
73870
|
-
//# debugId=
|
|
73877
|
+
//# debugId=cf84418d-5713-5c93-95cf-6a6747b9f247
|
package/dist/lsp.js
CHANGED
|
@@ -61517,6 +61517,13 @@ const IGNORED_DIRECTORIES = new Set([
|
|
|
61517
61517
|
"out",
|
|
61518
61518
|
"storybook-static"
|
|
61519
61519
|
]);
|
|
61520
|
+
const TYPESCRIPT_DECLARATION_FILE_PATTERN = /\.d\.(?:ts|mts|cts)$/;
|
|
61521
|
+
const OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES = new Set([
|
|
61522
|
+
"TS(1036)",
|
|
61523
|
+
"TS(1038)",
|
|
61524
|
+
"TS(1183)",
|
|
61525
|
+
"TS(1319)"
|
|
61526
|
+
]);
|
|
61520
61527
|
const MILLISECONDS_PER_SECOND = 1e3;
|
|
61521
61528
|
const REACT_ROUTER_CAPABILITY_THRESHOLDS = [
|
|
61522
61529
|
{
|
|
@@ -61830,7 +61837,7 @@ const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
|
61830
61837
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
61831
61838
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
61832
61839
|
const SIDECAR_LINT_CACHE_FILENAME = "sidecar-lint-cache.json";
|
|
61833
|
-
const CORE_PACKAGE_VERSION = "0.8.
|
|
61840
|
+
const CORE_PACKAGE_VERSION = "0.8.3";
|
|
61834
61841
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
61835
61842
|
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
61836
61843
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
@@ -69927,13 +69934,13 @@ const decodeFileDiagnostics = (raw) => {
|
|
|
69927
69934
|
}
|
|
69928
69935
|
};
|
|
69929
69936
|
const emptyCache$1 = () => ({
|
|
69930
|
-
version:
|
|
69937
|
+
version: 2,
|
|
69931
69938
|
rulesets: {}
|
|
69932
69939
|
});
|
|
69933
69940
|
const loadRulesetEntries$1 = (cacheFilePath, rulesetHash) => {
|
|
69934
69941
|
const entries = /* @__PURE__ */ new Map();
|
|
69935
69942
|
const persisted = failOpenReadJson(cacheFilePath, emptyCache$1());
|
|
69936
|
-
if (persisted.version !==
|
|
69943
|
+
if (persisted.version !== 2 || !isRecord(persisted.rulesets)) return entries;
|
|
69937
69944
|
const bucket = persisted.rulesets[rulesetHash];
|
|
69938
69945
|
if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
|
|
69939
69946
|
for (const [fileKey, rawDiagnostics] of Object.entries(bucket.files)) {
|
|
@@ -69953,7 +69960,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
69953
69960
|
},
|
|
69954
69961
|
persist: () => {
|
|
69955
69962
|
const onDisk = failOpenReadJson(cacheFilePath, emptyCache$1());
|
|
69956
|
-
const rulesets = onDisk.version ===
|
|
69963
|
+
const rulesets = onDisk.version === 2 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
|
|
69957
69964
|
const existingBucket = rulesets[rulesetHash];
|
|
69958
69965
|
const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
|
|
69959
69966
|
const ourFiles = {};
|
|
@@ -69967,7 +69974,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
69967
69974
|
files: Object.fromEntries(cappedEntries)
|
|
69968
69975
|
};
|
|
69969
69976
|
atomicWriteJson(cacheFilePath, {
|
|
69970
|
-
version:
|
|
69977
|
+
version: 2,
|
|
69971
69978
|
rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
|
|
69972
69979
|
});
|
|
69973
69980
|
}
|
|
@@ -70056,13 +70063,13 @@ const encodeSidecarFileEntry = (entry) => ({
|
|
|
70056
70063
|
diagnostics: entry.diagnostics
|
|
70057
70064
|
});
|
|
70058
70065
|
const emptyCache = () => ({
|
|
70059
|
-
version:
|
|
70066
|
+
version: 3,
|
|
70060
70067
|
rulesets: {}
|
|
70061
70068
|
});
|
|
70062
70069
|
const loadRulesetEntries = (cacheFilePath, rulesetHash) => {
|
|
70063
70070
|
const entries = /* @__PURE__ */ new Map();
|
|
70064
70071
|
const persisted = failOpenReadJson(cacheFilePath, emptyCache());
|
|
70065
|
-
if (persisted.version !==
|
|
70072
|
+
if (persisted.version !== 3 || !isRecord(persisted.rulesets)) return entries;
|
|
70066
70073
|
const bucket = persisted.rulesets[rulesetHash];
|
|
70067
70074
|
if (!isRecord(bucket) || !isRecord(bucket.files)) return entries;
|
|
70068
70075
|
for (const [fileKey, rawEntry] of Object.entries(bucket.files)) {
|
|
@@ -70082,7 +70089,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
70082
70089
|
},
|
|
70083
70090
|
persist: () => {
|
|
70084
70091
|
const onDisk = failOpenReadJson(cacheFilePath, emptyCache());
|
|
70085
|
-
const rulesets = onDisk.version ===
|
|
70092
|
+
const rulesets = onDisk.version === 3 && isRecord(onDisk.rulesets) ? { ...onDisk.rulesets } : {};
|
|
70086
70093
|
const existingBucket = rulesets[rulesetHash];
|
|
70087
70094
|
const existingFiles = isRecord(existingBucket) && isRecord(existingBucket.files) ? existingBucket.files : {};
|
|
70088
70095
|
const ourFiles = {};
|
|
@@ -70096,7 +70103,7 @@ const createSidecarLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
70096
70103
|
files: Object.fromEntries(cappedEntries)
|
|
70097
70104
|
};
|
|
70098
70105
|
atomicWriteJson(cacheFilePath, {
|
|
70099
|
-
version:
|
|
70106
|
+
version: 3,
|
|
70100
70107
|
rulesets: Object.fromEntries(Object.entries(rulesets).filter(([, bucket]) => isRecord(bucket) && typeof bucket.updatedAtMs === "number").sort(([, first], [, second]) => second.updatedAtMs - first.updatedAtMs).slice(0, 8))
|
|
70101
70108
|
});
|
|
70102
70109
|
}
|
|
@@ -71029,7 +71036,7 @@ const parseOxlintOutput = (stdout, project, rootDirectory) => {
|
|
|
71029
71036
|
minifiedFileCache.set(absolutePath, minified);
|
|
71030
71037
|
return minified;
|
|
71031
71038
|
};
|
|
71032
|
-
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71039
|
+
return suppressMemoizationInBailedOutFunctions(parsed.diagnostics.filter((diagnostic) => isMappableOxlintDiagnostic(diagnostic) && isLintableSourceFile(diagnostic.filename) && !(TYPESCRIPT_DECLARATION_FILE_PATTERN.test(diagnostic.filename) && OXLINT_IGNORED_DECLARATION_DIAGNOSTIC_CODES.has(diagnostic.code)) && !isMinifiedDiagnosticFile(diagnostic.filename) && !shouldSuppressLocalUseHookDiagnostic(diagnostic, rootDirectory) && !shouldSuppressCompilerFindingInWorklet(diagnostic, project, rootDirectory)).map((diagnostic) => {
|
|
71033
71040
|
const { plugin, rule } = parseRuleCode(diagnostic.code);
|
|
71034
71041
|
const primaryLabel = diagnostic.labels[0];
|
|
71035
71042
|
const cleaned = cleanDiagnosticMessage(diagnostic.message, diagnostic.help, plugin, rule, project);
|
|
@@ -73458,7 +73465,7 @@ const computeConfigFingerprint = (projectDirectory, version) => {
|
|
|
73458
73465
|
/** Display name used in client-facing messages and progress titles. */
|
|
73459
73466
|
const SERVER_DISPLAY_NAME = "React Doctor";
|
|
73460
73467
|
/** Server version reported in `serverInfo`; injected at build, `dev` from source. */
|
|
73461
|
-
const SERVER_VERSION = "0.8.
|
|
73468
|
+
const SERVER_VERSION = "0.8.3";
|
|
73462
73469
|
/** `Diagnostic.source` shown next to every published diagnostic. */
|
|
73463
73470
|
const DIAGNOSTIC_SOURCE = "react-doctor";
|
|
73464
73471
|
/**
|
|
@@ -74139,7 +74146,7 @@ const createLintCache = (input) => {
|
|
|
74139
74146
|
let persistTimer = null;
|
|
74140
74147
|
try {
|
|
74141
74148
|
const parsed = JSON.parse(fs.readFileSync(cacheFilePath, "utf8"));
|
|
74142
|
-
if (parsed.version ===
|
|
74149
|
+
if (parsed.version === 3 && parsed.fingerprint === input.fingerprint) for (const [fsPath, entry] of Object.entries(parsed.entries)) entries.set(fsPath, entry);
|
|
74143
74150
|
} catch {}
|
|
74144
74151
|
const persist = () => {
|
|
74145
74152
|
if (persistTimer) {
|
|
@@ -74150,7 +74157,7 @@ const createLintCache = (input) => {
|
|
|
74150
74157
|
dirty = false;
|
|
74151
74158
|
try {
|
|
74152
74159
|
const payload = {
|
|
74153
|
-
version:
|
|
74160
|
+
version: 3,
|
|
74154
74161
|
fingerprint: input.fingerprint,
|
|
74155
74162
|
entries: Object.fromEntries(entries)
|
|
74156
74163
|
};
|
|
@@ -75488,5 +75495,5 @@ const startLanguageServer = () => {
|
|
|
75488
75495
|
};
|
|
75489
75496
|
//#endregion
|
|
75490
75497
|
export { startLanguageServer };
|
|
75491
|
-
!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]="
|
|
75492
|
-
//# debugId=
|
|
75498
|
+
!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]="97b31424-577f-5b74-ac26-46212d2f1aaf")}catch(e){}}();
|
|
75499
|
+
//# debugId=97b31424-577f-5b74-ac26-46212d2f1aaf
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3-dev.3d7ea66",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -58,15 +58,15 @@
|
|
|
58
58
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
59
59
|
"jiti": "^2.7.0",
|
|
60
60
|
"magicast": "^0.5.3",
|
|
61
|
-
"oxlint": ">=1.
|
|
61
|
+
"oxlint": ">=1.74.0 <1.75.0",
|
|
62
62
|
"prompts": "^2.4.2",
|
|
63
63
|
"typescript": ">=5.0.4 <6",
|
|
64
64
|
"vscode-languageserver": "^9.0.1",
|
|
65
65
|
"vscode-languageserver-textdocument": "^1.0.12",
|
|
66
66
|
"vscode-uri": "^3.1.0",
|
|
67
67
|
"yaml": "^2.9.0",
|
|
68
|
-
"deslop-js": "0.8.
|
|
69
|
-
"oxlint-plugin-react-doctor": "0.8.
|
|
68
|
+
"deslop-js": "0.8.3",
|
|
69
|
+
"oxlint-plugin-react-doctor": "0.8.3-dev.3d7ea66"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/babel__code-frame": "^7.27.0",
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
"@xterm/headless": "^6.0.0",
|
|
75
75
|
"commander": "^14.0.3",
|
|
76
76
|
"ora": "^9.4.0",
|
|
77
|
-
"@react-doctor/api": "0.8.
|
|
78
|
-
"@react-doctor/core": "0.8.
|
|
79
|
-
"@react-doctor/language-server": "0.8.
|
|
77
|
+
"@react-doctor/api": "0.8.3",
|
|
78
|
+
"@react-doctor/core": "0.8.3",
|
|
79
|
+
"@react-doctor/language-server": "0.8.3"
|
|
80
80
|
},
|
|
81
81
|
"engines": {
|
|
82
82
|
"node": "^20.19.0 || >=22.13.0"
|