deslop-js 0.0.2

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/index.cjs ADDED
@@ -0,0 +1,4953 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) {
14
+ __defProp(to, key, {
15
+ get: ((k) => from[k]).bind(null, key),
16
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
17
+ });
18
+ }
19
+ }
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
+ value: mod,
25
+ enumerable: true
26
+ }) : target, mod));
27
+
28
+ //#endregion
29
+ let node_path = require("node:path");
30
+ node_path = __toESM(node_path, 1);
31
+ let node_fs = require("node:fs");
32
+ let fast_glob = require("fast-glob");
33
+ fast_glob = __toESM(fast_glob, 1);
34
+ let node_fs_promises = require("node:fs/promises");
35
+ let oxc_parser = require("oxc-parser");
36
+ let oxc_resolver = require("oxc-resolver");
37
+ let minimatch = require("minimatch");
38
+
39
+ //#region src/constants.ts
40
+ const DEFAULT_EXTENSIONS = [
41
+ ".ts",
42
+ ".tsx",
43
+ ".js",
44
+ ".jsx",
45
+ ".mts",
46
+ ".mjs",
47
+ ".cts",
48
+ ".cjs",
49
+ ".mdx",
50
+ ".astro",
51
+ ".graphql",
52
+ ".gql",
53
+ ".css",
54
+ ".scss",
55
+ ".vue",
56
+ ".svelte"
57
+ ];
58
+ const HIDDEN_DIRECTORY_ALLOWLIST = [
59
+ ".storybook",
60
+ ".vitepress",
61
+ ".well-known",
62
+ ".changeset",
63
+ ".github",
64
+ ".client",
65
+ ".server"
66
+ ];
67
+ const OUTPUT_DIRECTORIES = [
68
+ "dist",
69
+ "build",
70
+ "out",
71
+ "esm",
72
+ "cjs"
73
+ ];
74
+ const SOURCE_EXTENSIONS$3 = [
75
+ "ts",
76
+ "tsx",
77
+ "mts",
78
+ "cts",
79
+ "js",
80
+ "jsx",
81
+ "mjs",
82
+ "cjs"
83
+ ];
84
+ const DEFAULT_EXCLUSIONS = [
85
+ "**/node_modules/**",
86
+ "**/.git/**",
87
+ "**/coverage/**",
88
+ "**/*.min.js",
89
+ "**/*.min.mjs",
90
+ "**/mockServiceWorker.js"
91
+ ];
92
+ const SCRIPT_FILE_PATTERN = /(?:^|\s)(?:node|tsx|ts-node|tsc|npx|bun|esr|esno|jiti|babel-node|zx)\s+(?:(?:-[\w-]+(?:[=\s][\w./@=-]+)?\s+)|(?:[\w/-]+\s+))*([\w./@-]+\.(?:ts|tsx|js|jsx|mts|mjs|cts|cjs))(?:\s|$)/;
93
+ const SCRIPT_EXTENSIONLESS_FILE_PATTERN = /(?:^|\s)(?:node|tsx|ts-node|bun|esr|esno|jiti|babel-node|zx)\s+(?:(?:-[\w-]+(?:[=\s][\w./@=-]+)?\s+))*((?:[./]|[\w@][\w@-]*\/)[\w./@-]+)(?:\s|$)/;
94
+ const SCRIPT_CONFIG_FILE_PATTERN = /--config\s+([\w./@-]+\.(?:ts|tsx|js|jsx|mts|mjs|cts|cjs))/;
95
+ const SCRIPT_ENTRY_PATTERNS = [];
96
+ const DEFAULT_ENTRY_GLOBS = [
97
+ "src/index.{ts,tsx,js,jsx}",
98
+ "src/main.{ts,tsx,js,jsx}",
99
+ "index.{ts,tsx,js,jsx}",
100
+ "main.{ts,tsx,js,jsx}"
101
+ ];
102
+ const KNOWN_CONFIG_PREFIXES = [
103
+ "babel.config.",
104
+ "rollup.config.",
105
+ "webpack.config.",
106
+ "postcss.config.",
107
+ "stencil.config.",
108
+ "remotion.config.",
109
+ "metro.config.",
110
+ "tsup.config.",
111
+ "tsdown.config.",
112
+ "unbuild.config.",
113
+ "esbuild.config.",
114
+ "swc.config.",
115
+ "turbo.",
116
+ "jest.config.",
117
+ "jest.setup.",
118
+ "vitest.config.",
119
+ "vitest.ci.config.",
120
+ "vitest.setup.",
121
+ "vitest.workspace.",
122
+ "playwright.config.",
123
+ "cypress.config.",
124
+ "karma.conf.",
125
+ "eslint.config.",
126
+ "prettier.config.",
127
+ "stylelint.config.",
128
+ "lint-staged.config.",
129
+ "commitlint.config.",
130
+ "next.config.",
131
+ "next-sitemap.config.",
132
+ "nuxt.config.",
133
+ "astro.config.",
134
+ "sanity.config.",
135
+ "vite.config.",
136
+ "tailwind.config.",
137
+ "drizzle.config.",
138
+ "knexfile.",
139
+ "sentry.client.config.",
140
+ "sentry.server.config.",
141
+ "sentry.edge.config.",
142
+ "react-router.config.",
143
+ "typedoc.",
144
+ "deslop.config.",
145
+ "i18next-parser.config.",
146
+ "codegen.config.",
147
+ "graphql.config.",
148
+ "npmpackagejsonlint.config.",
149
+ "release-it.",
150
+ "release.config.",
151
+ "contentlayer.config.",
152
+ "rspack.config.",
153
+ "rsbuild.config.",
154
+ "module-federation.config.",
155
+ "next-env.d.",
156
+ "env.d.",
157
+ "vite-env.d."
158
+ ];
159
+ const IMPLICIT_DEPENDENCIES = new Set([
160
+ "typescript",
161
+ "@types/node",
162
+ "@types/react",
163
+ "@types/react-dom",
164
+ "eslint",
165
+ "prettier",
166
+ "husky",
167
+ "lint-staged",
168
+ "tslib"
169
+ ]);
170
+ const BUILTIN_MODULES = new Set([
171
+ "assert",
172
+ "async_hooks",
173
+ "buffer",
174
+ "child_process",
175
+ "cluster",
176
+ "console",
177
+ "constants",
178
+ "crypto",
179
+ "dgram",
180
+ "diagnostics_channel",
181
+ "dns",
182
+ "domain",
183
+ "events",
184
+ "fs",
185
+ "http",
186
+ "http2",
187
+ "https",
188
+ "inspector",
189
+ "module",
190
+ "net",
191
+ "os",
192
+ "path",
193
+ "perf_hooks",
194
+ "process",
195
+ "punycode",
196
+ "querystring",
197
+ "readline",
198
+ "repl",
199
+ "stream",
200
+ "string_decoder",
201
+ "sys",
202
+ "timers",
203
+ "tls",
204
+ "trace_events",
205
+ "tty",
206
+ "url",
207
+ "util",
208
+ "v8",
209
+ "vm",
210
+ "wasi",
211
+ "worker_threads",
212
+ "zlib"
213
+ ]);
214
+ const PLATFORM_SUFFIXES = [
215
+ ".web",
216
+ ".native",
217
+ ".ios",
218
+ ".android",
219
+ ".desktop",
220
+ ".windows",
221
+ ".macos",
222
+ ".any"
223
+ ];
224
+ const REACT_NATIVE_PLATFORM_EXTENSIONS = [
225
+ ".web.ts",
226
+ ".web.tsx",
227
+ ".web.js",
228
+ ".web.jsx",
229
+ ".native.ts",
230
+ ".native.tsx",
231
+ ".native.js",
232
+ ".native.jsx",
233
+ ".ios.ts",
234
+ ".ios.tsx",
235
+ ".ios.js",
236
+ ".ios.jsx",
237
+ ".android.ts",
238
+ ".android.tsx",
239
+ ".android.js",
240
+ ".android.jsx"
241
+ ];
242
+ const RESOLVER_EXTENSIONS = [
243
+ ...DEFAULT_EXTENSIONS,
244
+ ".d.ts",
245
+ ".d.mts",
246
+ ".d.cts",
247
+ ".json",
248
+ ".node",
249
+ ".css",
250
+ ".scss",
251
+ ".less",
252
+ ".svg",
253
+ ".png",
254
+ ".jpg",
255
+ ".graphql",
256
+ ".gql"
257
+ ];
258
+
259
+ //#endregion
260
+ //#region src/utils/line-column.ts
261
+ const getLineFromOffset = (source, offset) => {
262
+ let line = 1;
263
+ for (let charIndex = 0; charIndex < offset && charIndex < source.length; charIndex++) if (source[charIndex] === "\n") line++;
264
+ return line;
265
+ };
266
+ const getColumnFromOffset = (source, offset) => {
267
+ let column = 0;
268
+ for (let charIndex = offset - 1; charIndex >= 0; charIndex--) {
269
+ if (source[charIndex] === "\n") break;
270
+ column++;
271
+ }
272
+ return column;
273
+ };
274
+
275
+ //#endregion
276
+ //#region src/collect/parse.ts
277
+ const extractMdxImportsExports = (sourceText) => {
278
+ const statements = [];
279
+ let isInMultiline = false;
280
+ let braceDepth = 0;
281
+ for (const line of sourceText.split("\n")) {
282
+ const trimmedLine = line.trim();
283
+ if (isInMultiline) {
284
+ statements.push(line);
285
+ for (const character of trimmedLine) {
286
+ if (character === "{") braceDepth++;
287
+ if (character === "}") braceDepth--;
288
+ }
289
+ const hasFromClause = trimmedLine.includes(" from ") || trimmedLine.includes(" from'") || trimmedLine.includes(" from\"");
290
+ if (braceDepth <= 0 || trimmedLine.endsWith(";") || hasFromClause) {
291
+ isInMultiline = false;
292
+ braceDepth = 0;
293
+ }
294
+ } else if (trimmedLine.startsWith("import ") || trimmedLine.startsWith("import{") || trimmedLine.startsWith("export ") || trimmedLine.startsWith("export{")) {
295
+ statements.push(line);
296
+ for (const character of trimmedLine) {
297
+ if (character === "{") braceDepth++;
298
+ if (character === "}") braceDepth--;
299
+ }
300
+ if (braceDepth > 0 && !trimmedLine.includes(" from ")) isInMultiline = true;
301
+ }
302
+ }
303
+ return statements.join("\n");
304
+ };
305
+ const ASTRO_FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---/;
306
+ const extractAstroFrontmatter = (sourceText) => {
307
+ const frontmatterMatch = sourceText.match(ASTRO_FRONTMATTER_PATTERN);
308
+ if (!frontmatterMatch) return "";
309
+ return frontmatterMatch[1];
310
+ };
311
+ const VUE_SCRIPT_PATTERN = /<script[^>]*(?:lang=["'](?:ts|tsx)["'][^>]*)?>([\s\S]*?)<\/script>/gi;
312
+ const extractVueScriptContent = (sourceText) => {
313
+ const scriptBlocks = [];
314
+ let scriptMatch;
315
+ VUE_SCRIPT_PATTERN.lastIndex = 0;
316
+ while ((scriptMatch = VUE_SCRIPT_PATTERN.exec(sourceText)) !== null) if (scriptMatch[1]) scriptBlocks.push(scriptMatch[1]);
317
+ return scriptBlocks.join("\n");
318
+ };
319
+ const SVELTE_SCRIPT_PATTERN = /<script[^>]*>([\s\S]*?)<\/script>/gi;
320
+ const extractSvelteScriptContent = (sourceText) => {
321
+ const scriptBlocks = [];
322
+ let scriptMatch;
323
+ SVELTE_SCRIPT_PATTERN.lastIndex = 0;
324
+ while ((scriptMatch = SVELTE_SCRIPT_PATTERN.exec(sourceText)) !== null) if (scriptMatch[1]) scriptBlocks.push(scriptMatch[1]);
325
+ return scriptBlocks.join("\n");
326
+ };
327
+ const getModuleExportNameValue = (exportName) => {
328
+ if (exportName.type === "Identifier") return exportName.name;
329
+ if (exportName.type === "Literal") return exportName.value;
330
+ return "default";
331
+ };
332
+ const CSS_EXTENSIONS = [
333
+ ".css",
334
+ ".scss",
335
+ ".less",
336
+ ".sass"
337
+ ];
338
+ const CSS_IMPORT_PATTERN = /@import\s+(?:url\()?['"]([^'"]+)['"]\)?/g;
339
+ const SCSS_USE_FORWARD_PATTERN = /@(?:use|forward)\s+['"]([^'"]+)['"]/g;
340
+ const parseCssImports = (filePath) => {
341
+ const sourceText = (0, node_fs.readFileSync)(filePath, "utf-8");
342
+ const imports = [];
343
+ const patterns = [CSS_IMPORT_PATTERN, SCSS_USE_FORWARD_PATTERN];
344
+ for (const pattern of patterns) {
345
+ let match;
346
+ pattern.lastIndex = 0;
347
+ while ((match = pattern.exec(sourceText)) !== null) {
348
+ const specifier = match[1];
349
+ if (specifier && !specifier.startsWith("http")) imports.push({
350
+ specifier,
351
+ importedNames: [],
352
+ isTypeOnly: false,
353
+ isDynamic: false,
354
+ isSideEffect: true,
355
+ line: sourceText.substring(0, match.index).split("\n").length,
356
+ column: 0
357
+ });
358
+ }
359
+ }
360
+ return {
361
+ imports,
362
+ exports: [],
363
+ memberAccesses: [],
364
+ wholeObjectUses: []
365
+ };
366
+ };
367
+ const NON_JS_EXTENSIONS = [".graphql", ".gql"];
368
+ const parseSourceFile = (filePath) => {
369
+ if (CSS_EXTENSIONS.some((ext) => filePath.endsWith(ext))) return parseCssImports(filePath);
370
+ if (NON_JS_EXTENSIONS.some((ext) => filePath.endsWith(ext))) return {
371
+ imports: [],
372
+ exports: [],
373
+ memberAccesses: [],
374
+ wholeObjectUses: []
375
+ };
376
+ const sourceText = (0, node_fs.readFileSync)(filePath, "utf-8");
377
+ const imports = [];
378
+ const exports = [];
379
+ const isMdx = filePath.endsWith(".mdx");
380
+ const isAstro = filePath.endsWith(".astro");
381
+ const isVue = filePath.endsWith(".vue");
382
+ const isSvelte = filePath.endsWith(".svelte");
383
+ const textToParse = isMdx ? extractMdxImportsExports(sourceText) : isAstro ? extractAstroFrontmatter(sourceText) : isVue ? extractVueScriptContent(sourceText) : isSvelte ? extractSvelteScriptContent(sourceText) : sourceText;
384
+ const parseFileName = isMdx || isAstro || isVue || isSvelte ? filePath.replace(/\.(mdx|astro|vue|svelte)$/, ".tsx") : filePath;
385
+ let result = (0, oxc_parser.parseSync)(parseFileName, textToParse);
386
+ const isPlainJsFile = parseFileName.endsWith(".js") || parseFileName.endsWith(".mjs") || parseFileName.endsWith(".cjs");
387
+ if (result.errors.length > 0 && isPlainJsFile && result.errors.some((parseError) => {
388
+ const errorMessage = String(parseError.message ?? "");
389
+ return errorMessage.includes("JSX") || errorMessage.includes("Unexpected token");
390
+ })) result = (0, oxc_parser.parseSync)(parseFileName.replace(/\.(m?js|cjs)$/, ".jsx"), textToParse);
391
+ if (result.errors.length > 0) return {
392
+ imports,
393
+ exports,
394
+ memberAccesses: [],
395
+ wholeObjectUses: []
396
+ };
397
+ const program = result.program;
398
+ if (!program?.body) return {
399
+ imports,
400
+ exports,
401
+ memberAccesses: [],
402
+ wholeObjectUses: []
403
+ };
404
+ for (const node of program.body) switch (node.type) {
405
+ case "ImportDeclaration":
406
+ extractImportDeclaration(node, sourceText, imports);
407
+ break;
408
+ case "ExportNamedDeclaration":
409
+ extractNamedExportDeclaration(node, sourceText, exports);
410
+ break;
411
+ case "ExportDefaultDeclaration":
412
+ extractDefaultExportDeclaration(node, sourceText, exports);
413
+ break;
414
+ case "ExportAllDeclaration":
415
+ extractExportAllDeclaration(node, sourceText, exports);
416
+ break;
417
+ }
418
+ collectDynamicImports(program.body, sourceText, imports);
419
+ const namespaceLocalNames = collectNamespaceLocalNames(imports);
420
+ const memberAccesses = [];
421
+ const wholeObjectUses = [];
422
+ if (namespaceLocalNames.size > 0) collectMemberAccesses(program.body, namespaceLocalNames, memberAccesses, wholeObjectUses);
423
+ return {
424
+ imports,
425
+ exports,
426
+ memberAccesses,
427
+ wholeObjectUses
428
+ };
429
+ };
430
+ const WHOLE_OBJECT_FUNCTION_NAMES = new Set([
431
+ "keys",
432
+ "values",
433
+ "entries",
434
+ "assign",
435
+ "freeze",
436
+ "getOwnPropertyNames",
437
+ "getOwnPropertyDescriptors"
438
+ ]);
439
+ const collectNamespaceLocalNames = (imports) => {
440
+ const namespaceNames = /* @__PURE__ */ new Set();
441
+ for (const importInfo of imports) for (const importedName of importInfo.importedNames) if (importedName.isNamespace && importedName.alias) namespaceNames.add(importedName.alias);
442
+ return namespaceNames;
443
+ };
444
+ const collectMemberAccesses = (bodyNodes, namespaceLocalNames, memberAccesses, wholeObjectUses) => {
445
+ const walkForMemberAccesses = (node) => {
446
+ if (node.type === "MemberExpression" && !node.computed) {
447
+ const memberExpression = node;
448
+ if (memberExpression.object.type === "Identifier" && namespaceLocalNames.has(memberExpression.object.name)) {
449
+ const objectName = memberExpression.object.name;
450
+ const memberName = memberExpression.property.name;
451
+ if (memberName) memberAccesses.push({
452
+ objectName,
453
+ memberName
454
+ });
455
+ }
456
+ }
457
+ if (node.type === "MemberExpression" && Boolean(node.computed)) {
458
+ const computedExpression = node;
459
+ if (computedExpression.object.type === "Identifier" && namespaceLocalNames.has(computedExpression.object.name)) {
460
+ const objectName = computedExpression.object.name;
461
+ const expressionNode = node.expression;
462
+ if (expressionNode?.type === "Literal") {
463
+ const literalValue = expressionNode.value;
464
+ if (typeof literalValue === "string") memberAccesses.push({
465
+ objectName,
466
+ memberName: literalValue
467
+ });
468
+ else wholeObjectUses.push(objectName);
469
+ } else wholeObjectUses.push(objectName);
470
+ }
471
+ }
472
+ if (node.type === "SpreadElement") {
473
+ const spreadArgument = node.argument;
474
+ if (spreadArgument?.type === "Identifier" && namespaceLocalNames.has(spreadArgument.name)) wholeObjectUses.push(spreadArgument.name);
475
+ }
476
+ if (node.type === "ForInStatement") {
477
+ const forInRight = node.right;
478
+ if (forInRight?.type === "Identifier" && namespaceLocalNames.has(forInRight.name)) wholeObjectUses.push(forInRight.name);
479
+ }
480
+ if (node.type === "CallExpression") {
481
+ const callExpression = node;
482
+ if (callExpression.callee.type === "MemberExpression" && !callExpression.callee.computed) {
483
+ const calleeMember = callExpression.callee;
484
+ if (calleeMember.object.type === "Identifier" && calleeMember.object.name === "Object" && WHOLE_OBJECT_FUNCTION_NAMES.has(calleeMember.property.name)) {
485
+ const firstArgument = callExpression.arguments[0];
486
+ if (firstArgument && firstArgument.type !== "SpreadElement" && firstArgument.type === "Identifier" && namespaceLocalNames.has(firstArgument.name)) wholeObjectUses.push(firstArgument.name);
487
+ }
488
+ }
489
+ }
490
+ for (const value of Object.values(node)) if (Array.isArray(value)) {
491
+ for (const element of value) if (isWalkableNode(element)) walkForMemberAccesses(element);
492
+ } else if (isWalkableNode(value)) walkForMemberAccesses(value);
493
+ };
494
+ for (const topLevelNode of bodyNodes) if (isWalkableNode(topLevelNode)) walkForMemberAccesses(topLevelNode);
495
+ };
496
+ const extractImportDeclaration = (node, sourceText, imports) => {
497
+ const specifier = node.source.value;
498
+ if (!specifier) return;
499
+ const isTypeOnly = node.importKind === "type";
500
+ const importedNames = [];
501
+ for (const specifierNode of node.specifiers) switch (specifierNode.type) {
502
+ case "ImportDefaultSpecifier":
503
+ importedNames.push({
504
+ name: "default",
505
+ alias: specifierNode.local.name,
506
+ isNamespace: false,
507
+ isDefault: true,
508
+ isTypeOnly
509
+ });
510
+ break;
511
+ case "ImportNamespaceSpecifier":
512
+ importedNames.push({
513
+ name: "*",
514
+ alias: specifierNode.local.name,
515
+ isNamespace: true,
516
+ isDefault: false,
517
+ isTypeOnly
518
+ });
519
+ break;
520
+ case "ImportSpecifier": {
521
+ const importedName = getModuleExportNameValue(specifierNode.imported);
522
+ const localName = specifierNode.local.name;
523
+ importedNames.push({
524
+ name: importedName,
525
+ alias: localName !== importedName ? localName : void 0,
526
+ isNamespace: false,
527
+ isDefault: importedName === "default",
528
+ isTypeOnly: isTypeOnly || specifierNode.importKind === "type"
529
+ });
530
+ break;
531
+ }
532
+ }
533
+ const isSideEffectImport = importedNames.length === 0;
534
+ if (isSideEffectImport) importedNames.push({
535
+ name: "*",
536
+ alias: void 0,
537
+ isNamespace: false,
538
+ isDefault: false,
539
+ isTypeOnly: false
540
+ });
541
+ imports.push({
542
+ specifier,
543
+ importedNames,
544
+ isTypeOnly,
545
+ isDynamic: false,
546
+ isSideEffect: isSideEffectImport,
547
+ line: getLineFromOffset(sourceText, node.start),
548
+ column: getColumnFromOffset(sourceText, node.start)
549
+ });
550
+ };
551
+ const extractNamedExportDeclaration = (node, sourceText, exports) => {
552
+ const isTypeOnly = node.exportKind === "type";
553
+ const reExportSource = node.source?.value ?? void 0;
554
+ if (node.declaration) extractDeclarationNames(node.declaration, isTypeOnly, sourceText, exports, node.start);
555
+ for (const specifierNode of node.specifiers) {
556
+ const exportedName = getModuleExportNameValue(specifierNode.exported);
557
+ const localName = getModuleExportNameValue(specifierNode.local);
558
+ exports.push({
559
+ name: exportedName,
560
+ isDefault: exportedName === "default",
561
+ isTypeOnly: isTypeOnly || specifierNode.exportKind === "type",
562
+ isReExport: reExportSource !== void 0,
563
+ isSynthetic: false,
564
+ reExportSource,
565
+ reExportOriginalName: reExportSource !== void 0 ? localName : void 0,
566
+ isNamespaceReExport: false,
567
+ line: getLineFromOffset(sourceText, specifierNode.start ?? node.start),
568
+ column: getColumnFromOffset(sourceText, specifierNode.start ?? node.start)
569
+ });
570
+ }
571
+ };
572
+ const extractDefaultExportDeclaration = (node, sourceText, exports) => {
573
+ exports.push({
574
+ name: "default",
575
+ isDefault: true,
576
+ isTypeOnly: false,
577
+ isReExport: false,
578
+ isSynthetic: false,
579
+ reExportSource: void 0,
580
+ reExportOriginalName: void 0,
581
+ isNamespaceReExport: false,
582
+ line: getLineFromOffset(sourceText, node.start),
583
+ column: getColumnFromOffset(sourceText, node.start)
584
+ });
585
+ };
586
+ const extractExportAllDeclaration = (node, sourceText, exports) => {
587
+ const reExportSource = node.source.value;
588
+ if (!reExportSource) return;
589
+ const exportedName = node.exported ? getModuleExportNameValue(node.exported) : void 0;
590
+ exports.push({
591
+ name: exportedName ?? "*",
592
+ isDefault: false,
593
+ isTypeOnly: node.exportKind === "type",
594
+ isReExport: true,
595
+ isSynthetic: false,
596
+ reExportSource,
597
+ reExportOriginalName: "*",
598
+ isNamespaceReExport: !exportedName,
599
+ line: getLineFromOffset(sourceText, node.start),
600
+ column: getColumnFromOffset(sourceText, node.start)
601
+ });
602
+ };
603
+ const extractDeclarationNames = (declaration, isTypeOnly, sourceText, exports, fallbackStart) => {
604
+ const declarationType = declaration.type;
605
+ if (declarationType === "FunctionDeclaration" || declarationType === "ClassDeclaration" || declarationType === "TSEnumDeclaration") {
606
+ const declarationName = declaration.id?.name;
607
+ if (declarationName) exports.push({
608
+ name: declarationName,
609
+ isDefault: false,
610
+ isTypeOnly,
611
+ isReExport: false,
612
+ isSynthetic: false,
613
+ reExportSource: void 0,
614
+ reExportOriginalName: void 0,
615
+ isNamespaceReExport: false,
616
+ line: getLineFromOffset(sourceText, declaration.start ?? fallbackStart),
617
+ column: getColumnFromOffset(sourceText, declaration.start ?? fallbackStart)
618
+ });
619
+ return;
620
+ }
621
+ if (declarationType === "TSTypeAliasDeclaration" || declarationType === "TSInterfaceDeclaration") {
622
+ const declarationName = declaration.id.name;
623
+ if (declarationName) exports.push({
624
+ name: declarationName,
625
+ isDefault: false,
626
+ isTypeOnly: true,
627
+ isReExport: false,
628
+ isSynthetic: false,
629
+ reExportSource: void 0,
630
+ reExportOriginalName: void 0,
631
+ isNamespaceReExport: false,
632
+ line: getLineFromOffset(sourceText, declaration.start ?? fallbackStart),
633
+ column: getColumnFromOffset(sourceText, declaration.start ?? fallbackStart)
634
+ });
635
+ return;
636
+ }
637
+ if (declarationType === "VariableDeclaration") {
638
+ const variableDeclaration = declaration;
639
+ for (const declarator of variableDeclaration.declarations) {
640
+ const bindingNames = extractBindingPatternNames(declarator.id);
641
+ for (const bindingName of bindingNames) exports.push({
642
+ name: bindingName,
643
+ isDefault: false,
644
+ isTypeOnly,
645
+ isReExport: false,
646
+ isSynthetic: false,
647
+ reExportSource: void 0,
648
+ reExportOriginalName: void 0,
649
+ isNamespaceReExport: false,
650
+ line: getLineFromOffset(sourceText, declarator.start ?? fallbackStart),
651
+ column: getColumnFromOffset(sourceText, declarator.start ?? fallbackStart)
652
+ });
653
+ }
654
+ }
655
+ };
656
+ const extractBindingPatternNames = (pattern) => {
657
+ if (!pattern) return [];
658
+ if (pattern.type === "Identifier") return pattern.name ? [pattern.name] : [];
659
+ if (pattern.type === "ObjectPattern") {
660
+ const names = [];
661
+ for (const property of pattern.properties) if (property.type === "RestElement") names.push(...extractBindingPatternNames(property.argument));
662
+ else names.push(...extractBindingPatternNames(property.value));
663
+ return names;
664
+ }
665
+ if (pattern.type === "ArrayPattern") {
666
+ const names = [];
667
+ for (const element of pattern.elements) {
668
+ if (!element) continue;
669
+ if (element.type === "RestElement") names.push(...extractBindingPatternNames(element.argument));
670
+ else names.push(...extractBindingPatternNames(element));
671
+ }
672
+ return names;
673
+ }
674
+ if (pattern.type === "AssignmentPattern") return extractBindingPatternNames(pattern.left);
675
+ return [];
676
+ };
677
+ const createNamespaceImportBinding = () => ({
678
+ name: "*",
679
+ alias: void 0,
680
+ isNamespace: true,
681
+ isDefault: false,
682
+ isTypeOnly: false
683
+ });
684
+ const isWalkableNode = (value) => Boolean(value) && typeof value === "object" && typeof value.type === "string";
685
+ const extractStringLiteralFromArgument = (callArguments) => {
686
+ const firstArgument = callArguments[0];
687
+ if (!firstArgument) return void 0;
688
+ if (firstArgument.type === "SpreadElement") return void 0;
689
+ if (firstArgument.type !== "Literal") return void 0;
690
+ const literalValue = firstArgument.value;
691
+ return typeof literalValue === "string" ? literalValue : void 0;
692
+ };
693
+ const extractGlobPatterns = (callArguments) => {
694
+ const firstArgument = callArguments[0];
695
+ if (!firstArgument || firstArgument.type === "SpreadElement") return [];
696
+ if (firstArgument.type === "Literal") {
697
+ const literalValue = firstArgument.value;
698
+ if (typeof literalValue === "string" && (literalValue.startsWith("./") || literalValue.startsWith("../"))) return [literalValue];
699
+ return [];
700
+ }
701
+ if (firstArgument.type === "ArrayExpression") return firstArgument.elements.filter((element) => element.type === "Literal" && typeof element.value === "string" && (element.value.startsWith("./") || element.value.startsWith("../"))).map((element) => element.value);
702
+ return [];
703
+ };
704
+ const extractRegexGlobSuffix = (callArguments) => {
705
+ const thirdArgument = callArguments[2];
706
+ if (!thirdArgument || thirdArgument.type === "SpreadElement") return void 0;
707
+ if (thirdArgument.type !== "Literal") return void 0;
708
+ const regExpValue = thirdArgument.regex;
709
+ if (!regExpValue) return void 0;
710
+ const extensionMatch = regExpValue.pattern.match(/^\\\.([\w|]+)\$$/);
711
+ if (extensionMatch) {
712
+ const extensions = extensionMatch[1].split("|");
713
+ if (extensions.length === 1) return `*.${extensions[0]}`;
714
+ return `*.{${extensions.join(",")}}`;
715
+ }
716
+ };
717
+ const hasMockFactoryArgument = (callExpression) => {
718
+ const secondArgument = callExpression.arguments[1];
719
+ if (!secondArgument) return false;
720
+ if (secondArgument.type === "SpreadElement") return false;
721
+ return secondArgument.type === "ArrowFunctionExpression" || secondArgument.type === "FunctionExpression";
722
+ };
723
+ const synthesizeAutoMockSibling = (mockSource) => {
724
+ if (!mockSource || mockSource.includes("://") || mockSource.startsWith("data:") || mockSource.split("/").some((segment) => segment === "__mocks__")) return;
725
+ const lastSlashIndex = mockSource.lastIndexOf("/");
726
+ if (lastSlashIndex === -1) return void 0;
727
+ const directory = mockSource.slice(0, lastSlashIndex);
728
+ const fileName = mockSource.slice(lastSlashIndex + 1);
729
+ if (!fileName) return void 0;
730
+ return `${directory}/__mocks__/${fileName}`;
731
+ };
732
+ const collectDynamicImports = (bodyNodes, sourceText, imports) => {
733
+ const walkNode = (node) => {
734
+ if (node.type === "ImportExpression") {
735
+ const importExpression = node;
736
+ const sourceExpression = importExpression.source;
737
+ if (sourceExpression.type === "Literal") {
738
+ const specifierValue = sourceExpression.value;
739
+ if (specifierValue) imports.push({
740
+ specifier: specifierValue,
741
+ importedNames: [createNamespaceImportBinding()],
742
+ isTypeOnly: false,
743
+ isDynamic: true,
744
+ isSideEffect: false,
745
+ line: getLineFromOffset(sourceText, importExpression.start),
746
+ column: getColumnFromOffset(sourceText, importExpression.start)
747
+ });
748
+ } else if (sourceExpression.type === "TemplateLiteral") {
749
+ const templateLiteral = sourceExpression;
750
+ if (templateLiteral.quasis.length >= 2) {
751
+ const globPattern = templateLiteral.quasis.map((quasi) => quasi.value.cooked).join("*");
752
+ if (globPattern.startsWith("./") || globPattern.startsWith("../")) imports.push({
753
+ specifier: globPattern,
754
+ importedNames: [createNamespaceImportBinding()],
755
+ isTypeOnly: false,
756
+ isDynamic: true,
757
+ isSideEffect: false,
758
+ isGlob: true,
759
+ line: getLineFromOffset(sourceText, importExpression.start),
760
+ column: getColumnFromOffset(sourceText, importExpression.start)
761
+ });
762
+ }
763
+ }
764
+ return;
765
+ }
766
+ if (node.type === "CallExpression") {
767
+ const callExpression = node;
768
+ if (callExpression.callee.type === "Identifier" && callExpression.callee.name === "require") {
769
+ const requireSpecifier = extractStringLiteralFromArgument(callExpression.arguments);
770
+ if (requireSpecifier) imports.push({
771
+ specifier: requireSpecifier,
772
+ importedNames: [createNamespaceImportBinding()],
773
+ isTypeOnly: false,
774
+ isDynamic: true,
775
+ isSideEffect: false,
776
+ line: getLineFromOffset(sourceText, callExpression.start),
777
+ column: getColumnFromOffset(sourceText, callExpression.start)
778
+ });
779
+ }
780
+ if (callExpression.callee.type === "MemberExpression" && !callExpression.callee.computed) {
781
+ const memberExpression = callExpression.callee;
782
+ if (memberExpression.object.type === "Identifier" && memberExpression.object.name === "require" && memberExpression.property.name === "resolve") {
783
+ const resolveSpecifier = extractStringLiteralFromArgument(callExpression.arguments);
784
+ if (resolveSpecifier) imports.push({
785
+ specifier: resolveSpecifier,
786
+ importedNames: [createNamespaceImportBinding()],
787
+ isTypeOnly: false,
788
+ isDynamic: true,
789
+ isSideEffect: false,
790
+ line: getLineFromOffset(sourceText, callExpression.start),
791
+ column: getColumnFromOffset(sourceText, callExpression.start)
792
+ });
793
+ }
794
+ if (memberExpression.object.type === "Identifier" && (memberExpression.object.name === "vi" || memberExpression.object.name === "jest") && memberExpression.property.name === "mock") {
795
+ const mockSpecifier = extractStringLiteralFromArgument(callExpression.arguments);
796
+ if (mockSpecifier) {
797
+ imports.push({
798
+ specifier: mockSpecifier,
799
+ importedNames: [createNamespaceImportBinding()],
800
+ isTypeOnly: false,
801
+ isDynamic: true,
802
+ isSideEffect: true,
803
+ line: getLineFromOffset(sourceText, callExpression.start),
804
+ column: getColumnFromOffset(sourceText, callExpression.start)
805
+ });
806
+ const hasFactoryArgument = hasMockFactoryArgument(callExpression);
807
+ const autoMockSibling = synthesizeAutoMockSibling(mockSpecifier);
808
+ if (!hasFactoryArgument && autoMockSibling) imports.push({
809
+ specifier: autoMockSibling,
810
+ importedNames: [createNamespaceImportBinding()],
811
+ isTypeOnly: false,
812
+ isDynamic: true,
813
+ isSideEffect: true,
814
+ line: getLineFromOffset(sourceText, callExpression.start),
815
+ column: getColumnFromOffset(sourceText, callExpression.start)
816
+ });
817
+ }
818
+ }
819
+ if (memberExpression.object.type === "MetaProperty" && memberExpression.property.name === "glob") {
820
+ const globPatterns = extractGlobPatterns(callExpression.arguments);
821
+ for (const globPattern of globPatterns) imports.push({
822
+ specifier: globPattern,
823
+ importedNames: [createNamespaceImportBinding()],
824
+ isTypeOnly: false,
825
+ isDynamic: true,
826
+ isSideEffect: false,
827
+ isGlob: true,
828
+ line: getLineFromOffset(sourceText, callExpression.start),
829
+ column: getColumnFromOffset(sourceText, callExpression.start)
830
+ });
831
+ }
832
+ if (memberExpression.object.type === "Identifier" && memberExpression.object.name === "require" && memberExpression.property.name === "context") {
833
+ const directoryArgument = extractStringLiteralFromArgument(callExpression.arguments);
834
+ if (directoryArgument && (directoryArgument.startsWith("./") || directoryArgument.startsWith("../"))) {
835
+ const hasRegexArgument = callExpression.arguments.length >= 3 && callExpression.arguments[2].type !== "SpreadElement";
836
+ const regexSuffix = extractRegexGlobSuffix(callExpression.arguments);
837
+ if (!hasRegexArgument || Boolean(regexSuffix)) {
838
+ const contextGlobPrefix = callExpression.arguments[1]?.type === "Literal" && callExpression.arguments[1].value === true ? `${directoryArgument}/**/` : `${directoryArgument}/`;
839
+ const contextGlobPattern = regexSuffix ? `${contextGlobPrefix}${regexSuffix}` : `${contextGlobPrefix}*`;
840
+ imports.push({
841
+ specifier: contextGlobPattern,
842
+ importedNames: [createNamespaceImportBinding()],
843
+ isTypeOnly: false,
844
+ isDynamic: true,
845
+ isSideEffect: false,
846
+ isGlob: true,
847
+ line: getLineFromOffset(sourceText, callExpression.start),
848
+ column: getColumnFromOffset(sourceText, callExpression.start)
849
+ });
850
+ }
851
+ }
852
+ }
853
+ }
854
+ }
855
+ if (node.type === "NewExpression") {
856
+ const newExpression = node;
857
+ if (newExpression.callee.type === "Identifier" && newExpression.callee.name === "URL" && newExpression.arguments.length >= 2) {
858
+ const secondArgument = newExpression.arguments[1];
859
+ if (secondArgument.type === "MemberExpression" && secondArgument.object.type === "MetaProperty" && secondArgument.property.name === "url") {
860
+ const urlSpecifier = extractStringLiteralFromArgument(newExpression.arguments);
861
+ if (urlSpecifier) imports.push({
862
+ specifier: urlSpecifier,
863
+ importedNames: [createNamespaceImportBinding()],
864
+ isTypeOnly: false,
865
+ isDynamic: true,
866
+ isSideEffect: true,
867
+ line: getLineFromOffset(sourceText, newExpression.start),
868
+ column: getColumnFromOffset(sourceText, newExpression.start)
869
+ });
870
+ }
871
+ }
872
+ }
873
+ if (node.type === "Decorator") {
874
+ const expression = node.expression;
875
+ if (expression?.type === "CallExpression") {
876
+ const callNode = expression;
877
+ const callee = callNode.callee;
878
+ if (callee.type === "Identifier" && callee.name === "Component") {
879
+ const objectArgument = callNode.arguments[0];
880
+ if (objectArgument?.type === "ObjectExpression") {
881
+ const objectProperties = objectArgument.properties;
882
+ for (const property of objectProperties) {
883
+ if (property.type !== "ObjectProperty" && property.type !== "Property") continue;
884
+ const propertyKey = property.key;
885
+ const propertyName = propertyKey?.name ?? propertyKey?.value;
886
+ const propertyValue = property.value;
887
+ if (propertyName === "templateUrl" && propertyValue?.type === "Literal") {
888
+ const templatePath = propertyValue.value;
889
+ if (templatePath) imports.push({
890
+ specifier: templatePath.startsWith(".") ? templatePath : `./${templatePath}`,
891
+ importedNames: [],
892
+ isTypeOnly: false,
893
+ isDynamic: false,
894
+ isSideEffect: true,
895
+ line: getLineFromOffset(sourceText, property.start),
896
+ column: getColumnFromOffset(sourceText, property.start)
897
+ });
898
+ }
899
+ if ((propertyName === "styleUrl" || propertyName === "styleUrls") && propertyValue) {
900
+ const styleUrlValues = [];
901
+ if (propertyValue.type === "Literal") {
902
+ const singleValue = propertyValue.value;
903
+ if (singleValue) styleUrlValues.push(singleValue);
904
+ } else if (propertyValue.type === "ArrayExpression") {
905
+ const arrayElements = propertyValue.elements;
906
+ for (const element of arrayElements) if (element?.type === "Literal") {
907
+ const elementValue = element.value;
908
+ if (elementValue) styleUrlValues.push(elementValue);
909
+ }
910
+ }
911
+ for (const styleUrl of styleUrlValues) imports.push({
912
+ specifier: styleUrl.startsWith(".") ? styleUrl : `./${styleUrl}`,
913
+ importedNames: [],
914
+ isTypeOnly: false,
915
+ isDynamic: false,
916
+ isSideEffect: true,
917
+ line: getLineFromOffset(sourceText, property.start),
918
+ column: getColumnFromOffset(sourceText, property.start)
919
+ });
920
+ }
921
+ }
922
+ }
923
+ }
924
+ }
925
+ }
926
+ for (const value of Object.values(node)) if (Array.isArray(value)) {
927
+ for (const element of value) if (isWalkableNode(element)) walkNode(element);
928
+ } else if (isWalkableNode(value)) walkNode(value);
929
+ };
930
+ for (const topLevelNode of bodyNodes) if (isWalkableNode(topLevelNode)) walkNode(topLevelNode);
931
+ };
932
+ const ROUTE_CALL_FILE_ARG_INDEX = {
933
+ route: 1,
934
+ layout: 0,
935
+ index: 0
936
+ };
937
+ const extractStringFromExpression = (expression) => {
938
+ if (expression.type === "Literal") {
939
+ const literalValue = expression.value;
940
+ return typeof literalValue === "string" ? literalValue : void 0;
941
+ }
942
+ if (expression.type === "TemplateLiteral") {
943
+ const templateLiteral = expression;
944
+ if (templateLiteral.expressions.length === 0 && templateLiteral.quasis.length === 1) return templateLiteral.quasis[0]?.value.cooked;
945
+ }
946
+ };
947
+ const extractReactRouterRouteModuleEntries = (routesFilePath) => {
948
+ const result = (0, oxc_parser.parseSync)(routesFilePath, (0, node_fs.readFileSync)(routesFilePath, "utf-8"));
949
+ if (result.errors.length > 0 || !result.program?.body) return [];
950
+ const modulePaths = [];
951
+ const walkForRouteCalls = (node) => {
952
+ if (node.type === "CallExpression") {
953
+ const callExpression = node;
954
+ const callee = callExpression.callee;
955
+ if (callee.type === "Identifier") {
956
+ const fileArgumentIndex = ROUTE_CALL_FILE_ARG_INDEX[callee.name];
957
+ if (fileArgumentIndex !== void 0) {
958
+ const fileArgument = callExpression.arguments[fileArgumentIndex];
959
+ if (fileArgument && fileArgument.type !== "SpreadElement") {
960
+ const filePath = extractStringFromExpression(fileArgument);
961
+ if (filePath) modulePaths.push(filePath);
962
+ }
963
+ }
964
+ }
965
+ }
966
+ for (const value of Object.values(node)) if (Array.isArray(value)) {
967
+ for (const element of value) if (isWalkableNode(element)) walkForRouteCalls(element);
968
+ } else if (isWalkableNode(value)) walkForRouteCalls(value);
969
+ };
970
+ for (const topLevelNode of result.program.body) if (isWalkableNode(topLevelNode)) walkForRouteCalls(topLevelNode);
971
+ return modulePaths;
972
+ };
973
+
974
+ //#endregion
975
+ //#region src/collect/workspaces.ts
976
+ const resolveWorkspaces = (rootDir) => {
977
+ const rootPatterns = collectWorkspacePatterns(rootDir);
978
+ const hasRootLevelWorkspacePatterns = rootPatterns.length > 0;
979
+ let expandedDirectories = hasRootLevelWorkspacePatterns ? expandWorkspaceGlobs(rootPatterns, rootDir) : [];
980
+ const implicitSubProjects = discoverImplicitSubProjects(rootDir, expandedDirectories);
981
+ if (expandedDirectories.length === 0 && implicitSubProjects.length > 0) for (const subProjectDirectory of implicitSubProjects) {
982
+ const subPatterns = collectWorkspacePatterns(subProjectDirectory);
983
+ if (subPatterns.length > 0) {
984
+ const subExpanded = expandWorkspaceGlobs(subPatterns, subProjectDirectory);
985
+ expandedDirectories.push(subProjectDirectory, ...subExpanded);
986
+ }
987
+ }
988
+ const declaredDirectorySet = new Set(expandedDirectories);
989
+ const excludedDirectories = [];
990
+ const filteredImplicitSubProjects = implicitSubProjects;
991
+ const allDirectories = [...new Set([...expandedDirectories, ...filteredImplicitSubProjects])];
992
+ const workspacePackages = [];
993
+ for (const directory of allDirectories) {
994
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
995
+ if (!(0, node_fs.existsSync)(packageJsonPath)) continue;
996
+ try {
997
+ const packageContent = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
998
+ const packageJson = JSON.parse(packageContent);
999
+ const packageName = packageJson.name || (0, node_path.relative)(rootDir, directory);
1000
+ const entryFiles = extractWorkspaceEntries(packageJson, directory);
1001
+ const depthFromRoot = (0, node_path.relative)(rootDir, directory).split("/").filter(Boolean).length;
1002
+ workspacePackages.push({
1003
+ name: packageName,
1004
+ directory,
1005
+ entryFiles,
1006
+ isDeclaredWorkspace: declaredDirectorySet.has(directory),
1007
+ depthFromRoot
1008
+ });
1009
+ } catch {}
1010
+ }
1011
+ return {
1012
+ packages: workspacePackages,
1013
+ excludedDirectories,
1014
+ hasRootLevelWorkspacePatterns
1015
+ };
1016
+ };
1017
+ const IMPLICIT_SUB_PROJECT_SEARCH_DEPTH = 3;
1018
+ const STANDALONE_PROJECT_LOCKFILES = [
1019
+ "package-lock.json",
1020
+ "yarn.lock",
1021
+ "pnpm-lock.yaml",
1022
+ "bun.lockb"
1023
+ ];
1024
+ const isStandaloneProject = (directory) => STANDALONE_PROJECT_LOCKFILES.some((lockfile) => (0, node_fs.existsSync)((0, node_path.join)(directory, lockfile)));
1025
+ const discoverImplicitSubProjects = (rootDir, alreadyDiscoveredDirectories) => {
1026
+ const knownDirectories = new Set(alreadyDiscoveredDirectories);
1027
+ const hasDeclaredWorkspaces = alreadyDiscoveredDirectories.length > 0;
1028
+ const subProjectDirectories = [];
1029
+ const subPackageJsonPaths = fast_glob.default.sync("**/package.json", {
1030
+ cwd: rootDir,
1031
+ absolute: true,
1032
+ onlyFiles: true,
1033
+ ignore: [
1034
+ "**/node_modules/**",
1035
+ "**/dist/**",
1036
+ "**/build/**",
1037
+ "**/.git/**"
1038
+ ],
1039
+ deep: IMPLICIT_SUB_PROJECT_SEARCH_DEPTH + 1
1040
+ });
1041
+ for (const packageJsonPath of subPackageJsonPaths) {
1042
+ const directory = packageJsonPath.replace(/\/package\.json$/, "");
1043
+ if (directory === rootDir) continue;
1044
+ if (knownDirectories.has(directory)) continue;
1045
+ if (hasDeclaredWorkspaces && isStandaloneProject(directory)) continue;
1046
+ subProjectDirectories.push(directory);
1047
+ }
1048
+ return subProjectDirectories;
1049
+ };
1050
+ const collectWorkspacePatterns = (rootDir) => {
1051
+ const patterns = [];
1052
+ const packageJsonPath = (0, node_path.join)(rootDir, "package.json");
1053
+ if ((0, node_fs.existsSync)(packageJsonPath)) try {
1054
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
1055
+ const packageJson = JSON.parse(content);
1056
+ if (Array.isArray(packageJson.workspaces)) patterns.push(...packageJson.workspaces);
1057
+ else if (packageJson.workspaces?.packages) patterns.push(...packageJson.workspaces.packages);
1058
+ } catch {}
1059
+ const pnpmWorkspacePath = (0, node_path.join)(rootDir, "pnpm-workspace.yaml");
1060
+ if ((0, node_fs.existsSync)(pnpmWorkspacePath)) try {
1061
+ const packageLines = extractPnpmWorkspacePackages((0, node_fs.readFileSync)(pnpmWorkspacePath, "utf-8"));
1062
+ patterns.push(...packageLines);
1063
+ } catch {}
1064
+ return patterns;
1065
+ };
1066
+ const extractPnpmWorkspacePackages = (yamlContent) => {
1067
+ const packages = [];
1068
+ let inPackagesSection = false;
1069
+ for (const line of yamlContent.split("\n")) {
1070
+ const trimmedLine = line.trim();
1071
+ if (trimmedLine === "packages:") {
1072
+ inPackagesSection = true;
1073
+ continue;
1074
+ }
1075
+ if (inPackagesSection) {
1076
+ if (trimmedLine.startsWith("- ")) {
1077
+ const pattern = trimmedLine.slice(2).trim().replace(/^["']|["']$/g, "");
1078
+ if (pattern && !pattern.startsWith("!")) packages.push(pattern);
1079
+ } else if (trimmedLine && !trimmedLine.startsWith("#")) break;
1080
+ }
1081
+ }
1082
+ return packages;
1083
+ };
1084
+ const expandWorkspaceGlobs = (patterns, rootDir) => {
1085
+ const directories = [];
1086
+ for (const pattern of patterns) if (pattern.includes("*")) {
1087
+ const globPattern = pattern.endsWith("/") ? `${pattern}package.json` : `${pattern}/package.json`;
1088
+ try {
1089
+ const matchedFiles = fast_glob.default.sync(globPattern, {
1090
+ cwd: rootDir,
1091
+ absolute: true,
1092
+ onlyFiles: true
1093
+ });
1094
+ for (const matchedPath of matchedFiles) directories.push(matchedPath.replace(/\/package\.json$/, ""));
1095
+ } catch {}
1096
+ } else {
1097
+ const absoluteDirectory = (0, node_path.resolve)(rootDir, pattern);
1098
+ if ((0, node_fs.existsSync)((0, node_path.join)(absoluteDirectory, "package.json"))) directories.push(absoluteDirectory);
1099
+ }
1100
+ return [...new Set(directories)];
1101
+ };
1102
+ const SOURCE_EXTENSIONS$2 = [
1103
+ ".ts",
1104
+ ".tsx",
1105
+ ".js",
1106
+ ".jsx",
1107
+ ".mts",
1108
+ ".mjs",
1109
+ ".cts",
1110
+ ".cjs"
1111
+ ];
1112
+ const OUTPUT_DIR_PREFIXES$1 = [
1113
+ "dist/",
1114
+ "build/",
1115
+ "lib/",
1116
+ "lib-dist/",
1117
+ "esm/",
1118
+ "cjs/",
1119
+ "out/",
1120
+ "./dist/",
1121
+ "./lib-dist/"
1122
+ ];
1123
+ const SOURCE_INDEX_FALLBACK_STEMS$1 = [
1124
+ "src/index",
1125
+ "src/main",
1126
+ "index",
1127
+ "main"
1128
+ ];
1129
+ const resolveSourcePath$1 = (distPath, directory) => {
1130
+ const relativeToDist = (0, node_path.relative)(directory, distPath);
1131
+ if (OUTPUT_DIR_PREFIXES$1.some((prefix) => relativeToDist.startsWith(prefix))) {
1132
+ const sourceVariants = OUTPUT_DIR_PREFIXES$1.map((prefix) => relativeToDist.replace(new RegExp(`^${prefix.replace(".", "\\.")}`), "src/")).filter((variant) => variant !== relativeToDist);
1133
+ for (const variant of sourceVariants) {
1134
+ const withoutExtension = variant.replace(/\.[^.]+$/, "");
1135
+ for (const sourceExtension of SOURCE_EXTENSIONS$2) {
1136
+ const sourceCandidate = (0, node_path.resolve)(directory, withoutExtension + sourceExtension);
1137
+ if ((0, node_fs.existsSync)(sourceCandidate)) return [sourceCandidate];
1138
+ }
1139
+ }
1140
+ for (const stem of SOURCE_INDEX_FALLBACK_STEMS$1) for (const sourceExtension of SOURCE_EXTENSIONS$2) {
1141
+ const fallbackCandidate = (0, node_path.resolve)(directory, stem + sourceExtension);
1142
+ if ((0, node_fs.existsSync)(fallbackCandidate)) return [fallbackCandidate];
1143
+ }
1144
+ return [];
1145
+ }
1146
+ const resolvedDistPath = (0, node_path.resolve)(directory, relativeToDist);
1147
+ const candidates = [];
1148
+ const withoutJsExtension = relativeToDist.replace(/\.[cm]?js$/, "");
1149
+ if (withoutJsExtension !== relativeToDist) {
1150
+ for (const sourceExtension of SOURCE_EXTENSIONS$2) {
1151
+ const directSourceCandidate = (0, node_path.resolve)(directory, withoutJsExtension + sourceExtension);
1152
+ if ((0, node_fs.existsSync)(directSourceCandidate)) candidates.push(directSourceCandidate);
1153
+ }
1154
+ const indexCandidate = (0, node_path.resolve)(directory, withoutJsExtension, "index.ts");
1155
+ if ((0, node_fs.existsSync)(indexCandidate) && !candidates.includes(indexCandidate)) candidates.push(indexCandidate);
1156
+ }
1157
+ const withoutTsExtension = relativeToDist.replace(/\.ts$/, "");
1158
+ if (withoutTsExtension !== relativeToDist && !(0, node_fs.existsSync)(resolvedDistPath)) {
1159
+ const tsxCandidate = (0, node_path.resolve)(directory, withoutTsExtension + ".tsx");
1160
+ if ((0, node_fs.existsSync)(tsxCandidate) && !candidates.includes(tsxCandidate)) candidates.push(tsxCandidate);
1161
+ }
1162
+ if (candidates.length === 0 && (0, node_fs.existsSync)(resolvedDistPath)) candidates.push(resolvedDistPath);
1163
+ return candidates;
1164
+ };
1165
+ const extractWorkspaceEntries = (packageJson, directory) => {
1166
+ const entries = [];
1167
+ const addWithSourceResolution = (filePath) => {
1168
+ const resolved = (0, node_path.resolve)(directory, filePath);
1169
+ const sourceVariants = resolveSourcePath$1(resolved, directory);
1170
+ if (sourceVariants.length > 0) entries.push(...sourceVariants);
1171
+ else entries.push(resolved);
1172
+ };
1173
+ for (const field of [
1174
+ "main",
1175
+ "module",
1176
+ "browser",
1177
+ "types",
1178
+ "typings",
1179
+ "source"
1180
+ ]) {
1181
+ const fieldValue = packageJson[field];
1182
+ if (typeof fieldValue === "string") addWithSourceResolution(fieldValue);
1183
+ }
1184
+ if (packageJson.exports) {
1185
+ const exportPaths = [];
1186
+ collectExportPaths$1(packageJson.exports, directory, exportPaths);
1187
+ for (const exportPath of exportPaths) {
1188
+ const sourceVariants = resolveSourcePath$1(exportPath, directory);
1189
+ if (sourceVariants.length > 0) entries.push(...sourceVariants);
1190
+ else entries.push(exportPath);
1191
+ }
1192
+ }
1193
+ if (packageJson.bin) {
1194
+ if (typeof packageJson.bin === "string") addWithSourceResolution(packageJson.bin);
1195
+ else if (typeof packageJson.bin === "object" && packageJson.bin !== null) {
1196
+ for (const binPath of Object.values(packageJson.bin)) if (typeof binPath === "string") addWithSourceResolution(binPath);
1197
+ }
1198
+ }
1199
+ return [...new Set(entries)];
1200
+ };
1201
+ const collectExportPaths$1 = (exportValue, rootDir, entries) => {
1202
+ if (typeof exportValue === "string") {
1203
+ if (exportValue.startsWith(".")) if (exportValue.includes("*")) {
1204
+ const globPattern = exportValue.replace(/^\.\/?/, "");
1205
+ try {
1206
+ const expandedFiles = fast_glob.default.sync(globPattern, {
1207
+ cwd: rootDir,
1208
+ absolute: true,
1209
+ onlyFiles: true,
1210
+ ignore: ["**/node_modules/**"]
1211
+ });
1212
+ entries.push(...expandedFiles);
1213
+ } catch {}
1214
+ } else entries.push((0, node_path.resolve)(rootDir, exportValue));
1215
+ return;
1216
+ }
1217
+ if (typeof exportValue !== "object" || exportValue === null) return;
1218
+ for (const nestedValue of Object.values(exportValue)) collectExportPaths$1(nestedValue, rootDir, entries);
1219
+ };
1220
+ const NEXTJS_APP_ROUTER_CONVENTIONS = [
1221
+ "page",
1222
+ "layout",
1223
+ "loading",
1224
+ "error",
1225
+ "not-found",
1226
+ "template",
1227
+ "default",
1228
+ "route",
1229
+ "global-error",
1230
+ "forbidden",
1231
+ "unauthorized",
1232
+ "middleware",
1233
+ "instrumentation",
1234
+ "manifest",
1235
+ "robots",
1236
+ "sitemap",
1237
+ "opengraph-image",
1238
+ "twitter-image",
1239
+ "icon",
1240
+ "apple-icon",
1241
+ "actions"
1242
+ ];
1243
+ const FRAMEWORK_FILE_GLOB = "**/*.{ts,tsx,js,jsx,mjs,cjs}";
1244
+ const FRAMEWORK_FILE_GLOB_WITH_MDX = "**/*.{ts,tsx,js,jsx,mdx,md,mjs,cjs}";
1245
+ const NEXTJS_ENABLERS = ["next"];
1246
+ const REACT_ROUTER_ENABLERS = ["@react-router/dev"];
1247
+ const REMIX_ENABLERS = [
1248
+ "@remix-run/node",
1249
+ "@remix-run/react",
1250
+ "@remix-run/cloudflare",
1251
+ "@remix-run/cloudflare-pages",
1252
+ "@remix-run/deno"
1253
+ ];
1254
+ const NUXT_ENABLERS = ["nuxt"];
1255
+ const SVELTEKIT_ENABLERS = ["@sveltejs/kit"];
1256
+ const ASTRO_ENABLERS = ["astro"];
1257
+ const GATSBY_ENABLERS = ["gatsby"];
1258
+ const readDependencies = (directory) => {
1259
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
1260
+ if (!(0, node_fs.existsSync)(packageJsonPath)) return {};
1261
+ try {
1262
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
1263
+ const packageJson = JSON.parse(content);
1264
+ return {
1265
+ ...packageJson.dependencies,
1266
+ ...packageJson.devDependencies,
1267
+ ...packageJson.optionalDependencies
1268
+ };
1269
+ } catch {
1270
+ return {};
1271
+ }
1272
+ };
1273
+ const hasAnyEnabler = (dependencies, enablers) => enablers.some((enabler) => enabler in dependencies);
1274
+ const extractReactRouterAppDirectory = (directory) => {
1275
+ for (const configFile of [
1276
+ "react-router.config.ts",
1277
+ "react-router.config.js",
1278
+ "react-router.config.mjs",
1279
+ "react-router.config.cjs"
1280
+ ]) {
1281
+ const configPath = (0, node_path.join)(directory, configFile);
1282
+ if (!(0, node_fs.existsSync)(configPath)) continue;
1283
+ try {
1284
+ const appDirectoryMatch = (0, node_fs.readFileSync)(configPath, "utf-8").match(/appDirectory\s*:\s*['"`]([^'"`]+)['"`]/);
1285
+ if (appDirectoryMatch) return appDirectoryMatch[1].replace(/^\.\//, "");
1286
+ } catch {}
1287
+ }
1288
+ return "app";
1289
+ };
1290
+ const ROUTE_FILE_EXTENSIONS = [
1291
+ ".ts",
1292
+ ".tsx",
1293
+ ".js",
1294
+ ".jsx"
1295
+ ];
1296
+ const resolveRouteModulePath = (modulePath, routesFileDirectory) => {
1297
+ const normalizedPath = modulePath.startsWith("./") ? modulePath.slice(2) : modulePath;
1298
+ if (ROUTE_FILE_EXTENSIONS.some((extension) => normalizedPath.endsWith(extension))) {
1299
+ const absolutePath = (0, node_path.resolve)(routesFileDirectory, normalizedPath);
1300
+ if ((0, node_fs.existsSync)(absolutePath)) return absolutePath;
1301
+ return;
1302
+ }
1303
+ for (const extension of ROUTE_FILE_EXTENSIONS) {
1304
+ const absolutePath = (0, node_path.resolve)(routesFileDirectory, normalizedPath + extension);
1305
+ if ((0, node_fs.existsSync)(absolutePath)) return absolutePath;
1306
+ }
1307
+ for (const extension of ROUTE_FILE_EXTENSIONS) {
1308
+ const absolutePath = (0, node_path.resolve)(routesFileDirectory, normalizedPath, `index${extension}`);
1309
+ if ((0, node_fs.existsSync)(absolutePath)) return absolutePath;
1310
+ }
1311
+ };
1312
+ const extractRouteModuleEntriesFromRoutesFiles = (rootDir, appDirectory) => {
1313
+ const routesFileCandidates = fast_glob.default.sync([
1314
+ `${appDirectory}/routes.{ts,js,mts,mjs}`,
1315
+ `${appDirectory}/routes/**/*.{ts,js,mts,mjs}`,
1316
+ `src/routes.{ts,js,mts,mjs}`
1317
+ ], {
1318
+ cwd: rootDir,
1319
+ absolute: true,
1320
+ onlyFiles: true,
1321
+ ignore: ["**/node_modules/**"]
1322
+ });
1323
+ const resolvedEntries = [];
1324
+ for (const routesFilePath of routesFileCandidates) {
1325
+ const routesFileDirectory = (0, node_path.dirname)(routesFilePath);
1326
+ const modulePaths = extractReactRouterRouteModuleEntries(routesFilePath);
1327
+ for (const modulePath of modulePaths) {
1328
+ const resolvedPath = resolveRouteModulePath(modulePath, routesFileDirectory);
1329
+ if (resolvedPath) resolvedEntries.push(resolvedPath);
1330
+ }
1331
+ }
1332
+ return resolvedEntries;
1333
+ };
1334
+ const detectFrameworkEntries = (rootDir) => {
1335
+ const entryPoints = [];
1336
+ const dependencies = readDependencies(rootDir);
1337
+ const isNextjs = hasAnyEnabler(dependencies, NEXTJS_ENABLERS);
1338
+ const isReactRouter = hasAnyEnabler(dependencies, REACT_ROUTER_ENABLERS);
1339
+ const isRemix = hasAnyEnabler(dependencies, REMIX_ENABLERS);
1340
+ const isNuxt = hasAnyEnabler(dependencies, NUXT_ENABLERS);
1341
+ const isSvelteKit = hasAnyEnabler(dependencies, SVELTEKIT_ENABLERS);
1342
+ const isAstro = hasAnyEnabler(dependencies, ASTRO_ENABLERS);
1343
+ const isGatsby = hasAnyEnabler(dependencies, GATSBY_ENABLERS);
1344
+ if (isNextjs) {
1345
+ const appRouterConventionGlob = NEXTJS_APP_ROUTER_CONVENTIONS.map((convention) => `**/${convention}.{ts,tsx,js,jsx,mdx}`).join(",");
1346
+ const appDirs = [(0, node_path.join)(rootDir, "app"), (0, node_path.join)(rootDir, "src", "app")];
1347
+ for (const appDir of appDirs) if ((0, node_fs.existsSync)(appDir) && (0, node_fs.statSync)(appDir).isDirectory()) entryPoints.push(...fast_glob.default.sync(`{${appRouterConventionGlob}}`, {
1348
+ cwd: appDir,
1349
+ absolute: true,
1350
+ onlyFiles: true,
1351
+ ignore: ["**/node_modules/**"]
1352
+ }));
1353
+ const pagesDirs = [(0, node_path.join)(rootDir, "pages"), (0, node_path.join)(rootDir, "src", "pages")];
1354
+ for (const pagesDir of pagesDirs) if ((0, node_fs.existsSync)(pagesDir) && (0, node_fs.statSync)(pagesDir).isDirectory()) entryPoints.push(...fast_glob.default.sync(FRAMEWORK_FILE_GLOB, {
1355
+ cwd: pagesDir,
1356
+ absolute: true,
1357
+ onlyFiles: true,
1358
+ ignore: ["**/node_modules/**"]
1359
+ }));
1360
+ entryPoints.push(...fast_glob.default.sync([
1361
+ "middleware.{ts,js}",
1362
+ "src/middleware.{ts,js}",
1363
+ "instrumentation.{ts,js}",
1364
+ "instrumentation-client.{ts,js}",
1365
+ "src/instrumentation.{ts,js}",
1366
+ "src/instrumentation-client.{ts,js}",
1367
+ "mdx-components.{ts,tsx,js,jsx}",
1368
+ "src/mdx-components.{ts,tsx,js,jsx}"
1369
+ ], {
1370
+ cwd: rootDir,
1371
+ absolute: true,
1372
+ onlyFiles: true,
1373
+ ignore: ["**/node_modules/**"]
1374
+ }));
1375
+ }
1376
+ if (isReactRouter || isRemix) {
1377
+ const reactRouterAppDirectory = extractReactRouterAppDirectory(rootDir);
1378
+ entryPoints.push(...fast_glob.default.sync([
1379
+ `${reactRouterAppDirectory}/routes/**/*.{ts,tsx,js,jsx}`,
1380
+ `${reactRouterAppDirectory}/root.{ts,tsx,js,jsx}`,
1381
+ `${reactRouterAppDirectory}/entry.client.{ts,tsx,js,jsx}`,
1382
+ `${reactRouterAppDirectory}/entry.server.{ts,tsx,js,jsx}`,
1383
+ `${reactRouterAppDirectory}/routes.{ts,js,mts,mjs}`
1384
+ ], {
1385
+ cwd: rootDir,
1386
+ absolute: true,
1387
+ onlyFiles: true,
1388
+ ignore: ["**/node_modules/**"]
1389
+ }));
1390
+ const routeModuleEntries = extractRouteModuleEntriesFromRoutesFiles(rootDir, reactRouterAppDirectory);
1391
+ entryPoints.push(...routeModuleEntries);
1392
+ }
1393
+ if (isNuxt) for (const nuxtDir of [
1394
+ "pages",
1395
+ "layouts",
1396
+ "middleware",
1397
+ "server",
1398
+ "composables",
1399
+ "plugins"
1400
+ ]) {
1401
+ const dirPath = (0, node_path.join)(rootDir, nuxtDir);
1402
+ if ((0, node_fs.existsSync)(dirPath) && (0, node_fs.statSync)(dirPath).isDirectory()) entryPoints.push(...fast_glob.default.sync("**/*.{ts,tsx,js,jsx,vue}", {
1403
+ cwd: dirPath,
1404
+ absolute: true,
1405
+ onlyFiles: true,
1406
+ ignore: ["**/node_modules/**"]
1407
+ }));
1408
+ }
1409
+ if (isSvelteKit) {
1410
+ const svelteDirs = [
1411
+ (0, node_path.join)(rootDir, "src", "routes"),
1412
+ (0, node_path.join)(rootDir, "src", "lib"),
1413
+ (0, node_path.join)(rootDir, "src", "params")
1414
+ ];
1415
+ for (const svelteDir of svelteDirs) if ((0, node_fs.existsSync)(svelteDir) && (0, node_fs.statSync)(svelteDir).isDirectory()) entryPoints.push(...fast_glob.default.sync("**/*.{ts,tsx,js,jsx,svelte}", {
1416
+ cwd: svelteDir,
1417
+ absolute: true,
1418
+ onlyFiles: true,
1419
+ ignore: ["**/node_modules/**"]
1420
+ }));
1421
+ }
1422
+ if (isAstro) {
1423
+ const astroDirs = [
1424
+ (0, node_path.join)(rootDir, "src", "pages"),
1425
+ (0, node_path.join)(rootDir, "src", "layouts"),
1426
+ (0, node_path.join)(rootDir, "src", "content")
1427
+ ];
1428
+ for (const astroDir of astroDirs) if ((0, node_fs.existsSync)(astroDir) && (0, node_fs.statSync)(astroDir).isDirectory()) entryPoints.push(...fast_glob.default.sync(FRAMEWORK_FILE_GLOB_WITH_MDX, {
1429
+ cwd: astroDir,
1430
+ absolute: true,
1431
+ onlyFiles: true,
1432
+ ignore: ["**/node_modules/**"]
1433
+ }));
1434
+ }
1435
+ if (isGatsby) {
1436
+ const gatsbyDirs = [(0, node_path.join)(rootDir, "src", "pages"), (0, node_path.join)(rootDir, "src", "templates")];
1437
+ for (const gatsbyDir of gatsbyDirs) if ((0, node_fs.existsSync)(gatsbyDir) && (0, node_fs.statSync)(gatsbyDir).isDirectory()) entryPoints.push(...fast_glob.default.sync(FRAMEWORK_FILE_GLOB, {
1438
+ cwd: gatsbyDir,
1439
+ absolute: true,
1440
+ onlyFiles: true,
1441
+ ignore: ["**/node_modules/**"]
1442
+ }));
1443
+ }
1444
+ entryPoints.push(...fast_glob.default.sync([
1445
+ "**/*.stories.{ts,tsx,js,jsx,mts,mjs}",
1446
+ "**/*.story.{ts,tsx,js,jsx,mts,mjs}",
1447
+ ".storybook/**/*.{ts,tsx,js,jsx,mts,mjs}"
1448
+ ], {
1449
+ cwd: rootDir,
1450
+ absolute: true,
1451
+ onlyFiles: true,
1452
+ ignore: ["**/node_modules/**"],
1453
+ dot: true
1454
+ }));
1455
+ entryPoints.push(...fast_glob.default.sync([
1456
+ "env.{ts,js,mjs}",
1457
+ "src/env.{ts,js,mjs}",
1458
+ "src/routeTree.gen.{ts,tsx}",
1459
+ "src/router.{ts,tsx}"
1460
+ ], {
1461
+ cwd: rootDir,
1462
+ absolute: true,
1463
+ onlyFiles: true,
1464
+ ignore: ["**/node_modules/**"],
1465
+ dot: true
1466
+ }));
1467
+ for (const entryDir of ["e2e", "cypress"]) {
1468
+ const dirPath = (0, node_path.join)(rootDir, entryDir);
1469
+ if ((0, node_fs.existsSync)(dirPath) && (0, node_fs.statSync)(dirPath).isDirectory()) entryPoints.push(...fast_glob.default.sync(FRAMEWORK_FILE_GLOB, {
1470
+ cwd: dirPath,
1471
+ absolute: true,
1472
+ onlyFiles: true,
1473
+ dot: entryDir.startsWith(".")
1474
+ }));
1475
+ }
1476
+ entryPoints.push(...discoverElectronEntryPoints(rootDir));
1477
+ entryPoints.push(...discoverMobileEntryPoints(rootDir));
1478
+ return [...new Set(entryPoints)];
1479
+ };
1480
+ const ELECTRON_ENABLERS = [
1481
+ "electron",
1482
+ "electron-builder",
1483
+ "@electron-forge/cli",
1484
+ "electron-vite"
1485
+ ];
1486
+ const ELECTRON_ENTRY_PATTERNS = [
1487
+ "src/main/**/*.{ts,js}",
1488
+ "src/preload/**/*.{ts,js}",
1489
+ "electron/main.{ts,js}",
1490
+ "electron.vite.config.{ts,js,mjs}",
1491
+ "forge.config.{ts,js,cjs}",
1492
+ "electron-builder.{yml,yaml,json,json5,toml}"
1493
+ ];
1494
+ const discoverElectronEntryPoints = (rootDir) => {
1495
+ const packageJsonPath = (0, node_path.join)(rootDir, "package.json");
1496
+ if (!(0, node_fs.existsSync)(packageJsonPath)) return [];
1497
+ try {
1498
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
1499
+ const packageJson = JSON.parse(content);
1500
+ const allDependencies = {
1501
+ ...packageJson.dependencies,
1502
+ ...packageJson.devDependencies,
1503
+ ...packageJson.optionalDependencies
1504
+ };
1505
+ if (!ELECTRON_ENABLERS.some((enabler) => enabler in allDependencies)) return [];
1506
+ return fast_glob.default.sync(ELECTRON_ENTRY_PATTERNS, {
1507
+ cwd: rootDir,
1508
+ absolute: true,
1509
+ onlyFiles: true,
1510
+ ignore: ["**/node_modules/**"]
1511
+ });
1512
+ } catch {
1513
+ return [];
1514
+ }
1515
+ };
1516
+ const EXPO_ENABLERS = ["expo"];
1517
+ const EXPO_ROUTER_ENABLERS = ["expo-router"];
1518
+ const EXPO_ENTRY_PATTERNS = [
1519
+ "App.{ts,tsx,js,jsx}",
1520
+ "src/App.{ts,tsx,js,jsx}",
1521
+ "app.config.{ts,js,mjs,cjs}",
1522
+ "metro.config.{ts,js,mjs,cjs}",
1523
+ "babel.config.{ts,js,mjs,cjs}"
1524
+ ];
1525
+ const EXPO_ROUTER_ENTRY_PATTERNS = [
1526
+ "app/**/*.{ts,tsx,js,jsx}",
1527
+ "app.config.{ts,js,mjs,cjs}",
1528
+ "metro.config.{ts,js,mjs,cjs}",
1529
+ "babel.config.{ts,js,mjs,cjs}"
1530
+ ];
1531
+ const REACT_NATIVE_ENABLERS$1 = ["react-native"];
1532
+ const REACT_NATIVE_ENTRY_PATTERNS = [
1533
+ "index.{ts,tsx,js,jsx}",
1534
+ "index.android.{ts,tsx,js,jsx}",
1535
+ "index.ios.{ts,tsx,js,jsx}",
1536
+ "index.native.{ts,tsx,js,jsx}",
1537
+ "App.{ts,tsx,js,jsx}",
1538
+ "src/App.{ts,tsx,js,jsx}",
1539
+ "metro.config.{ts,js}",
1540
+ "react-native.config.{ts,js}"
1541
+ ];
1542
+ const discoverMobileEntryPoints = (directory) => {
1543
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
1544
+ if (!(0, node_fs.existsSync)(packageJsonPath)) return [];
1545
+ try {
1546
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
1547
+ const packageJson = JSON.parse(content);
1548
+ const allDependencies = {
1549
+ ...packageJson.dependencies,
1550
+ ...packageJson.devDependencies,
1551
+ ...packageJson.optionalDependencies
1552
+ };
1553
+ const detectedPatterns = [];
1554
+ if (EXPO_ROUTER_ENABLERS.some((enabler) => enabler in allDependencies)) detectedPatterns.push(...EXPO_ROUTER_ENTRY_PATTERNS);
1555
+ else if (EXPO_ENABLERS.some((enabler) => enabler in allDependencies)) detectedPatterns.push(...EXPO_ENTRY_PATTERNS);
1556
+ if (REACT_NATIVE_ENABLERS$1.some((enabler) => enabler in allDependencies)) detectedPatterns.push(...REACT_NATIVE_ENTRY_PATTERNS);
1557
+ if (detectedPatterns.length === 0) return [];
1558
+ return fast_glob.default.sync(detectedPatterns, {
1559
+ cwd: directory,
1560
+ absolute: true,
1561
+ onlyFiles: true,
1562
+ ignore: ["**/node_modules/**"]
1563
+ });
1564
+ } catch {
1565
+ return [];
1566
+ }
1567
+ };
1568
+
1569
+ //#endregion
1570
+ //#region src/resolver/source-path.ts
1571
+ const SOURCE_EXTENSIONS$1 = [
1572
+ ".ts",
1573
+ ".tsx",
1574
+ ".js",
1575
+ ".jsx",
1576
+ ".mts",
1577
+ ".mjs"
1578
+ ];
1579
+ const OUTPUT_DIR_PREFIXES = [
1580
+ "dist/esm/",
1581
+ "dist/cjs/",
1582
+ "dist/es/",
1583
+ "dist/lib/",
1584
+ "dist/",
1585
+ "build/",
1586
+ "lib/",
1587
+ "lib-dist/",
1588
+ "esm/",
1589
+ "cjs/",
1590
+ "out/"
1591
+ ];
1592
+ const DIST_WILDCARD_PATTERN = /^dist-[^/]+\//;
1593
+ const SOURCE_INDEX_FALLBACK_STEMS = ["src/index", "src/main"];
1594
+ const matchesOutputDirectory = (relativePath) => OUTPUT_DIR_PREFIXES.some((prefix) => relativePath.startsWith(prefix)) || DIST_WILDCARD_PATTERN.test(relativePath);
1595
+ const resolveSourcePath = (distPath, directory) => {
1596
+ if ((0, node_fs.existsSync)(distPath)) return distPath;
1597
+ const relativeToDist = (0, node_path.relative)(directory, distPath);
1598
+ const sourceReplacements = ["src/"];
1599
+ const allPrefixes = [...OUTPUT_DIR_PREFIXES];
1600
+ const wildcardMatch = DIST_WILDCARD_PATTERN.exec(relativeToDist);
1601
+ if (wildcardMatch) allPrefixes.push(wildcardMatch[0]);
1602
+ const sourceVariants = allPrefixes.flatMap((prefix) => sourceReplacements.map((replacement) => relativeToDist.replace(new RegExp(`^${prefix.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`), replacement))).filter((variant) => variant !== relativeToDist);
1603
+ for (const variant of sourceVariants) {
1604
+ const withoutExtension = variant.replace(/\.[^.]+$/, "");
1605
+ for (const sourceExtension of SOURCE_EXTENSIONS$1) {
1606
+ const sourceCandidate = (0, node_path.resolve)(directory, withoutExtension + sourceExtension);
1607
+ if ((0, node_fs.existsSync)(sourceCandidate)) return sourceCandidate;
1608
+ }
1609
+ }
1610
+ if (matchesOutputDirectory(relativeToDist)) for (const stem of SOURCE_INDEX_FALLBACK_STEMS) for (const sourceExtension of SOURCE_EXTENSIONS$1) {
1611
+ const fallbackCandidate = (0, node_path.resolve)(directory, stem + sourceExtension);
1612
+ if ((0, node_fs.existsSync)(fallbackCandidate)) return fallbackCandidate;
1613
+ }
1614
+ const withoutExtension = relativeToDist.replace(/\.[cm]?js$/, "");
1615
+ if (withoutExtension !== relativeToDist) {
1616
+ for (const sourceExtension of SOURCE_EXTENSIONS$1) {
1617
+ const directSourceCandidate = (0, node_path.resolve)(directory, withoutExtension + sourceExtension);
1618
+ if ((0, node_fs.existsSync)(directSourceCandidate)) return directSourceCandidate;
1619
+ }
1620
+ const indexCandidate = (0, node_path.resolve)(directory, withoutExtension, "index.ts");
1621
+ if ((0, node_fs.existsSync)(indexCandidate)) return indexCandidate;
1622
+ }
1623
+ };
1624
+
1625
+ //#endregion
1626
+ //#region src/collect/entries.ts
1627
+ const collectSourceFiles = async (config) => {
1628
+ const extensions = config.includeExtensions.length > 0 ? config.includeExtensions : DEFAULT_EXTENSIONS;
1629
+ const extensionGlob = extensions.length === 1 ? `**/*${extensions[0]}` : `**/*{${extensions.join(",")}}`;
1630
+ const ignorePatterns = [...DEFAULT_EXCLUSIONS, ...config.ignorePatterns];
1631
+ const absoluteRoot = (0, node_path.resolve)(config.rootDir);
1632
+ const mainFiles = await (0, fast_glob.default)(extensionGlob, {
1633
+ cwd: absoluteRoot,
1634
+ absolute: true,
1635
+ ignore: ignorePatterns,
1636
+ dot: false,
1637
+ onlyFiles: true
1638
+ });
1639
+ const allowedHiddenGlobs = HIDDEN_DIRECTORY_ALLOWLIST.flatMap((directory) => [`${directory}/**/*{${extensions.join(",")}}`, `**/${directory}/**/*{${extensions.join(",")}}`]);
1640
+ const hiddenFiles = allowedHiddenGlobs.length > 0 ? await (0, fast_glob.default)(allowedHiddenGlobs, {
1641
+ cwd: absoluteRoot,
1642
+ absolute: true,
1643
+ ignore: ignorePatterns,
1644
+ dot: true,
1645
+ onlyFiles: true
1646
+ }) : [];
1647
+ return [...mainFiles, ...hiddenFiles].sort().map((filePath, fileIndex) => ({
1648
+ index: fileIndex,
1649
+ path: filePath
1650
+ }));
1651
+ };
1652
+ const getFrameworkExclusions = (rootDir) => {
1653
+ const absoluteRoot = (0, node_path.resolve)(rootDir);
1654
+ const directoriesToCheck = [absoluteRoot, ...resolveWorkspaces(absoluteRoot).packages.map((workspacePackage) => workspacePackage.directory)];
1655
+ const ignorePatterns = [];
1656
+ for (const directory of directoriesToCheck) {
1657
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
1658
+ if (!(0, node_fs.existsSync)(packageJsonPath)) continue;
1659
+ let allDependencies = {};
1660
+ try {
1661
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
1662
+ const packageJson = JSON.parse(content);
1663
+ allDependencies = {
1664
+ ...packageJson.dependencies,
1665
+ ...packageJson.devDependencies,
1666
+ ...packageJson.optionalDependencies
1667
+ };
1668
+ } catch {
1669
+ continue;
1670
+ }
1671
+ for (const plugin of FRAMEWORK_PATTERNS) if (plugin.contentIgnorePatterns && isToolingPluginEnabled(plugin, allDependencies)) for (const pattern of plugin.contentIgnorePatterns) {
1672
+ const absolutePattern = (0, node_path.join)(directory, pattern);
1673
+ ignorePatterns.push(absolutePattern);
1674
+ }
1675
+ }
1676
+ return ignorePatterns;
1677
+ };
1678
+ const resolveEntries = async (config) => {
1679
+ const absoluteRoot = (0, node_path.resolve)(config.rootDir);
1680
+ const entryFiles = config.entryPatterns.length > 0 ? await (0, fast_glob.default)(config.entryPatterns, {
1681
+ cwd: absoluteRoot,
1682
+ absolute: true,
1683
+ onlyFiles: true
1684
+ }) : [];
1685
+ const packageJsonEntries = await extractPackageJsonEntries((0, node_path.resolve)(absoluteRoot, "package.json"));
1686
+ const workspaceDiscovery = resolveWorkspaces(absoluteRoot);
1687
+ const workspacePackages = workspaceDiscovery.packages;
1688
+ const isEntryEligible = (workspacePackage) => {
1689
+ if (workspaceDiscovery.hasRootLevelWorkspacePatterns) return true;
1690
+ return workspacePackage.depthFromRoot <= 2;
1691
+ };
1692
+ const hasDeclaredWorkspaces = workspacePackages.some((workspacePackage) => workspacePackage.isDeclaredWorkspace);
1693
+ const workspaceEntries = [];
1694
+ for (const workspacePackage of workspacePackages) {
1695
+ const isEligible = isEntryEligible(workspacePackage);
1696
+ if (workspaceDiscovery.hasRootLevelWorkspacePatterns && hasDeclaredWorkspaces ? workspacePackage.isDeclaredWorkspace && isEligible : isEligible) {
1697
+ const workspaceFrameworkEntries = detectFrameworkEntries(workspacePackage.directory);
1698
+ workspaceEntries.push(...workspaceFrameworkEntries);
1699
+ }
1700
+ if (isEligible && (workspacePackage.isDeclaredWorkspace || !workspaceDiscovery.hasRootLevelWorkspacePatterns)) {
1701
+ const workspacePackageJsonEntries = await extractPackageJsonEntries((0, node_path.resolve)(workspacePackage.directory, "package.json"));
1702
+ if (workspacePackageJsonEntries.some((entryPath) => (0, node_fs.existsSync)(entryPath))) workspaceEntries.push(...workspacePackageJsonEntries);
1703
+ else {
1704
+ const defaultFallback = findDefaultIndexEntry(workspacePackage.directory);
1705
+ if (defaultFallback) workspaceEntries.push(defaultFallback);
1706
+ }
1707
+ }
1708
+ }
1709
+ const frameworkEntries = detectFrameworkEntries(absoluteRoot);
1710
+ const entryEligiblePackages = workspacePackages.filter(isEntryEligible);
1711
+ const scriptEntries = extractScriptEntries(absoluteRoot);
1712
+ for (const workspacePackage of entryEligiblePackages) scriptEntries.push(...extractScriptEntries(workspacePackage.directory));
1713
+ const webpackEntries = extractWebpackEntryPoints(absoluteRoot);
1714
+ for (const workspacePackage of entryEligiblePackages) webpackEntries.push(...extractWebpackEntryPoints(workspacePackage.directory));
1715
+ const viteEntries = extractViteEntryPoints(absoluteRoot);
1716
+ for (const workspacePackage of entryEligiblePackages) viteEntries.push(...extractViteEntryPoints(workspacePackage.directory));
1717
+ const bundlerConfigEntries = extractBundlerConfigEntryPoints(absoluteRoot);
1718
+ for (const workspacePackage of entryEligiblePackages) bundlerConfigEntries.push(...extractBundlerConfigEntryPoints(workspacePackage.directory));
1719
+ const htmlScriptEntries = extractHtmlScriptEntries(absoluteRoot);
1720
+ for (const workspacePackage of entryEligiblePackages) htmlScriptEntries.push(...extractHtmlScriptEntries(workspacePackage.directory));
1721
+ const allDiscoveredEntries = [
1722
+ ...scriptEntries,
1723
+ ...webpackEntries,
1724
+ ...viteEntries,
1725
+ ...bundlerConfigEntries
1726
+ ];
1727
+ for (const entryPath of allDiscoveredEntries) if (entryPath.endsWith(".html") && (0, node_fs.existsSync)(entryPath)) htmlScriptEntries.push(...extractScriptTagsFromHtmlFile(entryPath));
1728
+ const angularEntries = extractAngularEntryPoints(absoluteRoot);
1729
+ for (const workspacePackage of entryEligiblePackages) angularEntries.push(...extractAngularEntryPoints(workspacePackage.directory));
1730
+ const testSetupEntries = extractTestSetupFiles(absoluteRoot);
1731
+ for (const workspacePackage of entryEligiblePackages) testSetupEntries.push(...extractTestSetupFiles(workspacePackage.directory));
1732
+ const pluginFileEntries = extractNextConfigPluginFiles(absoluteRoot);
1733
+ for (const workspacePackage of entryEligiblePackages) pluginFileEntries.push(...extractNextConfigPluginFiles(workspacePackage.directory));
1734
+ const testRunnerDiscovery = discoverTestRunnerEntryPoints(absoluteRoot, entryEligiblePackages);
1735
+ const toolingDiscovery = discoverToolingEntryPoints(absoluteRoot, entryEligiblePackages);
1736
+ const ciEntries = extractCiWorkflowEntries(absoluteRoot);
1737
+ const testEntries = [...new Set([...testRunnerDiscovery.entryFiles, ...testSetupEntries])];
1738
+ const testEntryPathSet = new Set(testEntries);
1739
+ return {
1740
+ productionEntries: [...new Set([
1741
+ ...entryFiles,
1742
+ ...packageJsonEntries,
1743
+ ...workspaceEntries,
1744
+ ...frameworkEntries,
1745
+ ...scriptEntries,
1746
+ ...webpackEntries,
1747
+ ...viteEntries,
1748
+ ...bundlerConfigEntries,
1749
+ ...htmlScriptEntries,
1750
+ ...angularEntries,
1751
+ ...pluginFileEntries,
1752
+ ...toolingDiscovery.entryFiles,
1753
+ ...ciEntries
1754
+ ])].filter((entryPath) => !testEntryPathSet.has(entryPath)),
1755
+ testEntries,
1756
+ alwaysUsedFiles: [...new Set([...toolingDiscovery.alwaysUsedFiles, ...testRunnerDiscovery.alwaysUsedFiles])]
1757
+ };
1758
+ };
1759
+ const DEFAULT_INDEX_PATTERNS = [
1760
+ "src/index.ts",
1761
+ "src/index.tsx",
1762
+ "src/index.js",
1763
+ "src/index.jsx",
1764
+ "src/main.ts",
1765
+ "src/main.tsx",
1766
+ "src/main.js",
1767
+ "src/main.jsx",
1768
+ "index.ts",
1769
+ "index.tsx",
1770
+ "index.js",
1771
+ "index.jsx",
1772
+ "main.ts",
1773
+ "main.tsx",
1774
+ "main.js",
1775
+ "main.jsx"
1776
+ ];
1777
+ const findDefaultIndexEntry = (directory) => {
1778
+ for (const pattern of DEFAULT_INDEX_PATTERNS) {
1779
+ const candidatePath = (0, node_path.resolve)(directory, pattern);
1780
+ if ((0, node_fs.existsSync)(candidatePath)) return candidatePath;
1781
+ }
1782
+ };
1783
+ const SOURCE_EXTENSIONS = [
1784
+ ".ts",
1785
+ ".tsx",
1786
+ ".mts",
1787
+ ".cts"
1788
+ ];
1789
+ const COMMON_SOURCE_DIRECTORIES = [
1790
+ "src",
1791
+ "lib",
1792
+ "main",
1793
+ "app",
1794
+ "source"
1795
+ ];
1796
+ const BUILD_OUTPUT_DIRECTORY_PATTERN = /^(?:\.\/)?(?:dist(?:-[a-z]+)?|build|out|esm|cjs)\/(?:(?:esm|cjs|es|lib|commonjs|module)\/)?/;
1797
+ const findSourceFile = (baseDir, relativePath) => {
1798
+ const pathWithoutExtension = (0, node_path.join)(baseDir, relativePath).replace(/\.[cm]?js(x?)$/, "");
1799
+ for (const sourceExtension of SOURCE_EXTENSIONS) {
1800
+ const candidatePath = pathWithoutExtension + sourceExtension;
1801
+ if ((0, node_fs.existsSync)(candidatePath)) return candidatePath;
1802
+ }
1803
+ const indexCandidate = (0, node_path.join)(pathWithoutExtension, "index.ts");
1804
+ if ((0, node_fs.existsSync)(indexCandidate)) return indexCandidate;
1805
+ };
1806
+ const findSourceFileStrict = (baseDir, relativePath) => {
1807
+ const pathWithoutExtension = (0, node_path.join)(baseDir, relativePath).replace(/\.[cm]?js(x?)$/, "");
1808
+ for (const sourceExtension of SOURCE_EXTENSIONS) {
1809
+ const candidatePath = pathWithoutExtension + sourceExtension;
1810
+ if ((0, node_fs.existsSync)(candidatePath)) return candidatePath;
1811
+ }
1812
+ const exactPath = (0, node_path.join)(baseDir, relativePath);
1813
+ if ((0, node_fs.existsSync)(exactPath)) return exactPath;
1814
+ };
1815
+ const resolveBuiltPathToSource = (builtAbsolutePath, rootDir) => {
1816
+ if ((0, node_fs.existsSync)(builtAbsolutePath)) return void 0;
1817
+ try {
1818
+ const tsconfigPath = (0, node_path.join)(rootDir, "tsconfig.json");
1819
+ if (!(0, node_fs.existsSync)(tsconfigPath)) return void 0;
1820
+ const tsconfigContent = (0, node_fs.readFileSync)(tsconfigPath, "utf-8").replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
1821
+ const tsconfig = JSON.parse(tsconfigContent);
1822
+ const outDir = tsconfig?.compilerOptions?.outDir;
1823
+ if (!outDir) return void 0;
1824
+ const absoluteOutDir = (0, node_path.resolve)(rootDir, outDir);
1825
+ const relativeToBuild = builtAbsolutePath.startsWith(absoluteOutDir) ? builtAbsolutePath.slice(absoluteOutDir.length) : void 0;
1826
+ if (!relativeToBuild) return void 0;
1827
+ const rootDirOption = tsconfig?.compilerOptions?.rootDir;
1828
+ const sourceRoot = rootDirOption ? (0, node_path.resolve)(rootDir, rootDirOption) : rootDir;
1829
+ const sourceFileMatch = findSourceFile(sourceRoot, relativeToBuild);
1830
+ if (sourceFileMatch) return sourceFileMatch;
1831
+ const directCandidate = (0, node_path.join)(sourceRoot, relativeToBuild);
1832
+ if ((0, node_fs.existsSync)(directCandidate)) return directCandidate;
1833
+ if (!rootDirOption) for (const sourceDir of COMMON_SOURCE_DIRECTORIES) {
1834
+ const candidate = findSourceFile((0, node_path.resolve)(rootDir, sourceDir), relativeToBuild);
1835
+ if (candidate) return candidate;
1836
+ }
1837
+ } catch {}
1838
+ };
1839
+ const resolveEntryPathViaHeuristic = (entryPath, rootDir) => {
1840
+ if (!BUILD_OUTPUT_DIRECTORY_PATTERN.test(entryPath)) return void 0;
1841
+ const buildDirMatch = entryPath.match(BUILD_OUTPUT_DIRECTORY_PATTERN);
1842
+ if (!buildDirMatch) return void 0;
1843
+ const relativeToBuildDir = entryPath.slice(buildDirMatch[0].length);
1844
+ for (const sourceDir of COMMON_SOURCE_DIRECTORIES) {
1845
+ const sourceBaseDir = (0, node_path.resolve)(rootDir, sourceDir);
1846
+ if (!(0, node_fs.existsSync)(sourceBaseDir)) continue;
1847
+ const sourceFileMatch = findSourceFileStrict(sourceBaseDir, relativeToBuildDir);
1848
+ if (sourceFileMatch) return sourceFileMatch;
1849
+ }
1850
+ };
1851
+ const resolveEntryPath = (entryPath, rootDir) => {
1852
+ const absolutePath = (0, node_path.resolve)(rootDir, entryPath);
1853
+ const normalizedEntry = entryPath.replace(/^\.\//, "");
1854
+ if (BUILD_OUTPUT_DIRECTORY_PATTERN.test(normalizedEntry)) {
1855
+ const sourcePath = resolveBuiltPathToSource(absolutePath, rootDir);
1856
+ if (sourcePath) return sourcePath;
1857
+ const heuristicMatch = resolveEntryPathViaHeuristic(normalizedEntry, rootDir);
1858
+ if (heuristicMatch) return heuristicMatch;
1859
+ }
1860
+ if ((0, node_fs.existsSync)(absolutePath)) return absolutePath;
1861
+ const sourcePath = resolveBuiltPathToSource(absolutePath, rootDir);
1862
+ if (sourcePath) return sourcePath;
1863
+ const directSourceMatch = findSourceFile(rootDir, normalizedEntry);
1864
+ if (directSourceMatch) return directSourceMatch;
1865
+ const heuristicMatch = resolveEntryPathViaHeuristic(normalizedEntry, rootDir);
1866
+ if (heuristicMatch) return heuristicMatch;
1867
+ return absolutePath;
1868
+ };
1869
+ const extractPackageJsonEntries = async (packageJsonPath) => {
1870
+ const entries = [];
1871
+ try {
1872
+ const content = await (0, node_fs_promises.readFile)(packageJsonPath, "utf-8");
1873
+ const packageJson = JSON.parse(content);
1874
+ const rootDir = packageJsonPath.replace(/\/package\.json$/, "");
1875
+ for (const field of [
1876
+ "main",
1877
+ "module",
1878
+ "browser",
1879
+ "types",
1880
+ "typings"
1881
+ ]) if (typeof packageJson[field] === "string") entries.push(resolveEntryPath(packageJson[field], rootDir));
1882
+ if (packageJson.exports) {
1883
+ const exportEntries = [];
1884
+ collectExportPaths(packageJson.exports, rootDir, exportEntries);
1885
+ for (const exportEntry of exportEntries) if ((0, node_fs.existsSync)(exportEntry)) entries.push(exportEntry);
1886
+ else {
1887
+ const sourcePath = resolveSourcePath(exportEntry, rootDir);
1888
+ if (sourcePath) entries.push(sourcePath);
1889
+ else if (exportEntry.endsWith(".ts")) {
1890
+ const tsxFallback = exportEntry.replace(/\.ts$/, ".tsx");
1891
+ if ((0, node_fs.existsSync)(tsxFallback)) entries.push(tsxFallback);
1892
+ else entries.push(exportEntry);
1893
+ } else entries.push(resolveEntryPath(exportEntry, rootDir));
1894
+ }
1895
+ }
1896
+ if (packageJson.bin) {
1897
+ if (typeof packageJson.bin === "string") entries.push(resolveEntryPath(packageJson.bin, rootDir));
1898
+ else if (typeof packageJson.bin === "object") {
1899
+ for (const binPath of Object.values(packageJson.bin)) if (typeof binPath === "string") entries.push(resolveEntryPath(binPath, rootDir));
1900
+ }
1901
+ }
1902
+ } catch {}
1903
+ return entries;
1904
+ };
1905
+ const SHELL_OPERATORS_PATTERN = /\s*(?:&&|\|\||[;&|])\s*/;
1906
+ const SCRIPT_MULTIPLEXERS = new Set([
1907
+ "concurrently",
1908
+ "run-s",
1909
+ "run-p",
1910
+ "npm-run-all",
1911
+ "npm-run-all2",
1912
+ "wireit",
1913
+ "turbo",
1914
+ "lerna",
1915
+ "ultra"
1916
+ ]);
1917
+ const CONFIG_LIKE_FLAGS = new Set([
1918
+ "--config",
1919
+ "-c",
1920
+ "--format",
1921
+ "--formatter",
1922
+ "--tsconfig",
1923
+ "--project",
1924
+ "-p",
1925
+ "--setup",
1926
+ "--global-setup"
1927
+ ]);
1928
+ const ENV_WRAPPER_BINARIES = new Set([
1929
+ "cross-env",
1930
+ "dotenv",
1931
+ "dotenv-flow",
1932
+ "env-cmd"
1933
+ ]);
1934
+ const IGNORED_CLI_TOOLS = new Set([
1935
+ "prettier",
1936
+ "eslint",
1937
+ "tslint",
1938
+ "stylelint",
1939
+ "biome",
1940
+ "oxlint",
1941
+ "oxfmt",
1942
+ "tsc",
1943
+ "tsup",
1944
+ "tsdown",
1945
+ "rollup",
1946
+ "webpack",
1947
+ "rimraf",
1948
+ "del-cli",
1949
+ "shx",
1950
+ "cpy-cli",
1951
+ "cpx",
1952
+ "echo",
1953
+ "cat",
1954
+ "mkdir",
1955
+ "rm",
1956
+ "cp",
1957
+ "mv",
1958
+ "ls",
1959
+ "pwd",
1960
+ "test",
1961
+ "husky",
1962
+ "lint-staged",
1963
+ "commitlint",
1964
+ "changeset",
1965
+ "changesets",
1966
+ "typedoc",
1967
+ "api-extractor",
1968
+ "madge",
1969
+ "depcheck",
1970
+ "deslop",
1971
+ "sort-package-json",
1972
+ "pnpm",
1973
+ "npm",
1974
+ "yarn",
1975
+ "ni",
1976
+ "nr",
1977
+ "nun",
1978
+ "next",
1979
+ "nuxt",
1980
+ "astro",
1981
+ "vite",
1982
+ "svelte-kit",
1983
+ "prisma",
1984
+ "drizzle-kit",
1985
+ "formatjs",
1986
+ "i18next",
1987
+ "i18next-parser",
1988
+ "lingui",
1989
+ "storybook",
1990
+ "chromatic",
1991
+ "msw",
1992
+ "patch-package",
1993
+ "syncpack",
1994
+ "manypkg",
1995
+ "jest",
1996
+ "vitest",
1997
+ "mocha",
1998
+ "ava",
1999
+ "tap",
2000
+ "c8",
2001
+ "nyc",
2002
+ "playwright",
2003
+ "cypress",
2004
+ "puppeteer",
2005
+ "webdriver",
2006
+ "sequelize",
2007
+ "typeorm",
2008
+ "mikro-orm",
2009
+ "wait-on",
2010
+ "start-server-and-test",
2011
+ "remark",
2012
+ "markdownlint",
2013
+ "markdownlint-cli2",
2014
+ "textlint",
2015
+ "alex",
2016
+ "cspell",
2017
+ "ncu",
2018
+ "npm-check-updates",
2019
+ "size-limit",
2020
+ "bundlewatch",
2021
+ "dbdocs",
2022
+ "lobe-i18n",
2023
+ "lobe-seo"
2024
+ ]);
2025
+ const looksLikeFilePath = (token) => {
2026
+ if (token.startsWith("-") || token.includes("${{") || token.includes("://")) return false;
2027
+ if (token.includes("}}") && !token.includes("{{")) return false;
2028
+ if (/\.(?:[cm]?[jt]sx?|css|scss|json|yaml|yml|toml|html|mjs|cjs|mts|cts|graphql|gql|mdx|astro|vue|svelte)$/.test(token)) return true;
2029
+ if (/\.\{[^}]+\}$/.test(token)) return true;
2030
+ if (token.startsWith("./") || token.startsWith("../")) return true;
2031
+ return token.includes("/") && !token.startsWith("@");
2032
+ };
2033
+ const isGlobPattern = (token) => {
2034
+ return token.includes("*") || token.includes("{") || token.includes("?");
2035
+ };
2036
+ const extractScriptFileArguments = (scriptCommand, directory) => {
2037
+ const entries = [];
2038
+ const segments = scriptCommand.split(SHELL_OPERATORS_PATTERN);
2039
+ for (const segment of segments) {
2040
+ const trimmedSegment = segment.trim();
2041
+ if (!trimmedSegment) continue;
2042
+ const tokens = trimmedSegment.split(/\s+/);
2043
+ if (tokens.length === 0) continue;
2044
+ let startIndex = 0;
2045
+ const firstBinary = tokens[0].replace(/^.*\//, "");
2046
+ if (ENV_WRAPPER_BINARIES.has(firstBinary)) {
2047
+ startIndex = 1;
2048
+ while (startIndex < tokens.length && /^[A-Z_][A-Z0-9_]*=/.test(tokens[startIndex])) startIndex++;
2049
+ if (startIndex >= tokens.length) continue;
2050
+ }
2051
+ const binaryName = tokens[startIndex].replace(/^.*\//, "");
2052
+ if (SCRIPT_MULTIPLEXERS.has(binaryName)) continue;
2053
+ const effectiveBinaryName = binaryName === "npx" || binaryName === "pnpx" || binaryName === "bunx" ? tokens[startIndex + 1]?.replace(/^.*\//, "") ?? "" : binaryName;
2054
+ const isNonEntryBinary = IGNORED_CLI_TOOLS.has(binaryName) || effectiveBinaryName !== "" && IGNORED_CLI_TOOLS.has(effectiveBinaryName);
2055
+ for (let tokenIndex = startIndex + 1; tokenIndex < tokens.length; tokenIndex++) {
2056
+ const token = tokens[tokenIndex].replace(/^['"]|['"]$/g, "");
2057
+ if (CONFIG_LIKE_FLAGS.has(token)) {
2058
+ if (tokenIndex + 1 < tokens.length && !tokens[tokenIndex + 1].startsWith("-")) {
2059
+ const configPath = tokens[tokenIndex + 1].replace(/^['"]|['"]$/g, "");
2060
+ if (looksLikeFilePath(configPath)) {
2061
+ const absoluteConfigPath = (0, node_path.resolve)(directory, configPath);
2062
+ if ((0, node_fs.existsSync)(absoluteConfigPath)) entries.push(absoluteConfigPath);
2063
+ }
2064
+ tokenIndex++;
2065
+ }
2066
+ continue;
2067
+ }
2068
+ const equalsIndex = token.indexOf("=");
2069
+ if (equalsIndex > 0 && CONFIG_LIKE_FLAGS.has(token.slice(0, equalsIndex))) {
2070
+ const configValue = token.slice(equalsIndex + 1);
2071
+ if (configValue && looksLikeFilePath(configValue)) {
2072
+ const absoluteConfigPath = (0, node_path.resolve)(directory, configValue);
2073
+ if ((0, node_fs.existsSync)(absoluteConfigPath)) entries.push(absoluteConfigPath);
2074
+ }
2075
+ continue;
2076
+ }
2077
+ if (token.startsWith("-")) continue;
2078
+ if (isNonEntryBinary) continue;
2079
+ if (!looksLikeFilePath(token)) continue;
2080
+ if (isGlobPattern(token)) {
2081
+ const expandedFiles = fast_glob.default.sync(token, {
2082
+ cwd: directory,
2083
+ absolute: true,
2084
+ onlyFiles: true,
2085
+ ignore: ["**/node_modules/**"]
2086
+ });
2087
+ entries.push(...expandedFiles);
2088
+ } else {
2089
+ const absoluteFilePath = (0, node_path.resolve)(directory, token);
2090
+ if ((0, node_fs.existsSync)(absoluteFilePath)) entries.push(absoluteFilePath);
2091
+ else {
2092
+ const sourcePath = resolveSourcePath(absoluteFilePath, directory);
2093
+ if (sourcePath) entries.push(sourcePath);
2094
+ }
2095
+ }
2096
+ }
2097
+ }
2098
+ return entries;
2099
+ };
2100
+ const EXTENSIONLESS_SCRIPT_EXTENSIONS = [
2101
+ ".ts",
2102
+ ".tsx",
2103
+ ".js",
2104
+ ".jsx",
2105
+ ".mts",
2106
+ ".mjs",
2107
+ ".cjs"
2108
+ ];
2109
+ const resolveExtensionlessScriptPath = (basePath) => {
2110
+ for (const extension of EXTENSIONLESS_SCRIPT_EXTENSIONS) {
2111
+ const candidate = basePath + extension;
2112
+ if ((0, node_fs.existsSync)(candidate)) return candidate;
2113
+ }
2114
+ const indexCandidate = (0, node_path.resolve)(basePath, "index.ts");
2115
+ if ((0, node_fs.existsSync)(indexCandidate)) return indexCandidate;
2116
+ };
2117
+ const extractScriptEntries = (directory) => {
2118
+ const packageJsonPath = (0, node_path.resolve)(directory, "package.json");
2119
+ if (!(0, node_fs.existsSync)(packageJsonPath)) return [];
2120
+ const entries = [];
2121
+ try {
2122
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
2123
+ const scripts = JSON.parse(content).scripts;
2124
+ if (scripts && typeof scripts === "object") for (const scriptCommand of Object.values(scripts)) {
2125
+ if (typeof scriptCommand !== "string") continue;
2126
+ const match = scriptCommand.match(SCRIPT_FILE_PATTERN);
2127
+ if (match?.[1]) {
2128
+ const scriptFilePath = (0, node_path.resolve)(directory, match[1]);
2129
+ if ((0, node_fs.existsSync)(scriptFilePath)) entries.push(scriptFilePath);
2130
+ else {
2131
+ const sourcePath = resolveSourcePath(scriptFilePath, directory);
2132
+ if (sourcePath) entries.push(sourcePath);
2133
+ }
2134
+ } else {
2135
+ const extensionlessMatch = scriptCommand.match(SCRIPT_EXTENSIONLESS_FILE_PATTERN);
2136
+ if (extensionlessMatch?.[1]) {
2137
+ const extensionlessPath = extensionlessMatch[1];
2138
+ const resolved = resolveExtensionlessScriptPath((0, node_path.resolve)(directory, extensionlessPath));
2139
+ if (resolved) entries.push(resolved);
2140
+ }
2141
+ }
2142
+ const configMatch = scriptCommand.match(SCRIPT_CONFIG_FILE_PATTERN);
2143
+ if (configMatch?.[1]) {
2144
+ const configFilePath = (0, node_path.resolve)(directory, configMatch[1]);
2145
+ if ((0, node_fs.existsSync)(configFilePath)) entries.push(configFilePath);
2146
+ else {
2147
+ const sourcePath = resolveSourcePath(configFilePath, directory);
2148
+ if (sourcePath) entries.push(sourcePath);
2149
+ }
2150
+ }
2151
+ entries.push(...extractScriptFileArguments(scriptCommand, directory));
2152
+ }
2153
+ } catch {}
2154
+ const scriptDirectoryFiles = fast_glob.default.sync(SCRIPT_ENTRY_PATTERNS, {
2155
+ cwd: directory,
2156
+ absolute: true,
2157
+ onlyFiles: true,
2158
+ ignore: ["**/node_modules/**"]
2159
+ });
2160
+ entries.push(...scriptDirectoryFiles);
2161
+ return entries;
2162
+ };
2163
+ const isYamlMapping = (line) => {
2164
+ const firstWord = line.split(/\s/)[0];
2165
+ if (!firstWord) return false;
2166
+ return firstWord.endsWith(":") && !firstWord.startsWith("http") && !firstWord.startsWith("ftp");
2167
+ };
2168
+ const extractCiRunCommands = (content) => {
2169
+ const commands = [];
2170
+ let inMultilineRun = false;
2171
+ let multilineIndent = 0;
2172
+ for (const line of content.split("\n")) {
2173
+ const trimmedLine = line.trim();
2174
+ if (trimmedLine === "" || trimmedLine.startsWith("#")) continue;
2175
+ if (inMultilineRun) {
2176
+ if (line.length - line.trimStart().length > multilineIndent && trimmedLine !== "") {
2177
+ commands.push(trimmedLine);
2178
+ continue;
2179
+ }
2180
+ inMultilineRun = false;
2181
+ }
2182
+ const runMatch = trimmedLine.match(/^(?:-\s+)?run:\s*(.*)$/);
2183
+ if (runMatch) {
2184
+ const runValue = runMatch[1].trim();
2185
+ if (runValue === "|" || runValue === "|-" || runValue === "|+") {
2186
+ inMultilineRun = true;
2187
+ multilineIndent = line.length - line.trimStart().length;
2188
+ } else if (runValue !== "") commands.push(runValue);
2189
+ continue;
2190
+ }
2191
+ if (trimmedLine.startsWith("- ")) {
2192
+ const listItem = trimmedLine.slice(2).trim();
2193
+ if (listItem !== "" && !listItem.startsWith("{") && !listItem.startsWith("[") && !isYamlMapping(listItem)) commands.push(listItem);
2194
+ }
2195
+ }
2196
+ return commands;
2197
+ };
2198
+ const extractCiWorkflowEntries = (rootDir) => {
2199
+ const entries = [];
2200
+ const workflowsDir = (0, node_path.join)(rootDir, ".github", "workflows");
2201
+ if (!(0, node_fs.existsSync)(workflowsDir)) return entries;
2202
+ const workflowFiles = fast_glob.default.sync("*.{yml,yaml}", {
2203
+ cwd: workflowsDir,
2204
+ absolute: true,
2205
+ onlyFiles: true
2206
+ });
2207
+ for (const workflowFile of workflowFiles) try {
2208
+ const runCommands = extractCiRunCommands((0, node_fs.readFileSync)(workflowFile, "utf-8"));
2209
+ for (const command of runCommands) {
2210
+ const scriptMatch = command.match(SCRIPT_FILE_PATTERN);
2211
+ if (scriptMatch?.[1]) {
2212
+ const scriptFilePath = (0, node_path.resolve)(rootDir, scriptMatch[1]);
2213
+ if ((0, node_fs.existsSync)(scriptFilePath)) entries.push(scriptFilePath);
2214
+ }
2215
+ const configMatch = command.match(SCRIPT_CONFIG_FILE_PATTERN);
2216
+ if (configMatch?.[1]) {
2217
+ const configFilePath = (0, node_path.resolve)(rootDir, configMatch[1]);
2218
+ if ((0, node_fs.existsSync)(configFilePath)) entries.push(configFilePath);
2219
+ }
2220
+ }
2221
+ } catch {}
2222
+ return entries;
2223
+ };
2224
+ const VITE_INPUT_BLOCK_PATTERN = /input\s*:\s*(?:\{[^}]*\}|\[[^\]]*\]|['"][^'"]+['"])/gs;
2225
+ const BUNDLER_ENTRY_FILE_PATTERN = /['"]([^'"]+\.(?:js|ts|tsx|jsx|mjs|mts|less|scss|css|sass|html))['"]/g;
2226
+ const extractViteEntryPoints = (directory) => {
2227
+ const entries = [];
2228
+ const viteConfigPaths = fast_glob.default.sync("vite.config.{js,ts,mjs,mts}", {
2229
+ cwd: directory,
2230
+ absolute: true,
2231
+ onlyFiles: true
2232
+ });
2233
+ for (const configPath of viteConfigPaths) try {
2234
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2235
+ let inputMatch;
2236
+ VITE_INPUT_BLOCK_PATTERN.lastIndex = 0;
2237
+ while ((inputMatch = VITE_INPUT_BLOCK_PATTERN.exec(content)) !== null) {
2238
+ const inputBlock = inputMatch[0];
2239
+ let valueMatch;
2240
+ BUNDLER_ENTRY_FILE_PATTERN.lastIndex = 0;
2241
+ while ((valueMatch = BUNDLER_ENTRY_FILE_PATTERN.exec(inputBlock)) !== null) {
2242
+ const entryPath = valueMatch[1];
2243
+ if (entryPath.startsWith("./") || entryPath.startsWith("../") || !entryPath.startsWith("/")) {
2244
+ const absoluteEntryPath = (0, node_path.resolve)(directory, entryPath);
2245
+ if ((0, node_fs.existsSync)(absoluteEntryPath)) entries.push(absoluteEntryPath);
2246
+ }
2247
+ }
2248
+ }
2249
+ } catch {}
2250
+ return entries;
2251
+ };
2252
+ const BUNDLER_CONFIG_ENTRY_BLOCK_PATTERN = /entry\s*:\s*\[([^\]]*)\]/gs;
2253
+ const BUNDLER_CONFIG_ENTRY_STRING_PATTERN = /['"]([^'"]+)['"]/g;
2254
+ const extractBundlerConfigEntryPoints = (directory) => {
2255
+ const entries = [];
2256
+ const configPaths = fast_glob.default.sync(["tsdown.config.{ts,js,cjs,mjs}", "tsup.config.{ts,js,cjs,mjs}"], {
2257
+ cwd: directory,
2258
+ absolute: true,
2259
+ onlyFiles: true
2260
+ });
2261
+ for (const configPath of configPaths) try {
2262
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2263
+ let blockMatch;
2264
+ BUNDLER_CONFIG_ENTRY_BLOCK_PATTERN.lastIndex = 0;
2265
+ while ((blockMatch = BUNDLER_CONFIG_ENTRY_BLOCK_PATTERN.exec(content)) !== null) {
2266
+ const arrayContent = blockMatch[1];
2267
+ let stringMatch;
2268
+ BUNDLER_CONFIG_ENTRY_STRING_PATTERN.lastIndex = 0;
2269
+ while ((stringMatch = BUNDLER_CONFIG_ENTRY_STRING_PATTERN.exec(arrayContent)) !== null) {
2270
+ const entryPath = stringMatch[1];
2271
+ const resolvedPath = resolveEntryWithExtensions((0, node_path.resolve)(directory, entryPath));
2272
+ if (resolvedPath) entries.push(resolvedPath);
2273
+ }
2274
+ }
2275
+ } catch {}
2276
+ return entries;
2277
+ };
2278
+ const WEBPACK_ENTRY_BLOCK_PATTERN = /entry\s*:\s*(?:\{[^}]*\}|\[[^\]]*\]|['"][^'"]+['"]|path\.(?:join|resolve)\([^)]*\))/gs;
2279
+ const WEBPACK_ENTRY_FILE_PATTERN = /['"]([^'"]+)['"]/g;
2280
+ const WEBPACK_PATH_JOIN_PATTERN = /path\.(?:join|resolve)\(\s*__dirname\s*,\s*((?:['"][^'"]*['"]\s*,?\s*)+)\)/g;
2281
+ const REQUIRE_RESOLVE_PATTERN = /require\.resolve\(\s*['"]([^'"]+)['"]\s*\)/g;
2282
+ const RESOLVABLE_EXTENSIONS = [
2283
+ ".ts",
2284
+ ".tsx",
2285
+ ".js",
2286
+ ".jsx",
2287
+ ".mjs",
2288
+ ".mts"
2289
+ ];
2290
+ const resolveEntryWithExtensions = (basePath) => {
2291
+ if ((0, node_fs.existsSync)(basePath)) return basePath;
2292
+ for (const extension of RESOLVABLE_EXTENSIONS) {
2293
+ const withExtension = basePath + extension;
2294
+ if ((0, node_fs.existsSync)(withExtension)) return withExtension;
2295
+ }
2296
+ const indexCandidates = RESOLVABLE_EXTENSIONS.map((extension) => (0, node_path.resolve)(basePath, `index${extension}`));
2297
+ for (const candidate of indexCandidates) if ((0, node_fs.existsSync)(candidate)) return candidate;
2298
+ };
2299
+ const extractWebpackEntryPoints = (directory) => {
2300
+ const entries = [];
2301
+ const webpackConfigPaths = fast_glob.default.sync([
2302
+ "webpack.config.{js,ts,mjs,cjs}",
2303
+ "**/webpack*.config.{js,ts,mjs,cjs}",
2304
+ "**/webpack.config*.{js,ts,mjs,cjs}",
2305
+ "**/webpack*.config*.babel.{js,ts}"
2306
+ ], {
2307
+ cwd: directory,
2308
+ absolute: true,
2309
+ onlyFiles: true,
2310
+ ignore: ["**/node_modules/**"],
2311
+ deep: 3
2312
+ });
2313
+ for (const configPath of webpackConfigPaths) try {
2314
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2315
+ const configDirectory = (0, node_path.dirname)(configPath);
2316
+ let pathJoinMatch;
2317
+ WEBPACK_PATH_JOIN_PATTERN.lastIndex = 0;
2318
+ while ((pathJoinMatch = WEBPACK_PATH_JOIN_PATTERN.exec(content)) !== null) {
2319
+ const segments = [...pathJoinMatch[1].matchAll(/['"]([^'"]*)['"]/g)].map((match) => match[1]);
2320
+ if (segments.length > 0) {
2321
+ const resolvedEntry = resolveEntryWithExtensions((0, node_path.resolve)(configDirectory, ...segments));
2322
+ if (resolvedEntry) entries.push(resolvedEntry);
2323
+ }
2324
+ }
2325
+ let requireResolveMatch;
2326
+ REQUIRE_RESOLVE_PATTERN.lastIndex = 0;
2327
+ while ((requireResolveMatch = REQUIRE_RESOLVE_PATTERN.exec(content)) !== null) {
2328
+ const requirePath = requireResolveMatch[1];
2329
+ if (requirePath.startsWith("./") || requirePath.startsWith("../")) {
2330
+ const resolvedEntry = resolveEntryWithExtensions((0, node_path.resolve)(configDirectory, requirePath));
2331
+ if (resolvedEntry) entries.push(resolvedEntry);
2332
+ }
2333
+ }
2334
+ let entryMatch;
2335
+ WEBPACK_ENTRY_BLOCK_PATTERN.lastIndex = 0;
2336
+ while ((entryMatch = WEBPACK_ENTRY_BLOCK_PATTERN.exec(content)) !== null) {
2337
+ const entryBlock = entryMatch[0];
2338
+ if (entryBlock.includes("path.join") || entryBlock.includes("path.resolve")) continue;
2339
+ let valueMatch;
2340
+ WEBPACK_ENTRY_FILE_PATTERN.lastIndex = 0;
2341
+ while ((valueMatch = WEBPACK_ENTRY_FILE_PATTERN.exec(entryBlock)) !== null) {
2342
+ const entryPath = valueMatch[1];
2343
+ if (entryPath.startsWith("./") || entryPath.startsWith("../") || !entryPath.startsWith("/")) {
2344
+ const resolvedEntry = resolveEntryWithExtensions((0, node_path.resolve)(directory, entryPath));
2345
+ if (resolvedEntry) entries.push(resolvedEntry);
2346
+ }
2347
+ }
2348
+ }
2349
+ } catch {}
2350
+ return entries;
2351
+ };
2352
+ const HTML_SCRIPT_SRC_PATTERN = /<script[^>]+src=["']([^"']+\.(?:ts|tsx|js|jsx|mts|mjs))["'][^>]*>/gi;
2353
+ const extractHtmlScriptEntries = (directory) => {
2354
+ const entries = [];
2355
+ const htmlFiles = fast_glob.default.sync(["index.html", "*.html"], {
2356
+ cwd: directory,
2357
+ absolute: true,
2358
+ onlyFiles: true,
2359
+ ignore: [
2360
+ "**/node_modules/**",
2361
+ "**/dist/**",
2362
+ "**/build/**"
2363
+ ],
2364
+ deep: 1
2365
+ });
2366
+ for (const htmlPath of htmlFiles) try {
2367
+ const content = (0, node_fs.readFileSync)(htmlPath, "utf-8");
2368
+ let scriptMatch;
2369
+ HTML_SCRIPT_SRC_PATTERN.lastIndex = 0;
2370
+ while ((scriptMatch = HTML_SCRIPT_SRC_PATTERN.exec(content)) !== null) {
2371
+ const scriptSrc = scriptMatch[1].replace(/^\//, "");
2372
+ const absoluteScriptPath = (0, node_path.resolve)(htmlPath.replace(/\/[^/]+$/, ""), scriptSrc);
2373
+ if ((0, node_fs.existsSync)(absoluteScriptPath)) entries.push(absoluteScriptPath);
2374
+ }
2375
+ } catch {}
2376
+ return entries;
2377
+ };
2378
+ const extractScriptTagsFromHtmlFile = (htmlFilePath) => {
2379
+ const entries = [];
2380
+ try {
2381
+ const content = (0, node_fs.readFileSync)(htmlFilePath, "utf-8");
2382
+ let scriptMatch;
2383
+ HTML_SCRIPT_SRC_PATTERN.lastIndex = 0;
2384
+ while ((scriptMatch = HTML_SCRIPT_SRC_PATTERN.exec(content)) !== null) {
2385
+ const scriptSrc = scriptMatch[1].replace(/^\//, "");
2386
+ const absoluteScriptPath = (0, node_path.resolve)((0, node_path.dirname)(htmlFilePath), scriptSrc);
2387
+ if ((0, node_fs.existsSync)(absoluteScriptPath)) entries.push(absoluteScriptPath);
2388
+ }
2389
+ } catch {}
2390
+ return entries;
2391
+ };
2392
+ const ANGULAR_ENTRY_KEYS = [
2393
+ "main",
2394
+ "polyfills",
2395
+ "styles"
2396
+ ];
2397
+ const extractAngularEntryPoints = (directory) => {
2398
+ const entries = [];
2399
+ const angularJsonPaths = fast_glob.default.sync(["angular.json", ".angular-cli.json"], {
2400
+ cwd: directory,
2401
+ absolute: true,
2402
+ onlyFiles: true
2403
+ });
2404
+ for (const angularJsonPath of angularJsonPaths) try {
2405
+ const content = (0, node_fs.readFileSync)(angularJsonPath, "utf-8");
2406
+ const projects = JSON.parse(content).projects ?? {};
2407
+ const angularDir = angularJsonPath.replace(/\/[^/]+$/, "");
2408
+ for (const projectConfig of Object.values(projects)) {
2409
+ const projectRecord = projectConfig;
2410
+ const architect = projectRecord.architect;
2411
+ if (architect) for (const targetConfig of Object.values(architect)) {
2412
+ const options = targetConfig.options;
2413
+ if (!options) continue;
2414
+ for (const entryKey of ANGULAR_ENTRY_KEYS) {
2415
+ const entryValue = options[entryKey];
2416
+ if (typeof entryValue === "string") {
2417
+ const absolutePath = (0, node_path.resolve)(angularDir, entryValue);
2418
+ if ((0, node_fs.existsSync)(absolutePath)) entries.push(absolutePath);
2419
+ }
2420
+ if (Array.isArray(entryValue)) {
2421
+ for (const entryItem of entryValue) if (typeof entryItem === "string") {
2422
+ const absolutePath = (0, node_path.resolve)(angularDir, entryItem);
2423
+ if ((0, node_fs.existsSync)(absolutePath)) entries.push(absolutePath);
2424
+ }
2425
+ }
2426
+ }
2427
+ }
2428
+ const projectDir = (0, node_path.resolve)(angularDir, typeof projectRecord.root === "string" ? projectRecord.root : "");
2429
+ const ngPackagePaths = fast_glob.default.sync(["ng-package.json", "**/ng-package.json"], {
2430
+ cwd: projectDir,
2431
+ absolute: true,
2432
+ onlyFiles: true,
2433
+ deep: 2,
2434
+ ignore: ["**/node_modules/**"]
2435
+ });
2436
+ for (const ngPackagePath of ngPackagePaths) try {
2437
+ const ngContent = (0, node_fs.readFileSync)(ngPackagePath, "utf-8");
2438
+ const ngPackage = JSON.parse(ngContent);
2439
+ const ngDir = ngPackagePath.replace(/\/[^/]+$/, "");
2440
+ const libEntry = ngPackage?.lib?.entryFile;
2441
+ if (typeof libEntry === "string") {
2442
+ const absoluteEntry = (0, node_path.resolve)(ngDir, libEntry);
2443
+ if ((0, node_fs.existsSync)(absoluteEntry)) entries.push(absoluteEntry);
2444
+ }
2445
+ } catch {}
2446
+ }
2447
+ } catch {}
2448
+ return entries;
2449
+ };
2450
+ const PLUGIN_FILE_ARGUMENT_PATTERN = /(?:createNextIntlPlugin|createMDX|withContentlayer|withPlaiceholder)\s*\(\s*['"]([^'"]+)['"]/g;
2451
+ const NEXT_INTL_IMPORT_PATTERN = /createNextIntlPlugin/;
2452
+ const NEXT_INTL_DEFAULT_PATHS = [
2453
+ "src/i18n/request.ts",
2454
+ "src/i18n/request.tsx",
2455
+ "src/i18n/request.js",
2456
+ "i18n/request.ts",
2457
+ "i18n/request.tsx",
2458
+ "i18n/request.js",
2459
+ "i18n.ts",
2460
+ "i18n.tsx"
2461
+ ];
2462
+ const extractNextConfigPluginFiles = (directory) => {
2463
+ const entries = [];
2464
+ const nextConfigPaths = fast_glob.default.sync(["next.config.{ts,js,mjs,mts}"], {
2465
+ cwd: directory,
2466
+ absolute: true,
2467
+ onlyFiles: true,
2468
+ ignore: ["**/node_modules/**"]
2469
+ });
2470
+ for (const configPath of nextConfigPaths) try {
2471
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2472
+ const configDirectory = configPath.replace(/\/[^/]+$/, "");
2473
+ let pluginMatch;
2474
+ PLUGIN_FILE_ARGUMENT_PATTERN.lastIndex = 0;
2475
+ let didMatchNextIntlWithPath = false;
2476
+ while ((pluginMatch = PLUGIN_FILE_ARGUMENT_PATTERN.exec(content)) !== null) {
2477
+ const filePath = pluginMatch[1];
2478
+ const absolutePath = (0, node_path.resolve)(configDirectory, filePath);
2479
+ if ((0, node_fs.existsSync)(absolutePath)) entries.push(absolutePath);
2480
+ if (pluginMatch[0].includes("createNextIntlPlugin")) didMatchNextIntlWithPath = true;
2481
+ }
2482
+ if (!didMatchNextIntlWithPath && NEXT_INTL_IMPORT_PATTERN.test(content)) for (const defaultPath of NEXT_INTL_DEFAULT_PATHS) {
2483
+ const absolutePath = (0, node_path.resolve)(configDirectory, defaultPath);
2484
+ if ((0, node_fs.existsSync)(absolutePath)) {
2485
+ entries.push(absolutePath);
2486
+ break;
2487
+ }
2488
+ }
2489
+ } catch {}
2490
+ return entries;
2491
+ };
2492
+ const VITEST_INCLUDE_ITEM_PATTERN = /['"]([^'"]+)['"]/g;
2493
+ const COVERAGE_BLOCK_PATTERN = /coverage\s*:\s*\{/g;
2494
+ const TEST_MATCH_ARRAY_PATTERN = /testMatch\s*:\s*\[([^\]]*)\]/;
2495
+ const STRING_LITERAL_PATTERN = /['"]([^'"]+)['"]/g;
2496
+ const extractJestTestMatchPatterns = (directory) => {
2497
+ const configPaths = fast_glob.default.sync(["jest.config.{ts,js,mjs,cjs}"], {
2498
+ cwd: directory,
2499
+ absolute: true,
2500
+ onlyFiles: true,
2501
+ ignore: ["**/node_modules/**"]
2502
+ });
2503
+ if (configPaths.length === 0) {
2504
+ try {
2505
+ const packageContent = (0, node_fs.readFileSync)((0, node_path.join)(directory, "package.json"), "utf-8");
2506
+ const packageJson = JSON.parse(packageContent);
2507
+ if (packageJson.jest?.testMatch) return convertJestTestMatchToGlobs(packageJson.jest.testMatch);
2508
+ } catch {}
2509
+ return [];
2510
+ }
2511
+ for (const configPath of configPaths) try {
2512
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2513
+ const testMatchMatch = TEST_MATCH_ARRAY_PATTERN.exec(content);
2514
+ if (!testMatchMatch) continue;
2515
+ const arrayContent = testMatchMatch[1];
2516
+ const patterns = [];
2517
+ STRING_LITERAL_PATTERN.lastIndex = 0;
2518
+ let itemMatch;
2519
+ while ((itemMatch = STRING_LITERAL_PATTERN.exec(arrayContent)) !== null) patterns.push(itemMatch[1]);
2520
+ if (patterns.length > 0) return convertJestTestMatchToGlobs(patterns);
2521
+ } catch {}
2522
+ return [];
2523
+ };
2524
+ const convertJestTestMatchToGlobs = (patterns) => {
2525
+ return patterns.map((pattern) => {
2526
+ let converted = pattern.replace(/<rootDir>\/?/g, "");
2527
+ converted = converted.replace(/\?\(\*\.\)/g, "*.");
2528
+ converted = converted.replace(/\?\(([^)]+)\)/g, (_, group) => {
2529
+ return `{${[...group.includes("|") ? group.split("|") : [group], ""].join(",")}}`;
2530
+ });
2531
+ converted = converted.replace(/\+\(([^)]+)\)/g, (_, group) => {
2532
+ return group.includes("|") ? `{${group.replace(/\|/g, ",")}}` : group;
2533
+ });
2534
+ converted = converted.replace(/\(([^)]+)\)/g, (_, group) => {
2535
+ return group.includes("|") ? `{${group.replace(/\|/g, ",")}}` : group;
2536
+ });
2537
+ return converted;
2538
+ });
2539
+ };
2540
+ const extractVitestIncludePatterns = (directory) => {
2541
+ const configPaths = fast_glob.default.sync(["vitest.config.{ts,js,mts,mjs}", "vitest.web.config.{ts,js,mts,mjs}"], {
2542
+ cwd: directory,
2543
+ absolute: true,
2544
+ onlyFiles: true,
2545
+ ignore: ["**/node_modules/**"]
2546
+ });
2547
+ const patterns = [];
2548
+ for (const configPath of configPaths) try {
2549
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2550
+ const coverageBlockRanges = findNestedBlockRanges(content, COVERAGE_BLOCK_PATTERN);
2551
+ const includePattern = /include\s*:\s*\[([^\]]*)\]/g;
2552
+ includePattern.lastIndex = 0;
2553
+ let includeMatch;
2554
+ while ((includeMatch = includePattern.exec(content)) !== null) {
2555
+ const matchStart = includeMatch.index;
2556
+ if (coverageBlockRanges.some(([blockStart, blockEnd]) => matchStart > blockStart && matchStart < blockEnd)) continue;
2557
+ const arrayContent = includeMatch[1];
2558
+ VITEST_INCLUDE_ITEM_PATTERN.lastIndex = 0;
2559
+ let itemMatch;
2560
+ while ((itemMatch = VITEST_INCLUDE_ITEM_PATTERN.exec(arrayContent)) !== null) patterns.push(itemMatch[1]);
2561
+ }
2562
+ } catch {}
2563
+ return patterns;
2564
+ };
2565
+ const findNestedBlockRanges = (content, blockStartPattern) => {
2566
+ const ranges = [];
2567
+ blockStartPattern.lastIndex = 0;
2568
+ let blockMatch;
2569
+ while ((blockMatch = blockStartPattern.exec(content)) !== null) {
2570
+ const openBraceIndex = content.indexOf("{", blockMatch.index);
2571
+ if (openBraceIndex === -1) continue;
2572
+ let braceDepth = 1;
2573
+ let position = openBraceIndex + 1;
2574
+ while (position < content.length && braceDepth > 0) {
2575
+ if (content[position] === "{") braceDepth++;
2576
+ if (content[position] === "}") braceDepth--;
2577
+ position++;
2578
+ }
2579
+ ranges.push([blockMatch.index, position]);
2580
+ }
2581
+ return ranges;
2582
+ };
2583
+ const SETUP_FILES_PATTERN = /(?:setupFiles|setupFilesAfterEnv|globalSetup|globalTeardown)\s*:\s*(?:\[([^\]]*)\]|['"]([^'"]+)['"])/gs;
2584
+ const SETUP_FILE_PATH_PATTERN = /['"]([^'"]+)['"]/g;
2585
+ const extractTestSetupFiles = (directory) => {
2586
+ const entries = [];
2587
+ const configPaths = fast_glob.default.sync([
2588
+ "vitest.config.{ts,js,mts,mjs}",
2589
+ "vitest.web.config.{ts,js,mts,mjs}",
2590
+ "vite.config.{ts,js,mts,mjs}",
2591
+ "jest.config.{ts,js,mjs,cjs}",
2592
+ "**/vitest.config.{ts,js,mts,mjs}"
2593
+ ], {
2594
+ cwd: directory,
2595
+ absolute: true,
2596
+ onlyFiles: true,
2597
+ ignore: ["**/node_modules/**"],
2598
+ deep: 3
2599
+ });
2600
+ for (const configPath of configPaths) try {
2601
+ const content = (0, node_fs.readFileSync)(configPath, "utf-8");
2602
+ const configDirectory = configPath.replace(/\/[^/]+$/, "");
2603
+ let setupMatch;
2604
+ SETUP_FILES_PATTERN.lastIndex = 0;
2605
+ while ((setupMatch = SETUP_FILES_PATTERN.exec(content)) !== null) {
2606
+ const arrayContent = setupMatch[1];
2607
+ const singleValue = setupMatch[2];
2608
+ if (singleValue) {
2609
+ const absolutePath = (0, node_path.resolve)(configDirectory, singleValue);
2610
+ if ((0, node_fs.existsSync)(absolutePath)) entries.push(absolutePath);
2611
+ }
2612
+ if (arrayContent) {
2613
+ let pathMatch;
2614
+ SETUP_FILE_PATH_PATTERN.lastIndex = 0;
2615
+ while ((pathMatch = SETUP_FILE_PATH_PATTERN.exec(arrayContent)) !== null) {
2616
+ const absolutePath = (0, node_path.resolve)(configDirectory, pathMatch[1]);
2617
+ if ((0, node_fs.existsSync)(absolutePath)) entries.push(absolutePath);
2618
+ }
2619
+ }
2620
+ }
2621
+ } catch {}
2622
+ return entries;
2623
+ };
2624
+ const IMPORTABLE_EXTENSION_SET = new Set(SOURCE_EXTENSIONS$3.map((extension) => `.${extension}`));
2625
+ const isImportableSourceFile = (filePath) => IMPORTABLE_EXTENSION_SET.has(filePath.slice(filePath.lastIndexOf(".")));
2626
+ const expandWildcardExportPattern = (pattern, rootDir) => {
2627
+ const normalized = pattern.startsWith("./") ? pattern.slice(2) : pattern;
2628
+ return fast_glob.default.sync(normalized, {
2629
+ cwd: rootDir,
2630
+ absolute: true,
2631
+ onlyFiles: true,
2632
+ ignore: ["**/node_modules/**"]
2633
+ }).filter(isImportableSourceFile);
2634
+ };
2635
+ const collectExportPaths = (exportValue, rootDir, entries) => {
2636
+ if (typeof exportValue === "string") {
2637
+ if (exportValue.includes("*")) {
2638
+ const expandedFiles = expandWildcardExportPattern(exportValue, rootDir);
2639
+ entries.push(...expandedFiles);
2640
+ return;
2641
+ }
2642
+ entries.push(resolveEntryPath(exportValue, rootDir));
2643
+ return;
2644
+ }
2645
+ if (typeof exportValue !== "object" || exportValue === null) return;
2646
+ for (const [, nestedValue] of Object.entries(exportValue)) collectExportPaths(nestedValue, rootDir, entries);
2647
+ };
2648
+ const TEST_FRAMEWORK_PATTERNS = [
2649
+ {
2650
+ enablers: [
2651
+ "vitest",
2652
+ "@vitest/runner",
2653
+ "vite-plus"
2654
+ ],
2655
+ configFileActivators: [
2656
+ "vitest.config.ts",
2657
+ "vitest.config.js",
2658
+ "vitest.config.mts",
2659
+ "vitest.config.mjs"
2660
+ ],
2661
+ entryPatterns: [
2662
+ "**/*.test.{ts,tsx,js,jsx}",
2663
+ "**/*.spec.{ts,tsx,js,jsx}",
2664
+ "**/__tests__/**/*.{ts,tsx,js,jsx}",
2665
+ "**/*.bench.{ts,tsx,js,jsx}"
2666
+ ],
2667
+ fixturePatterns: ["**/__fixtures__/**/*.{ts,tsx,js,jsx,json}", "**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
2668
+ alwaysUsed: [
2669
+ "vitest.config.{ts,js,mts,mjs}",
2670
+ "vitest.setup.{ts,js}",
2671
+ "vitest.workspace.{ts,js}",
2672
+ "**/src/setupTests.{ts,tsx,js,jsx}",
2673
+ "**/src/test-setup.{ts,tsx,js,jsx}"
2674
+ ]
2675
+ },
2676
+ {
2677
+ enablers: [
2678
+ "jest",
2679
+ "@jest/core",
2680
+ "ts-jest"
2681
+ ],
2682
+ configFileActivators: [
2683
+ "jest.config.ts",
2684
+ "jest.config.js",
2685
+ "jest.config.mjs",
2686
+ "jest.config.cjs"
2687
+ ],
2688
+ entryPatterns: [
2689
+ "**/*.test.{ts,tsx,js,jsx}",
2690
+ "**/*.spec.{ts,tsx,js,jsx}",
2691
+ "**/__tests__/**/*.{ts,tsx,js,jsx}",
2692
+ "**/__mocks__/**/*.{ts,tsx,js,jsx,mjs,cjs}"
2693
+ ],
2694
+ fixturePatterns: ["**/__fixtures__/**/*.{ts,tsx,js,jsx,json}", "**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
2695
+ alwaysUsed: ["jest.config.{ts,js,mjs,cjs}", "jest.setup.{ts,js,tsx,jsx}"]
2696
+ },
2697
+ {
2698
+ enablers: ["@playwright/test", "playwright"],
2699
+ configFileActivators: ["playwright.config.ts", "playwright.config.js"],
2700
+ entryPatterns: [
2701
+ "**/*.spec.{ts,tsx,js,jsx}",
2702
+ "**/*.test.{ts,tsx,js,jsx}",
2703
+ "tests/**/*.{ts,tsx,js,jsx}",
2704
+ "e2e/**/*.{ts,tsx,js,jsx}"
2705
+ ],
2706
+ fixturePatterns: ["**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
2707
+ alwaysUsed: ["playwright.config.{ts,js}"]
2708
+ },
2709
+ {
2710
+ enablers: ["mocha"],
2711
+ configFileActivators: [
2712
+ ".mocharc.js",
2713
+ ".mocharc.yaml",
2714
+ ".mocharc.yml",
2715
+ ".mocharc.json"
2716
+ ],
2717
+ entryPatterns: [
2718
+ "test/**/*.{ts,tsx,js,jsx}",
2719
+ "tests/**/*.{ts,tsx,js,jsx}",
2720
+ "spec/**/*.{ts,tsx,js,jsx}",
2721
+ "**/*.test.{ts,tsx,js,jsx}",
2722
+ "**/*.spec.{ts,tsx,js,jsx}"
2723
+ ],
2724
+ fixturePatterns: [],
2725
+ alwaysUsed: [".mocharc.*"]
2726
+ },
2727
+ {
2728
+ enablers: ["ava", "@ava/typescript"],
2729
+ configFileActivators: [
2730
+ "ava.config.js",
2731
+ "ava.config.cjs",
2732
+ "ava.config.mjs"
2733
+ ],
2734
+ entryPatterns: [
2735
+ "test/**/*.{ts,tsx,js,jsx}",
2736
+ "tests/**/*.{ts,tsx,js,jsx}",
2737
+ "**/*.test.{ts,tsx,js,jsx}",
2738
+ "**/*.spec.{ts,tsx,js,jsx}"
2739
+ ],
2740
+ fixturePatterns: [],
2741
+ alwaysUsed: ["ava.config.{js,cjs,mjs}"]
2742
+ },
2743
+ {
2744
+ enablers: ["cypress"],
2745
+ configFileActivators: ["cypress.config.ts", "cypress.config.js"],
2746
+ entryPatterns: [
2747
+ "**/*.cy.{ts,tsx,js,jsx}",
2748
+ "cypress/**/*.{ts,tsx,js,jsx}",
2749
+ "cypress/support/**/*.{ts,js}"
2750
+ ],
2751
+ fixturePatterns: ["**/fixtures/**/*.{ts,tsx,js,jsx,json}"],
2752
+ alwaysUsed: ["cypress.config.{ts,js}", "cypress.config.*.{ts,js}"]
2753
+ }
2754
+ ];
2755
+ const FRAMEWORK_PATTERNS = [
2756
+ {
2757
+ enablers: ["storybook"],
2758
+ enablerPrefixes: ["@storybook/"],
2759
+ entryPatterns: ["**/*.stories.{ts,tsx,js,jsx,mdx}", ".storybook/**/*.{ts,tsx,js,jsx}"],
2760
+ alwaysUsed: [
2761
+ ".storybook/main.{ts,js,mjs,cjs}",
2762
+ ".storybook/preview.{ts,tsx,js,jsx}",
2763
+ ".storybook/manager.{ts,tsx,js,jsx}"
2764
+ ]
2765
+ },
2766
+ {
2767
+ enablers: ["msw"],
2768
+ enablerPrefixes: [],
2769
+ entryPatterns: [
2770
+ "mocks/**/*.{ts,tsx,js,jsx}",
2771
+ "src/mocks/**/*.{ts,tsx,js,jsx}",
2772
+ "**/mocks/**/*.{ts,tsx,js,jsx}"
2773
+ ],
2774
+ alwaysUsed: []
2775
+ },
2776
+ {
2777
+ enablers: ["typeorm"],
2778
+ enablerPrefixes: [],
2779
+ entryPatterns: [
2780
+ "migrations/**/*.{ts,js}",
2781
+ "src/migrations/**/*.{ts,js}",
2782
+ "src/migration/**/*.{ts,js}",
2783
+ "migration/**/*.{ts,js}",
2784
+ "src/entity/**/*.{ts,js}"
2785
+ ],
2786
+ alwaysUsed: ["ormconfig.{ts,js,json}"]
2787
+ },
2788
+ {
2789
+ enablers: ["knex"],
2790
+ enablerPrefixes: [],
2791
+ entryPatterns: ["migrations/**/*.{ts,js}", "seeds/**/*.{ts,js}"],
2792
+ alwaysUsed: ["knexfile.{ts,js}"]
2793
+ },
2794
+ {
2795
+ enablers: ["drizzle-orm"],
2796
+ enablerPrefixes: [],
2797
+ entryPatterns: ["drizzle/**/*.{ts,js}"],
2798
+ alwaysUsed: ["drizzle.config.{ts,js,mjs}"]
2799
+ },
2800
+ {
2801
+ enablers: ["kysely"],
2802
+ enablerPrefixes: [],
2803
+ entryPatterns: ["migrations/**/*.{ts,js}", "src/migrations/**/*.{ts,js}"],
2804
+ alwaysUsed: []
2805
+ },
2806
+ {
2807
+ enablers: ["prisma", "@prisma/client"],
2808
+ enablerPrefixes: [],
2809
+ entryPatterns: ["prisma/**/*.{ts,js}", "prisma/seed.{ts,js}"],
2810
+ alwaysUsed: [
2811
+ "prisma/schema.prisma",
2812
+ "schema.prisma",
2813
+ "prisma/schema/*.prisma",
2814
+ "prisma.config.{ts,mts,cts,js,mjs,cjs}",
2815
+ ".config/prisma.{ts,mts,cts,js,mjs,cjs}"
2816
+ ]
2817
+ },
2818
+ {
2819
+ enablers: ["@nestjs/core"],
2820
+ enablerPrefixes: ["@nestjs/"],
2821
+ entryPatterns: [
2822
+ "src/main.ts",
2823
+ "src/**/*.module.ts",
2824
+ "src/**/*.controller.ts",
2825
+ "src/**/*.service.ts",
2826
+ "src/**/*.guard.ts",
2827
+ "src/**/*.interceptor.ts",
2828
+ "src/**/*.pipe.ts",
2829
+ "src/**/*.filter.ts",
2830
+ "src/**/*.middleware.ts",
2831
+ "src/**/*.decorator.ts",
2832
+ "src/**/*.gateway.ts",
2833
+ "src/**/*.resolver.ts"
2834
+ ],
2835
+ alwaysUsed: ["nest-cli.json"]
2836
+ },
2837
+ {
2838
+ enablers: ["wrangler"],
2839
+ enablerPrefixes: ["@cloudflare/"],
2840
+ entryPatterns: [
2841
+ "src/index.{ts,js}",
2842
+ "src/worker.{ts,js}",
2843
+ "functions/**/*.{ts,js}"
2844
+ ],
2845
+ alwaysUsed: []
2846
+ },
2847
+ {
2848
+ enablers: ["gatsby"],
2849
+ enablerPrefixes: ["gatsby-"],
2850
+ entryPatterns: [
2851
+ "src/pages/**/*.{ts,tsx,js,jsx}",
2852
+ "src/templates/**/*.{ts,tsx,js,jsx}",
2853
+ "src/api/**/*.{ts,js}"
2854
+ ],
2855
+ alwaysUsed: [
2856
+ "gatsby-config.{ts,js,mjs}",
2857
+ "gatsby-node.{ts,js,mjs}",
2858
+ "gatsby-browser.{ts,tsx,js,jsx}",
2859
+ "gatsby-ssr.{ts,tsx,js,jsx}"
2860
+ ]
2861
+ },
2862
+ {
2863
+ enablers: ["@angular/core"],
2864
+ enablerPrefixes: ["@angular/"],
2865
+ entryPatterns: [
2866
+ "src/main.ts",
2867
+ "src/app/**/*.ts",
2868
+ "src/environments/**/*.ts",
2869
+ "src/polyfills.ts",
2870
+ "src/test.ts"
2871
+ ],
2872
+ alwaysUsed: ["angular.json", "**/karma.conf.js"]
2873
+ },
2874
+ {
2875
+ enablers: ["react-scripts", "react-app-rewired"],
2876
+ enablerPrefixes: [],
2877
+ entryPatterns: ["src/index.{ts,tsx,js,jsx}"],
2878
+ alwaysUsed: [
2879
+ "src/setupTests.{ts,tsx,js,jsx}",
2880
+ "src/reportWebVitals.{ts,tsx,js,jsx}",
2881
+ "src/react-app-env.d.ts"
2882
+ ]
2883
+ },
2884
+ {
2885
+ enablers: [
2886
+ "@remix-run/node",
2887
+ "@remix-run/react",
2888
+ "@remix-run/cloudflare",
2889
+ "@react-router/node",
2890
+ "@react-router/serve",
2891
+ "@react-router/dev"
2892
+ ],
2893
+ enablerPrefixes: ["@remix-run/", "@react-router/"],
2894
+ entryPatterns: [
2895
+ "app/routes/**/*.{ts,tsx,js,jsx}",
2896
+ "app/root.{ts,tsx,js,jsx}",
2897
+ "app/entry.client.{ts,tsx,js,jsx}",
2898
+ "app/entry.server.{ts,tsx,js,jsx}",
2899
+ "app/routes.{ts,js,mts,mjs}",
2900
+ "src/routes.{ts,js,mts,mjs}"
2901
+ ],
2902
+ alwaysUsed: ["react-router.config.{ts,js,mjs}", "remix.config.{ts,js,mjs}"]
2903
+ },
2904
+ {
2905
+ enablers: ["@docusaurus/core"],
2906
+ enablerPrefixes: ["@docusaurus/"],
2907
+ entryPatterns: [
2908
+ "**/*.{md,mdx}",
2909
+ "src/pages/**/*.{ts,tsx,js,jsx}",
2910
+ "src/theme/**/*.{ts,tsx,js,jsx}",
2911
+ "src/theme/**/index.{ts,tsx,js,jsx}",
2912
+ "plugins/**/*.{ts,js,mjs}"
2913
+ ],
2914
+ alwaysUsed: [
2915
+ "docusaurus.config.{ts,js,mjs}",
2916
+ "sidebars.{ts,js,mjs,cjs}",
2917
+ "sidebar*.{ts,js,mjs,cjs}",
2918
+ "*-sidebar.{ts,js,mjs,cjs}",
2919
+ "*-sidebars.{ts,js,mjs,cjs}",
2920
+ "*Sidebar*.{ts,js,mjs,cjs}",
2921
+ "*sidebar*.{ts,js,mjs,cjs}"
2922
+ ],
2923
+ contentIgnorePatterns: ["versioned_sidebars/**"]
2924
+ },
2925
+ {
2926
+ enablers: ["eslint", "@eslint/js"],
2927
+ enablerPrefixes: [],
2928
+ entryPatterns: [],
2929
+ alwaysUsed: ["eslint.config.{js,mjs,cjs,ts,mts,cts}", ".eslintrc.{js,cjs,mjs,json,yaml,yml}"]
2930
+ },
2931
+ {
2932
+ enablers: ["prettier"],
2933
+ enablerPrefixes: [],
2934
+ entryPatterns: [],
2935
+ alwaysUsed: [".prettierrc.{js,cjs,mjs,json,yaml,yml}", "prettier.config.{js,mjs,cjs,ts}"]
2936
+ },
2937
+ {
2938
+ enablers: ["tailwindcss", "@tailwindcss/postcss"],
2939
+ enablerPrefixes: [],
2940
+ entryPatterns: [],
2941
+ alwaysUsed: ["tailwind.config.{ts,js,cjs,mjs}"]
2942
+ },
2943
+ {
2944
+ enablers: ["postcss"],
2945
+ enablerPrefixes: [],
2946
+ entryPatterns: [],
2947
+ alwaysUsed: ["postcss.config.{ts,js,cjs,mjs}"]
2948
+ },
2949
+ {
2950
+ enablers: ["typescript"],
2951
+ enablerPrefixes: [],
2952
+ entryPatterns: [],
2953
+ alwaysUsed: ["tsconfig.json", "tsconfig.*.json"]
2954
+ },
2955
+ {
2956
+ enablers: ["lint-staged"],
2957
+ enablerPrefixes: [],
2958
+ entryPatterns: [],
2959
+ alwaysUsed: [".lintstagedrc.{js,cjs,mjs,json}", "lint-staged.config.{js,mjs,cjs}"]
2960
+ },
2961
+ {
2962
+ enablers: ["husky"],
2963
+ enablerPrefixes: [],
2964
+ entryPatterns: [],
2965
+ alwaysUsed: [".husky/**/*"]
2966
+ },
2967
+ {
2968
+ enablers: ["@biomejs/biome"],
2969
+ enablerPrefixes: [],
2970
+ entryPatterns: [],
2971
+ alwaysUsed: ["biome.json", "biome.jsonc"]
2972
+ },
2973
+ {
2974
+ enablers: ["@commitlint/cli"],
2975
+ enablerPrefixes: [],
2976
+ entryPatterns: [],
2977
+ alwaysUsed: ["commitlint.config.{js,cjs,mjs,ts}", ".commitlintrc.{js,cjs,mjs,json,yaml,yml}"]
2978
+ },
2979
+ {
2980
+ enablers: ["semantic-release"],
2981
+ enablerPrefixes: [],
2982
+ entryPatterns: [],
2983
+ alwaysUsed: [".releaserc.{js,cjs,mjs,json,yaml,yml}", "release.config.{js,cjs,mjs,ts}"]
2984
+ },
2985
+ {
2986
+ enablers: ["@changesets/cli"],
2987
+ enablerPrefixes: [],
2988
+ entryPatterns: [],
2989
+ alwaysUsed: [".changeset/**/*"]
2990
+ },
2991
+ {
2992
+ enablers: ["next"],
2993
+ enablerPrefixes: [],
2994
+ entryPatterns: [
2995
+ "app/**/page.{ts,tsx,js,jsx}",
2996
+ "app/**/layout.{ts,tsx,js,jsx}",
2997
+ "app/**/loading.{ts,tsx,js,jsx}",
2998
+ "app/**/error.{ts,tsx,js,jsx}",
2999
+ "app/**/not-found.{ts,tsx,js,jsx}",
3000
+ "app/**/template.{ts,tsx,js,jsx}",
3001
+ "app/**/default.{ts,tsx,js,jsx}",
3002
+ "app/**/route.{ts,tsx,js,jsx}",
3003
+ "app/**/global-error.{ts,tsx,js,jsx}",
3004
+ "app/**/forbidden.{ts,tsx,js,jsx}",
3005
+ "app/**/unauthorized.{ts,tsx,js,jsx}",
3006
+ "app/global-not-found.{ts,tsx,js,jsx}",
3007
+ "app/**/opengraph-image.{ts,tsx,js,jsx}",
3008
+ "app/**/twitter-image.{ts,tsx,js,jsx}",
3009
+ "app/**/icon.{ts,tsx,js,jsx}",
3010
+ "app/**/apple-icon.{ts,tsx,js,jsx}",
3011
+ "app/**/manifest.{ts,tsx,js,jsx}",
3012
+ "app/**/sitemap.{ts,tsx,js,jsx}",
3013
+ "app/**/robots.{ts,tsx,js,jsx}",
3014
+ "pages/**/*.{ts,tsx,js,jsx}",
3015
+ "src/app/**/page.{ts,tsx,js,jsx}",
3016
+ "src/app/**/layout.{ts,tsx,js,jsx}",
3017
+ "src/app/**/loading.{ts,tsx,js,jsx}",
3018
+ "src/app/**/error.{ts,tsx,js,jsx}",
3019
+ "src/app/**/not-found.{ts,tsx,js,jsx}",
3020
+ "src/app/**/template.{ts,tsx,js,jsx}",
3021
+ "src/app/**/default.{ts,tsx,js,jsx}",
3022
+ "src/app/**/route.{ts,tsx,js,jsx}",
3023
+ "src/app/**/global-error.{ts,tsx,js,jsx}",
3024
+ "src/app/**/forbidden.{ts,tsx,js,jsx}",
3025
+ "src/app/**/unauthorized.{ts,tsx,js,jsx}",
3026
+ "src/app/global-not-found.{ts,tsx,js,jsx}",
3027
+ "src/app/**/opengraph-image.{ts,tsx,js,jsx}",
3028
+ "src/app/**/twitter-image.{ts,tsx,js,jsx}",
3029
+ "src/app/**/icon.{ts,tsx,js,jsx}",
3030
+ "src/app/**/apple-icon.{ts,tsx,js,jsx}",
3031
+ "src/app/**/manifest.{ts,tsx,js,jsx}",
3032
+ "src/app/**/sitemap.{ts,tsx,js,jsx}",
3033
+ "src/app/**/robots.{ts,tsx,js,jsx}",
3034
+ "src/pages/**/*.{ts,tsx,js,jsx}",
3035
+ "middleware.{ts,js}",
3036
+ "src/middleware.{ts,js}",
3037
+ "proxy.{ts,js}",
3038
+ "src/proxy.{ts,js}",
3039
+ "instrumentation.{ts,js}",
3040
+ "instrumentation-client.{ts,js}",
3041
+ "src/instrumentation.{ts,js}",
3042
+ "src/instrumentation-client.{ts,js}"
3043
+ ],
3044
+ alwaysUsed: [
3045
+ "next.config.{ts,js,mjs,mts}",
3046
+ "next-env.d.ts",
3047
+ "mdx-components.{ts,tsx,js,jsx}",
3048
+ "src/mdx-components.{ts,tsx,js,jsx}",
3049
+ "src/i18n/request.{ts,js}",
3050
+ "src/i18n/routing.{ts,js}",
3051
+ "i18n/request.{ts,js}",
3052
+ "i18n/routing.{ts,js}"
3053
+ ]
3054
+ },
3055
+ {
3056
+ enablers: [
3057
+ "@tanstack/react-router",
3058
+ "@tanstack/react-start",
3059
+ "@tanstack/start",
3060
+ "@tanstack/solid-router",
3061
+ "@tanstack/solid-start"
3062
+ ],
3063
+ enablerPrefixes: ["@tanstack/router"],
3064
+ entryPatterns: [
3065
+ "src/routes/**/*.{ts,tsx,js,jsx}",
3066
+ "app/routes/**/*.{ts,tsx,js,jsx}",
3067
+ "src/server.{ts,tsx,js,jsx}",
3068
+ "src/client.{ts,tsx,js,jsx}",
3069
+ "src/router.{ts,tsx,js,jsx}",
3070
+ "src/routeTree.gen.{ts,js}"
3071
+ ],
3072
+ alwaysUsed: ["tsr.config.json", "app.config.{ts,js}"]
3073
+ },
3074
+ {
3075
+ enablers: ["vite", "rolldown-vite"],
3076
+ enablerPrefixes: ["@vitejs/"],
3077
+ entryPatterns: [
3078
+ "src/main.{ts,tsx,js,jsx}",
3079
+ "src/index.{ts,tsx,js,jsx}",
3080
+ "index.html"
3081
+ ],
3082
+ alwaysUsed: ["vite.config.{ts,js,mts,mjs}"]
3083
+ },
3084
+ {
3085
+ enablers: ["vue", "@vue/cli-service"],
3086
+ enablerPrefixes: ["@vue/"],
3087
+ entryPatterns: ["src/main.{ts,js}", "src/App.vue"],
3088
+ alwaysUsed: ["vue.config.{ts,js,mjs,cjs}"]
3089
+ },
3090
+ {
3091
+ enablers: ["nuxt", "nuxt3"],
3092
+ enablerPrefixes: ["@nuxt/"],
3093
+ entryPatterns: [
3094
+ "pages/**/*.vue",
3095
+ "layouts/**/*.vue",
3096
+ "components/**/*.vue",
3097
+ "composables/**/*.{ts,js}",
3098
+ "plugins/**/*.{ts,js}",
3099
+ "middleware/**/*.{ts,js}",
3100
+ "server/**/*.{ts,js}",
3101
+ "app.vue"
3102
+ ],
3103
+ alwaysUsed: ["nuxt.config.{ts,js,mjs}"]
3104
+ },
3105
+ {
3106
+ enablers: ["svelte", "@sveltejs/kit"],
3107
+ enablerPrefixes: ["@sveltejs/"],
3108
+ entryPatterns: [
3109
+ "src/routes/**/*.svelte",
3110
+ "src/lib/**/*.svelte",
3111
+ "src/routes/**/+page.{ts,js,svelte}",
3112
+ "src/routes/**/+layout.{ts,js,svelte}",
3113
+ "src/routes/**/+server.{ts,js}"
3114
+ ],
3115
+ alwaysUsed: ["svelte.config.{ts,js,mjs}"]
3116
+ },
3117
+ {
3118
+ enablers: ["webpack", "webpack-cli"],
3119
+ enablerPrefixes: [],
3120
+ entryPatterns: [],
3121
+ alwaysUsed: ["webpack.config.{ts,js,mjs,cjs}", "webpack.*.config.{ts,js,mjs,cjs}"]
3122
+ },
3123
+ {
3124
+ enablers: ["rollup"],
3125
+ enablerPrefixes: [],
3126
+ entryPatterns: [],
3127
+ alwaysUsed: ["rollup.config.{ts,js,mjs,cjs}", "rollup.*.config.{ts,js,mjs,cjs}"]
3128
+ },
3129
+ {
3130
+ enablers: ["@rspack/core", "@rspack/cli"],
3131
+ enablerPrefixes: ["@rspack/"],
3132
+ entryPatterns: ["src/index.{ts,tsx,js,jsx}"],
3133
+ alwaysUsed: ["rspack.config.{ts,js,mjs,cjs}", "rspack.*.config.{ts,js,mjs,cjs}"]
3134
+ },
3135
+ {
3136
+ enablers: ["@rsbuild/core"],
3137
+ enablerPrefixes: ["@rsbuild/"],
3138
+ entryPatterns: ["src/index.{ts,tsx,js,jsx}"],
3139
+ alwaysUsed: ["rsbuild.config.{ts,js,mjs,cjs}"]
3140
+ },
3141
+ {
3142
+ enablers: ["tsup"],
3143
+ enablerPrefixes: [],
3144
+ entryPatterns: [],
3145
+ alwaysUsed: ["tsup.config.{ts,js,cjs,mjs}"]
3146
+ },
3147
+ {
3148
+ enablers: ["tsdown"],
3149
+ enablerPrefixes: [],
3150
+ entryPatterns: [],
3151
+ alwaysUsed: ["tsdown.config.{ts,js,cjs,mjs}"]
3152
+ },
3153
+ {
3154
+ enablers: ["@trigger.dev/sdk"],
3155
+ enablerPrefixes: ["@trigger.dev/"],
3156
+ entryPatterns: [],
3157
+ alwaysUsed: ["trigger.config.{ts,js,mjs,mts}"]
3158
+ },
3159
+ {
3160
+ enablers: ["@swc/core"],
3161
+ enablerPrefixes: [],
3162
+ entryPatterns: [],
3163
+ alwaysUsed: [".swcrc"]
3164
+ },
3165
+ {
3166
+ enablers: ["@babel/core"],
3167
+ enablerPrefixes: [],
3168
+ entryPatterns: [],
3169
+ alwaysUsed: ["babel.config.{js,cjs,mjs,json}", ".babelrc.{js,cjs,mjs,json}"]
3170
+ },
3171
+ {
3172
+ enablers: ["sanity", "@sanity/cli"],
3173
+ enablerPrefixes: ["@sanity/"],
3174
+ entryPatterns: [],
3175
+ alwaysUsed: ["sanity.config.{ts,js}", "sanity.cli.{ts,js}"]
3176
+ },
3177
+ {
3178
+ enablers: ["astro"],
3179
+ enablerPrefixes: ["@astrojs/"],
3180
+ entryPatterns: [
3181
+ "src/pages/**/*.{astro,ts,tsx,js,jsx,mts,mjs,cts,cjs,md,mdx}",
3182
+ "src/content/**/*.{ts,js,mts,mjs,cts,cjs,md,mdx}",
3183
+ "src/layouts/**/*.astro",
3184
+ "src/middleware.{js,ts,mjs,mts,cjs,cts}",
3185
+ "src/middleware/index.{js,ts,mjs,mts,cjs,cts}",
3186
+ "src/actions/index.{js,ts,mjs,mts,cjs,cts}"
3187
+ ],
3188
+ alwaysUsed: [
3189
+ "astro.config.{ts,js,mjs,cjs}",
3190
+ "src/content/config.{js,ts,mjs,mts,cjs,cts}",
3191
+ "src/content.config.{js,ts,mjs,mts,cjs,cts}"
3192
+ ]
3193
+ },
3194
+ {
3195
+ enablers: [
3196
+ "i18next",
3197
+ "react-i18next",
3198
+ "vue-i18n",
3199
+ "next-i18next"
3200
+ ],
3201
+ enablerPrefixes: [],
3202
+ entryPatterns: [
3203
+ "src/i18n.{ts,js,mjs}",
3204
+ "src/i18n/index.{ts,js}",
3205
+ "i18n.{ts,js,mjs}",
3206
+ "i18n/index.{ts,js}"
3207
+ ],
3208
+ alwaysUsed: [
3209
+ "src/i18n.{ts,js,mjs}",
3210
+ "src/i18n/index.{ts,js}",
3211
+ "i18n.{ts,js,mjs}",
3212
+ "i18n/index.{ts,js}",
3213
+ "i18next.config.{js,ts,mjs}",
3214
+ "next-i18next.config.{js,mjs}",
3215
+ "locales/**/*.json",
3216
+ "public/locales/**/*.json",
3217
+ "src/locales/**/*.json"
3218
+ ]
3219
+ },
3220
+ {
3221
+ enablers: ["turbo"],
3222
+ enablerPrefixes: [],
3223
+ entryPatterns: [],
3224
+ alwaysUsed: ["turbo.json", "turbo/generators/config.{ts,js}"]
3225
+ },
3226
+ {
3227
+ enablers: [
3228
+ "@sentry/nextjs",
3229
+ "@sentry/react",
3230
+ "@sentry/node",
3231
+ "@sentry/browser"
3232
+ ],
3233
+ enablerPrefixes: ["@sentry/"],
3234
+ entryPatterns: [],
3235
+ alwaysUsed: [
3236
+ "sentry.client.config.{ts,js,mjs}",
3237
+ "sentry.server.config.{ts,js,mjs}",
3238
+ "sentry.edge.config.{ts,js,mjs}"
3239
+ ]
3240
+ },
3241
+ {
3242
+ enablers: ["nodemon"],
3243
+ enablerPrefixes: [],
3244
+ entryPatterns: [],
3245
+ alwaysUsed: [
3246
+ "nodemon.json",
3247
+ ".nodemonrc",
3248
+ ".nodemonrc.{json,yml,yaml}"
3249
+ ]
3250
+ },
3251
+ {
3252
+ enablers: ["nx"],
3253
+ enablerPrefixes: ["@nx/"],
3254
+ entryPatterns: [],
3255
+ alwaysUsed: ["nx.json", "**/project.json"]
3256
+ },
3257
+ {
3258
+ enablers: ["react-native"],
3259
+ enablerPrefixes: ["@react-native/", "@react-native-community/"],
3260
+ entryPatterns: [
3261
+ "index.{ts,tsx,js,jsx}",
3262
+ "App.{ts,tsx,js,jsx}",
3263
+ "src/App.{ts,tsx,js,jsx}"
3264
+ ],
3265
+ alwaysUsed: [
3266
+ "metro.config.{ts,js}",
3267
+ "react-native.config.{ts,js}",
3268
+ "app.json"
3269
+ ]
3270
+ },
3271
+ {
3272
+ enablers: ["expo"],
3273
+ enablerPrefixes: ["@expo/"],
3274
+ entryPatterns: [
3275
+ "App.{ts,tsx,js,jsx}",
3276
+ "app/_layout.{ts,tsx,js,jsx}",
3277
+ "app/index.{ts,tsx,js,jsx}"
3278
+ ],
3279
+ alwaysUsed: ["app.json", "app.config.{ts,js}"]
3280
+ },
3281
+ {
3282
+ enablers: ["wrangler"],
3283
+ enablerPrefixes: ["@cloudflare/"],
3284
+ entryPatterns: [
3285
+ "src/index.{ts,js}",
3286
+ "src/worker.{ts,js}",
3287
+ "functions/**/*.{ts,js}"
3288
+ ],
3289
+ alwaysUsed: [
3290
+ "wrangler.toml",
3291
+ "wrangler.json",
3292
+ "wrangler.jsonc"
3293
+ ]
3294
+ },
3295
+ {
3296
+ enablers: [
3297
+ "electron",
3298
+ "electron-builder",
3299
+ "@electron-forge/cli",
3300
+ "electron-vite",
3301
+ "electron-webpack"
3302
+ ],
3303
+ enablerPrefixes: ["@electron-forge/", "@electron/"],
3304
+ entryPatterns: [
3305
+ "src/main/**/*.{ts,tsx,js,jsx}",
3306
+ "src/preload/**/*.{ts,tsx,js,jsx}",
3307
+ "electron/main.{ts,js}"
3308
+ ],
3309
+ alwaysUsed: [
3310
+ "electron-builder.{yml,yaml,json,json5,toml}",
3311
+ "forge.config.{ts,js,cjs}",
3312
+ "electron.vite.config.{ts,js,mjs}"
3313
+ ]
3314
+ },
3315
+ {
3316
+ enablers: ["lefthook"],
3317
+ enablerPrefixes: [],
3318
+ entryPatterns: [],
3319
+ alwaysUsed: [
3320
+ "lefthook.yml",
3321
+ "lefthook.yaml",
3322
+ ".lefthook.yml"
3323
+ ]
3324
+ },
3325
+ {
3326
+ enablers: ["syncpack"],
3327
+ enablerPrefixes: [],
3328
+ entryPatterns: [],
3329
+ alwaysUsed: [
3330
+ ".syncpackrc",
3331
+ ".syncpackrc.{json,yaml,yml}",
3332
+ "syncpack.config.{js,mjs,cjs}"
3333
+ ]
3334
+ },
3335
+ {
3336
+ enablers: ["@capacitor/core", "@capacitor/cli"],
3337
+ enablerPrefixes: ["@capacitor/"],
3338
+ entryPatterns: [],
3339
+ alwaysUsed: ["capacitor.config.{ts,js,json}"]
3340
+ }
3341
+ ];
3342
+ const detectNodeTestRunner = (directory) => {
3343
+ try {
3344
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
3345
+ if (!(0, node_fs.existsSync)(packageJsonPath)) return false;
3346
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
3347
+ const scripts = JSON.parse(content).scripts ?? {};
3348
+ return Object.values(scripts).some((scriptValue) => typeof scriptValue === "string" && /\bnode\b.*\s--test\b/.test(scriptValue));
3349
+ } catch {
3350
+ return false;
3351
+ }
3352
+ };
3353
+ const detectBunTestRunner = (directory) => {
3354
+ try {
3355
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
3356
+ if (!(0, node_fs.existsSync)(packageJsonPath)) return false;
3357
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
3358
+ const scripts = JSON.parse(content).scripts ?? {};
3359
+ return Object.values(scripts).some((scriptValue) => typeof scriptValue === "string" && /\bbun\s+test\b/.test(scriptValue));
3360
+ } catch {
3361
+ return false;
3362
+ }
3363
+ };
3364
+ const discoverTestRunnerEntryPoints = (rootDir, workspacePackages) => {
3365
+ const allEntries = [];
3366
+ const allAlwaysUsed = [];
3367
+ const directoriesToCheck = [rootDir, ...workspacePackages.map((workspacePackage) => workspacePackage.directory)];
3368
+ for (const directory of directoriesToCheck) {
3369
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
3370
+ if (!(0, node_fs.existsSync)(packageJsonPath)) continue;
3371
+ let allDependencies = {};
3372
+ try {
3373
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
3374
+ const packageJson = JSON.parse(content);
3375
+ allDependencies = {
3376
+ ...packageJson.dependencies,
3377
+ ...packageJson.devDependencies,
3378
+ ...packageJson.optionalDependencies
3379
+ };
3380
+ } catch {
3381
+ continue;
3382
+ }
3383
+ const activatedPatterns = [];
3384
+ const activatedFixturePatterns = [];
3385
+ const activatedAlwaysUsed = [];
3386
+ const isRunnerEnabled = (runner, dependencies, checkDirectory) => {
3387
+ if (runner.enablers.some((enabler) => {
3388
+ return enabler in dependencies;
3389
+ })) return true;
3390
+ return runner.configFileActivators.some((configFile) => (0, node_fs.existsSync)((0, node_path.join)(checkDirectory, configFile)));
3391
+ };
3392
+ for (const runner of TEST_FRAMEWORK_PATTERNS) if (isRunnerEnabled(runner, allDependencies, directory)) {
3393
+ const isVitestRunner = runner.enablers.includes("vitest");
3394
+ const isJestRunner = runner.enablers.includes("jest");
3395
+ let customPatterns = [];
3396
+ if (isVitestRunner) customPatterns = extractVitestIncludePatterns(directory);
3397
+ else if (isJestRunner) customPatterns = extractJestTestMatchPatterns(directory);
3398
+ if (customPatterns.length > 0) activatedPatterns.push(...customPatterns);
3399
+ else activatedPatterns.push(...runner.entryPatterns);
3400
+ activatedFixturePatterns.push(...runner.fixturePatterns);
3401
+ activatedAlwaysUsed.push(...runner.alwaysUsed);
3402
+ }
3403
+ if (activatedPatterns.length === 0 && directory !== rootDir) {
3404
+ const rootPackageJsonPath = (0, node_path.join)(rootDir, "package.json");
3405
+ if ((0, node_fs.existsSync)(rootPackageJsonPath)) try {
3406
+ const rootContent = (0, node_fs.readFileSync)(rootPackageJsonPath, "utf-8");
3407
+ const rootPackageJson = JSON.parse(rootContent);
3408
+ const rootDeps = {
3409
+ ...rootPackageJson.dependencies,
3410
+ ...rootPackageJson.devDependencies,
3411
+ ...rootPackageJson.optionalDependencies
3412
+ };
3413
+ for (const runner of TEST_FRAMEWORK_PATTERNS) if (isRunnerEnabled(runner, rootDeps, rootDir)) {
3414
+ activatedPatterns.push(...runner.entryPatterns);
3415
+ activatedFixturePatterns.push(...runner.fixturePatterns);
3416
+ activatedAlwaysUsed.push(...runner.alwaysUsed);
3417
+ }
3418
+ } catch {}
3419
+ }
3420
+ if (detectNodeTestRunner(directory) || detectNodeTestRunner(rootDir)) activatedPatterns.push("**/*.test.{ts,tsx,js,jsx,mts,mjs,cts,cjs}", "**/*.spec.{ts,tsx,js,jsx,mts,mjs,cts,cjs}", "**/__tests__/**/*.{ts,tsx,js,jsx,mts,mjs,cts,cjs}");
3421
+ if (detectBunTestRunner(directory) || detectBunTestRunner(rootDir)) activatedPatterns.push("**/*.test.{ts,tsx,js,jsx,mts,mjs}", "**/*.spec.{ts,tsx,js,jsx,mts,mjs}", "**/*_test.{ts,tsx,js,jsx,mts,mjs}", "**/*_spec.{ts,tsx,js,jsx,mts,mjs}", "**/__tests__/**/*.{ts,tsx,js,jsx,mts,mjs}");
3422
+ if (activatedPatterns.length === 0) continue;
3423
+ const uniquePatterns = [...new Set(activatedPatterns)];
3424
+ const testFiles = fast_glob.default.sync(uniquePatterns, {
3425
+ cwd: directory,
3426
+ absolute: true,
3427
+ onlyFiles: true,
3428
+ ignore: ["**/node_modules/**", "**/*.gen.{ts,tsx,js,jsx}"]
3429
+ });
3430
+ allEntries.push(...testFiles);
3431
+ const uniqueFixturePatterns = [...new Set(activatedFixturePatterns)];
3432
+ if (uniqueFixturePatterns.length > 0) {
3433
+ const fixtureFiles = fast_glob.default.sync(uniqueFixturePatterns, {
3434
+ cwd: directory,
3435
+ absolute: true,
3436
+ onlyFiles: true,
3437
+ ignore: ["**/node_modules/**"]
3438
+ });
3439
+ allEntries.push(...fixtureFiles);
3440
+ }
3441
+ const uniqueAlwaysUsed = [...new Set(activatedAlwaysUsed)];
3442
+ if (uniqueAlwaysUsed.length > 0) {
3443
+ const alwaysUsedFiles = fast_glob.default.sync(uniqueAlwaysUsed, {
3444
+ cwd: directory,
3445
+ absolute: true,
3446
+ onlyFiles: true,
3447
+ ignore: ["**/node_modules/**"],
3448
+ dot: true
3449
+ });
3450
+ allAlwaysUsed.push(...alwaysUsedFiles);
3451
+ }
3452
+ }
3453
+ return {
3454
+ entryFiles: allEntries,
3455
+ alwaysUsedFiles: allAlwaysUsed
3456
+ };
3457
+ };
3458
+ const isToolingPluginEnabled = (plugin, dependencies) => {
3459
+ if (plugin.enablers.some((enabler) => enabler in dependencies)) return true;
3460
+ if (plugin.enablerPrefixes.length > 0) {
3461
+ const depNames = Object.keys(dependencies);
3462
+ return plugin.enablerPrefixes.some((prefix) => depNames.some((depName) => depName.startsWith(prefix)));
3463
+ }
3464
+ return false;
3465
+ };
3466
+ const discoverToolingEntryPoints = (rootDir, workspacePackages) => {
3467
+ const allEntries = [];
3468
+ const allAlwaysUsed = [];
3469
+ const directoriesToCheck = [rootDir, ...workspacePackages.map((workspacePackage) => workspacePackage.directory)];
3470
+ let rootDependencies = {};
3471
+ const rootPackageJsonPath = (0, node_path.join)(rootDir, "package.json");
3472
+ if ((0, node_fs.existsSync)(rootPackageJsonPath)) try {
3473
+ const rootContent = (0, node_fs.readFileSync)(rootPackageJsonPath, "utf-8");
3474
+ const rootPackageJson = JSON.parse(rootContent);
3475
+ rootDependencies = {
3476
+ ...rootPackageJson.dependencies,
3477
+ ...rootPackageJson.devDependencies,
3478
+ ...rootPackageJson.optionalDependencies
3479
+ };
3480
+ } catch {}
3481
+ for (const directory of directoriesToCheck) {
3482
+ const packageJsonPath = (0, node_path.join)(directory, "package.json");
3483
+ if (!(0, node_fs.existsSync)(packageJsonPath)) continue;
3484
+ let workspaceDependencies = {};
3485
+ try {
3486
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
3487
+ const packageJson = JSON.parse(content);
3488
+ workspaceDependencies = {
3489
+ ...packageJson.dependencies,
3490
+ ...packageJson.devDependencies,
3491
+ ...packageJson.optionalDependencies
3492
+ };
3493
+ } catch {
3494
+ continue;
3495
+ }
3496
+ const mergedDependencies = directory === rootDir ? rootDependencies : workspaceDependencies;
3497
+ const activatedPatterns = [];
3498
+ const activatedAlwaysUsed = [];
3499
+ for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, mergedDependencies)) {
3500
+ activatedPatterns.push(...plugin.entryPatterns);
3501
+ activatedAlwaysUsed.push(...plugin.alwaysUsed);
3502
+ }
3503
+ if (activatedPatterns.length === 0 && activatedAlwaysUsed.length === 0) continue;
3504
+ const uniquePatterns = [...new Set(activatedPatterns)];
3505
+ const toolingFiles = fast_glob.default.sync(uniquePatterns, {
3506
+ cwd: directory,
3507
+ absolute: true,
3508
+ onlyFiles: true,
3509
+ ignore: ["**/node_modules/**"],
3510
+ dot: true
3511
+ });
3512
+ allEntries.push(...toolingFiles);
3513
+ const uniqueAlwaysUsed = [...new Set(activatedAlwaysUsed)];
3514
+ if (uniqueAlwaysUsed.length > 0) {
3515
+ const alwaysUsedFiles = fast_glob.default.sync(uniqueAlwaysUsed, {
3516
+ cwd: directory,
3517
+ absolute: true,
3518
+ onlyFiles: true,
3519
+ ignore: ["**/node_modules/**"],
3520
+ dot: true
3521
+ });
3522
+ allAlwaysUsed.push(...alwaysUsedFiles);
3523
+ }
3524
+ }
3525
+ const rootActivatedGlobalPatterns = [];
3526
+ for (const plugin of FRAMEWORK_PATTERNS) if (isToolingPluginEnabled(plugin, rootDependencies)) {
3527
+ for (const pattern of plugin.alwaysUsed) if (!pattern.startsWith("**/")) rootActivatedGlobalPatterns.push(`**/${pattern}`);
3528
+ }
3529
+ if (rootActivatedGlobalPatterns.length > 0) {
3530
+ const globalAlwaysUsedFiles = fast_glob.default.sync([...new Set(rootActivatedGlobalPatterns)], {
3531
+ cwd: rootDir,
3532
+ absolute: true,
3533
+ onlyFiles: true,
3534
+ ignore: ["**/node_modules/**"],
3535
+ dot: true
3536
+ });
3537
+ allAlwaysUsed.push(...globalAlwaysUsedFiles);
3538
+ }
3539
+ return {
3540
+ entryFiles: allEntries,
3541
+ alwaysUsedFiles: allAlwaysUsed
3542
+ };
3543
+ };
3544
+
3545
+ //#endregion
3546
+ //#region src/resolver/resolve.ts
3547
+ const fileExistsCache = /* @__PURE__ */ new Map();
3548
+ const pathExistsCache = /* @__PURE__ */ new Map();
3549
+ const fileContentCache = /* @__PURE__ */ new Map();
3550
+ const cachedReadFileSync = (filePath) => {
3551
+ const cached = fileContentCache.get(filePath);
3552
+ if (cached !== void 0) return cached;
3553
+ const content = (0, node_fs.readFileSync)(filePath, "utf-8");
3554
+ fileContentCache.set(filePath, content);
3555
+ return content;
3556
+ };
3557
+ const cachedExistsSync = (targetPath) => {
3558
+ const cached = pathExistsCache.get(targetPath);
3559
+ if (cached !== void 0) return cached;
3560
+ const result = (0, node_fs.existsSync)(targetPath);
3561
+ pathExistsCache.set(targetPath, result);
3562
+ return result;
3563
+ };
3564
+ const existsAsFile = (filePath) => {
3565
+ const cached = fileExistsCache.get(filePath);
3566
+ if (cached !== void 0) return cached;
3567
+ try {
3568
+ const result = cachedExistsSync(filePath) && (0, node_fs.statSync)(filePath).isFile();
3569
+ fileExistsCache.set(filePath, result);
3570
+ return result;
3571
+ } catch {
3572
+ fileExistsCache.set(filePath, false);
3573
+ return false;
3574
+ }
3575
+ };
3576
+ const trySourceFallback = (resolvedPath) => {
3577
+ const segments = resolvedPath.split(node_path.sep);
3578
+ const isOutputDirectory = (segment) => OUTPUT_DIRECTORIES.some((outputDirectory) => segment === outputDirectory || segment.startsWith(`${outputDirectory}-`));
3579
+ let lastOutputPosition = -1;
3580
+ for (let index = segments.length - 1; index >= 0; index--) if (isOutputDirectory(segments[index])) {
3581
+ lastOutputPosition = index;
3582
+ break;
3583
+ }
3584
+ if (lastOutputPosition === -1) return void 0;
3585
+ let firstOutputPosition = lastOutputPosition;
3586
+ while (firstOutputPosition > 0 && isOutputDirectory(segments[firstOutputPosition - 1])) firstOutputPosition--;
3587
+ const prefix = segments.slice(0, firstOutputPosition).join(node_path.sep);
3588
+ const suffix = segments.slice(lastOutputPosition + 1).join(node_path.sep);
3589
+ if (!suffix) return void 0;
3590
+ const fileExtension = (0, node_path.extname)((0, node_path.basename)(suffix));
3591
+ const stemmedSuffix = fileExtension ? suffix.slice(0, suffix.length - fileExtension.length) : suffix;
3592
+ for (const sourceExtension of SOURCE_EXTENSIONS$3) {
3593
+ const sourceCandidate = (0, node_path.join)(prefix, "src", `${stemmedSuffix}.${sourceExtension}`);
3594
+ if (existsAsFile(sourceCandidate)) return sourceCandidate;
3595
+ }
3596
+ };
3597
+ const resolvePathWithExtensionFallback = (candidatePath) => {
3598
+ if (existsAsFile(candidatePath)) return candidatePath;
3599
+ for (const extension of RESOLVER_EXTENSIONS) {
3600
+ const withExtension = candidatePath + extension;
3601
+ if (existsAsFile(withExtension)) return withExtension;
3602
+ }
3603
+ for (const extension of RESOLVER_EXTENSIONS) {
3604
+ const indexCandidate = (0, node_path.join)(candidatePath, `index${extension}`);
3605
+ if (existsAsFile(indexCandidate)) return indexCandidate;
3606
+ }
3607
+ return candidatePath;
3608
+ };
3609
+ const COMMON_RESOLVER_OPTIONS = {
3610
+ conditionNames: [
3611
+ "import",
3612
+ "require",
3613
+ "node",
3614
+ "default"
3615
+ ],
3616
+ extensions: RESOLVER_EXTENSIONS,
3617
+ mainFields: [
3618
+ "module",
3619
+ "main",
3620
+ "browser"
3621
+ ],
3622
+ extensionAlias: {
3623
+ ".js": [
3624
+ ".ts",
3625
+ ".tsx",
3626
+ ".js",
3627
+ ".jsx"
3628
+ ],
3629
+ ".jsx": [".tsx", ".jsx"],
3630
+ ".mjs": [".mts", ".mjs"],
3631
+ ".cjs": [".cts", ".cjs"]
3632
+ }
3633
+ };
3634
+ const TSCONFIG_FILENAMES = [
3635
+ "tsconfig.json",
3636
+ "tsconfig.web.json",
3637
+ "tsconfig.app.json",
3638
+ "tsconfig.base.json"
3639
+ ];
3640
+ const findNearestTsconfig = (fromDir, rootDir) => {
3641
+ let currentDirectory = fromDir;
3642
+ const normalizedRoot = (0, node_path.resolve)(rootDir);
3643
+ while (currentDirectory.length >= normalizedRoot.length) {
3644
+ for (const tsconfigFilename of TSCONFIG_FILENAMES) {
3645
+ const tsconfigCandidate = (0, node_path.join)(currentDirectory, tsconfigFilename);
3646
+ if (cachedExistsSync(tsconfigCandidate)) return tsconfigCandidate;
3647
+ }
3648
+ const parentDirectory = (0, node_path.dirname)(currentDirectory);
3649
+ if (parentDirectory === currentDirectory) break;
3650
+ currentDirectory = parentDirectory;
3651
+ }
3652
+ };
3653
+ const STYLE_FILE_EXTENSIONS = [
3654
+ ".css",
3655
+ ".scss",
3656
+ ".less",
3657
+ ".sass"
3658
+ ];
3659
+ const SCSS_PARTIAL_EXTENSIONS = [
3660
+ ".scss",
3661
+ ".sass",
3662
+ ".css"
3663
+ ];
3664
+ const resolveScssPartial = (specifier, fromDirectory) => {
3665
+ const basePath = (0, node_path.resolve)(fromDirectory, specifier);
3666
+ const baseDirectory = (0, node_path.dirname)(basePath);
3667
+ const baseFileName = basePath.split("/").pop() ?? "";
3668
+ const candidates = [];
3669
+ for (const extension of SCSS_PARTIAL_EXTENSIONS) if (!basePath.endsWith(extension)) {
3670
+ candidates.push(`${basePath}${extension}`);
3671
+ candidates.push((0, node_path.join)(baseDirectory, `_${baseFileName}${extension}`));
3672
+ } else {
3673
+ candidates.push(basePath);
3674
+ candidates.push((0, node_path.join)(baseDirectory, `_${baseFileName}`));
3675
+ }
3676
+ candidates.push((0, node_path.join)(basePath, `index.scss`));
3677
+ candidates.push((0, node_path.join)(basePath, `_index.scss`));
3678
+ candidates.push((0, node_path.join)(basePath, `index.sass`));
3679
+ candidates.push((0, node_path.join)(basePath, `_index.sass`));
3680
+ for (const candidate of candidates) if (cachedExistsSync(candidate)) return candidate;
3681
+ };
3682
+ const createResolver = (config, workspacePackages = [], options = {}) => {
3683
+ const resolverCache = /* @__PURE__ */ new Map();
3684
+ const resolveResultCache = /* @__PURE__ */ new Map();
3685
+ const failedTsconfigPaths = /* @__PURE__ */ new Set();
3686
+ const resolverExtensions = options.hasReactNative ? [...REACT_NATIVE_PLATFORM_EXTENSIONS, ...RESOLVER_EXTENSIONS] : RESOLVER_EXTENSIONS;
3687
+ const resolverOptions = {
3688
+ ...COMMON_RESOLVER_OPTIONS,
3689
+ extensions: resolverExtensions
3690
+ };
3691
+ const getOrCreateResolver = (tsconfigPath) => {
3692
+ const effectivePath = tsconfigPath && !failedTsconfigPaths.has(tsconfigPath) ? tsconfigPath : void 0;
3693
+ const cacheKey = effectivePath ?? "__no_tsconfig__";
3694
+ const existingResolver = resolverCache.get(cacheKey);
3695
+ if (existingResolver) return existingResolver;
3696
+ try {
3697
+ const newResolver = new oxc_resolver.ResolverFactory({
3698
+ ...resolverOptions,
3699
+ tsconfig: effectivePath ? {
3700
+ configFile: effectivePath,
3701
+ references: "auto"
3702
+ } : void 0
3703
+ });
3704
+ resolverCache.set(cacheKey, newResolver);
3705
+ return newResolver;
3706
+ } catch {
3707
+ if (effectivePath) {
3708
+ failedTsconfigPaths.add(effectivePath);
3709
+ return getOrCreateResolver(void 0);
3710
+ }
3711
+ const fallbackResolver = new oxc_resolver.ResolverFactory(COMMON_RESOLVER_OPTIONS);
3712
+ resolverCache.set(cacheKey, fallbackResolver);
3713
+ return fallbackResolver;
3714
+ }
3715
+ };
3716
+ const workspaceNameToDirectory = /* @__PURE__ */ new Map();
3717
+ for (const workspacePackage of workspacePackages) workspaceNameToDirectory.set(workspacePackage.name, workspacePackage.directory);
3718
+ let rootTsconfigPath;
3719
+ if (config.tsConfigPath) rootTsconfigPath = (0, node_path.resolve)(config.rootDir, config.tsConfigPath);
3720
+ else for (const candidate of [
3721
+ "tsconfig.json",
3722
+ "tsconfig.web.json",
3723
+ "tsconfig.app.json",
3724
+ "tsconfig.base.json"
3725
+ ]) {
3726
+ const candidatePath = (0, node_path.resolve)(config.rootDir, candidate);
3727
+ if (cachedExistsSync(candidatePath)) {
3728
+ rootTsconfigPath = candidatePath;
3729
+ break;
3730
+ }
3731
+ }
3732
+ const tsconfigPathCache = /* @__PURE__ */ new Map();
3733
+ const tsconfigPathAliasCache = /* @__PURE__ */ new Map();
3734
+ const findTsconfigForFile = (filePath) => {
3735
+ const fileDir = (0, node_path.dirname)(filePath);
3736
+ const cached = tsconfigPathCache.get(fileDir);
3737
+ if (cached !== void 0) return cached;
3738
+ const tsconfigResult = findNearestTsconfig(fileDir, config.rootDir) ?? rootTsconfigPath;
3739
+ tsconfigPathCache.set(fileDir, tsconfigResult);
3740
+ return tsconfigResult;
3741
+ };
3742
+ const tsconfigBaseUrlCache = /* @__PURE__ */ new Map();
3743
+ const getBaseUrlDirectory = (tsconfigFile) => {
3744
+ const cached = tsconfigBaseUrlCache.get(tsconfigFile);
3745
+ if (cached !== void 0) return cached;
3746
+ try {
3747
+ const cleanedContent = stripJsonComments(cachedReadFileSync(tsconfigFile));
3748
+ const baseUrl = JSON.parse(cleanedContent).compilerOptions?.baseUrl;
3749
+ if (baseUrl) {
3750
+ const absoluteBaseUrl = (0, node_path.resolve)((0, node_path.dirname)(tsconfigFile), baseUrl);
3751
+ tsconfigBaseUrlCache.set(tsconfigFile, absoluteBaseUrl);
3752
+ return absoluteBaseUrl;
3753
+ }
3754
+ } catch {}
3755
+ tsconfigBaseUrlCache.set(tsconfigFile, void 0);
3756
+ };
3757
+ const hasNextJsDependency = (() => {
3758
+ try {
3759
+ const rootPackageJson = JSON.parse(cachedReadFileSync((0, node_path.resolve)(config.rootDir, "package.json")));
3760
+ return "next" in {
3761
+ ...rootPackageJson.dependencies,
3762
+ ...rootPackageJson.devDependencies
3763
+ };
3764
+ } catch {
3765
+ return false;
3766
+ }
3767
+ })();
3768
+ const getPathAliases = (tsconfigFile) => {
3769
+ const cached = tsconfigPathAliasCache.get(tsconfigFile);
3770
+ if (cached) return cached;
3771
+ const aliasMap = /* @__PURE__ */ new Map();
3772
+ const tsconfigDir = (0, node_path.dirname)(tsconfigFile);
3773
+ try {
3774
+ const tsconfigContent = cachedReadFileSync(tsconfigFile).trim();
3775
+ if (tsconfigContent.length > 0) {
3776
+ const cleanedContent = stripJsonComments(tsconfigContent);
3777
+ const tsconfigJson = JSON.parse(cleanedContent);
3778
+ const paths = tsconfigJson.compilerOptions?.paths;
3779
+ const baseUrl = tsconfigJson.compilerOptions?.baseUrl ?? ".";
3780
+ if (paths && typeof paths === "object") {
3781
+ for (const [pattern, targets] of Object.entries(paths)) if (Array.isArray(targets)) aliasMap.set(pattern, targets.map((target) => (0, node_path.resolve)(tsconfigDir, baseUrl, target)));
3782
+ }
3783
+ }
3784
+ } catch {}
3785
+ if (aliasMap.size === 0 && hasNextJsDependency) if (cachedExistsSync((0, node_path.resolve)(tsconfigDir, "src"))) aliasMap.set("@/*", [(0, node_path.resolve)(tsconfigDir, "src/*")]);
3786
+ else aliasMap.set("@/*", [(0, node_path.resolve)(tsconfigDir, "*")]);
3787
+ tsconfigPathAliasCache.set(tsconfigFile, aliasMap);
3788
+ return aliasMap;
3789
+ };
3790
+ const tryResolveViaPathAlias = (specifier, fromFile) => {
3791
+ const tsconfigFile = findTsconfigForFile(fromFile);
3792
+ if (!tsconfigFile) return void 0;
3793
+ const aliases = getPathAliases(tsconfigFile);
3794
+ for (const [pattern, targetPatterns] of aliases) {
3795
+ const wildcardIndex = pattern.indexOf("*");
3796
+ if (wildcardIndex === -1) {
3797
+ if (specifier === pattern) for (const targetPattern of targetPatterns) {
3798
+ const candidate = targetPattern.replace("*", "");
3799
+ if (existsAsFile(candidate)) return candidate;
3800
+ for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(candidate + ext)) return candidate + ext;
3801
+ const indexCandidate = (0, node_path.join)(candidate, "index");
3802
+ for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + ext)) return indexCandidate + ext;
3803
+ }
3804
+ continue;
3805
+ }
3806
+ const prefix = pattern.slice(0, wildcardIndex);
3807
+ const suffix = pattern.slice(wildcardIndex + 1);
3808
+ if (!specifier.startsWith(prefix) || !specifier.endsWith(suffix)) continue;
3809
+ const matchedWildcard = specifier.slice(prefix.length, specifier.length - suffix.length);
3810
+ for (const targetPattern of targetPatterns) {
3811
+ const resolvedTarget = targetPattern.replace("*", matchedWildcard);
3812
+ if (existsAsFile(resolvedTarget)) return resolvedTarget;
3813
+ for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(resolvedTarget + ext)) return resolvedTarget + ext;
3814
+ const strippedTarget = resolvedTarget.replace(/\.[cm]?js$/, "");
3815
+ if (strippedTarget !== resolvedTarget) {
3816
+ for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(strippedTarget + ext)) return strippedTarget + ext;
3817
+ }
3818
+ const indexCandidate = (0, node_path.join)(resolvedTarget, "index");
3819
+ for (const ext of RESOLVER_EXTENSIONS) if (cachedExistsSync(indexCandidate + ext)) return indexCandidate + ext;
3820
+ }
3821
+ }
3822
+ };
3823
+ const resolveModule = (specifier, fromFile) => {
3824
+ const queryIndex = specifier.indexOf("?");
3825
+ const cleanedSpecifier = queryIndex !== -1 ? specifier.slice(0, queryIndex) : specifier;
3826
+ const fromDir = (0, node_path.dirname)(fromFile);
3827
+ const cacheKey = `${fromDir}::${cleanedSpecifier}`;
3828
+ const cached = resolveResultCache.get(cacheKey);
3829
+ if (cached) return cached;
3830
+ if (isBuiltinModule(cleanedSpecifier)) {
3831
+ const resolvedResult = {
3832
+ resolvedPath: void 0,
3833
+ isExternal: true,
3834
+ packageName: cleanedSpecifier.startsWith("node:") ? cleanedSpecifier.slice(5) : cleanedSpecifier
3835
+ };
3836
+ resolveResultCache.set(cacheKey, resolvedResult);
3837
+ return resolvedResult;
3838
+ }
3839
+ if (STYLE_FILE_EXTENSIONS.some((extension) => fromFile.endsWith(extension)) && isBareSpecifier(cleanedSpecifier)) {
3840
+ const scssResolved = resolveScssPartial(cleanedSpecifier, fromDir);
3841
+ if (scssResolved) {
3842
+ const resolvedResult = {
3843
+ resolvedPath: scssResolved,
3844
+ isExternal: false,
3845
+ packageName: void 0
3846
+ };
3847
+ resolveResultCache.set(cacheKey, resolvedResult);
3848
+ return resolvedResult;
3849
+ }
3850
+ }
3851
+ if (isBareSpecifier(cleanedSpecifier) && workspaceNameToDirectory.size > 0) {
3852
+ const packageName = extractPackageNameFromSpecifier(cleanedSpecifier);
3853
+ const workspaceDirectory = workspaceNameToDirectory.get(packageName);
3854
+ if (workspaceDirectory) {
3855
+ const subpath = cleanedSpecifier.slice(packageName.length + 1);
3856
+ const workspacePackageJsonPath = (0, node_path.join)(workspaceDirectory, "package.json");
3857
+ try {
3858
+ const workspacePackageContent = cachedReadFileSync(workspacePackageJsonPath);
3859
+ const workspacePackageJson = JSON.parse(workspacePackageContent);
3860
+ let resolvedEntryPath;
3861
+ if (subpath && workspacePackageJson.exports) {
3862
+ const exportKey = `./${subpath}`;
3863
+ const exportValue = workspacePackageJson.exports[exportKey];
3864
+ if (typeof exportValue === "string") {
3865
+ const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, exportValue));
3866
+ resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
3867
+ } else if (typeof exportValue === "object" && exportValue !== null) {
3868
+ const conditionValue = exportValue.import ?? exportValue.require ?? exportValue.default ?? exportValue.types;
3869
+ if (typeof conditionValue === "string") {
3870
+ const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, conditionValue));
3871
+ resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
3872
+ }
3873
+ }
3874
+ if (!resolvedEntryPath) for (const [wildcardPattern, wildcardTarget] of Object.entries(workspacePackageJson.exports)) {
3875
+ if (typeof wildcardPattern !== "string" || !wildcardPattern.includes("*")) continue;
3876
+ const wildcardTargetRecord = typeof wildcardTarget === "object" && wildcardTarget !== null ? wildcardTarget : void 0;
3877
+ const wildcardTargetValue = typeof wildcardTarget === "string" ? wildcardTarget : wildcardTargetRecord ? String(wildcardTargetRecord["import"] ?? wildcardTargetRecord["require"] ?? wildcardTargetRecord["default"] ?? wildcardTargetRecord["types"] ?? "") : void 0;
3878
+ if (typeof wildcardTargetValue !== "string") continue;
3879
+ const wildcardPrefix = wildcardPattern.slice(0, wildcardPattern.indexOf("*"));
3880
+ const wildcardSuffix = wildcardPattern.slice(wildcardPattern.indexOf("*") + 1);
3881
+ if (exportKey.startsWith(wildcardPrefix) && exportKey.endsWith(wildcardSuffix)) {
3882
+ const matchedSegment = exportKey.slice(wildcardPrefix.length, exportKey.length - wildcardSuffix.length || void 0);
3883
+ const candidatePath = resolvePathWithExtensionFallback((0, node_path.resolve)(workspaceDirectory, wildcardTargetValue.replace("*", matchedSegment)));
3884
+ resolvedEntryPath = existsAsFile(candidatePath) ? candidatePath : trySourceFallback(candidatePath);
3885
+ break;
3886
+ }
3887
+ }
3888
+ }
3889
+ if (subpath && !resolvedEntryPath) {
3890
+ const subpathCandidates = [(0, node_path.resolve)(workspaceDirectory, subpath), (0, node_path.resolve)(workspaceDirectory, "src", subpath)];
3891
+ for (const directSubpath of subpathCandidates) {
3892
+ for (const candidateExtension of RESOLVER_EXTENSIONS) {
3893
+ const candidate = directSubpath + candidateExtension;
3894
+ if (cachedExistsSync(candidate)) {
3895
+ resolvedEntryPath = candidate;
3896
+ break;
3897
+ }
3898
+ }
3899
+ if (resolvedEntryPath) break;
3900
+ for (const candidateExtension of RESOLVER_EXTENSIONS) {
3901
+ const indexCandidate = (0, node_path.join)(directSubpath, `index${candidateExtension}`);
3902
+ if (cachedExistsSync(indexCandidate)) {
3903
+ resolvedEntryPath = indexCandidate;
3904
+ break;
3905
+ }
3906
+ }
3907
+ if (resolvedEntryPath) break;
3908
+ }
3909
+ }
3910
+ if (!subpath) {
3911
+ const mainField = workspacePackageJson.main ?? workspacePackageJson.module;
3912
+ if (typeof mainField === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, mainField);
3913
+ if (!resolvedEntryPath && workspacePackageJson.exports?.["."]) {
3914
+ const dotExport = workspacePackageJson.exports["."];
3915
+ if (typeof dotExport === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, dotExport);
3916
+ else if (typeof dotExport === "object" && dotExport !== null) {
3917
+ const conditionValue = dotExport.import ?? dotExport.require ?? dotExport.default ?? dotExport.types;
3918
+ if (typeof conditionValue === "string") resolvedEntryPath = (0, node_path.resolve)(workspaceDirectory, conditionValue);
3919
+ }
3920
+ }
3921
+ }
3922
+ if (resolvedEntryPath) {
3923
+ const finalPath = resolveSourcePath(resolvedEntryPath, workspaceDirectory) ?? resolvedEntryPath;
3924
+ if (cachedExistsSync(finalPath)) {
3925
+ const resolvedResult = {
3926
+ resolvedPath: finalPath,
3927
+ isExternal: false,
3928
+ packageName: void 0
3929
+ };
3930
+ resolveResultCache.set(cacheKey, resolvedResult);
3931
+ return resolvedResult;
3932
+ }
3933
+ const sourceFallbackPath = trySourceFallback(resolvedEntryPath);
3934
+ if (sourceFallbackPath) {
3935
+ const resolvedResult = {
3936
+ resolvedPath: sourceFallbackPath,
3937
+ isExternal: false,
3938
+ packageName: void 0
3939
+ };
3940
+ resolveResultCache.set(cacheKey, resolvedResult);
3941
+ return resolvedResult;
3942
+ }
3943
+ }
3944
+ } catch {}
3945
+ }
3946
+ }
3947
+ const tsconfigForFile = findTsconfigForFile(fromFile);
3948
+ const resolver = getOrCreateResolver(tsconfigForFile);
3949
+ const tryResolve = (activeResolver) => {
3950
+ try {
3951
+ const resolverResult = activeResolver.sync(fromDir, cleanedSpecifier);
3952
+ if (resolverResult.path) {
3953
+ const isInsideNodeModules = resolverResult.path.includes("/node_modules/");
3954
+ return {
3955
+ resolvedPath: isInsideNodeModules ? void 0 : resolverResult.path,
3956
+ isExternal: isInsideNodeModules,
3957
+ packageName: isInsideNodeModules ? extractPackageNameFromSpecifier(cleanedSpecifier) : void 0
3958
+ };
3959
+ }
3960
+ } catch {
3961
+ return;
3962
+ }
3963
+ };
3964
+ const resolversToAttempt = [
3965
+ resolver,
3966
+ ...tsconfigForFile !== rootTsconfigPath && rootTsconfigPath ? [getOrCreateResolver(rootTsconfigPath)] : [],
3967
+ ...tsconfigForFile ? [getOrCreateResolver(void 0)] : []
3968
+ ];
3969
+ for (const activeResolver of resolversToAttempt) {
3970
+ const resolvedResult = tryResolve(activeResolver);
3971
+ if (resolvedResult) {
3972
+ resolveResultCache.set(cacheKey, resolvedResult);
3973
+ return resolvedResult;
3974
+ }
3975
+ }
3976
+ const pathAliasResolved = tryResolveViaPathAlias(cleanedSpecifier, fromFile);
3977
+ if (pathAliasResolved) {
3978
+ const resolvedResult = {
3979
+ resolvedPath: pathAliasResolved,
3980
+ isExternal: false,
3981
+ packageName: void 0
3982
+ };
3983
+ resolveResultCache.set(cacheKey, resolvedResult);
3984
+ return resolvedResult;
3985
+ }
3986
+ if (isBareSpecifier(cleanedSpecifier)) {
3987
+ const tsconfigFile = findTsconfigForFile(fromFile);
3988
+ if (tsconfigFile) {
3989
+ const baseUrlDirectory = getBaseUrlDirectory(tsconfigFile);
3990
+ if (baseUrlDirectory) {
3991
+ const baseUrlCandidate = (0, node_path.resolve)(baseUrlDirectory, cleanedSpecifier);
3992
+ for (const candidateExtension of RESOLVER_EXTENSIONS) {
3993
+ const fullCandidate = baseUrlCandidate + candidateExtension;
3994
+ if (cachedExistsSync(fullCandidate)) {
3995
+ const resolvedResult = {
3996
+ resolvedPath: fullCandidate,
3997
+ isExternal: false,
3998
+ packageName: void 0
3999
+ };
4000
+ resolveResultCache.set(cacheKey, resolvedResult);
4001
+ return resolvedResult;
4002
+ }
4003
+ }
4004
+ const indexCandidate = (0, node_path.join)(baseUrlCandidate, "index");
4005
+ for (const candidateExtension of RESOLVER_EXTENSIONS) {
4006
+ const fullCandidate = indexCandidate + candidateExtension;
4007
+ if (cachedExistsSync(fullCandidate)) {
4008
+ const resolvedResult = {
4009
+ resolvedPath: fullCandidate,
4010
+ isExternal: false,
4011
+ packageName: void 0
4012
+ };
4013
+ resolveResultCache.set(cacheKey, resolvedResult);
4014
+ return resolvedResult;
4015
+ }
4016
+ }
4017
+ }
4018
+ }
4019
+ const resolvedResult = {
4020
+ resolvedPath: void 0,
4021
+ isExternal: true,
4022
+ packageName: extractPackageNameFromSpecifier(cleanedSpecifier)
4023
+ };
4024
+ resolveResultCache.set(cacheKey, resolvedResult);
4025
+ return resolvedResult;
4026
+ }
4027
+ const unresolvedResult = {
4028
+ resolvedPath: void 0,
4029
+ isExternal: false,
4030
+ packageName: void 0
4031
+ };
4032
+ resolveResultCache.set(cacheKey, unresolvedResult);
4033
+ return unresolvedResult;
4034
+ };
4035
+ return { resolveModule };
4036
+ };
4037
+ const stripJsonComments = (content) => {
4038
+ let result = "";
4039
+ let insideString = false;
4040
+ let index = 0;
4041
+ while (index < content.length) {
4042
+ if (insideString) {
4043
+ if (content[index] === "\\" && index + 1 < content.length) {
4044
+ result += content[index] + content[index + 1];
4045
+ index += 2;
4046
+ continue;
4047
+ }
4048
+ if (content[index] === "\"") insideString = false;
4049
+ result += content[index];
4050
+ index++;
4051
+ continue;
4052
+ }
4053
+ if (content[index] === "\"") {
4054
+ insideString = true;
4055
+ result += content[index];
4056
+ index++;
4057
+ continue;
4058
+ }
4059
+ if (content[index] === "/" && index + 1 < content.length) {
4060
+ if (content[index + 1] === "/") {
4061
+ while (index < content.length && content[index] !== "\n") index++;
4062
+ continue;
4063
+ }
4064
+ if (content[index + 1] === "*") {
4065
+ index += 2;
4066
+ while (index + 1 < content.length && !(content[index] === "*" && content[index + 1] === "/")) index++;
4067
+ index += 2;
4068
+ continue;
4069
+ }
4070
+ }
4071
+ result += content[index];
4072
+ index++;
4073
+ }
4074
+ return result.replace(/,(\s*[}\]])/g, "$1");
4075
+ };
4076
+ const BUILTIN_SUBPATH_MODULES = new Set([
4077
+ "fs",
4078
+ "dns",
4079
+ "stream",
4080
+ "readline",
4081
+ "timers",
4082
+ "util"
4083
+ ]);
4084
+ const isBuiltinModule = (specifier) => {
4085
+ if (specifier.startsWith("node:")) return true;
4086
+ const baseName = specifier.split("/")[0];
4087
+ if (!BUILTIN_MODULES.has(baseName)) return false;
4088
+ if (!specifier.includes("/")) return true;
4089
+ return BUILTIN_SUBPATH_MODULES.has(baseName);
4090
+ };
4091
+ const isBareSpecifier = (specifier) => !specifier.startsWith(".") && !specifier.startsWith("/");
4092
+ const extractPackageNameFromSpecifier = (specifier) => {
4093
+ if (specifier.startsWith("node:")) return specifier.slice(5).split("/")[0];
4094
+ if (specifier.startsWith("@")) {
4095
+ const parts = specifier.split("/");
4096
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : specifier;
4097
+ }
4098
+ return specifier.split("/")[0];
4099
+ };
4100
+
4101
+ //#endregion
4102
+ //#region src/utils/is-config-file.ts
4103
+ const isConfigFile = (filePath) => {
4104
+ const fileName = filePath.split("/").pop() ?? "";
4105
+ if (fileName.startsWith(".") && !fileName.startsWith("..")) {
4106
+ if (fileName.toLowerCase().includes("rc.")) return true;
4107
+ }
4108
+ return KNOWN_CONFIG_PREFIXES.some((prefix) => fileName.startsWith(prefix));
4109
+ };
4110
+
4111
+ //#endregion
4112
+ //#region src/linker/build.ts
4113
+ const buildDependencyGraph = (inputs) => {
4114
+ const fileIdMap = /* @__PURE__ */ new Map();
4115
+ for (const input of inputs) fileIdMap.set(input.fileId.path, input.fileId.index);
4116
+ const modules = inputs.map((input) => ({
4117
+ fileId: input.fileId,
4118
+ imports: input.parsed.imports,
4119
+ exports: input.parsed.exports,
4120
+ memberAccesses: input.parsed.memberAccesses,
4121
+ wholeObjectUses: input.parsed.wholeObjectUses,
4122
+ isEntryPoint: input.isEntryPoint,
4123
+ isTestEntry: input.isTestEntry,
4124
+ isReachable: false,
4125
+ isDeclarationFile: input.fileId.path.endsWith(".d.ts") || input.fileId.path.endsWith(".d.mts") || input.fileId.path.endsWith(".d.cts"),
4126
+ isConfigFile: isConfigFile(input.fileId.path)
4127
+ }));
4128
+ const edges = [];
4129
+ const reverseEdges = /* @__PURE__ */ new Map();
4130
+ const addEdge = (sourceIndex, targetIndex, symbols, isReExportEdge = false, reExportedNames = [], reExportMappings = []) => {
4131
+ edges.push({
4132
+ source: sourceIndex,
4133
+ target: targetIndex,
4134
+ importedSymbols: symbols,
4135
+ isReExportEdge,
4136
+ reExportedNames,
4137
+ reExportMappings
4138
+ });
4139
+ const existingReverseEdges = reverseEdges.get(targetIndex);
4140
+ if (existingReverseEdges) {
4141
+ if (!existingReverseEdges.includes(sourceIndex)) existingReverseEdges.push(sourceIndex);
4142
+ } else reverseEdges.set(targetIndex, [sourceIndex]);
4143
+ };
4144
+ for (const input of inputs) {
4145
+ const sourceIndex = input.fileId.index;
4146
+ for (const importInfo of input.parsed.imports) {
4147
+ if (importInfo.isGlob) {
4148
+ const sourceDir = node_path.default.dirname(input.fileId.path);
4149
+ const globPattern = importInfo.specifier;
4150
+ for (const [filePath] of fileIdMap) {
4151
+ const relativePath = node_path.default.relative(sourceDir, filePath);
4152
+ if ((0, minimatch.minimatch)(relativePath.startsWith(".") ? relativePath : `./${relativePath}`, globPattern)) {
4153
+ const targetIndex = fileIdMap.get(filePath);
4154
+ if (targetIndex !== void 0) addEdge(sourceIndex, targetIndex, []);
4155
+ }
4156
+ }
4157
+ continue;
4158
+ }
4159
+ const resolved = input.resolvedImports.get(importInfo.specifier);
4160
+ if (!resolved?.resolvedPath) continue;
4161
+ const targetIndex = fileIdMap.get(resolved.resolvedPath);
4162
+ if (targetIndex === void 0) continue;
4163
+ addEdge(sourceIndex, targetIndex, importInfo.importedNames.map((importedName) => ({
4164
+ importedName: importedName.name,
4165
+ localName: importedName.alias ?? importedName.name,
4166
+ isTypeOnly: importedName.isTypeOnly,
4167
+ isNamespace: importedName.isNamespace,
4168
+ isDefault: importedName.isDefault
4169
+ })));
4170
+ }
4171
+ const reExportsByTarget = /* @__PURE__ */ new Map();
4172
+ for (const exportInfo of input.parsed.exports) {
4173
+ if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
4174
+ const resolved = input.resolvedImports.get(exportInfo.reExportSource);
4175
+ if (!resolved?.resolvedPath) continue;
4176
+ const targetIndex = fileIdMap.get(resolved.resolvedPath);
4177
+ if (targetIndex === void 0) continue;
4178
+ const exportedName = exportInfo.isNamespaceReExport ? "*" : exportInfo.name;
4179
+ const originalName = exportInfo.isNamespaceReExport ? "*" : exportInfo.reExportOriginalName ?? exportInfo.name;
4180
+ const existing = reExportsByTarget.get(targetIndex);
4181
+ if (existing) {
4182
+ existing.names.push(exportedName);
4183
+ existing.mappings.push({
4184
+ exportedName,
4185
+ originalName
4186
+ });
4187
+ } else reExportsByTarget.set(targetIndex, {
4188
+ names: [exportedName],
4189
+ mappings: [{
4190
+ exportedName,
4191
+ originalName
4192
+ }]
4193
+ });
4194
+ }
4195
+ for (const [targetIndex, { names: reExportedNames, mappings: reExportMappings }] of reExportsByTarget) addEdge(sourceIndex, targetIndex, [], true, reExportedNames, reExportMappings);
4196
+ }
4197
+ return {
4198
+ modules,
4199
+ edges,
4200
+ reverseEdges,
4201
+ fileIdMap
4202
+ };
4203
+ };
4204
+
4205
+ //#endregion
4206
+ //#region src/linker/reachability.ts
4207
+ const PLATFORM_DIRECTORY_NAMES = new Set([
4208
+ "web",
4209
+ "native",
4210
+ "ios",
4211
+ "android",
4212
+ "desktop",
4213
+ "windows",
4214
+ "macos"
4215
+ ]);
4216
+ const stripPlatformSuffix = (filePath) => {
4217
+ for (const suffix of PLATFORM_SUFFIXES) {
4218
+ const extensionIndex = filePath.lastIndexOf(".");
4219
+ if (extensionIndex === -1) continue;
4220
+ const withoutExtension = filePath.slice(0, extensionIndex);
4221
+ if (withoutExtension.endsWith(suffix)) return withoutExtension.slice(0, -suffix.length) + filePath.slice(extensionIndex);
4222
+ }
4223
+ };
4224
+ const stripPlatformDirectory = (filePath) => {
4225
+ const segments = filePath.split("/");
4226
+ for (let segmentIndex = segments.length - 2; segmentIndex >= 0; segmentIndex--) if (PLATFORM_DIRECTORY_NAMES.has(segments[segmentIndex])) return [...segments.slice(0, segmentIndex), ...segments.slice(segmentIndex + 1)].join("/");
4227
+ };
4228
+ const traceReachability = (graph) => {
4229
+ const totalModules = graph.modules.length;
4230
+ const visited = new Uint8Array(totalModules);
4231
+ const consumedExportsPerModule = /* @__PURE__ */ new Map();
4232
+ const queue = [];
4233
+ const outgoingEdgesMap = /* @__PURE__ */ new Map();
4234
+ for (const edge of graph.edges) {
4235
+ const existing = outgoingEdgesMap.get(edge.source);
4236
+ if (existing) existing.push(edge);
4237
+ else outgoingEdgesMap.set(edge.source, [edge]);
4238
+ }
4239
+ for (const module of graph.modules) if (module.isEntryPoint) {
4240
+ const moduleIndex = module.fileId.index;
4241
+ if (moduleIndex < totalModules) {
4242
+ visited[moduleIndex] = 1;
4243
+ queue.push({
4244
+ moduleIndex,
4245
+ demandedSymbols: "all"
4246
+ });
4247
+ }
4248
+ }
4249
+ const markConsumedExports = (targetModuleIndex, symbols) => {
4250
+ if (symbols === "all") {
4251
+ consumedExportsPerModule.set(targetModuleIndex, new Set(["*"]));
4252
+ return;
4253
+ }
4254
+ const existing = consumedExportsPerModule.get(targetModuleIndex);
4255
+ if (existing && existing.has("*")) return;
4256
+ if (existing) for (const symbol of symbols) existing.add(symbol);
4257
+ else consumedExportsPerModule.set(targetModuleIndex, new Set(symbols));
4258
+ };
4259
+ let headPointer = 0;
4260
+ while (headPointer < queue.length) {
4261
+ const { moduleIndex: currentIndex } = queue[headPointer++];
4262
+ const outgoingEdges = outgoingEdgesMap.get(currentIndex);
4263
+ if (!outgoingEdges) continue;
4264
+ for (const edge of outgoingEdges) {
4265
+ const targetIndex = edge.target;
4266
+ if (targetIndex >= totalModules) continue;
4267
+ if (edge.isReExportEdge) {
4268
+ if (!visited[targetIndex]) {
4269
+ visited[targetIndex] = 1;
4270
+ markConsumedExports(targetIndex, "all");
4271
+ queue.push({
4272
+ moduleIndex: targetIndex,
4273
+ demandedSymbols: "all"
4274
+ });
4275
+ }
4276
+ } else {
4277
+ const importSymbolNames = /* @__PURE__ */ new Set();
4278
+ let isNamespaceOrSideEffect = edge.importedSymbols.length === 0;
4279
+ for (const symbol of edge.importedSymbols) {
4280
+ if (symbol.isNamespace) {
4281
+ isNamespaceOrSideEffect = true;
4282
+ break;
4283
+ }
4284
+ importSymbolNames.add(symbol.importedName);
4285
+ if (symbol.isDefault) importSymbolNames.add("default");
4286
+ }
4287
+ const symbolDemand = isNamespaceOrSideEffect ? "all" : importSymbolNames;
4288
+ if (!visited[targetIndex]) {
4289
+ visited[targetIndex] = 1;
4290
+ markConsumedExports(targetIndex, symbolDemand);
4291
+ queue.push({
4292
+ moduleIndex: targetIndex,
4293
+ demandedSymbols: symbolDemand
4294
+ });
4295
+ } else {
4296
+ const existingConsumed = consumedExportsPerModule.get(targetIndex);
4297
+ if (symbolDemand !== "all" && existingConsumed && !existingConsumed.has("*")) {
4298
+ let hasNewSymbols = false;
4299
+ for (const symbol of symbolDemand) if (!existingConsumed.has(symbol)) {
4300
+ hasNewSymbols = true;
4301
+ break;
4302
+ }
4303
+ if (hasNewSymbols) {
4304
+ markConsumedExports(targetIndex, symbolDemand);
4305
+ queue.push({
4306
+ moduleIndex: targetIndex,
4307
+ demandedSymbols: symbolDemand
4308
+ });
4309
+ }
4310
+ } else if (symbolDemand === "all" && (!existingConsumed || !existingConsumed.has("*"))) {
4311
+ markConsumedExports(targetIndex, "all");
4312
+ queue.push({
4313
+ moduleIndex: targetIndex,
4314
+ demandedSymbols: "all"
4315
+ });
4316
+ }
4317
+ }
4318
+ }
4319
+ }
4320
+ }
4321
+ const platformSiblingGroups = /* @__PURE__ */ new Map();
4322
+ const addToSiblingGroup = (groupKey, moduleIndex) => {
4323
+ const existingSiblings = platformSiblingGroups.get(groupKey);
4324
+ if (existingSiblings) existingSiblings.push(moduleIndex);
4325
+ else platformSiblingGroups.set(groupKey, [moduleIndex]);
4326
+ };
4327
+ for (let moduleIndex = 0; moduleIndex < totalModules; moduleIndex++) {
4328
+ const modulePath = graph.modules[moduleIndex].fileId.path;
4329
+ const basePathFromSuffix = stripPlatformSuffix(modulePath);
4330
+ if (basePathFromSuffix) addToSiblingGroup(basePathFromSuffix, moduleIndex);
4331
+ const basePathFromDirectory = stripPlatformDirectory(modulePath);
4332
+ if (basePathFromDirectory) addToSiblingGroup("dir:" + basePathFromDirectory, moduleIndex);
4333
+ }
4334
+ for (let moduleIndex = 0; moduleIndex < totalModules; moduleIndex++) {
4335
+ const modulePath = graph.modules[moduleIndex].fileId.path;
4336
+ if (platformSiblingGroups.has(modulePath)) platformSiblingGroups.get(modulePath).push(moduleIndex);
4337
+ }
4338
+ const platformQueue = [];
4339
+ for (const siblingIndices of platformSiblingGroups.values()) if (siblingIndices.some((index) => Boolean(visited[index]))) {
4340
+ for (const siblingIndex of siblingIndices) if (!visited[siblingIndex]) {
4341
+ visited[siblingIndex] = 1;
4342
+ platformQueue.push({
4343
+ moduleIndex: siblingIndex,
4344
+ demandedSymbols: "all"
4345
+ });
4346
+ }
4347
+ }
4348
+ let platformHeadPointer = 0;
4349
+ while (platformHeadPointer < platformQueue.length) {
4350
+ const { moduleIndex: currentIndex } = platformQueue[platformHeadPointer++];
4351
+ const outgoingEdges = outgoingEdgesMap.get(currentIndex);
4352
+ if (!outgoingEdges) continue;
4353
+ for (const edge of outgoingEdges) if (edge.target < totalModules && !visited[edge.target]) {
4354
+ visited[edge.target] = 1;
4355
+ platformQueue.push({
4356
+ moduleIndex: edge.target,
4357
+ demandedSymbols: "all"
4358
+ });
4359
+ }
4360
+ }
4361
+ for (let moduleIndex = 0; moduleIndex < totalModules; moduleIndex++) graph.modules[moduleIndex].isReachable = Boolean(visited[moduleIndex]);
4362
+ };
4363
+
4364
+ //#endregion
4365
+ //#region src/linker/re-exports.ts
4366
+ const resolveReExportChains = (graph) => {
4367
+ const sourceToTargets = buildSourceTargetMap(graph);
4368
+ const maxIterations = graph.modules.length * 2 + 1;
4369
+ let didChange = true;
4370
+ let iterationCount = 0;
4371
+ while (didChange && iterationCount < maxIterations) {
4372
+ didChange = false;
4373
+ iterationCount++;
4374
+ for (const module of graph.modules) {
4375
+ const originalExportCount = module.exports.length;
4376
+ for (let exportIndex = 0; exportIndex < originalExportCount; exportIndex++) {
4377
+ const exportInfo = module.exports[exportIndex];
4378
+ if (!exportInfo.isReExport || !exportInfo.reExportSource) continue;
4379
+ if (!exportInfo.isNamespaceReExport) continue;
4380
+ const targetIndices = sourceToTargets.get(module.fileId.index);
4381
+ if (!targetIndices) continue;
4382
+ for (const targetIndex of targetIndices) {
4383
+ const targetModule = graph.modules[targetIndex];
4384
+ if (!targetModule) continue;
4385
+ for (const targetExport of targetModule.exports) {
4386
+ if (targetExport.name === "*" && targetExport.isNamespaceReExport) continue;
4387
+ if (!module.exports.some((existingExport) => existingExport.name === targetExport.name && !existingExport.isNamespaceReExport)) {
4388
+ module.exports.push({
4389
+ name: targetExport.name,
4390
+ isDefault: targetExport.isDefault,
4391
+ isTypeOnly: targetExport.isTypeOnly || exportInfo.isTypeOnly,
4392
+ isReExport: true,
4393
+ isSynthetic: true,
4394
+ reExportSource: exportInfo.reExportSource,
4395
+ reExportOriginalName: targetExport.name,
4396
+ isNamespaceReExport: false,
4397
+ line: exportInfo.line,
4398
+ column: exportInfo.column
4399
+ });
4400
+ didChange = true;
4401
+ }
4402
+ }
4403
+ }
4404
+ }
4405
+ }
4406
+ }
4407
+ };
4408
+ const buildSourceTargetMap = (graph) => {
4409
+ const sourceTargets = /* @__PURE__ */ new Map();
4410
+ for (const edge of graph.edges) {
4411
+ const existing = sourceTargets.get(edge.source);
4412
+ if (existing) {
4413
+ if (!existing.includes(edge.target)) existing.push(edge.target);
4414
+ } else sourceTargets.set(edge.source, [edge.target]);
4415
+ }
4416
+ return sourceTargets;
4417
+ };
4418
+
4419
+ //#endregion
4420
+ //#region src/report/files.ts
4421
+ const isHtmlFile = (filePath) => {
4422
+ return filePath.endsWith(".html");
4423
+ };
4424
+ const detectOrphanFiles = (graph) => {
4425
+ const unusedFiles = [];
4426
+ for (const module of graph.modules) {
4427
+ if (module.isReachable) continue;
4428
+ if (module.isEntryPoint) continue;
4429
+ if (module.isDeclarationFile) continue;
4430
+ if (module.isConfigFile) continue;
4431
+ if (isHtmlFile(module.fileId.path)) continue;
4432
+ if (isBarrelWithReachableSources(module, graph)) continue;
4433
+ if (hasReachableDirectImporter(module.fileId.index, graph)) continue;
4434
+ unusedFiles.push({ path: module.fileId.path });
4435
+ }
4436
+ return unusedFiles;
4437
+ };
4438
+ const isBarrelWithReachableSources = (module, graph) => {
4439
+ if (module.exports.length === 0) return false;
4440
+ if (!module.exports.every((exportInfo) => exportInfo.isNamespaceReExport || exportInfo.isSynthetic)) return false;
4441
+ for (const edge of graph.edges) if (edge.source === module.fileId.index) {
4442
+ if (graph.modules[edge.target]?.isReachable) return true;
4443
+ }
4444
+ return false;
4445
+ };
4446
+ const hasReachableDirectImporter = (targetModuleIndex, graph) => {
4447
+ for (const edge of graph.edges) {
4448
+ if (edge.target !== targetModuleIndex) continue;
4449
+ if (edge.isReExportEdge) continue;
4450
+ if (graph.modules[edge.source]?.isReachable) return true;
4451
+ }
4452
+ return false;
4453
+ };
4454
+
4455
+ //#endregion
4456
+ //#region src/report/exports.ts
4457
+ const detectDeadExports = (graph, config) => {
4458
+ const usageMap = buildUsageMap(graph);
4459
+ const unusedExports = [];
4460
+ for (const module of graph.modules) {
4461
+ if (!module.isReachable) continue;
4462
+ if (module.isDeclarationFile) continue;
4463
+ if (module.isEntryPoint && !config.includeEntryExports) continue;
4464
+ for (const exportInfo of module.exports) {
4465
+ if (exportInfo.name === "*" && exportInfo.isNamespaceReExport) continue;
4466
+ if (exportInfo.isReExport && exportInfo.reExportOriginalName) continue;
4467
+ if (!config.reportTypes && exportInfo.isTypeOnly) continue;
4468
+ const usageKey = `${module.fileId.path}::${exportInfo.name}`;
4469
+ if (!usageMap.has(usageKey)) unusedExports.push({
4470
+ path: module.fileId.path,
4471
+ name: exportInfo.name,
4472
+ line: exportInfo.line,
4473
+ column: exportInfo.column,
4474
+ isTypeOnly: exportInfo.isTypeOnly
4475
+ });
4476
+ }
4477
+ }
4478
+ return unusedExports;
4479
+ };
4480
+ const buildUsageMap = (graph) => {
4481
+ const usedExportKeys = /* @__PURE__ */ new Set();
4482
+ const sourceToTargetMap = buildSourceToTargetsMap(graph);
4483
+ for (const edge of graph.edges) {
4484
+ const targetModule = graph.modules[edge.target];
4485
+ if (!targetModule) continue;
4486
+ const sourceModule = graph.modules[edge.source];
4487
+ for (const symbol of edge.importedSymbols) if (symbol.isNamespace) handleNamespaceImport(sourceModule, targetModule, symbol.localName, graph, sourceToTargetMap, usedExportKeys);
4488
+ else {
4489
+ const importName = symbol.isDefault ? "default" : symbol.importedName;
4490
+ markExportUsedRecursive(targetModule.fileId.path, importName, graph, sourceToTargetMap, usedExportKeys, /* @__PURE__ */ new Set());
4491
+ }
4492
+ }
4493
+ return usedExportKeys;
4494
+ };
4495
+ const handleNamespaceImport = (sourceModule, targetModule, namespaceLocalName, graph, sourceToTargets, usedKeys) => {
4496
+ if (!sourceModule) {
4497
+ markAllExportsUsedRecursive(targetModule, graph, sourceToTargets, usedKeys, /* @__PURE__ */ new Set());
4498
+ return;
4499
+ }
4500
+ if (sourceModule.wholeObjectUses.includes(namespaceLocalName)) {
4501
+ markAllExportsUsedRecursive(targetModule, graph, sourceToTargets, usedKeys, /* @__PURE__ */ new Set());
4502
+ return;
4503
+ }
4504
+ const accessedMemberNames = extractAccessedMemberNames(sourceModule.memberAccesses, namespaceLocalName);
4505
+ const isNamespaceReExported = sourceModule.exports.some((exportInfo) => exportInfo.reExportOriginalName === namespaceLocalName || !exportInfo.isReExport && exportInfo.name === namespaceLocalName);
4506
+ if (accessedMemberNames.length === 0 && !isNamespaceReExported) {
4507
+ markAllExportsUsedRecursive(targetModule, graph, sourceToTargets, usedKeys, /* @__PURE__ */ new Set());
4508
+ return;
4509
+ }
4510
+ if (isNamespaceReExported && !sourceModule.isEntryPoint) {
4511
+ markAllExportsUsedRecursive(targetModule, graph, sourceToTargets, usedKeys, /* @__PURE__ */ new Set());
4512
+ return;
4513
+ }
4514
+ for (const memberName of accessedMemberNames) markExportUsedRecursive(targetModule.fileId.path, memberName, graph, sourceToTargets, usedKeys, /* @__PURE__ */ new Set());
4515
+ };
4516
+ const extractAccessedMemberNames = (memberAccesses, objectName) => {
4517
+ const memberNames = [];
4518
+ const seenNames = /* @__PURE__ */ new Set();
4519
+ for (const access of memberAccesses) if (access.objectName === objectName && !seenNames.has(access.memberName)) {
4520
+ seenNames.add(access.memberName);
4521
+ memberNames.push(access.memberName);
4522
+ }
4523
+ return memberNames;
4524
+ };
4525
+ const buildSourceToTargetsMap = (graph) => {
4526
+ const sourceToTargets = /* @__PURE__ */ new Map();
4527
+ for (const edge of graph.edges) {
4528
+ const existing = sourceToTargets.get(edge.source);
4529
+ if (existing) {
4530
+ if (!existing.includes(edge.target)) existing.push(edge.target);
4531
+ } else sourceToTargets.set(edge.source, [edge.target]);
4532
+ }
4533
+ return sourceToTargets;
4534
+ };
4535
+ const markAllExportsUsedRecursive = (module, graph, sourceToTargets, usedKeys, visited) => {
4536
+ const visitKey = `all::${module.fileId.path}`;
4537
+ if (visited.has(visitKey)) return;
4538
+ visited.add(visitKey);
4539
+ for (const exportInfo of module.exports) {
4540
+ if (exportInfo.name === "*" && exportInfo.isNamespaceReExport) continue;
4541
+ const usageKey = `${module.fileId.path}::${exportInfo.name}`;
4542
+ usedKeys.add(usageKey);
4543
+ if (exportInfo.isReExport && exportInfo.reExportSource) followReExportChain(module.fileId.index, exportInfo, graph, sourceToTargets, usedKeys, visited);
4544
+ }
4545
+ };
4546
+ const markExportUsedRecursive = (filePath, exportName, graph, sourceToTargets, usedKeys, visited) => {
4547
+ const visitKey = `${filePath}::${exportName}`;
4548
+ if (visited.has(visitKey)) return;
4549
+ visited.add(visitKey);
4550
+ usedKeys.add(visitKey);
4551
+ const moduleIndex = graph.fileIdMap.get(filePath);
4552
+ if (moduleIndex === void 0) return;
4553
+ const module = graph.modules[moduleIndex];
4554
+ if (!module) return;
4555
+ for (const exportInfo of module.exports) {
4556
+ if (exportInfo.name !== exportName) continue;
4557
+ if (exportInfo.isReExport && exportInfo.reExportSource) followReExportChain(moduleIndex, exportInfo, graph, sourceToTargets, usedKeys, visited);
4558
+ }
4559
+ };
4560
+ const followReExportChain = (reExporterModuleIndex, exportInfo, graph, sourceToTargets, usedKeys, visited) => {
4561
+ const targetIndices = sourceToTargets.get(reExporterModuleIndex);
4562
+ if (!targetIndices) return;
4563
+ const originalName = exportInfo.reExportOriginalName ?? exportInfo.name;
4564
+ for (const targetIndex of targetIndices) {
4565
+ const targetModule = graph.modules[targetIndex];
4566
+ if (!targetModule) continue;
4567
+ if (originalName === "*" || exportInfo.isNamespaceReExport) markExportUsedRecursive(targetModule.fileId.path, exportInfo.name, graph, sourceToTargets, usedKeys, visited);
4568
+ else if (targetModule.exports.some((targetExport) => targetExport.name === originalName || targetExport.isNamespaceReExport && targetExport.name === "*")) markExportUsedRecursive(targetModule.fileId.path, originalName, graph, sourceToTargets, usedKeys, visited);
4569
+ }
4570
+ };
4571
+
4572
+ //#endregion
4573
+ //#region src/utils/package-name.ts
4574
+ const extractPackageName = (specifier) => {
4575
+ if (specifier.startsWith(".") || specifier.startsWith("/")) return void 0;
4576
+ if (specifier.startsWith("node:")) return void 0;
4577
+ if (specifier.startsWith("@")) {
4578
+ const parts = specifier.split("/");
4579
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : void 0;
4580
+ }
4581
+ return specifier.split("/")[0];
4582
+ };
4583
+
4584
+ //#endregion
4585
+ //#region src/report/packages.ts
4586
+ const detectStalePackages = (graph, config) => {
4587
+ const packageJsonPath = (0, node_path.resolve)(config.rootDir, "package.json");
4588
+ let packageJson;
4589
+ try {
4590
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
4591
+ packageJson = JSON.parse(content);
4592
+ } catch {
4593
+ return [];
4594
+ }
4595
+ const dependencies = packageJson.dependencies ?? {};
4596
+ const devDependencies = packageJson.devDependencies ?? {};
4597
+ const declaredDependencies = /* @__PURE__ */ new Map();
4598
+ for (const dependencyName of Object.keys(dependencies)) declaredDependencies.set(dependencyName, false);
4599
+ for (const dependencyName of Object.keys(devDependencies)) declaredDependencies.set(dependencyName, true);
4600
+ const usedPackageNames = collectUsedPackages(graph);
4601
+ const unusedDependencies = [];
4602
+ for (const [dependencyName, isDevDependency] of declaredDependencies) {
4603
+ if (isAlwaysConsideredUsed(dependencyName)) continue;
4604
+ if (!usedPackageNames.has(dependencyName)) unusedDependencies.push({
4605
+ name: dependencyName,
4606
+ isDevDependency
4607
+ });
4608
+ }
4609
+ return unusedDependencies;
4610
+ };
4611
+ const collectUsedPackages = (graph) => {
4612
+ const usedPackages = /* @__PURE__ */ new Set();
4613
+ for (const module of graph.modules) for (const importInfo of module.imports) {
4614
+ const packageName = extractPackageName(importInfo.specifier);
4615
+ if (packageName) usedPackages.add(packageName);
4616
+ }
4617
+ return usedPackages;
4618
+ };
4619
+ const isAlwaysConsideredUsed = (dependencyName) => {
4620
+ if (IMPLICIT_DEPENDENCIES.has(dependencyName)) return true;
4621
+ if (dependencyName.startsWith("@types/")) return true;
4622
+ if (dependencyName.startsWith("eslint-config-")) return true;
4623
+ if (dependencyName.startsWith("eslint-plugin-")) return true;
4624
+ if (dependencyName.startsWith("prettier-plugin-")) return true;
4625
+ return false;
4626
+ };
4627
+
4628
+ //#endregion
4629
+ //#region src/report/cycles.ts
4630
+ const UNDEFINED_INDEX = -1;
4631
+ const buildAdjacencyList = (graph) => {
4632
+ const targetSets = Array.from({ length: graph.modules.length }, () => /* @__PURE__ */ new Set());
4633
+ for (const edge of graph.edges) {
4634
+ if (edge.importedSymbols.every((symbol) => symbol.isTypeOnly)) continue;
4635
+ if (edge.target < graph.modules.length) targetSets[edge.source].add(edge.target);
4636
+ }
4637
+ return targetSets.map((targets) => [...targets]);
4638
+ };
4639
+ const findStronglyConnectedComponents = (adjacencyList) => {
4640
+ const nodeCount = adjacencyList.length;
4641
+ if (nodeCount === 0) return [];
4642
+ const state = {
4643
+ indexCounter: 0,
4644
+ indices: Array(nodeCount).fill(UNDEFINED_INDEX),
4645
+ lowlinks: Array(nodeCount).fill(0),
4646
+ onStack: Array(nodeCount).fill(false),
4647
+ stack: []
4648
+ };
4649
+ const components = [];
4650
+ const dfsStack = [];
4651
+ for (let startNode = 0; startNode < nodeCount; startNode++) {
4652
+ if (state.indices[startNode] !== UNDEFINED_INDEX) continue;
4653
+ state.indices[startNode] = state.indexCounter;
4654
+ state.lowlinks[startNode] = state.indexCounter;
4655
+ state.indexCounter++;
4656
+ state.onStack[startNode] = true;
4657
+ state.stack.push(startNode);
4658
+ dfsStack.push({
4659
+ node: startNode,
4660
+ successorPosition: 0
4661
+ });
4662
+ while (dfsStack.length > 0) {
4663
+ const frame = dfsStack[dfsStack.length - 1];
4664
+ const successors = adjacencyList[frame.node];
4665
+ if (frame.successorPosition < successors.length) {
4666
+ const successor = successors[frame.successorPosition];
4667
+ frame.successorPosition++;
4668
+ if (state.indices[successor] === UNDEFINED_INDEX) {
4669
+ state.indices[successor] = state.indexCounter;
4670
+ state.lowlinks[successor] = state.indexCounter;
4671
+ state.indexCounter++;
4672
+ state.onStack[successor] = true;
4673
+ state.stack.push(successor);
4674
+ dfsStack.push({
4675
+ node: successor,
4676
+ successorPosition: 0
4677
+ });
4678
+ } else if (state.onStack[successor]) state.lowlinks[frame.node] = Math.min(state.lowlinks[frame.node], state.indices[successor]);
4679
+ } else {
4680
+ const currentNode = frame.node;
4681
+ const currentLowlink = state.lowlinks[currentNode];
4682
+ const currentIndex = state.indices[currentNode];
4683
+ dfsStack.pop();
4684
+ if (dfsStack.length > 0) {
4685
+ const parentFrame = dfsStack[dfsStack.length - 1];
4686
+ state.lowlinks[parentFrame.node] = Math.min(state.lowlinks[parentFrame.node], currentLowlink);
4687
+ }
4688
+ if (currentLowlink === currentIndex) {
4689
+ const component = [];
4690
+ let poppedNode;
4691
+ do {
4692
+ poppedNode = state.stack.pop();
4693
+ state.onStack[poppedNode] = false;
4694
+ component.push(poppedNode);
4695
+ } while (poppedNode !== currentNode);
4696
+ if (component.length >= 2) components.push(component);
4697
+ }
4698
+ }
4699
+ }
4700
+ }
4701
+ return components;
4702
+ };
4703
+ const canonicalizeCycle = (cycle, graph) => {
4704
+ if (cycle.length === 0) return [];
4705
+ let minPosition = 0;
4706
+ let minPath = graph.modules[cycle[0]].fileId.path;
4707
+ for (let position = 1; position < cycle.length; position++) {
4708
+ const currentPath = graph.modules[cycle[position]].fileId.path;
4709
+ if (currentPath < minPath) {
4710
+ minPath = currentPath;
4711
+ minPosition = position;
4712
+ }
4713
+ }
4714
+ return [...cycle.slice(minPosition), ...cycle.slice(0, minPosition)];
4715
+ };
4716
+ const enumerateElementaryCycles = (componentNodes, adjacencyList, graph) => {
4717
+ if (componentNodes.length === 2) {
4718
+ const [nodeA, nodeB] = componentNodes;
4719
+ return [graph.modules[nodeA].fileId.path <= graph.modules[nodeB].fileId.path ? [nodeA, nodeB] : [nodeB, nodeA]];
4720
+ }
4721
+ const componentSet = new Set(componentNodes);
4722
+ const cycles = [];
4723
+ const seenKeys = /* @__PURE__ */ new Set();
4724
+ for (const startNode of componentNodes) {
4725
+ if (cycles.length >= 20) break;
4726
+ const visitedInThisSearch = /* @__PURE__ */ new Set();
4727
+ visitedInThisSearch.add(startNode);
4728
+ const pathStack = [startNode];
4729
+ const successorPositionStack = [0];
4730
+ while (pathStack.length > 0 && cycles.length < 20) {
4731
+ const currentNode = pathStack[pathStack.length - 1];
4732
+ const currentSuccessorPosition = successorPositionStack[successorPositionStack.length - 1];
4733
+ const successors = adjacencyList[currentNode].filter((successor) => componentSet.has(successor));
4734
+ if (currentSuccessorPosition < successors.length) {
4735
+ successorPositionStack[successorPositionStack.length - 1]++;
4736
+ const successor = successors[currentSuccessorPosition];
4737
+ if (successor === startNode) {
4738
+ const canonical = canonicalizeCycle([...pathStack], graph);
4739
+ const key = canonical.join(",");
4740
+ if (!seenKeys.has(key)) {
4741
+ seenKeys.add(key);
4742
+ cycles.push(canonical);
4743
+ }
4744
+ } else if (!visitedInThisSearch.has(successor)) {
4745
+ visitedInThisSearch.add(successor);
4746
+ pathStack.push(successor);
4747
+ successorPositionStack.push(0);
4748
+ }
4749
+ } else {
4750
+ visitedInThisSearch.delete(pathStack.pop());
4751
+ successorPositionStack.pop();
4752
+ }
4753
+ }
4754
+ }
4755
+ return cycles;
4756
+ };
4757
+ const detectCycles = (graph) => {
4758
+ const adjacencyList = buildAdjacencyList(graph);
4759
+ const components = findStronglyConnectedComponents(adjacencyList);
4760
+ const allCycles = [];
4761
+ const seenKeys = /* @__PURE__ */ new Set();
4762
+ const sortedComponents = [...components].sort((componentA, componentB) => componentA.length - componentB.length);
4763
+ for (const component of sortedComponents) {
4764
+ if (allCycles.length >= 200) break;
4765
+ if (component.length > 50) continue;
4766
+ const elementaryCycles = enumerateElementaryCycles(component, adjacencyList, graph);
4767
+ for (const cycle of elementaryCycles) {
4768
+ const key = cycle.join(",");
4769
+ if (!seenKeys.has(key)) {
4770
+ seenKeys.add(key);
4771
+ allCycles.push(cycle);
4772
+ }
4773
+ if (allCycles.length >= 200) break;
4774
+ }
4775
+ }
4776
+ allCycles.sort((cycleA, cycleB) => {
4777
+ const lengthDiff = cycleA.length - cycleB.length;
4778
+ if (lengthDiff !== 0) return lengthDiff;
4779
+ return graph.modules[cycleA[0]].fileId.path.localeCompare(graph.modules[cycleB[0]].fileId.path);
4780
+ });
4781
+ return allCycles.map((cycle) => ({ files: cycle.map((nodeIndex) => graph.modules[nodeIndex].fileId.path) }));
4782
+ };
4783
+
4784
+ //#endregion
4785
+ //#region src/report/generate.ts
4786
+ const generateReport = (graph, config) => {
4787
+ const analysisStartTime = performance.now();
4788
+ const unusedFiles = detectOrphanFiles(graph);
4789
+ const unusedExports = detectDeadExports(graph, config);
4790
+ const unusedDependencies = detectStalePackages(graph, config);
4791
+ const circularDependencies = detectCycles(graph);
4792
+ const totalExports = graph.modules.reduce((exportCount, module) => exportCount + module.exports.filter((exportInfo) => !(exportInfo.name === "*" && exportInfo.isNamespaceReExport)).length, 0);
4793
+ return {
4794
+ unusedFiles,
4795
+ unusedExports,
4796
+ unusedDependencies,
4797
+ circularDependencies,
4798
+ totalFiles: graph.modules.length,
4799
+ totalExports,
4800
+ analysisTimeMs: performance.now() - analysisStartTime
4801
+ };
4802
+ };
4803
+
4804
+ //#endregion
4805
+ //#region src/index.ts
4806
+ const STYLE_EXTENSIONS = [".css", ".scss"];
4807
+ const REACT_NATIVE_ENABLERS = ["react-native", "expo"];
4808
+ const detectReactNative = (rootDir, workspacePackages) => {
4809
+ const directoriesToCheck = [rootDir, ...workspacePackages.map((workspacePackage) => workspacePackage.directory)];
4810
+ for (const directory of directoriesToCheck) {
4811
+ const packageJsonPath = (0, node_path.resolve)(directory, "package.json");
4812
+ if (!(0, node_fs.existsSync)(packageJsonPath)) continue;
4813
+ try {
4814
+ const content = (0, node_fs.readFileSync)(packageJsonPath, "utf-8");
4815
+ const packageJson = JSON.parse(content);
4816
+ const allDependencies = {
4817
+ ...packageJson.dependencies,
4818
+ ...packageJson.devDependencies,
4819
+ ...packageJson.optionalDependencies
4820
+ };
4821
+ if (REACT_NATIVE_ENABLERS.some((enabler) => enabler in allDependencies)) return true;
4822
+ } catch {
4823
+ continue;
4824
+ }
4825
+ }
4826
+ return false;
4827
+ };
4828
+ const defineConfig = (options) => ({
4829
+ rootDir: (0, node_path.resolve)(options.rootDir),
4830
+ entryPatterns: options.entryPatterns ?? DEFAULT_ENTRY_GLOBS,
4831
+ ignorePatterns: options.ignorePatterns ?? [],
4832
+ includeExtensions: options.includeExtensions ?? DEFAULT_EXTENSIONS,
4833
+ tsConfigPath: options.tsConfigPath ?? void 0,
4834
+ reportTypes: options.reportTypes ?? false,
4835
+ includeEntryExports: options.includeEntryExports ?? false
4836
+ });
4837
+ const analyze = async (config) => {
4838
+ const pipelineStartTime = performance.now();
4839
+ const workspaceDiscovery = resolveWorkspaces((0, node_path.resolve)(config.rootDir));
4840
+ const workspacePackages = workspaceDiscovery.packages;
4841
+ const frameworkIgnorePatterns = getFrameworkExclusions(config.rootDir);
4842
+ const absoluteRoot = (0, node_path.resolve)(config.rootDir);
4843
+ const outputDirectoryExclusions = OUTPUT_DIRECTORIES.flatMap((outputDirectory) => {
4844
+ const exclusions = [`${absoluteRoot}/${outputDirectory}/**`];
4845
+ for (const workspacePackage of workspacePackages) exclusions.push(`${workspacePackage.directory}/${outputDirectory}/**`);
4846
+ return exclusions;
4847
+ });
4848
+ const allExclusionPatterns = [
4849
+ ...workspaceDiscovery.excludedDirectories.map((directory) => `${directory}/**`),
4850
+ ...frameworkIgnorePatterns,
4851
+ ...outputDirectoryExclusions
4852
+ ];
4853
+ const configWithExclusions = allExclusionPatterns.length > 0 ? {
4854
+ ...config,
4855
+ ignorePatterns: [...config.ignorePatterns, ...allExclusionPatterns]
4856
+ } : config;
4857
+ const files = await collectSourceFiles(configWithExclusions);
4858
+ const discoveredEntries = await resolveEntries(configWithExclusions);
4859
+ const productionEntrySet = new Set(discoveredEntries.productionEntries);
4860
+ const testEntrySet = new Set(discoveredEntries.testEntries);
4861
+ const alwaysUsedFileSet = new Set(discoveredEntries.alwaysUsedFiles);
4862
+ const hasReactNative = detectReactNative(config.rootDir, workspacePackages);
4863
+ const moduleResolver = createResolver(config, workspacePackages.map((workspacePackage) => ({
4864
+ name: workspacePackage.name,
4865
+ directory: workspacePackage.directory
4866
+ })), { hasReactNative });
4867
+ const graphInputs = [];
4868
+ for (const file of files) {
4869
+ const parsedModule = parseSourceFile(file.path);
4870
+ const resolvedImportMap = /* @__PURE__ */ new Map();
4871
+ for (const importInfo of parsedModule.imports) {
4872
+ if (importInfo.isGlob) {
4873
+ const fileDir = (0, node_path.dirname)(file.path);
4874
+ const expandedFiles = fast_glob.default.sync(importInfo.specifier, {
4875
+ cwd: fileDir,
4876
+ absolute: true,
4877
+ onlyFiles: true,
4878
+ ignore: ["**/node_modules/**"]
4879
+ });
4880
+ for (const expandedFile of expandedFiles) resolvedImportMap.set(expandedFile, {
4881
+ resolvedPath: expandedFile,
4882
+ isExternal: false,
4883
+ packageName: void 0
4884
+ });
4885
+ resolvedImportMap.set(importInfo.specifier, {
4886
+ resolvedPath: void 0,
4887
+ isExternal: false,
4888
+ packageName: void 0
4889
+ });
4890
+ continue;
4891
+ }
4892
+ const resolvedImport = moduleResolver.resolveModule(importInfo.specifier, file.path);
4893
+ resolvedImportMap.set(importInfo.specifier, resolvedImport);
4894
+ }
4895
+ for (const exportInfo of parsedModule.exports) if (exportInfo.isReExport && exportInfo.reExportSource) {
4896
+ if (!resolvedImportMap.has(exportInfo.reExportSource)) {
4897
+ const resolvedImport = moduleResolver.resolveModule(exportInfo.reExportSource, file.path);
4898
+ resolvedImportMap.set(exportInfo.reExportSource, resolvedImport);
4899
+ }
4900
+ }
4901
+ const isAlwaysUsed = alwaysUsedFileSet.has(file.path);
4902
+ graphInputs.push({
4903
+ fileId: file,
4904
+ parsed: parsedModule,
4905
+ resolvedImports: resolvedImportMap,
4906
+ isEntryPoint: isAlwaysUsed || productionEntrySet.has(file.path) || testEntrySet.has(file.path),
4907
+ isTestEntry: testEntrySet.has(file.path)
4908
+ });
4909
+ }
4910
+ const discoveredFilePaths = new Set(files.map((file) => file.path));
4911
+ const styleFilesToAdd = /* @__PURE__ */ new Set();
4912
+ for (const input of graphInputs) for (const [, resolvedImport] of input.resolvedImports) {
4913
+ if (!resolvedImport.resolvedPath || resolvedImport.isExternal) continue;
4914
+ if (discoveredFilePaths.has(resolvedImport.resolvedPath)) continue;
4915
+ if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && (0, node_fs.existsSync)(resolvedImport.resolvedPath)) styleFilesToAdd.add(resolvedImport.resolvedPath);
4916
+ }
4917
+ const sortedStyleFiles = [...styleFilesToAdd].sort();
4918
+ let nextFileIndex = files.length;
4919
+ for (const styleFilePath of sortedStyleFiles) {
4920
+ const styleSourceFile = {
4921
+ index: nextFileIndex,
4922
+ path: styleFilePath
4923
+ };
4924
+ const parsedStyleModule = parseSourceFile(styleFilePath);
4925
+ const resolvedStyleImportMap = /* @__PURE__ */ new Map();
4926
+ for (const importInfo of parsedStyleModule.imports) {
4927
+ const resolvedImport = moduleResolver.resolveModule(importInfo.specifier, styleFilePath);
4928
+ resolvedStyleImportMap.set(importInfo.specifier, resolvedImport);
4929
+ if (resolvedImport.resolvedPath && !discoveredFilePaths.has(resolvedImport.resolvedPath)) {
4930
+ if (STYLE_EXTENSIONS.some((ext) => resolvedImport.resolvedPath.endsWith(ext)) && (0, node_fs.existsSync)(resolvedImport.resolvedPath)) styleFilesToAdd.add(resolvedImport.resolvedPath);
4931
+ }
4932
+ }
4933
+ graphInputs.push({
4934
+ fileId: styleSourceFile,
4935
+ parsed: parsedStyleModule,
4936
+ resolvedImports: resolvedStyleImportMap,
4937
+ isEntryPoint: false,
4938
+ isTestEntry: false
4939
+ });
4940
+ discoveredFilePaths.add(styleFilePath);
4941
+ nextFileIndex++;
4942
+ }
4943
+ const moduleGraph = buildDependencyGraph(graphInputs);
4944
+ resolveReExportChains(moduleGraph);
4945
+ traceReachability(moduleGraph);
4946
+ const analysisResult = generateReport(moduleGraph, config);
4947
+ analysisResult.analysisTimeMs = performance.now() - pipelineStartTime;
4948
+ return analysisResult;
4949
+ };
4950
+
4951
+ //#endregion
4952
+ exports.analyze = analyze;
4953
+ exports.defineConfig = defineConfig;