foresthouse 1.0.0-dev.3 → 1.0.0-dev.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +14 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{tree-DbnWcUnV.mjs → tree-BrguxPgp.mjs} +184 -23
- package/dist/tree-BrguxPgp.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/tree-DbnWcUnV.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- Resolves local imports, re-exports, `require()`, and string-literal dynamic `import()`
|
|
20
20
|
- Honors the nearest `tsconfig.json` or `jsconfig.json`, including `baseUrl` and `paths`
|
|
21
21
|
- Prints a tree by default, or JSON with `--json`
|
|
22
|
+
- Colorizes ASCII output automatically when the terminal supports ANSI colors
|
|
22
23
|
|
|
23
24
|
## Usage
|
|
24
25
|
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as graphToSerializableReactTree, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-
|
|
2
|
+
import { a as graphToSerializableReactTree, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-BrguxPgp.mjs";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import process from "node:process";
|
|
5
5
|
//#region src/cli.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -27,14 +27,25 @@ interface PrintTreeOptions {
|
|
|
27
27
|
readonly cwd?: string;
|
|
28
28
|
readonly includeExternals?: boolean;
|
|
29
29
|
readonly omitUnused?: boolean;
|
|
30
|
+
readonly color?: ColorMode;
|
|
30
31
|
}
|
|
31
32
|
type ReactSymbolKind = 'component' | 'hook';
|
|
33
|
+
type ColorMode = boolean | 'auto';
|
|
32
34
|
type ReactUsageFilter = 'all' | ReactSymbolKind;
|
|
33
35
|
type ReactUsageEdgeKind = 'render' | 'hook-call';
|
|
36
|
+
interface ReactUsageLocation {
|
|
37
|
+
readonly filePath: string;
|
|
38
|
+
readonly line: number;
|
|
39
|
+
readonly column: number;
|
|
40
|
+
}
|
|
34
41
|
interface ReactUsageEdge {
|
|
35
42
|
readonly kind: ReactUsageEdgeKind;
|
|
36
43
|
readonly target: string;
|
|
37
44
|
}
|
|
45
|
+
interface ReactUsageEntry {
|
|
46
|
+
readonly target: string;
|
|
47
|
+
readonly location: ReactUsageLocation;
|
|
48
|
+
}
|
|
38
49
|
interface ReactUsageNode {
|
|
39
50
|
readonly id: string;
|
|
40
51
|
readonly name: string;
|
|
@@ -47,10 +58,12 @@ interface ReactUsageGraph {
|
|
|
47
58
|
readonly cwd: string;
|
|
48
59
|
readonly entryId: string;
|
|
49
60
|
readonly nodes: ReadonlyMap<string, ReactUsageNode>;
|
|
61
|
+
readonly entries: readonly ReactUsageEntry[];
|
|
50
62
|
}
|
|
51
63
|
interface PrintReactTreeOptions {
|
|
52
64
|
readonly cwd?: string;
|
|
53
65
|
readonly filter?: ReactUsageFilter;
|
|
66
|
+
readonly color?: ColorMode;
|
|
54
67
|
}
|
|
55
68
|
//#endregion
|
|
56
69
|
//#region src/analyzer.d.ts
|
|
@@ -72,5 +85,5 @@ declare function printReactUsageTree(graph: ReactUsageGraph, options?: PrintReac
|
|
|
72
85
|
//#region src/tree.d.ts
|
|
73
86
|
declare function printDependencyTree(graph: DependencyGraph, options?: PrintTreeOptions): string;
|
|
74
87
|
//#endregion
|
|
75
|
-
export { type AnalyzeOptions, type DependencyEdge, type DependencyGraph, type DependencyKind, type PrintReactTreeOptions, type PrintTreeOptions, type ReactSymbolKind, type ReactUsageEdge, type ReactUsageEdgeKind, type ReactUsageFilter, type ReactUsageGraph, type ReactUsageNode, type ReferenceKind, type SourceModuleNode, analyzeDependencies, analyzeReactUsage, getReactUsageRoots, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printReactUsageTree };
|
|
88
|
+
export { type AnalyzeOptions, type ColorMode, type DependencyEdge, type DependencyGraph, type DependencyKind, type PrintReactTreeOptions, type PrintTreeOptions, type ReactSymbolKind, type ReactUsageEdge, type ReactUsageEdgeKind, type ReactUsageEntry, type ReactUsageFilter, type ReactUsageGraph, type ReactUsageLocation, type ReactUsageNode, type ReferenceKind, type SourceModuleNode, analyzeDependencies, analyzeReactUsage, getReactUsageRoots, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printReactUsageTree };
|
|
76
89
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/react-tree.ts","../src/tree.ts"],"mappings":";KAAY,cAAA;AAAA,KAEA,aAAA;AAAA,UAOK,cAAA;EAAA,SACN,SAAA;EAAA,SACA,aAAA,EAAe,aAAA;EAAA,SACf,UAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA,EAAM,cAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,EAAA;EAAA,SACA,YAAA,WAAuB,cAAA;AAAA;AAAA,UAGjB,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,gBAAA;EAAA,SAC3B,UAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,GAAA;EAAA,SACA,UAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,GAAA;EAAA,SACA,gBAAA;EAAA,SACA,UAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/react-tree.ts","../src/tree.ts"],"mappings":";KAAY,cAAA;AAAA,KAEA,aAAA;AAAA,UAOK,cAAA;EAAA,SACN,SAAA;EAAA,SACA,aAAA,EAAe,aAAA;EAAA,SACf,UAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA,EAAM,cAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,EAAA;EAAA,SACA,YAAA,WAAuB,cAAA;AAAA;AAAA,UAGjB,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,gBAAA;EAAA,SAC3B,UAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,GAAA;EAAA,SACA,UAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,GAAA;EAAA,SACA,gBAAA;EAAA,SACA,UAAA;EAAA,SACA,KAAA,GAAQ,SAAA;AAAA;AAAA,KAGP,eAAA;AAAA,KAEA,SAAA;AAAA,KAEA,gBAAA,WAA2B,eAAA;AAAA,KAE3B,kBAAA;AAAA,UAEK,kBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,IAAA,EAAM,kBAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,eAAA;EAAA,SACN,MAAA;EAAA,SACA,QAAA,EAAU,kBAAA;AAAA;AAAA,UAGJ,cAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA,EAAM,eAAA;EAAA,SACN,QAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA,WAAiB,cAAA;AAAA;AAAA,UAGX,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,cAAA;EAAA,SAC3B,OAAA,WAAkB,eAAA;AAAA;AAAA,UAGZ,qBAAA;EAAA,SACN,GAAA;EAAA,SACA,MAAA,GAAS,gBAAA;EAAA,SACT,KAAA,GAAQ,SAAA;AAAA;;;iBCtDH,mBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBA8Ba,uBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,UAAA;AAAA;;;iBC8BG,iBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBAwJa,4BAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,MAAA,GAAS,gBAAA;AAAA;AAAA,iBAqCN,kBAAA,CACd,KAAA,EAAO,eAAA,EACP,MAAA,GAAQ,gBAAA;;;iBCvRM,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,qBAAA;;;iBCTK,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,gBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as graphToSerializableReactTree, i as getReactUsageRoots, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-
|
|
1
|
+
import { a as graphToSerializableReactTree, i as getReactUsageRoots, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-BrguxPgp.mjs";
|
|
2
2
|
export { analyzeDependencies, analyzeReactUsage, getReactUsageRoots, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printReactUsageTree };
|
|
@@ -3,6 +3,7 @@ import fs from "node:fs";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import ts from "typescript";
|
|
5
5
|
import { parseSync, visitorKeys } from "oxc-parser";
|
|
6
|
+
import process$1 from "node:process";
|
|
6
7
|
//#region src/config.ts
|
|
7
8
|
function loadCompilerOptions(searchFrom, explicitConfigPath) {
|
|
8
9
|
const configPath = explicitConfigPath === void 0 ? findNearestConfig(searchFrom) : path.resolve(searchFrom, explicitConfigPath);
|
|
@@ -324,7 +325,8 @@ function analyzeReactUsage(entryFile, options = {}) {
|
|
|
324
325
|
const fileAnalyses = /* @__PURE__ */ new Map();
|
|
325
326
|
for (const filePath of [...reachableFiles].sort()) {
|
|
326
327
|
if (!isSourceCodeFile(filePath) || filePath.endsWith(".d.ts")) continue;
|
|
327
|
-
const
|
|
328
|
+
const sourceText = fs.readFileSync(filePath, "utf8");
|
|
329
|
+
const parseResult = parseSync(filePath, sourceText, {
|
|
328
330
|
astType: "ts",
|
|
329
331
|
sourceType: "unambiguous"
|
|
330
332
|
});
|
|
@@ -333,7 +335,7 @@ function analyzeReactUsage(entryFile, options = {}) {
|
|
|
333
335
|
dependencyNode?.dependencies.forEach((dependency) => {
|
|
334
336
|
if (dependency.kind === "source") sourceDependencies.set(dependency.specifier, dependency.target);
|
|
335
337
|
});
|
|
336
|
-
fileAnalyses.set(filePath, analyzeReactFile(parseResult.program, filePath, sourceDependencies));
|
|
338
|
+
fileAnalyses.set(filePath, analyzeReactFile(parseResult.program, filePath, sourceText, sourceDependencies));
|
|
337
339
|
}
|
|
338
340
|
const nodes = /* @__PURE__ */ new Map();
|
|
339
341
|
for (const fileAnalysis of fileAnalyses.values()) for (const symbol of fileAnalysis.symbolsById.values()) nodes.set(symbol.id, {
|
|
@@ -374,19 +376,44 @@ function analyzeReactUsage(entryFile, options = {}) {
|
|
|
374
376
|
usages: sortedUsages
|
|
375
377
|
});
|
|
376
378
|
}
|
|
379
|
+
const entriesByKey = /* @__PURE__ */ new Map();
|
|
380
|
+
for (const fileAnalysis of fileAnalyses.values()) for (const entry of fileAnalysis.renderEntries) {
|
|
381
|
+
const targetId = resolveReactReference(fileAnalysis, fileAnalyses, entry.referenceName, "component");
|
|
382
|
+
if (targetId === void 0) continue;
|
|
383
|
+
const key = `${entry.location.filePath}:${entry.location.line}:${entry.location.column}:${targetId}`;
|
|
384
|
+
entriesByKey.set(key, {
|
|
385
|
+
target: targetId,
|
|
386
|
+
location: entry.location
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
const entries = [...entriesByKey.values()].sort((left, right) => compareReactUsageEntries(left, right, nodes));
|
|
377
390
|
return {
|
|
378
391
|
cwd: dependencyGraph.cwd,
|
|
379
392
|
entryId: dependencyGraph.entryId,
|
|
380
|
-
nodes
|
|
393
|
+
nodes,
|
|
394
|
+
entries
|
|
381
395
|
};
|
|
382
396
|
}
|
|
383
397
|
function graphToSerializableReactTree(graph, options = {}) {
|
|
398
|
+
const filter = options.filter ?? "all";
|
|
399
|
+
const entries = getReactUsageEntries(graph, filter);
|
|
400
|
+
const roots = entries.length > 0 ? entries.map((entry) => serializeReactUsageNode(entry.target, graph, filter, /* @__PURE__ */ new Set())) : getReactUsageRoots(graph, filter).map((rootId) => serializeReactUsageNode(rootId, graph, filter, /* @__PURE__ */ new Set()));
|
|
384
401
|
return {
|
|
385
402
|
kind: "react-usage",
|
|
386
|
-
|
|
403
|
+
entries: entries.map((entry) => serializeReactUsageEntry(entry, graph, filter)),
|
|
404
|
+
roots
|
|
387
405
|
};
|
|
388
406
|
}
|
|
407
|
+
function getReactUsageEntries(graph, filter = "all") {
|
|
408
|
+
if (filter === "hook") return [];
|
|
409
|
+
return graph.entries.filter((entry) => {
|
|
410
|
+
const targetNode = graph.nodes.get(entry.target);
|
|
411
|
+
return targetNode !== void 0 && matchesReactFilter(targetNode, filter);
|
|
412
|
+
});
|
|
413
|
+
}
|
|
389
414
|
function getReactUsageRoots(graph, filter = "all") {
|
|
415
|
+
const entries = getReactUsageEntries(graph, filter);
|
|
416
|
+
if (entries.length > 0) return [...new Set(entries.map((entry) => entry.target))];
|
|
390
417
|
const filteredNodes = getFilteredReactUsageNodes(graph, filter);
|
|
391
418
|
const inboundCounts = /* @__PURE__ */ new Map();
|
|
392
419
|
filteredNodes.forEach((node) => {
|
|
@@ -407,13 +434,14 @@ function getFilteredUsages(node, graph, filter = "all") {
|
|
|
407
434
|
return targetNode !== void 0 && matchesReactFilter(targetNode, filter);
|
|
408
435
|
});
|
|
409
436
|
}
|
|
410
|
-
function analyzeReactFile(program, filePath, sourceDependencies) {
|
|
437
|
+
function analyzeReactFile(program, filePath, sourceText, sourceDependencies) {
|
|
411
438
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
412
439
|
program.body.forEach((statement) => {
|
|
413
440
|
collectTopLevelReactSymbols(statement, filePath, symbolsByName);
|
|
414
441
|
});
|
|
415
442
|
const importsByLocalName = /* @__PURE__ */ new Map();
|
|
416
443
|
const exportsByName = /* @__PURE__ */ new Map();
|
|
444
|
+
const renderEntries = collectRenderEntries(program, filePath, sourceText);
|
|
417
445
|
program.body.forEach((statement) => {
|
|
418
446
|
collectImportsAndExports(statement, sourceDependencies, symbolsByName, importsByLocalName, exportsByName);
|
|
419
447
|
});
|
|
@@ -424,10 +452,83 @@ function analyzeReactFile(program, filePath, sourceDependencies) {
|
|
|
424
452
|
filePath,
|
|
425
453
|
importsByLocalName,
|
|
426
454
|
exportsByName,
|
|
455
|
+
renderEntries,
|
|
427
456
|
symbolsById: new Map([...symbolsByName.values()].map((symbol) => [symbol.id, symbol])),
|
|
428
457
|
symbolsByName
|
|
429
458
|
};
|
|
430
459
|
}
|
|
460
|
+
function collectRenderEntries(program, filePath, sourceText) {
|
|
461
|
+
const entries = /* @__PURE__ */ new Map();
|
|
462
|
+
program.body.forEach((statement) => {
|
|
463
|
+
collectStatementRenderEntries(statement, filePath, sourceText, entries);
|
|
464
|
+
});
|
|
465
|
+
return [...entries.values()].sort(comparePendingReactUsageEntries);
|
|
466
|
+
}
|
|
467
|
+
function collectStatementRenderEntries(statement, filePath, sourceText, entries) {
|
|
468
|
+
collectNodeRenderEntries(statement, filePath, sourceText, entries, false);
|
|
469
|
+
}
|
|
470
|
+
function collectNodeRenderEntries(node, filePath, sourceText, entries, hasComponentAncestor) {
|
|
471
|
+
if (FUNCTION_NODE_TYPES.has(node.type)) return;
|
|
472
|
+
let nextHasComponentAncestor = hasComponentAncestor;
|
|
473
|
+
if (node.type === "JSXElement") {
|
|
474
|
+
const referenceName = getComponentReferenceName(node);
|
|
475
|
+
if (referenceName !== void 0) {
|
|
476
|
+
if (!hasComponentAncestor) addPendingRenderEntry(entries, referenceName, createReactUsageLocation(filePath, sourceText, node.start));
|
|
477
|
+
nextHasComponentAncestor = true;
|
|
478
|
+
}
|
|
479
|
+
} else if (node.type === "CallExpression") {
|
|
480
|
+
const referenceName = getCreateElementComponentReferenceName(node);
|
|
481
|
+
if (referenceName !== void 0) {
|
|
482
|
+
if (!hasComponentAncestor) addPendingRenderEntry(entries, referenceName, createReactUsageLocation(filePath, sourceText, node.start));
|
|
483
|
+
nextHasComponentAncestor = true;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const keys = visitorKeys[node.type];
|
|
487
|
+
if (keys === void 0) return;
|
|
488
|
+
keys.forEach((key) => {
|
|
489
|
+
const value = node[key];
|
|
490
|
+
collectRenderEntryChild(value, filePath, sourceText, entries, nextHasComponentAncestor);
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
function collectRenderEntryChild(value, filePath, sourceText, entries, hasComponentAncestor) {
|
|
494
|
+
if (Array.isArray(value)) {
|
|
495
|
+
value.forEach((entry) => {
|
|
496
|
+
collectRenderEntryChild(entry, filePath, sourceText, entries, hasComponentAncestor);
|
|
497
|
+
});
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
if (!isNode(value)) return;
|
|
501
|
+
collectNodeRenderEntries(value, filePath, sourceText, entries, hasComponentAncestor);
|
|
502
|
+
}
|
|
503
|
+
function addPendingRenderEntry(entries, referenceName, location) {
|
|
504
|
+
const key = `${location.filePath}:${location.line}:${location.column}:${referenceName}`;
|
|
505
|
+
entries.set(key, {
|
|
506
|
+
referenceName,
|
|
507
|
+
location
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
function createReactUsageLocation(filePath, sourceText, offset) {
|
|
511
|
+
return {
|
|
512
|
+
filePath,
|
|
513
|
+
...offsetToLineAndColumn(sourceText, offset)
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
function offsetToLineAndColumn(sourceText, offset) {
|
|
517
|
+
let line = 1;
|
|
518
|
+
let column = 1;
|
|
519
|
+
for (let index = 0; index < offset && index < sourceText.length; index += 1) {
|
|
520
|
+
if (sourceText[index] === "\n") {
|
|
521
|
+
line += 1;
|
|
522
|
+
column = 1;
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
column += 1;
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
line,
|
|
529
|
+
column
|
|
530
|
+
};
|
|
531
|
+
}
|
|
431
532
|
function collectTopLevelReactSymbols(statement, filePath, symbolsByName) {
|
|
432
533
|
switch (statement.type) {
|
|
433
534
|
case "FunctionDeclaration":
|
|
@@ -731,12 +832,27 @@ function serializeReactUsageNode(nodeId, graph, filter, visited) {
|
|
|
731
832
|
}))
|
|
732
833
|
};
|
|
733
834
|
}
|
|
835
|
+
function serializeReactUsageEntry(entry, graph, filter) {
|
|
836
|
+
return {
|
|
837
|
+
targetId: entry.target,
|
|
838
|
+
filePath: toDisplayPath(entry.location.filePath, graph.cwd),
|
|
839
|
+
line: entry.location.line,
|
|
840
|
+
column: entry.location.column,
|
|
841
|
+
node: serializeReactUsageNode(entry.target, graph, filter, /* @__PURE__ */ new Set())
|
|
842
|
+
};
|
|
843
|
+
}
|
|
734
844
|
function compareReactNodeIds(leftId, rightId, nodes) {
|
|
735
845
|
const left = nodes.get(leftId);
|
|
736
846
|
const right = nodes.get(rightId);
|
|
737
847
|
if (left === void 0 || right === void 0) return leftId.localeCompare(rightId);
|
|
738
848
|
return compareReactNodes(left, right);
|
|
739
849
|
}
|
|
850
|
+
function compareReactUsageEntries(left, right, nodes) {
|
|
851
|
+
return left.location.filePath.localeCompare(right.location.filePath) || left.location.line - right.location.line || left.location.column - right.location.column || compareReactNodeIds(left.target, right.target, nodes);
|
|
852
|
+
}
|
|
853
|
+
function comparePendingReactUsageEntries(left, right) {
|
|
854
|
+
return left.location.filePath.localeCompare(right.location.filePath) || left.location.line - right.location.line || left.location.column - right.location.column || left.referenceName.localeCompare(right.referenceName);
|
|
855
|
+
}
|
|
740
856
|
function compareReactNodes(left, right) {
|
|
741
857
|
return left.filePath.localeCompare(right.filePath) || left.name.localeCompare(right.name) || left.kind.localeCompare(right.kind);
|
|
742
858
|
}
|
|
@@ -750,47 +866,92 @@ function isComponentName(name) {
|
|
|
750
866
|
return /^[A-Z]/.test(name);
|
|
751
867
|
}
|
|
752
868
|
//#endregion
|
|
869
|
+
//#region src/color.ts
|
|
870
|
+
const ANSI_RESET = "\x1B[0m";
|
|
871
|
+
const ANSI_COMPONENT = "\x1B[36m";
|
|
872
|
+
const ANSI_HOOK = "\x1B[35m";
|
|
873
|
+
const ANSI_UNUSED = "\x1B[38;5;214m";
|
|
874
|
+
function resolveColorSupport(mode = "auto", options = {}) {
|
|
875
|
+
if (mode === true) return true;
|
|
876
|
+
if (mode === false) return false;
|
|
877
|
+
const forceColor = "forceColor" in options ? options.forceColor : process$1.env.FORCE_COLOR;
|
|
878
|
+
if (forceColor !== void 0) return forceColor !== "0";
|
|
879
|
+
if (("noColor" in options ? options.noColor : process$1.env.NO_COLOR) !== void 0) return false;
|
|
880
|
+
return ("isTTY" in options ? options.isTTY : process$1.stdout.isTTY) === true;
|
|
881
|
+
}
|
|
882
|
+
function colorizeUnusedMarker(text, enabled) {
|
|
883
|
+
if (!enabled) return text;
|
|
884
|
+
return text.replaceAll("(unused)", `${ANSI_UNUSED}(unused)${ANSI_RESET}`);
|
|
885
|
+
}
|
|
886
|
+
function formatReactSymbolLabel(name, kind, enabled) {
|
|
887
|
+
const label = `${name} [${kind}]`;
|
|
888
|
+
if (!enabled) return label;
|
|
889
|
+
return `${kind === "component" ? ANSI_COMPONENT : ANSI_HOOK}${label}${ANSI_RESET}`;
|
|
890
|
+
}
|
|
891
|
+
//#endregion
|
|
753
892
|
//#region src/react-tree.ts
|
|
754
893
|
function printReactUsageTree(graph, options = {}) {
|
|
755
894
|
const cwd = options.cwd ?? graph.cwd;
|
|
895
|
+
const color = resolveColorSupport(options.color);
|
|
756
896
|
const filter = options.filter ?? "all";
|
|
897
|
+
const entries = getReactUsageEntries(graph, filter);
|
|
898
|
+
if (entries.length > 0) return renderReactUsageEntries(graph, entries, cwd, filter, color);
|
|
757
899
|
const roots = getReactUsageRoots(graph, filter);
|
|
758
900
|
if (roots.length === 0) return "No React symbols found.";
|
|
759
901
|
const lines = [];
|
|
760
902
|
roots.forEach((rootId, index) => {
|
|
761
903
|
const root = graph.nodes.get(rootId);
|
|
762
904
|
if (root === void 0) return;
|
|
763
|
-
lines.push(formatReactNodeLabel(root, cwd));
|
|
905
|
+
lines.push(formatReactNodeLabel(root, cwd, color));
|
|
764
906
|
const usages = getFilteredUsages(root, graph, filter);
|
|
765
907
|
usages.forEach((usage, usageIndex) => {
|
|
766
|
-
lines.push(...renderUsage(usage, graph, cwd, filter, new Set([root.id]), "", usageIndex === usages.length - 1));
|
|
908
|
+
lines.push(...renderUsage(usage, graph, cwd, filter, color, new Set([root.id]), "", usageIndex === usages.length - 1));
|
|
767
909
|
});
|
|
768
910
|
if (index < roots.length - 1) lines.push("");
|
|
769
911
|
});
|
|
770
912
|
return lines.join("\n");
|
|
771
913
|
}
|
|
772
|
-
function
|
|
914
|
+
function renderReactUsageEntries(graph, entries, cwd, filter, color) {
|
|
915
|
+
const lines = [];
|
|
916
|
+
entries.forEach((entry, index) => {
|
|
917
|
+
const root = graph.nodes.get(entry.target);
|
|
918
|
+
if (root === void 0) return;
|
|
919
|
+
lines.push(formatReactEntryLabel(entry, cwd));
|
|
920
|
+
lines.push(formatReactNodeLabel(root, cwd, color));
|
|
921
|
+
const usages = getFilteredUsages(root, graph, filter);
|
|
922
|
+
usages.forEach((usage, usageIndex) => {
|
|
923
|
+
lines.push(...renderUsage(usage, graph, cwd, filter, color, new Set([root.id]), "", usageIndex === usages.length - 1));
|
|
924
|
+
});
|
|
925
|
+
if (index < entries.length - 1) lines.push("");
|
|
926
|
+
});
|
|
927
|
+
return lines.join("\n");
|
|
928
|
+
}
|
|
929
|
+
function renderUsage(usage, graph, cwd, filter, color, visited, prefix, isLast) {
|
|
773
930
|
const branch = `${prefix}${isLast ? "└─ " : "├─ "}`;
|
|
774
931
|
const target = graph.nodes.get(usage.target);
|
|
775
932
|
if (target === void 0) return [`${branch}${usage.target}`];
|
|
776
|
-
if (visited.has(target.id)) return [`${branch}${formatReactNodeLabel(target, cwd)} (circular)`];
|
|
777
|
-
const childLines = [`${branch}${formatReactNodeLabel(target, cwd)}`];
|
|
933
|
+
if (visited.has(target.id)) return [`${branch}${formatReactNodeLabel(target, cwd, color)} (circular)`];
|
|
934
|
+
const childLines = [`${branch}${formatReactNodeLabel(target, cwd, color)}`];
|
|
778
935
|
const nextVisited = new Set(visited);
|
|
779
936
|
nextVisited.add(target.id);
|
|
780
937
|
const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
|
|
781
938
|
const childUsages = getFilteredUsages(target, graph, filter);
|
|
782
939
|
childUsages.forEach((childUsage, index) => {
|
|
783
|
-
childLines.push(...renderUsage(childUsage, graph, cwd, filter, nextVisited, nextPrefix, index === childUsages.length - 1));
|
|
940
|
+
childLines.push(...renderUsage(childUsage, graph, cwd, filter, color, nextVisited, nextPrefix, index === childUsages.length - 1));
|
|
784
941
|
});
|
|
785
942
|
return childLines;
|
|
786
943
|
}
|
|
787
|
-
function formatReactNodeLabel(node, cwd) {
|
|
788
|
-
return `${node.name
|
|
944
|
+
function formatReactNodeLabel(node, cwd, color) {
|
|
945
|
+
return `${formatReactSymbolLabel(node.name, node.kind, color)} (${toDisplayPath(node.filePath, cwd)})`;
|
|
946
|
+
}
|
|
947
|
+
function formatReactEntryLabel(entry, cwd) {
|
|
948
|
+
return `${toDisplayPath(entry.location.filePath, cwd)}:${entry.location.line}:${entry.location.column}`;
|
|
789
949
|
}
|
|
790
950
|
//#endregion
|
|
791
951
|
//#region src/tree.ts
|
|
792
952
|
function printDependencyTree(graph, options = {}) {
|
|
793
953
|
const cwd = options.cwd ?? graph.cwd;
|
|
954
|
+
const color = resolveColorSupport(options.color);
|
|
794
955
|
const includeExternals = options.includeExternals ?? false;
|
|
795
956
|
const omitUnused = options.omitUnused ?? false;
|
|
796
957
|
const rootLines = [toDisplayPath(graph.entryId, cwd)];
|
|
@@ -799,14 +960,14 @@ function printDependencyTree(graph, options = {}) {
|
|
|
799
960
|
if (entryNode === void 0) return rootLines.join("\n");
|
|
800
961
|
const rootDependencies = filterDependencies(entryNode.dependencies, includeExternals, omitUnused);
|
|
801
962
|
rootDependencies.forEach((dependency, index) => {
|
|
802
|
-
const lines = renderDependency(dependency, graph, visited, "", index === rootDependencies.length - 1, includeExternals, omitUnused, cwd);
|
|
963
|
+
const lines = renderDependency(dependency, graph, visited, "", index === rootDependencies.length - 1, includeExternals, omitUnused, color, cwd);
|
|
803
964
|
rootLines.push(...lines);
|
|
804
965
|
});
|
|
805
966
|
return rootLines.join("\n");
|
|
806
967
|
}
|
|
807
|
-
function renderDependency(dependency, graph, visited, prefix, isLast, includeExternals, omitUnused, cwd) {
|
|
968
|
+
function renderDependency(dependency, graph, visited, prefix, isLast, includeExternals, omitUnused, color, cwd) {
|
|
808
969
|
const branch = `${prefix}${isLast ? "└─ " : "├─ "}`;
|
|
809
|
-
const label = formatDependencyLabel(dependency,
|
|
970
|
+
const label = formatDependencyLabel(dependency, cwd, color);
|
|
810
971
|
if (dependency.kind !== "source") return [`${branch}${label}`];
|
|
811
972
|
if (visited.has(dependency.target)) return [`${branch}${label} (circular)`];
|
|
812
973
|
const childNode = graph.nodes.get(dependency.target);
|
|
@@ -818,7 +979,7 @@ function renderDependency(dependency, graph, visited, prefix, isLast, includeExt
|
|
|
818
979
|
const childDependencies = filterDependencies(childNode.dependencies, includeExternals, omitUnused);
|
|
819
980
|
childDependencies.forEach((childDependency, index) => {
|
|
820
981
|
const isChildLast = index === childDependencies.length - 1;
|
|
821
|
-
childLines.push(...renderDependency(childDependency, graph, nextVisited, nextPrefix, isChildLast, includeExternals, omitUnused, cwd));
|
|
982
|
+
childLines.push(...renderDependency(childDependency, graph, nextVisited, nextPrefix, isChildLast, includeExternals, omitUnused, color, cwd));
|
|
822
983
|
});
|
|
823
984
|
return childLines;
|
|
824
985
|
}
|
|
@@ -829,7 +990,7 @@ function filterDependencies(dependencies, includeExternals, omitUnused) {
|
|
|
829
990
|
return includeExternals;
|
|
830
991
|
});
|
|
831
992
|
}
|
|
832
|
-
function formatDependencyLabel(dependency,
|
|
993
|
+
function formatDependencyLabel(dependency, cwd, color) {
|
|
833
994
|
const prefixes = [];
|
|
834
995
|
if (dependency.isTypeOnly) prefixes.push("type");
|
|
835
996
|
if (dependency.referenceKind === "require") prefixes.push("require");
|
|
@@ -837,10 +998,10 @@ function formatDependencyLabel(dependency, _graph, cwd) {
|
|
|
837
998
|
else if (dependency.referenceKind === "export") prefixes.push("re-export");
|
|
838
999
|
else if (dependency.referenceKind === "import-equals") prefixes.push("import=");
|
|
839
1000
|
const annotation = prefixes.length > 0 ? `[${prefixes.join(", ")}] ` : "";
|
|
840
|
-
if (dependency.kind === "source") return withUnusedSuffix(`${annotation}${toDisplayPath(dependency.target, cwd)}`, dependency.unused);
|
|
841
|
-
if (dependency.kind === "missing") return withUnusedSuffix(`${annotation}${dependency.specifier} [missing]`, dependency.unused);
|
|
842
|
-
if (dependency.kind === "builtin") return withUnusedSuffix(`${annotation}${dependency.target} [builtin]`, dependency.unused);
|
|
843
|
-
return withUnusedSuffix(`${annotation}${dependency.target} [external]`, dependency.unused);
|
|
1001
|
+
if (dependency.kind === "source") return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${toDisplayPath(dependency.target, cwd)}`, dependency.unused), color);
|
|
1002
|
+
if (dependency.kind === "missing") return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${dependency.specifier} [missing]`, dependency.unused), color);
|
|
1003
|
+
if (dependency.kind === "builtin") return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${dependency.target} [builtin]`, dependency.unused), color);
|
|
1004
|
+
return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${dependency.target} [external]`, dependency.unused), color);
|
|
844
1005
|
}
|
|
845
1006
|
function withUnusedSuffix(label, unused) {
|
|
846
1007
|
return unused ? `${label} (unused)` : label;
|
|
@@ -848,4 +1009,4 @@ function withUnusedSuffix(label, unused) {
|
|
|
848
1009
|
//#endregion
|
|
849
1010
|
export { graphToSerializableReactTree as a, getReactUsageRoots as i, printReactUsageTree as n, analyzeDependencies as o, analyzeReactUsage as r, graphToSerializableTree as s, printDependencyTree as t };
|
|
850
1011
|
|
|
851
|
-
//# sourceMappingURL=tree-
|
|
1012
|
+
//# sourceMappingURL=tree-BrguxPgp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-BrguxPgp.mjs","names":["process"],"sources":["../src/config.ts","../src/path-utils.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/color.ts","../src/react-tree.ts","../src/tree.ts"],"sourcesContent":["import path from 'node:path'\nimport ts from 'typescript'\n\nexport interface LoadedConfig {\n readonly path?: string\n readonly compilerOptions: ts.CompilerOptions\n}\n\nexport function loadCompilerOptions(\n searchFrom: string,\n explicitConfigPath?: string,\n): LoadedConfig {\n const configPath =\n explicitConfigPath === undefined\n ? findNearestConfig(searchFrom)\n : path.resolve(searchFrom, explicitConfigPath)\n\n if (configPath === undefined) {\n return {\n compilerOptions: defaultCompilerOptions(),\n }\n }\n\n const readResult = ts.readConfigFile(configPath, ts.sys.readFile)\n if (readResult.error !== undefined) {\n throw new Error(\n `Failed to read TypeScript config at ${configPath}: ${formatDiagnostic(\n readResult.error,\n )}`,\n )\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n readResult.config,\n ts.sys,\n path.dirname(configPath),\n defaultCompilerOptions(),\n configPath,\n )\n\n if (parsed.errors.length > 0) {\n const [firstError] = parsed.errors\n if (firstError === undefined) {\n throw new Error(`Failed to parse TypeScript config at ${configPath}.`)\n }\n\n throw new Error(\n `Failed to parse TypeScript config at ${configPath}: ${formatDiagnostic(\n firstError,\n )}`,\n )\n }\n\n return {\n path: configPath,\n compilerOptions: parsed.options,\n }\n}\n\nfunction findNearestConfig(searchFrom: string): string | undefined {\n let currentDirectory = path.resolve(searchFrom)\n\n while (true) {\n const tsconfigPath = path.join(currentDirectory, 'tsconfig.json')\n if (ts.sys.fileExists(tsconfigPath)) {\n return tsconfigPath\n }\n\n const jsconfigPath = path.join(currentDirectory, 'jsconfig.json')\n if (ts.sys.fileExists(jsconfigPath)) {\n return jsconfigPath\n }\n\n const parentDirectory = path.dirname(currentDirectory)\n if (parentDirectory === currentDirectory) {\n return undefined\n }\n\n currentDirectory = parentDirectory\n }\n}\n\nfunction defaultCompilerOptions(): ts.CompilerOptions {\n return {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n target: ts.ScriptTarget.ESNext,\n resolveJsonModule: true,\n esModuleInterop: true,\n }\n}\n\nfunction formatDiagnostic(diagnostic: ts.Diagnostic): string {\n return ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')\n}\n","import path from 'node:path'\n\nexport const SOURCE_EXTENSIONS = new Set([\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n])\n\nexport function normalizeFilePath(filePath: string): string {\n return path.normalize(filePath)\n}\n\nexport function toDisplayPath(filePath: string, cwd: string): string {\n const relativePath = path.relative(cwd, filePath)\n if (relativePath === '') {\n return '.'\n }\n\n const normalizedPath = relativePath.split(path.sep).join('/')\n return normalizedPath.startsWith('..') ? filePath : normalizedPath\n}\n\nexport function isSourceCodeFile(filePath: string): boolean {\n return SOURCE_EXTENSIONS.has(path.extname(filePath).toLowerCase())\n}\n","import fs from 'node:fs'\nimport { builtinModules } from 'node:module'\nimport path from 'node:path'\nimport ts from 'typescript'\n\nimport { loadCompilerOptions } from './config.js'\nimport {\n isSourceCodeFile,\n normalizeFilePath,\n toDisplayPath,\n} from './path-utils.js'\nimport type {\n AnalyzeOptions,\n DependencyEdge,\n DependencyGraph,\n DependencyKind,\n ReferenceKind,\n SourceModuleNode,\n} from './types.js'\n\ninterface ModuleReference {\n readonly specifier: string\n readonly referenceKind: ReferenceKind\n readonly isTypeOnly: boolean\n readonly unused: boolean\n}\n\nconst BUILTIN_MODULES = new Set(\n builtinModules.flatMap((name) => [name, `node:${name}`]),\n)\n\nexport function analyzeDependencies(\n entryFile: string,\n options: AnalyzeOptions = {},\n): DependencyGraph {\n const cwd = path.resolve(options.cwd ?? process.cwd())\n const resolvedEntryPath = resolveExistingPath(cwd, entryFile)\n const { compilerOptions, path: configPath } = loadCompilerOptions(\n path.dirname(resolvedEntryPath),\n options.configPath,\n )\n\n const host: ts.ModuleResolutionHost = {\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n directoryExists: ts.sys.directoryExists,\n getCurrentDirectory: () => cwd,\n getDirectories: ts.sys.getDirectories,\n ...(ts.sys.realpath === undefined ? {} : { realpath: ts.sys.realpath }),\n }\n\n const nodes = new Map<string, SourceModuleNode>()\n const program = createProgram(resolvedEntryPath, compilerOptions, cwd)\n const checker = program.getTypeChecker()\n visitFile(resolvedEntryPath, compilerOptions, host, checker, program, nodes)\n\n return {\n cwd,\n entryId: resolvedEntryPath,\n nodes,\n ...(configPath === undefined ? {} : { configPath }),\n }\n}\n\nexport function graphToSerializableTree(\n graph: DependencyGraph,\n options: {\n readonly omitUnused?: boolean\n } = {},\n): object {\n const visited = new Set<string>()\n return serializeNode(\n graph.entryId,\n graph,\n visited,\n options.omitUnused ?? false,\n )\n}\n\nfunction serializeNode(\n filePath: string,\n graph: DependencyGraph,\n visited: Set<string>,\n omitUnused: boolean,\n): object {\n const node = graph.nodes.get(filePath)\n const displayPath = toDisplayPath(filePath, graph.cwd)\n\n if (node === undefined) {\n return {\n path: displayPath,\n kind: 'missing',\n dependencies: [],\n }\n }\n\n if (visited.has(filePath)) {\n return {\n path: displayPath,\n kind: 'circular',\n dependencies: [],\n }\n }\n\n visited.add(filePath)\n\n const dependencies = node.dependencies\n .filter((dependency) => !omitUnused || !dependency.unused)\n .map((dependency) => {\n if (dependency.kind !== 'source') {\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target:\n dependency.kind === 'missing'\n ? dependency.target\n : toDisplayPath(dependency.target, graph.cwd),\n }\n }\n\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target: toDisplayPath(dependency.target, graph.cwd),\n node: serializeNode(\n dependency.target,\n graph,\n new Set(visited),\n omitUnused,\n ),\n }\n })\n\n return {\n path: displayPath,\n kind: filePath === graph.entryId ? 'entry' : 'source',\n dependencies,\n }\n}\n\nfunction visitFile(\n filePath: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n checker: ts.TypeChecker,\n program: ts.Program,\n nodes: Map<string, SourceModuleNode>,\n): void {\n const normalizedPath = normalizeFilePath(filePath)\n if (nodes.has(normalizedPath)) {\n return\n }\n\n const sourceFile =\n program.getSourceFile(normalizedPath) ?? createSourceFile(normalizedPath)\n\n const references = collectModuleReferences(sourceFile, checker)\n const dependencies = references.map((reference) =>\n resolveDependency(reference, normalizedPath, compilerOptions, host),\n )\n\n nodes.set(normalizedPath, {\n id: normalizedPath,\n dependencies,\n })\n\n for (const dependency of dependencies) {\n if (dependency.kind === 'source') {\n visitFile(\n dependency.target,\n compilerOptions,\n host,\n checker,\n program,\n nodes,\n )\n }\n }\n}\n\nfunction collectModuleReferences(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ModuleReference[] {\n const references = new Map<string, ModuleReference>()\n const unusedImports = collectUnusedImports(sourceFile, checker)\n\n function addReference(\n specifier: string,\n referenceKind: ReferenceKind,\n isTypeOnly: boolean,\n unused: boolean,\n ): void {\n const key = `${referenceKind}:${isTypeOnly ? 'type' : 'value'}:${specifier}`\n const existing = references.get(key)\n if (existing !== undefined) {\n if (existing.unused && !unused) {\n references.set(key, {\n ...existing,\n unused: false,\n })\n }\n return\n }\n\n references.set(key, {\n specifier,\n referenceKind,\n isTypeOnly,\n unused,\n })\n }\n\n function visit(node: ts.Node): void {\n if (\n ts.isImportDeclaration(node) &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'import',\n node.importClause?.isTypeOnly ?? false,\n unusedImports.get(node) ?? false,\n )\n } else if (\n ts.isExportDeclaration(node) &&\n node.moduleSpecifier !== undefined &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'export',\n node.isTypeOnly ?? false,\n false,\n )\n } else if (ts.isImportEqualsDeclaration(node)) {\n const moduleReference = node.moduleReference\n if (\n ts.isExternalModuleReference(moduleReference) &&\n moduleReference.expression !== undefined &&\n ts.isStringLiteralLike(moduleReference.expression)\n ) {\n addReference(\n moduleReference.expression.text,\n 'import-equals',\n false,\n false,\n )\n }\n } else if (ts.isCallExpression(node)) {\n if (\n node.expression.kind === ts.SyntaxKind.ImportKeyword &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'dynamic-import', false, false)\n }\n }\n\n if (\n ts.isIdentifier(node.expression) &&\n node.expression.text === 'require' &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'require', false, false)\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n return [...references.values()]\n}\n\nfunction resolveDependency(\n reference: ModuleReference,\n containingFile: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n): DependencyEdge {\n const specifier = reference.specifier\n if (BUILTIN_MODULES.has(specifier)) {\n return createEdge(reference, 'builtin', specifier)\n }\n\n const resolution = ts.resolveModuleName(\n specifier,\n containingFile,\n compilerOptions,\n host,\n ).resolvedModule\n\n if (resolution !== undefined) {\n const resolvedPath = normalizeFilePath(resolution.resolvedFileName)\n if (\n resolution.isExternalLibraryImport ||\n resolvedPath.includes(`${path.sep}node_modules${path.sep}`)\n ) {\n return createEdge(reference, 'external', specifier)\n }\n\n if (isSourceCodeFile(resolvedPath) && !resolvedPath.endsWith('.d.ts')) {\n return createEdge(reference, 'source', resolvedPath)\n }\n }\n\n if (!specifier.startsWith('.') && !path.isAbsolute(specifier)) {\n return createEdge(reference, 'external', specifier)\n }\n\n return createEdge(reference, 'missing', specifier)\n}\n\nfunction createEdge(\n reference: ModuleReference,\n kind: DependencyKind,\n target: string,\n): DependencyEdge {\n return {\n specifier: reference.specifier,\n referenceKind: reference.referenceKind,\n isTypeOnly: reference.isTypeOnly,\n unused: reference.unused,\n kind,\n target,\n }\n}\n\nfunction createProgram(\n entryFile: string,\n compilerOptions: ts.CompilerOptions,\n cwd: string,\n): ts.Program {\n const host = ts.createCompilerHost(compilerOptions, true)\n host.getCurrentDirectory = () => cwd\n\n if (ts.sys.realpath !== undefined) {\n host.realpath = ts.sys.realpath\n }\n\n return ts.createProgram({\n rootNames: [entryFile],\n options: compilerOptions,\n host,\n })\n}\n\nfunction createSourceFile(filePath: string): ts.SourceFile {\n const sourceText = fs.readFileSync(filePath, 'utf8')\n return ts.createSourceFile(\n filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n getScriptKind(filePath),\n )\n}\n\nfunction collectUnusedImports(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ReadonlyMap<ts.ImportDeclaration, boolean> {\n const importUsage = new Map<\n ts.ImportDeclaration,\n {\n canTrack: boolean\n used: boolean\n }\n >()\n const symbolToImportDeclaration = new Map<ts.Symbol, ts.ImportDeclaration>()\n const importedLocalNames = new Set<string>()\n\n sourceFile.statements.forEach((statement) => {\n if (\n !ts.isImportDeclaration(statement) ||\n statement.importClause === undefined\n ) {\n return\n }\n\n const identifiers = getImportBindingIdentifiers(statement.importClause)\n if (identifiers.length === 0) {\n return\n }\n\n importUsage.set(statement, {\n canTrack: false,\n used: false,\n })\n\n identifiers.forEach((identifier) => {\n importedLocalNames.add(identifier.text)\n\n const symbol = tryGetSymbolAtLocation(checker, identifier)\n if (symbol === undefined) {\n return\n }\n\n symbolToImportDeclaration.set(symbol, statement)\n const state = importUsage.get(statement)\n if (state !== undefined) {\n state.canTrack = true\n }\n })\n })\n\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node)) {\n return\n }\n\n if (\n ts.isIdentifier(node) &&\n importedLocalNames.has(node.text) &&\n isReferenceIdentifier(node)\n ) {\n const symbol = tryGetSymbolAtLocation(checker, node)\n const declaration =\n symbol === undefined ? undefined : symbolToImportDeclaration.get(symbol)\n if (declaration !== undefined) {\n const state = importUsage.get(declaration)\n if (state !== undefined) {\n state.used = true\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n\n return new Map(\n [...importUsage.entries()].map(([declaration, state]) => [\n declaration,\n state.canTrack && !state.used,\n ]),\n )\n}\n\nfunction getImportBindingIdentifiers(\n importClause: ts.ImportClause,\n): ts.Identifier[] {\n const identifiers: ts.Identifier[] = []\n\n if (importClause.name !== undefined) {\n identifiers.push(importClause.name)\n }\n\n const namedBindings = importClause.namedBindings\n if (namedBindings === undefined) {\n return identifiers\n }\n\n if (ts.isNamespaceImport(namedBindings)) {\n identifiers.push(namedBindings.name)\n return identifiers\n }\n\n namedBindings.elements.forEach((element) => {\n identifiers.push(element.name)\n })\n\n return identifiers\n}\n\nfunction isReferenceIdentifier(node: ts.Identifier): boolean {\n const parent = node.parent\n\n if (ts.isPropertyAccessExpression(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isQualifiedName(parent) && parent.right === node) {\n return false\n }\n\n if (ts.isPropertyAssignment(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isBindingElement(parent) && parent.propertyName === node) {\n return false\n }\n\n if (ts.isJsxAttribute(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isExportSpecifier(parent)) {\n return parent.propertyName === node || parent.propertyName === undefined\n }\n\n return true\n}\n\nfunction tryGetSymbolAtLocation(\n checker: ts.TypeChecker,\n node: ts.Node,\n): ts.Symbol | undefined {\n try {\n return checker.getSymbolAtLocation(node)\n } catch {\n return undefined\n }\n}\n\nfunction getScriptKind(filePath: string): ts.ScriptKind {\n switch (path.extname(filePath).toLowerCase()) {\n case '.js':\n case '.mjs':\n case '.cjs':\n return ts.ScriptKind.JS\n case '.jsx':\n return ts.ScriptKind.JSX\n case '.tsx':\n return ts.ScriptKind.TSX\n case '.json':\n return ts.ScriptKind.JSON\n default:\n return ts.ScriptKind.TS\n }\n}\n\nfunction resolveExistingPath(cwd: string, entryFile: string): string {\n const absolutePath = path.resolve(cwd, entryFile)\n const normalizedPath = normalizeFilePath(absolutePath)\n\n if (!fs.existsSync(normalizedPath)) {\n throw new Error(`Entry file not found: ${entryFile}`)\n }\n\n if (!isSourceCodeFile(normalizedPath)) {\n throw new Error(`Entry file must be a JS/TS source file: ${entryFile}`)\n }\n\n return normalizedPath\n}\n","import fs from 'node:fs'\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ExportDefaultDeclaration,\n ExportNamedDeclaration,\n Expression,\n FunctionBody,\n ImportDeclaration,\n ImportDeclarationSpecifier,\n JSXElement,\n JSXElementName,\n JSXFragment,\n ModuleExportName,\n Node,\n Function as OxcFunction,\n Program,\n Statement,\n VariableDeclarator,\n} from 'oxc-parser'\nimport { parseSync, visitorKeys } from 'oxc-parser'\n\nimport { analyzeDependencies } from './analyzer.js'\nimport { isSourceCodeFile, toDisplayPath } from './path-utils.js'\nimport type {\n AnalyzeOptions,\n ReactSymbolKind,\n ReactUsageEdge,\n ReactUsageEntry,\n ReactUsageFilter,\n ReactUsageGraph,\n ReactUsageLocation,\n ReactUsageNode,\n} from './types.js'\n\ninterface PendingReactUsageNode {\n readonly id: string\n readonly name: string\n readonly kind: ReactSymbolKind\n readonly filePath: string\n readonly declaration: OxcFunction | ArrowFunctionExpression\n readonly exportNames: Set<string>\n readonly componentReferences: Set<string>\n readonly hookReferences: Set<string>\n}\n\ninterface PendingReactUsageEntry {\n readonly referenceName: string\n readonly location: ReactUsageLocation\n}\n\ninterface ImportBinding {\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n}\n\ninterface FileAnalysis {\n readonly filePath: string\n readonly importsByLocalName: Map<string, ImportBinding>\n readonly exportsByName: Map<string, string>\n readonly renderEntries: readonly PendingReactUsageEntry[]\n readonly symbolsById: Map<string, PendingReactUsageNode>\n readonly symbolsByName: Map<string, PendingReactUsageNode>\n}\n\ninterface SerializedReactUsageNode {\n readonly id: string\n readonly name: string\n readonly symbolKind: ReactSymbolKind | 'circular'\n readonly filePath: string\n readonly exportNames: readonly string[]\n readonly usages: readonly SerializedReactUsageEdge[]\n}\n\ninterface SerializedReactUsageEntry {\n readonly targetId: string\n readonly filePath: string\n readonly line: number\n readonly column: number\n readonly node: SerializedReactUsageNode\n}\n\ninterface SerializedReactUsageEdge {\n readonly kind: ReactUsageEdge['kind']\n readonly targetId: string\n readonly node: SerializedReactUsageNode\n}\n\nconst FUNCTION_NODE_TYPES = new Set([\n 'FunctionDeclaration',\n 'FunctionExpression',\n 'ArrowFunctionExpression',\n 'TSDeclareFunction',\n 'TSEmptyBodyFunctionExpression',\n])\n\nexport function analyzeReactUsage(\n entryFile: string,\n options: AnalyzeOptions = {},\n): ReactUsageGraph {\n const dependencyGraph = analyzeDependencies(entryFile, options)\n const reachableFiles = new Set<string>([\n dependencyGraph.entryId,\n ...dependencyGraph.nodes.keys(),\n ])\n const fileAnalyses = new Map<string, FileAnalysis>()\n\n for (const filePath of [...reachableFiles].sort()) {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n continue\n }\n\n const sourceText = fs.readFileSync(filePath, 'utf8')\n const parseResult = parseSync(filePath, sourceText, {\n astType: 'ts',\n sourceType: 'unambiguous',\n })\n\n const dependencyNode = dependencyGraph.nodes.get(filePath)\n const sourceDependencies = new Map<string, string>()\n dependencyNode?.dependencies.forEach((dependency) => {\n if (dependency.kind === 'source') {\n sourceDependencies.set(dependency.specifier, dependency.target)\n }\n })\n\n fileAnalyses.set(\n filePath,\n analyzeReactFile(\n parseResult.program,\n filePath,\n sourceText,\n sourceDependencies,\n ),\n )\n }\n\n const nodes = new Map<string, ReactUsageNode>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n nodes.set(symbol.id, {\n id: symbol.id,\n name: symbol.name,\n kind: symbol.kind,\n filePath: symbol.filePath,\n exportNames: [...symbol.exportNames].sort(),\n usages: [],\n })\n }\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n fileAnalysis.importsByLocalName.forEach((binding, localName) => {\n if (binding.sourcePath !== undefined) {\n return\n }\n\n if (!isHookName(localName) && !isHookName(binding.importedName)) {\n return\n }\n\n const externalNode = createExternalHookNode(binding, localName)\n if (!nodes.has(externalNode.id)) {\n nodes.set(externalNode.id, externalNode)\n }\n })\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n const usages = new Map<string, ReactUsageEdge>()\n\n symbol.componentReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'component',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`render:${targetId}`, {\n kind: 'render',\n target: targetId,\n })\n }\n })\n\n symbol.hookReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'hook',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`hook:${targetId}`, {\n kind: 'hook-call',\n target: targetId,\n })\n }\n })\n\n const node = nodes.get(symbol.id)\n if (node === undefined) {\n continue\n }\n\n const sortedUsages = [...usages.values()].sort((left, right) =>\n compareReactNodeIds(left.target, right.target, nodes),\n )\n\n nodes.set(symbol.id, {\n ...node,\n usages: sortedUsages,\n })\n }\n }\n\n const entriesByKey = new Map<string, ReactUsageEntry>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const entry of fileAnalysis.renderEntries) {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n entry.referenceName,\n 'component',\n )\n if (targetId === undefined) {\n continue\n }\n\n const key = `${entry.location.filePath}:${entry.location.line}:${entry.location.column}:${targetId}`\n entriesByKey.set(key, {\n target: targetId,\n location: entry.location,\n })\n }\n }\n\n const entries = [...entriesByKey.values()].sort((left, right) =>\n compareReactUsageEntries(left, right, nodes),\n )\n\n return {\n cwd: dependencyGraph.cwd,\n entryId: dependencyGraph.entryId,\n nodes,\n entries,\n }\n}\n\nexport function graphToSerializableReactTree(\n graph: ReactUsageGraph,\n options: {\n readonly filter?: ReactUsageFilter\n } = {},\n): object {\n const filter = options.filter ?? 'all'\n const entries = getReactUsageEntries(graph, filter)\n const roots =\n entries.length > 0\n ? entries.map((entry) =>\n serializeReactUsageNode(entry.target, graph, filter, new Set()),\n )\n : getReactUsageRoots(graph, filter).map((rootId) =>\n serializeReactUsageNode(rootId, graph, filter, new Set()),\n )\n\n return {\n kind: 'react-usage',\n entries: entries.map((entry) =>\n serializeReactUsageEntry(entry, graph, filter),\n ),\n roots,\n }\n}\n\nexport function getReactUsageEntries(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEntry[] {\n if (filter === 'hook') {\n return []\n }\n\n return graph.entries.filter((entry) => {\n const targetNode = graph.nodes.get(entry.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nexport function getReactUsageRoots(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): string[] {\n const entries = getReactUsageEntries(graph, filter)\n if (entries.length > 0) {\n return [...new Set(entries.map((entry) => entry.target))]\n }\n\n const filteredNodes = getFilteredReactUsageNodes(graph, filter)\n const inboundCounts = new Map<string, number>()\n\n filteredNodes.forEach((node) => {\n inboundCounts.set(node.id, 0)\n })\n\n filteredNodes.forEach((node) => {\n getFilteredUsages(node, graph, filter).forEach((usage) => {\n inboundCounts.set(\n usage.target,\n (inboundCounts.get(usage.target) ?? 0) + 1,\n )\n })\n })\n\n const roots = filteredNodes\n .filter((node) => (inboundCounts.get(node.id) ?? 0) === 0)\n .map((node) => node.id)\n\n if (roots.length > 0) {\n return roots.sort((left, right) =>\n compareReactNodeIds(left, right, graph.nodes),\n )\n }\n\n return filteredNodes\n .map((node) => node.id)\n .sort((left, right) => compareReactNodeIds(left, right, graph.nodes))\n}\n\nexport function getFilteredUsages(\n node: ReactUsageNode,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEdge[] {\n return node.usages.filter((usage) => {\n const targetNode = graph.nodes.get(usage.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nfunction analyzeReactFile(\n program: Program,\n filePath: string,\n sourceText: string,\n sourceDependencies: ReadonlyMap<string, string>,\n): FileAnalysis {\n const symbolsByName = new Map<string, PendingReactUsageNode>()\n\n program.body.forEach((statement) => {\n collectTopLevelReactSymbols(statement, filePath, symbolsByName)\n })\n\n const importsByLocalName = new Map<string, ImportBinding>()\n const exportsByName = new Map<string, string>()\n const renderEntries = collectRenderEntries(program, filePath, sourceText)\n\n program.body.forEach((statement) => {\n collectImportsAndExports(\n statement,\n sourceDependencies,\n symbolsByName,\n importsByLocalName,\n exportsByName,\n )\n })\n\n symbolsByName.forEach((symbol) => {\n analyzeSymbolUsages(symbol)\n })\n\n return {\n filePath,\n importsByLocalName,\n exportsByName,\n renderEntries,\n symbolsById: new Map(\n [...symbolsByName.values()].map((symbol) => [symbol.id, symbol]),\n ),\n symbolsByName,\n }\n}\n\nfunction collectRenderEntries(\n program: Program,\n filePath: string,\n sourceText: string,\n): PendingReactUsageEntry[] {\n const entries = new Map<string, PendingReactUsageEntry>()\n\n program.body.forEach((statement) => {\n collectStatementRenderEntries(statement, filePath, sourceText, entries)\n })\n\n return [...entries.values()].sort(comparePendingReactUsageEntries)\n}\n\nfunction collectStatementRenderEntries(\n statement: Statement,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n): void {\n collectNodeRenderEntries(statement, filePath, sourceText, entries, false)\n}\n\nfunction collectNodeRenderEntries(\n node: Node,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n hasComponentAncestor: boolean,\n): void {\n if (FUNCTION_NODE_TYPES.has(node.type)) {\n return\n }\n\n let nextHasComponentAncestor = hasComponentAncestor\n\n if (node.type === 'JSXElement') {\n const referenceName = getComponentReferenceName(node)\n if (referenceName !== undefined) {\n if (!hasComponentAncestor) {\n addPendingRenderEntry(\n entries,\n referenceName,\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n nextHasComponentAncestor = true\n }\n } else if (node.type === 'CallExpression') {\n const referenceName = getCreateElementComponentReferenceName(node)\n if (referenceName !== undefined) {\n if (!hasComponentAncestor) {\n addPendingRenderEntry(\n entries,\n referenceName,\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n nextHasComponentAncestor = true\n }\n }\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n collectRenderEntryChild(\n value,\n filePath,\n sourceText,\n entries,\n nextHasComponentAncestor,\n )\n })\n}\n\nfunction collectRenderEntryChild(\n value: unknown,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n hasComponentAncestor: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n collectRenderEntryChild(\n entry,\n filePath,\n sourceText,\n entries,\n hasComponentAncestor,\n )\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n collectNodeRenderEntries(\n value,\n filePath,\n sourceText,\n entries,\n hasComponentAncestor,\n )\n}\n\nfunction addPendingRenderEntry(\n entries: Map<string, PendingReactUsageEntry>,\n referenceName: string,\n location: ReactUsageLocation,\n): void {\n const key = `${location.filePath}:${location.line}:${location.column}:${referenceName}`\n entries.set(key, {\n referenceName,\n location,\n })\n}\n\nfunction createReactUsageLocation(\n filePath: string,\n sourceText: string,\n offset: number,\n): ReactUsageLocation {\n return {\n filePath,\n ...offsetToLineAndColumn(sourceText, offset),\n }\n}\n\nfunction offsetToLineAndColumn(\n sourceText: string,\n offset: number,\n): Pick<ReactUsageLocation, 'line' | 'column'> {\n let line = 1\n let column = 1\n\n for (let index = 0; index < offset && index < sourceText.length; index += 1) {\n if (sourceText[index] === '\\n') {\n line += 1\n column = 1\n continue\n }\n\n column += 1\n }\n\n return { line, column }\n}\n\nfunction collectTopLevelReactSymbols(\n statement: Statement,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n switch (statement.type) {\n case 'FunctionDeclaration':\n addFunctionSymbol(statement, filePath, symbolsByName)\n return\n case 'VariableDeclaration':\n statement.declarations.forEach((declarator) => {\n addVariableSymbol(declarator, filePath, symbolsByName)\n })\n return\n case 'ExportNamedDeclaration':\n if (statement.declaration !== null) {\n collectTopLevelReactSymbols(\n statement.declaration,\n filePath,\n symbolsByName,\n )\n }\n return\n case 'ExportDefaultDeclaration':\n addDefaultExportSymbol(statement, filePath, symbolsByName)\n return\n default:\n return\n }\n}\n\nfunction addFunctionSymbol(\n declaration: OxcFunction,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n const name = declaration.id?.name\n if (name === undefined) {\n return\n }\n\n const kind = classifyReactSymbol(name, declaration)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration),\n )\n}\n\nfunction addVariableSymbol(\n declarator: VariableDeclarator,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (declarator.id.type !== 'Identifier' || declarator.init === null) {\n return\n }\n\n if (\n declarator.init.type !== 'ArrowFunctionExpression' &&\n declarator.init.type !== 'FunctionExpression'\n ) {\n return\n }\n\n const name = declarator.id.name\n const kind = classifyReactSymbol(name, declarator.init)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declarator.init),\n )\n}\n\nfunction addDefaultExportSymbol(\n declaration: ExportDefaultDeclaration,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n addFunctionSymbol(declaration.declaration, filePath, symbolsByName)\n } else if (declaration.declaration.type === 'ArrowFunctionExpression') {\n const name = 'default'\n const kind = declaration.declaration.body\n ? classifyReactSymbol(name, declaration.declaration)\n : undefined\n if (kind !== undefined) {\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration.declaration),\n )\n }\n }\n}\n\nfunction createPendingSymbol(\n filePath: string,\n name: string,\n kind: ReactSymbolKind,\n declaration: OxcFunction | ArrowFunctionExpression,\n): PendingReactUsageNode {\n return {\n id: `${filePath}#${kind}:${name}`,\n name,\n kind,\n filePath,\n declaration,\n exportNames: new Set<string>(),\n componentReferences: new Set<string>(),\n hookReferences: new Set<string>(),\n }\n}\n\nfunction collectImportsAndExports(\n statement: Statement,\n sourceDependencies: ReadonlyMap<string, string>,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n importsByLocalName: Map<string, ImportBinding>,\n exportsByName: Map<string, string>,\n): void {\n switch (statement.type) {\n case 'ImportDeclaration':\n collectImportBindings(statement, sourceDependencies, importsByLocalName)\n return\n case 'ExportNamedDeclaration':\n collectNamedExports(statement, symbolsByName, exportsByName)\n return\n case 'ExportDefaultDeclaration':\n collectDefaultExport(statement, symbolsByName, exportsByName)\n return\n default:\n return\n }\n}\n\nfunction collectImportBindings(\n declaration: ImportDeclaration,\n sourceDependencies: ReadonlyMap<string, string>,\n importsByLocalName: Map<string, ImportBinding>,\n): void {\n if (declaration.importKind === 'type') {\n return\n }\n\n const sourceSpecifier = declaration.source.value\n const sourcePath = sourceDependencies.get(declaration.source.value)\n\n declaration.specifiers.forEach((specifier) => {\n const binding = getImportBinding(specifier, sourceSpecifier, sourcePath)\n if (binding === undefined) {\n return\n }\n\n importsByLocalName.set(binding.localName, {\n importedName: binding.importedName,\n sourceSpecifier: binding.sourceSpecifier,\n ...(binding.sourcePath === undefined\n ? {}\n : { sourcePath: binding.sourcePath }),\n })\n })\n}\n\nfunction getImportBinding(\n specifier: ImportDeclarationSpecifier,\n sourceSpecifier: string,\n sourcePath: string | undefined,\n):\n | {\n readonly localName: string\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n }\n | undefined {\n if (specifier.type === 'ImportSpecifier') {\n if (specifier.importKind === 'type') {\n return undefined\n }\n\n return {\n localName: specifier.local.name,\n importedName: toModuleExportName(specifier.imported),\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n if (specifier.type === 'ImportDefaultSpecifier') {\n return {\n localName: specifier.local.name,\n importedName: 'default',\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n return undefined\n}\n\nfunction collectNamedExports(\n declaration: ExportNamedDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (declaration.exportKind === 'type') {\n return\n }\n\n if (declaration.declaration !== null) {\n if (declaration.declaration.type === 'FunctionDeclaration') {\n const name = declaration.declaration.id?.name\n if (name !== undefined) {\n addExportBinding(name, name, symbolsByName, exportsByName)\n }\n } else if (declaration.declaration.type === 'VariableDeclaration') {\n declaration.declaration.declarations.forEach((declarator) => {\n if (declarator.id.type === 'Identifier') {\n addExportBinding(\n declarator.id.name,\n declarator.id.name,\n symbolsByName,\n exportsByName,\n )\n }\n })\n }\n\n return\n }\n\n if (declaration.source !== null) {\n return\n }\n\n declaration.specifiers.forEach((specifier) => {\n if (specifier.exportKind === 'type') {\n return\n }\n\n const localName = toModuleExportName(specifier.local)\n const exportedName = toModuleExportName(specifier.exported)\n addExportBinding(localName, exportedName, symbolsByName, exportsByName)\n })\n}\n\nfunction collectDefaultExport(\n declaration: ExportDefaultDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n const localName = declaration.declaration.id?.name\n if (localName !== undefined) {\n addExportBinding(localName, 'default', symbolsByName, exportsByName)\n }\n return\n }\n\n if (declaration.declaration.type === 'Identifier') {\n addExportBinding(\n declaration.declaration.name,\n 'default',\n symbolsByName,\n exportsByName,\n )\n return\n }\n\n if (declaration.declaration.type === 'ArrowFunctionExpression') {\n addExportBinding('default', 'default', symbolsByName, exportsByName)\n }\n}\n\nfunction addExportBinding(\n localName: string,\n exportedName: string,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n const symbol = symbolsByName.get(localName)\n if (symbol === undefined) {\n return\n }\n\n symbol.exportNames.add(exportedName)\n exportsByName.set(exportedName, symbol.id)\n}\n\nfunction analyzeSymbolUsages(symbol: PendingReactUsageNode): void {\n const root =\n symbol.declaration.type === 'ArrowFunctionExpression'\n ? symbol.declaration.body\n : symbol.declaration.body\n\n if (root === null) {\n return\n }\n\n walkReactUsageTree(root, (node) => {\n if (node.type === 'JSXElement') {\n const name = getComponentReferenceName(node)\n if (name !== undefined) {\n symbol.componentReferences.add(name)\n }\n return\n }\n\n if (node.type === 'CallExpression') {\n const hookReference = getHookReferenceName(node)\n if (hookReference !== undefined) {\n symbol.hookReferences.add(hookReference)\n }\n\n const componentReference = getCreateElementComponentReferenceName(node)\n if (componentReference !== undefined) {\n symbol.componentReferences.add(componentReference)\n }\n }\n })\n}\n\nfunction classifyReactSymbol(\n name: string,\n declaration: OxcFunction | ArrowFunctionExpression,\n): ReactSymbolKind | undefined {\n if (isHookName(name)) {\n return 'hook'\n }\n\n if (isComponentName(name) && returnsReactElement(declaration)) {\n return 'component'\n }\n\n return undefined\n}\n\nfunction returnsReactElement(\n declaration: OxcFunction | ArrowFunctionExpression,\n): boolean {\n if (\n declaration.type === 'ArrowFunctionExpression' &&\n declaration.expression\n ) {\n return containsReactElementLikeExpression(declaration.body as Expression)\n }\n\n const body = declaration.body\n if (body === null) {\n return false\n }\n\n let found = false\n walkReactUsageTree(body, (node) => {\n if (node.type !== 'ReturnStatement' || node.argument === null) {\n return\n }\n\n if (containsReactElementLikeExpression(node.argument)) {\n found = true\n }\n })\n\n return found\n}\n\nfunction containsReactElementLikeExpression(expression: Expression): boolean {\n let found = false\n\n walkNode(expression, (node) => {\n if (\n node.type === 'JSXElement' ||\n node.type === 'JSXFragment' ||\n (node.type === 'CallExpression' && isReactCreateElementCall(node))\n ) {\n found = true\n }\n })\n\n return found\n}\n\nfunction getComponentReferenceName(node: JSXElement): string | undefined {\n const name = getJsxName(node.openingElement.name)\n return name !== undefined && isComponentName(name) ? name : undefined\n}\n\nfunction getHookReferenceName(node: CallExpression): string | undefined {\n const calleeName = getIdentifierName(node.callee)\n return calleeName !== undefined && isHookName(calleeName)\n ? calleeName\n : undefined\n}\n\nfunction getCreateElementComponentReferenceName(\n node: CallExpression,\n): string | undefined {\n if (!isReactCreateElementCall(node)) {\n return undefined\n }\n\n const [firstArgument] = node.arguments\n if (firstArgument === undefined || firstArgument.type !== 'Identifier') {\n return undefined\n }\n\n return isComponentName(firstArgument.name) ? firstArgument.name : undefined\n}\n\nfunction isReactCreateElementCall(node: CallExpression): boolean {\n const callee = unwrapExpression(node.callee)\n if (callee.type !== 'MemberExpression' || callee.computed) {\n return false\n }\n\n return (\n callee.object.type === 'Identifier' &&\n callee.object.name === 'React' &&\n callee.property.name === 'createElement'\n )\n}\n\nfunction getJsxName(name: JSXElementName): string | undefined {\n if (name.type === 'JSXIdentifier') {\n return name.name\n }\n\n return undefined\n}\n\nfunction getIdentifierName(expression: Expression): string | undefined {\n const unwrapped = unwrapExpression(expression)\n return unwrapped.type === 'Identifier' ? unwrapped.name : undefined\n}\n\nfunction unwrapExpression(expression: Expression): Expression {\n let current = expression\n\n while (true) {\n if (\n current.type === 'ParenthesizedExpression' ||\n current.type === 'TSAsExpression' ||\n current.type === 'TSSatisfiesExpression' ||\n current.type === 'TSTypeAssertion' ||\n current.type === 'TSNonNullExpression'\n ) {\n current = current.expression\n continue\n }\n\n return current\n }\n}\n\nfunction walkReactUsageTree(\n root: FunctionBody | Expression | JSXFragment | JSXElement,\n visit: (node: Node) => void,\n): void {\n walkNode(root, visit, true)\n}\n\nfunction walkNode(\n node: Node,\n visit: (node: Node) => void,\n allowNestedFunctions = false,\n): void {\n visit(node)\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n walkChild(value, visit, allowNestedFunctions)\n })\n}\n\nfunction walkChild(\n value: unknown,\n visit: (node: Node) => void,\n allowNestedFunctions: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n walkChild(entry, visit, allowNestedFunctions)\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n if (!allowNestedFunctions && FUNCTION_NODE_TYPES.has(value.type)) {\n return\n }\n\n walkNode(value, visit, false)\n}\n\nfunction isNode(value: unknown): value is Node {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n typeof (value as { type: unknown }).type === 'string'\n )\n}\n\nfunction resolveReactReference(\n fileAnalysis: FileAnalysis,\n fileAnalyses: ReadonlyMap<string, FileAnalysis>,\n name: string,\n kind: ReactSymbolKind,\n): string | undefined {\n const localSymbol = fileAnalysis.symbolsByName.get(name)\n if (localSymbol !== undefined && localSymbol.kind === kind) {\n return localSymbol.id\n }\n\n const importBinding = fileAnalysis.importsByLocalName.get(name)\n if (importBinding === undefined) {\n return undefined\n }\n\n if (importBinding.sourcePath === undefined) {\n return kind === 'hook'\n ? getExternalHookNodeId(importBinding, name)\n : undefined\n }\n\n const sourceFileAnalysis = fileAnalyses.get(importBinding.sourcePath)\n if (sourceFileAnalysis === undefined) {\n return undefined\n }\n\n const targetId = sourceFileAnalysis.exportsByName.get(\n importBinding.importedName,\n )\n if (targetId === undefined) {\n return undefined\n }\n\n const targetSymbol = sourceFileAnalysis.symbolsById.get(targetId)\n return targetSymbol?.kind === kind ? targetId : undefined\n}\n\nfunction createExternalHookNode(\n binding: ImportBinding,\n localName: string,\n): ReactUsageNode {\n const name = getExternalHookName(binding, localName)\n\n return {\n id: getExternalHookNodeId(binding, localName),\n name,\n kind: 'hook',\n filePath: binding.sourceSpecifier,\n exportNames: [binding.importedName],\n usages: [],\n }\n}\n\nfunction getExternalHookNodeId(\n binding: ImportBinding,\n localName: string,\n): string {\n return `external:${binding.sourceSpecifier}#hook:${getExternalHookName(binding, localName)}`\n}\n\nfunction getExternalHookName(\n binding: ImportBinding,\n localName: string,\n): string {\n return binding.importedName === 'default' ? localName : binding.importedName\n}\n\nfunction getFilteredReactUsageNodes(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): ReactUsageNode[] {\n return [...graph.nodes.values()]\n .filter((node) => matchesReactFilter(node, filter))\n .sort((left, right) => compareReactNodes(left, right))\n}\n\nfunction matchesReactFilter(\n node: ReactUsageNode,\n filter: ReactUsageFilter,\n): boolean {\n return filter === 'all' || node.kind === filter\n}\n\nfunction serializeReactUsageNode(\n nodeId: string,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n visited: Set<string>,\n): SerializedReactUsageNode {\n const node = graph.nodes.get(nodeId)\n if (node === undefined) {\n return {\n id: nodeId,\n name: nodeId,\n symbolKind: 'circular',\n filePath: '',\n exportNames: [],\n usages: [],\n }\n }\n\n if (visited.has(nodeId)) {\n return {\n id: node.id,\n name: node.name,\n symbolKind: 'circular',\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: [],\n }\n }\n\n const nextVisited = new Set(visited)\n nextVisited.add(nodeId)\n\n return {\n id: node.id,\n name: node.name,\n symbolKind: node.kind,\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: getFilteredUsages(node, graph, filter).map((usage) => ({\n kind: usage.kind,\n targetId: usage.target,\n node: serializeReactUsageNode(usage.target, graph, filter, nextVisited),\n })),\n }\n}\n\nfunction serializeReactUsageEntry(\n entry: ReactUsageEntry,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): SerializedReactUsageEntry {\n return {\n targetId: entry.target,\n filePath: toDisplayPath(entry.location.filePath, graph.cwd),\n line: entry.location.line,\n column: entry.location.column,\n node: serializeReactUsageNode(entry.target, graph, filter, new Set()),\n }\n}\n\nfunction compareReactNodeIds(\n leftId: string,\n rightId: string,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n const left = nodes.get(leftId)\n const right = nodes.get(rightId)\n\n if (left === undefined || right === undefined) {\n return leftId.localeCompare(rightId)\n }\n\n return compareReactNodes(left, right)\n}\n\nfunction compareReactUsageEntries(\n left: ReactUsageEntry,\n right: ReactUsageEntry,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n return (\n left.location.filePath.localeCompare(right.location.filePath) ||\n left.location.line - right.location.line ||\n left.location.column - right.location.column ||\n compareReactNodeIds(left.target, right.target, nodes)\n )\n}\n\nfunction comparePendingReactUsageEntries(\n left: PendingReactUsageEntry,\n right: PendingReactUsageEntry,\n): number {\n return (\n left.location.filePath.localeCompare(right.location.filePath) ||\n left.location.line - right.location.line ||\n left.location.column - right.location.column ||\n left.referenceName.localeCompare(right.referenceName)\n )\n}\n\nfunction compareReactNodes(\n left: ReactUsageNode,\n right: ReactUsageNode,\n): number {\n return (\n left.filePath.localeCompare(right.filePath) ||\n left.name.localeCompare(right.name) ||\n left.kind.localeCompare(right.kind)\n )\n}\n\nfunction toModuleExportName(name: ModuleExportName): string {\n return name.type === 'Literal' ? name.value : name.name\n}\n\nfunction isHookName(name: string): boolean {\n return /^use[A-Z0-9]/.test(name)\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name)\n}\n","import process from 'node:process'\n\nimport type { ColorMode, ReactSymbolKind } from './types.js'\n\nconst ANSI_RESET = '\\u001B[0m'\nconst ANSI_COMPONENT = '\\u001B[36m'\nconst ANSI_HOOK = '\\u001B[35m'\nconst ANSI_UNUSED = '\\u001B[38;5;214m'\n\ninterface ResolveColorSupportOptions {\n readonly forceColor?: string | undefined\n readonly isTTY?: boolean | undefined\n readonly noColor?: string | undefined\n}\n\nexport function resolveColorSupport(\n mode: ColorMode = 'auto',\n options: ResolveColorSupportOptions = {},\n): boolean {\n if (mode === true) {\n return true\n }\n\n if (mode === false) {\n return false\n }\n\n const forceColor =\n 'forceColor' in options ? options.forceColor : process.env.FORCE_COLOR\n if (forceColor !== undefined) {\n return forceColor !== '0'\n }\n\n const noColor = 'noColor' in options ? options.noColor : process.env.NO_COLOR\n if (noColor !== undefined) {\n return false\n }\n\n const isTTY = 'isTTY' in options ? options.isTTY : process.stdout.isTTY\n return isTTY === true\n}\n\nexport function colorizeUnusedMarker(text: string, enabled: boolean): string {\n if (!enabled) {\n return text\n }\n\n return text.replaceAll('(unused)', `${ANSI_UNUSED}(unused)${ANSI_RESET}`)\n}\n\nexport function formatReactSymbolLabel(\n name: string,\n kind: ReactSymbolKind,\n enabled: boolean,\n): string {\n const label = `${name} [${kind}]`\n if (!enabled) {\n return label\n }\n\n const color = kind === 'component' ? ANSI_COMPONENT : ANSI_HOOK\n return `${color}${label}${ANSI_RESET}`\n}\n","import { formatReactSymbolLabel, resolveColorSupport } from './color.js'\nimport { toDisplayPath } from './path-utils.js'\nimport {\n getFilteredUsages,\n getReactUsageEntries,\n getReactUsageRoots,\n} from './react-analyzer.js'\nimport type {\n PrintReactTreeOptions,\n ReactUsageEdge,\n ReactUsageEntry,\n ReactUsageGraph,\n ReactUsageNode,\n} from './types.js'\n\nexport function printReactUsageTree(\n graph: ReactUsageGraph,\n options: PrintReactTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const color = resolveColorSupport(options.color)\n const filter = options.filter ?? 'all'\n const entries = getReactUsageEntries(graph, filter)\n\n if (entries.length > 0) {\n return renderReactUsageEntries(graph, entries, cwd, filter, color)\n }\n\n const roots = getReactUsageRoots(graph, filter)\n if (roots.length === 0) {\n return 'No React symbols found.'\n }\n\n const lines: string[] = []\n roots.forEach((rootId, index) => {\n const root = graph.nodes.get(rootId)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactNodeLabel(root, cwd, color))\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n color,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < roots.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderReactUsageEntries(\n graph: ReactUsageGraph,\n entries: readonly ReactUsageEntry[],\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n color: boolean,\n): string {\n const lines: string[] = []\n\n entries.forEach((entry, index) => {\n const root = graph.nodes.get(entry.target)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactEntryLabel(entry, cwd))\n lines.push(formatReactNodeLabel(root, cwd, color))\n\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n color,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < entries.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderUsage(\n usage: ReactUsageEdge,\n graph: ReactUsageGraph,\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n color: boolean,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const target = graph.nodes.get(usage.target)\n\n if (target === undefined) {\n return [`${branch}${usage.target}`]\n }\n\n if (visited.has(target.id)) {\n return [`${branch}${formatReactNodeLabel(target, cwd, color)} (circular)`]\n }\n\n const childLines = [`${branch}${formatReactNodeLabel(target, cwd, color)}`]\n const nextVisited = new Set(visited)\n nextVisited.add(target.id)\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const childUsages = getFilteredUsages(target, graph, filter)\n\n childUsages.forEach((childUsage, index) => {\n childLines.push(\n ...renderUsage(\n childUsage,\n graph,\n cwd,\n filter,\n color,\n nextVisited,\n nextPrefix,\n index === childUsages.length - 1,\n ),\n )\n })\n\n return childLines\n}\n\nfunction formatReactNodeLabel(\n node: ReactUsageNode,\n cwd: string,\n color: boolean,\n): string {\n return `${formatReactSymbolLabel(node.name, node.kind, color)} (${toDisplayPath(node.filePath, cwd)})`\n}\n\nfunction formatReactEntryLabel(entry: ReactUsageEntry, cwd: string): string {\n return `${toDisplayPath(entry.location.filePath, cwd)}:${entry.location.line}:${entry.location.column}`\n}\n","import { colorizeUnusedMarker, resolveColorSupport } from './color.js'\nimport { toDisplayPath } from './path-utils.js'\nimport type {\n DependencyEdge,\n DependencyGraph,\n PrintTreeOptions,\n} from './types.js'\n\nexport function printDependencyTree(\n graph: DependencyGraph,\n options: PrintTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const color = resolveColorSupport(options.color)\n const includeExternals = options.includeExternals ?? false\n const omitUnused = options.omitUnused ?? false\n const rootLines = [toDisplayPath(graph.entryId, cwd)]\n const visited = new Set<string>([graph.entryId])\n const entryNode = graph.nodes.get(graph.entryId)\n\n if (entryNode === undefined) {\n return rootLines.join('\\n')\n }\n\n const rootDependencies = filterDependencies(\n entryNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n rootDependencies.forEach((dependency, index) => {\n const isLast = index === rootDependencies.length - 1\n const lines = renderDependency(\n dependency,\n graph,\n visited,\n '',\n isLast,\n includeExternals,\n omitUnused,\n color,\n cwd,\n )\n rootLines.push(...lines)\n })\n\n return rootLines.join('\\n')\n}\n\nfunction renderDependency(\n dependency: DependencyEdge,\n graph: DependencyGraph,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n includeExternals: boolean,\n omitUnused: boolean,\n color: boolean,\n cwd: string,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const label = formatDependencyLabel(dependency, cwd, color)\n\n if (dependency.kind !== 'source') {\n return [`${branch}${label}`]\n }\n\n if (visited.has(dependency.target)) {\n return [`${branch}${label} (circular)`]\n }\n\n const childNode = graph.nodes.get(dependency.target)\n if (childNode === undefined) {\n return [`${branch}${label}`]\n }\n\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const nextVisited = new Set(visited)\n nextVisited.add(dependency.target)\n\n const childLines = [`${branch}${label}`]\n const childDependencies = filterDependencies(\n childNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n childDependencies.forEach((childDependency, index) => {\n const isChildLast = index === childDependencies.length - 1\n childLines.push(\n ...renderDependency(\n childDependency,\n graph,\n nextVisited,\n nextPrefix,\n isChildLast,\n includeExternals,\n omitUnused,\n color,\n cwd,\n ),\n )\n })\n\n return childLines\n}\n\nfunction filterDependencies(\n dependencies: readonly DependencyEdge[],\n includeExternals: boolean,\n omitUnused: boolean,\n): DependencyEdge[] {\n return dependencies.filter((dependency) => {\n if (omitUnused && dependency.unused) {\n return false\n }\n\n if (dependency.kind === 'source' || dependency.kind === 'missing') {\n return true\n }\n\n return includeExternals\n })\n}\n\nfunction formatDependencyLabel(\n dependency: DependencyEdge,\n cwd: string,\n color: boolean,\n): string {\n const prefixes: string[] = []\n if (dependency.isTypeOnly) {\n prefixes.push('type')\n }\n\n if (dependency.referenceKind === 'require') {\n prefixes.push('require')\n } else if (dependency.referenceKind === 'dynamic-import') {\n prefixes.push('dynamic')\n } else if (dependency.referenceKind === 'export') {\n prefixes.push('re-export')\n } else if (dependency.referenceKind === 'import-equals') {\n prefixes.push('import=')\n }\n\n const annotation = prefixes.length > 0 ? `[${prefixes.join(', ')}] ` : ''\n\n if (dependency.kind === 'source') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${toDisplayPath(dependency.target, cwd)}`,\n dependency.unused,\n ),\n color,\n )\n }\n\n if (dependency.kind === 'missing') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.specifier} [missing]`,\n dependency.unused,\n ),\n color,\n )\n }\n\n if (dependency.kind === 'builtin') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.target} [builtin]`,\n dependency.unused,\n ),\n color,\n )\n }\n\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.target} [external]`,\n dependency.unused,\n ),\n color,\n )\n}\n\nfunction withUnusedSuffix(label: string, unused: boolean): string {\n return unused ? `${label} (unused)` : label\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tree-DbnWcUnV.mjs","names":[],"sources":["../src/config.ts","../src/path-utils.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/react-tree.ts","../src/tree.ts"],"sourcesContent":["import path from 'node:path'\nimport ts from 'typescript'\n\nexport interface LoadedConfig {\n readonly path?: string\n readonly compilerOptions: ts.CompilerOptions\n}\n\nexport function loadCompilerOptions(\n searchFrom: string,\n explicitConfigPath?: string,\n): LoadedConfig {\n const configPath =\n explicitConfigPath === undefined\n ? findNearestConfig(searchFrom)\n : path.resolve(searchFrom, explicitConfigPath)\n\n if (configPath === undefined) {\n return {\n compilerOptions: defaultCompilerOptions(),\n }\n }\n\n const readResult = ts.readConfigFile(configPath, ts.sys.readFile)\n if (readResult.error !== undefined) {\n throw new Error(\n `Failed to read TypeScript config at ${configPath}: ${formatDiagnostic(\n readResult.error,\n )}`,\n )\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n readResult.config,\n ts.sys,\n path.dirname(configPath),\n defaultCompilerOptions(),\n configPath,\n )\n\n if (parsed.errors.length > 0) {\n const [firstError] = parsed.errors\n if (firstError === undefined) {\n throw new Error(`Failed to parse TypeScript config at ${configPath}.`)\n }\n\n throw new Error(\n `Failed to parse TypeScript config at ${configPath}: ${formatDiagnostic(\n firstError,\n )}`,\n )\n }\n\n return {\n path: configPath,\n compilerOptions: parsed.options,\n }\n}\n\nfunction findNearestConfig(searchFrom: string): string | undefined {\n let currentDirectory = path.resolve(searchFrom)\n\n while (true) {\n const tsconfigPath = path.join(currentDirectory, 'tsconfig.json')\n if (ts.sys.fileExists(tsconfigPath)) {\n return tsconfigPath\n }\n\n const jsconfigPath = path.join(currentDirectory, 'jsconfig.json')\n if (ts.sys.fileExists(jsconfigPath)) {\n return jsconfigPath\n }\n\n const parentDirectory = path.dirname(currentDirectory)\n if (parentDirectory === currentDirectory) {\n return undefined\n }\n\n currentDirectory = parentDirectory\n }\n}\n\nfunction defaultCompilerOptions(): ts.CompilerOptions {\n return {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n target: ts.ScriptTarget.ESNext,\n resolveJsonModule: true,\n esModuleInterop: true,\n }\n}\n\nfunction formatDiagnostic(diagnostic: ts.Diagnostic): string {\n return ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')\n}\n","import path from 'node:path'\n\nexport const SOURCE_EXTENSIONS = new Set([\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n])\n\nexport function normalizeFilePath(filePath: string): string {\n return path.normalize(filePath)\n}\n\nexport function toDisplayPath(filePath: string, cwd: string): string {\n const relativePath = path.relative(cwd, filePath)\n if (relativePath === '') {\n return '.'\n }\n\n const normalizedPath = relativePath.split(path.sep).join('/')\n return normalizedPath.startsWith('..') ? filePath : normalizedPath\n}\n\nexport function isSourceCodeFile(filePath: string): boolean {\n return SOURCE_EXTENSIONS.has(path.extname(filePath).toLowerCase())\n}\n","import fs from 'node:fs'\nimport { builtinModules } from 'node:module'\nimport path from 'node:path'\nimport ts from 'typescript'\n\nimport { loadCompilerOptions } from './config.js'\nimport {\n isSourceCodeFile,\n normalizeFilePath,\n toDisplayPath,\n} from './path-utils.js'\nimport type {\n AnalyzeOptions,\n DependencyEdge,\n DependencyGraph,\n DependencyKind,\n ReferenceKind,\n SourceModuleNode,\n} from './types.js'\n\ninterface ModuleReference {\n readonly specifier: string\n readonly referenceKind: ReferenceKind\n readonly isTypeOnly: boolean\n readonly unused: boolean\n}\n\nconst BUILTIN_MODULES = new Set(\n builtinModules.flatMap((name) => [name, `node:${name}`]),\n)\n\nexport function analyzeDependencies(\n entryFile: string,\n options: AnalyzeOptions = {},\n): DependencyGraph {\n const cwd = path.resolve(options.cwd ?? process.cwd())\n const resolvedEntryPath = resolveExistingPath(cwd, entryFile)\n const { compilerOptions, path: configPath } = loadCompilerOptions(\n path.dirname(resolvedEntryPath),\n options.configPath,\n )\n\n const host: ts.ModuleResolutionHost = {\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n directoryExists: ts.sys.directoryExists,\n getCurrentDirectory: () => cwd,\n getDirectories: ts.sys.getDirectories,\n ...(ts.sys.realpath === undefined ? {} : { realpath: ts.sys.realpath }),\n }\n\n const nodes = new Map<string, SourceModuleNode>()\n const program = createProgram(resolvedEntryPath, compilerOptions, cwd)\n const checker = program.getTypeChecker()\n visitFile(resolvedEntryPath, compilerOptions, host, checker, program, nodes)\n\n return {\n cwd,\n entryId: resolvedEntryPath,\n nodes,\n ...(configPath === undefined ? {} : { configPath }),\n }\n}\n\nexport function graphToSerializableTree(\n graph: DependencyGraph,\n options: {\n readonly omitUnused?: boolean\n } = {},\n): object {\n const visited = new Set<string>()\n return serializeNode(\n graph.entryId,\n graph,\n visited,\n options.omitUnused ?? false,\n )\n}\n\nfunction serializeNode(\n filePath: string,\n graph: DependencyGraph,\n visited: Set<string>,\n omitUnused: boolean,\n): object {\n const node = graph.nodes.get(filePath)\n const displayPath = toDisplayPath(filePath, graph.cwd)\n\n if (node === undefined) {\n return {\n path: displayPath,\n kind: 'missing',\n dependencies: [],\n }\n }\n\n if (visited.has(filePath)) {\n return {\n path: displayPath,\n kind: 'circular',\n dependencies: [],\n }\n }\n\n visited.add(filePath)\n\n const dependencies = node.dependencies\n .filter((dependency) => !omitUnused || !dependency.unused)\n .map((dependency) => {\n if (dependency.kind !== 'source') {\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target:\n dependency.kind === 'missing'\n ? dependency.target\n : toDisplayPath(dependency.target, graph.cwd),\n }\n }\n\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target: toDisplayPath(dependency.target, graph.cwd),\n node: serializeNode(\n dependency.target,\n graph,\n new Set(visited),\n omitUnused,\n ),\n }\n })\n\n return {\n path: displayPath,\n kind: filePath === graph.entryId ? 'entry' : 'source',\n dependencies,\n }\n}\n\nfunction visitFile(\n filePath: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n checker: ts.TypeChecker,\n program: ts.Program,\n nodes: Map<string, SourceModuleNode>,\n): void {\n const normalizedPath = normalizeFilePath(filePath)\n if (nodes.has(normalizedPath)) {\n return\n }\n\n const sourceFile =\n program.getSourceFile(normalizedPath) ?? createSourceFile(normalizedPath)\n\n const references = collectModuleReferences(sourceFile, checker)\n const dependencies = references.map((reference) =>\n resolveDependency(reference, normalizedPath, compilerOptions, host),\n )\n\n nodes.set(normalizedPath, {\n id: normalizedPath,\n dependencies,\n })\n\n for (const dependency of dependencies) {\n if (dependency.kind === 'source') {\n visitFile(\n dependency.target,\n compilerOptions,\n host,\n checker,\n program,\n nodes,\n )\n }\n }\n}\n\nfunction collectModuleReferences(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ModuleReference[] {\n const references = new Map<string, ModuleReference>()\n const unusedImports = collectUnusedImports(sourceFile, checker)\n\n function addReference(\n specifier: string,\n referenceKind: ReferenceKind,\n isTypeOnly: boolean,\n unused: boolean,\n ): void {\n const key = `${referenceKind}:${isTypeOnly ? 'type' : 'value'}:${specifier}`\n const existing = references.get(key)\n if (existing !== undefined) {\n if (existing.unused && !unused) {\n references.set(key, {\n ...existing,\n unused: false,\n })\n }\n return\n }\n\n references.set(key, {\n specifier,\n referenceKind,\n isTypeOnly,\n unused,\n })\n }\n\n function visit(node: ts.Node): void {\n if (\n ts.isImportDeclaration(node) &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'import',\n node.importClause?.isTypeOnly ?? false,\n unusedImports.get(node) ?? false,\n )\n } else if (\n ts.isExportDeclaration(node) &&\n node.moduleSpecifier !== undefined &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'export',\n node.isTypeOnly ?? false,\n false,\n )\n } else if (ts.isImportEqualsDeclaration(node)) {\n const moduleReference = node.moduleReference\n if (\n ts.isExternalModuleReference(moduleReference) &&\n moduleReference.expression !== undefined &&\n ts.isStringLiteralLike(moduleReference.expression)\n ) {\n addReference(\n moduleReference.expression.text,\n 'import-equals',\n false,\n false,\n )\n }\n } else if (ts.isCallExpression(node)) {\n if (\n node.expression.kind === ts.SyntaxKind.ImportKeyword &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'dynamic-import', false, false)\n }\n }\n\n if (\n ts.isIdentifier(node.expression) &&\n node.expression.text === 'require' &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'require', false, false)\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n return [...references.values()]\n}\n\nfunction resolveDependency(\n reference: ModuleReference,\n containingFile: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n): DependencyEdge {\n const specifier = reference.specifier\n if (BUILTIN_MODULES.has(specifier)) {\n return createEdge(reference, 'builtin', specifier)\n }\n\n const resolution = ts.resolveModuleName(\n specifier,\n containingFile,\n compilerOptions,\n host,\n ).resolvedModule\n\n if (resolution !== undefined) {\n const resolvedPath = normalizeFilePath(resolution.resolvedFileName)\n if (\n resolution.isExternalLibraryImport ||\n resolvedPath.includes(`${path.sep}node_modules${path.sep}`)\n ) {\n return createEdge(reference, 'external', specifier)\n }\n\n if (isSourceCodeFile(resolvedPath) && !resolvedPath.endsWith('.d.ts')) {\n return createEdge(reference, 'source', resolvedPath)\n }\n }\n\n if (!specifier.startsWith('.') && !path.isAbsolute(specifier)) {\n return createEdge(reference, 'external', specifier)\n }\n\n return createEdge(reference, 'missing', specifier)\n}\n\nfunction createEdge(\n reference: ModuleReference,\n kind: DependencyKind,\n target: string,\n): DependencyEdge {\n return {\n specifier: reference.specifier,\n referenceKind: reference.referenceKind,\n isTypeOnly: reference.isTypeOnly,\n unused: reference.unused,\n kind,\n target,\n }\n}\n\nfunction createProgram(\n entryFile: string,\n compilerOptions: ts.CompilerOptions,\n cwd: string,\n): ts.Program {\n const host = ts.createCompilerHost(compilerOptions, true)\n host.getCurrentDirectory = () => cwd\n\n if (ts.sys.realpath !== undefined) {\n host.realpath = ts.sys.realpath\n }\n\n return ts.createProgram({\n rootNames: [entryFile],\n options: compilerOptions,\n host,\n })\n}\n\nfunction createSourceFile(filePath: string): ts.SourceFile {\n const sourceText = fs.readFileSync(filePath, 'utf8')\n return ts.createSourceFile(\n filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n getScriptKind(filePath),\n )\n}\n\nfunction collectUnusedImports(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ReadonlyMap<ts.ImportDeclaration, boolean> {\n const importUsage = new Map<\n ts.ImportDeclaration,\n {\n canTrack: boolean\n used: boolean\n }\n >()\n const symbolToImportDeclaration = new Map<ts.Symbol, ts.ImportDeclaration>()\n const importedLocalNames = new Set<string>()\n\n sourceFile.statements.forEach((statement) => {\n if (\n !ts.isImportDeclaration(statement) ||\n statement.importClause === undefined\n ) {\n return\n }\n\n const identifiers = getImportBindingIdentifiers(statement.importClause)\n if (identifiers.length === 0) {\n return\n }\n\n importUsage.set(statement, {\n canTrack: false,\n used: false,\n })\n\n identifiers.forEach((identifier) => {\n importedLocalNames.add(identifier.text)\n\n const symbol = tryGetSymbolAtLocation(checker, identifier)\n if (symbol === undefined) {\n return\n }\n\n symbolToImportDeclaration.set(symbol, statement)\n const state = importUsage.get(statement)\n if (state !== undefined) {\n state.canTrack = true\n }\n })\n })\n\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node)) {\n return\n }\n\n if (\n ts.isIdentifier(node) &&\n importedLocalNames.has(node.text) &&\n isReferenceIdentifier(node)\n ) {\n const symbol = tryGetSymbolAtLocation(checker, node)\n const declaration =\n symbol === undefined ? undefined : symbolToImportDeclaration.get(symbol)\n if (declaration !== undefined) {\n const state = importUsage.get(declaration)\n if (state !== undefined) {\n state.used = true\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n\n return new Map(\n [...importUsage.entries()].map(([declaration, state]) => [\n declaration,\n state.canTrack && !state.used,\n ]),\n )\n}\n\nfunction getImportBindingIdentifiers(\n importClause: ts.ImportClause,\n): ts.Identifier[] {\n const identifiers: ts.Identifier[] = []\n\n if (importClause.name !== undefined) {\n identifiers.push(importClause.name)\n }\n\n const namedBindings = importClause.namedBindings\n if (namedBindings === undefined) {\n return identifiers\n }\n\n if (ts.isNamespaceImport(namedBindings)) {\n identifiers.push(namedBindings.name)\n return identifiers\n }\n\n namedBindings.elements.forEach((element) => {\n identifiers.push(element.name)\n })\n\n return identifiers\n}\n\nfunction isReferenceIdentifier(node: ts.Identifier): boolean {\n const parent = node.parent\n\n if (ts.isPropertyAccessExpression(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isQualifiedName(parent) && parent.right === node) {\n return false\n }\n\n if (ts.isPropertyAssignment(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isBindingElement(parent) && parent.propertyName === node) {\n return false\n }\n\n if (ts.isJsxAttribute(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isExportSpecifier(parent)) {\n return parent.propertyName === node || parent.propertyName === undefined\n }\n\n return true\n}\n\nfunction tryGetSymbolAtLocation(\n checker: ts.TypeChecker,\n node: ts.Node,\n): ts.Symbol | undefined {\n try {\n return checker.getSymbolAtLocation(node)\n } catch {\n return undefined\n }\n}\n\nfunction getScriptKind(filePath: string): ts.ScriptKind {\n switch (path.extname(filePath).toLowerCase()) {\n case '.js':\n case '.mjs':\n case '.cjs':\n return ts.ScriptKind.JS\n case '.jsx':\n return ts.ScriptKind.JSX\n case '.tsx':\n return ts.ScriptKind.TSX\n case '.json':\n return ts.ScriptKind.JSON\n default:\n return ts.ScriptKind.TS\n }\n}\n\nfunction resolveExistingPath(cwd: string, entryFile: string): string {\n const absolutePath = path.resolve(cwd, entryFile)\n const normalizedPath = normalizeFilePath(absolutePath)\n\n if (!fs.existsSync(normalizedPath)) {\n throw new Error(`Entry file not found: ${entryFile}`)\n }\n\n if (!isSourceCodeFile(normalizedPath)) {\n throw new Error(`Entry file must be a JS/TS source file: ${entryFile}`)\n }\n\n return normalizedPath\n}\n","import fs from 'node:fs'\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ExportDefaultDeclaration,\n ExportNamedDeclaration,\n Expression,\n FunctionBody,\n ImportDeclaration,\n ImportDeclarationSpecifier,\n JSXElement,\n JSXElementName,\n JSXFragment,\n ModuleExportName,\n Node,\n Function as OxcFunction,\n Program,\n Statement,\n VariableDeclarator,\n} from 'oxc-parser'\nimport { parseSync, visitorKeys } from 'oxc-parser'\n\nimport { analyzeDependencies } from './analyzer.js'\nimport { isSourceCodeFile, toDisplayPath } from './path-utils.js'\nimport type {\n AnalyzeOptions,\n ReactSymbolKind,\n ReactUsageEdge,\n ReactUsageFilter,\n ReactUsageGraph,\n ReactUsageNode,\n} from './types.js'\n\ninterface PendingReactUsageNode {\n readonly id: string\n readonly name: string\n readonly kind: ReactSymbolKind\n readonly filePath: string\n readonly declaration: OxcFunction | ArrowFunctionExpression\n readonly exportNames: Set<string>\n readonly componentReferences: Set<string>\n readonly hookReferences: Set<string>\n}\n\ninterface ImportBinding {\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n}\n\ninterface FileAnalysis {\n readonly filePath: string\n readonly importsByLocalName: Map<string, ImportBinding>\n readonly exportsByName: Map<string, string>\n readonly symbolsById: Map<string, PendingReactUsageNode>\n readonly symbolsByName: Map<string, PendingReactUsageNode>\n}\n\ninterface SerializedReactUsageNode {\n readonly id: string\n readonly name: string\n readonly symbolKind: ReactSymbolKind | 'circular'\n readonly filePath: string\n readonly exportNames: readonly string[]\n readonly usages: readonly SerializedReactUsageEdge[]\n}\n\ninterface SerializedReactUsageEdge {\n readonly kind: ReactUsageEdge['kind']\n readonly targetId: string\n readonly node: SerializedReactUsageNode\n}\n\nconst FUNCTION_NODE_TYPES = new Set([\n 'FunctionDeclaration',\n 'FunctionExpression',\n 'ArrowFunctionExpression',\n 'TSDeclareFunction',\n 'TSEmptyBodyFunctionExpression',\n])\n\nexport function analyzeReactUsage(\n entryFile: string,\n options: AnalyzeOptions = {},\n): ReactUsageGraph {\n const dependencyGraph = analyzeDependencies(entryFile, options)\n const reachableFiles = new Set<string>([\n dependencyGraph.entryId,\n ...dependencyGraph.nodes.keys(),\n ])\n const fileAnalyses = new Map<string, FileAnalysis>()\n\n for (const filePath of [...reachableFiles].sort()) {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n continue\n }\n\n const sourceText = fs.readFileSync(filePath, 'utf8')\n const parseResult = parseSync(filePath, sourceText, {\n astType: 'ts',\n sourceType: 'unambiguous',\n })\n\n const dependencyNode = dependencyGraph.nodes.get(filePath)\n const sourceDependencies = new Map<string, string>()\n dependencyNode?.dependencies.forEach((dependency) => {\n if (dependency.kind === 'source') {\n sourceDependencies.set(dependency.specifier, dependency.target)\n }\n })\n\n fileAnalyses.set(\n filePath,\n analyzeReactFile(parseResult.program, filePath, sourceDependencies),\n )\n }\n\n const nodes = new Map<string, ReactUsageNode>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n nodes.set(symbol.id, {\n id: symbol.id,\n name: symbol.name,\n kind: symbol.kind,\n filePath: symbol.filePath,\n exportNames: [...symbol.exportNames].sort(),\n usages: [],\n })\n }\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n fileAnalysis.importsByLocalName.forEach((binding, localName) => {\n if (binding.sourcePath !== undefined) {\n return\n }\n\n if (!isHookName(localName) && !isHookName(binding.importedName)) {\n return\n }\n\n const externalNode = createExternalHookNode(binding, localName)\n if (!nodes.has(externalNode.id)) {\n nodes.set(externalNode.id, externalNode)\n }\n })\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n const usages = new Map<string, ReactUsageEdge>()\n\n symbol.componentReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'component',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`render:${targetId}`, {\n kind: 'render',\n target: targetId,\n })\n }\n })\n\n symbol.hookReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'hook',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`hook:${targetId}`, {\n kind: 'hook-call',\n target: targetId,\n })\n }\n })\n\n const node = nodes.get(symbol.id)\n if (node === undefined) {\n continue\n }\n\n const sortedUsages = [...usages.values()].sort((left, right) =>\n compareReactNodeIds(left.target, right.target, nodes),\n )\n\n nodes.set(symbol.id, {\n ...node,\n usages: sortedUsages,\n })\n }\n }\n\n return {\n cwd: dependencyGraph.cwd,\n entryId: dependencyGraph.entryId,\n nodes,\n }\n}\n\nexport function graphToSerializableReactTree(\n graph: ReactUsageGraph,\n options: {\n readonly filter?: ReactUsageFilter\n } = {},\n): object {\n const roots = getReactUsageRoots(graph, options.filter)\n\n return {\n kind: 'react-usage',\n roots: roots.map((rootId) =>\n serializeReactUsageNode(\n rootId,\n graph,\n options.filter ?? 'all',\n new Set(),\n ),\n ),\n }\n}\n\nexport function getReactUsageRoots(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): string[] {\n const filteredNodes = getFilteredReactUsageNodes(graph, filter)\n const inboundCounts = new Map<string, number>()\n\n filteredNodes.forEach((node) => {\n inboundCounts.set(node.id, 0)\n })\n\n filteredNodes.forEach((node) => {\n getFilteredUsages(node, graph, filter).forEach((usage) => {\n inboundCounts.set(\n usage.target,\n (inboundCounts.get(usage.target) ?? 0) + 1,\n )\n })\n })\n\n const roots = filteredNodes\n .filter((node) => (inboundCounts.get(node.id) ?? 0) === 0)\n .map((node) => node.id)\n\n if (roots.length > 0) {\n return roots.sort((left, right) =>\n compareReactNodeIds(left, right, graph.nodes),\n )\n }\n\n return filteredNodes\n .map((node) => node.id)\n .sort((left, right) => compareReactNodeIds(left, right, graph.nodes))\n}\n\nexport function getFilteredUsages(\n node: ReactUsageNode,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEdge[] {\n return node.usages.filter((usage) => {\n const targetNode = graph.nodes.get(usage.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nfunction analyzeReactFile(\n program: Program,\n filePath: string,\n sourceDependencies: ReadonlyMap<string, string>,\n): FileAnalysis {\n const symbolsByName = new Map<string, PendingReactUsageNode>()\n\n program.body.forEach((statement) => {\n collectTopLevelReactSymbols(statement, filePath, symbolsByName)\n })\n\n const importsByLocalName = new Map<string, ImportBinding>()\n const exportsByName = new Map<string, string>()\n\n program.body.forEach((statement) => {\n collectImportsAndExports(\n statement,\n sourceDependencies,\n symbolsByName,\n importsByLocalName,\n exportsByName,\n )\n })\n\n symbolsByName.forEach((symbol) => {\n analyzeSymbolUsages(symbol)\n })\n\n return {\n filePath,\n importsByLocalName,\n exportsByName,\n symbolsById: new Map(\n [...symbolsByName.values()].map((symbol) => [symbol.id, symbol]),\n ),\n symbolsByName,\n }\n}\n\nfunction collectTopLevelReactSymbols(\n statement: Statement,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n switch (statement.type) {\n case 'FunctionDeclaration':\n addFunctionSymbol(statement, filePath, symbolsByName)\n return\n case 'VariableDeclaration':\n statement.declarations.forEach((declarator) => {\n addVariableSymbol(declarator, filePath, symbolsByName)\n })\n return\n case 'ExportNamedDeclaration':\n if (statement.declaration !== null) {\n collectTopLevelReactSymbols(\n statement.declaration,\n filePath,\n symbolsByName,\n )\n }\n return\n case 'ExportDefaultDeclaration':\n addDefaultExportSymbol(statement, filePath, symbolsByName)\n return\n default:\n return\n }\n}\n\nfunction addFunctionSymbol(\n declaration: OxcFunction,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n const name = declaration.id?.name\n if (name === undefined) {\n return\n }\n\n const kind = classifyReactSymbol(name, declaration)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration),\n )\n}\n\nfunction addVariableSymbol(\n declarator: VariableDeclarator,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (declarator.id.type !== 'Identifier' || declarator.init === null) {\n return\n }\n\n if (\n declarator.init.type !== 'ArrowFunctionExpression' &&\n declarator.init.type !== 'FunctionExpression'\n ) {\n return\n }\n\n const name = declarator.id.name\n const kind = classifyReactSymbol(name, declarator.init)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declarator.init),\n )\n}\n\nfunction addDefaultExportSymbol(\n declaration: ExportDefaultDeclaration,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n addFunctionSymbol(declaration.declaration, filePath, symbolsByName)\n } else if (declaration.declaration.type === 'ArrowFunctionExpression') {\n const name = 'default'\n const kind = declaration.declaration.body\n ? classifyReactSymbol(name, declaration.declaration)\n : undefined\n if (kind !== undefined) {\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration.declaration),\n )\n }\n }\n}\n\nfunction createPendingSymbol(\n filePath: string,\n name: string,\n kind: ReactSymbolKind,\n declaration: OxcFunction | ArrowFunctionExpression,\n): PendingReactUsageNode {\n return {\n id: `${filePath}#${kind}:${name}`,\n name,\n kind,\n filePath,\n declaration,\n exportNames: new Set<string>(),\n componentReferences: new Set<string>(),\n hookReferences: new Set<string>(),\n }\n}\n\nfunction collectImportsAndExports(\n statement: Statement,\n sourceDependencies: ReadonlyMap<string, string>,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n importsByLocalName: Map<string, ImportBinding>,\n exportsByName: Map<string, string>,\n): void {\n switch (statement.type) {\n case 'ImportDeclaration':\n collectImportBindings(statement, sourceDependencies, importsByLocalName)\n return\n case 'ExportNamedDeclaration':\n collectNamedExports(statement, symbolsByName, exportsByName)\n return\n case 'ExportDefaultDeclaration':\n collectDefaultExport(statement, symbolsByName, exportsByName)\n return\n default:\n return\n }\n}\n\nfunction collectImportBindings(\n declaration: ImportDeclaration,\n sourceDependencies: ReadonlyMap<string, string>,\n importsByLocalName: Map<string, ImportBinding>,\n): void {\n if (declaration.importKind === 'type') {\n return\n }\n\n const sourceSpecifier = declaration.source.value\n const sourcePath = sourceDependencies.get(declaration.source.value)\n\n declaration.specifiers.forEach((specifier) => {\n const binding = getImportBinding(specifier, sourceSpecifier, sourcePath)\n if (binding === undefined) {\n return\n }\n\n importsByLocalName.set(binding.localName, {\n importedName: binding.importedName,\n sourceSpecifier: binding.sourceSpecifier,\n ...(binding.sourcePath === undefined\n ? {}\n : { sourcePath: binding.sourcePath }),\n })\n })\n}\n\nfunction getImportBinding(\n specifier: ImportDeclarationSpecifier,\n sourceSpecifier: string,\n sourcePath: string | undefined,\n):\n | {\n readonly localName: string\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n }\n | undefined {\n if (specifier.type === 'ImportSpecifier') {\n if (specifier.importKind === 'type') {\n return undefined\n }\n\n return {\n localName: specifier.local.name,\n importedName: toModuleExportName(specifier.imported),\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n if (specifier.type === 'ImportDefaultSpecifier') {\n return {\n localName: specifier.local.name,\n importedName: 'default',\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n return undefined\n}\n\nfunction collectNamedExports(\n declaration: ExportNamedDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (declaration.exportKind === 'type') {\n return\n }\n\n if (declaration.declaration !== null) {\n if (declaration.declaration.type === 'FunctionDeclaration') {\n const name = declaration.declaration.id?.name\n if (name !== undefined) {\n addExportBinding(name, name, symbolsByName, exportsByName)\n }\n } else if (declaration.declaration.type === 'VariableDeclaration') {\n declaration.declaration.declarations.forEach((declarator) => {\n if (declarator.id.type === 'Identifier') {\n addExportBinding(\n declarator.id.name,\n declarator.id.name,\n symbolsByName,\n exportsByName,\n )\n }\n })\n }\n\n return\n }\n\n if (declaration.source !== null) {\n return\n }\n\n declaration.specifiers.forEach((specifier) => {\n if (specifier.exportKind === 'type') {\n return\n }\n\n const localName = toModuleExportName(specifier.local)\n const exportedName = toModuleExportName(specifier.exported)\n addExportBinding(localName, exportedName, symbolsByName, exportsByName)\n })\n}\n\nfunction collectDefaultExport(\n declaration: ExportDefaultDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n const localName = declaration.declaration.id?.name\n if (localName !== undefined) {\n addExportBinding(localName, 'default', symbolsByName, exportsByName)\n }\n return\n }\n\n if (declaration.declaration.type === 'Identifier') {\n addExportBinding(\n declaration.declaration.name,\n 'default',\n symbolsByName,\n exportsByName,\n )\n return\n }\n\n if (declaration.declaration.type === 'ArrowFunctionExpression') {\n addExportBinding('default', 'default', symbolsByName, exportsByName)\n }\n}\n\nfunction addExportBinding(\n localName: string,\n exportedName: string,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n const symbol = symbolsByName.get(localName)\n if (symbol === undefined) {\n return\n }\n\n symbol.exportNames.add(exportedName)\n exportsByName.set(exportedName, symbol.id)\n}\n\nfunction analyzeSymbolUsages(symbol: PendingReactUsageNode): void {\n const root =\n symbol.declaration.type === 'ArrowFunctionExpression'\n ? symbol.declaration.body\n : symbol.declaration.body\n\n if (root === null) {\n return\n }\n\n walkReactUsageTree(root, (node) => {\n if (node.type === 'JSXElement') {\n const name = getComponentReferenceName(node)\n if (name !== undefined) {\n symbol.componentReferences.add(name)\n }\n return\n }\n\n if (node.type === 'CallExpression') {\n const hookReference = getHookReferenceName(node)\n if (hookReference !== undefined) {\n symbol.hookReferences.add(hookReference)\n }\n\n const componentReference = getCreateElementComponentReferenceName(node)\n if (componentReference !== undefined) {\n symbol.componentReferences.add(componentReference)\n }\n }\n })\n}\n\nfunction classifyReactSymbol(\n name: string,\n declaration: OxcFunction | ArrowFunctionExpression,\n): ReactSymbolKind | undefined {\n if (isHookName(name)) {\n return 'hook'\n }\n\n if (isComponentName(name) && returnsReactElement(declaration)) {\n return 'component'\n }\n\n return undefined\n}\n\nfunction returnsReactElement(\n declaration: OxcFunction | ArrowFunctionExpression,\n): boolean {\n if (\n declaration.type === 'ArrowFunctionExpression' &&\n declaration.expression\n ) {\n return containsReactElementLikeExpression(declaration.body as Expression)\n }\n\n const body = declaration.body\n if (body === null) {\n return false\n }\n\n let found = false\n walkReactUsageTree(body, (node) => {\n if (node.type !== 'ReturnStatement' || node.argument === null) {\n return\n }\n\n if (containsReactElementLikeExpression(node.argument)) {\n found = true\n }\n })\n\n return found\n}\n\nfunction containsReactElementLikeExpression(expression: Expression): boolean {\n let found = false\n\n walkNode(expression, (node) => {\n if (\n node.type === 'JSXElement' ||\n node.type === 'JSXFragment' ||\n (node.type === 'CallExpression' && isReactCreateElementCall(node))\n ) {\n found = true\n }\n })\n\n return found\n}\n\nfunction getComponentReferenceName(node: JSXElement): string | undefined {\n const name = getJsxName(node.openingElement.name)\n return name !== undefined && isComponentName(name) ? name : undefined\n}\n\nfunction getHookReferenceName(node: CallExpression): string | undefined {\n const calleeName = getIdentifierName(node.callee)\n return calleeName !== undefined && isHookName(calleeName)\n ? calleeName\n : undefined\n}\n\nfunction getCreateElementComponentReferenceName(\n node: CallExpression,\n): string | undefined {\n if (!isReactCreateElementCall(node)) {\n return undefined\n }\n\n const [firstArgument] = node.arguments\n if (firstArgument === undefined || firstArgument.type !== 'Identifier') {\n return undefined\n }\n\n return isComponentName(firstArgument.name) ? firstArgument.name : undefined\n}\n\nfunction isReactCreateElementCall(node: CallExpression): boolean {\n const callee = unwrapExpression(node.callee)\n if (callee.type !== 'MemberExpression' || callee.computed) {\n return false\n }\n\n return (\n callee.object.type === 'Identifier' &&\n callee.object.name === 'React' &&\n callee.property.name === 'createElement'\n )\n}\n\nfunction getJsxName(name: JSXElementName): string | undefined {\n if (name.type === 'JSXIdentifier') {\n return name.name\n }\n\n return undefined\n}\n\nfunction getIdentifierName(expression: Expression): string | undefined {\n const unwrapped = unwrapExpression(expression)\n return unwrapped.type === 'Identifier' ? unwrapped.name : undefined\n}\n\nfunction unwrapExpression(expression: Expression): Expression {\n let current = expression\n\n while (true) {\n if (\n current.type === 'ParenthesizedExpression' ||\n current.type === 'TSAsExpression' ||\n current.type === 'TSSatisfiesExpression' ||\n current.type === 'TSTypeAssertion' ||\n current.type === 'TSNonNullExpression'\n ) {\n current = current.expression\n continue\n }\n\n return current\n }\n}\n\nfunction walkReactUsageTree(\n root: FunctionBody | Expression | JSXFragment | JSXElement,\n visit: (node: Node) => void,\n): void {\n walkNode(root, visit, true)\n}\n\nfunction walkNode(\n node: Node,\n visit: (node: Node) => void,\n allowNestedFunctions = false,\n): void {\n visit(node)\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n walkChild(value, visit, allowNestedFunctions)\n })\n}\n\nfunction walkChild(\n value: unknown,\n visit: (node: Node) => void,\n allowNestedFunctions: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n walkChild(entry, visit, allowNestedFunctions)\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n if (!allowNestedFunctions && FUNCTION_NODE_TYPES.has(value.type)) {\n return\n }\n\n walkNode(value, visit, false)\n}\n\nfunction isNode(value: unknown): value is Node {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n typeof (value as { type: unknown }).type === 'string'\n )\n}\n\nfunction resolveReactReference(\n fileAnalysis: FileAnalysis,\n fileAnalyses: ReadonlyMap<string, FileAnalysis>,\n name: string,\n kind: ReactSymbolKind,\n): string | undefined {\n const localSymbol = fileAnalysis.symbolsByName.get(name)\n if (localSymbol !== undefined && localSymbol.kind === kind) {\n return localSymbol.id\n }\n\n const importBinding = fileAnalysis.importsByLocalName.get(name)\n if (importBinding === undefined) {\n return undefined\n }\n\n if (importBinding.sourcePath === undefined) {\n return kind === 'hook'\n ? getExternalHookNodeId(importBinding, name)\n : undefined\n }\n\n const sourceFileAnalysis = fileAnalyses.get(importBinding.sourcePath)\n if (sourceFileAnalysis === undefined) {\n return undefined\n }\n\n const targetId = sourceFileAnalysis.exportsByName.get(\n importBinding.importedName,\n )\n if (targetId === undefined) {\n return undefined\n }\n\n const targetSymbol = sourceFileAnalysis.symbolsById.get(targetId)\n return targetSymbol?.kind === kind ? targetId : undefined\n}\n\nfunction createExternalHookNode(\n binding: ImportBinding,\n localName: string,\n): ReactUsageNode {\n const name = getExternalHookName(binding, localName)\n\n return {\n id: getExternalHookNodeId(binding, localName),\n name,\n kind: 'hook',\n filePath: binding.sourceSpecifier,\n exportNames: [binding.importedName],\n usages: [],\n }\n}\n\nfunction getExternalHookNodeId(\n binding: ImportBinding,\n localName: string,\n): string {\n return `external:${binding.sourceSpecifier}#hook:${getExternalHookName(binding, localName)}`\n}\n\nfunction getExternalHookName(\n binding: ImportBinding,\n localName: string,\n): string {\n return binding.importedName === 'default' ? localName : binding.importedName\n}\n\nfunction getFilteredReactUsageNodes(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): ReactUsageNode[] {\n return [...graph.nodes.values()]\n .filter((node) => matchesReactFilter(node, filter))\n .sort((left, right) => compareReactNodes(left, right))\n}\n\nfunction matchesReactFilter(\n node: ReactUsageNode,\n filter: ReactUsageFilter,\n): boolean {\n return filter === 'all' || node.kind === filter\n}\n\nfunction serializeReactUsageNode(\n nodeId: string,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n visited: Set<string>,\n): SerializedReactUsageNode {\n const node = graph.nodes.get(nodeId)\n if (node === undefined) {\n return {\n id: nodeId,\n name: nodeId,\n symbolKind: 'circular',\n filePath: '',\n exportNames: [],\n usages: [],\n }\n }\n\n if (visited.has(nodeId)) {\n return {\n id: node.id,\n name: node.name,\n symbolKind: 'circular',\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: [],\n }\n }\n\n const nextVisited = new Set(visited)\n nextVisited.add(nodeId)\n\n return {\n id: node.id,\n name: node.name,\n symbolKind: node.kind,\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: getFilteredUsages(node, graph, filter).map((usage) => ({\n kind: usage.kind,\n targetId: usage.target,\n node: serializeReactUsageNode(usage.target, graph, filter, nextVisited),\n })),\n }\n}\n\nfunction compareReactNodeIds(\n leftId: string,\n rightId: string,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n const left = nodes.get(leftId)\n const right = nodes.get(rightId)\n\n if (left === undefined || right === undefined) {\n return leftId.localeCompare(rightId)\n }\n\n return compareReactNodes(left, right)\n}\n\nfunction compareReactNodes(\n left: ReactUsageNode,\n right: ReactUsageNode,\n): number {\n return (\n left.filePath.localeCompare(right.filePath) ||\n left.name.localeCompare(right.name) ||\n left.kind.localeCompare(right.kind)\n )\n}\n\nfunction toModuleExportName(name: ModuleExportName): string {\n return name.type === 'Literal' ? name.value : name.name\n}\n\nfunction isHookName(name: string): boolean {\n return /^use[A-Z0-9]/.test(name)\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name)\n}\n","import { toDisplayPath } from './path-utils.js'\nimport { getFilteredUsages, getReactUsageRoots } from './react-analyzer.js'\nimport type {\n PrintReactTreeOptions,\n ReactUsageEdge,\n ReactUsageGraph,\n ReactUsageNode,\n} from './types.js'\n\nexport function printReactUsageTree(\n graph: ReactUsageGraph,\n options: PrintReactTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const filter = options.filter ?? 'all'\n const roots = getReactUsageRoots(graph, filter)\n\n if (roots.length === 0) {\n return 'No React symbols found.'\n }\n\n const lines: string[] = []\n roots.forEach((rootId, index) => {\n const root = graph.nodes.get(rootId)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactNodeLabel(root, cwd))\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < roots.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderUsage(\n usage: ReactUsageEdge,\n graph: ReactUsageGraph,\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const target = graph.nodes.get(usage.target)\n\n if (target === undefined) {\n return [`${branch}${usage.target}`]\n }\n\n if (visited.has(target.id)) {\n return [`${branch}${formatReactNodeLabel(target, cwd)} (circular)`]\n }\n\n const childLines = [`${branch}${formatReactNodeLabel(target, cwd)}`]\n const nextVisited = new Set(visited)\n nextVisited.add(target.id)\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const childUsages = getFilteredUsages(target, graph, filter)\n\n childUsages.forEach((childUsage, index) => {\n childLines.push(\n ...renderUsage(\n childUsage,\n graph,\n cwd,\n filter,\n nextVisited,\n nextPrefix,\n index === childUsages.length - 1,\n ),\n )\n })\n\n return childLines\n}\n\nfunction formatReactNodeLabel(node: ReactUsageNode, cwd: string): string {\n return `${node.name} [${node.kind}] (${toDisplayPath(node.filePath, cwd)})`\n}\n","import { toDisplayPath } from './path-utils.js'\nimport type {\n DependencyEdge,\n DependencyGraph,\n PrintTreeOptions,\n} from './types.js'\n\nexport function printDependencyTree(\n graph: DependencyGraph,\n options: PrintTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const includeExternals = options.includeExternals ?? false\n const omitUnused = options.omitUnused ?? false\n const rootLines = [toDisplayPath(graph.entryId, cwd)]\n const visited = new Set<string>([graph.entryId])\n const entryNode = graph.nodes.get(graph.entryId)\n\n if (entryNode === undefined) {\n return rootLines.join('\\n')\n }\n\n const rootDependencies = filterDependencies(\n entryNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n rootDependencies.forEach((dependency, index) => {\n const isLast = index === rootDependencies.length - 1\n const lines = renderDependency(\n dependency,\n graph,\n visited,\n '',\n isLast,\n includeExternals,\n omitUnused,\n cwd,\n )\n rootLines.push(...lines)\n })\n\n return rootLines.join('\\n')\n}\n\nfunction renderDependency(\n dependency: DependencyEdge,\n graph: DependencyGraph,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n includeExternals: boolean,\n omitUnused: boolean,\n cwd: string,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const label = formatDependencyLabel(dependency, graph, cwd)\n\n if (dependency.kind !== 'source') {\n return [`${branch}${label}`]\n }\n\n if (visited.has(dependency.target)) {\n return [`${branch}${label} (circular)`]\n }\n\n const childNode = graph.nodes.get(dependency.target)\n if (childNode === undefined) {\n return [`${branch}${label}`]\n }\n\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const nextVisited = new Set(visited)\n nextVisited.add(dependency.target)\n\n const childLines = [`${branch}${label}`]\n const childDependencies = filterDependencies(\n childNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n childDependencies.forEach((childDependency, index) => {\n const isChildLast = index === childDependencies.length - 1\n childLines.push(\n ...renderDependency(\n childDependency,\n graph,\n nextVisited,\n nextPrefix,\n isChildLast,\n includeExternals,\n omitUnused,\n cwd,\n ),\n )\n })\n\n return childLines\n}\n\nfunction filterDependencies(\n dependencies: readonly DependencyEdge[],\n includeExternals: boolean,\n omitUnused: boolean,\n): DependencyEdge[] {\n return dependencies.filter((dependency) => {\n if (omitUnused && dependency.unused) {\n return false\n }\n\n if (dependency.kind === 'source' || dependency.kind === 'missing') {\n return true\n }\n\n return includeExternals\n })\n}\n\nfunction formatDependencyLabel(\n dependency: DependencyEdge,\n _graph: DependencyGraph,\n cwd: string,\n): string {\n const prefixes: string[] = []\n if (dependency.isTypeOnly) {\n prefixes.push('type')\n }\n\n if (dependency.referenceKind === 'require') {\n prefixes.push('require')\n } else if (dependency.referenceKind === 'dynamic-import') {\n prefixes.push('dynamic')\n } else if (dependency.referenceKind === 'export') {\n prefixes.push('re-export')\n } else if (dependency.referenceKind === 'import-equals') {\n prefixes.push('import=')\n }\n\n const annotation = prefixes.length > 0 ? `[${prefixes.join(', ')}] ` : ''\n\n if (dependency.kind === 'source') {\n return withUnusedSuffix(\n `${annotation}${toDisplayPath(dependency.target, cwd)}`,\n dependency.unused,\n )\n }\n\n if (dependency.kind === 'missing') {\n return withUnusedSuffix(\n `${annotation}${dependency.specifier} [missing]`,\n dependency.unused,\n )\n }\n\n if (dependency.kind === 'builtin') {\n return withUnusedSuffix(\n `${annotation}${dependency.target} [builtin]`,\n dependency.unused,\n )\n }\n\n return withUnusedSuffix(\n `${annotation}${dependency.target} [external]`,\n dependency.unused,\n )\n}\n\nfunction withUnusedSuffix(label: string, unused: boolean): string {\n return unused ? `${label} (unused)` : label\n}\n"],"mappings":"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"}
|