foresthouse 1.0.0-dev.3 → 1.0.0-dev.4

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 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-DbnWcUnV.mjs";
2
+ import { a as graphToSerializableReactTree, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-B5Q_Mgkq.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,8 +27,10 @@ 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';
34
36
  interface ReactUsageEdge {
@@ -51,6 +53,7 @@ interface ReactUsageGraph {
51
53
  interface PrintReactTreeOptions {
52
54
  readonly cwd?: string;
53
55
  readonly filter?: ReactUsageFilter;
56
+ readonly color?: ColorMode;
54
57
  }
55
58
  //#endregion
56
59
  //#region src/analyzer.d.ts
@@ -72,5 +75,5 @@ declare function printReactUsageTree(graph: ReactUsageGraph, options?: PrintReac
72
75
  //#region src/tree.d.ts
73
76
  declare function printDependencyTree(graph: DependencyGraph, options?: PrintTreeOptions): string;
74
77
  //#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 };
78
+ export { type AnalyzeOptions, type ColorMode, 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 };
76
79
  //# sourceMappingURL=index.d.mts.map
@@ -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,KAGC,eAAA;AAAA,KAEA,gBAAA,WAA2B,eAAA;AAAA,KAE3B,kBAAA;AAAA,UAEK,cAAA;EAAA,SACN,IAAA,EAAM,kBAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,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;AAAA;AAAA,UAGrB,qBAAA;EAAA,SACN,GAAA;EAAA,SACA,MAAA,GAAS,gBAAA;AAAA;;;iBCtCJ,mBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBA8Ba,uBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,UAAA;AAAA;;;iBCcG,iBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBAyHa,4BAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,MAAA,GAAS,gBAAA;AAAA;AAAA,iBAkBN,kBAAA,CACd,KAAA,EAAO,eAAA,EACP,MAAA,GAAQ,gBAAA;;;iBC3NM,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,qBAAA;;;iBCJK,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,gBAAA"}
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,cAAA;EAAA,SACN,IAAA,EAAM,kBAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,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;AAAA;AAAA,UAGrB,qBAAA;EAAA,SACN,GAAA;EAAA,SACA,MAAA,GAAS,gBAAA;EAAA,SACT,KAAA,GAAQ,SAAA;AAAA;;;iBC1CH,mBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBA8Ba,uBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,UAAA;AAAA;;;iBCcG,iBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBAyHa,4BAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,MAAA,GAAS,gBAAA;AAAA;AAAA,iBAkBN,kBAAA,CACd,KAAA,EAAO,eAAA,EACP,MAAA,GAAQ,gBAAA;;;iBC1NM,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,qBAAA;;;iBCJK,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-DbnWcUnV.mjs";
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-B5Q_Mgkq.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);
@@ -750,9 +751,33 @@ function isComponentName(name) {
750
751
  return /^[A-Z]/.test(name);
751
752
  }
752
753
  //#endregion
754
+ //#region src/color.ts
755
+ const ANSI_RESET = "\x1B[0m";
756
+ const ANSI_COMPONENT = "\x1B[36m";
757
+ const ANSI_HOOK = "\x1B[35m";
758
+ const ANSI_UNUSED = "\x1B[38;5;214m";
759
+ function resolveColorSupport(mode = "auto", options = {}) {
760
+ if (mode === true) return true;
761
+ if (mode === false) return false;
762
+ const forceColor = "forceColor" in options ? options.forceColor : process$1.env.FORCE_COLOR;
763
+ if (forceColor !== void 0) return forceColor !== "0";
764
+ if (("noColor" in options ? options.noColor : process$1.env.NO_COLOR) !== void 0) return false;
765
+ return ("isTTY" in options ? options.isTTY : process$1.stdout.isTTY) === true;
766
+ }
767
+ function colorizeUnusedMarker(text, enabled) {
768
+ if (!enabled) return text;
769
+ return text.replaceAll("(unused)", `${ANSI_UNUSED}(unused)${ANSI_RESET}`);
770
+ }
771
+ function formatReactSymbolLabel(name, kind, enabled) {
772
+ const label = `${name} [${kind}]`;
773
+ if (!enabled) return label;
774
+ return `${kind === "component" ? ANSI_COMPONENT : ANSI_HOOK}${label}${ANSI_RESET}`;
775
+ }
776
+ //#endregion
753
777
  //#region src/react-tree.ts
754
778
  function printReactUsageTree(graph, options = {}) {
755
779
  const cwd = options.cwd ?? graph.cwd;
780
+ const color = resolveColorSupport(options.color);
756
781
  const filter = options.filter ?? "all";
757
782
  const roots = getReactUsageRoots(graph, filter);
758
783
  if (roots.length === 0) return "No React symbols found.";
@@ -760,37 +785,38 @@ function printReactUsageTree(graph, options = {}) {
760
785
  roots.forEach((rootId, index) => {
761
786
  const root = graph.nodes.get(rootId);
762
787
  if (root === void 0) return;
763
- lines.push(formatReactNodeLabel(root, cwd));
788
+ lines.push(formatReactNodeLabel(root, cwd, color));
764
789
  const usages = getFilteredUsages(root, graph, filter);
765
790
  usages.forEach((usage, usageIndex) => {
766
- lines.push(...renderUsage(usage, graph, cwd, filter, new Set([root.id]), "", usageIndex === usages.length - 1));
791
+ lines.push(...renderUsage(usage, graph, cwd, filter, color, new Set([root.id]), "", usageIndex === usages.length - 1));
767
792
  });
768
793
  if (index < roots.length - 1) lines.push("");
769
794
  });
770
795
  return lines.join("\n");
771
796
  }
772
- function renderUsage(usage, graph, cwd, filter, visited, prefix, isLast) {
797
+ function renderUsage(usage, graph, cwd, filter, color, visited, prefix, isLast) {
773
798
  const branch = `${prefix}${isLast ? "└─ " : "├─ "}`;
774
799
  const target = graph.nodes.get(usage.target);
775
800
  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)}`];
801
+ if (visited.has(target.id)) return [`${branch}${formatReactNodeLabel(target, cwd, color)} (circular)`];
802
+ const childLines = [`${branch}${formatReactNodeLabel(target, cwd, color)}`];
778
803
  const nextVisited = new Set(visited);
779
804
  nextVisited.add(target.id);
780
805
  const nextPrefix = `${prefix}${isLast ? " " : "│ "}`;
781
806
  const childUsages = getFilteredUsages(target, graph, filter);
782
807
  childUsages.forEach((childUsage, index) => {
783
- childLines.push(...renderUsage(childUsage, graph, cwd, filter, nextVisited, nextPrefix, index === childUsages.length - 1));
808
+ childLines.push(...renderUsage(childUsage, graph, cwd, filter, color, nextVisited, nextPrefix, index === childUsages.length - 1));
784
809
  });
785
810
  return childLines;
786
811
  }
787
- function formatReactNodeLabel(node, cwd) {
788
- return `${node.name} [${node.kind}] (${toDisplayPath(node.filePath, cwd)})`;
812
+ function formatReactNodeLabel(node, cwd, color) {
813
+ return `${formatReactSymbolLabel(node.name, node.kind, color)} (${toDisplayPath(node.filePath, cwd)})`;
789
814
  }
790
815
  //#endregion
791
816
  //#region src/tree.ts
792
817
  function printDependencyTree(graph, options = {}) {
793
818
  const cwd = options.cwd ?? graph.cwd;
819
+ const color = resolveColorSupport(options.color);
794
820
  const includeExternals = options.includeExternals ?? false;
795
821
  const omitUnused = options.omitUnused ?? false;
796
822
  const rootLines = [toDisplayPath(graph.entryId, cwd)];
@@ -799,14 +825,14 @@ function printDependencyTree(graph, options = {}) {
799
825
  if (entryNode === void 0) return rootLines.join("\n");
800
826
  const rootDependencies = filterDependencies(entryNode.dependencies, includeExternals, omitUnused);
801
827
  rootDependencies.forEach((dependency, index) => {
802
- const lines = renderDependency(dependency, graph, visited, "", index === rootDependencies.length - 1, includeExternals, omitUnused, cwd);
828
+ const lines = renderDependency(dependency, graph, visited, "", index === rootDependencies.length - 1, includeExternals, omitUnused, color, cwd);
803
829
  rootLines.push(...lines);
804
830
  });
805
831
  return rootLines.join("\n");
806
832
  }
807
- function renderDependency(dependency, graph, visited, prefix, isLast, includeExternals, omitUnused, cwd) {
833
+ function renderDependency(dependency, graph, visited, prefix, isLast, includeExternals, omitUnused, color, cwd) {
808
834
  const branch = `${prefix}${isLast ? "└─ " : "├─ "}`;
809
- const label = formatDependencyLabel(dependency, graph, cwd);
835
+ const label = formatDependencyLabel(dependency, cwd, color);
810
836
  if (dependency.kind !== "source") return [`${branch}${label}`];
811
837
  if (visited.has(dependency.target)) return [`${branch}${label} (circular)`];
812
838
  const childNode = graph.nodes.get(dependency.target);
@@ -818,7 +844,7 @@ function renderDependency(dependency, graph, visited, prefix, isLast, includeExt
818
844
  const childDependencies = filterDependencies(childNode.dependencies, includeExternals, omitUnused);
819
845
  childDependencies.forEach((childDependency, index) => {
820
846
  const isChildLast = index === childDependencies.length - 1;
821
- childLines.push(...renderDependency(childDependency, graph, nextVisited, nextPrefix, isChildLast, includeExternals, omitUnused, cwd));
847
+ childLines.push(...renderDependency(childDependency, graph, nextVisited, nextPrefix, isChildLast, includeExternals, omitUnused, color, cwd));
822
848
  });
823
849
  return childLines;
824
850
  }
@@ -829,7 +855,7 @@ function filterDependencies(dependencies, includeExternals, omitUnused) {
829
855
  return includeExternals;
830
856
  });
831
857
  }
832
- function formatDependencyLabel(dependency, _graph, cwd) {
858
+ function formatDependencyLabel(dependency, cwd, color) {
833
859
  const prefixes = [];
834
860
  if (dependency.isTypeOnly) prefixes.push("type");
835
861
  if (dependency.referenceKind === "require") prefixes.push("require");
@@ -837,10 +863,10 @@ function formatDependencyLabel(dependency, _graph, cwd) {
837
863
  else if (dependency.referenceKind === "export") prefixes.push("re-export");
838
864
  else if (dependency.referenceKind === "import-equals") prefixes.push("import=");
839
865
  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);
866
+ if (dependency.kind === "source") return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${toDisplayPath(dependency.target, cwd)}`, dependency.unused), color);
867
+ if (dependency.kind === "missing") return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${dependency.specifier} [missing]`, dependency.unused), color);
868
+ if (dependency.kind === "builtin") return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${dependency.target} [builtin]`, dependency.unused), color);
869
+ return colorizeUnusedMarker(withUnusedSuffix(`${annotation}${dependency.target} [external]`, dependency.unused), color);
844
870
  }
845
871
  function withUnusedSuffix(label, unused) {
846
872
  return unused ? `${label} (unused)` : label;
@@ -848,4 +874,4 @@ function withUnusedSuffix(label, unused) {
848
874
  //#endregion
849
875
  export { graphToSerializableReactTree as a, getReactUsageRoots as i, printReactUsageTree as n, analyzeDependencies as o, analyzeReactUsage as r, graphToSerializableTree as s, printDependencyTree as t };
850
876
 
851
- //# sourceMappingURL=tree-DbnWcUnV.mjs.map
877
+ //# sourceMappingURL=tree-B5Q_Mgkq.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree-B5Q_Mgkq.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 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 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 { 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 color = resolveColorSupport(options.color)\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, 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 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","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,6 +1,6 @@
1
1
  {
2
2
  "name": "foresthouse",
3
- "version": "1.0.0-dev.3",
3
+ "version": "1.0.0-dev.4",
4
4
  "description": "A Node.js CLI that reads JavaScript and TypeScript entry files and prints an import tree.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.32.1",
@@ -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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"}