react-doctor 0.6.3-dev.ce49250 → 0.6.3-dev.e257a5e
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 +52 -156
- package/dist/index.d.ts +0 -10
- package/dist/index.js +41 -56
- package/dist/lsp.js +41 -56
- package/package.json +3 -3
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]="82500030-a7a7-5da8-b18e-cbdb42102dc3")}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";
|
|
@@ -18,7 +18,6 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
|
|
18
18
|
import { createJiti } from "jiti";
|
|
19
19
|
import * as Crypto from "node:crypto";
|
|
20
20
|
import crypto, { createHash, randomUUID } from "node:crypto";
|
|
21
|
-
import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
|
|
22
21
|
import { gzipSync } from "node:zlib";
|
|
23
22
|
import * as Sentry from "@sentry/node";
|
|
24
23
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
@@ -36129,9 +36128,7 @@ const SOCKET_PACKAGE_PAGE_BASE = "https://socket.dev/npm/package";
|
|
|
36129
36128
|
const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
36130
36129
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
36131
36130
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
36132
|
-
const CORE_PACKAGE_VERSION = "0.6.3";
|
|
36133
36131
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
36134
|
-
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
36135
36132
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
36136
36133
|
const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
|
|
36137
36134
|
const SUPPLY_CHAIN_CATEGORY = "Security";
|
|
@@ -40584,9 +40581,38 @@ const failOpenReadJson = (filePath, fallback) => {
|
|
|
40584
40581
|
return fallback;
|
|
40585
40582
|
}
|
|
40586
40583
|
};
|
|
40587
|
-
const ANALYZED_FILE_EXTENSIONS = new Set(
|
|
40588
|
-
|
|
40589
|
-
|
|
40584
|
+
const ANALYZED_FILE_EXTENSIONS = new Set([
|
|
40585
|
+
".ts",
|
|
40586
|
+
".tsx",
|
|
40587
|
+
".js",
|
|
40588
|
+
".jsx",
|
|
40589
|
+
".mts",
|
|
40590
|
+
".mjs",
|
|
40591
|
+
".cts",
|
|
40592
|
+
".cjs",
|
|
40593
|
+
".mdx",
|
|
40594
|
+
".astro",
|
|
40595
|
+
".graphql",
|
|
40596
|
+
".gql",
|
|
40597
|
+
".css",
|
|
40598
|
+
".scss",
|
|
40599
|
+
".vue",
|
|
40600
|
+
".svelte"
|
|
40601
|
+
]);
|
|
40602
|
+
const ANALYZED_MANIFEST_NAMES = new Set([
|
|
40603
|
+
"package.json",
|
|
40604
|
+
"knip.json",
|
|
40605
|
+
"app.json",
|
|
40606
|
+
"pnpm-workspace.yaml",
|
|
40607
|
+
"lerna.json",
|
|
40608
|
+
"pnpm-lock.yaml",
|
|
40609
|
+
"package-lock.json",
|
|
40610
|
+
"yarn.lock",
|
|
40611
|
+
"bun.lock",
|
|
40612
|
+
"bun.lockb",
|
|
40613
|
+
"deno.lock",
|
|
40614
|
+
".gitignore"
|
|
40615
|
+
]);
|
|
40590
40616
|
const isTsConfigLikeFile = (fileName) => (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
40591
40617
|
const isFingerprintedFile = (fileName) => ANALYZED_FILE_EXTENSIONS.has(Path.extname(fileName).toLowerCase()) || ANALYZED_MANIFEST_NAMES.has(fileName) || isTsConfigLikeFile(fileName);
|
|
40592
40618
|
const collectAnalyzedFileFingerprints = (rootDirectory) => {
|
|
@@ -40612,7 +40638,6 @@ const resolveDeslopVersion = () => {
|
|
|
40612
40638
|
};
|
|
40613
40639
|
const computeDeadCodeCacheKey = (input) => crypto.createHash("sha1").update(JSON.stringify({
|
|
40614
40640
|
schemaVersion: 1,
|
|
40615
|
-
coreVersion: input.coreVersion,
|
|
40616
40641
|
deslopVersion: resolveDeslopVersion(),
|
|
40617
40642
|
deslopJsModuleSpecifier: input.deslopJsModuleSpecifier,
|
|
40618
40643
|
entryPatterns: input.entryPatterns,
|
|
@@ -40777,14 +40802,6 @@ process.stdin.on("end", () => {
|
|
|
40777
40802
|
circularDependencies: result.circularDependencies.map((cycle) => ({
|
|
40778
40803
|
files: cycle.files,
|
|
40779
40804
|
})),
|
|
40780
|
-
...(result.incrementalCacheStats
|
|
40781
|
-
? {
|
|
40782
|
-
summaryCacheStats: {
|
|
40783
|
-
hits: result.incrementalCacheStats.summaryHits,
|
|
40784
|
-
misses: result.incrementalCacheStats.summaryMisses,
|
|
40785
|
-
},
|
|
40786
|
-
}
|
|
40787
|
-
: {}),
|
|
40788
40805
|
});
|
|
40789
40806
|
|
|
40790
40807
|
const serializeError = (error) =>
|
|
@@ -40808,9 +40825,6 @@ process.stdin.on("end", () => {
|
|
|
40808
40825
|
...(workerInput.ignorePatterns.length > 0
|
|
40809
40826
|
? { ignorePatterns: workerInput.ignorePatterns }
|
|
40810
40827
|
: {}),
|
|
40811
|
-
...(workerInput.incrementalCachePath
|
|
40812
|
-
? { incrementalCachePath: workerInput.incrementalCachePath }
|
|
40813
|
-
: {}),
|
|
40814
40828
|
// We consume only deslop's GRAPH-based findings (unusedFiles, unusedExports,
|
|
40815
40829
|
// unusedDependencies, circularDependencies). Everything else deslop can compute
|
|
40816
40830
|
// is pure wasted work for us, and it's the bulk of the runtime:
|
|
@@ -40821,18 +40835,12 @@ process.stdin.on("end", () => {
|
|
|
40821
40835
|
// are the single most expensive pass — duplicate-block detection alone was
|
|
40822
40836
|
// ~83s of a ~130s Sentry scan — so skipping them is an ~8.5x dead-code
|
|
40823
40837
|
// speedup on a large repo.
|
|
40824
|
-
//
|
|
40825
|
-
// simplifiable functions, identity wrappers, …) — ~120 ms of discarded
|
|
40826
|
-
// output per scan, and skipping them lets the incremental cache drop the
|
|
40827
|
-
// DRY-pattern summary fields (the largest slice of the cache file).
|
|
40828
|
-
// All are provably safe: the consumed graph findings are computed by their own
|
|
40838
|
+
// Both are provably safe: the consumed graph findings are computed by their own
|
|
40829
40839
|
// detectors, independent of these passes (confirmed byte-identical on
|
|
40830
|
-
// excalidraw + mui-material + sentry
|
|
40831
|
-
//
|
|
40832
|
-
// for path-alias resolution in the import graph.
|
|
40840
|
+
// excalidraw + mui-material + sentry). tsConfigPath stays — the module resolver
|
|
40841
|
+
// needs it for path-alias resolution in the import graph.
|
|
40833
40842
|
semantic: { enabled: false },
|
|
40834
40843
|
reportCodeQuality: false,
|
|
40835
|
-
reportRedundancy: false,
|
|
40836
40844
|
};
|
|
40837
40845
|
const result = await analyze(defineConfig(config));
|
|
40838
40846
|
emit({ ok: true, result: normalizeResult(result) });
|
|
@@ -40916,23 +40924,13 @@ const parseCircularDependencies = (value) => {
|
|
|
40916
40924
|
}
|
|
40917
40925
|
return circularDependencies;
|
|
40918
40926
|
};
|
|
40919
|
-
const parseSummaryCacheStats = (value) => {
|
|
40920
|
-
if (!isRecord$1(value)) return void 0;
|
|
40921
|
-
if (typeof value.hits !== "number" || typeof value.misses !== "number") return void 0;
|
|
40922
|
-
return {
|
|
40923
|
-
hits: value.hits,
|
|
40924
|
-
misses: value.misses
|
|
40925
|
-
};
|
|
40926
|
-
};
|
|
40927
40927
|
const parseDeadCodeWorkerResult = (value) => {
|
|
40928
40928
|
if (!isRecord$1(value)) throw new Error("Dead-code worker returned an invalid result.");
|
|
40929
|
-
const summaryCacheStats = parseSummaryCacheStats(value.summaryCacheStats);
|
|
40930
40929
|
return {
|
|
40931
40930
|
unusedFiles: parseUnusedFiles(value.unusedFiles),
|
|
40932
40931
|
unusedExports: parseUnusedExports(value.unusedExports),
|
|
40933
40932
|
unusedDependencies: parseUnusedDependencies(value.unusedDependencies),
|
|
40934
|
-
circularDependencies: parseCircularDependencies(value.circularDependencies)
|
|
40935
|
-
...summaryCacheStats ? { summaryCacheStats } : {}
|
|
40933
|
+
circularDependencies: parseCircularDependencies(value.circularDependencies)
|
|
40936
40934
|
};
|
|
40937
40935
|
};
|
|
40938
40936
|
const parseDeadCodeWorkerError = (value) => {
|
|
@@ -41053,15 +41051,13 @@ const checkDeadCode = async (options) => {
|
|
|
41053
41051
|
entryPatterns,
|
|
41054
41052
|
ignorePatterns,
|
|
41055
41053
|
tsConfigPath,
|
|
41056
|
-
deslopJsModuleSpecifier
|
|
41057
|
-
coreVersion: CORE_PACKAGE_VERSION
|
|
41054
|
+
deslopJsModuleSpecifier
|
|
41058
41055
|
}) : null;
|
|
41059
41056
|
if (cacheKey !== null) {
|
|
41060
41057
|
const cachedDiagnostics = lookupDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey);
|
|
41061
41058
|
options.onCacheOutcome?.(cachedDiagnostics !== null);
|
|
41062
41059
|
if (cachedDiagnostics !== null) return [...cachedDiagnostics];
|
|
41063
41060
|
}
|
|
41064
|
-
const incrementalCachePath = options.cacheEnabled === true ? Path.join(resolveReactDoctorCacheDir(rootDirectory), DEAD_CODE_SUMMARY_CACHE_FILENAME) : void 0;
|
|
41065
41061
|
const spawnAndRun = () => {
|
|
41066
41062
|
return runDeadCodeWorkerWithTimeout((options.createWorker ?? createDeadCodeWorker)({
|
|
41067
41063
|
rootDirectory,
|
|
@@ -41069,12 +41065,10 @@ const checkDeadCode = async (options) => {
|
|
|
41069
41065
|
tsConfigPath,
|
|
41070
41066
|
ignorePatterns,
|
|
41071
41067
|
deslopJsModuleSpecifier,
|
|
41072
|
-
parseConcurrency: options.parseConcurrency
|
|
41073
|
-
incrementalCachePath
|
|
41068
|
+
parseConcurrency: options.parseConcurrency
|
|
41074
41069
|
}), options.workerTimeoutMs ?? 12e4, options.abortSignal);
|
|
41075
41070
|
};
|
|
41076
41071
|
const result = parseDeadCodeWorkerResult(options.createWorker === void 0 ? await withDeadCodeWorkerSlot(spawnAndRun, options.abortSignal) : await spawnAndRun());
|
|
41077
|
-
if (result.summaryCacheStats !== void 0) options.onSummaryCacheStats?.(result.summaryCacheStats);
|
|
41078
41072
|
const toRelative = (filePath) => toRelativeFilePath(rootDirectory, filePath);
|
|
41079
41073
|
const diagnostics = [];
|
|
41080
41074
|
for (const unusedFile of result.unusedFiles) diagnostics.push({
|
|
@@ -41242,8 +41236,7 @@ var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
|
41242
41236
|
workerTimeoutMs: input.workerTimeoutMs,
|
|
41243
41237
|
abortSignal: signal,
|
|
41244
41238
|
cacheEnabled,
|
|
41245
|
-
onCacheOutcome: input.onCacheOutcome
|
|
41246
|
-
onSummaryCacheStats: input.onSummaryCacheStats
|
|
41239
|
+
onCacheOutcome: input.onCacheOutcome
|
|
41247
41240
|
}),
|
|
41248
41241
|
catch: (cause) => new ReactDoctorError({ reason: new DeadCodeAnalysisFailed({ cause }) })
|
|
41249
41242
|
}).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)));
|
|
@@ -44425,10 +44418,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
44425
44418
|
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs,
|
|
44426
44419
|
onCacheOutcome: (didHitCache) => {
|
|
44427
44420
|
deadCodeCacheHit = didHitCache;
|
|
44428
|
-
},
|
|
44429
|
-
onSummaryCacheStats: (stats) => {
|
|
44430
|
-
deadCodeSummaryCacheHits = stats.hits;
|
|
44431
|
-
deadCodeSummaryCacheMisses = stats.misses;
|
|
44432
44421
|
}
|
|
44433
44422
|
}).pipe(catchTag("ReactDoctorError", (error) => unwrap(gen(function* () {
|
|
44434
44423
|
yield* set(deadCodeFailure, {
|
|
@@ -44458,8 +44447,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
44458
44447
|
let lintCacheHitFileCount = null;
|
|
44459
44448
|
let lintCacheTotalFileCount = null;
|
|
44460
44449
|
let deadCodeCacheHit = null;
|
|
44461
|
-
let deadCodeSummaryCacheHits = null;
|
|
44462
|
-
let deadCodeSummaryCacheMisses = null;
|
|
44463
44450
|
const baseLintStream = linterService.run({
|
|
44464
44451
|
rootDirectory: scanDirectory,
|
|
44465
44452
|
project,
|
|
@@ -44590,8 +44577,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
44590
44577
|
lintCacheHitFileCount,
|
|
44591
44578
|
lintCacheTotalFileCount,
|
|
44592
44579
|
deadCodeCacheHit: lintFailureState.didFail ? null : deadCodeCacheHit,
|
|
44593
|
-
deadCodeSummaryCacheHits: lintFailureState.didFail ? null : deadCodeSummaryCacheHits,
|
|
44594
|
-
deadCodeSummaryCacheMisses: lintFailureState.didFail ? null : deadCodeSummaryCacheMisses,
|
|
44595
44580
|
suppressedRuleCounts: transform.summarizeSuppressions()
|
|
44596
44581
|
};
|
|
44597
44582
|
}).pipe(withSpan("runInspect", { attributes: {
|
|
@@ -45464,7 +45449,7 @@ const makeNoopConsole = () => ({
|
|
|
45464
45449
|
});
|
|
45465
45450
|
//#endregion
|
|
45466
45451
|
//#region src/cli/utils/version.ts
|
|
45467
|
-
const VERSION = "0.6.3-dev.
|
|
45452
|
+
const VERSION = "0.6.3-dev.e257a5e";
|
|
45468
45453
|
//#endregion
|
|
45469
45454
|
//#region src/cli/utils/json-mode.ts
|
|
45470
45455
|
let context = null;
|
|
@@ -45833,13 +45818,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
45833
45818
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
45834
45819
|
* standard `SENTRY_RELEASE` override.
|
|
45835
45820
|
*/
|
|
45836
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.6.3-dev.
|
|
45821
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.6.3-dev.e257a5e`;
|
|
45837
45822
|
/**
|
|
45838
45823
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
45839
45824
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
45840
45825
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
45841
45826
|
*/
|
|
45842
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.6.3-dev.
|
|
45827
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.6.3-dev.e257a5e") ? "development" : "production");
|
|
45843
45828
|
/**
|
|
45844
45829
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
45845
45830
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -58068,9 +58053,7 @@ const buildOutcomeAttributes = (input) => {
|
|
|
58068
58053
|
...withNamespace("deadCode", {
|
|
58069
58054
|
failed: input.didDeadCodeFail ?? null,
|
|
58070
58055
|
overlapped: input.deadCodeOverlapped ?? null,
|
|
58071
|
-
cacheHit: result.deadCodeCacheHit ?? null
|
|
58072
|
-
summaryCacheHits: result.deadCodeSummaryCacheHits ?? null,
|
|
58073
|
-
summaryCacheMisses: result.deadCodeSummaryCacheMisses ?? null
|
|
58056
|
+
cacheHit: result.deadCodeCacheHit ?? null
|
|
58074
58057
|
}),
|
|
58075
58058
|
...withNamespace("supplyChain", { overlapTimedOut: input.supplyChainOverlapTimedOut ?? null }),
|
|
58076
58059
|
...withNamespace("securityScan", { failed: input.securityScanFailed ?? null }),
|
|
@@ -59393,89 +59376,13 @@ const stringifyStableJson = (value) => {
|
|
|
59393
59376
|
};
|
|
59394
59377
|
const hashString = (value) => crypto.createHash("sha1").update(value).digest("hex");
|
|
59395
59378
|
const readHeadSha = (projectDirectory) => runGit(projectDirectory, ["rev-parse", "HEAD"]);
|
|
59396
|
-
const
|
|
59397
|
-
const
|
|
59398
|
-
const tokens = statusOutput.split("\0");
|
|
59399
|
-
for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex += 1) {
|
|
59400
|
-
let record = tokens[tokenIndex];
|
|
59401
|
-
if (record.length === 0) continue;
|
|
59402
|
-
if (record.length < 3 || record[2] !== " ") {
|
|
59403
|
-
if (tokenIndex !== 0) return null;
|
|
59404
|
-
record = ` ${record}`;
|
|
59405
|
-
}
|
|
59406
|
-
if (record.length < 4 || record[2] !== " ") return null;
|
|
59407
|
-
const statusCode = record.slice(0, 2);
|
|
59408
|
-
const recordPath = record.slice(3);
|
|
59409
|
-
if (statusCode.includes("R") || statusCode.includes("C")) {
|
|
59410
|
-
tokenIndex += 1;
|
|
59411
|
-
const originPath = tokens[tokenIndex];
|
|
59412
|
-
if (originPath === void 0 || originPath.length === 0) return null;
|
|
59413
|
-
entries.push({
|
|
59414
|
-
statusCode,
|
|
59415
|
-
path: recordPath,
|
|
59416
|
-
originPath
|
|
59417
|
-
});
|
|
59418
|
-
continue;
|
|
59419
|
-
}
|
|
59420
|
-
entries.push({
|
|
59421
|
-
statusCode,
|
|
59422
|
-
path: recordPath
|
|
59423
|
-
});
|
|
59424
|
-
}
|
|
59425
|
-
return entries;
|
|
59426
|
-
};
|
|
59427
|
-
const buildDirtyPathContentFingerprint = (absolutePath, statusCode) => {
|
|
59428
|
-
let stats;
|
|
59429
|
-
try {
|
|
59430
|
-
stats = fs.lstatSync(absolutePath);
|
|
59431
|
-
} catch {
|
|
59432
|
-
return statusCode.includes("D") ? "deleted" : null;
|
|
59433
|
-
}
|
|
59434
|
-
if (stats.isSymbolicLink()) try {
|
|
59435
|
-
return `link:${fs.readlinkSync(absolutePath)}`;
|
|
59436
|
-
} catch {
|
|
59437
|
-
return null;
|
|
59438
|
-
}
|
|
59439
|
-
if (!stats.isFile()) return null;
|
|
59440
|
-
if (stats.size > 10485760) return `stat:${stats.mtimeMs}:${stats.size}`;
|
|
59441
|
-
return hashFileContents(absolutePath);
|
|
59442
|
-
};
|
|
59443
|
-
const buildWorktreeFingerprint = (projectDirectory) => {
|
|
59444
|
-
const statusOutput = runGit(projectDirectory, [
|
|
59379
|
+
const isWorktreeClean = (projectDirectory) => {
|
|
59380
|
+
const status = runGit(projectDirectory, [
|
|
59445
59381
|
"status",
|
|
59446
59382
|
"--porcelain=v1",
|
|
59447
|
-
"-
|
|
59448
|
-
"--untracked-files=all"
|
|
59383
|
+
"--untracked-files=normal"
|
|
59449
59384
|
]);
|
|
59450
|
-
|
|
59451
|
-
if (statusOutput.length === 0) return [];
|
|
59452
|
-
const statusEntries = parseWorktreeStatusRecords(statusOutput);
|
|
59453
|
-
if (statusEntries === null) return null;
|
|
59454
|
-
if (statusEntries.length > 300) return null;
|
|
59455
|
-
const repositoryRoot = runGit(projectDirectory, ["rev-parse", "--show-toplevel"]);
|
|
59456
|
-
if (repositoryRoot === null) return null;
|
|
59457
|
-
const dirtyEntries = [];
|
|
59458
|
-
for (const statusEntry of statusEntries) {
|
|
59459
|
-
const contentFingerprint = buildDirtyPathContentFingerprint(path.join(repositoryRoot, statusEntry.path), statusEntry.statusCode);
|
|
59460
|
-
if (contentFingerprint === null) return null;
|
|
59461
|
-
dirtyEntries.push({
|
|
59462
|
-
...statusEntry,
|
|
59463
|
-
contentFingerprint
|
|
59464
|
-
});
|
|
59465
|
-
}
|
|
59466
|
-
return dirtyEntries.sort((firstEntry, secondEntry) => {
|
|
59467
|
-
const firstSortKey = `${firstEntry.path}${firstEntry.statusCode}`;
|
|
59468
|
-
const secondSortKey = `${secondEntry.path}${secondEntry.statusCode}`;
|
|
59469
|
-
return firstSortKey < secondSortKey ? -1 : firstSortKey > secondSortKey ? 1 : 0;
|
|
59470
|
-
});
|
|
59471
|
-
};
|
|
59472
|
-
const DOTENV_FILE_NAME_PATTERN = /^\.env(\.|$)/;
|
|
59473
|
-
const resolveDotenvFingerprint = (projectDirectory) => {
|
|
59474
|
-
try {
|
|
59475
|
-
return fs.readdirSync(projectDirectory).filter((entryName) => DOTENV_FILE_NAME_PATTERN.test(entryName)).sort().map((entryName) => `${entryName}=${fileFingerprint(path.join(projectDirectory, entryName)) ?? "unreadable"}`);
|
|
59476
|
-
} catch {
|
|
59477
|
-
return [];
|
|
59478
|
-
}
|
|
59385
|
+
return status !== null && status.length === 0;
|
|
59479
59386
|
};
|
|
59480
59387
|
const hasHiddenTrackedFileState = (projectDirectory) => {
|
|
59481
59388
|
const output = runGit(projectDirectory, ["ls-files", "-v"]);
|
|
@@ -59558,9 +59465,8 @@ const resolveToolchainFingerprint = (nodeBinaryPath) => {
|
|
|
59558
59465
|
};
|
|
59559
59466
|
const buildScanResultCacheKey = (input) => {
|
|
59560
59467
|
if (isScanResultCacheDisabled()) return null;
|
|
59468
|
+
if (!isWorktreeClean(input.projectDirectory)) return null;
|
|
59561
59469
|
if (hasHiddenTrackedFileState(input.projectDirectory)) return null;
|
|
59562
|
-
const worktreeFingerprint = buildWorktreeFingerprint(input.projectDirectory);
|
|
59563
|
-
if (worktreeFingerprint === null) return null;
|
|
59564
59470
|
const headSha = readHeadSha(input.projectDirectory);
|
|
59565
59471
|
if (headSha === null) return null;
|
|
59566
59472
|
if (stringifyStableJson(input.userConfig) === null) return null;
|
|
@@ -59568,8 +59474,6 @@ const buildScanResultCacheKey = (input) => {
|
|
|
59568
59474
|
schemaVersion: 3,
|
|
59569
59475
|
projectIdentity: resolveProjectIdentity(input.projectDirectory),
|
|
59570
59476
|
headSha,
|
|
59571
|
-
worktreeFingerprint,
|
|
59572
|
-
dotenvFingerprint: resolveDotenvFingerprint(input.projectDirectory),
|
|
59573
59477
|
reactDoctorVersion: input.version,
|
|
59574
59478
|
nodeVersion: process.version,
|
|
59575
59479
|
toolchainFingerprint: resolveToolchainFingerprint(input.nodeBinaryPath),
|
|
@@ -59963,9 +59867,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
|
|
|
59963
59867
|
baselineDegraded,
|
|
59964
59868
|
lintCacheHitFileCount: output.lintCacheHitFileCount,
|
|
59965
59869
|
lintCacheTotalFileCount: output.lintCacheTotalFileCount,
|
|
59966
|
-
deadCodeCacheHit: output.deadCodeCacheHit
|
|
59967
|
-
deadCodeSummaryCacheHits: output.deadCodeSummaryCacheHits,
|
|
59968
|
-
deadCodeSummaryCacheMisses: output.deadCodeSummaryCacheMisses
|
|
59870
|
+
deadCodeCacheHit: output.deadCodeCacheHit
|
|
59969
59871
|
});
|
|
59970
59872
|
recordOnboardingCompletion(options);
|
|
59971
59873
|
return result;
|
|
@@ -60001,8 +59903,6 @@ const renderAndRecordScan = async (input) => {
|
|
|
60001
59903
|
lintCacheHitFileCount: input.lintCacheHitFileCount ?? null,
|
|
60002
59904
|
lintCacheTotalFileCount: input.lintCacheTotalFileCount ?? null,
|
|
60003
59905
|
deadCodeCacheHit: input.deadCodeCacheHit ?? null,
|
|
60004
|
-
deadCodeSummaryCacheHits: input.deadCodeSummaryCacheHits ?? null,
|
|
60005
|
-
deadCodeSummaryCacheMisses: input.deadCodeSummaryCacheMisses ?? null,
|
|
60006
59906
|
baselineDelta: input.payload.baselineDelta
|
|
60007
59907
|
}), input.options.silent));
|
|
60008
59908
|
const { workerCount: resolvedWorkerCount, parallel } = resolveWorkerTelemetry(input.payload.scanConcurrency, input.options.concurrency);
|
|
@@ -60041,7 +59941,7 @@ const renderAndRecordScan = async (input) => {
|
|
|
60041
59941
|
return result;
|
|
60042
59942
|
};
|
|
60043
59943
|
const finalizeAndRender = (input) => gen(function* () {
|
|
60044
|
-
const { options, elapsedMilliseconds, diagnostics, score, project, userConfig, didLintFail, lintFailureReason, lintPartialFailures, didDeadCodeFail, deadCodeFailureReason, directory, scannedFileCount, scannedFilePaths, scanElapsedMilliseconds, lintCacheHitFileCount, lintCacheTotalFileCount, deadCodeCacheHit,
|
|
59944
|
+
const { options, elapsedMilliseconds, diagnostics, score, project, userConfig, didLintFail, lintFailureReason, lintPartialFailures, didDeadCodeFail, deadCodeFailureReason, directory, scannedFileCount, scannedFilePaths, scanElapsedMilliseconds, lintCacheHitFileCount, lintCacheTotalFileCount, deadCodeCacheHit, baselineDelta } = input;
|
|
60045
59945
|
const { skippedChecks, skippedCheckReasons } = buildSkippedChecks({
|
|
60046
59946
|
didLintFail,
|
|
60047
59947
|
lintFailureReason,
|
|
@@ -60066,10 +59966,6 @@ const finalizeAndRender = (input) => gen(function* () {
|
|
|
60066
59966
|
lintCacheTotalFileCount
|
|
60067
59967
|
} : {},
|
|
60068
59968
|
...deadCodeCacheHit !== null ? { deadCodeCacheHit } : {},
|
|
60069
|
-
...deadCodeSummaryCacheHits !== null && deadCodeSummaryCacheMisses !== null ? {
|
|
60070
|
-
deadCodeSummaryCacheHits,
|
|
60071
|
-
deadCodeSummaryCacheMisses
|
|
60072
|
-
} : {},
|
|
60073
59969
|
...baselineDelta ? { baselineDelta } : {}
|
|
60074
59970
|
});
|
|
60075
59971
|
if (options.suppressRendering) return buildResult();
|
|
@@ -63916,4 +63812,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
63916
63812
|
export {};
|
|
63917
63813
|
|
|
63918
63814
|
//# sourceMappingURL=cli.js.map
|
|
63919
|
-
//# debugId=
|
|
63815
|
+
//# debugId=82500030-a7a7-5da8-b18e-cbdb42102dc3
|
package/dist/index.d.ts
CHANGED
|
@@ -9751,16 +9751,6 @@ interface InspectResult {
|
|
|
9751
9751
|
* projects it onto the Sentry wide event as `deadCode.cacheHit`.
|
|
9752
9752
|
*/
|
|
9753
9753
|
deadCodeCacheHit?: boolean | null;
|
|
9754
|
-
/**
|
|
9755
|
-
* deslop's incremental summary-cache outcome for the dead-code analysis:
|
|
9756
|
-
* collected files served from cached parse summaries vs freshly parsed.
|
|
9757
|
-
* Both absent whenever no analysis consulted the incremental store — a
|
|
9758
|
-
* whole-result cache hit, the cache disabled, or dead-code skipped. The CLI
|
|
9759
|
-
* projects them onto the Sentry wide event as `deadCode.summaryCacheHits` /
|
|
9760
|
-
* `deadCode.summaryCacheMisses`.
|
|
9761
|
-
*/
|
|
9762
|
-
deadCodeSummaryCacheHits?: number | null;
|
|
9763
|
-
deadCodeSummaryCacheMisses?: number | null;
|
|
9764
9754
|
/**
|
|
9765
9755
|
* Present only for a baseline run (`InspectOptions.baseline` set). The
|
|
9766
9756
|
* `diagnostics` above are then the *introduced* findings only; this
|
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]="fb390a00-3616-5547-b572-1ce120b0e1a2")}catch(e){}}();
|
|
3
3
|
import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import * as NFS from "node:fs";
|
|
@@ -18,7 +18,6 @@ import { fileURLToPath } from "node:url";
|
|
|
18
18
|
import { createJiti } from "jiti";
|
|
19
19
|
import * as Crypto from "node:crypto";
|
|
20
20
|
import crypto, { createHash } from "node:crypto";
|
|
21
|
-
import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
|
|
22
21
|
import { gzipSync } from "node:zlib";
|
|
23
22
|
//#region ../../node_modules/.pnpm/effect@4.0.0-beta.70/node_modules/effect/dist/Pipeable.js
|
|
24
23
|
/**
|
|
@@ -32928,9 +32927,7 @@ const SOCKET_PACKAGE_PAGE_BASE = "https://socket.dev/npm/package";
|
|
|
32928
32927
|
const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
32929
32928
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
32930
32929
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
32931
|
-
const CORE_PACKAGE_VERSION = "0.6.3";
|
|
32932
32930
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
32933
|
-
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
32934
32931
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
32935
32932
|
const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
|
|
32936
32933
|
const SUPPLY_CHAIN_CATEGORY = "Security";
|
|
@@ -37341,9 +37338,38 @@ const failOpenReadJson = (filePath, fallback) => {
|
|
|
37341
37338
|
return fallback;
|
|
37342
37339
|
}
|
|
37343
37340
|
};
|
|
37344
|
-
const ANALYZED_FILE_EXTENSIONS = new Set(
|
|
37345
|
-
|
|
37346
|
-
|
|
37341
|
+
const ANALYZED_FILE_EXTENSIONS = new Set([
|
|
37342
|
+
".ts",
|
|
37343
|
+
".tsx",
|
|
37344
|
+
".js",
|
|
37345
|
+
".jsx",
|
|
37346
|
+
".mts",
|
|
37347
|
+
".mjs",
|
|
37348
|
+
".cts",
|
|
37349
|
+
".cjs",
|
|
37350
|
+
".mdx",
|
|
37351
|
+
".astro",
|
|
37352
|
+
".graphql",
|
|
37353
|
+
".gql",
|
|
37354
|
+
".css",
|
|
37355
|
+
".scss",
|
|
37356
|
+
".vue",
|
|
37357
|
+
".svelte"
|
|
37358
|
+
]);
|
|
37359
|
+
const ANALYZED_MANIFEST_NAMES = new Set([
|
|
37360
|
+
"package.json",
|
|
37361
|
+
"knip.json",
|
|
37362
|
+
"app.json",
|
|
37363
|
+
"pnpm-workspace.yaml",
|
|
37364
|
+
"lerna.json",
|
|
37365
|
+
"pnpm-lock.yaml",
|
|
37366
|
+
"package-lock.json",
|
|
37367
|
+
"yarn.lock",
|
|
37368
|
+
"bun.lock",
|
|
37369
|
+
"bun.lockb",
|
|
37370
|
+
"deno.lock",
|
|
37371
|
+
".gitignore"
|
|
37372
|
+
]);
|
|
37347
37373
|
const isTsConfigLikeFile = (fileName) => (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
37348
37374
|
const isFingerprintedFile = (fileName) => ANALYZED_FILE_EXTENSIONS.has(Path.extname(fileName).toLowerCase()) || ANALYZED_MANIFEST_NAMES.has(fileName) || isTsConfigLikeFile(fileName);
|
|
37349
37375
|
const collectAnalyzedFileFingerprints = (rootDirectory) => {
|
|
@@ -37369,7 +37395,6 @@ const resolveDeslopVersion = () => {
|
|
|
37369
37395
|
};
|
|
37370
37396
|
const computeDeadCodeCacheKey = (input) => crypto.createHash("sha1").update(JSON.stringify({
|
|
37371
37397
|
schemaVersion: 1,
|
|
37372
|
-
coreVersion: input.coreVersion,
|
|
37373
37398
|
deslopVersion: resolveDeslopVersion(),
|
|
37374
37399
|
deslopJsModuleSpecifier: input.deslopJsModuleSpecifier,
|
|
37375
37400
|
entryPatterns: input.entryPatterns,
|
|
@@ -37534,14 +37559,6 @@ process.stdin.on("end", () => {
|
|
|
37534
37559
|
circularDependencies: result.circularDependencies.map((cycle) => ({
|
|
37535
37560
|
files: cycle.files,
|
|
37536
37561
|
})),
|
|
37537
|
-
...(result.incrementalCacheStats
|
|
37538
|
-
? {
|
|
37539
|
-
summaryCacheStats: {
|
|
37540
|
-
hits: result.incrementalCacheStats.summaryHits,
|
|
37541
|
-
misses: result.incrementalCacheStats.summaryMisses,
|
|
37542
|
-
},
|
|
37543
|
-
}
|
|
37544
|
-
: {}),
|
|
37545
37562
|
});
|
|
37546
37563
|
|
|
37547
37564
|
const serializeError = (error) =>
|
|
@@ -37565,9 +37582,6 @@ process.stdin.on("end", () => {
|
|
|
37565
37582
|
...(workerInput.ignorePatterns.length > 0
|
|
37566
37583
|
? { ignorePatterns: workerInput.ignorePatterns }
|
|
37567
37584
|
: {}),
|
|
37568
|
-
...(workerInput.incrementalCachePath
|
|
37569
|
-
? { incrementalCachePath: workerInput.incrementalCachePath }
|
|
37570
|
-
: {}),
|
|
37571
37585
|
// We consume only deslop's GRAPH-based findings (unusedFiles, unusedExports,
|
|
37572
37586
|
// unusedDependencies, circularDependencies). Everything else deslop can compute
|
|
37573
37587
|
// is pure wasted work for us, and it's the bulk of the runtime:
|
|
@@ -37578,18 +37592,12 @@ process.stdin.on("end", () => {
|
|
|
37578
37592
|
// are the single most expensive pass — duplicate-block detection alone was
|
|
37579
37593
|
// ~83s of a ~130s Sentry scan — so skipping them is an ~8.5x dead-code
|
|
37580
37594
|
// speedup on a large repo.
|
|
37581
|
-
//
|
|
37582
|
-
// simplifiable functions, identity wrappers, …) — ~120 ms of discarded
|
|
37583
|
-
// output per scan, and skipping them lets the incremental cache drop the
|
|
37584
|
-
// DRY-pattern summary fields (the largest slice of the cache file).
|
|
37585
|
-
// All are provably safe: the consumed graph findings are computed by their own
|
|
37595
|
+
// Both are provably safe: the consumed graph findings are computed by their own
|
|
37586
37596
|
// detectors, independent of these passes (confirmed byte-identical on
|
|
37587
|
-
// excalidraw + mui-material + sentry
|
|
37588
|
-
//
|
|
37589
|
-
// for path-alias resolution in the import graph.
|
|
37597
|
+
// excalidraw + mui-material + sentry). tsConfigPath stays — the module resolver
|
|
37598
|
+
// needs it for path-alias resolution in the import graph.
|
|
37590
37599
|
semantic: { enabled: false },
|
|
37591
37600
|
reportCodeQuality: false,
|
|
37592
|
-
reportRedundancy: false,
|
|
37593
37601
|
};
|
|
37594
37602
|
const result = await analyze(defineConfig(config));
|
|
37595
37603
|
emit({ ok: true, result: normalizeResult(result) });
|
|
@@ -37673,23 +37681,13 @@ const parseCircularDependencies = (value) => {
|
|
|
37673
37681
|
}
|
|
37674
37682
|
return circularDependencies;
|
|
37675
37683
|
};
|
|
37676
|
-
const parseSummaryCacheStats = (value) => {
|
|
37677
|
-
if (!isRecord(value)) return void 0;
|
|
37678
|
-
if (typeof value.hits !== "number" || typeof value.misses !== "number") return void 0;
|
|
37679
|
-
return {
|
|
37680
|
-
hits: value.hits,
|
|
37681
|
-
misses: value.misses
|
|
37682
|
-
};
|
|
37683
|
-
};
|
|
37684
37684
|
const parseDeadCodeWorkerResult = (value) => {
|
|
37685
37685
|
if (!isRecord(value)) throw new Error("Dead-code worker returned an invalid result.");
|
|
37686
|
-
const summaryCacheStats = parseSummaryCacheStats(value.summaryCacheStats);
|
|
37687
37686
|
return {
|
|
37688
37687
|
unusedFiles: parseUnusedFiles(value.unusedFiles),
|
|
37689
37688
|
unusedExports: parseUnusedExports(value.unusedExports),
|
|
37690
37689
|
unusedDependencies: parseUnusedDependencies(value.unusedDependencies),
|
|
37691
|
-
circularDependencies: parseCircularDependencies(value.circularDependencies)
|
|
37692
|
-
...summaryCacheStats ? { summaryCacheStats } : {}
|
|
37690
|
+
circularDependencies: parseCircularDependencies(value.circularDependencies)
|
|
37693
37691
|
};
|
|
37694
37692
|
};
|
|
37695
37693
|
const parseDeadCodeWorkerError = (value) => {
|
|
@@ -37810,15 +37808,13 @@ const checkDeadCode = async (options) => {
|
|
|
37810
37808
|
entryPatterns,
|
|
37811
37809
|
ignorePatterns,
|
|
37812
37810
|
tsConfigPath,
|
|
37813
|
-
deslopJsModuleSpecifier
|
|
37814
|
-
coreVersion: CORE_PACKAGE_VERSION
|
|
37811
|
+
deslopJsModuleSpecifier
|
|
37815
37812
|
}) : null;
|
|
37816
37813
|
if (cacheKey !== null) {
|
|
37817
37814
|
const cachedDiagnostics = lookupDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey);
|
|
37818
37815
|
options.onCacheOutcome?.(cachedDiagnostics !== null);
|
|
37819
37816
|
if (cachedDiagnostics !== null) return [...cachedDiagnostics];
|
|
37820
37817
|
}
|
|
37821
|
-
const incrementalCachePath = options.cacheEnabled === true ? Path.join(resolveReactDoctorCacheDir(rootDirectory), DEAD_CODE_SUMMARY_CACHE_FILENAME) : void 0;
|
|
37822
37818
|
const spawnAndRun = () => {
|
|
37823
37819
|
return runDeadCodeWorkerWithTimeout((options.createWorker ?? createDeadCodeWorker)({
|
|
37824
37820
|
rootDirectory,
|
|
@@ -37826,12 +37822,10 @@ const checkDeadCode = async (options) => {
|
|
|
37826
37822
|
tsConfigPath,
|
|
37827
37823
|
ignorePatterns,
|
|
37828
37824
|
deslopJsModuleSpecifier,
|
|
37829
|
-
parseConcurrency: options.parseConcurrency
|
|
37830
|
-
incrementalCachePath
|
|
37825
|
+
parseConcurrency: options.parseConcurrency
|
|
37831
37826
|
}), options.workerTimeoutMs ?? 12e4, options.abortSignal);
|
|
37832
37827
|
};
|
|
37833
37828
|
const result = parseDeadCodeWorkerResult(options.createWorker === void 0 ? await withDeadCodeWorkerSlot(spawnAndRun, options.abortSignal) : await spawnAndRun());
|
|
37834
|
-
if (result.summaryCacheStats !== void 0) options.onSummaryCacheStats?.(result.summaryCacheStats);
|
|
37835
37829
|
const toRelative = (filePath) => toRelativeFilePath(rootDirectory, filePath);
|
|
37836
37830
|
const diagnostics = [];
|
|
37837
37831
|
for (const unusedFile of result.unusedFiles) diagnostics.push({
|
|
@@ -37999,8 +37993,7 @@ var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
|
37999
37993
|
workerTimeoutMs: input.workerTimeoutMs,
|
|
38000
37994
|
abortSignal: signal,
|
|
38001
37995
|
cacheEnabled,
|
|
38002
|
-
onCacheOutcome: input.onCacheOutcome
|
|
38003
|
-
onSummaryCacheStats: input.onSummaryCacheStats
|
|
37996
|
+
onCacheOutcome: input.onCacheOutcome
|
|
38004
37997
|
}),
|
|
38005
37998
|
catch: (cause) => new ReactDoctorError({ reason: new DeadCodeAnalysisFailed({ cause }) })
|
|
38006
37999
|
}).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)));
|
|
@@ -41182,10 +41175,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41182
41175
|
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs,
|
|
41183
41176
|
onCacheOutcome: (didHitCache) => {
|
|
41184
41177
|
deadCodeCacheHit = didHitCache;
|
|
41185
|
-
},
|
|
41186
|
-
onSummaryCacheStats: (stats) => {
|
|
41187
|
-
deadCodeSummaryCacheHits = stats.hits;
|
|
41188
|
-
deadCodeSummaryCacheMisses = stats.misses;
|
|
41189
41178
|
}
|
|
41190
41179
|
}).pipe(catchTag("ReactDoctorError", (error) => unwrap(gen(function* () {
|
|
41191
41180
|
yield* set(deadCodeFailure, {
|
|
@@ -41215,8 +41204,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41215
41204
|
let lintCacheHitFileCount = null;
|
|
41216
41205
|
let lintCacheTotalFileCount = null;
|
|
41217
41206
|
let deadCodeCacheHit = null;
|
|
41218
|
-
let deadCodeSummaryCacheHits = null;
|
|
41219
|
-
let deadCodeSummaryCacheMisses = null;
|
|
41220
41207
|
const baseLintStream = linterService.run({
|
|
41221
41208
|
rootDirectory: scanDirectory,
|
|
41222
41209
|
project,
|
|
@@ -41347,8 +41334,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41347
41334
|
lintCacheHitFileCount,
|
|
41348
41335
|
lintCacheTotalFileCount,
|
|
41349
41336
|
deadCodeCacheHit: lintFailureState.didFail ? null : deadCodeCacheHit,
|
|
41350
|
-
deadCodeSummaryCacheHits: lintFailureState.didFail ? null : deadCodeSummaryCacheHits,
|
|
41351
|
-
deadCodeSummaryCacheMisses: lintFailureState.didFail ? null : deadCodeSummaryCacheMisses,
|
|
41352
41337
|
suppressedRuleCounts: transform.summarizeSuppressions()
|
|
41353
41338
|
};
|
|
41354
41339
|
}).pipe(withSpan("runInspect", { attributes: {
|
|
@@ -41989,4 +41974,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
41989
41974
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
41990
41975
|
|
|
41991
41976
|
//# sourceMappingURL=index.js.map
|
|
41992
|
-
//# debugId=
|
|
41977
|
+
//# debugId=fb390a00-3616-5547-b572-1ce120b0e1a2
|
package/dist/lsp.js
CHANGED
|
@@ -15,7 +15,6 @@ import { fileURLToPath } from "node:url";
|
|
|
15
15
|
import { createJiti } from "jiti";
|
|
16
16
|
import * as Crypto from "node:crypto";
|
|
17
17
|
import crypto, { createHash } from "node:crypto";
|
|
18
|
-
import { ANALYZED_MANIFEST_FILENAMES, DEFAULT_EXTENSIONS } from "deslop-js/analyzed-inputs";
|
|
19
18
|
import { gzipSync } from "node:zlib";
|
|
20
19
|
import { CodeActionKind, CodeActionTriggerKind, DidChangeWatchedFilesNotification, DocumentDiagnosticReportKind, FileChangeType, TextDocumentSyncKind, TextDocuments, createConnection } from "vscode-languageserver/node.js";
|
|
21
20
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
@@ -32987,9 +32986,7 @@ const SOCKET_PACKAGE_PAGE_BASE = "https://socket.dev/npm/package";
|
|
|
32987
32986
|
const SOCKET_FREE_USER_AGENT = "react-doctor-supply-chain";
|
|
32988
32987
|
const FILE_LINT_CACHE_FILENAME = "file-lint-cache.json";
|
|
32989
32988
|
const FILE_LINT_CACHE_MAX_FILE_COUNT = 5e4;
|
|
32990
|
-
const CORE_PACKAGE_VERSION = "0.6.3";
|
|
32991
32989
|
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
32992
|
-
const DEAD_CODE_SUMMARY_CACHE_FILENAME = "dead-code-summaries.json";
|
|
32993
32990
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
32994
32991
|
const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
|
|
32995
32992
|
const SUPPLY_CHAIN_CATEGORY = "Security";
|
|
@@ -37326,9 +37323,38 @@ const failOpenReadJson = (filePath, fallback) => {
|
|
|
37326
37323
|
return fallback;
|
|
37327
37324
|
}
|
|
37328
37325
|
};
|
|
37329
|
-
const ANALYZED_FILE_EXTENSIONS = new Set(
|
|
37330
|
-
|
|
37331
|
-
|
|
37326
|
+
const ANALYZED_FILE_EXTENSIONS = new Set([
|
|
37327
|
+
".ts",
|
|
37328
|
+
".tsx",
|
|
37329
|
+
".js",
|
|
37330
|
+
".jsx",
|
|
37331
|
+
".mts",
|
|
37332
|
+
".mjs",
|
|
37333
|
+
".cts",
|
|
37334
|
+
".cjs",
|
|
37335
|
+
".mdx",
|
|
37336
|
+
".astro",
|
|
37337
|
+
".graphql",
|
|
37338
|
+
".gql",
|
|
37339
|
+
".css",
|
|
37340
|
+
".scss",
|
|
37341
|
+
".vue",
|
|
37342
|
+
".svelte"
|
|
37343
|
+
]);
|
|
37344
|
+
const ANALYZED_MANIFEST_NAMES = new Set([
|
|
37345
|
+
"package.json",
|
|
37346
|
+
"knip.json",
|
|
37347
|
+
"app.json",
|
|
37348
|
+
"pnpm-workspace.yaml",
|
|
37349
|
+
"lerna.json",
|
|
37350
|
+
"pnpm-lock.yaml",
|
|
37351
|
+
"package-lock.json",
|
|
37352
|
+
"yarn.lock",
|
|
37353
|
+
"bun.lock",
|
|
37354
|
+
"bun.lockb",
|
|
37355
|
+
"deno.lock",
|
|
37356
|
+
".gitignore"
|
|
37357
|
+
]);
|
|
37332
37358
|
const isTsConfigLikeFile = (fileName) => (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
37333
37359
|
const isFingerprintedFile = (fileName) => ANALYZED_FILE_EXTENSIONS.has(Path.extname(fileName).toLowerCase()) || ANALYZED_MANIFEST_NAMES.has(fileName) || isTsConfigLikeFile(fileName);
|
|
37334
37360
|
const collectAnalyzedFileFingerprints = (rootDirectory) => {
|
|
@@ -37354,7 +37380,6 @@ const resolveDeslopVersion = () => {
|
|
|
37354
37380
|
};
|
|
37355
37381
|
const computeDeadCodeCacheKey = (input) => crypto.createHash("sha1").update(JSON.stringify({
|
|
37356
37382
|
schemaVersion: 1,
|
|
37357
|
-
coreVersion: input.coreVersion,
|
|
37358
37383
|
deslopVersion: resolveDeslopVersion(),
|
|
37359
37384
|
deslopJsModuleSpecifier: input.deslopJsModuleSpecifier,
|
|
37360
37385
|
entryPatterns: input.entryPatterns,
|
|
@@ -37519,14 +37544,6 @@ process.stdin.on("end", () => {
|
|
|
37519
37544
|
circularDependencies: result.circularDependencies.map((cycle) => ({
|
|
37520
37545
|
files: cycle.files,
|
|
37521
37546
|
})),
|
|
37522
|
-
...(result.incrementalCacheStats
|
|
37523
|
-
? {
|
|
37524
|
-
summaryCacheStats: {
|
|
37525
|
-
hits: result.incrementalCacheStats.summaryHits,
|
|
37526
|
-
misses: result.incrementalCacheStats.summaryMisses,
|
|
37527
|
-
},
|
|
37528
|
-
}
|
|
37529
|
-
: {}),
|
|
37530
37547
|
});
|
|
37531
37548
|
|
|
37532
37549
|
const serializeError = (error) =>
|
|
@@ -37550,9 +37567,6 @@ process.stdin.on("end", () => {
|
|
|
37550
37567
|
...(workerInput.ignorePatterns.length > 0
|
|
37551
37568
|
? { ignorePatterns: workerInput.ignorePatterns }
|
|
37552
37569
|
: {}),
|
|
37553
|
-
...(workerInput.incrementalCachePath
|
|
37554
|
-
? { incrementalCachePath: workerInput.incrementalCachePath }
|
|
37555
|
-
: {}),
|
|
37556
37570
|
// We consume only deslop's GRAPH-based findings (unusedFiles, unusedExports,
|
|
37557
37571
|
// unusedDependencies, circularDependencies). Everything else deslop can compute
|
|
37558
37572
|
// is pure wasted work for us, and it's the bulk of the runtime:
|
|
@@ -37563,18 +37577,12 @@ process.stdin.on("end", () => {
|
|
|
37563
37577
|
// are the single most expensive pass — duplicate-block detection alone was
|
|
37564
37578
|
// ~83s of a ~130s Sentry scan — so skipping them is an ~8.5x dead-code
|
|
37565
37579
|
// speedup on a large repo.
|
|
37566
|
-
//
|
|
37567
|
-
// simplifiable functions, identity wrappers, …) — ~120 ms of discarded
|
|
37568
|
-
// output per scan, and skipping them lets the incremental cache drop the
|
|
37569
|
-
// DRY-pattern summary fields (the largest slice of the cache file).
|
|
37570
|
-
// All are provably safe: the consumed graph findings are computed by their own
|
|
37580
|
+
// Both are provably safe: the consumed graph findings are computed by their own
|
|
37571
37581
|
// detectors, independent of these passes (confirmed byte-identical on
|
|
37572
|
-
// excalidraw + mui-material + sentry
|
|
37573
|
-
//
|
|
37574
|
-
// for path-alias resolution in the import graph.
|
|
37582
|
+
// excalidraw + mui-material + sentry). tsConfigPath stays — the module resolver
|
|
37583
|
+
// needs it for path-alias resolution in the import graph.
|
|
37575
37584
|
semantic: { enabled: false },
|
|
37576
37585
|
reportCodeQuality: false,
|
|
37577
|
-
reportRedundancy: false,
|
|
37578
37586
|
};
|
|
37579
37587
|
const result = await analyze(defineConfig(config));
|
|
37580
37588
|
emit({ ok: true, result: normalizeResult(result) });
|
|
@@ -37658,23 +37666,13 @@ const parseCircularDependencies = (value) => {
|
|
|
37658
37666
|
}
|
|
37659
37667
|
return circularDependencies;
|
|
37660
37668
|
};
|
|
37661
|
-
const parseSummaryCacheStats = (value) => {
|
|
37662
|
-
if (!isRecord(value)) return void 0;
|
|
37663
|
-
if (typeof value.hits !== "number" || typeof value.misses !== "number") return void 0;
|
|
37664
|
-
return {
|
|
37665
|
-
hits: value.hits,
|
|
37666
|
-
misses: value.misses
|
|
37667
|
-
};
|
|
37668
|
-
};
|
|
37669
37669
|
const parseDeadCodeWorkerResult = (value) => {
|
|
37670
37670
|
if (!isRecord(value)) throw new Error("Dead-code worker returned an invalid result.");
|
|
37671
|
-
const summaryCacheStats = parseSummaryCacheStats(value.summaryCacheStats);
|
|
37672
37671
|
return {
|
|
37673
37672
|
unusedFiles: parseUnusedFiles(value.unusedFiles),
|
|
37674
37673
|
unusedExports: parseUnusedExports(value.unusedExports),
|
|
37675
37674
|
unusedDependencies: parseUnusedDependencies(value.unusedDependencies),
|
|
37676
|
-
circularDependencies: parseCircularDependencies(value.circularDependencies)
|
|
37677
|
-
...summaryCacheStats ? { summaryCacheStats } : {}
|
|
37675
|
+
circularDependencies: parseCircularDependencies(value.circularDependencies)
|
|
37678
37676
|
};
|
|
37679
37677
|
};
|
|
37680
37678
|
const parseDeadCodeWorkerError = (value) => {
|
|
@@ -37795,15 +37793,13 @@ const checkDeadCode = async (options) => {
|
|
|
37795
37793
|
entryPatterns,
|
|
37796
37794
|
ignorePatterns,
|
|
37797
37795
|
tsConfigPath,
|
|
37798
|
-
deslopJsModuleSpecifier
|
|
37799
|
-
coreVersion: CORE_PACKAGE_VERSION
|
|
37796
|
+
deslopJsModuleSpecifier
|
|
37800
37797
|
}) : null;
|
|
37801
37798
|
if (cacheKey !== null) {
|
|
37802
37799
|
const cachedDiagnostics = lookupDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey);
|
|
37803
37800
|
options.onCacheOutcome?.(cachedDiagnostics !== null);
|
|
37804
37801
|
if (cachedDiagnostics !== null) return [...cachedDiagnostics];
|
|
37805
37802
|
}
|
|
37806
|
-
const incrementalCachePath = options.cacheEnabled === true ? Path.join(resolveReactDoctorCacheDir(rootDirectory), DEAD_CODE_SUMMARY_CACHE_FILENAME) : void 0;
|
|
37807
37803
|
const spawnAndRun = () => {
|
|
37808
37804
|
return runDeadCodeWorkerWithTimeout((options.createWorker ?? createDeadCodeWorker)({
|
|
37809
37805
|
rootDirectory,
|
|
@@ -37811,12 +37807,10 @@ const checkDeadCode = async (options) => {
|
|
|
37811
37807
|
tsConfigPath,
|
|
37812
37808
|
ignorePatterns,
|
|
37813
37809
|
deslopJsModuleSpecifier,
|
|
37814
|
-
parseConcurrency: options.parseConcurrency
|
|
37815
|
-
incrementalCachePath
|
|
37810
|
+
parseConcurrency: options.parseConcurrency
|
|
37816
37811
|
}), options.workerTimeoutMs ?? 12e4, options.abortSignal);
|
|
37817
37812
|
};
|
|
37818
37813
|
const result = parseDeadCodeWorkerResult(options.createWorker === void 0 ? await withDeadCodeWorkerSlot(spawnAndRun, options.abortSignal) : await spawnAndRun());
|
|
37819
|
-
if (result.summaryCacheStats !== void 0) options.onSummaryCacheStats?.(result.summaryCacheStats);
|
|
37820
37814
|
const toRelative = (filePath) => toRelativeFilePath(rootDirectory, filePath);
|
|
37821
37815
|
const diagnostics = [];
|
|
37822
37816
|
for (const unusedFile of result.unusedFiles) diagnostics.push({
|
|
@@ -37984,8 +37978,7 @@ var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
|
37984
37978
|
workerTimeoutMs: input.workerTimeoutMs,
|
|
37985
37979
|
abortSignal: signal,
|
|
37986
37980
|
cacheEnabled,
|
|
37987
|
-
onCacheOutcome: input.onCacheOutcome
|
|
37988
|
-
onSummaryCacheStats: input.onSummaryCacheStats
|
|
37981
|
+
onCacheOutcome: input.onCacheOutcome
|
|
37989
37982
|
}),
|
|
37990
37983
|
catch: (cause) => new ReactDoctorError({ reason: new DeadCodeAnalysisFailed({ cause }) })
|
|
37991
37984
|
}).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)));
|
|
@@ -41167,10 +41160,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41167
41160
|
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs,
|
|
41168
41161
|
onCacheOutcome: (didHitCache) => {
|
|
41169
41162
|
deadCodeCacheHit = didHitCache;
|
|
41170
|
-
},
|
|
41171
|
-
onSummaryCacheStats: (stats) => {
|
|
41172
|
-
deadCodeSummaryCacheHits = stats.hits;
|
|
41173
|
-
deadCodeSummaryCacheMisses = stats.misses;
|
|
41174
41163
|
}
|
|
41175
41164
|
}).pipe(catchTag("ReactDoctorError", (error) => unwrap(gen(function* () {
|
|
41176
41165
|
yield* set(deadCodeFailure, {
|
|
@@ -41200,8 +41189,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41200
41189
|
let lintCacheHitFileCount = null;
|
|
41201
41190
|
let lintCacheTotalFileCount = null;
|
|
41202
41191
|
let deadCodeCacheHit = null;
|
|
41203
|
-
let deadCodeSummaryCacheHits = null;
|
|
41204
|
-
let deadCodeSummaryCacheMisses = null;
|
|
41205
41192
|
const baseLintStream = linterService.run({
|
|
41206
41193
|
rootDirectory: scanDirectory,
|
|
41207
41194
|
project,
|
|
@@ -41332,8 +41319,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41332
41319
|
lintCacheHitFileCount,
|
|
41333
41320
|
lintCacheTotalFileCount,
|
|
41334
41321
|
deadCodeCacheHit: lintFailureState.didFail ? null : deadCodeCacheHit,
|
|
41335
|
-
deadCodeSummaryCacheHits: lintFailureState.didFail ? null : deadCodeSummaryCacheHits,
|
|
41336
|
-
deadCodeSummaryCacheMisses: lintFailureState.didFail ? null : deadCodeSummaryCacheMisses,
|
|
41337
41322
|
suppressedRuleCounts: transform.summarizeSuppressions()
|
|
41338
41323
|
};
|
|
41339
41324
|
}).pipe(withSpan("runInspect", { attributes: {
|
|
@@ -43713,5 +43698,5 @@ const startLanguageServer = () => {
|
|
|
43713
43698
|
};
|
|
43714
43699
|
//#endregion
|
|
43715
43700
|
export { startLanguageServer };
|
|
43716
|
-
!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]="
|
|
43717
|
-
//# debugId=
|
|
43701
|
+
!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]="46e851cc-7b86-5c73-afb0-e09296beab28")}catch(e){}}();
|
|
43702
|
+
//# debugId=46e851cc-7b86-5c73-afb0-e09296beab28
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-doctor",
|
|
3
|
-
"version": "0.6.3-dev.
|
|
3
|
+
"version": "0.6.3-dev.e257a5e",
|
|
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
|
+
"oxlint-plugin-react-doctor": "0.6.3-dev.e257a5e",
|
|
69
|
+
"deslop-js": "0.6.3"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/babel__code-frame": "^7.27.0",
|