deslop-js 0.6.3 → 0.7.0
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/analyzed-inputs.cjs +5 -0
- package/dist/analyzed-inputs.d.cts +5 -0
- package/dist/analyzed-inputs.d.mts +5 -0
- package/dist/analyzed-inputs.mjs +3 -0
- package/dist/constants-CD9NXHxi.cjs +530 -0
- package/dist/constants-oYYofMhb.mjs +344 -0
- package/dist/entries-worker.mjs +3736 -0
- package/dist/index.cjs +672 -476
- package/dist/index.d.cts +22 -0
- package/dist/index.d.mts +22 -0
- package/dist/index.mjs +625 -430
- package/dist/parse-worker.mjs +1 -2212
- package/dist/parse-xkrZfjHl.mjs +2308 -0
- package/package.json +11 -1
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
}) : target, mod));
|
|
27
27
|
|
|
28
28
|
//#endregion
|
|
29
|
+
const require_constants = require('./constants-CD9NXHxi.cjs');
|
|
29
30
|
let node_path = require("node:path");
|
|
30
31
|
node_path = __toESM(node_path, 1);
|
|
31
32
|
let node_fs = require("node:fs");
|
|
@@ -36,327 +37,20 @@ let oxc_parser = require("oxc-parser");
|
|
|
36
37
|
let typescript = require("typescript");
|
|
37
38
|
typescript = __toESM(typescript, 1);
|
|
38
39
|
let oxc_resolver = require("oxc-resolver");
|
|
39
|
-
let node_worker_threads = require("node:worker_threads");
|
|
40
|
-
let node_url = require("node:url");
|
|
41
40
|
let node_os = require("node:os");
|
|
42
41
|
node_os = __toESM(node_os, 1);
|
|
42
|
+
let node_worker_threads = require("node:worker_threads");
|
|
43
|
+
let node_url = require("node:url");
|
|
43
44
|
let minimatch = require("minimatch");
|
|
45
|
+
let node_crypto = require("node:crypto");
|
|
46
|
+
node_crypto = __toESM(node_crypto, 1);
|
|
47
|
+
let node_module = require("node:module");
|
|
44
48
|
let node_child_process = require("node:child_process");
|
|
45
49
|
|
|
46
|
-
//#region src/constants.ts
|
|
47
|
-
const DEFAULT_EXTENSIONS = [
|
|
48
|
-
".ts",
|
|
49
|
-
".tsx",
|
|
50
|
-
".js",
|
|
51
|
-
".jsx",
|
|
52
|
-
".mts",
|
|
53
|
-
".mjs",
|
|
54
|
-
".cts",
|
|
55
|
-
".cjs",
|
|
56
|
-
".mdx",
|
|
57
|
-
".astro",
|
|
58
|
-
".graphql",
|
|
59
|
-
".gql",
|
|
60
|
-
".css",
|
|
61
|
-
".scss",
|
|
62
|
-
".vue",
|
|
63
|
-
".svelte"
|
|
64
|
-
];
|
|
65
|
-
const HIDDEN_DIRECTORY_ALLOWLIST = [
|
|
66
|
-
".storybook",
|
|
67
|
-
".vitepress",
|
|
68
|
-
".well-known",
|
|
69
|
-
".changeset",
|
|
70
|
-
".github",
|
|
71
|
-
".client",
|
|
72
|
-
".server"
|
|
73
|
-
];
|
|
74
|
-
const OUTPUT_DIRECTORIES = [
|
|
75
|
-
"dist",
|
|
76
|
-
"build",
|
|
77
|
-
"out",
|
|
78
|
-
"esm",
|
|
79
|
-
"cjs"
|
|
80
|
-
];
|
|
81
|
-
const SOURCE_EXTENSIONS$3 = [
|
|
82
|
-
"ts",
|
|
83
|
-
"tsx",
|
|
84
|
-
"mts",
|
|
85
|
-
"cts",
|
|
86
|
-
"js",
|
|
87
|
-
"jsx",
|
|
88
|
-
"mjs",
|
|
89
|
-
"cjs"
|
|
90
|
-
];
|
|
91
|
-
const DEFAULT_EXCLUSIONS = [
|
|
92
|
-
"**/node_modules/**",
|
|
93
|
-
"**/.git/**",
|
|
94
|
-
"**/coverage/**",
|
|
95
|
-
"**/*.min.js",
|
|
96
|
-
"**/*.min.mjs",
|
|
97
|
-
"**/mockServiceWorker.js"
|
|
98
|
-
];
|
|
99
|
-
const SCRIPT_FILE_PATTERN = /(?:^|\s)(?:node|tsx|ts-node|tsc|npx|bun|esr|esno|jiti|babel-node|zx)\s+(?:\S+\s+)*?([\w./@-]+\.(?:ts|tsx|js|jsx|mts|mjs|cts|cjs))(?:\s|$)/;
|
|
100
|
-
const SCRIPT_EXTENSIONLESS_FILE_PATTERN = /(?:^|\s)(?:node|tsx|ts-node|bun|esr|esno|jiti|babel-node|zx)\s+(?:\S+\s+)*?((?:[./]|[\w@][\w@-]*\/)[\w./@-]+)(?:\s|$)/;
|
|
101
|
-
const SCRIPT_CONFIG_FILE_PATTERN = /--config\s+([\w./@-]+\.(?:ts|tsx|js|jsx|mts|mjs|cts|cjs))/;
|
|
102
|
-
const SCRIPT_ENTRY_PATTERNS = [];
|
|
103
|
-
const DEFAULT_ENTRY_GLOBS = [
|
|
104
|
-
"src/index.{ts,tsx,js,jsx}",
|
|
105
|
-
"src/main.{ts,tsx,js,jsx}",
|
|
106
|
-
"index.{ts,tsx,js,jsx}",
|
|
107
|
-
"main.{ts,tsx,js,jsx}"
|
|
108
|
-
];
|
|
109
|
-
const KNOWN_CONFIG_PREFIXES = [
|
|
110
|
-
"babel.config.",
|
|
111
|
-
"rollup.config.",
|
|
112
|
-
"webpack.config.",
|
|
113
|
-
"postcss.config.",
|
|
114
|
-
"stencil.config.",
|
|
115
|
-
"remotion.config.",
|
|
116
|
-
"metro.config.",
|
|
117
|
-
"tsup.config.",
|
|
118
|
-
"tsdown.config.",
|
|
119
|
-
"unbuild.config.",
|
|
120
|
-
"esbuild.config.",
|
|
121
|
-
"swc.config.",
|
|
122
|
-
"turbo.",
|
|
123
|
-
"jest.config.",
|
|
124
|
-
"jest.setup.",
|
|
125
|
-
"vitest.config.",
|
|
126
|
-
"vitest.ci.config.",
|
|
127
|
-
"vitest.setup.",
|
|
128
|
-
"vitest.workspace.",
|
|
129
|
-
"playwright.config.",
|
|
130
|
-
"cypress.config.",
|
|
131
|
-
"karma.conf.",
|
|
132
|
-
"eslint.config.",
|
|
133
|
-
"prettier.config.",
|
|
134
|
-
"stylelint.config.",
|
|
135
|
-
"lint-staged.config.",
|
|
136
|
-
"commitlint.config.",
|
|
137
|
-
"next.config.",
|
|
138
|
-
"next-sitemap.config.",
|
|
139
|
-
"nuxt.config.",
|
|
140
|
-
"astro.config.",
|
|
141
|
-
"sanity.config.",
|
|
142
|
-
"vite.config.",
|
|
143
|
-
"tailwind.config.",
|
|
144
|
-
"drizzle.config.",
|
|
145
|
-
"knexfile.",
|
|
146
|
-
"sentry.client.config.",
|
|
147
|
-
"sentry.server.config.",
|
|
148
|
-
"sentry.edge.config.",
|
|
149
|
-
"react-router.config.",
|
|
150
|
-
"typedoc.",
|
|
151
|
-
"deslop.config.",
|
|
152
|
-
"i18next-parser.config.",
|
|
153
|
-
"codegen.config.",
|
|
154
|
-
"graphql.config.",
|
|
155
|
-
"npmpackagejsonlint.config.",
|
|
156
|
-
"release-it.",
|
|
157
|
-
"release.config.",
|
|
158
|
-
"contentlayer.config.",
|
|
159
|
-
"rspack.config.",
|
|
160
|
-
"rsbuild.config.",
|
|
161
|
-
"module-federation.config.",
|
|
162
|
-
"vercel.",
|
|
163
|
-
"next-env.d.",
|
|
164
|
-
"env.d.",
|
|
165
|
-
"vite-env.d."
|
|
166
|
-
];
|
|
167
|
-
const IMPLICIT_DEPENDENCIES = new Set([
|
|
168
|
-
"typescript",
|
|
169
|
-
"@types/node",
|
|
170
|
-
"@types/react",
|
|
171
|
-
"@types/react-dom",
|
|
172
|
-
"eslint",
|
|
173
|
-
"prettier",
|
|
174
|
-
"husky",
|
|
175
|
-
"lint-staged",
|
|
176
|
-
"tslib",
|
|
177
|
-
"@babel/core",
|
|
178
|
-
"@babel/runtime",
|
|
179
|
-
"babel-core",
|
|
180
|
-
"babel-jest",
|
|
181
|
-
"babel-loader",
|
|
182
|
-
"postcss",
|
|
183
|
-
"cross-env",
|
|
184
|
-
"sass",
|
|
185
|
-
"node-sass",
|
|
186
|
-
"less",
|
|
187
|
-
"oxlint",
|
|
188
|
-
"biome",
|
|
189
|
-
"@biomejs/biome",
|
|
190
|
-
"patch-package",
|
|
191
|
-
"simple-git-hooks",
|
|
192
|
-
"lefthook",
|
|
193
|
-
"ts-node",
|
|
194
|
-
"ts-jest",
|
|
195
|
-
"tsx",
|
|
196
|
-
"jsdom",
|
|
197
|
-
"rimraf",
|
|
198
|
-
"concurrently",
|
|
199
|
-
"npm-run-all",
|
|
200
|
-
"npm-run-all2",
|
|
201
|
-
"dotenv-cli",
|
|
202
|
-
"webpack",
|
|
203
|
-
"rollup",
|
|
204
|
-
"terser",
|
|
205
|
-
"autoprefixer",
|
|
206
|
-
"tailwindcss",
|
|
207
|
-
"react-test-renderer",
|
|
208
|
-
"esbuild",
|
|
209
|
-
"typedoc",
|
|
210
|
-
"commitizen",
|
|
211
|
-
"cz-conventional-changelog"
|
|
212
|
-
]);
|
|
213
|
-
const BUILTIN_MODULES = new Set([
|
|
214
|
-
"assert",
|
|
215
|
-
"async_hooks",
|
|
216
|
-
"buffer",
|
|
217
|
-
"child_process",
|
|
218
|
-
"cluster",
|
|
219
|
-
"console",
|
|
220
|
-
"constants",
|
|
221
|
-
"crypto",
|
|
222
|
-
"dgram",
|
|
223
|
-
"diagnostics_channel",
|
|
224
|
-
"dns",
|
|
225
|
-
"domain",
|
|
226
|
-
"events",
|
|
227
|
-
"fs",
|
|
228
|
-
"http",
|
|
229
|
-
"http2",
|
|
230
|
-
"https",
|
|
231
|
-
"inspector",
|
|
232
|
-
"module",
|
|
233
|
-
"net",
|
|
234
|
-
"os",
|
|
235
|
-
"path",
|
|
236
|
-
"perf_hooks",
|
|
237
|
-
"process",
|
|
238
|
-
"punycode",
|
|
239
|
-
"querystring",
|
|
240
|
-
"readline",
|
|
241
|
-
"repl",
|
|
242
|
-
"stream",
|
|
243
|
-
"string_decoder",
|
|
244
|
-
"sys",
|
|
245
|
-
"timers",
|
|
246
|
-
"tls",
|
|
247
|
-
"trace_events",
|
|
248
|
-
"tty",
|
|
249
|
-
"url",
|
|
250
|
-
"util",
|
|
251
|
-
"v8",
|
|
252
|
-
"vm",
|
|
253
|
-
"wasi",
|
|
254
|
-
"worker_threads",
|
|
255
|
-
"zlib"
|
|
256
|
-
]);
|
|
257
|
-
const PLATFORM_SUFFIXES = [
|
|
258
|
-
".web",
|
|
259
|
-
".react-native",
|
|
260
|
-
".native",
|
|
261
|
-
".ios",
|
|
262
|
-
".android",
|
|
263
|
-
".desktop",
|
|
264
|
-
".windows",
|
|
265
|
-
".macos",
|
|
266
|
-
".any",
|
|
267
|
-
".react-server",
|
|
268
|
-
".server",
|
|
269
|
-
".client"
|
|
270
|
-
];
|
|
271
|
-
const REACT_NATIVE_PLATFORM_EXTENSIONS = [
|
|
272
|
-
".web.ts",
|
|
273
|
-
".web.tsx",
|
|
274
|
-
".web.js",
|
|
275
|
-
".web.jsx",
|
|
276
|
-
".native.ts",
|
|
277
|
-
".native.tsx",
|
|
278
|
-
".native.js",
|
|
279
|
-
".native.jsx",
|
|
280
|
-
".ios.ts",
|
|
281
|
-
".ios.tsx",
|
|
282
|
-
".ios.js",
|
|
283
|
-
".ios.jsx",
|
|
284
|
-
".android.ts",
|
|
285
|
-
".android.tsx",
|
|
286
|
-
".android.js",
|
|
287
|
-
".android.jsx"
|
|
288
|
-
];
|
|
289
|
-
const RESOLVER_EXTENSIONS = [
|
|
290
|
-
...DEFAULT_EXTENSIONS,
|
|
291
|
-
".d.ts",
|
|
292
|
-
".d.mts",
|
|
293
|
-
".d.cts",
|
|
294
|
-
".json",
|
|
295
|
-
".node",
|
|
296
|
-
".css",
|
|
297
|
-
".scss",
|
|
298
|
-
".less",
|
|
299
|
-
".svg",
|
|
300
|
-
".png",
|
|
301
|
-
".jpg",
|
|
302
|
-
".graphql",
|
|
303
|
-
".gql"
|
|
304
|
-
];
|
|
305
|
-
const SEMANTIC_MAX_PROGRAM_FILES = 5e3;
|
|
306
|
-
const MAX_PARSE_FILE_SIZE_BYTES = 2e6;
|
|
307
|
-
const MAX_ANALYSIS_ERRORS = 5e3;
|
|
308
|
-
const MAX_ERROR_DETAIL_LENGTH = 1e3;
|
|
309
|
-
const BINARY_DETECTION_SAMPLE_BYTES = 2048;
|
|
310
|
-
const MINIFIED_DETECTION_MIN_BYTES = 5e3;
|
|
311
|
-
/**
|
|
312
|
-
* Numeric literals below 1000 are dominated by indices, counters, small
|
|
313
|
-
* ranges, ports, percentages, and array sizes that coincide by accident
|
|
314
|
-
* (every `MAX_RETRIES = 3` is not a duplicate of every `LIMIT = 3`).
|
|
315
|
-
* 1000 admits real shared constants (timeouts in ms, byte sizes, polling
|
|
316
|
-
* intervals) without producing the noise floor that smaller magnitudes do.
|
|
317
|
-
* NOTE: even at 1000, the rule still produces medium-confidence false
|
|
318
|
-
* positives when constants share a value coincidentally with different
|
|
319
|
-
* names (e.g. `STEP_DELAY_MS` vs `MINIMUM_TOKENS`); the report explicitly
|
|
320
|
-
* downgrades those to `confidence: "medium"`.
|
|
321
|
-
*/
|
|
322
|
-
const MIN_NUMERIC_LITERAL_MAGNITUDE_FOR_DUPLICATE = 1e3;
|
|
323
|
-
const DEFAULT_SEMANTIC_DECORATOR_ALLOWLIST = [
|
|
324
|
-
"Component",
|
|
325
|
-
"Injectable",
|
|
326
|
-
"NgModule",
|
|
327
|
-
"Pipe",
|
|
328
|
-
"Directive",
|
|
329
|
-
"Controller",
|
|
330
|
-
"Module",
|
|
331
|
-
"Resolver",
|
|
332
|
-
"Query",
|
|
333
|
-
"Mutation",
|
|
334
|
-
"Get",
|
|
335
|
-
"Post",
|
|
336
|
-
"Put",
|
|
337
|
-
"Patch",
|
|
338
|
-
"Delete",
|
|
339
|
-
"Head",
|
|
340
|
-
"Options",
|
|
341
|
-
"All",
|
|
342
|
-
"Sse",
|
|
343
|
-
"WebSocketGateway",
|
|
344
|
-
"SubscribeMessage"
|
|
345
|
-
];
|
|
346
|
-
const DEFAULT_SEMANTIC_TSCONFIG_NAMES = [
|
|
347
|
-
"tsconfig.json",
|
|
348
|
-
"tsconfig.app.json",
|
|
349
|
-
"tsconfig.build.json",
|
|
350
|
-
"tsconfig.src.json",
|
|
351
|
-
"jsconfig.json"
|
|
352
|
-
];
|
|
353
|
-
const GIT_CHECK_IGNORE_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
354
|
-
|
|
355
|
-
//#endregion
|
|
356
50
|
//#region src/errors.ts
|
|
357
51
|
const truncateDetail = (text) => {
|
|
358
52
|
if (text.length <= 1e3) return text;
|
|
359
|
-
return `${text.slice(0, MAX_ERROR_DETAIL_LENGTH)}… [truncated ${text.length - MAX_ERROR_DETAIL_LENGTH} chars]`;
|
|
53
|
+
return `${text.slice(0, require_constants.MAX_ERROR_DETAIL_LENGTH)}… [truncated ${text.length - require_constants.MAX_ERROR_DETAIL_LENGTH} chars]`;
|
|
360
54
|
};
|
|
361
55
|
const describeUnknownError = (caughtValue) => {
|
|
362
56
|
let rawText;
|
|
@@ -1716,7 +1410,7 @@ const stripByteOrderMark = (sourceText) => {
|
|
|
1716
1410
|
return sourceText;
|
|
1717
1411
|
};
|
|
1718
1412
|
const looksLikeBinaryContent = (sourceText) => {
|
|
1719
|
-
const sampleLength = Math.min(sourceText.length, BINARY_DETECTION_SAMPLE_BYTES);
|
|
1413
|
+
const sampleLength = Math.min(sourceText.length, require_constants.BINARY_DETECTION_SAMPLE_BYTES);
|
|
1720
1414
|
let nullByteCount = 0;
|
|
1721
1415
|
for (let scanIndex = 0; scanIndex < sampleLength; scanIndex++) {
|
|
1722
1416
|
if (sourceText.charCodeAt(scanIndex) === 0) nullByteCount++;
|
|
@@ -1745,7 +1439,7 @@ const safeReadSourceFile = (filePath, errors) => {
|
|
|
1745
1439
|
if (stats.size > 2e6) {
|
|
1746
1440
|
errors.push(new FileReadError({
|
|
1747
1441
|
code: "file-too-large",
|
|
1748
|
-
message: `file size ${stats.size}B exceeds MAX_PARSE_FILE_SIZE_BYTES (${MAX_PARSE_FILE_SIZE_BYTES})`,
|
|
1442
|
+
message: `file size ${stats.size}B exceeds MAX_PARSE_FILE_SIZE_BYTES (${require_constants.MAX_PARSE_FILE_SIZE_BYTES})`,
|
|
1749
1443
|
path: filePath
|
|
1750
1444
|
}));
|
|
1751
1445
|
return;
|
|
@@ -2644,13 +2338,7 @@ const resolveWorkspaces = (rootDir) => {
|
|
|
2644
2338
|
};
|
|
2645
2339
|
};
|
|
2646
2340
|
const IMPLICIT_SUB_PROJECT_SEARCH_DEPTH = 3;
|
|
2647
|
-
const
|
|
2648
|
-
"package-lock.json",
|
|
2649
|
-
"yarn.lock",
|
|
2650
|
-
"pnpm-lock.yaml",
|
|
2651
|
-
"bun.lockb"
|
|
2652
|
-
];
|
|
2653
|
-
const isStandaloneProject = (directory) => STANDALONE_PROJECT_LOCKFILES.some((lockfile) => (0, node_fs.existsSync)((0, node_path.join)(directory, lockfile)));
|
|
2341
|
+
const isStandaloneProject = (directory) => require_constants.STANDALONE_PROJECT_LOCKFILES.some((lockfile) => (0, node_fs.existsSync)((0, node_path.join)(directory, lockfile)));
|
|
2654
2342
|
const discoverImplicitSubProjects = (rootDir, alreadyDiscoveredDirectories) => {
|
|
2655
2343
|
const knownDirectories = new Set(alreadyDiscoveredDirectories);
|
|
2656
2344
|
const hasDeclaredWorkspaces = alreadyDiscoveredDirectories.length > 0;
|
|
@@ -3211,7 +2899,7 @@ const NESTED_EXPO_CONFIG_FILE_GLOBS = [
|
|
|
3211
2899
|
"**/app.json"
|
|
3212
2900
|
];
|
|
3213
2901
|
const EXPO_REACT_NATIVE_DEPENDENCIES = new Set(["expo", "react-native"]);
|
|
3214
|
-
const EXPO_PLUGIN_RESOLVABLE_EXTENSIONS = SOURCE_EXTENSIONS
|
|
2902
|
+
const EXPO_PLUGIN_RESOLVABLE_EXTENSIONS = require_constants.SOURCE_EXTENSIONS.map((sourceExtension) => `.${sourceExtension}`);
|
|
3215
2903
|
const isRecord = (value) => typeof value === "object" && value !== null;
|
|
3216
2904
|
const isExpoOrReactNativeWorkspace = (dependencies) => [...EXPO_REACT_NATIVE_DEPENDENCIES].some((dependencyName) => dependencyName in dependencies);
|
|
3217
2905
|
const isLocalExpoPluginPath = (value) => (value.startsWith("./") || value.startsWith("../")) && !value.includes("*") && !value.includes("?");
|
|
@@ -3476,21 +3164,6 @@ const resolveWithIndexPrefix = (stemPath, directory) => {
|
|
|
3476
3164
|
|
|
3477
3165
|
//#endregion
|
|
3478
3166
|
//#region src/utils/find-monorepo-root.ts
|
|
3479
|
-
const MONOREPO_ROOT_MARKERS = [
|
|
3480
|
-
"pnpm-workspace.yaml",
|
|
3481
|
-
"pnpm-workspace.yml",
|
|
3482
|
-
"lerna.json",
|
|
3483
|
-
"nx.json",
|
|
3484
|
-
"turbo.json",
|
|
3485
|
-
"rush.json"
|
|
3486
|
-
];
|
|
3487
|
-
const LOCKFILE_MARKERS = [
|
|
3488
|
-
"pnpm-lock.yaml",
|
|
3489
|
-
"yarn.lock",
|
|
3490
|
-
"package-lock.json",
|
|
3491
|
-
"bun.lockb",
|
|
3492
|
-
"bun.lock"
|
|
3493
|
-
];
|
|
3494
3167
|
const MAX_MONOREPO_WALK_DEPTH = 5;
|
|
3495
3168
|
const findMonorepoRoot = (rootDir) => {
|
|
3496
3169
|
let currentDirectory = (0, node_path.resolve)(rootDir);
|
|
@@ -3501,16 +3174,16 @@ const findMonorepoRoot = (rootDir) => {
|
|
|
3501
3174
|
currentDirectory = parentDirectory;
|
|
3502
3175
|
walkedDepth++;
|
|
3503
3176
|
if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, ".git"))) {
|
|
3504
|
-
for (const marker of MONOREPO_ROOT_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, marker))) return currentDirectory;
|
|
3177
|
+
for (const marker of require_constants.MONOREPO_ROOT_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, marker))) return currentDirectory;
|
|
3505
3178
|
const packageJsonPath = (0, node_path.join)(currentDirectory, "package.json");
|
|
3506
3179
|
if ((0, node_fs.existsSync)(packageJsonPath)) try {
|
|
3507
3180
|
const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
|
|
3508
3181
|
if (JSON.parse(content).workspaces) return currentDirectory;
|
|
3509
3182
|
} catch {}
|
|
3510
|
-
for (const lockfile of LOCKFILE_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, lockfile))) return currentDirectory;
|
|
3183
|
+
for (const lockfile of require_constants.LOCKFILE_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, lockfile))) return currentDirectory;
|
|
3511
3184
|
return;
|
|
3512
3185
|
}
|
|
3513
|
-
for (const marker of MONOREPO_ROOT_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, marker))) return currentDirectory;
|
|
3186
|
+
for (const marker of require_constants.MONOREPO_ROOT_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, marker))) return currentDirectory;
|
|
3514
3187
|
const packageJsonPath = (0, node_path.join)(currentDirectory, "package.json");
|
|
3515
3188
|
if ((0, node_fs.existsSync)(packageJsonPath)) try {
|
|
3516
3189
|
const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
|
|
@@ -3518,7 +3191,7 @@ const findMonorepoRoot = (rootDir) => {
|
|
|
3518
3191
|
} catch {
|
|
3519
3192
|
continue;
|
|
3520
3193
|
}
|
|
3521
|
-
for (const lockfile of LOCKFILE_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, lockfile))) return currentDirectory;
|
|
3194
|
+
for (const lockfile of require_constants.LOCKFILE_MARKERS) if ((0, node_fs.existsSync)((0, node_path.join)(currentDirectory, lockfile))) return currentDirectory;
|
|
3522
3195
|
}
|
|
3523
3196
|
};
|
|
3524
3197
|
|
|
@@ -3742,9 +3415,9 @@ const isPlatformBuiltinOrVirtualSpecifier = (specifier) => {
|
|
|
3742
3415
|
if (specifier === "std" || specifier.startsWith("std/")) return true;
|
|
3743
3416
|
const stripped = specifier.startsWith("node:") ? specifier.slice(5) : specifier;
|
|
3744
3417
|
const slashIndex = stripped.indexOf("/");
|
|
3745
|
-
if (slashIndex === -1) return BUILTIN_MODULES.has(stripped);
|
|
3418
|
+
if (slashIndex === -1) return require_constants.BUILTIN_MODULES.has(stripped);
|
|
3746
3419
|
const baseName = stripped.slice(0, slashIndex);
|
|
3747
|
-
if (!BUILTIN_MODULES.has(baseName)) return false;
|
|
3420
|
+
if (!require_constants.BUILTIN_MODULES.has(baseName)) return false;
|
|
3748
3421
|
return BUILTIN_SUBPATH_NODE_MODULES.has(baseName);
|
|
3749
3422
|
};
|
|
3750
3423
|
|
|
@@ -3798,7 +3471,7 @@ const existsAsFile = (filePath) => {
|
|
|
3798
3471
|
};
|
|
3799
3472
|
const trySourceFallback = (resolvedPath) => {
|
|
3800
3473
|
const segments = resolvedPath.split(node_path.sep);
|
|
3801
|
-
const isOutputDirectory = (segment) => OUTPUT_DIRECTORIES.some((outputDirectory) => segment === outputDirectory || segment.startsWith(`${outputDirectory}-`));
|
|
3474
|
+
const isOutputDirectory = (segment) => require_constants.OUTPUT_DIRECTORIES.some((outputDirectory) => segment === outputDirectory || segment.startsWith(`${outputDirectory}-`));
|
|
3802
3475
|
let lastOutputPosition = -1;
|
|
3803
3476
|
for (let index = segments.length - 1; index >= 0; index--) if (isOutputDirectory(segments[index])) {
|
|
3804
3477
|
lastOutputPosition = index;
|
|
@@ -3812,18 +3485,18 @@ const trySourceFallback = (resolvedPath) => {
|
|
|
3812
3485
|
if (!suffix) return void 0;
|
|
3813
3486
|
const fileExtension = (0, node_path.extname)((0, node_path.basename)(suffix));
|
|
3814
3487
|
const stemmedSuffix = fileExtension ? suffix.slice(0, suffix.length - fileExtension.length) : suffix;
|
|
3815
|
-
for (const sourceExtension of SOURCE_EXTENSIONS
|
|
3488
|
+
for (const sourceExtension of require_constants.SOURCE_EXTENSIONS) {
|
|
3816
3489
|
const sourceCandidate = (0, node_path.join)(prefix, "src", `${stemmedSuffix}.${sourceExtension}`);
|
|
3817
3490
|
if (existsAsFile(sourceCandidate)) return sourceCandidate;
|
|
3818
3491
|
}
|
|
3819
3492
|
};
|
|
3820
3493
|
const resolvePathWithExtensionFallback = (candidatePath) => {
|
|
3821
3494
|
if (existsAsFile(candidatePath)) return candidatePath;
|
|
3822
|
-
for (const extension of RESOLVER_EXTENSIONS) {
|
|
3495
|
+
for (const extension of require_constants.RESOLVER_EXTENSIONS) {
|
|
3823
3496
|
const withExtension = candidatePath + extension;
|
|
3824
3497
|
if (existsAsFile(withExtension)) return withExtension;
|
|
3825
3498
|
}
|
|
3826
|
-
for (const extension of RESOLVER_EXTENSIONS) {
|
|
3499
|
+
for (const extension of require_constants.RESOLVER_EXTENSIONS) {
|
|
3827
3500
|
const indexCandidate = (0, node_path.join)(candidatePath, `index${extension}`);
|
|
3828
3501
|
if (existsAsFile(indexCandidate)) return indexCandidate;
|
|
3829
3502
|
}
|
|
@@ -3831,13 +3504,13 @@ const resolvePathWithExtensionFallback = (candidatePath) => {
|
|
|
3831
3504
|
};
|
|
3832
3505
|
const resolveAliasTarget = (target) => {
|
|
3833
3506
|
if (existsAsFile(target)) return target;
|
|
3834
|
-
for (const extension of RESOLVER_EXTENSIONS) if (cachedExistsSync(target + extension)) return target + extension;
|
|
3507
|
+
for (const extension of require_constants.RESOLVER_EXTENSIONS) if (cachedExistsSync(target + extension)) return target + extension;
|
|
3835
3508
|
const sourceTarget = target.replace(/\.[cm]?js$/, "");
|
|
3836
3509
|
if (sourceTarget !== target) {
|
|
3837
|
-
for (const extension of RESOLVER_EXTENSIONS) if (cachedExistsSync(sourceTarget + extension)) return sourceTarget + extension;
|
|
3510
|
+
for (const extension of require_constants.RESOLVER_EXTENSIONS) if (cachedExistsSync(sourceTarget + extension)) return sourceTarget + extension;
|
|
3838
3511
|
}
|
|
3839
3512
|
const indexCandidate = (0, node_path.join)(target, "index");
|
|
3840
|
-
for (const extension of RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + extension)) return indexCandidate + extension;
|
|
3513
|
+
for (const extension of require_constants.RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + extension)) return indexCandidate + extension;
|
|
3841
3514
|
};
|
|
3842
3515
|
const pathMappingSpecificity = (mapping) => mapping.isWildcard ? mapping.prefix.length + mapping.suffix.length : Number.MAX_SAFE_INTEGER;
|
|
3843
3516
|
const compilePathMappings = (entries) => {
|
|
@@ -3880,7 +3553,7 @@ const COMMON_RESOLVER_OPTIONS = {
|
|
|
3880
3553
|
"node",
|
|
3881
3554
|
"default"
|
|
3882
3555
|
],
|
|
3883
|
-
extensions: RESOLVER_EXTENSIONS,
|
|
3556
|
+
extensions: require_constants.RESOLVER_EXTENSIONS,
|
|
3884
3557
|
mainFields: [
|
|
3885
3558
|
"module",
|
|
3886
3559
|
"main",
|
|
@@ -4176,7 +3849,7 @@ const resolveWorkspaceSubpath = (workspaceDirectory, subpath) => {
|
|
|
4176
3849
|
if (subpath && !resolvedEntryPath) {
|
|
4177
3850
|
const subpathCandidates = [(0, node_path.resolve)(workspaceDirectory, subpath), (0, node_path.resolve)(workspaceDirectory, "src", subpath)];
|
|
4178
3851
|
for (const directSubpath of subpathCandidates) {
|
|
4179
|
-
for (const candidateExtension of RESOLVER_EXTENSIONS) {
|
|
3852
|
+
for (const candidateExtension of require_constants.RESOLVER_EXTENSIONS) {
|
|
4180
3853
|
const candidate = directSubpath + candidateExtension;
|
|
4181
3854
|
if (cachedExistsSync(candidate)) {
|
|
4182
3855
|
resolvedEntryPath = candidate;
|
|
@@ -4184,7 +3857,7 @@ const resolveWorkspaceSubpath = (workspaceDirectory, subpath) => {
|
|
|
4184
3857
|
}
|
|
4185
3858
|
}
|
|
4186
3859
|
if (resolvedEntryPath) break;
|
|
4187
|
-
for (const candidateExtension of RESOLVER_EXTENSIONS) {
|
|
3860
|
+
for (const candidateExtension of require_constants.RESOLVER_EXTENSIONS) {
|
|
4188
3861
|
const indexCandidate = (0, node_path.join)(directSubpath, `index${candidateExtension}`);
|
|
4189
3862
|
if (cachedExistsSync(indexCandidate)) {
|
|
4190
3863
|
resolvedEntryPath = indexCandidate;
|
|
@@ -4214,7 +3887,7 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
4214
3887
|
const resolverCache = /* @__PURE__ */ new Map();
|
|
4215
3888
|
const resolveResultCache = /* @__PURE__ */ new Map();
|
|
4216
3889
|
const failedTsconfigPaths = /* @__PURE__ */ new Set();
|
|
4217
|
-
const resolverExtensions = options.hasReactNative ? [...REACT_NATIVE_PLATFORM_EXTENSIONS, ...RESOLVER_EXTENSIONS] : RESOLVER_EXTENSIONS;
|
|
3890
|
+
const resolverExtensions = options.hasReactNative ? [...require_constants.REACT_NATIVE_PLATFORM_EXTENSIONS, ...require_constants.RESOLVER_EXTENSIONS] : require_constants.RESOLVER_EXTENSIONS;
|
|
4218
3891
|
const resolverOptions = {
|
|
4219
3892
|
...COMMON_RESOLVER_OPTIONS,
|
|
4220
3893
|
extensions: resolverExtensions
|
|
@@ -4603,7 +4276,7 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
4603
4276
|
const baseUrlDirectory = getBaseUrlDirectory(tsconfigFile);
|
|
4604
4277
|
if (baseUrlDirectory) {
|
|
4605
4278
|
const baseUrlCandidate = (0, node_path.resolve)(baseUrlDirectory, cleanedSpecifier);
|
|
4606
|
-
for (const candidateExtension of RESOLVER_EXTENSIONS) {
|
|
4279
|
+
for (const candidateExtension of require_constants.RESOLVER_EXTENSIONS) {
|
|
4607
4280
|
const fullCandidate = baseUrlCandidate + candidateExtension;
|
|
4608
4281
|
if (cachedExistsSync(fullCandidate)) {
|
|
4609
4282
|
const resolvedResult = {
|
|
@@ -4616,7 +4289,7 @@ const createResolver = (config, workspacePackages = [], options = {}) => {
|
|
|
4616
4289
|
}
|
|
4617
4290
|
}
|
|
4618
4291
|
const indexCandidate = (0, node_path.join)(baseUrlCandidate, "index");
|
|
4619
|
-
for (const candidateExtension of RESOLVER_EXTENSIONS) {
|
|
4292
|
+
for (const candidateExtension of require_constants.RESOLVER_EXTENSIONS) {
|
|
4620
4293
|
const fullCandidate = indexCandidate + candidateExtension;
|
|
4621
4294
|
if (cachedExistsSync(fullCandidate)) {
|
|
4622
4295
|
const resolvedResult = {
|
|
@@ -4792,9 +4465,9 @@ const extractSiblingWorkspaceImportEntries = (absoluteRoot) => {
|
|
|
4792
4465
|
//#endregion
|
|
4793
4466
|
//#region src/collect/entries.ts
|
|
4794
4467
|
const collectSourceFiles = async (config) => {
|
|
4795
|
-
const extensions = config.includeExtensions.length > 0 ? config.includeExtensions : DEFAULT_EXTENSIONS;
|
|
4468
|
+
const extensions = config.includeExtensions.length > 0 ? config.includeExtensions : require_constants.DEFAULT_EXTENSIONS;
|
|
4796
4469
|
const extensionGlob = extensions.length === 1 ? `**/*${extensions[0]}` : `**/*{${extensions.join(",")}}`;
|
|
4797
|
-
const ignorePatterns = [...DEFAULT_EXCLUSIONS, ...config.ignorePatterns].map(toPosixPath);
|
|
4470
|
+
const ignorePatterns = [...require_constants.DEFAULT_EXCLUSIONS, ...config.ignorePatterns].map(toPosixPath);
|
|
4798
4471
|
const absoluteRoot = (0, node_path.resolve)(config.rootDir);
|
|
4799
4472
|
const mainFiles = await (0, fast_glob.default)(extensionGlob, {
|
|
4800
4473
|
cwd: absoluteRoot,
|
|
@@ -4803,7 +4476,7 @@ const collectSourceFiles = async (config) => {
|
|
|
4803
4476
|
dot: false,
|
|
4804
4477
|
onlyFiles: true
|
|
4805
4478
|
});
|
|
4806
|
-
const allowedHiddenGlobs = HIDDEN_DIRECTORY_ALLOWLIST.flatMap((directory) => [`${directory}/**/*{${extensions.join(",")}}`, `**/${directory}/**/*{${extensions.join(",")}}`]);
|
|
4479
|
+
const allowedHiddenGlobs = require_constants.HIDDEN_DIRECTORY_ALLOWLIST.flatMap((directory) => [`${directory}/**/*{${extensions.join(",")}}`, `**/${directory}/**/*{${extensions.join(",")}}`]);
|
|
4807
4480
|
const hiddenFiles = allowedHiddenGlobs.length > 0 ? await (0, fast_glob.default)(allowedHiddenGlobs, {
|
|
4808
4481
|
cwd: absoluteRoot,
|
|
4809
4482
|
absolute: true,
|
|
@@ -5374,7 +5047,7 @@ const extractScriptEntries = (directory) => {
|
|
|
5374
5047
|
const scripts = JSON.parse(content).scripts;
|
|
5375
5048
|
if (scripts && typeof scripts === "object") for (const scriptCommand of Object.values(scripts)) {
|
|
5376
5049
|
if (typeof scriptCommand !== "string") continue;
|
|
5377
|
-
const match = scriptCommand.match(SCRIPT_FILE_PATTERN);
|
|
5050
|
+
const match = scriptCommand.match(require_constants.SCRIPT_FILE_PATTERN);
|
|
5378
5051
|
if (match?.[1]) {
|
|
5379
5052
|
const scriptFilePath = (0, node_path.resolve)(directory, match[1]);
|
|
5380
5053
|
if ((0, node_fs.existsSync)(scriptFilePath)) entries.push(scriptFilePath);
|
|
@@ -5383,14 +5056,14 @@ const extractScriptEntries = (directory) => {
|
|
|
5383
5056
|
if (sourcePath) entries.push(sourcePath);
|
|
5384
5057
|
}
|
|
5385
5058
|
} else {
|
|
5386
|
-
const extensionlessMatch = scriptCommand.match(SCRIPT_EXTENSIONLESS_FILE_PATTERN);
|
|
5059
|
+
const extensionlessMatch = scriptCommand.match(require_constants.SCRIPT_EXTENSIONLESS_FILE_PATTERN);
|
|
5387
5060
|
if (extensionlessMatch?.[1]) {
|
|
5388
5061
|
const extensionlessPath = extensionlessMatch[1];
|
|
5389
5062
|
const resolved = resolveExtensionlessScriptPath((0, node_path.resolve)(directory, extensionlessPath));
|
|
5390
5063
|
if (resolved) entries.push(resolved);
|
|
5391
5064
|
}
|
|
5392
5065
|
}
|
|
5393
|
-
const configMatch = scriptCommand.match(SCRIPT_CONFIG_FILE_PATTERN);
|
|
5066
|
+
const configMatch = scriptCommand.match(require_constants.SCRIPT_CONFIG_FILE_PATTERN);
|
|
5394
5067
|
if (configMatch?.[1]) {
|
|
5395
5068
|
const configFilePath = (0, node_path.resolve)(directory, configMatch[1]);
|
|
5396
5069
|
if ((0, node_fs.existsSync)(configFilePath)) entries.push(configFilePath);
|
|
@@ -5402,7 +5075,7 @@ const extractScriptEntries = (directory) => {
|
|
|
5402
5075
|
entries.push(...extractScriptFileArguments(scriptCommand, directory));
|
|
5403
5076
|
}
|
|
5404
5077
|
} catch {}
|
|
5405
|
-
const scriptDirectoryFiles = fast_glob.default.sync(SCRIPT_ENTRY_PATTERNS, {
|
|
5078
|
+
const scriptDirectoryFiles = fast_glob.default.sync(require_constants.SCRIPT_ENTRY_PATTERNS, {
|
|
5406
5079
|
cwd: directory,
|
|
5407
5080
|
absolute: true,
|
|
5408
5081
|
onlyFiles: true,
|
|
@@ -5458,12 +5131,12 @@ const extractCiWorkflowEntries = (rootDir) => {
|
|
|
5458
5131
|
for (const workflowFile of workflowFiles) try {
|
|
5459
5132
|
const runCommands = extractCiRunCommands((0, node_fs.readFileSync)(workflowFile, "utf-8"));
|
|
5460
5133
|
for (const command of runCommands) {
|
|
5461
|
-
const scriptMatch = command.match(SCRIPT_FILE_PATTERN);
|
|
5134
|
+
const scriptMatch = command.match(require_constants.SCRIPT_FILE_PATTERN);
|
|
5462
5135
|
if (scriptMatch?.[1]) {
|
|
5463
5136
|
const scriptFilePath = (0, node_path.resolve)(rootDir, scriptMatch[1]);
|
|
5464
5137
|
if ((0, node_fs.existsSync)(scriptFilePath)) entries.push(scriptFilePath);
|
|
5465
5138
|
}
|
|
5466
|
-
const configMatch = command.match(SCRIPT_CONFIG_FILE_PATTERN);
|
|
5139
|
+
const configMatch = command.match(require_constants.SCRIPT_CONFIG_FILE_PATTERN);
|
|
5467
5140
|
if (configMatch?.[1]) {
|
|
5468
5141
|
const configFilePath = (0, node_path.resolve)(rootDir, configMatch[1]);
|
|
5469
5142
|
if ((0, node_fs.existsSync)(configFilePath)) entries.push(configFilePath);
|
|
@@ -6109,7 +5782,7 @@ const extractTestSetupFiles = (directory) => {
|
|
|
6109
5782
|
} catch {}
|
|
6110
5783
|
return entries;
|
|
6111
5784
|
};
|
|
6112
|
-
const IMPORTABLE_EXTENSION_SET = new Set(SOURCE_EXTENSIONS
|
|
5785
|
+
const IMPORTABLE_EXTENSION_SET = new Set(require_constants.SOURCE_EXTENSIONS.map((extension) => `.${extension}`));
|
|
6113
5786
|
const isImportableSourceFile = (filePath) => IMPORTABLE_EXTENSION_SET.has(filePath.slice(filePath.lastIndexOf(".")));
|
|
6114
5787
|
const expandWildcardExportPattern = (pattern, rootDir) => {
|
|
6115
5788
|
const normalized = pattern.startsWith("./") ? pattern.slice(2) : pattern;
|
|
@@ -7256,6 +6929,18 @@ const resolveAvailableConcurrency = () => {
|
|
|
7256
6929
|
return clampParseConcurrency(available);
|
|
7257
6930
|
};
|
|
7258
6931
|
|
|
6932
|
+
//#endregion
|
|
6933
|
+
//#region src/collect/launch-worker.ts
|
|
6934
|
+
/**
|
|
6935
|
+
* Launches a worker module that sits next to `fromModuleUrl`: the TypeScript
|
|
6936
|
+
* source (via tsx) when the caller itself runs from source — tests and direct
|
|
6937
|
+
* `tsx` execution — and the built `.mjs` sibling when running from dist.
|
|
6938
|
+
*/
|
|
6939
|
+
const launchSiblingWorker = (fromModuleUrl, workerBaseName) => {
|
|
6940
|
+
const isTypeScriptSource = fromModuleUrl.endsWith(".ts");
|
|
6941
|
+
return new node_worker_threads.Worker((0, node_url.fileURLToPath)(new URL(isTypeScriptSource ? `./${workerBaseName}.ts` : `./${workerBaseName}.mjs`, fromModuleUrl)), { ...isTypeScriptSource ? { execArgv: ["--import", "tsx"] } : {} });
|
|
6942
|
+
};
|
|
6943
|
+
|
|
7259
6944
|
//#endregion
|
|
7260
6945
|
//#region src/collect/parallel-parse.ts
|
|
7261
6946
|
const deserializeErrors = (serializedErrors) => serializedErrors.map((errorJson) => new DeslopError({
|
|
@@ -7282,14 +6967,6 @@ const deserializeParsedSource = (serialized) => ({
|
|
|
7282
6967
|
duplicateConstantCandidates: serialized.duplicateConstantCandidates,
|
|
7283
6968
|
errors: deserializeErrors(serialized.errors)
|
|
7284
6969
|
});
|
|
7285
|
-
const resolveWorkerPath = () => {
|
|
7286
|
-
const currentUrl = require("url").pathToFileURL(__filename).href;
|
|
7287
|
-
if (currentUrl.endsWith(".ts")) return (0, node_url.fileURLToPath)(new URL("./parse-worker.ts", currentUrl));
|
|
7288
|
-
return (0, node_url.fileURLToPath)(new URL("./parse-worker.mjs", currentUrl));
|
|
7289
|
-
};
|
|
7290
|
-
const createWorker = (workerPath) => {
|
|
7291
|
-
return new node_worker_threads.Worker(workerPath, { ...workerPath.endsWith(".ts") ? { execArgv: ["--import", "tsx"] } : {} });
|
|
7292
|
-
};
|
|
7293
6970
|
const waitForReady = (worker) => new Promise((resolve, reject) => {
|
|
7294
6971
|
const onMessage = (message) => {
|
|
7295
6972
|
if (message.type === "ready") {
|
|
@@ -7307,11 +6984,10 @@ const waitForReady = (worker) => new Promise((resolve, reject) => {
|
|
|
7307
6984
|
worker.on("error", onError);
|
|
7308
6985
|
});
|
|
7309
6986
|
const parseFilesWithWorkerPool = async (files, workerCount) => {
|
|
7310
|
-
const workerPath = resolveWorkerPath();
|
|
7311
6987
|
const results = new Array(files.length);
|
|
7312
6988
|
const workers = [];
|
|
7313
6989
|
try {
|
|
7314
|
-
for (let workerIndex = 0; workerIndex < workerCount; workerIndex++) workers.push(
|
|
6990
|
+
for (let workerIndex = 0; workerIndex < workerCount; workerIndex++) workers.push(launchSiblingWorker(require("url").pathToFileURL(__filename).href, "parse-worker"));
|
|
7315
6991
|
await Promise.all(workers.map(waitForReady));
|
|
7316
6992
|
} catch {
|
|
7317
6993
|
for (const worker of workers) worker.terminate();
|
|
@@ -7397,7 +7073,7 @@ const isConfigFile = (filePath) => {
|
|
|
7397
7073
|
if (fileName.startsWith(".") && !fileName.startsWith("..")) {
|
|
7398
7074
|
if (fileName.toLowerCase().includes("rc.")) return true;
|
|
7399
7075
|
}
|
|
7400
|
-
return KNOWN_CONFIG_PREFIXES.some((prefix) => fileName.startsWith(prefix));
|
|
7076
|
+
return require_constants.KNOWN_CONFIG_PREFIXES.some((prefix) => fileName.startsWith(prefix));
|
|
7401
7077
|
};
|
|
7402
7078
|
|
|
7403
7079
|
//#endregion
|
|
@@ -7524,7 +7200,7 @@ const PLATFORM_DIRECTORY_NAMES = new Set([
|
|
|
7524
7200
|
"macos"
|
|
7525
7201
|
]);
|
|
7526
7202
|
const stripPlatformSuffix = (filePath) => {
|
|
7527
|
-
for (const suffix of PLATFORM_SUFFIXES) {
|
|
7203
|
+
for (const suffix of require_constants.PLATFORM_SUFFIXES) {
|
|
7528
7204
|
const extensionIndex = filePath.lastIndexOf(".");
|
|
7529
7205
|
if (extensionIndex === -1) continue;
|
|
7530
7206
|
const withoutExtension = filePath.slice(0, extensionIndex);
|
|
@@ -7831,10 +7507,16 @@ const detectDeadExports = (graph, config) => {
|
|
|
7831
7507
|
const buildUsageMap = (graph) => {
|
|
7832
7508
|
const usedExportKeys = /* @__PURE__ */ new Set();
|
|
7833
7509
|
const sourceToTargetMap = buildSourceToTargetsMap(graph);
|
|
7510
|
+
const reExportEdgesBySource = /* @__PURE__ */ new Map();
|
|
7511
|
+
for (const edge of graph.edges) {
|
|
7512
|
+
if (!edge.isReExportEdge) continue;
|
|
7513
|
+
const existingEdges = reExportEdgesBySource.get(edge.source);
|
|
7514
|
+
if (existingEdges) existingEdges.push(edge);
|
|
7515
|
+
else reExportEdgesBySource.set(edge.source, [edge]);
|
|
7516
|
+
}
|
|
7834
7517
|
for (const module of graph.modules) {
|
|
7835
7518
|
if (!module.isEntryPoint) continue;
|
|
7836
|
-
for (const edge of
|
|
7837
|
-
if (edge.source !== module.fileId.index || !edge.isReExportEdge) continue;
|
|
7519
|
+
for (const edge of reExportEdgesBySource.get(module.fileId.index) ?? []) {
|
|
7838
7520
|
const targetModule = graph.modules[edge.target];
|
|
7839
7521
|
if (!targetModule) continue;
|
|
7840
7522
|
if (edge.reExportedNames.includes("*")) markAllExportsUsedRecursive(targetModule, graph, sourceToTargetMap, usedExportKeys, /* @__PURE__ */ new Set());
|
|
@@ -8081,12 +7763,29 @@ const matchesPackageTokenReference = (command, packageName) => {
|
|
|
8081
7763
|
|
|
8082
7764
|
//#endregion
|
|
8083
7765
|
//#region src/report/packages.ts
|
|
8084
|
-
const
|
|
7766
|
+
const globPackageFiles = (cwd, patterns, options, summaryCache) => summaryCache?.matchWalkedFiles({
|
|
7767
|
+
cwd,
|
|
7768
|
+
patterns,
|
|
7769
|
+
...options
|
|
7770
|
+
}) ?? fast_glob.default.sync([...patterns], {
|
|
7771
|
+
cwd,
|
|
7772
|
+
absolute: true,
|
|
7773
|
+
onlyFiles: true,
|
|
7774
|
+
ignore: [...options.ignore],
|
|
7775
|
+
deep: options.deep,
|
|
7776
|
+
...options.dot === void 0 ? {} : { dot: options.dot }
|
|
7777
|
+
});
|
|
7778
|
+
const containsPackageName = (content, packageName) => content.includes(packageName);
|
|
7779
|
+
const matchPackageNamesInFile = (filePath, kind, names, matcher, summaryCache) => {
|
|
7780
|
+
if (summaryCache !== void 0) return summaryCache.matchPackageNames(filePath, kind, names, matcher);
|
|
7781
|
+
const content = (0, node_fs.readFileSync)(filePath, "utf-8");
|
|
7782
|
+
const matchedNames = [];
|
|
7783
|
+
for (const packageName of names) if (matcher(content, packageName)) matchedNames.push(packageName);
|
|
7784
|
+
return matchedNames;
|
|
7785
|
+
};
|
|
7786
|
+
const discoverAllPackageJsonPaths = (rootDir, summaryCache) => {
|
|
8085
7787
|
const paths = [(0, node_path.join)(rootDir, "package.json")];
|
|
8086
|
-
const workspacePackageJsons =
|
|
8087
|
-
cwd: rootDir,
|
|
8088
|
-
absolute: true,
|
|
8089
|
-
onlyFiles: true,
|
|
7788
|
+
const workspacePackageJsons = globPackageFiles(rootDir, ["**/package.json"], {
|
|
8090
7789
|
ignore: [
|
|
8091
7790
|
"**/node_modules/**",
|
|
8092
7791
|
"**/dist/**",
|
|
@@ -8094,11 +7793,11 @@ const discoverAllPackageJsonPaths = (rootDir) => {
|
|
|
8094
7793
|
"**/.git/**"
|
|
8095
7794
|
],
|
|
8096
7795
|
deep: 5
|
|
8097
|
-
});
|
|
7796
|
+
}, summaryCache);
|
|
8098
7797
|
for (const workspacePath of workspacePackageJsons) if (workspacePath !== paths[0] && !paths.includes(workspacePath)) paths.push(workspacePath);
|
|
8099
7798
|
return paths;
|
|
8100
7799
|
};
|
|
8101
|
-
const detectStalePackages = (graph, config) => {
|
|
7800
|
+
const detectStalePackages = (graph, config, summaryCache) => {
|
|
8102
7801
|
const packageJsonPath = (0, node_path.resolve)(config.rootDir, "package.json");
|
|
8103
7802
|
let packageJson;
|
|
8104
7803
|
try {
|
|
@@ -8116,7 +7815,7 @@ const detectStalePackages = (graph, config) => {
|
|
|
8116
7815
|
const usedPackageNames = collectUsedPackages(graph);
|
|
8117
7816
|
const monorepoRoot = findMonorepoRoot(config.rootDir);
|
|
8118
7817
|
const nodeModulesSearchRoots = monorepoRoot && monorepoRoot !== config.rootDir ? [config.rootDir, monorepoRoot] : [config.rootDir];
|
|
8119
|
-
const allPackageJsonPaths = discoverAllPackageJsonPaths(config.rootDir);
|
|
7818
|
+
const allPackageJsonPaths = discoverAllPackageJsonPaths(config.rootDir, summaryCache);
|
|
8120
7819
|
if (monorepoRoot) {
|
|
8121
7820
|
const monorepoPackageJson = (0, node_path.join)(monorepoRoot, "package.json");
|
|
8122
7821
|
if (!allPackageJsonPaths.includes(monorepoPackageJson) && (0, node_fs.existsSync)(monorepoPackageJson)) allPackageJsonPaths.push(monorepoPackageJson);
|
|
@@ -8129,13 +7828,13 @@ const detectStalePackages = (graph, config) => {
|
|
|
8129
7828
|
const packageJsonConfigReferenced = collectPackageJsonConfigReferences(workspacePackageJsonPath, declaredNames);
|
|
8130
7829
|
for (const packageName of packageJsonConfigReferenced) usedPackageNames.add(packageName);
|
|
8131
7830
|
}
|
|
8132
|
-
const nxProjectReferenced = collectNxProjectJsonReferences(config.rootDir, declaredNames, binToPackage);
|
|
7831
|
+
const nxProjectReferenced = collectNxProjectJsonReferences(config.rootDir, declaredNames, binToPackage, summaryCache);
|
|
8133
7832
|
for (const packageName of nxProjectReferenced) usedPackageNames.add(packageName);
|
|
8134
7833
|
const configSearchRoots = monorepoRoot && monorepoRoot !== config.rootDir ? [config.rootDir, monorepoRoot] : [config.rootDir];
|
|
8135
7834
|
for (const configSearchRoot of configSearchRoots) {
|
|
8136
|
-
const configReferenced = collectConfigReferencedPackages(configSearchRoot, graph, declaredNames);
|
|
7835
|
+
const configReferenced = collectConfigReferencedPackages(configSearchRoot, graph, declaredNames, summaryCache);
|
|
8137
7836
|
for (const packageName of configReferenced) usedPackageNames.add(packageName);
|
|
8138
|
-
const tsconfigReferenced = collectTsconfigReferencedPackages(configSearchRoot);
|
|
7837
|
+
const tsconfigReferenced = collectTsconfigReferencedPackages(configSearchRoot, summaryCache);
|
|
8139
7838
|
for (const packageName of tsconfigReferenced) usedPackageNames.add(packageName);
|
|
8140
7839
|
const { packageNames: expoPluginPackageNames } = extractExpoConfigPluginEntries(configSearchRoot, {
|
|
8141
7840
|
...dependencies,
|
|
@@ -8187,7 +7886,7 @@ const detectStalePackages = (graph, config) => {
|
|
|
8187
7886
|
candidateUnused.add(dependencyName);
|
|
8188
7887
|
}
|
|
8189
7888
|
if (candidateUnused.size > 0) {
|
|
8190
|
-
const sourceFileRescued = scanSourceFilesForPackageImports(config.rootDir, candidateUnused);
|
|
7889
|
+
const sourceFileRescued = scanSourceFilesForPackageImports(config.rootDir, candidateUnused, summaryCache);
|
|
8191
7890
|
for (const packageName of sourceFileRescued) {
|
|
8192
7891
|
usedPackageNames.add(packageName);
|
|
8193
7892
|
candidateUnused.delete(packageName);
|
|
@@ -8355,35 +8054,26 @@ const CONFIG_FILE_GLOBS = [
|
|
|
8355
8054
|
".dumirc.js",
|
|
8356
8055
|
"dumi.config.{ts,js}"
|
|
8357
8056
|
];
|
|
8358
|
-
const collectConfigReferencedPackages = (rootDir, graph, declaredNames) => {
|
|
8057
|
+
const collectConfigReferencedPackages = (rootDir, graph, declaredNames, summaryCache) => {
|
|
8359
8058
|
const referenced = /* @__PURE__ */ new Set();
|
|
8360
|
-
|
|
8361
|
-
if (!module.isConfigFile) continue;
|
|
8059
|
+
const addMatchesFromFile = (filePath, kind, matcher) => {
|
|
8362
8060
|
try {
|
|
8363
|
-
const
|
|
8364
|
-
for (const packageName of declaredNames) if (content.includes(packageName)) referenced.add(packageName);
|
|
8061
|
+
for (const packageName of matchPackageNamesInFile(filePath, kind, declaredNames, matcher, summaryCache)) referenced.add(packageName);
|
|
8365
8062
|
} catch {
|
|
8366
|
-
|
|
8063
|
+
return;
|
|
8367
8064
|
}
|
|
8065
|
+
};
|
|
8066
|
+
for (const module of graph.modules) {
|
|
8067
|
+
if (!module.isConfigFile) continue;
|
|
8068
|
+
addMatchesFromFile(module.fileId.path, "substring", containsPackageName);
|
|
8368
8069
|
}
|
|
8369
|
-
const configFiles =
|
|
8370
|
-
cwd: rootDir,
|
|
8371
|
-
absolute: true,
|
|
8372
|
-
onlyFiles: true,
|
|
8070
|
+
const configFiles = globPackageFiles(rootDir, CONFIG_FILE_GLOBS, {
|
|
8373
8071
|
ignore: ["**/node_modules/**"],
|
|
8374
8072
|
dot: true,
|
|
8375
8073
|
deep: 3
|
|
8376
|
-
});
|
|
8377
|
-
for (const configPath of configFiles)
|
|
8378
|
-
|
|
8379
|
-
for (const packageName of declaredNames) if (content.includes(packageName)) referenced.add(packageName);
|
|
8380
|
-
} catch {
|
|
8381
|
-
continue;
|
|
8382
|
-
}
|
|
8383
|
-
const documentationFiles = fast_glob.default.sync(["**/*.{mdx,md}"], {
|
|
8384
|
-
cwd: rootDir,
|
|
8385
|
-
absolute: true,
|
|
8386
|
-
onlyFiles: true,
|
|
8074
|
+
}, summaryCache);
|
|
8075
|
+
for (const configPath of configFiles) addMatchesFromFile(configPath, "substring", containsPackageName);
|
|
8076
|
+
const documentationFiles = globPackageFiles(rootDir, ["**/*.{mdx,md}"], {
|
|
8387
8077
|
ignore: [
|
|
8388
8078
|
"**/node_modules/**",
|
|
8389
8079
|
"**/dist/**",
|
|
@@ -8391,13 +8081,8 @@ const collectConfigReferencedPackages = (rootDir, graph, declaredNames) => {
|
|
|
8391
8081
|
"**/CHANGELOG.md"
|
|
8392
8082
|
],
|
|
8393
8083
|
deep: 6
|
|
8394
|
-
});
|
|
8395
|
-
for (const documentationPath of documentationFiles)
|
|
8396
|
-
const content = (0, node_fs.readFileSync)(documentationPath, "utf-8");
|
|
8397
|
-
for (const packageName of declaredNames) if (matchesPackageImportReference(content, packageName)) referenced.add(packageName);
|
|
8398
|
-
} catch {
|
|
8399
|
-
continue;
|
|
8400
|
-
}
|
|
8084
|
+
}, summaryCache);
|
|
8085
|
+
for (const documentationPath of documentationFiles) addMatchesFromFile(documentationPath, "importReference", matchesPackageImportReference);
|
|
8401
8086
|
return referenced;
|
|
8402
8087
|
};
|
|
8403
8088
|
const PACKAGE_JSON_CONFIG_SECTIONS = [
|
|
@@ -8468,19 +8153,16 @@ const collectPackageJsonConfigReferences = (packageJsonPath, declaredNames) => {
|
|
|
8468
8153
|
}
|
|
8469
8154
|
return referenced;
|
|
8470
8155
|
};
|
|
8471
|
-
const collectNxProjectJsonReferences = (rootDir, declaredNames, binToPackage) => {
|
|
8156
|
+
const collectNxProjectJsonReferences = (rootDir, declaredNames, binToPackage, summaryCache) => {
|
|
8472
8157
|
const referenced = /* @__PURE__ */ new Set();
|
|
8473
|
-
const projectJsonPaths =
|
|
8474
|
-
cwd: rootDir,
|
|
8475
|
-
absolute: true,
|
|
8476
|
-
onlyFiles: true,
|
|
8158
|
+
const projectJsonPaths = globPackageFiles(rootDir, ["project.json", "**/project.json"], {
|
|
8477
8159
|
ignore: [
|
|
8478
8160
|
"**/node_modules/**",
|
|
8479
8161
|
"**/dist/**",
|
|
8480
8162
|
"**/build/**"
|
|
8481
8163
|
],
|
|
8482
8164
|
deep: 5
|
|
8483
|
-
});
|
|
8165
|
+
}, summaryCache);
|
|
8484
8166
|
for (const projectJsonPath of projectJsonPaths) try {
|
|
8485
8167
|
const content = (0, node_fs.readFileSync)(projectJsonPath, "utf-8");
|
|
8486
8168
|
const projectJson = JSON.parse(content);
|
|
@@ -8508,16 +8190,13 @@ const TSCONFIG_GLOBS = [
|
|
|
8508
8190
|
"**/tsconfig.json",
|
|
8509
8191
|
"**/tsconfig.*.json"
|
|
8510
8192
|
];
|
|
8511
|
-
const collectTsconfigReferencedPackages = (rootDir) => {
|
|
8193
|
+
const collectTsconfigReferencedPackages = (rootDir, summaryCache) => {
|
|
8512
8194
|
const referenced = /* @__PURE__ */ new Set();
|
|
8513
|
-
const tsconfigFiles =
|
|
8514
|
-
cwd: rootDir,
|
|
8515
|
-
absolute: true,
|
|
8516
|
-
onlyFiles: true,
|
|
8195
|
+
const tsconfigFiles = globPackageFiles(rootDir, TSCONFIG_GLOBS, {
|
|
8517
8196
|
ignore: ["**/node_modules/**"],
|
|
8518
8197
|
dot: false,
|
|
8519
8198
|
deep: 4
|
|
8520
|
-
});
|
|
8199
|
+
}, summaryCache);
|
|
8521
8200
|
for (const tsconfigPath of tsconfigFiles) try {
|
|
8522
8201
|
const cleaned = (0, node_fs.readFileSync)(tsconfigPath, "utf-8").replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
8523
8202
|
const parsed = JSON.parse(cleaned);
|
|
@@ -8563,16 +8242,22 @@ const SOURCE_FILE_IGNORES = [
|
|
|
8563
8242
|
"**/*.min.js",
|
|
8564
8243
|
"**/*.d.ts"
|
|
8565
8244
|
];
|
|
8566
|
-
const scanSourceFilesForPackageImports = (rootDir, candidatePackages) => {
|
|
8245
|
+
const scanSourceFilesForPackageImports = (rootDir, candidatePackages, summaryCache) => {
|
|
8567
8246
|
const found = /* @__PURE__ */ new Set();
|
|
8568
8247
|
if (candidatePackages.size === 0) return found;
|
|
8569
|
-
const sourceFiles =
|
|
8570
|
-
cwd: rootDir,
|
|
8571
|
-
absolute: true,
|
|
8572
|
-
onlyFiles: true,
|
|
8248
|
+
const sourceFiles = globPackageFiles(rootDir, SOURCE_FILE_GLOBS, {
|
|
8573
8249
|
ignore: SOURCE_FILE_IGNORES,
|
|
8574
8250
|
deep: 15
|
|
8575
|
-
});
|
|
8251
|
+
}, summaryCache);
|
|
8252
|
+
if (summaryCache !== void 0) {
|
|
8253
|
+
for (const filePath of sourceFiles) try {
|
|
8254
|
+
for (const packageName of summaryCache.matchPackageNames(filePath, "importReference", candidatePackages, matchesPackageImportReference)) found.add(packageName);
|
|
8255
|
+
} catch {
|
|
8256
|
+
continue;
|
|
8257
|
+
}
|
|
8258
|
+
for (const packageName of found) candidatePackages.delete(packageName);
|
|
8259
|
+
return found;
|
|
8260
|
+
}
|
|
8576
8261
|
for (const filePath of sourceFiles) {
|
|
8577
8262
|
if (candidatePackages.size === 0) break;
|
|
8578
8263
|
try {
|
|
@@ -8641,7 +8326,7 @@ const ALWAYS_USED_PREFIXES = [
|
|
|
8641
8326
|
];
|
|
8642
8327
|
const ALWAYS_USED_SUFFIXES = ["-loader"];
|
|
8643
8328
|
const isAlwaysConsideredUsed = (dependencyName) => {
|
|
8644
|
-
if (IMPLICIT_DEPENDENCIES.has(dependencyName)) return true;
|
|
8329
|
+
if (require_constants.IMPLICIT_DEPENDENCIES.has(dependencyName)) return true;
|
|
8645
8330
|
if (ALWAYS_USED_PREFIXES.some((prefix) => dependencyName.startsWith(prefix))) return true;
|
|
8646
8331
|
if (ALWAYS_USED_SUFFIXES.some((suffix) => dependencyName.endsWith(suffix))) return true;
|
|
8647
8332
|
return false;
|
|
@@ -8809,13 +8494,13 @@ const isPlatformSpecificModulePath = (modulePath) => {
|
|
|
8809
8494
|
const extensionIndex = modulePath.lastIndexOf(".");
|
|
8810
8495
|
if (extensionIndex === -1) return false;
|
|
8811
8496
|
const withoutExtension = modulePath.slice(0, extensionIndex);
|
|
8812
|
-
return PLATFORM_SUFFIXES.some((suffix) => withoutExtension.endsWith(suffix));
|
|
8497
|
+
return require_constants.PLATFORM_SUFFIXES.some((suffix) => withoutExtension.endsWith(suffix));
|
|
8813
8498
|
};
|
|
8814
8499
|
const platformStrippedBasePath = (modulePath) => {
|
|
8815
8500
|
const extensionIndex = modulePath.lastIndexOf(".");
|
|
8816
8501
|
if (extensionIndex === -1) return modulePath;
|
|
8817
8502
|
const withoutExtension = modulePath.slice(0, extensionIndex);
|
|
8818
|
-
for (const suffix of PLATFORM_SUFFIXES) if (withoutExtension.endsWith(suffix)) return withoutExtension.slice(0, -suffix.length) + modulePath.slice(extensionIndex);
|
|
8503
|
+
for (const suffix of require_constants.PLATFORM_SUFFIXES) if (withoutExtension.endsWith(suffix)) return withoutExtension.slice(0, -suffix.length) + modulePath.slice(extensionIndex);
|
|
8819
8504
|
return modulePath;
|
|
8820
8505
|
};
|
|
8821
8506
|
const buildPlatformSiblingGroupSizes = (graph) => {
|
|
@@ -9855,7 +9540,7 @@ const tokenizeAst = (program) => {
|
|
|
9855
9540
|
//#endregion
|
|
9856
9541
|
//#region src/duplicate-blocks/index.ts
|
|
9857
9542
|
const isBinaryFile = (sourceText) => {
|
|
9858
|
-
const sampleEnd = Math.min(sourceText.length, BINARY_DETECTION_SAMPLE_BYTES);
|
|
9543
|
+
const sampleEnd = Math.min(sourceText.length, require_constants.BINARY_DETECTION_SAMPLE_BYTES);
|
|
9859
9544
|
let nullByteCount = 0;
|
|
9860
9545
|
for (let charIndex = 0; charIndex < sampleEnd; charIndex++) if (sourceText.charCodeAt(charIndex) === 0) {
|
|
9861
9546
|
nullByteCount++;
|
|
@@ -11587,7 +11272,7 @@ const findNearestTsconfig = (rootDir, explicitPath) => {
|
|
|
11587
11272
|
if ((0, node_fs.existsSync)(absoluteExplicit)) return absoluteExplicit;
|
|
11588
11273
|
return;
|
|
11589
11274
|
}
|
|
11590
|
-
for (const candidateName of DEFAULT_SEMANTIC_TSCONFIG_NAMES) {
|
|
11275
|
+
for (const candidateName of require_constants.DEFAULT_SEMANTIC_TSCONFIG_NAMES) {
|
|
11591
11276
|
const candidatePath = (0, node_path.resolve)(rootDir, candidateName);
|
|
11592
11277
|
if ((0, node_fs.existsSync)(candidatePath)) return candidatePath;
|
|
11593
11278
|
}
|
|
@@ -11640,7 +11325,7 @@ const createSemanticContext = (rootDir, tsconfigPath) => {
|
|
|
11640
11325
|
}
|
|
11641
11326
|
if (parsedCommandLine.fileNames.length > 5e3) return {
|
|
11642
11327
|
ok: false,
|
|
11643
|
-
failure: failureFor("too-many-files", `Project has ${parsedCommandLine.fileNames.length} files, exceeds SEMANTIC_MAX_PROGRAM_FILES=${SEMANTIC_MAX_PROGRAM_FILES}`, { rootDir: resolvedTsconfigPath })
|
|
11328
|
+
failure: failureFor("too-many-files", `Project has ${parsedCommandLine.fileNames.length} files, exceeds SEMANTIC_MAX_PROGRAM_FILES=${require_constants.SEMANTIC_MAX_PROGRAM_FILES}`, { rootDir: resolvedTsconfigPath })
|
|
11644
11329
|
};
|
|
11645
11330
|
try {
|
|
11646
11331
|
const program = typescript.default.createProgram({
|
|
@@ -12542,7 +12227,7 @@ const safeReportDetector = (detectorName, detector, fallback, errorSink) => runS
|
|
|
12542
12227
|
module: "report",
|
|
12543
12228
|
contextDescription: "while building findings"
|
|
12544
12229
|
});
|
|
12545
|
-
const generateReport = (graph, config) => {
|
|
12230
|
+
const generateReport = (graph, config, summaryCache) => {
|
|
12546
12231
|
const analysisStartTime = performance.now();
|
|
12547
12232
|
const errorSink = [];
|
|
12548
12233
|
for (const module of graph.modules) {
|
|
@@ -12554,7 +12239,7 @@ const generateReport = (graph, config) => {
|
|
|
12554
12239
|
}
|
|
12555
12240
|
const unusedFiles = safeReportDetector("detectOrphanFiles", () => detectOrphanFiles(graph), [], errorSink);
|
|
12556
12241
|
const unusedExports = safeReportDetector("detectDeadExports", () => detectDeadExports(graph, config), [], errorSink);
|
|
12557
|
-
const unusedDependencies = safeReportDetector("detectStalePackages", () => detectStalePackages(graph, config), [], errorSink);
|
|
12242
|
+
const unusedDependencies = safeReportDetector("detectStalePackages", () => detectStalePackages(graph, config, summaryCache), [], errorSink);
|
|
12558
12243
|
const circularDependencies = safeReportDetector("detectCycles", () => detectCycles(graph), [], errorSink);
|
|
12559
12244
|
const syntacticRedundantAliases = config.reportRedundancy ? [...safeReportDetector("detectRedundantAliases", () => detectRedundantAliases(graph), [], errorSink), ...safeReportDetector("detectUselessAliasedReExports", () => detectUselessAliasedReExports(graph), [], errorSink)] : [];
|
|
12560
12245
|
const duplicateExports = config.reportRedundancy ? safeReportDetector("detectDuplicateExports", () => detectDuplicateExports(graph), [], errorSink) : [];
|
|
@@ -12648,6 +12333,478 @@ const generateReport = (graph, config) => {
|
|
|
12648
12333
|
};
|
|
12649
12334
|
};
|
|
12650
12335
|
|
|
12336
|
+
//#endregion
|
|
12337
|
+
//#region src/collect/entries-in-worker.ts
|
|
12338
|
+
/**
|
|
12339
|
+
* Runs `resolveEntries` on a dedicated worker thread so its ~90%-synchronous
|
|
12340
|
+
* fs work overlaps the main-thread analysis phases — the incremental-cache
|
|
12341
|
+
* warm path has no long parse `await` left to hide it behind. Entry content
|
|
12342
|
+
* reads stay live (fresh every run) exactly as inline. Worker infrastructure
|
|
12343
|
+
* failures fall back to the inline call (same result, just serialized); an
|
|
12344
|
+
* error thrown by `resolveEntries` itself rejects with the same message an
|
|
12345
|
+
* inline throw would, so the caller's fallback-to-empty-entries handling is
|
|
12346
|
+
* unchanged.
|
|
12347
|
+
*/
|
|
12348
|
+
const resolveEntriesInWorker = async (config) => {
|
|
12349
|
+
let worker;
|
|
12350
|
+
try {
|
|
12351
|
+
worker = launchSiblingWorker(require("url").pathToFileURL(__filename).href, "entries-worker");
|
|
12352
|
+
} catch {
|
|
12353
|
+
return resolveEntries(config);
|
|
12354
|
+
}
|
|
12355
|
+
try {
|
|
12356
|
+
const outcome = await new Promise((resolveOutcome) => {
|
|
12357
|
+
worker.on("message", (message) => {
|
|
12358
|
+
if (message.type === "ready") worker.postMessage({
|
|
12359
|
+
type: "resolve-entries",
|
|
12360
|
+
config
|
|
12361
|
+
});
|
|
12362
|
+
else if (message.type === "result") resolveOutcome({
|
|
12363
|
+
kind: "result",
|
|
12364
|
+
entries: message.entries
|
|
12365
|
+
});
|
|
12366
|
+
else if (message.type === "error") resolveOutcome({
|
|
12367
|
+
kind: "analysis-error",
|
|
12368
|
+
errorMessage: message.errorMessage
|
|
12369
|
+
});
|
|
12370
|
+
});
|
|
12371
|
+
worker.on("error", () => resolveOutcome({ kind: "infra-failure" }));
|
|
12372
|
+
worker.on("exit", () => resolveOutcome({ kind: "infra-failure" }));
|
|
12373
|
+
});
|
|
12374
|
+
if (outcome.kind === "result") return outcome.entries;
|
|
12375
|
+
if (outcome.kind === "analysis-error") throw new Error(outcome.errorMessage);
|
|
12376
|
+
return resolveEntries(config);
|
|
12377
|
+
} finally {
|
|
12378
|
+
worker.terminate();
|
|
12379
|
+
}
|
|
12380
|
+
};
|
|
12381
|
+
|
|
12382
|
+
//#endregion
|
|
12383
|
+
//#region src/summary-cache.ts
|
|
12384
|
+
const WALK_SKIP_DIRECTORY_NAMES = new Set(["node_modules", ".git"]);
|
|
12385
|
+
const MANIFEST_LIKE_FILENAMES = new Set(require_constants.ANALYZED_MANIFEST_FILENAMES);
|
|
12386
|
+
const isManifestLikeFileName = (fileName) => MANIFEST_LIKE_FILENAMES.has(fileName) || (fileName.startsWith("tsconfig") || fileName.startsWith("jsconfig")) && fileName.endsWith(".json");
|
|
12387
|
+
const isResolverConfigFileName = (fileName) => fileName.includes("webpack") || fileName.startsWith("vite.config.") || fileName.startsWith("vitest.config.") || fileName.startsWith("babel.config.") || fileName.startsWith(".babelrc") || fileName.startsWith("jest.config.");
|
|
12388
|
+
const sha1Hex = (text) => node_crypto.default.createHash("sha1").update(text).digest("hex");
|
|
12389
|
+
const sha1OfFileBytes = (filePath) => {
|
|
12390
|
+
try {
|
|
12391
|
+
return node_crypto.default.createHash("sha1").update((0, node_fs.readFileSync)(filePath)).digest("hex");
|
|
12392
|
+
} catch {
|
|
12393
|
+
return null;
|
|
12394
|
+
}
|
|
12395
|
+
};
|
|
12396
|
+
const fileNameOfPosixPath = (posixPath) => posixPath.slice(posixPath.lastIndexOf("/") + 1);
|
|
12397
|
+
const deslopRequire = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
|
|
12398
|
+
const resolveOwnPackageVersion = () => {
|
|
12399
|
+
try {
|
|
12400
|
+
const packageJson = deslopRequire("deslop-js/package.json");
|
|
12401
|
+
return typeof packageJson?.version === "string" ? packageJson.version : "unknown";
|
|
12402
|
+
} catch {
|
|
12403
|
+
return "unknown";
|
|
12404
|
+
}
|
|
12405
|
+
};
|
|
12406
|
+
const walkTreeStats = (rootDirectory) => {
|
|
12407
|
+
const collected = /* @__PURE__ */ new Map();
|
|
12408
|
+
const followedLinkTargets = /* @__PURE__ */ new Set();
|
|
12409
|
+
const walk = (directory) => {
|
|
12410
|
+
let entries;
|
|
12411
|
+
try {
|
|
12412
|
+
entries = (0, node_fs.readdirSync)(directory, { withFileTypes: true });
|
|
12413
|
+
} catch {
|
|
12414
|
+
return;
|
|
12415
|
+
}
|
|
12416
|
+
for (const entry of entries) {
|
|
12417
|
+
const entryPath = `${directory}/${entry.name}`;
|
|
12418
|
+
if (entry.isDirectory()) {
|
|
12419
|
+
if (!WALK_SKIP_DIRECTORY_NAMES.has(entry.name)) walk(entryPath);
|
|
12420
|
+
continue;
|
|
12421
|
+
}
|
|
12422
|
+
if (entry.isSymbolicLink()) {
|
|
12423
|
+
if (WALK_SKIP_DIRECTORY_NAMES.has(entry.name)) continue;
|
|
12424
|
+
try {
|
|
12425
|
+
const linkStat = (0, node_fs.statSync)(entryPath);
|
|
12426
|
+
if (linkStat.isDirectory()) {
|
|
12427
|
+
const linkTarget = (0, node_fs.realpathSync)(entryPath);
|
|
12428
|
+
if (!followedLinkTargets.has(linkTarget)) {
|
|
12429
|
+
followedLinkTargets.add(linkTarget);
|
|
12430
|
+
walk(entryPath);
|
|
12431
|
+
}
|
|
12432
|
+
} else if (linkStat.isFile()) collected.set(entryPath, {
|
|
12433
|
+
m: linkStat.mtimeMs,
|
|
12434
|
+
s: linkStat.size
|
|
12435
|
+
});
|
|
12436
|
+
} catch {
|
|
12437
|
+
continue;
|
|
12438
|
+
}
|
|
12439
|
+
continue;
|
|
12440
|
+
}
|
|
12441
|
+
if (!entry.isFile()) continue;
|
|
12442
|
+
try {
|
|
12443
|
+
const fileStat = (0, node_fs.statSync)(entryPath);
|
|
12444
|
+
collected.set(entryPath, {
|
|
12445
|
+
m: fileStat.mtimeMs,
|
|
12446
|
+
s: fileStat.size
|
|
12447
|
+
});
|
|
12448
|
+
} catch {
|
|
12449
|
+
continue;
|
|
12450
|
+
}
|
|
12451
|
+
}
|
|
12452
|
+
};
|
|
12453
|
+
walk(toPosixPath((0, node_path.resolve)(rootDirectory)));
|
|
12454
|
+
return collected;
|
|
12455
|
+
};
|
|
12456
|
+
const compileGlobAlternation = (patterns, matchDotNames) => {
|
|
12457
|
+
const regexSources = [];
|
|
12458
|
+
for (const pattern of patterns) {
|
|
12459
|
+
const compiled = new minimatch.Minimatch(pattern, { dot: matchDotNames }).makeRe();
|
|
12460
|
+
if (compiled === false) return null;
|
|
12461
|
+
regexSources.push(compiled.source);
|
|
12462
|
+
}
|
|
12463
|
+
return regexSources.length === 0 ? null : new RegExp(regexSources.join("|"));
|
|
12464
|
+
};
|
|
12465
|
+
const countPathSegments = (relativePath) => {
|
|
12466
|
+
let segmentCount = 1;
|
|
12467
|
+
for (let charIndex = 0; charIndex < relativePath.length; charIndex++) if (relativePath.charCodeAt(charIndex) === 47) segmentCount++;
|
|
12468
|
+
return segmentCount;
|
|
12469
|
+
};
|
|
12470
|
+
const contentFingerprintOf = (filePath, fileStat) => `${filePath}:${fileStat.s}:${sha1OfFileBytes(filePath) ?? `stat-${fileStat.m}`}`;
|
|
12471
|
+
const computeCollectHash = (walkedStats) => {
|
|
12472
|
+
const fingerprintLines = [];
|
|
12473
|
+
for (const [filePath, fileStat] of walkedStats) fingerprintLines.push(isManifestLikeFileName(fileNameOfPosixPath(filePath)) ? contentFingerprintOf(filePath, fileStat) : filePath);
|
|
12474
|
+
fingerprintLines.sort();
|
|
12475
|
+
return sha1Hex(fingerprintLines.join("\n"));
|
|
12476
|
+
};
|
|
12477
|
+
const computeResolutionHash = (collectHash, walkedStats) => {
|
|
12478
|
+
const fingerprintLines = [];
|
|
12479
|
+
for (const [filePath, fileStat] of walkedStats) if (isResolverConfigFileName(fileNameOfPosixPath(filePath))) fingerprintLines.push(contentFingerprintOf(filePath, fileStat));
|
|
12480
|
+
fingerprintLines.sort();
|
|
12481
|
+
return sha1Hex(`${collectHash}\n${fingerprintLines.join("\n")}`);
|
|
12482
|
+
};
|
|
12483
|
+
const computeScopeHash = (config) => sha1Hex(JSON.stringify({
|
|
12484
|
+
deslopVersion: resolveOwnPackageVersion(),
|
|
12485
|
+
rootDir: toPosixPath((0, node_path.resolve)(config.rootDir)),
|
|
12486
|
+
entryPatterns: config.entryPatterns,
|
|
12487
|
+
ignorePatterns: config.ignorePatterns,
|
|
12488
|
+
includeExtensions: config.includeExtensions,
|
|
12489
|
+
reportTypes: config.reportTypes,
|
|
12490
|
+
includeEntryExports: config.includeEntryExports,
|
|
12491
|
+
reportRedundancy: config.reportRedundancy,
|
|
12492
|
+
tsConfigPath: config.tsConfigPath ?? null,
|
|
12493
|
+
paths: config.paths ?? null
|
|
12494
|
+
}));
|
|
12495
|
+
const isRecordValue = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12496
|
+
const isStringArray = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
12497
|
+
const isOptionalArray = (value) => value === void 0 || Array.isArray(value);
|
|
12498
|
+
const emptyStore = (scopeHash) => ({
|
|
12499
|
+
version: 2,
|
|
12500
|
+
scopeHash,
|
|
12501
|
+
fileList: null,
|
|
12502
|
+
resolutions: null,
|
|
12503
|
+
summaries: {},
|
|
12504
|
+
packageFacts: {}
|
|
12505
|
+
});
|
|
12506
|
+
const readPersistedStore = (cachePath, scopeHash) => {
|
|
12507
|
+
try {
|
|
12508
|
+
const parsed = JSON.parse((0, node_fs.readFileSync)(cachePath, "utf-8"));
|
|
12509
|
+
if (isRecordValue(parsed) && parsed.version === 2 && parsed.scopeHash === scopeHash && isRecordValue(parsed.summaries) && isRecordValue(parsed.packageFacts)) {
|
|
12510
|
+
const persisted = parsed;
|
|
12511
|
+
return {
|
|
12512
|
+
version: 2,
|
|
12513
|
+
scopeHash,
|
|
12514
|
+
fileList: isRecordValue(persisted.fileList) ? persisted.fileList : null,
|
|
12515
|
+
resolutions: isRecordValue(persisted.resolutions) && typeof persisted.resolutions.hash === "string" && isRecordValue(persisted.resolutions.entries) ? persisted.resolutions : null,
|
|
12516
|
+
summaries: persisted.summaries,
|
|
12517
|
+
packageFacts: persisted.packageFacts
|
|
12518
|
+
};
|
|
12519
|
+
}
|
|
12520
|
+
} catch {}
|
|
12521
|
+
return emptyStore(scopeHash);
|
|
12522
|
+
};
|
|
12523
|
+
const intersectLocalReferencesWithOwnExports = (parsed) => {
|
|
12524
|
+
if (parsed.localIdentifierReferences.length === 0) return [];
|
|
12525
|
+
const ownExportNames = new Set(parsed.exports.map((exportInfo) => exportInfo.name));
|
|
12526
|
+
return parsed.localIdentifierReferences.filter((identifierName) => ownExportNames.has(identifierName));
|
|
12527
|
+
};
|
|
12528
|
+
const toPersistedArray = (values) => values.length > 0 ? values : void 0;
|
|
12529
|
+
const serializeParsedSource = (parsed, shouldPersistDryPatternFields) => ({
|
|
12530
|
+
imports: toPersistedArray(parsed.imports),
|
|
12531
|
+
exports: toPersistedArray(parsed.exports),
|
|
12532
|
+
memberAccesses: toPersistedArray(parsed.memberAccesses),
|
|
12533
|
+
wholeObjectUses: toPersistedArray(parsed.wholeObjectUses),
|
|
12534
|
+
localIdentifierReferences: toPersistedArray(intersectLocalReferencesWithOwnExports(parsed)),
|
|
12535
|
+
referencedFilenames: toPersistedArray(parsed.referencedFilenames),
|
|
12536
|
+
...shouldPersistDryPatternFields ? {
|
|
12537
|
+
redundantTypePatterns: toPersistedArray(parsed.redundantTypePatterns),
|
|
12538
|
+
identityWrappers: toPersistedArray(parsed.identityWrappers),
|
|
12539
|
+
typeDefinitionHashes: toPersistedArray(parsed.typeDefinitionHashes),
|
|
12540
|
+
inlineTypeLiterals: toPersistedArray(parsed.inlineTypeLiterals),
|
|
12541
|
+
simplifiableFunctions: toPersistedArray(parsed.simplifiableFunctions),
|
|
12542
|
+
simplifiableExpressions: toPersistedArray(parsed.simplifiableExpressions),
|
|
12543
|
+
duplicateConstantCandidates: toPersistedArray(parsed.duplicateConstantCandidates)
|
|
12544
|
+
} : {},
|
|
12545
|
+
errors: toPersistedArray(parsed.errors.map((deslopError) => deslopError.toJSON()))
|
|
12546
|
+
});
|
|
12547
|
+
const isPersistedErrorJson = (value) => isRecordValue(value) && typeof value.code === "string" && typeof value.module === "string" && typeof value.message === "string";
|
|
12548
|
+
const PERSISTED_SOURCE_ARRAY_FIELDS = [
|
|
12549
|
+
"imports",
|
|
12550
|
+
"exports",
|
|
12551
|
+
"memberAccesses",
|
|
12552
|
+
"wholeObjectUses",
|
|
12553
|
+
"localIdentifierReferences",
|
|
12554
|
+
"referencedFilenames",
|
|
12555
|
+
"redundantTypePatterns",
|
|
12556
|
+
"identityWrappers",
|
|
12557
|
+
"typeDefinitionHashes",
|
|
12558
|
+
"inlineTypeLiterals",
|
|
12559
|
+
"simplifiableFunctions",
|
|
12560
|
+
"simplifiableExpressions",
|
|
12561
|
+
"duplicateConstantCandidates",
|
|
12562
|
+
"errors"
|
|
12563
|
+
];
|
|
12564
|
+
const reviveParsedSource = (persisted) => {
|
|
12565
|
+
if (!isRecordValue(persisted)) return null;
|
|
12566
|
+
for (const fieldName of PERSISTED_SOURCE_ARRAY_FIELDS) if (!isOptionalArray(persisted[fieldName])) return null;
|
|
12567
|
+
const source = persisted;
|
|
12568
|
+
const persistedErrors = source.errors ?? [];
|
|
12569
|
+
if (!persistedErrors.every(isPersistedErrorJson)) return null;
|
|
12570
|
+
return {
|
|
12571
|
+
imports: source.imports ?? [],
|
|
12572
|
+
exports: source.exports ?? [],
|
|
12573
|
+
memberAccesses: source.memberAccesses ?? [],
|
|
12574
|
+
wholeObjectUses: source.wholeObjectUses ?? [],
|
|
12575
|
+
localIdentifierReferences: source.localIdentifierReferences ?? [],
|
|
12576
|
+
referencedFilenames: source.referencedFilenames ?? [],
|
|
12577
|
+
redundantTypePatterns: source.redundantTypePatterns ?? [],
|
|
12578
|
+
identityWrappers: source.identityWrappers ?? [],
|
|
12579
|
+
typeDefinitionHashes: source.typeDefinitionHashes ?? [],
|
|
12580
|
+
inlineTypeLiterals: source.inlineTypeLiterals ?? [],
|
|
12581
|
+
simplifiableFunctions: source.simplifiableFunctions ?? [],
|
|
12582
|
+
simplifiableExpressions: source.simplifiableExpressions ?? [],
|
|
12583
|
+
duplicateConstantCandidates: source.duplicateConstantCandidates ?? [],
|
|
12584
|
+
errors: persistedErrors.map((errorJson) => new DeslopError({
|
|
12585
|
+
code: errorJson.code,
|
|
12586
|
+
module: errorJson.module,
|
|
12587
|
+
severity: errorJson.severity,
|
|
12588
|
+
message: errorJson.message,
|
|
12589
|
+
path: errorJson.path,
|
|
12590
|
+
detail: errorJson.detail
|
|
12591
|
+
}))
|
|
12592
|
+
};
|
|
12593
|
+
};
|
|
12594
|
+
const atomicWriteFile = (filePath, contents) => {
|
|
12595
|
+
try {
|
|
12596
|
+
(0, node_fs.mkdirSync)((0, node_path.dirname)(filePath), { recursive: true });
|
|
12597
|
+
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
12598
|
+
(0, node_fs.writeFileSync)(temporaryPath, contents);
|
|
12599
|
+
(0, node_fs.renameSync)(temporaryPath, filePath);
|
|
12600
|
+
} catch {}
|
|
12601
|
+
};
|
|
12602
|
+
const createSummaryCache = (cachePath, config) => {
|
|
12603
|
+
const scopeHash = computeScopeHash(config);
|
|
12604
|
+
const store = readPersistedStore(cachePath, scopeHash);
|
|
12605
|
+
const walkRoot = toPosixPath((0, node_path.resolve)(config.rootDir));
|
|
12606
|
+
const walkedStats = walkTreeStats(config.rootDir);
|
|
12607
|
+
const collectHash = computeCollectHash(walkedStats);
|
|
12608
|
+
const resolutionHash = computeResolutionHash(collectHash, walkedStats);
|
|
12609
|
+
const shouldPersistDryPatternFields = config.reportRedundancy;
|
|
12610
|
+
if (store.resolutions === null || store.resolutions.hash !== resolutionHash) store.resolutions = {
|
|
12611
|
+
hash: resolutionHash,
|
|
12612
|
+
entries: {}
|
|
12613
|
+
};
|
|
12614
|
+
const resolutionEntries = store.resolutions.entries;
|
|
12615
|
+
let isDirty = false;
|
|
12616
|
+
const activeSummaryPaths = /* @__PURE__ */ new Set();
|
|
12617
|
+
const activeResolutionKeys = /* @__PURE__ */ new Set();
|
|
12618
|
+
const activeFactPaths = /* @__PURE__ */ new Set();
|
|
12619
|
+
const sortedNameSetMemo = /* @__PURE__ */ new WeakMap();
|
|
12620
|
+
const statOfLive = (filePath) => {
|
|
12621
|
+
try {
|
|
12622
|
+
const fileStat = (0, node_fs.statSync)(filePath);
|
|
12623
|
+
return {
|
|
12624
|
+
m: fileStat.mtimeMs,
|
|
12625
|
+
s: fileStat.size
|
|
12626
|
+
};
|
|
12627
|
+
} catch {
|
|
12628
|
+
return null;
|
|
12629
|
+
}
|
|
12630
|
+
};
|
|
12631
|
+
const statOf = (filePath) => walkedStats.get(filePath) ?? statOfLive(filePath);
|
|
12632
|
+
return {
|
|
12633
|
+
lookupFileList: () => {
|
|
12634
|
+
const cachedFileList = store.fileList;
|
|
12635
|
+
if (cachedFileList === null || cachedFileList.hash !== collectHash || !isStringArray(cachedFileList.files)) return null;
|
|
12636
|
+
return cachedFileList.files.map((filePath, fileIndex) => ({
|
|
12637
|
+
index: fileIndex,
|
|
12638
|
+
path: filePath
|
|
12639
|
+
}));
|
|
12640
|
+
},
|
|
12641
|
+
storeFileList: (files) => {
|
|
12642
|
+
store.fileList = {
|
|
12643
|
+
hash: collectHash,
|
|
12644
|
+
files: files.map((file) => file.path)
|
|
12645
|
+
};
|
|
12646
|
+
isDirty = true;
|
|
12647
|
+
},
|
|
12648
|
+
lookupSummary: (filePath) => {
|
|
12649
|
+
const cachedSummary = store.summaries[filePath];
|
|
12650
|
+
if (!isRecordValue(cachedSummary)) return null;
|
|
12651
|
+
const fileStat = statOf(filePath);
|
|
12652
|
+
if (!fileStat) return null;
|
|
12653
|
+
if (fileStat.m !== cachedSummary.m || fileStat.s !== cachedSummary.s) {
|
|
12654
|
+
if (fileStat.s !== cachedSummary.s || typeof cachedSummary.h !== "string") return null;
|
|
12655
|
+
const contentHash = sha1OfFileBytes(filePath);
|
|
12656
|
+
if (contentHash === null || contentHash !== cachedSummary.h) return null;
|
|
12657
|
+
cachedSummary.m = fileStat.m;
|
|
12658
|
+
cachedSummary.s = fileStat.s;
|
|
12659
|
+
isDirty = true;
|
|
12660
|
+
}
|
|
12661
|
+
const revived = reviveParsedSource(cachedSummary.p);
|
|
12662
|
+
if (revived === null) return null;
|
|
12663
|
+
activeSummaryPaths.add(filePath);
|
|
12664
|
+
return revived;
|
|
12665
|
+
},
|
|
12666
|
+
storeSummary: (filePath, parsed) => {
|
|
12667
|
+
const walkStat = statOf(filePath);
|
|
12668
|
+
if (!walkStat) return;
|
|
12669
|
+
const contentHash = sha1OfFileBytes(filePath);
|
|
12670
|
+
if (contentHash === null) return;
|
|
12671
|
+
const liveStat = statOfLive(filePath);
|
|
12672
|
+
if (liveStat === null || liveStat.m !== walkStat.m || liveStat.s !== walkStat.s) return;
|
|
12673
|
+
store.summaries[filePath] = {
|
|
12674
|
+
m: walkStat.m,
|
|
12675
|
+
s: walkStat.s,
|
|
12676
|
+
h: contentHash,
|
|
12677
|
+
p: serializeParsedSource(parsed, shouldPersistDryPatternFields)
|
|
12678
|
+
};
|
|
12679
|
+
activeSummaryPaths.add(filePath);
|
|
12680
|
+
isDirty = true;
|
|
12681
|
+
},
|
|
12682
|
+
lookupResolution: (specifier, fromFile) => {
|
|
12683
|
+
const resolutionKey = `${(0, node_path.dirname)(fromFile)}::${specifier}`;
|
|
12684
|
+
const cachedResolution = resolutionEntries[resolutionKey];
|
|
12685
|
+
if (!isRecordValue(cachedResolution) || typeof cachedResolution.e !== "boolean") return null;
|
|
12686
|
+
activeResolutionKeys.add(resolutionKey);
|
|
12687
|
+
return {
|
|
12688
|
+
resolvedPath: typeof cachedResolution.p === "string" ? cachedResolution.p : void 0,
|
|
12689
|
+
isExternal: cachedResolution.e,
|
|
12690
|
+
packageName: typeof cachedResolution.n === "string" ? cachedResolution.n : void 0
|
|
12691
|
+
};
|
|
12692
|
+
},
|
|
12693
|
+
storeResolution: (specifier, fromFile, resolved) => {
|
|
12694
|
+
const resolutionKey = `${(0, node_path.dirname)(fromFile)}::${specifier}`;
|
|
12695
|
+
resolutionEntries[resolutionKey] = {
|
|
12696
|
+
p: resolved.resolvedPath ?? null,
|
|
12697
|
+
e: resolved.isExternal,
|
|
12698
|
+
n: resolved.packageName ?? null
|
|
12699
|
+
};
|
|
12700
|
+
activeResolutionKeys.add(resolutionKey);
|
|
12701
|
+
isDirty = true;
|
|
12702
|
+
},
|
|
12703
|
+
matchPackageNames: (filePath, kind, names, matcher) => {
|
|
12704
|
+
let nameSet = sortedNameSetMemo.get(names);
|
|
12705
|
+
if (nameSet === void 0) {
|
|
12706
|
+
const sortedNames = [...names].sort();
|
|
12707
|
+
nameSet = {
|
|
12708
|
+
sortedNames,
|
|
12709
|
+
hash: sha1Hex(sortedNames.join("\n"))
|
|
12710
|
+
};
|
|
12711
|
+
sortedNameSetMemo.set(names, nameSet);
|
|
12712
|
+
}
|
|
12713
|
+
activeFactPaths.add(filePath);
|
|
12714
|
+
const fileStat = statOf(filePath);
|
|
12715
|
+
const existingEntry = isRecordValue(store.packageFacts[filePath]) ? store.packageFacts[filePath] : null;
|
|
12716
|
+
let validEntry = fileStat !== null && existingEntry !== null && existingEntry.m === fileStat.m && existingEntry.s === fileStat.s ? existingEntry : null;
|
|
12717
|
+
const existingMatch = validEntry?.[kind];
|
|
12718
|
+
if (isRecordValue(existingMatch) && existingMatch.h === nameSet.hash && isStringArray(existingMatch.matched)) return existingMatch.matched;
|
|
12719
|
+
const content = (0, node_fs.readFileSync)(filePath, "utf-8");
|
|
12720
|
+
const contentHash = sha1Hex(content);
|
|
12721
|
+
if (validEntry === null && fileStat !== null && existingEntry?.h === contentHash) {
|
|
12722
|
+
existingEntry.m = fileStat.m;
|
|
12723
|
+
existingEntry.s = fileStat.s;
|
|
12724
|
+
isDirty = true;
|
|
12725
|
+
validEntry = existingEntry;
|
|
12726
|
+
const repairedMatch = validEntry[kind];
|
|
12727
|
+
if (isRecordValue(repairedMatch) && repairedMatch.h === nameSet.hash && isStringArray(repairedMatch.matched)) return repairedMatch.matched;
|
|
12728
|
+
}
|
|
12729
|
+
const matchedNames = nameSet.sortedNames.filter((packageName) => matcher(content, packageName));
|
|
12730
|
+
if (fileStat !== null) {
|
|
12731
|
+
const factEntry = validEntry ?? {
|
|
12732
|
+
m: fileStat.m,
|
|
12733
|
+
s: fileStat.s,
|
|
12734
|
+
h: contentHash
|
|
12735
|
+
};
|
|
12736
|
+
factEntry[kind] = {
|
|
12737
|
+
h: nameSet.hash,
|
|
12738
|
+
matched: matchedNames
|
|
12739
|
+
};
|
|
12740
|
+
store.packageFacts[filePath] = factEntry;
|
|
12741
|
+
isDirty = true;
|
|
12742
|
+
}
|
|
12743
|
+
return matchedNames;
|
|
12744
|
+
},
|
|
12745
|
+
matchWalkedFiles: (query) => {
|
|
12746
|
+
if (toPosixPath((0, node_path.resolve)(query.cwd)) !== walkRoot) return null;
|
|
12747
|
+
const positiveMatcher = compileGlobAlternation(query.patterns, query.dot === true);
|
|
12748
|
+
if (positiveMatcher === null) return null;
|
|
12749
|
+
const ignoreMatcher = query.ignore.length > 0 ? compileGlobAlternation(query.ignore, true) : null;
|
|
12750
|
+
if (query.ignore.length > 0 && ignoreMatcher === null) return null;
|
|
12751
|
+
const rootPrefixLength = walkRoot.length + 1;
|
|
12752
|
+
const matchedPaths = [];
|
|
12753
|
+
for (const filePath of walkedStats.keys()) {
|
|
12754
|
+
const relativePath = filePath.slice(rootPrefixLength);
|
|
12755
|
+
if (countPathSegments(relativePath) > query.deep) continue;
|
|
12756
|
+
if (ignoreMatcher !== null && ignoreMatcher.test(relativePath)) continue;
|
|
12757
|
+
if (positiveMatcher.test(relativePath)) matchedPaths.push(filePath);
|
|
12758
|
+
}
|
|
12759
|
+
return matchedPaths.sort();
|
|
12760
|
+
},
|
|
12761
|
+
save: () => {
|
|
12762
|
+
if (!isDirty) return;
|
|
12763
|
+
const compactedSummaries = {};
|
|
12764
|
+
for (const filePath of activeSummaryPaths) {
|
|
12765
|
+
const summaryEntry = store.summaries[filePath];
|
|
12766
|
+
if (summaryEntry !== void 0) compactedSummaries[filePath] = summaryEntry;
|
|
12767
|
+
}
|
|
12768
|
+
const compactedFacts = {};
|
|
12769
|
+
for (const filePath of activeFactPaths) {
|
|
12770
|
+
const factEntry = store.packageFacts[filePath];
|
|
12771
|
+
if (factEntry !== void 0) compactedFacts[filePath] = factEntry;
|
|
12772
|
+
}
|
|
12773
|
+
const compactedResolutions = {};
|
|
12774
|
+
for (const resolutionKey of activeResolutionKeys) {
|
|
12775
|
+
const resolutionEntry = resolutionEntries[resolutionKey];
|
|
12776
|
+
if (resolutionEntry !== void 0) compactedResolutions[resolutionKey] = resolutionEntry;
|
|
12777
|
+
}
|
|
12778
|
+
const serialized = JSON.stringify({
|
|
12779
|
+
version: 2,
|
|
12780
|
+
scopeHash,
|
|
12781
|
+
fileList: store.fileList,
|
|
12782
|
+
resolutions: {
|
|
12783
|
+
hash: resolutionHash,
|
|
12784
|
+
entries: compactedResolutions
|
|
12785
|
+
},
|
|
12786
|
+
summaries: compactedSummaries,
|
|
12787
|
+
packageFacts: compactedFacts
|
|
12788
|
+
});
|
|
12789
|
+
if (serialized.length > 268435456) return;
|
|
12790
|
+
atomicWriteFile(cachePath, serialized);
|
|
12791
|
+
}
|
|
12792
|
+
};
|
|
12793
|
+
};
|
|
12794
|
+
/**
|
|
12795
|
+
* Loads the incremental cache configured at `config.incrementalCachePath`.
|
|
12796
|
+
* Returns `null` (analysis runs exactly as without a cache) when the path is
|
|
12797
|
+
* unset or anything about initialization fails.
|
|
12798
|
+
*/
|
|
12799
|
+
const loadSummaryCache = (config) => {
|
|
12800
|
+
if (!config.incrementalCachePath) return null;
|
|
12801
|
+
try {
|
|
12802
|
+
return createSummaryCache(config.incrementalCachePath, config);
|
|
12803
|
+
} catch {
|
|
12804
|
+
return null;
|
|
12805
|
+
}
|
|
12806
|
+
};
|
|
12807
|
+
|
|
12651
12808
|
//#endregion
|
|
12652
12809
|
//#region src/utils/collect-git-ignored-paths.ts
|
|
12653
12810
|
/**
|
|
@@ -12686,7 +12843,7 @@ const collectGitIgnoredPaths = (rootDirectory, candidatePaths) => {
|
|
|
12686
12843
|
cwd: rootDirectory,
|
|
12687
12844
|
input: candidatePaths.join("\0"),
|
|
12688
12845
|
encoding: "utf-8",
|
|
12689
|
-
maxBuffer: GIT_CHECK_IGNORE_MAX_BUFFER_BYTES
|
|
12846
|
+
maxBuffer: require_constants.GIT_CHECK_IGNORE_MAX_BUFFER_BYTES
|
|
12690
12847
|
});
|
|
12691
12848
|
if (result.error) {
|
|
12692
12849
|
const gitBinaryMissing = "code" in result.error && result.error.code === "ENOENT";
|
|
@@ -12802,7 +12959,7 @@ const fillSemanticConfig = (semanticOverrides) => {
|
|
|
12802
12959
|
reportRedundantVariableAliases: overrides.reportRedundantVariableAliases ?? true,
|
|
12803
12960
|
reportMisclassifiedDependencies: overrides.reportMisclassifiedDependencies ?? true,
|
|
12804
12961
|
reportRoundTripAliases: overrides.reportRoundTripAliases ?? true,
|
|
12805
|
-
decoratorAllowlist: overrides.decoratorAllowlist ?? DEFAULT_SEMANTIC_DECORATOR_ALLOWLIST
|
|
12962
|
+
decoratorAllowlist: overrides.decoratorAllowlist ?? require_constants.DEFAULT_SEMANTIC_DECORATOR_ALLOWLIST
|
|
12806
12963
|
};
|
|
12807
12964
|
};
|
|
12808
12965
|
const fillDuplicateBlocksConfig = (duplicateBlocksOverrides) => {
|
|
@@ -12837,11 +12994,12 @@ const fillComplexityConfig = (complexityOverrides) => {
|
|
|
12837
12994
|
};
|
|
12838
12995
|
const defineConfig = (options) => ({
|
|
12839
12996
|
rootDir: (0, node_path.resolve)(options.rootDir),
|
|
12840
|
-
entryPatterns: options.entryPatterns ?? DEFAULT_ENTRY_GLOBS,
|
|
12997
|
+
entryPatterns: options.entryPatterns ?? require_constants.DEFAULT_ENTRY_GLOBS,
|
|
12841
12998
|
ignorePatterns: options.ignorePatterns ?? [],
|
|
12842
|
-
includeExtensions: options.includeExtensions ?? DEFAULT_EXTENSIONS,
|
|
12999
|
+
includeExtensions: options.includeExtensions ?? require_constants.DEFAULT_EXTENSIONS,
|
|
12843
13000
|
tsConfigPath: options.tsConfigPath,
|
|
12844
13001
|
paths: options.paths,
|
|
13002
|
+
incrementalCachePath: options.incrementalCachePath,
|
|
12845
13003
|
reportTypes: options.reportTypes ?? false,
|
|
12846
13004
|
includeEntryExports: options.includeEntryExports ?? false,
|
|
12847
13005
|
reportRedundancy: options.reportRedundancy ?? true,
|
|
@@ -12952,7 +13110,7 @@ const analyze = async (config) => {
|
|
|
12952
13110
|
}));
|
|
12953
13111
|
}
|
|
12954
13112
|
const absoluteRoot = (0, node_path.resolve)(config.rootDir);
|
|
12955
|
-
const outputDirectoryExclusions = OUTPUT_DIRECTORIES.flatMap((outputDirectory) => [`${absoluteRoot}/${outputDirectory}/**`, `${absoluteRoot}/**/${outputDirectory}/**`]);
|
|
13113
|
+
const outputDirectoryExclusions = require_constants.OUTPUT_DIRECTORIES.flatMap((outputDirectory) => [`${absoluteRoot}/${outputDirectory}/**`, `${absoluteRoot}/**/${outputDirectory}/**`]);
|
|
12956
13114
|
const allExclusionPatterns = [
|
|
12957
13115
|
...workspaceDiscovery.excludedDirectories.map((directory) => `${directory}/**`),
|
|
12958
13116
|
...frameworkIgnorePatterns,
|
|
@@ -12962,24 +13120,26 @@ const analyze = async (config) => {
|
|
|
12962
13120
|
...config,
|
|
12963
13121
|
ignorePatterns: [...config.ignorePatterns, ...allExclusionPatterns]
|
|
12964
13122
|
} : config;
|
|
13123
|
+
const entriesPromise = (configWithExclusions.incrementalCachePath ? resolveEntriesInWorker(configWithExclusions) : resolveEntries(configWithExclusions)).catch((entriesError) => {
|
|
13124
|
+
setupErrors.push(new WorkspaceError({
|
|
13125
|
+
code: "workspace-discovery-failed",
|
|
13126
|
+
message: "resolveEntries failed — defaulting to empty entry set",
|
|
13127
|
+
path: config.rootDir,
|
|
13128
|
+
detail: describeUnknownError(entriesError)
|
|
13129
|
+
}));
|
|
13130
|
+
return {
|
|
13131
|
+
productionEntries: [],
|
|
13132
|
+
testEntries: [],
|
|
13133
|
+
alwaysUsedFiles: []
|
|
13134
|
+
};
|
|
13135
|
+
});
|
|
13136
|
+
const summaryCache = loadSummaryCache(configWithExclusions);
|
|
12965
13137
|
let files;
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
message: "resolveEntries failed — defaulting to empty entry set",
|
|
12972
|
-
path: config.rootDir,
|
|
12973
|
-
detail: describeUnknownError(entriesError)
|
|
12974
|
-
}));
|
|
12975
|
-
return {
|
|
12976
|
-
productionEntries: [],
|
|
12977
|
-
testEntries: [],
|
|
12978
|
-
alwaysUsedFiles: []
|
|
12979
|
-
};
|
|
12980
|
-
})]);
|
|
12981
|
-
files = collectedFiles;
|
|
12982
|
-
discoveredEntries = resolvedEntries;
|
|
13138
|
+
const cachedFileList = summaryCache?.lookupFileList() ?? null;
|
|
13139
|
+
if (cachedFileList !== null) files = cachedFileList;
|
|
13140
|
+
else try {
|
|
13141
|
+
files = await collectSourceFiles(configWithExclusions);
|
|
13142
|
+
summaryCache?.storeFileList(files);
|
|
12983
13143
|
} catch (collectError) {
|
|
12984
13144
|
setupErrors.push(new WorkspaceError({
|
|
12985
13145
|
code: "workspace-discovery-failed",
|
|
@@ -12990,9 +13150,6 @@ const analyze = async (config) => {
|
|
|
12990
13150
|
}));
|
|
12991
13151
|
return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
|
|
12992
13152
|
}
|
|
12993
|
-
const productionEntrySet = new Set(discoveredEntries.productionEntries);
|
|
12994
|
-
const testEntrySet = new Set(discoveredEntries.testEntries);
|
|
12995
|
-
const alwaysUsedFileSet = new Set(discoveredEntries.alwaysUsedFiles);
|
|
12996
13153
|
const gitIgnoreResult = collectGitIgnoredPaths((0, node_path.resolve)(config.rootDir), files.map((file) => file.path));
|
|
12997
13154
|
const gitIgnoredFileSet = gitIgnoreResult.ignoredPaths;
|
|
12998
13155
|
if (gitIgnoreResult.gitUnavailable) setupErrors.push(new WorkspaceError({
|
|
@@ -13024,7 +13181,41 @@ const analyze = async (config) => {
|
|
|
13024
13181
|
}));
|
|
13025
13182
|
return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
|
|
13026
13183
|
}
|
|
13027
|
-
const
|
|
13184
|
+
const resolveModuleThroughCache = (specifier, fromFile) => {
|
|
13185
|
+
if (summaryCache === null) return moduleResolver.resolveModule(specifier, fromFile);
|
|
13186
|
+
const cachedResolution = summaryCache.lookupResolution(specifier, fromFile);
|
|
13187
|
+
if (cachedResolution !== null) return cachedResolution;
|
|
13188
|
+
const resolved = moduleResolver.resolveModule(specifier, fromFile);
|
|
13189
|
+
summaryCache.storeResolution(specifier, fromFile, resolved);
|
|
13190
|
+
return resolved;
|
|
13191
|
+
};
|
|
13192
|
+
let parsedModules;
|
|
13193
|
+
let summaryMissCount = 0;
|
|
13194
|
+
if (summaryCache === null) parsedModules = await parseFilesInParallel(files);
|
|
13195
|
+
else {
|
|
13196
|
+
parsedModules = new Array(files.length);
|
|
13197
|
+
const missedFiles = [];
|
|
13198
|
+
const missedPositions = [];
|
|
13199
|
+
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
|
|
13200
|
+
const cachedSummary = summaryCache.lookupSummary(files[fileIndex].path);
|
|
13201
|
+
if (cachedSummary !== null) {
|
|
13202
|
+
parsedModules[fileIndex] = cachedSummary;
|
|
13203
|
+
continue;
|
|
13204
|
+
}
|
|
13205
|
+
missedFiles.push(files[fileIndex]);
|
|
13206
|
+
missedPositions.push(fileIndex);
|
|
13207
|
+
}
|
|
13208
|
+
summaryMissCount = missedFiles.length;
|
|
13209
|
+
const parsedMissedModules = await parseFilesInParallel(missedFiles);
|
|
13210
|
+
for (let missIndex = 0; missIndex < missedFiles.length; missIndex++) {
|
|
13211
|
+
parsedModules[missedPositions[missIndex]] = parsedMissedModules[missIndex];
|
|
13212
|
+
summaryCache.storeSummary(missedFiles[missIndex].path, parsedMissedModules[missIndex]);
|
|
13213
|
+
}
|
|
13214
|
+
}
|
|
13215
|
+
const discoveredEntries = await entriesPromise;
|
|
13216
|
+
const productionEntrySet = new Set(discoveredEntries.productionEntries);
|
|
13217
|
+
const testEntrySet = new Set(discoveredEntries.testEntries);
|
|
13218
|
+
const alwaysUsedFileSet = new Set(discoveredEntries.alwaysUsedFiles);
|
|
13028
13219
|
const graphInputs = [];
|
|
13029
13220
|
for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {
|
|
13030
13221
|
const file = files[fileIndex];
|
|
@@ -13032,7 +13223,7 @@ const analyze = async (config) => {
|
|
|
13032
13223
|
const resolvedImportMap = /* @__PURE__ */ new Map();
|
|
13033
13224
|
const safeResolveImport = (specifier) => {
|
|
13034
13225
|
try {
|
|
13035
|
-
return
|
|
13226
|
+
return resolveModuleThroughCache(specifier, file.path);
|
|
13036
13227
|
} catch (resolveError) {
|
|
13037
13228
|
setupErrors.push(new ResolverError({
|
|
13038
13229
|
severity: "warning",
|
|
@@ -13112,7 +13303,7 @@ const analyze = async (config) => {
|
|
|
13112
13303
|
for (const importInfo of parsedStyleModule.imports) {
|
|
13113
13304
|
let resolvedImport;
|
|
13114
13305
|
try {
|
|
13115
|
-
resolvedImport =
|
|
13306
|
+
resolvedImport = resolveModuleThroughCache(importInfo.specifier, styleFilePath);
|
|
13116
13307
|
} catch (styleResolveError) {
|
|
13117
13308
|
setupErrors.push(new ResolverError({
|
|
13118
13309
|
severity: "warning",
|
|
@@ -13176,7 +13367,7 @@ const analyze = async (config) => {
|
|
|
13176
13367
|
}
|
|
13177
13368
|
let analysisResult;
|
|
13178
13369
|
try {
|
|
13179
|
-
analysisResult = generateReport(moduleGraph, config);
|
|
13370
|
+
analysisResult = generateReport(moduleGraph, config, summaryCache ?? void 0);
|
|
13180
13371
|
} catch (reportError) {
|
|
13181
13372
|
setupErrors.push(new DetectorError({
|
|
13182
13373
|
module: "report",
|
|
@@ -13186,6 +13377,11 @@ const analyze = async (config) => {
|
|
|
13186
13377
|
}));
|
|
13187
13378
|
return buildEmptyScanResult(setupErrors, performance.now() - pipelineStartTime);
|
|
13188
13379
|
}
|
|
13380
|
+
summaryCache?.save();
|
|
13381
|
+
if (summaryCache !== null) analysisResult.incrementalCacheStats = {
|
|
13382
|
+
summaryHits: files.length - summaryMissCount,
|
|
13383
|
+
summaryMisses: summaryMissCount
|
|
13384
|
+
};
|
|
13189
13385
|
if (setupErrors.length > 0) analysisResult.analysisErrors = [...setupErrors, ...analysisResult.analysisErrors];
|
|
13190
13386
|
analysisResult.analysisTimeMs = performance.now() - pipelineStartTime;
|
|
13191
13387
|
return analysisResult;
|