react-doctor 0.6.3-dev.20d81f6 → 0.6.3-dev.8325343
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 -240
- package/dist/index.d.ts +0 -8
- package/dist/index.js +38 -141
- package/dist/lsp.js +38 -141
- package/package.json +2 -2
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]="2921b8ff-14cf-5604-8ae5-b65b4f1347fc")}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,8 +36128,6 @@ 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
|
-
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
36134
36131
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
36135
36132
|
const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
|
|
36136
36133
|
const SUPPLY_CHAIN_CATEGORY = "Security";
|
|
@@ -38815,25 +38812,6 @@ var PerFileLintCacheEnabled = class extends Reference("react-doctor/PerFileLintC
|
|
|
38815
38812
|
if (CACHE_DISABLED_VALUES$1.has(noFileCache)) return false;
|
|
38816
38813
|
return true;
|
|
38817
38814
|
} }) {};
|
|
38818
|
-
/**
|
|
38819
|
-
* Whether the whole-project dead-code result cache
|
|
38820
|
-
* (`dead-code/dead-code-result-cache.ts`) is active. Defaults ON — a rescan
|
|
38821
|
-
* whose inputs (source tree, manifests, configs, analyzer version) are
|
|
38822
|
-
* unchanged replays the stored diagnostics instead of re-running the
|
|
38823
|
-
* analysis worker. Opt-OUT, two knobs (matching the per-file lint cache):
|
|
38824
|
-
*
|
|
38825
|
-
* - `REACT_DOCTOR_NO_CACHE` — the global off-switch.
|
|
38826
|
-
* - `REACT_DOCTOR_NO_DEAD_CODE_CACHE` — granular: bust only this cache.
|
|
38827
|
-
*
|
|
38828
|
-
* Tests override via `Layer.succeed(DeadCodeResultCacheEnabled, false)`.
|
|
38829
|
-
*/
|
|
38830
|
-
var DeadCodeResultCacheEnabled = class extends Reference("react-doctor/DeadCodeResultCacheEnabled", { defaultValue: () => {
|
|
38831
|
-
const noCache = process.env["REACT_DOCTOR_NO_CACHE"]?.toLowerCase() ?? "";
|
|
38832
|
-
const noDeadCodeCache = process.env["REACT_DOCTOR_NO_DEAD_CODE_CACHE"]?.toLowerCase() ?? "";
|
|
38833
|
-
if (CACHE_DISABLED_VALUES$1.has(noCache)) return false;
|
|
38834
|
-
if (CACHE_DISABLED_VALUES$1.has(noDeadCodeCache)) return false;
|
|
38835
|
-
return true;
|
|
38836
|
-
} }) {};
|
|
38837
38815
|
const DIAGNOSTIC_SURFACES = [
|
|
38838
38816
|
"cli",
|
|
38839
38817
|
"prComment",
|
|
@@ -40566,80 +40544,6 @@ const collectDeadCodeIgnorePatterns = (rootDirectory) => {
|
|
|
40566
40544
|
return [...seen].filter((pattern) => pattern.length > 0);
|
|
40567
40545
|
};
|
|
40568
40546
|
const collectDeadCodeEntryPatterns = (rootDirectory) => [...new Set(collectKnipPatterns(rootDirectory, "entry"))].filter((pattern) => pattern.length > 0);
|
|
40569
|
-
const atomicWriteJson = (filePath, value) => {
|
|
40570
|
-
try {
|
|
40571
|
-
NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
|
|
40572
|
-
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
40573
|
-
NFS.writeFileSync(temporaryPath, JSON.stringify(value));
|
|
40574
|
-
NFS.renameSync(temporaryPath, filePath);
|
|
40575
|
-
} catch {
|
|
40576
|
-
return;
|
|
40577
|
-
}
|
|
40578
|
-
};
|
|
40579
|
-
const failOpenReadJson = (filePath, fallback) => {
|
|
40580
|
-
try {
|
|
40581
|
-
return JSON.parse(NFS.readFileSync(filePath, "utf8"));
|
|
40582
|
-
} catch {
|
|
40583
|
-
return fallback;
|
|
40584
|
-
}
|
|
40585
|
-
};
|
|
40586
|
-
const ANALYZED_FILE_EXTENSIONS = new Set(DEFAULT_EXTENSIONS);
|
|
40587
|
-
const CORE_SIDE_MANIFEST_NAMES = ["knip.json", "deno.lock"];
|
|
40588
|
-
const ANALYZED_MANIFEST_NAMES = new Set([...ANALYZED_MANIFEST_FILENAMES, ...CORE_SIDE_MANIFEST_NAMES]);
|
|
40589
|
-
const isTsConfigLikeFile = (fileName) => (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
40590
|
-
const isFingerprintedFile = (fileName) => ANALYZED_FILE_EXTENSIONS.has(Path.extname(fileName).toLowerCase()) || ANALYZED_MANIFEST_NAMES.has(fileName) || isTsConfigLikeFile(fileName);
|
|
40591
|
-
const collectAnalyzedFileFingerprints = (rootDirectory) => {
|
|
40592
|
-
const fingerprints = [];
|
|
40593
|
-
for (const { absolutePath, name } of walkSourceTreeFiles(rootDirectory)) {
|
|
40594
|
-
if (!isFingerprintedFile(name)) continue;
|
|
40595
|
-
try {
|
|
40596
|
-
const fileStat = NFS.statSync(absolutePath);
|
|
40597
|
-
const relativePath = Path.relative(rootDirectory, absolutePath).replace(/\\/g, "/");
|
|
40598
|
-
fingerprints.push(`${relativePath}:${fileStat.mtimeMs}:${fileStat.size}`);
|
|
40599
|
-
} catch {}
|
|
40600
|
-
}
|
|
40601
|
-
return fingerprints.sort();
|
|
40602
|
-
};
|
|
40603
|
-
const bundledRequire$2 = createRequire(import.meta.url);
|
|
40604
|
-
const resolveDeslopVersion = () => {
|
|
40605
|
-
try {
|
|
40606
|
-
const packageJson = JSON.parse(NFS.readFileSync(bundledRequire$2.resolve("deslop-js/package.json"), "utf8"));
|
|
40607
|
-
return isRecord$1(packageJson) && typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
40608
|
-
} catch {
|
|
40609
|
-
return "unknown";
|
|
40610
|
-
}
|
|
40611
|
-
};
|
|
40612
|
-
const computeDeadCodeCacheKey = (input) => crypto.createHash("sha1").update(JSON.stringify({
|
|
40613
|
-
schemaVersion: 1,
|
|
40614
|
-
coreVersion: input.coreVersion,
|
|
40615
|
-
deslopVersion: resolveDeslopVersion(),
|
|
40616
|
-
deslopJsModuleSpecifier: input.deslopJsModuleSpecifier,
|
|
40617
|
-
entryPatterns: input.entryPatterns,
|
|
40618
|
-
ignorePatterns: input.ignorePatterns,
|
|
40619
|
-
tsConfigFile: input.tsConfigPath === void 0 ? null : Path.relative(input.rootDirectory, input.tsConfigPath).replace(/\\/g, "/"),
|
|
40620
|
-
files: collectAnalyzedFileFingerprints(input.rootDirectory)
|
|
40621
|
-
})).digest("hex");
|
|
40622
|
-
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
40623
|
-
const decodeCachedDiagnostics = (raw) => {
|
|
40624
|
-
try {
|
|
40625
|
-
for (const entry of raw) validateDiagnostic$1(entry);
|
|
40626
|
-
return raw;
|
|
40627
|
-
} catch {
|
|
40628
|
-
return null;
|
|
40629
|
-
}
|
|
40630
|
-
};
|
|
40631
|
-
const lookupDeadCodeResultCache = (cacheDirectory, cacheKey) => {
|
|
40632
|
-
const persisted = failOpenReadJson(Path.join(cacheDirectory, DEAD_CODE_CACHE_FILENAME), null);
|
|
40633
|
-
if (persisted === null || !isRecord$1(persisted) || persisted.version !== 1 || persisted.key !== cacheKey || !Array.isArray(persisted.diagnostics)) return null;
|
|
40634
|
-
return decodeCachedDiagnostics(persisted.diagnostics);
|
|
40635
|
-
};
|
|
40636
|
-
const storeDeadCodeResultCache = (cacheDirectory, cacheKey, diagnostics) => {
|
|
40637
|
-
atomicWriteJson(Path.join(cacheDirectory, DEAD_CODE_CACHE_FILENAME), {
|
|
40638
|
-
version: 1,
|
|
40639
|
-
key: cacheKey,
|
|
40640
|
-
diagnostics
|
|
40641
|
-
});
|
|
40642
|
-
};
|
|
40643
40547
|
const readSystemFacts = () => ({
|
|
40644
40548
|
availableCores: os.availableParallelism(),
|
|
40645
40549
|
totalMemoryBytes: os.totalmem(),
|
|
@@ -40708,21 +40612,6 @@ const withDeadCodeWorkerSlot = async (task, abortSignal) => {
|
|
|
40708
40612
|
releaseSlot();
|
|
40709
40613
|
}
|
|
40710
40614
|
};
|
|
40711
|
-
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
40712
|
-
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
40713
|
-
const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
|
|
40714
|
-
if (cacheDirOverride) return Path.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
|
|
40715
|
-
const nodeModulesDirectory = Path.join(projectDirectory, "node_modules");
|
|
40716
|
-
if (NFS.existsSync(nodeModulesDirectory)) return Path.join(nodeModulesDirectory, ".cache", "react-doctor");
|
|
40717
|
-
return Path.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
|
|
40718
|
-
};
|
|
40719
|
-
const resolveUserCacheScope = () => {
|
|
40720
|
-
try {
|
|
40721
|
-
return String(process.getuid?.() ?? os.userInfo().username);
|
|
40722
|
-
} catch {
|
|
40723
|
-
return "shared";
|
|
40724
|
-
}
|
|
40725
|
-
};
|
|
40726
40615
|
/**
|
|
40727
40616
|
* Resolves a path to its canonical, symlink-free form, falling back to
|
|
40728
40617
|
* the input when it cannot be realpath'd (broken symlink, permission
|
|
@@ -41018,28 +40907,13 @@ const checkDeadCode = async (options) => {
|
|
|
41018
40907
|
if (!NFS.existsSync(Path.join(rootDirectory, "package.json"))) return [];
|
|
41019
40908
|
const entryPatterns = collectDeadCodeEntryPatterns(rootDirectory);
|
|
41020
40909
|
const ignorePatterns = collectDeadCodeIgnorePatterns(rootDirectory);
|
|
41021
|
-
const tsConfigPath = resolveTsConfigPath(rootDirectory);
|
|
41022
|
-
const deslopJsModuleSpecifier = options.deslopJsModuleSpecifier ?? import.meta.resolve("deslop-js");
|
|
41023
|
-
const cacheKey = options.cacheEnabled ? computeDeadCodeCacheKey({
|
|
41024
|
-
rootDirectory,
|
|
41025
|
-
entryPatterns,
|
|
41026
|
-
ignorePatterns,
|
|
41027
|
-
tsConfigPath,
|
|
41028
|
-
deslopJsModuleSpecifier,
|
|
41029
|
-
coreVersion: CORE_PACKAGE_VERSION
|
|
41030
|
-
}) : null;
|
|
41031
|
-
if (cacheKey !== null) {
|
|
41032
|
-
const cachedDiagnostics = lookupDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey);
|
|
41033
|
-
options.onCacheOutcome?.(cachedDiagnostics !== null);
|
|
41034
|
-
if (cachedDiagnostics !== null) return [...cachedDiagnostics];
|
|
41035
|
-
}
|
|
41036
40910
|
const spawnAndRun = () => {
|
|
41037
40911
|
return runDeadCodeWorkerWithTimeout((options.createWorker ?? createDeadCodeWorker)({
|
|
41038
40912
|
rootDirectory,
|
|
41039
40913
|
entryPatterns,
|
|
41040
|
-
tsConfigPath,
|
|
40914
|
+
tsConfigPath: resolveTsConfigPath(rootDirectory),
|
|
41041
40915
|
ignorePatterns,
|
|
41042
|
-
deslopJsModuleSpecifier,
|
|
40916
|
+
deslopJsModuleSpecifier: options.deslopJsModuleSpecifier ?? import.meta.resolve("deslop-js"),
|
|
41043
40917
|
parseConcurrency: options.parseConcurrency
|
|
41044
40918
|
}), options.workerTimeoutMs ?? 12e4, options.abortSignal);
|
|
41045
40919
|
};
|
|
@@ -41100,7 +40974,6 @@ const checkDeadCode = async (options) => {
|
|
|
41100
40974
|
category: DEAD_CODE_CATEGORY
|
|
41101
40975
|
});
|
|
41102
40976
|
}
|
|
41103
|
-
if (cacheKey !== null) storeDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey, diagnostics);
|
|
41104
40977
|
return diagnostics;
|
|
41105
40978
|
};
|
|
41106
40979
|
const DEAD_CODE_RULE_KEY_PREFIX = `${DEAD_CODE_PLUGIN}/`;
|
|
@@ -41203,15 +41076,12 @@ var Config = class Config extends Service()("react-doctor/Config") {
|
|
|
41203
41076
|
*/
|
|
41204
41077
|
var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
41205
41078
|
static layerNode = succeed$3(DeadCode, DeadCode.of({ run: (input) => unwrap(fn("DeadCode.run")(function* () {
|
|
41206
|
-
const cacheEnabled = yield* DeadCodeResultCacheEnabled;
|
|
41207
41079
|
return yield* tryPromise({
|
|
41208
41080
|
try: (signal) => checkDeadCode({
|
|
41209
41081
|
rootDirectory: input.rootDirectory,
|
|
41210
41082
|
parseConcurrency: input.parseConcurrency,
|
|
41211
41083
|
workerTimeoutMs: input.workerTimeoutMs,
|
|
41212
|
-
abortSignal: signal
|
|
41213
|
-
cacheEnabled,
|
|
41214
|
-
onCacheOutcome: input.onCacheOutcome
|
|
41084
|
+
abortSignal: signal
|
|
41215
41085
|
}),
|
|
41216
41086
|
catch: (cause) => new ReactDoctorError({ reason: new DeadCodeAnalysisFailed({ cause }) })
|
|
41217
41087
|
}).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)));
|
|
@@ -42137,6 +42007,23 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
42137
42007
|
}
|
|
42138
42008
|
};
|
|
42139
42009
|
};
|
|
42010
|
+
const atomicWriteJson = (filePath, value) => {
|
|
42011
|
+
try {
|
|
42012
|
+
NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
|
|
42013
|
+
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
42014
|
+
NFS.writeFileSync(temporaryPath, JSON.stringify(value));
|
|
42015
|
+
NFS.renameSync(temporaryPath, filePath);
|
|
42016
|
+
} catch {
|
|
42017
|
+
return;
|
|
42018
|
+
}
|
|
42019
|
+
};
|
|
42020
|
+
const failOpenReadJson = (filePath, fallback) => {
|
|
42021
|
+
try {
|
|
42022
|
+
return JSON.parse(NFS.readFileSync(filePath, "utf8"));
|
|
42023
|
+
} catch {
|
|
42024
|
+
return fallback;
|
|
42025
|
+
}
|
|
42026
|
+
};
|
|
42140
42027
|
const validateDiagnostic = decodeUnknownSync(Diagnostic);
|
|
42141
42028
|
const decodeFileDiagnostics = (raw) => {
|
|
42142
42029
|
if (!Array.isArray(raw)) return null;
|
|
@@ -42194,7 +42081,7 @@ const createFileLintCache = (cacheDirectory, rulesetHash) => {
|
|
|
42194
42081
|
}
|
|
42195
42082
|
};
|
|
42196
42083
|
};
|
|
42197
|
-
const bundledRequire$
|
|
42084
|
+
const bundledRequire$2 = createRequire(import.meta.url);
|
|
42198
42085
|
const childNodeVersionByBinaryPath = /* @__PURE__ */ new Map();
|
|
42199
42086
|
const resolveChildNodeVersion = (nodeBinaryPath) => {
|
|
42200
42087
|
if (nodeBinaryPath === process.execPath) return process.version;
|
|
@@ -42220,7 +42107,7 @@ const TOOLCHAIN_PACKAGE_SPECIFIERS$1 = [
|
|
|
42220
42107
|
const resolveOxlintToolchainVersions = (nodeBinaryPath = process.execPath) => {
|
|
42221
42108
|
const versions = [`node=${resolveChildNodeVersion(nodeBinaryPath)}`];
|
|
42222
42109
|
for (const specifier of TOOLCHAIN_PACKAGE_SPECIFIERS$1) try {
|
|
42223
|
-
const packageJson = bundledRequire$
|
|
42110
|
+
const packageJson = bundledRequire$2(specifier);
|
|
42224
42111
|
const version = typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
42225
42112
|
versions.push(`${specifier}=${version}`);
|
|
42226
42113
|
} catch {
|
|
@@ -43264,6 +43151,21 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
43264
43151
|
}
|
|
43265
43152
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
43266
43153
|
};
|
|
43154
|
+
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
43155
|
+
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
43156
|
+
const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
|
|
43157
|
+
if (cacheDirOverride) return Path.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
|
|
43158
|
+
const nodeModulesDirectory = Path.join(projectDirectory, "node_modules");
|
|
43159
|
+
if (NFS.existsSync(nodeModulesDirectory)) return Path.join(nodeModulesDirectory, ".cache", "react-doctor");
|
|
43160
|
+
return Path.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
|
|
43161
|
+
};
|
|
43162
|
+
const resolveUserCacheScope = () => {
|
|
43163
|
+
try {
|
|
43164
|
+
return String(process.getuid?.() ?? os.userInfo().username);
|
|
43165
|
+
} catch {
|
|
43166
|
+
return "shared";
|
|
43167
|
+
}
|
|
43168
|
+
};
|
|
43267
43169
|
/**
|
|
43268
43170
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
43269
43171
|
* the runner: once for the primary scan, once for the
|
|
@@ -44390,10 +44292,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
44390
44292
|
const buildCollectDeadCode = (deadCodeTimeout) => runCollect(applyPerElementPipeline(deadCodeService.run({
|
|
44391
44293
|
rootDirectory: scanDirectory,
|
|
44392
44294
|
parseConcurrency: deadCodeParseConcurrency,
|
|
44393
|
-
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs
|
|
44394
|
-
onCacheOutcome: (didHitCache) => {
|
|
44395
|
-
deadCodeCacheHit = didHitCache;
|
|
44396
|
-
}
|
|
44295
|
+
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs
|
|
44397
44296
|
}).pipe(catchTag("ReactDoctorError", (error) => unwrap(gen(function* () {
|
|
44398
44297
|
yield* set(deadCodeFailure, {
|
|
44399
44298
|
didFail: true,
|
|
@@ -44421,7 +44320,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
44421
44320
|
let lastReportedTotalFileCount = 0;
|
|
44422
44321
|
let lintCacheHitFileCount = null;
|
|
44423
44322
|
let lintCacheTotalFileCount = null;
|
|
44424
|
-
let deadCodeCacheHit = null;
|
|
44425
44323
|
const baseLintStream = linterService.run({
|
|
44426
44324
|
rootDirectory: scanDirectory,
|
|
44427
44325
|
project,
|
|
@@ -44551,7 +44449,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
44551
44449
|
securityScanFailed,
|
|
44552
44450
|
lintCacheHitFileCount,
|
|
44553
44451
|
lintCacheTotalFileCount,
|
|
44554
|
-
deadCodeCacheHit: lintFailureState.didFail ? null : deadCodeCacheHit,
|
|
44555
44452
|
suppressedRuleCounts: transform.summarizeSuppressions()
|
|
44556
44453
|
};
|
|
44557
44454
|
}).pipe(withSpan("runInspect", { attributes: {
|
|
@@ -45333,7 +45230,6 @@ const isNonInteractiveEnvironment = () => NON_INTERACTIVE_ENVIRONMENT_VARIABLES.
|
|
|
45333
45230
|
const REACT_DOCTOR_CONFIG_PROJECT_NAME = "react-doctor";
|
|
45334
45231
|
const STAGED_FILES_TEMP_DIR_PREFIX = "react-doctor-staged-";
|
|
45335
45232
|
const BASELINE_FILES_TEMP_DIR_PREFIX = "react-doctor-baseline-";
|
|
45336
|
-
const RUN_GIT_MAX_BUFFER_BYTES = 64 * 1024 * 1024;
|
|
45337
45233
|
const GH_DEFAULT_BRANCH_PROBE_TIMEOUT_MS = 5e3;
|
|
45338
45234
|
const CI_TRUST_COMPANIES = "PayPal, Rippling, and Alibaba";
|
|
45339
45235
|
const WELCOME_EXPLANATION_HOLD_MS = 1e3;
|
|
@@ -45424,7 +45320,7 @@ const makeNoopConsole = () => ({
|
|
|
45424
45320
|
});
|
|
45425
45321
|
//#endregion
|
|
45426
45322
|
//#region src/cli/utils/version.ts
|
|
45427
|
-
const VERSION = "0.6.3-dev.
|
|
45323
|
+
const VERSION = "0.6.3-dev.8325343";
|
|
45428
45324
|
//#endregion
|
|
45429
45325
|
//#region src/cli/utils/json-mode.ts
|
|
45430
45326
|
let context = null;
|
|
@@ -45793,13 +45689,13 @@ const isDevVersion = (version) => version === "0.0.0" || version.includes("-");
|
|
|
45793
45689
|
* uploads source-map artifacts under, so stack frames symbolicate. Honors the
|
|
45794
45690
|
* standard `SENTRY_RELEASE` override.
|
|
45795
45691
|
*/
|
|
45796
|
-
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.6.3-dev.
|
|
45692
|
+
const resolveSentryRelease = () => process.env.SENTRY_RELEASE || `react-doctor@0.6.3-dev.8325343`;
|
|
45797
45693
|
/**
|
|
45798
45694
|
* Deployment environment shown in Sentry's environment filter. Defaults to
|
|
45799
45695
|
* `production` for tagged releases and `development` for dev/unbuilt versions,
|
|
45800
45696
|
* overridable via the standard `SENTRY_ENVIRONMENT` env var.
|
|
45801
45697
|
*/
|
|
45802
|
-
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.6.3-dev.
|
|
45698
|
+
const resolveSentryEnvironment = () => process.env.SENTRY_ENVIRONMENT || (isDevVersion("0.6.3-dev.8325343") ? "development" : "production");
|
|
45803
45699
|
/**
|
|
45804
45700
|
* Performance-tracing sample rate in `[0, 1]`. Reads `SENTRY_TRACES_SAMPLE_RATE`
|
|
45805
45701
|
* (set to `0` to disable tracing) and falls back to
|
|
@@ -46000,8 +45896,7 @@ const runGit = (projectRoot, args) => {
|
|
|
46000
45896
|
"ignore",
|
|
46001
45897
|
"pipe",
|
|
46002
45898
|
"ignore"
|
|
46003
|
-
]
|
|
46004
|
-
maxBuffer: RUN_GIT_MAX_BUFFER_BYTES
|
|
45899
|
+
]
|
|
46005
45900
|
}).trim();
|
|
46006
45901
|
} catch {
|
|
46007
45902
|
return null;
|
|
@@ -58027,8 +57922,7 @@ const buildOutcomeAttributes = (input) => {
|
|
|
58027
57922
|
}),
|
|
58028
57923
|
...withNamespace("deadCode", {
|
|
58029
57924
|
failed: input.didDeadCodeFail ?? null,
|
|
58030
|
-
overlapped: input.deadCodeOverlapped ?? null
|
|
58031
|
-
cacheHit: result.deadCodeCacheHit ?? null
|
|
57925
|
+
overlapped: input.deadCodeOverlapped ?? null
|
|
58032
57926
|
}),
|
|
58033
57927
|
...withNamespace("supplyChain", { overlapTimedOut: input.supplyChainOverlapTimedOut ?? null }),
|
|
58034
57928
|
...withNamespace("securityScan", { failed: input.securityScanFailed ?? null }),
|
|
@@ -59351,89 +59245,13 @@ const stringifyStableJson = (value) => {
|
|
|
59351
59245
|
};
|
|
59352
59246
|
const hashString = (value) => crypto.createHash("sha1").update(value).digest("hex");
|
|
59353
59247
|
const readHeadSha = (projectDirectory) => runGit(projectDirectory, ["rev-parse", "HEAD"]);
|
|
59354
|
-
const
|
|
59355
|
-
const
|
|
59356
|
-
const tokens = statusOutput.split("\0");
|
|
59357
|
-
for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex += 1) {
|
|
59358
|
-
let record = tokens[tokenIndex];
|
|
59359
|
-
if (record.length === 0) continue;
|
|
59360
|
-
if (record.length < 3 || record[2] !== " ") {
|
|
59361
|
-
if (tokenIndex !== 0) return null;
|
|
59362
|
-
record = ` ${record}`;
|
|
59363
|
-
}
|
|
59364
|
-
if (record.length < 4 || record[2] !== " ") return null;
|
|
59365
|
-
const statusCode = record.slice(0, 2);
|
|
59366
|
-
const recordPath = record.slice(3);
|
|
59367
|
-
if (statusCode.includes("R") || statusCode.includes("C")) {
|
|
59368
|
-
tokenIndex += 1;
|
|
59369
|
-
const originPath = tokens[tokenIndex];
|
|
59370
|
-
if (originPath === void 0 || originPath.length === 0) return null;
|
|
59371
|
-
entries.push({
|
|
59372
|
-
statusCode,
|
|
59373
|
-
path: recordPath,
|
|
59374
|
-
originPath
|
|
59375
|
-
});
|
|
59376
|
-
continue;
|
|
59377
|
-
}
|
|
59378
|
-
entries.push({
|
|
59379
|
-
statusCode,
|
|
59380
|
-
path: recordPath
|
|
59381
|
-
});
|
|
59382
|
-
}
|
|
59383
|
-
return entries;
|
|
59384
|
-
};
|
|
59385
|
-
const buildDirtyPathContentFingerprint = (absolutePath, statusCode) => {
|
|
59386
|
-
let stats;
|
|
59387
|
-
try {
|
|
59388
|
-
stats = fs.lstatSync(absolutePath);
|
|
59389
|
-
} catch {
|
|
59390
|
-
return statusCode.includes("D") ? "deleted" : null;
|
|
59391
|
-
}
|
|
59392
|
-
if (stats.isSymbolicLink()) try {
|
|
59393
|
-
return `link:${fs.readlinkSync(absolutePath)}`;
|
|
59394
|
-
} catch {
|
|
59395
|
-
return null;
|
|
59396
|
-
}
|
|
59397
|
-
if (!stats.isFile()) return null;
|
|
59398
|
-
if (stats.size > 10485760) return `stat:${stats.mtimeMs}:${stats.size}`;
|
|
59399
|
-
return hashFileContents(absolutePath);
|
|
59400
|
-
};
|
|
59401
|
-
const buildWorktreeFingerprint = (projectDirectory) => {
|
|
59402
|
-
const statusOutput = runGit(projectDirectory, [
|
|
59248
|
+
const isWorktreeClean = (projectDirectory) => {
|
|
59249
|
+
const status = runGit(projectDirectory, [
|
|
59403
59250
|
"status",
|
|
59404
59251
|
"--porcelain=v1",
|
|
59405
|
-
"-
|
|
59406
|
-
"--untracked-files=all"
|
|
59252
|
+
"--untracked-files=normal"
|
|
59407
59253
|
]);
|
|
59408
|
-
|
|
59409
|
-
if (statusOutput.length === 0) return [];
|
|
59410
|
-
const statusEntries = parseWorktreeStatusRecords(statusOutput);
|
|
59411
|
-
if (statusEntries === null) return null;
|
|
59412
|
-
if (statusEntries.length > 300) return null;
|
|
59413
|
-
const repositoryRoot = runGit(projectDirectory, ["rev-parse", "--show-toplevel"]);
|
|
59414
|
-
if (repositoryRoot === null) return null;
|
|
59415
|
-
const dirtyEntries = [];
|
|
59416
|
-
for (const statusEntry of statusEntries) {
|
|
59417
|
-
const contentFingerprint = buildDirtyPathContentFingerprint(path.join(repositoryRoot, statusEntry.path), statusEntry.statusCode);
|
|
59418
|
-
if (contentFingerprint === null) return null;
|
|
59419
|
-
dirtyEntries.push({
|
|
59420
|
-
...statusEntry,
|
|
59421
|
-
contentFingerprint
|
|
59422
|
-
});
|
|
59423
|
-
}
|
|
59424
|
-
return dirtyEntries.sort((firstEntry, secondEntry) => {
|
|
59425
|
-
const firstSortKey = `${firstEntry.path}${firstEntry.statusCode}`;
|
|
59426
|
-
const secondSortKey = `${secondEntry.path}${secondEntry.statusCode}`;
|
|
59427
|
-
return firstSortKey < secondSortKey ? -1 : firstSortKey > secondSortKey ? 1 : 0;
|
|
59428
|
-
});
|
|
59429
|
-
};
|
|
59430
|
-
const DOTENV_FILE_NAME_PATTERN = /^\.env(\.|$)/;
|
|
59431
|
-
const resolveDotenvFingerprint = (projectDirectory) => {
|
|
59432
|
-
try {
|
|
59433
|
-
return fs.readdirSync(projectDirectory).filter((entryName) => DOTENV_FILE_NAME_PATTERN.test(entryName)).sort().map((entryName) => `${entryName}=${fileFingerprint(path.join(projectDirectory, entryName)) ?? "unreadable"}`);
|
|
59434
|
-
} catch {
|
|
59435
|
-
return [];
|
|
59436
|
-
}
|
|
59254
|
+
return status !== null && status.length === 0;
|
|
59437
59255
|
};
|
|
59438
59256
|
const hasHiddenTrackedFileState = (projectDirectory) => {
|
|
59439
59257
|
const output = runGit(projectDirectory, ["ls-files", "-v"]);
|
|
@@ -59516,9 +59334,8 @@ const resolveToolchainFingerprint = (nodeBinaryPath) => {
|
|
|
59516
59334
|
};
|
|
59517
59335
|
const buildScanResultCacheKey = (input) => {
|
|
59518
59336
|
if (isScanResultCacheDisabled()) return null;
|
|
59337
|
+
if (!isWorktreeClean(input.projectDirectory)) return null;
|
|
59519
59338
|
if (hasHiddenTrackedFileState(input.projectDirectory)) return null;
|
|
59520
|
-
const worktreeFingerprint = buildWorktreeFingerprint(input.projectDirectory);
|
|
59521
|
-
if (worktreeFingerprint === null) return null;
|
|
59522
59339
|
const headSha = readHeadSha(input.projectDirectory);
|
|
59523
59340
|
if (headSha === null) return null;
|
|
59524
59341
|
if (stringifyStableJson(input.userConfig) === null) return null;
|
|
@@ -59526,8 +59343,6 @@ const buildScanResultCacheKey = (input) => {
|
|
|
59526
59343
|
schemaVersion: 3,
|
|
59527
59344
|
projectIdentity: resolveProjectIdentity(input.projectDirectory),
|
|
59528
59345
|
headSha,
|
|
59529
|
-
worktreeFingerprint,
|
|
59530
|
-
dotenvFingerprint: resolveDotenvFingerprint(input.projectDirectory),
|
|
59531
59346
|
reactDoctorVersion: input.version,
|
|
59532
59347
|
nodeVersion: process.version,
|
|
59533
59348
|
toolchainFingerprint: resolveToolchainFingerprint(input.nodeBinaryPath),
|
|
@@ -59920,8 +59735,7 @@ const runInspectWithRuntime = async (directory, options, userConfig, hasConfigOv
|
|
|
59920
59735
|
scanMode: baselineDelta ? "baseline" : isDiffMode ? "diff" : "full",
|
|
59921
59736
|
baselineDegraded,
|
|
59922
59737
|
lintCacheHitFileCount: output.lintCacheHitFileCount,
|
|
59923
|
-
lintCacheTotalFileCount: output.lintCacheTotalFileCount
|
|
59924
|
-
deadCodeCacheHit: output.deadCodeCacheHit
|
|
59738
|
+
lintCacheTotalFileCount: output.lintCacheTotalFileCount
|
|
59925
59739
|
});
|
|
59926
59740
|
recordOnboardingCompletion(options);
|
|
59927
59741
|
return result;
|
|
@@ -59956,7 +59770,6 @@ const renderAndRecordScan = async (input) => {
|
|
|
59956
59770
|
scanElapsedMilliseconds: input.payload.scanElapsedMilliseconds,
|
|
59957
59771
|
lintCacheHitFileCount: input.lintCacheHitFileCount ?? null,
|
|
59958
59772
|
lintCacheTotalFileCount: input.lintCacheTotalFileCount ?? null,
|
|
59959
|
-
deadCodeCacheHit: input.deadCodeCacheHit ?? null,
|
|
59960
59773
|
baselineDelta: input.payload.baselineDelta
|
|
59961
59774
|
}), input.options.silent));
|
|
59962
59775
|
const { workerCount: resolvedWorkerCount, parallel } = resolveWorkerTelemetry(input.payload.scanConcurrency, input.options.concurrency);
|
|
@@ -59995,7 +59808,7 @@ const renderAndRecordScan = async (input) => {
|
|
|
59995
59808
|
return result;
|
|
59996
59809
|
};
|
|
59997
59810
|
const finalizeAndRender = (input) => gen(function* () {
|
|
59998
|
-
const { options, elapsedMilliseconds, diagnostics, score, project, userConfig, didLintFail, lintFailureReason, lintPartialFailures, didDeadCodeFail, deadCodeFailureReason, directory, scannedFileCount, scannedFilePaths, scanElapsedMilliseconds, lintCacheHitFileCount, lintCacheTotalFileCount,
|
|
59811
|
+
const { options, elapsedMilliseconds, diagnostics, score, project, userConfig, didLintFail, lintFailureReason, lintPartialFailures, didDeadCodeFail, deadCodeFailureReason, directory, scannedFileCount, scannedFilePaths, scanElapsedMilliseconds, lintCacheHitFileCount, lintCacheTotalFileCount, baselineDelta } = input;
|
|
59999
59812
|
const { skippedChecks, skippedCheckReasons } = buildSkippedChecks({
|
|
60000
59813
|
didLintFail,
|
|
60001
59814
|
lintFailureReason,
|
|
@@ -60019,7 +59832,6 @@ const finalizeAndRender = (input) => gen(function* () {
|
|
|
60019
59832
|
lintCacheHitFileCount,
|
|
60020
59833
|
lintCacheTotalFileCount
|
|
60021
59834
|
} : {},
|
|
60022
|
-
...deadCodeCacheHit !== null ? { deadCodeCacheHit } : {},
|
|
60023
59835
|
...baselineDelta ? { baselineDelta } : {}
|
|
60024
59836
|
});
|
|
60025
59837
|
if (options.suppressRendering) return buildResult();
|
|
@@ -63866,4 +63678,4 @@ Promise.resolve().then(() => assertNoRemovedFlags(process.argv)).then(() => prog
|
|
|
63866
63678
|
export {};
|
|
63867
63679
|
|
|
63868
63680
|
//# sourceMappingURL=cli.js.map
|
|
63869
|
-
//# debugId=
|
|
63681
|
+
//# debugId=2921b8ff-14cf-5604-8ae5-b65b4f1347fc
|
package/dist/index.d.ts
CHANGED
|
@@ -9743,14 +9743,6 @@ interface InspectResult {
|
|
|
9743
9743
|
*/
|
|
9744
9744
|
lintCacheHitFileCount?: number | null;
|
|
9745
9745
|
lintCacheTotalFileCount?: number | null;
|
|
9746
|
-
/**
|
|
9747
|
-
* Dead-code result cache outcome: `true` when the pass replayed a cached
|
|
9748
|
-
* result (the analysis never ran), `false` on a fresh analysis. Absent when
|
|
9749
|
-
* the pass never consulted the cache — dead-code skipped, the cache
|
|
9750
|
-
* disabled, or a whole-repo cache replay where no analysis ran. The CLI
|
|
9751
|
-
* projects it onto the Sentry wide event as `deadCode.cacheHit`.
|
|
9752
|
-
*/
|
|
9753
|
-
deadCodeCacheHit?: boolean | null;
|
|
9754
9746
|
/**
|
|
9755
9747
|
* Present only for a baseline run (`InspectOptions.baseline` set). The
|
|
9756
9748
|
* `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]="8565c6ea-39f3-51e6-895a-ae9f7c026d0e")}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,8 +32927,6 @@ 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
|
-
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
32933
32930
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
32934
32931
|
const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
|
|
32935
32932
|
const SUPPLY_CHAIN_CATEGORY = "Security";
|
|
@@ -35616,25 +35613,6 @@ var PerFileLintCacheEnabled = class extends Reference("react-doctor/PerFileLintC
|
|
|
35616
35613
|
if (CACHE_DISABLED_VALUES.has(noFileCache)) return false;
|
|
35617
35614
|
return true;
|
|
35618
35615
|
} }) {};
|
|
35619
|
-
/**
|
|
35620
|
-
* Whether the whole-project dead-code result cache
|
|
35621
|
-
* (`dead-code/dead-code-result-cache.ts`) is active. Defaults ON — a rescan
|
|
35622
|
-
* whose inputs (source tree, manifests, configs, analyzer version) are
|
|
35623
|
-
* unchanged replays the stored diagnostics instead of re-running the
|
|
35624
|
-
* analysis worker. Opt-OUT, two knobs (matching the per-file lint cache):
|
|
35625
|
-
*
|
|
35626
|
-
* - `REACT_DOCTOR_NO_CACHE` — the global off-switch.
|
|
35627
|
-
* - `REACT_DOCTOR_NO_DEAD_CODE_CACHE` — granular: bust only this cache.
|
|
35628
|
-
*
|
|
35629
|
-
* Tests override via `Layer.succeed(DeadCodeResultCacheEnabled, false)`.
|
|
35630
|
-
*/
|
|
35631
|
-
var DeadCodeResultCacheEnabled = class extends Reference("react-doctor/DeadCodeResultCacheEnabled", { defaultValue: () => {
|
|
35632
|
-
const noCache = process.env["REACT_DOCTOR_NO_CACHE"]?.toLowerCase() ?? "";
|
|
35633
|
-
const noDeadCodeCache = process.env["REACT_DOCTOR_NO_DEAD_CODE_CACHE"]?.toLowerCase() ?? "";
|
|
35634
|
-
if (CACHE_DISABLED_VALUES.has(noCache)) return false;
|
|
35635
|
-
if (CACHE_DISABLED_VALUES.has(noDeadCodeCache)) return false;
|
|
35636
|
-
return true;
|
|
35637
|
-
} }) {};
|
|
35638
35616
|
const DIAGNOSTIC_SURFACES = [
|
|
35639
35617
|
"cli",
|
|
35640
35618
|
"prComment",
|
|
@@ -37323,80 +37301,6 @@ const collectDeadCodeIgnorePatterns = (rootDirectory) => {
|
|
|
37323
37301
|
return [...seen].filter((pattern) => pattern.length > 0);
|
|
37324
37302
|
};
|
|
37325
37303
|
const collectDeadCodeEntryPatterns = (rootDirectory) => [...new Set(collectKnipPatterns(rootDirectory, "entry"))].filter((pattern) => pattern.length > 0);
|
|
37326
|
-
const atomicWriteJson = (filePath, value) => {
|
|
37327
|
-
try {
|
|
37328
|
-
NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
|
|
37329
|
-
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
37330
|
-
NFS.writeFileSync(temporaryPath, JSON.stringify(value));
|
|
37331
|
-
NFS.renameSync(temporaryPath, filePath);
|
|
37332
|
-
} catch {
|
|
37333
|
-
return;
|
|
37334
|
-
}
|
|
37335
|
-
};
|
|
37336
|
-
const failOpenReadJson = (filePath, fallback) => {
|
|
37337
|
-
try {
|
|
37338
|
-
return JSON.parse(NFS.readFileSync(filePath, "utf8"));
|
|
37339
|
-
} catch {
|
|
37340
|
-
return fallback;
|
|
37341
|
-
}
|
|
37342
|
-
};
|
|
37343
|
-
const ANALYZED_FILE_EXTENSIONS = new Set(DEFAULT_EXTENSIONS);
|
|
37344
|
-
const CORE_SIDE_MANIFEST_NAMES = ["knip.json", "deno.lock"];
|
|
37345
|
-
const ANALYZED_MANIFEST_NAMES = new Set([...ANALYZED_MANIFEST_FILENAMES, ...CORE_SIDE_MANIFEST_NAMES]);
|
|
37346
|
-
const isTsConfigLikeFile = (fileName) => (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
37347
|
-
const isFingerprintedFile = (fileName) => ANALYZED_FILE_EXTENSIONS.has(Path.extname(fileName).toLowerCase()) || ANALYZED_MANIFEST_NAMES.has(fileName) || isTsConfigLikeFile(fileName);
|
|
37348
|
-
const collectAnalyzedFileFingerprints = (rootDirectory) => {
|
|
37349
|
-
const fingerprints = [];
|
|
37350
|
-
for (const { absolutePath, name } of walkSourceTreeFiles(rootDirectory)) {
|
|
37351
|
-
if (!isFingerprintedFile(name)) continue;
|
|
37352
|
-
try {
|
|
37353
|
-
const fileStat = NFS.statSync(absolutePath);
|
|
37354
|
-
const relativePath = Path.relative(rootDirectory, absolutePath).replace(/\\/g, "/");
|
|
37355
|
-
fingerprints.push(`${relativePath}:${fileStat.mtimeMs}:${fileStat.size}`);
|
|
37356
|
-
} catch {}
|
|
37357
|
-
}
|
|
37358
|
-
return fingerprints.sort();
|
|
37359
|
-
};
|
|
37360
|
-
const bundledRequire$2 = createRequire(import.meta.url);
|
|
37361
|
-
const resolveDeslopVersion = () => {
|
|
37362
|
-
try {
|
|
37363
|
-
const packageJson = JSON.parse(NFS.readFileSync(bundledRequire$2.resolve("deslop-js/package.json"), "utf8"));
|
|
37364
|
-
return isRecord(packageJson) && typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
37365
|
-
} catch {
|
|
37366
|
-
return "unknown";
|
|
37367
|
-
}
|
|
37368
|
-
};
|
|
37369
|
-
const computeDeadCodeCacheKey = (input) => crypto.createHash("sha1").update(JSON.stringify({
|
|
37370
|
-
schemaVersion: 1,
|
|
37371
|
-
coreVersion: input.coreVersion,
|
|
37372
|
-
deslopVersion: resolveDeslopVersion(),
|
|
37373
|
-
deslopJsModuleSpecifier: input.deslopJsModuleSpecifier,
|
|
37374
|
-
entryPatterns: input.entryPatterns,
|
|
37375
|
-
ignorePatterns: input.ignorePatterns,
|
|
37376
|
-
tsConfigFile: input.tsConfigPath === void 0 ? null : Path.relative(input.rootDirectory, input.tsConfigPath).replace(/\\/g, "/"),
|
|
37377
|
-
files: collectAnalyzedFileFingerprints(input.rootDirectory)
|
|
37378
|
-
})).digest("hex");
|
|
37379
|
-
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
37380
|
-
const decodeCachedDiagnostics = (raw) => {
|
|
37381
|
-
try {
|
|
37382
|
-
for (const entry of raw) validateDiagnostic$1(entry);
|
|
37383
|
-
return raw;
|
|
37384
|
-
} catch {
|
|
37385
|
-
return null;
|
|
37386
|
-
}
|
|
37387
|
-
};
|
|
37388
|
-
const lookupDeadCodeResultCache = (cacheDirectory, cacheKey) => {
|
|
37389
|
-
const persisted = failOpenReadJson(Path.join(cacheDirectory, DEAD_CODE_CACHE_FILENAME), null);
|
|
37390
|
-
if (persisted === null || !isRecord(persisted) || persisted.version !== 1 || persisted.key !== cacheKey || !Array.isArray(persisted.diagnostics)) return null;
|
|
37391
|
-
return decodeCachedDiagnostics(persisted.diagnostics);
|
|
37392
|
-
};
|
|
37393
|
-
const storeDeadCodeResultCache = (cacheDirectory, cacheKey, diagnostics) => {
|
|
37394
|
-
atomicWriteJson(Path.join(cacheDirectory, DEAD_CODE_CACHE_FILENAME), {
|
|
37395
|
-
version: 1,
|
|
37396
|
-
key: cacheKey,
|
|
37397
|
-
diagnostics
|
|
37398
|
-
});
|
|
37399
|
-
};
|
|
37400
37304
|
const readSystemFacts = () => ({
|
|
37401
37305
|
availableCores: os.availableParallelism(),
|
|
37402
37306
|
totalMemoryBytes: os.totalmem(),
|
|
@@ -37465,21 +37369,6 @@ const withDeadCodeWorkerSlot = async (task, abortSignal) => {
|
|
|
37465
37369
|
releaseSlot();
|
|
37466
37370
|
}
|
|
37467
37371
|
};
|
|
37468
|
-
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
37469
|
-
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
37470
|
-
const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
|
|
37471
|
-
if (cacheDirOverride) return Path.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
|
|
37472
|
-
const nodeModulesDirectory = Path.join(projectDirectory, "node_modules");
|
|
37473
|
-
if (NFS.existsSync(nodeModulesDirectory)) return Path.join(nodeModulesDirectory, ".cache", "react-doctor");
|
|
37474
|
-
return Path.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
|
|
37475
|
-
};
|
|
37476
|
-
const resolveUserCacheScope = () => {
|
|
37477
|
-
try {
|
|
37478
|
-
return String(process.getuid?.() ?? os.userInfo().username);
|
|
37479
|
-
} catch {
|
|
37480
|
-
return "shared";
|
|
37481
|
-
}
|
|
37482
|
-
};
|
|
37483
37372
|
/**
|
|
37484
37373
|
* Resolves a path to its canonical, symlink-free form, falling back to
|
|
37485
37374
|
* the input when it cannot be realpath'd (broken symlink, permission
|
|
@@ -37775,28 +37664,13 @@ const checkDeadCode = async (options) => {
|
|
|
37775
37664
|
if (!NFS.existsSync(Path.join(rootDirectory, "package.json"))) return [];
|
|
37776
37665
|
const entryPatterns = collectDeadCodeEntryPatterns(rootDirectory);
|
|
37777
37666
|
const ignorePatterns = collectDeadCodeIgnorePatterns(rootDirectory);
|
|
37778
|
-
const tsConfigPath = resolveTsConfigPath(rootDirectory);
|
|
37779
|
-
const deslopJsModuleSpecifier = options.deslopJsModuleSpecifier ?? import.meta.resolve("deslop-js");
|
|
37780
|
-
const cacheKey = options.cacheEnabled ? computeDeadCodeCacheKey({
|
|
37781
|
-
rootDirectory,
|
|
37782
|
-
entryPatterns,
|
|
37783
|
-
ignorePatterns,
|
|
37784
|
-
tsConfigPath,
|
|
37785
|
-
deslopJsModuleSpecifier,
|
|
37786
|
-
coreVersion: CORE_PACKAGE_VERSION
|
|
37787
|
-
}) : null;
|
|
37788
|
-
if (cacheKey !== null) {
|
|
37789
|
-
const cachedDiagnostics = lookupDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey);
|
|
37790
|
-
options.onCacheOutcome?.(cachedDiagnostics !== null);
|
|
37791
|
-
if (cachedDiagnostics !== null) return [...cachedDiagnostics];
|
|
37792
|
-
}
|
|
37793
37667
|
const spawnAndRun = () => {
|
|
37794
37668
|
return runDeadCodeWorkerWithTimeout((options.createWorker ?? createDeadCodeWorker)({
|
|
37795
37669
|
rootDirectory,
|
|
37796
37670
|
entryPatterns,
|
|
37797
|
-
tsConfigPath,
|
|
37671
|
+
tsConfigPath: resolveTsConfigPath(rootDirectory),
|
|
37798
37672
|
ignorePatterns,
|
|
37799
|
-
deslopJsModuleSpecifier,
|
|
37673
|
+
deslopJsModuleSpecifier: options.deslopJsModuleSpecifier ?? import.meta.resolve("deslop-js"),
|
|
37800
37674
|
parseConcurrency: options.parseConcurrency
|
|
37801
37675
|
}), options.workerTimeoutMs ?? 12e4, options.abortSignal);
|
|
37802
37676
|
};
|
|
@@ -37857,7 +37731,6 @@ const checkDeadCode = async (options) => {
|
|
|
37857
37731
|
category: DEAD_CODE_CATEGORY
|
|
37858
37732
|
});
|
|
37859
37733
|
}
|
|
37860
|
-
if (cacheKey !== null) storeDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey, diagnostics);
|
|
37861
37734
|
return diagnostics;
|
|
37862
37735
|
};
|
|
37863
37736
|
const DEAD_CODE_RULE_KEY_PREFIX = `${DEAD_CODE_PLUGIN}/`;
|
|
@@ -37960,15 +37833,12 @@ var Config = class Config extends Service()("react-doctor/Config") {
|
|
|
37960
37833
|
*/
|
|
37961
37834
|
var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
37962
37835
|
static layerNode = succeed$3(DeadCode, DeadCode.of({ run: (input) => unwrap(fn("DeadCode.run")(function* () {
|
|
37963
|
-
const cacheEnabled = yield* DeadCodeResultCacheEnabled;
|
|
37964
37836
|
return yield* tryPromise({
|
|
37965
37837
|
try: (signal) => checkDeadCode({
|
|
37966
37838
|
rootDirectory: input.rootDirectory,
|
|
37967
37839
|
parseConcurrency: input.parseConcurrency,
|
|
37968
37840
|
workerTimeoutMs: input.workerTimeoutMs,
|
|
37969
|
-
abortSignal: signal
|
|
37970
|
-
cacheEnabled,
|
|
37971
|
-
onCacheOutcome: input.onCacheOutcome
|
|
37841
|
+
abortSignal: signal
|
|
37972
37842
|
}),
|
|
37973
37843
|
catch: (cause) => new ReactDoctorError({ reason: new DeadCodeAnalysisFailed({ cause }) })
|
|
37974
37844
|
}).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)));
|
|
@@ -38894,6 +38764,23 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
38894
38764
|
}
|
|
38895
38765
|
};
|
|
38896
38766
|
};
|
|
38767
|
+
const atomicWriteJson = (filePath, value) => {
|
|
38768
|
+
try {
|
|
38769
|
+
NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
|
|
38770
|
+
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
38771
|
+
NFS.writeFileSync(temporaryPath, JSON.stringify(value));
|
|
38772
|
+
NFS.renameSync(temporaryPath, filePath);
|
|
38773
|
+
} catch {
|
|
38774
|
+
return;
|
|
38775
|
+
}
|
|
38776
|
+
};
|
|
38777
|
+
const failOpenReadJson = (filePath, fallback) => {
|
|
38778
|
+
try {
|
|
38779
|
+
return JSON.parse(NFS.readFileSync(filePath, "utf8"));
|
|
38780
|
+
} catch {
|
|
38781
|
+
return fallback;
|
|
38782
|
+
}
|
|
38783
|
+
};
|
|
38897
38784
|
const validateDiagnostic = decodeUnknownSync(Diagnostic);
|
|
38898
38785
|
const decodeFileDiagnostics = (raw) => {
|
|
38899
38786
|
if (!Array.isArray(raw)) return null;
|
|
@@ -40021,6 +39908,21 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
40021
39908
|
}
|
|
40022
39909
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
40023
39910
|
};
|
|
39911
|
+
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
39912
|
+
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
39913
|
+
const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
|
|
39914
|
+
if (cacheDirOverride) return Path.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
|
|
39915
|
+
const nodeModulesDirectory = Path.join(projectDirectory, "node_modules");
|
|
39916
|
+
if (NFS.existsSync(nodeModulesDirectory)) return Path.join(nodeModulesDirectory, ".cache", "react-doctor");
|
|
39917
|
+
return Path.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
|
|
39918
|
+
};
|
|
39919
|
+
const resolveUserCacheScope = () => {
|
|
39920
|
+
try {
|
|
39921
|
+
return String(process.getuid?.() ?? os.userInfo().username);
|
|
39922
|
+
} catch {
|
|
39923
|
+
return "shared";
|
|
39924
|
+
}
|
|
39925
|
+
};
|
|
40024
39926
|
/**
|
|
40025
39927
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
40026
39928
|
* the runner: once for the primary scan, once for the
|
|
@@ -41147,10 +41049,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41147
41049
|
const buildCollectDeadCode = (deadCodeTimeout) => runCollect(applyPerElementPipeline(deadCodeService.run({
|
|
41148
41050
|
rootDirectory: scanDirectory,
|
|
41149
41051
|
parseConcurrency: deadCodeParseConcurrency,
|
|
41150
|
-
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs
|
|
41151
|
-
onCacheOutcome: (didHitCache) => {
|
|
41152
|
-
deadCodeCacheHit = didHitCache;
|
|
41153
|
-
}
|
|
41052
|
+
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs
|
|
41154
41053
|
}).pipe(catchTag("ReactDoctorError", (error) => unwrap(gen(function* () {
|
|
41155
41054
|
yield* set(deadCodeFailure, {
|
|
41156
41055
|
didFail: true,
|
|
@@ -41178,7 +41077,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41178
41077
|
let lastReportedTotalFileCount = 0;
|
|
41179
41078
|
let lintCacheHitFileCount = null;
|
|
41180
41079
|
let lintCacheTotalFileCount = null;
|
|
41181
|
-
let deadCodeCacheHit = null;
|
|
41182
41080
|
const baseLintStream = linterService.run({
|
|
41183
41081
|
rootDirectory: scanDirectory,
|
|
41184
41082
|
project,
|
|
@@ -41308,7 +41206,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41308
41206
|
securityScanFailed,
|
|
41309
41207
|
lintCacheHitFileCount,
|
|
41310
41208
|
lintCacheTotalFileCount,
|
|
41311
|
-
deadCodeCacheHit: lintFailureState.didFail ? null : deadCodeCacheHit,
|
|
41312
41209
|
suppressedRuleCounts: transform.summarizeSuppressions()
|
|
41313
41210
|
};
|
|
41314
41211
|
}).pipe(withSpan("runInspect", { attributes: {
|
|
@@ -41949,4 +41846,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
41949
41846
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
41950
41847
|
|
|
41951
41848
|
//# sourceMappingURL=index.js.map
|
|
41952
|
-
//# debugId=
|
|
41849
|
+
//# debugId=8565c6ea-39f3-51e6-895a-ae9f7c026d0e
|
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,8 +32986,6 @@ 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
|
-
const DEAD_CODE_CACHE_FILENAME = "dead-code-cache.json";
|
|
32992
32989
|
const SUPPLY_CHAIN_PLUGIN = "socket";
|
|
32993
32990
|
const SUPPLY_CHAIN_RULE = "low-supply-chain-score";
|
|
32994
32991
|
const SUPPLY_CHAIN_CATEGORY = "Security";
|
|
@@ -35649,25 +35646,6 @@ var PerFileLintCacheEnabled = class extends Reference("react-doctor/PerFileLintC
|
|
|
35649
35646
|
if (CACHE_DISABLED_VALUES.has(noFileCache)) return false;
|
|
35650
35647
|
return true;
|
|
35651
35648
|
} }) {};
|
|
35652
|
-
/**
|
|
35653
|
-
* Whether the whole-project dead-code result cache
|
|
35654
|
-
* (`dead-code/dead-code-result-cache.ts`) is active. Defaults ON — a rescan
|
|
35655
|
-
* whose inputs (source tree, manifests, configs, analyzer version) are
|
|
35656
|
-
* unchanged replays the stored diagnostics instead of re-running the
|
|
35657
|
-
* analysis worker. Opt-OUT, two knobs (matching the per-file lint cache):
|
|
35658
|
-
*
|
|
35659
|
-
* - `REACT_DOCTOR_NO_CACHE` — the global off-switch.
|
|
35660
|
-
* - `REACT_DOCTOR_NO_DEAD_CODE_CACHE` — granular: bust only this cache.
|
|
35661
|
-
*
|
|
35662
|
-
* Tests override via `Layer.succeed(DeadCodeResultCacheEnabled, false)`.
|
|
35663
|
-
*/
|
|
35664
|
-
var DeadCodeResultCacheEnabled = class extends Reference("react-doctor/DeadCodeResultCacheEnabled", { defaultValue: () => {
|
|
35665
|
-
const noCache = process.env["REACT_DOCTOR_NO_CACHE"]?.toLowerCase() ?? "";
|
|
35666
|
-
const noDeadCodeCache = process.env["REACT_DOCTOR_NO_DEAD_CODE_CACHE"]?.toLowerCase() ?? "";
|
|
35667
|
-
if (CACHE_DISABLED_VALUES.has(noCache)) return false;
|
|
35668
|
-
if (CACHE_DISABLED_VALUES.has(noDeadCodeCache)) return false;
|
|
35669
|
-
return true;
|
|
35670
|
-
} }) {};
|
|
35671
35649
|
const DIAGNOSTIC_SURFACES = [
|
|
35672
35650
|
"cli",
|
|
35673
35651
|
"prComment",
|
|
@@ -37308,80 +37286,6 @@ const collectDeadCodeIgnorePatterns = (rootDirectory) => {
|
|
|
37308
37286
|
return [...seen].filter((pattern) => pattern.length > 0);
|
|
37309
37287
|
};
|
|
37310
37288
|
const collectDeadCodeEntryPatterns = (rootDirectory) => [...new Set(collectKnipPatterns(rootDirectory, "entry"))].filter((pattern) => pattern.length > 0);
|
|
37311
|
-
const atomicWriteJson = (filePath, value) => {
|
|
37312
|
-
try {
|
|
37313
|
-
NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
|
|
37314
|
-
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
37315
|
-
NFS.writeFileSync(temporaryPath, JSON.stringify(value));
|
|
37316
|
-
NFS.renameSync(temporaryPath, filePath);
|
|
37317
|
-
} catch {
|
|
37318
|
-
return;
|
|
37319
|
-
}
|
|
37320
|
-
};
|
|
37321
|
-
const failOpenReadJson = (filePath, fallback) => {
|
|
37322
|
-
try {
|
|
37323
|
-
return JSON.parse(NFS.readFileSync(filePath, "utf8"));
|
|
37324
|
-
} catch {
|
|
37325
|
-
return fallback;
|
|
37326
|
-
}
|
|
37327
|
-
};
|
|
37328
|
-
const ANALYZED_FILE_EXTENSIONS = new Set(DEFAULT_EXTENSIONS);
|
|
37329
|
-
const CORE_SIDE_MANIFEST_NAMES = ["knip.json", "deno.lock"];
|
|
37330
|
-
const ANALYZED_MANIFEST_NAMES = new Set([...ANALYZED_MANIFEST_FILENAMES, ...CORE_SIDE_MANIFEST_NAMES]);
|
|
37331
|
-
const isTsConfigLikeFile = (fileName) => (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
37332
|
-
const isFingerprintedFile = (fileName) => ANALYZED_FILE_EXTENSIONS.has(Path.extname(fileName).toLowerCase()) || ANALYZED_MANIFEST_NAMES.has(fileName) || isTsConfigLikeFile(fileName);
|
|
37333
|
-
const collectAnalyzedFileFingerprints = (rootDirectory) => {
|
|
37334
|
-
const fingerprints = [];
|
|
37335
|
-
for (const { absolutePath, name } of walkSourceTreeFiles(rootDirectory)) {
|
|
37336
|
-
if (!isFingerprintedFile(name)) continue;
|
|
37337
|
-
try {
|
|
37338
|
-
const fileStat = NFS.statSync(absolutePath);
|
|
37339
|
-
const relativePath = Path.relative(rootDirectory, absolutePath).replace(/\\/g, "/");
|
|
37340
|
-
fingerprints.push(`${relativePath}:${fileStat.mtimeMs}:${fileStat.size}`);
|
|
37341
|
-
} catch {}
|
|
37342
|
-
}
|
|
37343
|
-
return fingerprints.sort();
|
|
37344
|
-
};
|
|
37345
|
-
const bundledRequire$2 = createRequire(import.meta.url);
|
|
37346
|
-
const resolveDeslopVersion = () => {
|
|
37347
|
-
try {
|
|
37348
|
-
const packageJson = JSON.parse(NFS.readFileSync(bundledRequire$2.resolve("deslop-js/package.json"), "utf8"));
|
|
37349
|
-
return isRecord(packageJson) && typeof packageJson.version === "string" ? packageJson.version : "unknown";
|
|
37350
|
-
} catch {
|
|
37351
|
-
return "unknown";
|
|
37352
|
-
}
|
|
37353
|
-
};
|
|
37354
|
-
const computeDeadCodeCacheKey = (input) => crypto.createHash("sha1").update(JSON.stringify({
|
|
37355
|
-
schemaVersion: 1,
|
|
37356
|
-
coreVersion: input.coreVersion,
|
|
37357
|
-
deslopVersion: resolveDeslopVersion(),
|
|
37358
|
-
deslopJsModuleSpecifier: input.deslopJsModuleSpecifier,
|
|
37359
|
-
entryPatterns: input.entryPatterns,
|
|
37360
|
-
ignorePatterns: input.ignorePatterns,
|
|
37361
|
-
tsConfigFile: input.tsConfigPath === void 0 ? null : Path.relative(input.rootDirectory, input.tsConfigPath).replace(/\\/g, "/"),
|
|
37362
|
-
files: collectAnalyzedFileFingerprints(input.rootDirectory)
|
|
37363
|
-
})).digest("hex");
|
|
37364
|
-
const validateDiagnostic$1 = decodeUnknownSync(Diagnostic);
|
|
37365
|
-
const decodeCachedDiagnostics = (raw) => {
|
|
37366
|
-
try {
|
|
37367
|
-
for (const entry of raw) validateDiagnostic$1(entry);
|
|
37368
|
-
return raw;
|
|
37369
|
-
} catch {
|
|
37370
|
-
return null;
|
|
37371
|
-
}
|
|
37372
|
-
};
|
|
37373
|
-
const lookupDeadCodeResultCache = (cacheDirectory, cacheKey) => {
|
|
37374
|
-
const persisted = failOpenReadJson(Path.join(cacheDirectory, DEAD_CODE_CACHE_FILENAME), null);
|
|
37375
|
-
if (persisted === null || !isRecord(persisted) || persisted.version !== 1 || persisted.key !== cacheKey || !Array.isArray(persisted.diagnostics)) return null;
|
|
37376
|
-
return decodeCachedDiagnostics(persisted.diagnostics);
|
|
37377
|
-
};
|
|
37378
|
-
const storeDeadCodeResultCache = (cacheDirectory, cacheKey, diagnostics) => {
|
|
37379
|
-
atomicWriteJson(Path.join(cacheDirectory, DEAD_CODE_CACHE_FILENAME), {
|
|
37380
|
-
version: 1,
|
|
37381
|
-
key: cacheKey,
|
|
37382
|
-
diagnostics
|
|
37383
|
-
});
|
|
37384
|
-
};
|
|
37385
37289
|
const readSystemFacts = () => ({
|
|
37386
37290
|
availableCores: os.availableParallelism(),
|
|
37387
37291
|
totalMemoryBytes: os.totalmem(),
|
|
@@ -37450,21 +37354,6 @@ const withDeadCodeWorkerSlot = async (task, abortSignal) => {
|
|
|
37450
37354
|
releaseSlot();
|
|
37451
37355
|
}
|
|
37452
37356
|
};
|
|
37453
|
-
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
37454
|
-
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
37455
|
-
const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
|
|
37456
|
-
if (cacheDirOverride) return Path.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
|
|
37457
|
-
const nodeModulesDirectory = Path.join(projectDirectory, "node_modules");
|
|
37458
|
-
if (NFS.existsSync(nodeModulesDirectory)) return Path.join(nodeModulesDirectory, ".cache", "react-doctor");
|
|
37459
|
-
return Path.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
|
|
37460
|
-
};
|
|
37461
|
-
const resolveUserCacheScope = () => {
|
|
37462
|
-
try {
|
|
37463
|
-
return String(process.getuid?.() ?? os.userInfo().username);
|
|
37464
|
-
} catch {
|
|
37465
|
-
return "shared";
|
|
37466
|
-
}
|
|
37467
|
-
};
|
|
37468
37357
|
/**
|
|
37469
37358
|
* Resolves a path to its canonical, symlink-free form, falling back to
|
|
37470
37359
|
* the input when it cannot be realpath'd (broken symlink, permission
|
|
@@ -37760,28 +37649,13 @@ const checkDeadCode = async (options) => {
|
|
|
37760
37649
|
if (!NFS.existsSync(Path.join(rootDirectory, "package.json"))) return [];
|
|
37761
37650
|
const entryPatterns = collectDeadCodeEntryPatterns(rootDirectory);
|
|
37762
37651
|
const ignorePatterns = collectDeadCodeIgnorePatterns(rootDirectory);
|
|
37763
|
-
const tsConfigPath = resolveTsConfigPath(rootDirectory);
|
|
37764
|
-
const deslopJsModuleSpecifier = options.deslopJsModuleSpecifier ?? import.meta.resolve("deslop-js");
|
|
37765
|
-
const cacheKey = options.cacheEnabled ? computeDeadCodeCacheKey({
|
|
37766
|
-
rootDirectory,
|
|
37767
|
-
entryPatterns,
|
|
37768
|
-
ignorePatterns,
|
|
37769
|
-
tsConfigPath,
|
|
37770
|
-
deslopJsModuleSpecifier,
|
|
37771
|
-
coreVersion: CORE_PACKAGE_VERSION
|
|
37772
|
-
}) : null;
|
|
37773
|
-
if (cacheKey !== null) {
|
|
37774
|
-
const cachedDiagnostics = lookupDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey);
|
|
37775
|
-
options.onCacheOutcome?.(cachedDiagnostics !== null);
|
|
37776
|
-
if (cachedDiagnostics !== null) return [...cachedDiagnostics];
|
|
37777
|
-
}
|
|
37778
37652
|
const spawnAndRun = () => {
|
|
37779
37653
|
return runDeadCodeWorkerWithTimeout((options.createWorker ?? createDeadCodeWorker)({
|
|
37780
37654
|
rootDirectory,
|
|
37781
37655
|
entryPatterns,
|
|
37782
|
-
tsConfigPath,
|
|
37656
|
+
tsConfigPath: resolveTsConfigPath(rootDirectory),
|
|
37783
37657
|
ignorePatterns,
|
|
37784
|
-
deslopJsModuleSpecifier,
|
|
37658
|
+
deslopJsModuleSpecifier: options.deslopJsModuleSpecifier ?? import.meta.resolve("deslop-js"),
|
|
37785
37659
|
parseConcurrency: options.parseConcurrency
|
|
37786
37660
|
}), options.workerTimeoutMs ?? 12e4, options.abortSignal);
|
|
37787
37661
|
};
|
|
@@ -37842,7 +37716,6 @@ const checkDeadCode = async (options) => {
|
|
|
37842
37716
|
category: DEAD_CODE_CATEGORY
|
|
37843
37717
|
});
|
|
37844
37718
|
}
|
|
37845
|
-
if (cacheKey !== null) storeDeadCodeResultCache(resolveReactDoctorCacheDir(rootDirectory), cacheKey, diagnostics);
|
|
37846
37719
|
return diagnostics;
|
|
37847
37720
|
};
|
|
37848
37721
|
const DEAD_CODE_RULE_KEY_PREFIX = `${DEAD_CODE_PLUGIN}/`;
|
|
@@ -37945,15 +37818,12 @@ var Config = class Config extends Service()("react-doctor/Config") {
|
|
|
37945
37818
|
*/
|
|
37946
37819
|
var DeadCode = class DeadCode extends Service()("react-doctor/DeadCode") {
|
|
37947
37820
|
static layerNode = succeed$3(DeadCode, DeadCode.of({ run: (input) => unwrap(fn("DeadCode.run")(function* () {
|
|
37948
|
-
const cacheEnabled = yield* DeadCodeResultCacheEnabled;
|
|
37949
37821
|
return yield* tryPromise({
|
|
37950
37822
|
try: (signal) => checkDeadCode({
|
|
37951
37823
|
rootDirectory: input.rootDirectory,
|
|
37952
37824
|
parseConcurrency: input.parseConcurrency,
|
|
37953
37825
|
workerTimeoutMs: input.workerTimeoutMs,
|
|
37954
|
-
abortSignal: signal
|
|
37955
|
-
cacheEnabled,
|
|
37956
|
-
onCacheOutcome: input.onCacheOutcome
|
|
37826
|
+
abortSignal: signal
|
|
37957
37827
|
}),
|
|
37958
37828
|
catch: (cause) => new ReactDoctorError({ reason: new DeadCodeAnalysisFailed({ cause }) })
|
|
37959
37829
|
}).pipe(map$3((diagnostics) => fromIterable$1(diagnostics)));
|
|
@@ -38879,6 +38749,23 @@ const createOxlintConfig = ({ pluginPath, project, customRulesOnly = false, exte
|
|
|
38879
38749
|
}
|
|
38880
38750
|
};
|
|
38881
38751
|
};
|
|
38752
|
+
const atomicWriteJson = (filePath, value) => {
|
|
38753
|
+
try {
|
|
38754
|
+
NFS.mkdirSync(Path.dirname(filePath), { recursive: true });
|
|
38755
|
+
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
38756
|
+
NFS.writeFileSync(temporaryPath, JSON.stringify(value));
|
|
38757
|
+
NFS.renameSync(temporaryPath, filePath);
|
|
38758
|
+
} catch {
|
|
38759
|
+
return;
|
|
38760
|
+
}
|
|
38761
|
+
};
|
|
38762
|
+
const failOpenReadJson = (filePath, fallback) => {
|
|
38763
|
+
try {
|
|
38764
|
+
return JSON.parse(NFS.readFileSync(filePath, "utf8"));
|
|
38765
|
+
} catch {
|
|
38766
|
+
return fallback;
|
|
38767
|
+
}
|
|
38768
|
+
};
|
|
38882
38769
|
const validateDiagnostic = decodeUnknownSync(Diagnostic);
|
|
38883
38770
|
const decodeFileDiagnostics = (raw) => {
|
|
38884
38771
|
if (!Array.isArray(raw)) return null;
|
|
@@ -40006,6 +39893,21 @@ const planLintBatches = ({ baseArgs, files, sizeByFile }) => {
|
|
|
40006
39893
|
}
|
|
40007
39894
|
return batches.filter((batch) => batch.fileIndexes.length > 0).map((batch) => batch.fileIndexes.sort((leftIndex, rightIndex) => leftIndex - rightIndex).map((fileIndex) => files[fileIndex]));
|
|
40008
39895
|
};
|
|
39896
|
+
const projectCacheSubdir = (projectDirectory) => crypto.createHash("sha256").update(projectDirectory).digest("hex").slice(0, 16);
|
|
39897
|
+
const resolveReactDoctorCacheDir = (projectDirectory) => {
|
|
39898
|
+
const cacheDirOverride = process.env["REACT_DOCTOR_CACHE_DIR"]?.trim();
|
|
39899
|
+
if (cacheDirOverride) return Path.join(cacheDirOverride, projectCacheSubdir(projectDirectory));
|
|
39900
|
+
const nodeModulesDirectory = Path.join(projectDirectory, "node_modules");
|
|
39901
|
+
if (NFS.existsSync(nodeModulesDirectory)) return Path.join(nodeModulesDirectory, ".cache", "react-doctor");
|
|
39902
|
+
return Path.join(os.tmpdir(), `react-doctor-cache-${resolveUserCacheScope()}`, projectCacheSubdir(projectDirectory));
|
|
39903
|
+
};
|
|
39904
|
+
const resolveUserCacheScope = () => {
|
|
39905
|
+
try {
|
|
39906
|
+
return String(process.getuid?.() ?? os.userInfo().username);
|
|
39907
|
+
} catch {
|
|
39908
|
+
return "shared";
|
|
39909
|
+
}
|
|
39910
|
+
};
|
|
40009
39911
|
/**
|
|
40010
39912
|
* Atomically (re)writes the generated oxlintrc.json. Used twice in
|
|
40011
39913
|
* the runner: once for the primary scan, once for the
|
|
@@ -41132,10 +41034,7 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41132
41034
|
const buildCollectDeadCode = (deadCodeTimeout) => runCollect(applyPerElementPipeline(deadCodeService.run({
|
|
41133
41035
|
rootDirectory: scanDirectory,
|
|
41134
41036
|
parseConcurrency: deadCodeParseConcurrency,
|
|
41135
|
-
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs
|
|
41136
|
-
onCacheOutcome: (didHitCache) => {
|
|
41137
|
-
deadCodeCacheHit = didHitCache;
|
|
41138
|
-
}
|
|
41037
|
+
workerTimeoutMs: deadCodeTimeout.workerTimeoutMs
|
|
41139
41038
|
}).pipe(catchTag("ReactDoctorError", (error) => unwrap(gen(function* () {
|
|
41140
41039
|
yield* set(deadCodeFailure, {
|
|
41141
41040
|
didFail: true,
|
|
@@ -41163,7 +41062,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41163
41062
|
let lastReportedTotalFileCount = 0;
|
|
41164
41063
|
let lintCacheHitFileCount = null;
|
|
41165
41064
|
let lintCacheTotalFileCount = null;
|
|
41166
|
-
let deadCodeCacheHit = null;
|
|
41167
41065
|
const baseLintStream = linterService.run({
|
|
41168
41066
|
rootDirectory: scanDirectory,
|
|
41169
41067
|
project,
|
|
@@ -41293,7 +41191,6 @@ const runInspect = (input, hooks = {}) => gen(function* () {
|
|
|
41293
41191
|
securityScanFailed,
|
|
41294
41192
|
lintCacheHitFileCount,
|
|
41295
41193
|
lintCacheTotalFileCount,
|
|
41296
|
-
deadCodeCacheHit: lintFailureState.didFail ? null : deadCodeCacheHit,
|
|
41297
41194
|
suppressedRuleCounts: transform.summarizeSuppressions()
|
|
41298
41195
|
};
|
|
41299
41196
|
}).pipe(withSpan("runInspect", { attributes: {
|
|
@@ -43673,5 +43570,5 @@ const startLanguageServer = () => {
|
|
|
43673
43570
|
};
|
|
43674
43571
|
//#endregion
|
|
43675
43572
|
export { startLanguageServer };
|
|
43676
|
-
!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]="
|
|
43677
|
-
//# debugId=
|
|
43573
|
+
!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]="94a57ec3-d5a9-52ea-a743-e91d996065b8")}catch(e){}}();
|
|
43574
|
+
//# debugId=94a57ec3-d5a9-52ea-a743-e91d996065b8
|
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.8325343",
|
|
4
4
|
"description": "Your agent writes bad React. This catches it",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"vscode-uri": "^3.1.0",
|
|
67
67
|
"yaml": "^2.9.0",
|
|
68
68
|
"deslop-js": "0.6.3",
|
|
69
|
-
"oxlint-plugin-react-doctor": "0.6.3-dev.
|
|
69
|
+
"oxlint-plugin-react-doctor": "0.6.3-dev.8325343"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/babel__code-frame": "^7.27.0",
|