foresthouse 1.0.0-dev.5 → 1.0.0-dev.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as graphToSerializableReactTree, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-
|
|
2
|
+
import { a as graphToSerializableReactTree, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-BX1YFcqX.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.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/react-tree.ts","../src/tree.ts"],"mappings":";KAAY,cAAA;AAAA,KAEA,aAAA;AAAA,UAOK,cAAA;EAAA,SACN,SAAA;EAAA,SACA,aAAA,EAAe,aAAA;EAAA,SACf,UAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA,EAAM,cAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,EAAA;EAAA,SACA,YAAA,WAAuB,cAAA;AAAA;AAAA,UAGjB,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,gBAAA;EAAA,SAC3B,UAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,GAAA;EAAA,SACA,UAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,GAAA;EAAA,SACA,gBAAA;EAAA,SACA,UAAA;EAAA,SACA,KAAA,GAAQ,SAAA;AAAA;AAAA,KAGP,eAAA;AAAA,KAEA,SAAA;AAAA,KAEA,gBAAA,WAA2B,eAAA;AAAA,KAE3B,kBAAA;AAAA,UAEK,kBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,IAAA,EAAM,kBAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,eAAA;EAAA,SACN,MAAA;EAAA,SACA,QAAA,EAAU,kBAAA;AAAA;AAAA,UAGJ,cAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA,EAAM,eAAA;EAAA,SACN,QAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA,WAAiB,cAAA;AAAA;AAAA,UAGX,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,cAAA;EAAA,SAC3B,OAAA,WAAkB,eAAA;AAAA;AAAA,UAGZ,qBAAA;EAAA,SACN,GAAA;EAAA,SACA,MAAA,GAAS,gBAAA;EAAA,SACT,KAAA,GAAQ,SAAA;AAAA;;;iBCtDH,mBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBA8Ba,uBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,UAAA;AAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/react-tree.ts","../src/tree.ts"],"mappings":";KAAY,cAAA;AAAA,KAEA,aAAA;AAAA,UAOK,cAAA;EAAA,SACN,SAAA;EAAA,SACA,aAAA,EAAe,aAAA;EAAA,SACf,UAAA;EAAA,SACA,MAAA;EAAA,SACA,IAAA,EAAM,cAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,EAAA;EAAA,SACA,YAAA,WAAuB,cAAA;AAAA;AAAA,UAGjB,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,gBAAA;EAAA,SAC3B,UAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,GAAA;EAAA,SACA,UAAA;AAAA;AAAA,UAGM,gBAAA;EAAA,SACN,GAAA;EAAA,SACA,gBAAA;EAAA,SACA,UAAA;EAAA,SACA,KAAA,GAAQ,SAAA;AAAA;AAAA,KAGP,eAAA;AAAA,KAEA,SAAA;AAAA,KAEA,gBAAA,WAA2B,eAAA;AAAA,KAE3B,kBAAA;AAAA,UAEK,kBAAA;EAAA,SACN,QAAA;EAAA,SACA,IAAA;EAAA,SACA,MAAA;AAAA;AAAA,UAGM,cAAA;EAAA,SACN,IAAA,EAAM,kBAAA;EAAA,SACN,MAAA;AAAA;AAAA,UAGM,eAAA;EAAA,SACN,MAAA;EAAA,SACA,QAAA,EAAU,kBAAA;AAAA;AAAA,UAGJ,cAAA;EAAA,SACN,EAAA;EAAA,SACA,IAAA;EAAA,SACA,IAAA,EAAM,eAAA;EAAA,SACN,QAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA,WAAiB,cAAA;AAAA;AAAA,UAGX,eAAA;EAAA,SACN,GAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA,EAAO,WAAA,SAAoB,cAAA;EAAA,SAC3B,OAAA,WAAkB,eAAA;AAAA;AAAA,UAGZ,qBAAA;EAAA,SACN,GAAA;EAAA,SACA,MAAA,GAAS,gBAAA;EAAA,SACT,KAAA,GAAQ,SAAA;AAAA;;;iBCtDH,mBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBA8Ba,uBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,UAAA;AAAA;;;iBC+BG,iBAAA,CACd,SAAA,UACA,OAAA,GAAS,cAAA,GACR,eAAA;AAAA,iBAyJa,4BAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA;EAAA,SACW,MAAA,GAAS,gBAAA;AAAA;AAAA,iBAiCN,kBAAA,CACd,KAAA,EAAO,eAAA,EACP,MAAA,GAAQ,gBAAA;;;iBCrRM,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,qBAAA;;;iBCTK,mBAAA,CACd,KAAA,EAAO,eAAA,EACP,OAAA,GAAS,gBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as graphToSerializableReactTree, i as getReactUsageRoots, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-
|
|
1
|
+
import { a as graphToSerializableReactTree, i as getReactUsageRoots, n as printReactUsageTree, o as analyzeDependencies, r as analyzeReactUsage, s as graphToSerializableTree, t as printDependencyTree } from "./tree-BX1YFcqX.mjs";
|
|
2
2
|
export { analyzeDependencies, analyzeReactUsage, getReactUsageRoots, graphToSerializableReactTree, graphToSerializableTree, printDependencyTree, printReactUsageTree };
|
|
@@ -335,7 +335,7 @@ function analyzeReactUsage(entryFile, options = {}) {
|
|
|
335
335
|
dependencyNode?.dependencies.forEach((dependency) => {
|
|
336
336
|
if (dependency.kind === "source") sourceDependencies.set(dependency.specifier, dependency.target);
|
|
337
337
|
});
|
|
338
|
-
fileAnalyses.set(filePath, analyzeReactFile(parseResult.program, filePath, sourceText, sourceDependencies));
|
|
338
|
+
fileAnalyses.set(filePath, analyzeReactFile(parseResult.program, filePath, sourceText, filePath === dependencyGraph.entryId, sourceDependencies));
|
|
339
339
|
}
|
|
340
340
|
const nodes = /* @__PURE__ */ new Map();
|
|
341
341
|
for (const fileAnalysis of fileAnalyses.values()) for (const symbol of fileAnalysis.symbolsById.values()) nodes.set(symbol.id, {
|
|
@@ -377,8 +377,8 @@ function analyzeReactUsage(entryFile, options = {}) {
|
|
|
377
377
|
});
|
|
378
378
|
}
|
|
379
379
|
const entriesByKey = /* @__PURE__ */ new Map();
|
|
380
|
-
for (const fileAnalysis of fileAnalyses.values()) for (const entry of fileAnalysis.
|
|
381
|
-
const targetId = resolveReactReference(fileAnalysis, fileAnalyses, entry.referenceName,
|
|
380
|
+
for (const fileAnalysis of fileAnalyses.values()) for (const entry of fileAnalysis.entryUsages) {
|
|
381
|
+
const targetId = resolveReactReference(fileAnalysis, fileAnalyses, entry.referenceName, entry.kind);
|
|
382
382
|
if (targetId === void 0) continue;
|
|
383
383
|
const key = `${entry.location.filePath}:${entry.location.line}:${entry.location.column}:${targetId}`;
|
|
384
384
|
entriesByKey.set(key, {
|
|
@@ -405,7 +405,6 @@ function graphToSerializableReactTree(graph, options = {}) {
|
|
|
405
405
|
};
|
|
406
406
|
}
|
|
407
407
|
function getReactUsageEntries(graph, filter = "all") {
|
|
408
|
-
if (filter === "hook") return [];
|
|
409
408
|
return graph.entries.filter((entry) => {
|
|
410
409
|
const targetNode = graph.nodes.get(entry.target);
|
|
411
410
|
return targetNode !== void 0 && matchesReactFilter(targetNode, filter);
|
|
@@ -434,14 +433,14 @@ function getFilteredUsages(node, graph, filter = "all") {
|
|
|
434
433
|
return targetNode !== void 0 && matchesReactFilter(targetNode, filter);
|
|
435
434
|
});
|
|
436
435
|
}
|
|
437
|
-
function analyzeReactFile(program, filePath, sourceText, sourceDependencies) {
|
|
436
|
+
function analyzeReactFile(program, filePath, sourceText, includeNestedRenderEntries, sourceDependencies) {
|
|
438
437
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
439
438
|
program.body.forEach((statement) => {
|
|
440
439
|
collectTopLevelReactSymbols(statement, filePath, symbolsByName);
|
|
441
440
|
});
|
|
442
441
|
const importsByLocalName = /* @__PURE__ */ new Map();
|
|
443
442
|
const exportsByName = /* @__PURE__ */ new Map();
|
|
444
|
-
const
|
|
443
|
+
const entryUsages = collectEntryUsages(program, filePath, sourceText, includeNestedRenderEntries);
|
|
445
444
|
program.body.forEach((statement) => {
|
|
446
445
|
collectImportsAndExports(statement, sourceDependencies, symbolsByName, importsByLocalName, exportsByName);
|
|
447
446
|
});
|
|
@@ -452,34 +451,36 @@ function analyzeReactFile(program, filePath, sourceText, sourceDependencies) {
|
|
|
452
451
|
filePath,
|
|
453
452
|
importsByLocalName,
|
|
454
453
|
exportsByName,
|
|
455
|
-
|
|
454
|
+
entryUsages,
|
|
456
455
|
symbolsById: new Map([...symbolsByName.values()].map((symbol) => [symbol.id, symbol])),
|
|
457
456
|
symbolsByName
|
|
458
457
|
};
|
|
459
458
|
}
|
|
460
|
-
function
|
|
459
|
+
function collectEntryUsages(program, filePath, sourceText, includeNestedFunctions) {
|
|
461
460
|
const entries = /* @__PURE__ */ new Map();
|
|
462
461
|
program.body.forEach((statement) => {
|
|
463
|
-
|
|
462
|
+
collectStatementEntryUsages(statement, filePath, sourceText, entries, includeNestedFunctions);
|
|
464
463
|
});
|
|
465
464
|
return [...entries.values()].sort(comparePendingReactUsageEntries);
|
|
466
465
|
}
|
|
467
|
-
function
|
|
468
|
-
|
|
466
|
+
function collectStatementEntryUsages(statement, filePath, sourceText, entries, includeNestedFunctions) {
|
|
467
|
+
collectNodeEntryUsages(statement, filePath, sourceText, entries, false, includeNestedFunctions);
|
|
469
468
|
}
|
|
470
|
-
function
|
|
471
|
-
if (FUNCTION_NODE_TYPES.has(node.type)) return;
|
|
469
|
+
function collectNodeEntryUsages(node, filePath, sourceText, entries, hasComponentAncestor, includeNestedFunctions) {
|
|
470
|
+
if (!includeNestedFunctions && FUNCTION_NODE_TYPES.has(node.type)) return;
|
|
472
471
|
let nextHasComponentAncestor = hasComponentAncestor;
|
|
473
472
|
if (node.type === "JSXElement") {
|
|
474
473
|
const referenceName = getComponentReferenceName(node);
|
|
475
474
|
if (referenceName !== void 0) {
|
|
476
|
-
if (!hasComponentAncestor)
|
|
475
|
+
if (!hasComponentAncestor) addPendingReactUsageEntry(entries, referenceName, "component", createReactUsageLocation(filePath, sourceText, node.start));
|
|
477
476
|
nextHasComponentAncestor = true;
|
|
478
477
|
}
|
|
479
478
|
} else if (node.type === "CallExpression") {
|
|
479
|
+
const hookReference = getHookReferenceName(node);
|
|
480
|
+
if (hookReference !== void 0) addPendingReactUsageEntry(entries, hookReference, "hook", createReactUsageLocation(filePath, sourceText, node.start));
|
|
480
481
|
const referenceName = getCreateElementComponentReferenceName(node);
|
|
481
482
|
if (referenceName !== void 0) {
|
|
482
|
-
if (!hasComponentAncestor)
|
|
483
|
+
if (!hasComponentAncestor) addPendingReactUsageEntry(entries, referenceName, "component", createReactUsageLocation(filePath, sourceText, node.start));
|
|
483
484
|
nextHasComponentAncestor = true;
|
|
484
485
|
}
|
|
485
486
|
}
|
|
@@ -487,23 +488,24 @@ function collectNodeRenderEntries(node, filePath, sourceText, entries, hasCompon
|
|
|
487
488
|
if (keys === void 0) return;
|
|
488
489
|
keys.forEach((key) => {
|
|
489
490
|
const value = node[key];
|
|
490
|
-
|
|
491
|
+
collectEntryUsageChild(value, filePath, sourceText, entries, nextHasComponentAncestor, includeNestedFunctions);
|
|
491
492
|
});
|
|
492
493
|
}
|
|
493
|
-
function
|
|
494
|
+
function collectEntryUsageChild(value, filePath, sourceText, entries, hasComponentAncestor, includeNestedFunctions) {
|
|
494
495
|
if (Array.isArray(value)) {
|
|
495
496
|
value.forEach((entry) => {
|
|
496
|
-
|
|
497
|
+
collectEntryUsageChild(entry, filePath, sourceText, entries, hasComponentAncestor, includeNestedFunctions);
|
|
497
498
|
});
|
|
498
499
|
return;
|
|
499
500
|
}
|
|
500
501
|
if (!isNode(value)) return;
|
|
501
|
-
|
|
502
|
+
collectNodeEntryUsages(value, filePath, sourceText, entries, hasComponentAncestor, includeNestedFunctions);
|
|
502
503
|
}
|
|
503
|
-
function
|
|
504
|
-
const key = `${location.filePath}:${location.line}:${location.column}:${referenceName}`;
|
|
504
|
+
function addPendingReactUsageEntry(entries, referenceName, kind, location) {
|
|
505
|
+
const key = `${location.filePath}:${location.line}:${location.column}:${kind}:${referenceName}`;
|
|
505
506
|
entries.set(key, {
|
|
506
507
|
referenceName,
|
|
508
|
+
kind,
|
|
507
509
|
location
|
|
508
510
|
});
|
|
509
511
|
}
|
|
@@ -851,7 +853,7 @@ function compareReactUsageEntries(left, right, nodes) {
|
|
|
851
853
|
return left.location.filePath.localeCompare(right.location.filePath) || left.location.line - right.location.line || left.location.column - right.location.column || compareReactNodeIds(left.target, right.target, nodes);
|
|
852
854
|
}
|
|
853
855
|
function comparePendingReactUsageEntries(left, right) {
|
|
854
|
-
return left.location.filePath.localeCompare(right.location.filePath) || left.location.line - right.location.line || left.location.column - right.location.column || left.referenceName.localeCompare(right.referenceName);
|
|
856
|
+
return left.location.filePath.localeCompare(right.location.filePath) || left.location.line - right.location.line || left.location.column - right.location.column || left.kind.localeCompare(right.kind) || left.referenceName.localeCompare(right.referenceName);
|
|
855
857
|
}
|
|
856
858
|
function compareReactNodes(left, right) {
|
|
857
859
|
return left.filePath.localeCompare(right.filePath) || left.name.localeCompare(right.name) || left.kind.localeCompare(right.kind);
|
|
@@ -1009,4 +1011,4 @@ function withUnusedSuffix(label, unused) {
|
|
|
1009
1011
|
//#endregion
|
|
1010
1012
|
export { graphToSerializableReactTree as a, getReactUsageRoots as i, printReactUsageTree as n, analyzeDependencies as o, analyzeReactUsage as r, graphToSerializableTree as s, printDependencyTree as t };
|
|
1011
1013
|
|
|
1012
|
-
//# sourceMappingURL=tree-
|
|
1014
|
+
//# sourceMappingURL=tree-BX1YFcqX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-BX1YFcqX.mjs","names":["process"],"sources":["../src/config.ts","../src/path-utils.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/color.ts","../src/react-tree.ts","../src/tree.ts"],"sourcesContent":["import path from 'node:path'\nimport ts from 'typescript'\n\nexport interface LoadedConfig {\n readonly path?: string\n readonly compilerOptions: ts.CompilerOptions\n}\n\nexport function loadCompilerOptions(\n searchFrom: string,\n explicitConfigPath?: string,\n): LoadedConfig {\n const configPath =\n explicitConfigPath === undefined\n ? findNearestConfig(searchFrom)\n : path.resolve(searchFrom, explicitConfigPath)\n\n if (configPath === undefined) {\n return {\n compilerOptions: defaultCompilerOptions(),\n }\n }\n\n const readResult = ts.readConfigFile(configPath, ts.sys.readFile)\n if (readResult.error !== undefined) {\n throw new Error(\n `Failed to read TypeScript config at ${configPath}: ${formatDiagnostic(\n readResult.error,\n )}`,\n )\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n readResult.config,\n ts.sys,\n path.dirname(configPath),\n defaultCompilerOptions(),\n configPath,\n )\n\n if (parsed.errors.length > 0) {\n const [firstError] = parsed.errors\n if (firstError === undefined) {\n throw new Error(`Failed to parse TypeScript config at ${configPath}.`)\n }\n\n throw new Error(\n `Failed to parse TypeScript config at ${configPath}: ${formatDiagnostic(\n firstError,\n )}`,\n )\n }\n\n return {\n path: configPath,\n compilerOptions: parsed.options,\n }\n}\n\nfunction findNearestConfig(searchFrom: string): string | undefined {\n let currentDirectory = path.resolve(searchFrom)\n\n while (true) {\n const tsconfigPath = path.join(currentDirectory, 'tsconfig.json')\n if (ts.sys.fileExists(tsconfigPath)) {\n return tsconfigPath\n }\n\n const jsconfigPath = path.join(currentDirectory, 'jsconfig.json')\n if (ts.sys.fileExists(jsconfigPath)) {\n return jsconfigPath\n }\n\n const parentDirectory = path.dirname(currentDirectory)\n if (parentDirectory === currentDirectory) {\n return undefined\n }\n\n currentDirectory = parentDirectory\n }\n}\n\nfunction defaultCompilerOptions(): ts.CompilerOptions {\n return {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n target: ts.ScriptTarget.ESNext,\n resolveJsonModule: true,\n esModuleInterop: true,\n }\n}\n\nfunction formatDiagnostic(diagnostic: ts.Diagnostic): string {\n return ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')\n}\n","import path from 'node:path'\n\nexport const SOURCE_EXTENSIONS = new Set([\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n])\n\nexport function normalizeFilePath(filePath: string): string {\n return path.normalize(filePath)\n}\n\nexport function toDisplayPath(filePath: string, cwd: string): string {\n const relativePath = path.relative(cwd, filePath)\n if (relativePath === '') {\n return '.'\n }\n\n const normalizedPath = relativePath.split(path.sep).join('/')\n return normalizedPath.startsWith('..') ? filePath : normalizedPath\n}\n\nexport function isSourceCodeFile(filePath: string): boolean {\n return SOURCE_EXTENSIONS.has(path.extname(filePath).toLowerCase())\n}\n","import fs from 'node:fs'\nimport { builtinModules } from 'node:module'\nimport path from 'node:path'\nimport ts from 'typescript'\n\nimport { loadCompilerOptions } from './config.js'\nimport {\n isSourceCodeFile,\n normalizeFilePath,\n toDisplayPath,\n} from './path-utils.js'\nimport type {\n AnalyzeOptions,\n DependencyEdge,\n DependencyGraph,\n DependencyKind,\n ReferenceKind,\n SourceModuleNode,\n} from './types.js'\n\ninterface ModuleReference {\n readonly specifier: string\n readonly referenceKind: ReferenceKind\n readonly isTypeOnly: boolean\n readonly unused: boolean\n}\n\nconst BUILTIN_MODULES = new Set(\n builtinModules.flatMap((name) => [name, `node:${name}`]),\n)\n\nexport function analyzeDependencies(\n entryFile: string,\n options: AnalyzeOptions = {},\n): DependencyGraph {\n const cwd = path.resolve(options.cwd ?? process.cwd())\n const resolvedEntryPath = resolveExistingPath(cwd, entryFile)\n const { compilerOptions, path: configPath } = loadCompilerOptions(\n path.dirname(resolvedEntryPath),\n options.configPath,\n )\n\n const host: ts.ModuleResolutionHost = {\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n directoryExists: ts.sys.directoryExists,\n getCurrentDirectory: () => cwd,\n getDirectories: ts.sys.getDirectories,\n ...(ts.sys.realpath === undefined ? {} : { realpath: ts.sys.realpath }),\n }\n\n const nodes = new Map<string, SourceModuleNode>()\n const program = createProgram(resolvedEntryPath, compilerOptions, cwd)\n const checker = program.getTypeChecker()\n visitFile(resolvedEntryPath, compilerOptions, host, checker, program, nodes)\n\n return {\n cwd,\n entryId: resolvedEntryPath,\n nodes,\n ...(configPath === undefined ? {} : { configPath }),\n }\n}\n\nexport function graphToSerializableTree(\n graph: DependencyGraph,\n options: {\n readonly omitUnused?: boolean\n } = {},\n): object {\n const visited = new Set<string>()\n return serializeNode(\n graph.entryId,\n graph,\n visited,\n options.omitUnused ?? false,\n )\n}\n\nfunction serializeNode(\n filePath: string,\n graph: DependencyGraph,\n visited: Set<string>,\n omitUnused: boolean,\n): object {\n const node = graph.nodes.get(filePath)\n const displayPath = toDisplayPath(filePath, graph.cwd)\n\n if (node === undefined) {\n return {\n path: displayPath,\n kind: 'missing',\n dependencies: [],\n }\n }\n\n if (visited.has(filePath)) {\n return {\n path: displayPath,\n kind: 'circular',\n dependencies: [],\n }\n }\n\n visited.add(filePath)\n\n const dependencies = node.dependencies\n .filter((dependency) => !omitUnused || !dependency.unused)\n .map((dependency) => {\n if (dependency.kind !== 'source') {\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target:\n dependency.kind === 'missing'\n ? dependency.target\n : toDisplayPath(dependency.target, graph.cwd),\n }\n }\n\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target: toDisplayPath(dependency.target, graph.cwd),\n node: serializeNode(\n dependency.target,\n graph,\n new Set(visited),\n omitUnused,\n ),\n }\n })\n\n return {\n path: displayPath,\n kind: filePath === graph.entryId ? 'entry' : 'source',\n dependencies,\n }\n}\n\nfunction visitFile(\n filePath: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n checker: ts.TypeChecker,\n program: ts.Program,\n nodes: Map<string, SourceModuleNode>,\n): void {\n const normalizedPath = normalizeFilePath(filePath)\n if (nodes.has(normalizedPath)) {\n return\n }\n\n const sourceFile =\n program.getSourceFile(normalizedPath) ?? createSourceFile(normalizedPath)\n\n const references = collectModuleReferences(sourceFile, checker)\n const dependencies = references.map((reference) =>\n resolveDependency(reference, normalizedPath, compilerOptions, host),\n )\n\n nodes.set(normalizedPath, {\n id: normalizedPath,\n dependencies,\n })\n\n for (const dependency of dependencies) {\n if (dependency.kind === 'source') {\n visitFile(\n dependency.target,\n compilerOptions,\n host,\n checker,\n program,\n nodes,\n )\n }\n }\n}\n\nfunction collectModuleReferences(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ModuleReference[] {\n const references = new Map<string, ModuleReference>()\n const unusedImports = collectUnusedImports(sourceFile, checker)\n\n function addReference(\n specifier: string,\n referenceKind: ReferenceKind,\n isTypeOnly: boolean,\n unused: boolean,\n ): void {\n const key = `${referenceKind}:${isTypeOnly ? 'type' : 'value'}:${specifier}`\n const existing = references.get(key)\n if (existing !== undefined) {\n if (existing.unused && !unused) {\n references.set(key, {\n ...existing,\n unused: false,\n })\n }\n return\n }\n\n references.set(key, {\n specifier,\n referenceKind,\n isTypeOnly,\n unused,\n })\n }\n\n function visit(node: ts.Node): void {\n if (\n ts.isImportDeclaration(node) &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'import',\n node.importClause?.isTypeOnly ?? false,\n unusedImports.get(node) ?? false,\n )\n } else if (\n ts.isExportDeclaration(node) &&\n node.moduleSpecifier !== undefined &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'export',\n node.isTypeOnly ?? false,\n false,\n )\n } else if (ts.isImportEqualsDeclaration(node)) {\n const moduleReference = node.moduleReference\n if (\n ts.isExternalModuleReference(moduleReference) &&\n moduleReference.expression !== undefined &&\n ts.isStringLiteralLike(moduleReference.expression)\n ) {\n addReference(\n moduleReference.expression.text,\n 'import-equals',\n false,\n false,\n )\n }\n } else if (ts.isCallExpression(node)) {\n if (\n node.expression.kind === ts.SyntaxKind.ImportKeyword &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'dynamic-import', false, false)\n }\n }\n\n if (\n ts.isIdentifier(node.expression) &&\n node.expression.text === 'require' &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'require', false, false)\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n return [...references.values()]\n}\n\nfunction resolveDependency(\n reference: ModuleReference,\n containingFile: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n): DependencyEdge {\n const specifier = reference.specifier\n if (BUILTIN_MODULES.has(specifier)) {\n return createEdge(reference, 'builtin', specifier)\n }\n\n const resolution = ts.resolveModuleName(\n specifier,\n containingFile,\n compilerOptions,\n host,\n ).resolvedModule\n\n if (resolution !== undefined) {\n const resolvedPath = normalizeFilePath(resolution.resolvedFileName)\n if (\n resolution.isExternalLibraryImport ||\n resolvedPath.includes(`${path.sep}node_modules${path.sep}`)\n ) {\n return createEdge(reference, 'external', specifier)\n }\n\n if (isSourceCodeFile(resolvedPath) && !resolvedPath.endsWith('.d.ts')) {\n return createEdge(reference, 'source', resolvedPath)\n }\n }\n\n if (!specifier.startsWith('.') && !path.isAbsolute(specifier)) {\n return createEdge(reference, 'external', specifier)\n }\n\n return createEdge(reference, 'missing', specifier)\n}\n\nfunction createEdge(\n reference: ModuleReference,\n kind: DependencyKind,\n target: string,\n): DependencyEdge {\n return {\n specifier: reference.specifier,\n referenceKind: reference.referenceKind,\n isTypeOnly: reference.isTypeOnly,\n unused: reference.unused,\n kind,\n target,\n }\n}\n\nfunction createProgram(\n entryFile: string,\n compilerOptions: ts.CompilerOptions,\n cwd: string,\n): ts.Program {\n const host = ts.createCompilerHost(compilerOptions, true)\n host.getCurrentDirectory = () => cwd\n\n if (ts.sys.realpath !== undefined) {\n host.realpath = ts.sys.realpath\n }\n\n return ts.createProgram({\n rootNames: [entryFile],\n options: compilerOptions,\n host,\n })\n}\n\nfunction createSourceFile(filePath: string): ts.SourceFile {\n const sourceText = fs.readFileSync(filePath, 'utf8')\n return ts.createSourceFile(\n filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n getScriptKind(filePath),\n )\n}\n\nfunction collectUnusedImports(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ReadonlyMap<ts.ImportDeclaration, boolean> {\n const importUsage = new Map<\n ts.ImportDeclaration,\n {\n canTrack: boolean\n used: boolean\n }\n >()\n const symbolToImportDeclaration = new Map<ts.Symbol, ts.ImportDeclaration>()\n const importedLocalNames = new Set<string>()\n\n sourceFile.statements.forEach((statement) => {\n if (\n !ts.isImportDeclaration(statement) ||\n statement.importClause === undefined\n ) {\n return\n }\n\n const identifiers = getImportBindingIdentifiers(statement.importClause)\n if (identifiers.length === 0) {\n return\n }\n\n importUsage.set(statement, {\n canTrack: false,\n used: false,\n })\n\n identifiers.forEach((identifier) => {\n importedLocalNames.add(identifier.text)\n\n const symbol = tryGetSymbolAtLocation(checker, identifier)\n if (symbol === undefined) {\n return\n }\n\n symbolToImportDeclaration.set(symbol, statement)\n const state = importUsage.get(statement)\n if (state !== undefined) {\n state.canTrack = true\n }\n })\n })\n\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node)) {\n return\n }\n\n if (\n ts.isIdentifier(node) &&\n importedLocalNames.has(node.text) &&\n isReferenceIdentifier(node)\n ) {\n const symbol = tryGetSymbolAtLocation(checker, node)\n const declaration =\n symbol === undefined ? undefined : symbolToImportDeclaration.get(symbol)\n if (declaration !== undefined) {\n const state = importUsage.get(declaration)\n if (state !== undefined) {\n state.used = true\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n\n return new Map(\n [...importUsage.entries()].map(([declaration, state]) => [\n declaration,\n state.canTrack && !state.used,\n ]),\n )\n}\n\nfunction getImportBindingIdentifiers(\n importClause: ts.ImportClause,\n): ts.Identifier[] {\n const identifiers: ts.Identifier[] = []\n\n if (importClause.name !== undefined) {\n identifiers.push(importClause.name)\n }\n\n const namedBindings = importClause.namedBindings\n if (namedBindings === undefined) {\n return identifiers\n }\n\n if (ts.isNamespaceImport(namedBindings)) {\n identifiers.push(namedBindings.name)\n return identifiers\n }\n\n namedBindings.elements.forEach((element) => {\n identifiers.push(element.name)\n })\n\n return identifiers\n}\n\nfunction isReferenceIdentifier(node: ts.Identifier): boolean {\n const parent = node.parent\n\n if (ts.isPropertyAccessExpression(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isQualifiedName(parent) && parent.right === node) {\n return false\n }\n\n if (ts.isPropertyAssignment(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isBindingElement(parent) && parent.propertyName === node) {\n return false\n }\n\n if (ts.isJsxAttribute(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isExportSpecifier(parent)) {\n return parent.propertyName === node || parent.propertyName === undefined\n }\n\n return true\n}\n\nfunction tryGetSymbolAtLocation(\n checker: ts.TypeChecker,\n node: ts.Node,\n): ts.Symbol | undefined {\n try {\n return checker.getSymbolAtLocation(node)\n } catch {\n return undefined\n }\n}\n\nfunction getScriptKind(filePath: string): ts.ScriptKind {\n switch (path.extname(filePath).toLowerCase()) {\n case '.js':\n case '.mjs':\n case '.cjs':\n return ts.ScriptKind.JS\n case '.jsx':\n return ts.ScriptKind.JSX\n case '.tsx':\n return ts.ScriptKind.TSX\n case '.json':\n return ts.ScriptKind.JSON\n default:\n return ts.ScriptKind.TS\n }\n}\n\nfunction resolveExistingPath(cwd: string, entryFile: string): string {\n const absolutePath = path.resolve(cwd, entryFile)\n const normalizedPath = normalizeFilePath(absolutePath)\n\n if (!fs.existsSync(normalizedPath)) {\n throw new Error(`Entry file not found: ${entryFile}`)\n }\n\n if (!isSourceCodeFile(normalizedPath)) {\n throw new Error(`Entry file must be a JS/TS source file: ${entryFile}`)\n }\n\n return normalizedPath\n}\n","import fs from 'node:fs'\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ExportDefaultDeclaration,\n ExportNamedDeclaration,\n Expression,\n FunctionBody,\n ImportDeclaration,\n ImportDeclarationSpecifier,\n JSXElement,\n JSXElementName,\n JSXFragment,\n ModuleExportName,\n Node,\n Function as OxcFunction,\n Program,\n Statement,\n VariableDeclarator,\n} from 'oxc-parser'\nimport { parseSync, visitorKeys } from 'oxc-parser'\n\nimport { analyzeDependencies } from './analyzer.js'\nimport { isSourceCodeFile, toDisplayPath } from './path-utils.js'\nimport type {\n AnalyzeOptions,\n ReactSymbolKind,\n ReactUsageEdge,\n ReactUsageEntry,\n ReactUsageFilter,\n ReactUsageGraph,\n ReactUsageLocation,\n ReactUsageNode,\n} from './types.js'\n\ninterface PendingReactUsageNode {\n readonly id: string\n readonly name: string\n readonly kind: ReactSymbolKind\n readonly filePath: string\n readonly declaration: OxcFunction | ArrowFunctionExpression\n readonly exportNames: Set<string>\n readonly componentReferences: Set<string>\n readonly hookReferences: Set<string>\n}\n\ninterface PendingReactUsageEntry {\n readonly referenceName: string\n readonly kind: ReactSymbolKind\n readonly location: ReactUsageLocation\n}\n\ninterface ImportBinding {\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n}\n\ninterface FileAnalysis {\n readonly filePath: string\n readonly importsByLocalName: Map<string, ImportBinding>\n readonly exportsByName: Map<string, string>\n readonly entryUsages: readonly PendingReactUsageEntry[]\n readonly symbolsById: Map<string, PendingReactUsageNode>\n readonly symbolsByName: Map<string, PendingReactUsageNode>\n}\n\ninterface SerializedReactUsageNode {\n readonly id: string\n readonly name: string\n readonly symbolKind: ReactSymbolKind | 'circular'\n readonly filePath: string\n readonly exportNames: readonly string[]\n readonly usages: readonly SerializedReactUsageEdge[]\n}\n\ninterface SerializedReactUsageEntry {\n readonly targetId: string\n readonly filePath: string\n readonly line: number\n readonly column: number\n readonly node: SerializedReactUsageNode\n}\n\ninterface SerializedReactUsageEdge {\n readonly kind: ReactUsageEdge['kind']\n readonly targetId: string\n readonly node: SerializedReactUsageNode\n}\n\nconst FUNCTION_NODE_TYPES = new Set([\n 'FunctionDeclaration',\n 'FunctionExpression',\n 'ArrowFunctionExpression',\n 'TSDeclareFunction',\n 'TSEmptyBodyFunctionExpression',\n])\n\nexport function analyzeReactUsage(\n entryFile: string,\n options: AnalyzeOptions = {},\n): ReactUsageGraph {\n const dependencyGraph = analyzeDependencies(entryFile, options)\n const reachableFiles = new Set<string>([\n dependencyGraph.entryId,\n ...dependencyGraph.nodes.keys(),\n ])\n const fileAnalyses = new Map<string, FileAnalysis>()\n\n for (const filePath of [...reachableFiles].sort()) {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n continue\n }\n\n const sourceText = fs.readFileSync(filePath, 'utf8')\n const parseResult = parseSync(filePath, sourceText, {\n astType: 'ts',\n sourceType: 'unambiguous',\n })\n\n const dependencyNode = dependencyGraph.nodes.get(filePath)\n const sourceDependencies = new Map<string, string>()\n dependencyNode?.dependencies.forEach((dependency) => {\n if (dependency.kind === 'source') {\n sourceDependencies.set(dependency.specifier, dependency.target)\n }\n })\n\n fileAnalyses.set(\n filePath,\n analyzeReactFile(\n parseResult.program,\n filePath,\n sourceText,\n filePath === dependencyGraph.entryId,\n sourceDependencies,\n ),\n )\n }\n\n const nodes = new Map<string, ReactUsageNode>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n nodes.set(symbol.id, {\n id: symbol.id,\n name: symbol.name,\n kind: symbol.kind,\n filePath: symbol.filePath,\n exportNames: [...symbol.exportNames].sort(),\n usages: [],\n })\n }\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n fileAnalysis.importsByLocalName.forEach((binding, localName) => {\n if (binding.sourcePath !== undefined) {\n return\n }\n\n if (!isHookName(localName) && !isHookName(binding.importedName)) {\n return\n }\n\n const externalNode = createExternalHookNode(binding, localName)\n if (!nodes.has(externalNode.id)) {\n nodes.set(externalNode.id, externalNode)\n }\n })\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n const usages = new Map<string, ReactUsageEdge>()\n\n symbol.componentReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'component',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`render:${targetId}`, {\n kind: 'render',\n target: targetId,\n })\n }\n })\n\n symbol.hookReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'hook',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`hook:${targetId}`, {\n kind: 'hook-call',\n target: targetId,\n })\n }\n })\n\n const node = nodes.get(symbol.id)\n if (node === undefined) {\n continue\n }\n\n const sortedUsages = [...usages.values()].sort((left, right) =>\n compareReactNodeIds(left.target, right.target, nodes),\n )\n\n nodes.set(symbol.id, {\n ...node,\n usages: sortedUsages,\n })\n }\n }\n\n const entriesByKey = new Map<string, ReactUsageEntry>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const entry of fileAnalysis.entryUsages) {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n entry.referenceName,\n entry.kind,\n )\n if (targetId === undefined) {\n continue\n }\n\n const key = `${entry.location.filePath}:${entry.location.line}:${entry.location.column}:${targetId}`\n entriesByKey.set(key, {\n target: targetId,\n location: entry.location,\n })\n }\n }\n\n const entries = [...entriesByKey.values()].sort((left, right) =>\n compareReactUsageEntries(left, right, nodes),\n )\n\n return {\n cwd: dependencyGraph.cwd,\n entryId: dependencyGraph.entryId,\n nodes,\n entries,\n }\n}\n\nexport function graphToSerializableReactTree(\n graph: ReactUsageGraph,\n options: {\n readonly filter?: ReactUsageFilter\n } = {},\n): object {\n const filter = options.filter ?? 'all'\n const entries = getReactUsageEntries(graph, filter)\n const roots =\n entries.length > 0\n ? entries.map((entry) =>\n serializeReactUsageNode(entry.target, graph, filter, new Set()),\n )\n : getReactUsageRoots(graph, filter).map((rootId) =>\n serializeReactUsageNode(rootId, graph, filter, new Set()),\n )\n\n return {\n kind: 'react-usage',\n entries: entries.map((entry) =>\n serializeReactUsageEntry(entry, graph, filter),\n ),\n roots,\n }\n}\n\nexport function getReactUsageEntries(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEntry[] {\n return graph.entries.filter((entry) => {\n const targetNode = graph.nodes.get(entry.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nexport function getReactUsageRoots(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): string[] {\n const entries = getReactUsageEntries(graph, filter)\n if (entries.length > 0) {\n return [...new Set(entries.map((entry) => entry.target))]\n }\n\n const filteredNodes = getFilteredReactUsageNodes(graph, filter)\n const inboundCounts = new Map<string, number>()\n\n filteredNodes.forEach((node) => {\n inboundCounts.set(node.id, 0)\n })\n\n filteredNodes.forEach((node) => {\n getFilteredUsages(node, graph, filter).forEach((usage) => {\n inboundCounts.set(\n usage.target,\n (inboundCounts.get(usage.target) ?? 0) + 1,\n )\n })\n })\n\n const roots = filteredNodes\n .filter((node) => (inboundCounts.get(node.id) ?? 0) === 0)\n .map((node) => node.id)\n\n if (roots.length > 0) {\n return roots.sort((left, right) =>\n compareReactNodeIds(left, right, graph.nodes),\n )\n }\n\n return filteredNodes\n .map((node) => node.id)\n .sort((left, right) => compareReactNodeIds(left, right, graph.nodes))\n}\n\nexport function getFilteredUsages(\n node: ReactUsageNode,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEdge[] {\n return node.usages.filter((usage) => {\n const targetNode = graph.nodes.get(usage.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nfunction analyzeReactFile(\n program: Program,\n filePath: string,\n sourceText: string,\n includeNestedRenderEntries: boolean,\n sourceDependencies: ReadonlyMap<string, string>,\n): FileAnalysis {\n const symbolsByName = new Map<string, PendingReactUsageNode>()\n\n program.body.forEach((statement) => {\n collectTopLevelReactSymbols(statement, filePath, symbolsByName)\n })\n\n const importsByLocalName = new Map<string, ImportBinding>()\n const exportsByName = new Map<string, string>()\n const entryUsages = collectEntryUsages(\n program,\n filePath,\n sourceText,\n includeNestedRenderEntries,\n )\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 entryUsages,\n symbolsById: new Map(\n [...symbolsByName.values()].map((symbol) => [symbol.id, symbol]),\n ),\n symbolsByName,\n }\n}\n\nfunction collectEntryUsages(\n program: Program,\n filePath: string,\n sourceText: string,\n includeNestedFunctions: boolean,\n): PendingReactUsageEntry[] {\n const entries = new Map<string, PendingReactUsageEntry>()\n\n program.body.forEach((statement) => {\n collectStatementEntryUsages(\n statement,\n filePath,\n sourceText,\n entries,\n includeNestedFunctions,\n )\n })\n\n return [...entries.values()].sort(comparePendingReactUsageEntries)\n}\n\nfunction collectStatementEntryUsages(\n statement: Statement,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n includeNestedFunctions: boolean,\n): void {\n collectNodeEntryUsages(\n statement,\n filePath,\n sourceText,\n entries,\n false,\n includeNestedFunctions,\n )\n}\n\nfunction collectNodeEntryUsages(\n node: Node,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n hasComponentAncestor: boolean,\n includeNestedFunctions: boolean,\n): void {\n if (!includeNestedFunctions && FUNCTION_NODE_TYPES.has(node.type)) {\n return\n }\n\n let nextHasComponentAncestor = hasComponentAncestor\n\n if (node.type === 'JSXElement') {\n const referenceName = getComponentReferenceName(node)\n if (referenceName !== undefined) {\n if (!hasComponentAncestor) {\n addPendingReactUsageEntry(\n entries,\n referenceName,\n 'component',\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n nextHasComponentAncestor = true\n }\n } else if (node.type === 'CallExpression') {\n const hookReference = getHookReferenceName(node)\n if (hookReference !== undefined) {\n addPendingReactUsageEntry(\n entries,\n hookReference,\n 'hook',\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n\n const referenceName = getCreateElementComponentReferenceName(node)\n if (referenceName !== undefined) {\n if (!hasComponentAncestor) {\n addPendingReactUsageEntry(\n entries,\n referenceName,\n 'component',\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n nextHasComponentAncestor = true\n }\n }\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n collectEntryUsageChild(\n value,\n filePath,\n sourceText,\n entries,\n nextHasComponentAncestor,\n includeNestedFunctions,\n )\n })\n}\n\nfunction collectEntryUsageChild(\n value: unknown,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n hasComponentAncestor: boolean,\n includeNestedFunctions: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n collectEntryUsageChild(\n entry,\n filePath,\n sourceText,\n entries,\n hasComponentAncestor,\n includeNestedFunctions,\n )\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n collectNodeEntryUsages(\n value,\n filePath,\n sourceText,\n entries,\n hasComponentAncestor,\n includeNestedFunctions,\n )\n}\n\nfunction addPendingReactUsageEntry(\n entries: Map<string, PendingReactUsageEntry>,\n referenceName: string,\n kind: ReactSymbolKind,\n location: ReactUsageLocation,\n): void {\n const key = `${location.filePath}:${location.line}:${location.column}:${kind}:${referenceName}`\n entries.set(key, {\n referenceName,\n kind,\n location,\n })\n}\n\nfunction createReactUsageLocation(\n filePath: string,\n sourceText: string,\n offset: number,\n): ReactUsageLocation {\n return {\n filePath,\n ...offsetToLineAndColumn(sourceText, offset),\n }\n}\n\nfunction offsetToLineAndColumn(\n sourceText: string,\n offset: number,\n): Pick<ReactUsageLocation, 'line' | 'column'> {\n let line = 1\n let column = 1\n\n for (let index = 0; index < offset && index < sourceText.length; index += 1) {\n if (sourceText[index] === '\\n') {\n line += 1\n column = 1\n continue\n }\n\n column += 1\n }\n\n return { line, column }\n}\n\nfunction collectTopLevelReactSymbols(\n statement: Statement,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n switch (statement.type) {\n case 'FunctionDeclaration':\n addFunctionSymbol(statement, filePath, symbolsByName)\n return\n case 'VariableDeclaration':\n statement.declarations.forEach((declarator) => {\n addVariableSymbol(declarator, filePath, symbolsByName)\n })\n return\n case 'ExportNamedDeclaration':\n if (statement.declaration !== null) {\n collectTopLevelReactSymbols(\n statement.declaration,\n filePath,\n symbolsByName,\n )\n }\n return\n case 'ExportDefaultDeclaration':\n addDefaultExportSymbol(statement, filePath, symbolsByName)\n return\n default:\n return\n }\n}\n\nfunction addFunctionSymbol(\n declaration: OxcFunction,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n const name = declaration.id?.name\n if (name === undefined) {\n return\n }\n\n const kind = classifyReactSymbol(name, declaration)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration),\n )\n}\n\nfunction addVariableSymbol(\n declarator: VariableDeclarator,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (declarator.id.type !== 'Identifier' || declarator.init === null) {\n return\n }\n\n if (\n declarator.init.type !== 'ArrowFunctionExpression' &&\n declarator.init.type !== 'FunctionExpression'\n ) {\n return\n }\n\n const name = declarator.id.name\n const kind = classifyReactSymbol(name, declarator.init)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declarator.init),\n )\n}\n\nfunction addDefaultExportSymbol(\n declaration: ExportDefaultDeclaration,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n addFunctionSymbol(declaration.declaration, filePath, symbolsByName)\n } else if (declaration.declaration.type === 'ArrowFunctionExpression') {\n const name = 'default'\n const kind = declaration.declaration.body\n ? classifyReactSymbol(name, declaration.declaration)\n : undefined\n if (kind !== undefined) {\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration.declaration),\n )\n }\n }\n}\n\nfunction createPendingSymbol(\n filePath: string,\n name: string,\n kind: ReactSymbolKind,\n declaration: OxcFunction | ArrowFunctionExpression,\n): PendingReactUsageNode {\n return {\n id: `${filePath}#${kind}:${name}`,\n name,\n kind,\n filePath,\n declaration,\n exportNames: new Set<string>(),\n componentReferences: new Set<string>(),\n hookReferences: new Set<string>(),\n }\n}\n\nfunction collectImportsAndExports(\n statement: Statement,\n sourceDependencies: ReadonlyMap<string, string>,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n importsByLocalName: Map<string, ImportBinding>,\n exportsByName: Map<string, string>,\n): void {\n switch (statement.type) {\n case 'ImportDeclaration':\n collectImportBindings(statement, sourceDependencies, importsByLocalName)\n return\n case 'ExportNamedDeclaration':\n collectNamedExports(statement, symbolsByName, exportsByName)\n return\n case 'ExportDefaultDeclaration':\n collectDefaultExport(statement, symbolsByName, exportsByName)\n return\n default:\n return\n }\n}\n\nfunction collectImportBindings(\n declaration: ImportDeclaration,\n sourceDependencies: ReadonlyMap<string, string>,\n importsByLocalName: Map<string, ImportBinding>,\n): void {\n if (declaration.importKind === 'type') {\n return\n }\n\n const sourceSpecifier = declaration.source.value\n const sourcePath = sourceDependencies.get(declaration.source.value)\n\n declaration.specifiers.forEach((specifier) => {\n const binding = getImportBinding(specifier, sourceSpecifier, sourcePath)\n if (binding === undefined) {\n return\n }\n\n importsByLocalName.set(binding.localName, {\n importedName: binding.importedName,\n sourceSpecifier: binding.sourceSpecifier,\n ...(binding.sourcePath === undefined\n ? {}\n : { sourcePath: binding.sourcePath }),\n })\n })\n}\n\nfunction getImportBinding(\n specifier: ImportDeclarationSpecifier,\n sourceSpecifier: string,\n sourcePath: string | undefined,\n):\n | {\n readonly localName: string\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n }\n | undefined {\n if (specifier.type === 'ImportSpecifier') {\n if (specifier.importKind === 'type') {\n return undefined\n }\n\n return {\n localName: specifier.local.name,\n importedName: toModuleExportName(specifier.imported),\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n if (specifier.type === 'ImportDefaultSpecifier') {\n return {\n localName: specifier.local.name,\n importedName: 'default',\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n return undefined\n}\n\nfunction collectNamedExports(\n declaration: ExportNamedDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (declaration.exportKind === 'type') {\n return\n }\n\n if (declaration.declaration !== null) {\n if (declaration.declaration.type === 'FunctionDeclaration') {\n const name = declaration.declaration.id?.name\n if (name !== undefined) {\n addExportBinding(name, name, symbolsByName, exportsByName)\n }\n } else if (declaration.declaration.type === 'VariableDeclaration') {\n declaration.declaration.declarations.forEach((declarator) => {\n if (declarator.id.type === 'Identifier') {\n addExportBinding(\n declarator.id.name,\n declarator.id.name,\n symbolsByName,\n exportsByName,\n )\n }\n })\n }\n\n return\n }\n\n if (declaration.source !== null) {\n return\n }\n\n declaration.specifiers.forEach((specifier) => {\n if (specifier.exportKind === 'type') {\n return\n }\n\n const localName = toModuleExportName(specifier.local)\n const exportedName = toModuleExportName(specifier.exported)\n addExportBinding(localName, exportedName, symbolsByName, exportsByName)\n })\n}\n\nfunction collectDefaultExport(\n declaration: ExportDefaultDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n const localName = declaration.declaration.id?.name\n if (localName !== undefined) {\n addExportBinding(localName, 'default', symbolsByName, exportsByName)\n }\n return\n }\n\n if (declaration.declaration.type === 'Identifier') {\n addExportBinding(\n declaration.declaration.name,\n 'default',\n symbolsByName,\n exportsByName,\n )\n return\n }\n\n if (declaration.declaration.type === 'ArrowFunctionExpression') {\n addExportBinding('default', 'default', symbolsByName, exportsByName)\n }\n}\n\nfunction addExportBinding(\n localName: string,\n exportedName: string,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n const symbol = symbolsByName.get(localName)\n if (symbol === undefined) {\n return\n }\n\n symbol.exportNames.add(exportedName)\n exportsByName.set(exportedName, symbol.id)\n}\n\nfunction analyzeSymbolUsages(symbol: PendingReactUsageNode): void {\n const root =\n symbol.declaration.type === 'ArrowFunctionExpression'\n ? symbol.declaration.body\n : symbol.declaration.body\n\n if (root === null) {\n return\n }\n\n walkReactUsageTree(root, (node) => {\n if (node.type === 'JSXElement') {\n const name = getComponentReferenceName(node)\n if (name !== undefined) {\n symbol.componentReferences.add(name)\n }\n return\n }\n\n if (node.type === 'CallExpression') {\n const hookReference = getHookReferenceName(node)\n if (hookReference !== undefined) {\n symbol.hookReferences.add(hookReference)\n }\n\n const componentReference = getCreateElementComponentReferenceName(node)\n if (componentReference !== undefined) {\n symbol.componentReferences.add(componentReference)\n }\n }\n })\n}\n\nfunction classifyReactSymbol(\n name: string,\n declaration: OxcFunction | ArrowFunctionExpression,\n): ReactSymbolKind | undefined {\n if (isHookName(name)) {\n return 'hook'\n }\n\n if (isComponentName(name) && returnsReactElement(declaration)) {\n return 'component'\n }\n\n return undefined\n}\n\nfunction returnsReactElement(\n declaration: OxcFunction | ArrowFunctionExpression,\n): boolean {\n if (\n declaration.type === 'ArrowFunctionExpression' &&\n declaration.expression\n ) {\n return containsReactElementLikeExpression(declaration.body as Expression)\n }\n\n const body = declaration.body\n if (body === null) {\n return false\n }\n\n let found = false\n walkReactUsageTree(body, (node) => {\n if (node.type !== 'ReturnStatement' || node.argument === null) {\n return\n }\n\n if (containsReactElementLikeExpression(node.argument)) {\n found = true\n }\n })\n\n return found\n}\n\nfunction containsReactElementLikeExpression(expression: Expression): boolean {\n let found = false\n\n walkNode(expression, (node) => {\n if (\n node.type === 'JSXElement' ||\n node.type === 'JSXFragment' ||\n (node.type === 'CallExpression' && isReactCreateElementCall(node))\n ) {\n found = true\n }\n })\n\n return found\n}\n\nfunction getComponentReferenceName(node: JSXElement): string | undefined {\n const name = getJsxName(node.openingElement.name)\n return name !== undefined && isComponentName(name) ? name : undefined\n}\n\nfunction getHookReferenceName(node: CallExpression): string | undefined {\n const calleeName = getIdentifierName(node.callee)\n return calleeName !== undefined && isHookName(calleeName)\n ? calleeName\n : undefined\n}\n\nfunction getCreateElementComponentReferenceName(\n node: CallExpression,\n): string | undefined {\n if (!isReactCreateElementCall(node)) {\n return undefined\n }\n\n const [firstArgument] = node.arguments\n if (firstArgument === undefined || firstArgument.type !== 'Identifier') {\n return undefined\n }\n\n return isComponentName(firstArgument.name) ? firstArgument.name : undefined\n}\n\nfunction isReactCreateElementCall(node: CallExpression): boolean {\n const callee = unwrapExpression(node.callee)\n if (callee.type !== 'MemberExpression' || callee.computed) {\n return false\n }\n\n return (\n callee.object.type === 'Identifier' &&\n callee.object.name === 'React' &&\n callee.property.name === 'createElement'\n )\n}\n\nfunction getJsxName(name: JSXElementName): string | undefined {\n if (name.type === 'JSXIdentifier') {\n return name.name\n }\n\n return undefined\n}\n\nfunction getIdentifierName(expression: Expression): string | undefined {\n const unwrapped = unwrapExpression(expression)\n return unwrapped.type === 'Identifier' ? unwrapped.name : undefined\n}\n\nfunction unwrapExpression(expression: Expression): Expression {\n let current = expression\n\n while (true) {\n if (\n current.type === 'ParenthesizedExpression' ||\n current.type === 'TSAsExpression' ||\n current.type === 'TSSatisfiesExpression' ||\n current.type === 'TSTypeAssertion' ||\n current.type === 'TSNonNullExpression'\n ) {\n current = current.expression\n continue\n }\n\n return current\n }\n}\n\nfunction walkReactUsageTree(\n root: FunctionBody | Expression | JSXFragment | JSXElement,\n visit: (node: Node) => void,\n): void {\n walkNode(root, visit, true)\n}\n\nfunction walkNode(\n node: Node,\n visit: (node: Node) => void,\n allowNestedFunctions = false,\n): void {\n visit(node)\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n walkChild(value, visit, allowNestedFunctions)\n })\n}\n\nfunction walkChild(\n value: unknown,\n visit: (node: Node) => void,\n allowNestedFunctions: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n walkChild(entry, visit, allowNestedFunctions)\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n if (!allowNestedFunctions && FUNCTION_NODE_TYPES.has(value.type)) {\n return\n }\n\n walkNode(value, visit, false)\n}\n\nfunction isNode(value: unknown): value is Node {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n typeof (value as { type: unknown }).type === 'string'\n )\n}\n\nfunction resolveReactReference(\n fileAnalysis: FileAnalysis,\n fileAnalyses: ReadonlyMap<string, FileAnalysis>,\n name: string,\n kind: ReactSymbolKind,\n): string | undefined {\n const localSymbol = fileAnalysis.symbolsByName.get(name)\n if (localSymbol !== undefined && localSymbol.kind === kind) {\n return localSymbol.id\n }\n\n const importBinding = fileAnalysis.importsByLocalName.get(name)\n if (importBinding === undefined) {\n return undefined\n }\n\n if (importBinding.sourcePath === undefined) {\n return kind === 'hook'\n ? getExternalHookNodeId(importBinding, name)\n : undefined\n }\n\n const sourceFileAnalysis = fileAnalyses.get(importBinding.sourcePath)\n if (sourceFileAnalysis === undefined) {\n return undefined\n }\n\n const targetId = sourceFileAnalysis.exportsByName.get(\n importBinding.importedName,\n )\n if (targetId === undefined) {\n return undefined\n }\n\n const targetSymbol = sourceFileAnalysis.symbolsById.get(targetId)\n return targetSymbol?.kind === kind ? targetId : undefined\n}\n\nfunction createExternalHookNode(\n binding: ImportBinding,\n localName: string,\n): ReactUsageNode {\n const name = getExternalHookName(binding, localName)\n\n return {\n id: getExternalHookNodeId(binding, localName),\n name,\n kind: 'hook',\n filePath: binding.sourceSpecifier,\n exportNames: [binding.importedName],\n usages: [],\n }\n}\n\nfunction getExternalHookNodeId(\n binding: ImportBinding,\n localName: string,\n): string {\n return `external:${binding.sourceSpecifier}#hook:${getExternalHookName(binding, localName)}`\n}\n\nfunction getExternalHookName(\n binding: ImportBinding,\n localName: string,\n): string {\n return binding.importedName === 'default' ? localName : binding.importedName\n}\n\nfunction getFilteredReactUsageNodes(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): ReactUsageNode[] {\n return [...graph.nodes.values()]\n .filter((node) => matchesReactFilter(node, filter))\n .sort((left, right) => compareReactNodes(left, right))\n}\n\nfunction matchesReactFilter(\n node: ReactUsageNode,\n filter: ReactUsageFilter,\n): boolean {\n return filter === 'all' || node.kind === filter\n}\n\nfunction serializeReactUsageNode(\n nodeId: string,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n visited: Set<string>,\n): SerializedReactUsageNode {\n const node = graph.nodes.get(nodeId)\n if (node === undefined) {\n return {\n id: nodeId,\n name: nodeId,\n symbolKind: 'circular',\n filePath: '',\n exportNames: [],\n usages: [],\n }\n }\n\n if (visited.has(nodeId)) {\n return {\n id: node.id,\n name: node.name,\n symbolKind: 'circular',\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: [],\n }\n }\n\n const nextVisited = new Set(visited)\n nextVisited.add(nodeId)\n\n return {\n id: node.id,\n name: node.name,\n symbolKind: node.kind,\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: getFilteredUsages(node, graph, filter).map((usage) => ({\n kind: usage.kind,\n targetId: usage.target,\n node: serializeReactUsageNode(usage.target, graph, filter, nextVisited),\n })),\n }\n}\n\nfunction serializeReactUsageEntry(\n entry: ReactUsageEntry,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): SerializedReactUsageEntry {\n return {\n targetId: entry.target,\n filePath: toDisplayPath(entry.location.filePath, graph.cwd),\n line: entry.location.line,\n column: entry.location.column,\n node: serializeReactUsageNode(entry.target, graph, filter, new Set()),\n }\n}\n\nfunction compareReactNodeIds(\n leftId: string,\n rightId: string,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n const left = nodes.get(leftId)\n const right = nodes.get(rightId)\n\n if (left === undefined || right === undefined) {\n return leftId.localeCompare(rightId)\n }\n\n return compareReactNodes(left, right)\n}\n\nfunction compareReactUsageEntries(\n left: ReactUsageEntry,\n right: ReactUsageEntry,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n return (\n left.location.filePath.localeCompare(right.location.filePath) ||\n left.location.line - right.location.line ||\n left.location.column - right.location.column ||\n compareReactNodeIds(left.target, right.target, nodes)\n )\n}\n\nfunction comparePendingReactUsageEntries(\n left: PendingReactUsageEntry,\n right: PendingReactUsageEntry,\n): number {\n return (\n left.location.filePath.localeCompare(right.location.filePath) ||\n left.location.line - right.location.line ||\n left.location.column - right.location.column ||\n left.kind.localeCompare(right.kind) ||\n left.referenceName.localeCompare(right.referenceName)\n )\n}\n\nfunction compareReactNodes(\n left: ReactUsageNode,\n right: ReactUsageNode,\n): number {\n return (\n left.filePath.localeCompare(right.filePath) ||\n left.name.localeCompare(right.name) ||\n left.kind.localeCompare(right.kind)\n )\n}\n\nfunction toModuleExportName(name: ModuleExportName): string {\n return name.type === 'Literal' ? name.value : name.name\n}\n\nfunction isHookName(name: string): boolean {\n return /^use[A-Z0-9]/.test(name)\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name)\n}\n","import process from 'node:process'\n\nimport type { ColorMode, ReactSymbolKind } from './types.js'\n\nconst ANSI_RESET = '\\u001B[0m'\nconst ANSI_COMPONENT = '\\u001B[36m'\nconst ANSI_HOOK = '\\u001B[35m'\nconst ANSI_UNUSED = '\\u001B[38;5;214m'\n\ninterface ResolveColorSupportOptions {\n readonly forceColor?: string | undefined\n readonly isTTY?: boolean | undefined\n readonly noColor?: string | undefined\n}\n\nexport function resolveColorSupport(\n mode: ColorMode = 'auto',\n options: ResolveColorSupportOptions = {},\n): boolean {\n if (mode === true) {\n return true\n }\n\n if (mode === false) {\n return false\n }\n\n const forceColor =\n 'forceColor' in options ? options.forceColor : process.env.FORCE_COLOR\n if (forceColor !== undefined) {\n return forceColor !== '0'\n }\n\n const noColor = 'noColor' in options ? options.noColor : process.env.NO_COLOR\n if (noColor !== undefined) {\n return false\n }\n\n const isTTY = 'isTTY' in options ? options.isTTY : process.stdout.isTTY\n return isTTY === true\n}\n\nexport function colorizeUnusedMarker(text: string, enabled: boolean): string {\n if (!enabled) {\n return text\n }\n\n return text.replaceAll('(unused)', `${ANSI_UNUSED}(unused)${ANSI_RESET}`)\n}\n\nexport function formatReactSymbolLabel(\n name: string,\n kind: ReactSymbolKind,\n enabled: boolean,\n): string {\n const label = `${name} [${kind}]`\n if (!enabled) {\n return label\n }\n\n const color = kind === 'component' ? ANSI_COMPONENT : ANSI_HOOK\n return `${color}${label}${ANSI_RESET}`\n}\n","import { formatReactSymbolLabel, resolveColorSupport } from './color.js'\nimport { toDisplayPath } from './path-utils.js'\nimport {\n getFilteredUsages,\n getReactUsageEntries,\n getReactUsageRoots,\n} from './react-analyzer.js'\nimport type {\n PrintReactTreeOptions,\n ReactUsageEdge,\n ReactUsageEntry,\n ReactUsageGraph,\n ReactUsageNode,\n} from './types.js'\n\nexport function printReactUsageTree(\n graph: ReactUsageGraph,\n options: PrintReactTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const color = resolveColorSupport(options.color)\n const filter = options.filter ?? 'all'\n const entries = getReactUsageEntries(graph, filter)\n\n if (entries.length > 0) {\n return renderReactUsageEntries(graph, entries, cwd, filter, color)\n }\n\n const roots = getReactUsageRoots(graph, filter)\n if (roots.length === 0) {\n return 'No React symbols found.'\n }\n\n const lines: string[] = []\n roots.forEach((rootId, index) => {\n const root = graph.nodes.get(rootId)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactNodeLabel(root, cwd, color))\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n color,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < roots.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderReactUsageEntries(\n graph: ReactUsageGraph,\n entries: readonly ReactUsageEntry[],\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n color: boolean,\n): string {\n const lines: string[] = []\n\n entries.forEach((entry, index) => {\n const root = graph.nodes.get(entry.target)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactEntryLabel(entry, cwd))\n lines.push(formatReactNodeLabel(root, cwd, color))\n\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n color,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < entries.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderUsage(\n usage: ReactUsageEdge,\n graph: ReactUsageGraph,\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n color: boolean,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const target = graph.nodes.get(usage.target)\n\n if (target === undefined) {\n return [`${branch}${usage.target}`]\n }\n\n if (visited.has(target.id)) {\n return [`${branch}${formatReactNodeLabel(target, cwd, color)} (circular)`]\n }\n\n const childLines = [`${branch}${formatReactNodeLabel(target, cwd, color)}`]\n const nextVisited = new Set(visited)\n nextVisited.add(target.id)\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const childUsages = getFilteredUsages(target, graph, filter)\n\n childUsages.forEach((childUsage, index) => {\n childLines.push(\n ...renderUsage(\n childUsage,\n graph,\n cwd,\n filter,\n color,\n nextVisited,\n nextPrefix,\n index === childUsages.length - 1,\n ),\n )\n })\n\n return childLines\n}\n\nfunction formatReactNodeLabel(\n node: ReactUsageNode,\n cwd: string,\n color: boolean,\n): string {\n return `${formatReactSymbolLabel(node.name, node.kind, color)} (${toDisplayPath(node.filePath, cwd)})`\n}\n\nfunction formatReactEntryLabel(entry: ReactUsageEntry, cwd: string): string {\n return `${toDisplayPath(entry.location.filePath, cwd)}:${entry.location.line}:${entry.location.column}`\n}\n","import { colorizeUnusedMarker, resolveColorSupport } from './color.js'\nimport { toDisplayPath } from './path-utils.js'\nimport type {\n DependencyEdge,\n DependencyGraph,\n PrintTreeOptions,\n} from './types.js'\n\nexport function printDependencyTree(\n graph: DependencyGraph,\n options: PrintTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const color = resolveColorSupport(options.color)\n const includeExternals = options.includeExternals ?? false\n const omitUnused = options.omitUnused ?? false\n const rootLines = [toDisplayPath(graph.entryId, cwd)]\n const visited = new Set<string>([graph.entryId])\n const entryNode = graph.nodes.get(graph.entryId)\n\n if (entryNode === undefined) {\n return rootLines.join('\\n')\n }\n\n const rootDependencies = filterDependencies(\n entryNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n rootDependencies.forEach((dependency, index) => {\n const isLast = index === rootDependencies.length - 1\n const lines = renderDependency(\n dependency,\n graph,\n visited,\n '',\n isLast,\n includeExternals,\n omitUnused,\n color,\n cwd,\n )\n rootLines.push(...lines)\n })\n\n return rootLines.join('\\n')\n}\n\nfunction renderDependency(\n dependency: DependencyEdge,\n graph: DependencyGraph,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n includeExternals: boolean,\n omitUnused: boolean,\n color: boolean,\n cwd: string,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const label = formatDependencyLabel(dependency, cwd, color)\n\n if (dependency.kind !== 'source') {\n return [`${branch}${label}`]\n }\n\n if (visited.has(dependency.target)) {\n return [`${branch}${label} (circular)`]\n }\n\n const childNode = graph.nodes.get(dependency.target)\n if (childNode === undefined) {\n return [`${branch}${label}`]\n }\n\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const nextVisited = new Set(visited)\n nextVisited.add(dependency.target)\n\n const childLines = [`${branch}${label}`]\n const childDependencies = filterDependencies(\n childNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n childDependencies.forEach((childDependency, index) => {\n const isChildLast = index === childDependencies.length - 1\n childLines.push(\n ...renderDependency(\n childDependency,\n graph,\n nextVisited,\n nextPrefix,\n isChildLast,\n includeExternals,\n omitUnused,\n color,\n cwd,\n ),\n )\n })\n\n return childLines\n}\n\nfunction filterDependencies(\n dependencies: readonly DependencyEdge[],\n includeExternals: boolean,\n omitUnused: boolean,\n): DependencyEdge[] {\n return dependencies.filter((dependency) => {\n if (omitUnused && dependency.unused) {\n return false\n }\n\n if (dependency.kind === 'source' || dependency.kind === 'missing') {\n return true\n }\n\n return includeExternals\n })\n}\n\nfunction formatDependencyLabel(\n dependency: DependencyEdge,\n cwd: string,\n color: boolean,\n): string {\n const prefixes: string[] = []\n if (dependency.isTypeOnly) {\n prefixes.push('type')\n }\n\n if (dependency.referenceKind === 'require') {\n prefixes.push('require')\n } else if (dependency.referenceKind === 'dynamic-import') {\n prefixes.push('dynamic')\n } else if (dependency.referenceKind === 'export') {\n prefixes.push('re-export')\n } else if (dependency.referenceKind === 'import-equals') {\n prefixes.push('import=')\n }\n\n const annotation = prefixes.length > 0 ? `[${prefixes.join(', ')}] ` : ''\n\n if (dependency.kind === 'source') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${toDisplayPath(dependency.target, cwd)}`,\n dependency.unused,\n ),\n color,\n )\n }\n\n if (dependency.kind === 'missing') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.specifier} [missing]`,\n dependency.unused,\n ),\n color,\n )\n }\n\n if (dependency.kind === 'builtin') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.target} [builtin]`,\n dependency.unused,\n ),\n color,\n )\n }\n\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.target} [external]`,\n dependency.unused,\n ),\n color,\n )\n}\n\nfunction withUnusedSuffix(label: string, unused: boolean): string {\n return unused ? `${label} (unused)` : label\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tree-BrguxPgp.mjs","names":["process"],"sources":["../src/config.ts","../src/path-utils.ts","../src/analyzer.ts","../src/react-analyzer.ts","../src/color.ts","../src/react-tree.ts","../src/tree.ts"],"sourcesContent":["import path from 'node:path'\nimport ts from 'typescript'\n\nexport interface LoadedConfig {\n readonly path?: string\n readonly compilerOptions: ts.CompilerOptions\n}\n\nexport function loadCompilerOptions(\n searchFrom: string,\n explicitConfigPath?: string,\n): LoadedConfig {\n const configPath =\n explicitConfigPath === undefined\n ? findNearestConfig(searchFrom)\n : path.resolve(searchFrom, explicitConfigPath)\n\n if (configPath === undefined) {\n return {\n compilerOptions: defaultCompilerOptions(),\n }\n }\n\n const readResult = ts.readConfigFile(configPath, ts.sys.readFile)\n if (readResult.error !== undefined) {\n throw new Error(\n `Failed to read TypeScript config at ${configPath}: ${formatDiagnostic(\n readResult.error,\n )}`,\n )\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n readResult.config,\n ts.sys,\n path.dirname(configPath),\n defaultCompilerOptions(),\n configPath,\n )\n\n if (parsed.errors.length > 0) {\n const [firstError] = parsed.errors\n if (firstError === undefined) {\n throw new Error(`Failed to parse TypeScript config at ${configPath}.`)\n }\n\n throw new Error(\n `Failed to parse TypeScript config at ${configPath}: ${formatDiagnostic(\n firstError,\n )}`,\n )\n }\n\n return {\n path: configPath,\n compilerOptions: parsed.options,\n }\n}\n\nfunction findNearestConfig(searchFrom: string): string | undefined {\n let currentDirectory = path.resolve(searchFrom)\n\n while (true) {\n const tsconfigPath = path.join(currentDirectory, 'tsconfig.json')\n if (ts.sys.fileExists(tsconfigPath)) {\n return tsconfigPath\n }\n\n const jsconfigPath = path.join(currentDirectory, 'jsconfig.json')\n if (ts.sys.fileExists(jsconfigPath)) {\n return jsconfigPath\n }\n\n const parentDirectory = path.dirname(currentDirectory)\n if (parentDirectory === currentDirectory) {\n return undefined\n }\n\n currentDirectory = parentDirectory\n }\n}\n\nfunction defaultCompilerOptions(): ts.CompilerOptions {\n return {\n allowJs: true,\n jsx: ts.JsxEmit.ReactJSX,\n module: ts.ModuleKind.NodeNext,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n target: ts.ScriptTarget.ESNext,\n resolveJsonModule: true,\n esModuleInterop: true,\n }\n}\n\nfunction formatDiagnostic(diagnostic: ts.Diagnostic): string {\n return ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n')\n}\n","import path from 'node:path'\n\nexport const SOURCE_EXTENSIONS = new Set([\n '.js',\n '.jsx',\n '.ts',\n '.tsx',\n '.mjs',\n '.cjs',\n '.mts',\n '.cts',\n])\n\nexport function normalizeFilePath(filePath: string): string {\n return path.normalize(filePath)\n}\n\nexport function toDisplayPath(filePath: string, cwd: string): string {\n const relativePath = path.relative(cwd, filePath)\n if (relativePath === '') {\n return '.'\n }\n\n const normalizedPath = relativePath.split(path.sep).join('/')\n return normalizedPath.startsWith('..') ? filePath : normalizedPath\n}\n\nexport function isSourceCodeFile(filePath: string): boolean {\n return SOURCE_EXTENSIONS.has(path.extname(filePath).toLowerCase())\n}\n","import fs from 'node:fs'\nimport { builtinModules } from 'node:module'\nimport path from 'node:path'\nimport ts from 'typescript'\n\nimport { loadCompilerOptions } from './config.js'\nimport {\n isSourceCodeFile,\n normalizeFilePath,\n toDisplayPath,\n} from './path-utils.js'\nimport type {\n AnalyzeOptions,\n DependencyEdge,\n DependencyGraph,\n DependencyKind,\n ReferenceKind,\n SourceModuleNode,\n} from './types.js'\n\ninterface ModuleReference {\n readonly specifier: string\n readonly referenceKind: ReferenceKind\n readonly isTypeOnly: boolean\n readonly unused: boolean\n}\n\nconst BUILTIN_MODULES = new Set(\n builtinModules.flatMap((name) => [name, `node:${name}`]),\n)\n\nexport function analyzeDependencies(\n entryFile: string,\n options: AnalyzeOptions = {},\n): DependencyGraph {\n const cwd = path.resolve(options.cwd ?? process.cwd())\n const resolvedEntryPath = resolveExistingPath(cwd, entryFile)\n const { compilerOptions, path: configPath } = loadCompilerOptions(\n path.dirname(resolvedEntryPath),\n options.configPath,\n )\n\n const host: ts.ModuleResolutionHost = {\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n directoryExists: ts.sys.directoryExists,\n getCurrentDirectory: () => cwd,\n getDirectories: ts.sys.getDirectories,\n ...(ts.sys.realpath === undefined ? {} : { realpath: ts.sys.realpath }),\n }\n\n const nodes = new Map<string, SourceModuleNode>()\n const program = createProgram(resolvedEntryPath, compilerOptions, cwd)\n const checker = program.getTypeChecker()\n visitFile(resolvedEntryPath, compilerOptions, host, checker, program, nodes)\n\n return {\n cwd,\n entryId: resolvedEntryPath,\n nodes,\n ...(configPath === undefined ? {} : { configPath }),\n }\n}\n\nexport function graphToSerializableTree(\n graph: DependencyGraph,\n options: {\n readonly omitUnused?: boolean\n } = {},\n): object {\n const visited = new Set<string>()\n return serializeNode(\n graph.entryId,\n graph,\n visited,\n options.omitUnused ?? false,\n )\n}\n\nfunction serializeNode(\n filePath: string,\n graph: DependencyGraph,\n visited: Set<string>,\n omitUnused: boolean,\n): object {\n const node = graph.nodes.get(filePath)\n const displayPath = toDisplayPath(filePath, graph.cwd)\n\n if (node === undefined) {\n return {\n path: displayPath,\n kind: 'missing',\n dependencies: [],\n }\n }\n\n if (visited.has(filePath)) {\n return {\n path: displayPath,\n kind: 'circular',\n dependencies: [],\n }\n }\n\n visited.add(filePath)\n\n const dependencies = node.dependencies\n .filter((dependency) => !omitUnused || !dependency.unused)\n .map((dependency) => {\n if (dependency.kind !== 'source') {\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target:\n dependency.kind === 'missing'\n ? dependency.target\n : toDisplayPath(dependency.target, graph.cwd),\n }\n }\n\n return {\n specifier: dependency.specifier,\n referenceKind: dependency.referenceKind,\n isTypeOnly: dependency.isTypeOnly,\n unused: dependency.unused,\n kind: dependency.kind,\n target: toDisplayPath(dependency.target, graph.cwd),\n node: serializeNode(\n dependency.target,\n graph,\n new Set(visited),\n omitUnused,\n ),\n }\n })\n\n return {\n path: displayPath,\n kind: filePath === graph.entryId ? 'entry' : 'source',\n dependencies,\n }\n}\n\nfunction visitFile(\n filePath: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n checker: ts.TypeChecker,\n program: ts.Program,\n nodes: Map<string, SourceModuleNode>,\n): void {\n const normalizedPath = normalizeFilePath(filePath)\n if (nodes.has(normalizedPath)) {\n return\n }\n\n const sourceFile =\n program.getSourceFile(normalizedPath) ?? createSourceFile(normalizedPath)\n\n const references = collectModuleReferences(sourceFile, checker)\n const dependencies = references.map((reference) =>\n resolveDependency(reference, normalizedPath, compilerOptions, host),\n )\n\n nodes.set(normalizedPath, {\n id: normalizedPath,\n dependencies,\n })\n\n for (const dependency of dependencies) {\n if (dependency.kind === 'source') {\n visitFile(\n dependency.target,\n compilerOptions,\n host,\n checker,\n program,\n nodes,\n )\n }\n }\n}\n\nfunction collectModuleReferences(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ModuleReference[] {\n const references = new Map<string, ModuleReference>()\n const unusedImports = collectUnusedImports(sourceFile, checker)\n\n function addReference(\n specifier: string,\n referenceKind: ReferenceKind,\n isTypeOnly: boolean,\n unused: boolean,\n ): void {\n const key = `${referenceKind}:${isTypeOnly ? 'type' : 'value'}:${specifier}`\n const existing = references.get(key)\n if (existing !== undefined) {\n if (existing.unused && !unused) {\n references.set(key, {\n ...existing,\n unused: false,\n })\n }\n return\n }\n\n references.set(key, {\n specifier,\n referenceKind,\n isTypeOnly,\n unused,\n })\n }\n\n function visit(node: ts.Node): void {\n if (\n ts.isImportDeclaration(node) &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'import',\n node.importClause?.isTypeOnly ?? false,\n unusedImports.get(node) ?? false,\n )\n } else if (\n ts.isExportDeclaration(node) &&\n node.moduleSpecifier !== undefined &&\n ts.isStringLiteralLike(node.moduleSpecifier)\n ) {\n addReference(\n node.moduleSpecifier.text,\n 'export',\n node.isTypeOnly ?? false,\n false,\n )\n } else if (ts.isImportEqualsDeclaration(node)) {\n const moduleReference = node.moduleReference\n if (\n ts.isExternalModuleReference(moduleReference) &&\n moduleReference.expression !== undefined &&\n ts.isStringLiteralLike(moduleReference.expression)\n ) {\n addReference(\n moduleReference.expression.text,\n 'import-equals',\n false,\n false,\n )\n }\n } else if (ts.isCallExpression(node)) {\n if (\n node.expression.kind === ts.SyntaxKind.ImportKeyword &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'dynamic-import', false, false)\n }\n }\n\n if (\n ts.isIdentifier(node.expression) &&\n node.expression.text === 'require' &&\n node.arguments.length === 1\n ) {\n const [argument] = node.arguments\n if (argument !== undefined && ts.isStringLiteralLike(argument)) {\n addReference(argument.text, 'require', false, false)\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n return [...references.values()]\n}\n\nfunction resolveDependency(\n reference: ModuleReference,\n containingFile: string,\n compilerOptions: ts.CompilerOptions,\n host: ts.ModuleResolutionHost,\n): DependencyEdge {\n const specifier = reference.specifier\n if (BUILTIN_MODULES.has(specifier)) {\n return createEdge(reference, 'builtin', specifier)\n }\n\n const resolution = ts.resolveModuleName(\n specifier,\n containingFile,\n compilerOptions,\n host,\n ).resolvedModule\n\n if (resolution !== undefined) {\n const resolvedPath = normalizeFilePath(resolution.resolvedFileName)\n if (\n resolution.isExternalLibraryImport ||\n resolvedPath.includes(`${path.sep}node_modules${path.sep}`)\n ) {\n return createEdge(reference, 'external', specifier)\n }\n\n if (isSourceCodeFile(resolvedPath) && !resolvedPath.endsWith('.d.ts')) {\n return createEdge(reference, 'source', resolvedPath)\n }\n }\n\n if (!specifier.startsWith('.') && !path.isAbsolute(specifier)) {\n return createEdge(reference, 'external', specifier)\n }\n\n return createEdge(reference, 'missing', specifier)\n}\n\nfunction createEdge(\n reference: ModuleReference,\n kind: DependencyKind,\n target: string,\n): DependencyEdge {\n return {\n specifier: reference.specifier,\n referenceKind: reference.referenceKind,\n isTypeOnly: reference.isTypeOnly,\n unused: reference.unused,\n kind,\n target,\n }\n}\n\nfunction createProgram(\n entryFile: string,\n compilerOptions: ts.CompilerOptions,\n cwd: string,\n): ts.Program {\n const host = ts.createCompilerHost(compilerOptions, true)\n host.getCurrentDirectory = () => cwd\n\n if (ts.sys.realpath !== undefined) {\n host.realpath = ts.sys.realpath\n }\n\n return ts.createProgram({\n rootNames: [entryFile],\n options: compilerOptions,\n host,\n })\n}\n\nfunction createSourceFile(filePath: string): ts.SourceFile {\n const sourceText = fs.readFileSync(filePath, 'utf8')\n return ts.createSourceFile(\n filePath,\n sourceText,\n ts.ScriptTarget.Latest,\n true,\n getScriptKind(filePath),\n )\n}\n\nfunction collectUnusedImports(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): ReadonlyMap<ts.ImportDeclaration, boolean> {\n const importUsage = new Map<\n ts.ImportDeclaration,\n {\n canTrack: boolean\n used: boolean\n }\n >()\n const symbolToImportDeclaration = new Map<ts.Symbol, ts.ImportDeclaration>()\n const importedLocalNames = new Set<string>()\n\n sourceFile.statements.forEach((statement) => {\n if (\n !ts.isImportDeclaration(statement) ||\n statement.importClause === undefined\n ) {\n return\n }\n\n const identifiers = getImportBindingIdentifiers(statement.importClause)\n if (identifiers.length === 0) {\n return\n }\n\n importUsage.set(statement, {\n canTrack: false,\n used: false,\n })\n\n identifiers.forEach((identifier) => {\n importedLocalNames.add(identifier.text)\n\n const symbol = tryGetSymbolAtLocation(checker, identifier)\n if (symbol === undefined) {\n return\n }\n\n symbolToImportDeclaration.set(symbol, statement)\n const state = importUsage.get(statement)\n if (state !== undefined) {\n state.canTrack = true\n }\n })\n })\n\n function visit(node: ts.Node): void {\n if (ts.isImportDeclaration(node)) {\n return\n }\n\n if (\n ts.isIdentifier(node) &&\n importedLocalNames.has(node.text) &&\n isReferenceIdentifier(node)\n ) {\n const symbol = tryGetSymbolAtLocation(checker, node)\n const declaration =\n symbol === undefined ? undefined : symbolToImportDeclaration.get(symbol)\n if (declaration !== undefined) {\n const state = importUsage.get(declaration)\n if (state !== undefined) {\n state.used = true\n }\n }\n }\n\n ts.forEachChild(node, visit)\n }\n\n visit(sourceFile)\n\n return new Map(\n [...importUsage.entries()].map(([declaration, state]) => [\n declaration,\n state.canTrack && !state.used,\n ]),\n )\n}\n\nfunction getImportBindingIdentifiers(\n importClause: ts.ImportClause,\n): ts.Identifier[] {\n const identifiers: ts.Identifier[] = []\n\n if (importClause.name !== undefined) {\n identifiers.push(importClause.name)\n }\n\n const namedBindings = importClause.namedBindings\n if (namedBindings === undefined) {\n return identifiers\n }\n\n if (ts.isNamespaceImport(namedBindings)) {\n identifiers.push(namedBindings.name)\n return identifiers\n }\n\n namedBindings.elements.forEach((element) => {\n identifiers.push(element.name)\n })\n\n return identifiers\n}\n\nfunction isReferenceIdentifier(node: ts.Identifier): boolean {\n const parent = node.parent\n\n if (ts.isPropertyAccessExpression(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isQualifiedName(parent) && parent.right === node) {\n return false\n }\n\n if (ts.isPropertyAssignment(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isBindingElement(parent) && parent.propertyName === node) {\n return false\n }\n\n if (ts.isJsxAttribute(parent) && parent.name === node) {\n return false\n }\n\n if (ts.isExportSpecifier(parent)) {\n return parent.propertyName === node || parent.propertyName === undefined\n }\n\n return true\n}\n\nfunction tryGetSymbolAtLocation(\n checker: ts.TypeChecker,\n node: ts.Node,\n): ts.Symbol | undefined {\n try {\n return checker.getSymbolAtLocation(node)\n } catch {\n return undefined\n }\n}\n\nfunction getScriptKind(filePath: string): ts.ScriptKind {\n switch (path.extname(filePath).toLowerCase()) {\n case '.js':\n case '.mjs':\n case '.cjs':\n return ts.ScriptKind.JS\n case '.jsx':\n return ts.ScriptKind.JSX\n case '.tsx':\n return ts.ScriptKind.TSX\n case '.json':\n return ts.ScriptKind.JSON\n default:\n return ts.ScriptKind.TS\n }\n}\n\nfunction resolveExistingPath(cwd: string, entryFile: string): string {\n const absolutePath = path.resolve(cwd, entryFile)\n const normalizedPath = normalizeFilePath(absolutePath)\n\n if (!fs.existsSync(normalizedPath)) {\n throw new Error(`Entry file not found: ${entryFile}`)\n }\n\n if (!isSourceCodeFile(normalizedPath)) {\n throw new Error(`Entry file must be a JS/TS source file: ${entryFile}`)\n }\n\n return normalizedPath\n}\n","import fs from 'node:fs'\nimport type {\n ArrowFunctionExpression,\n CallExpression,\n ExportDefaultDeclaration,\n ExportNamedDeclaration,\n Expression,\n FunctionBody,\n ImportDeclaration,\n ImportDeclarationSpecifier,\n JSXElement,\n JSXElementName,\n JSXFragment,\n ModuleExportName,\n Node,\n Function as OxcFunction,\n Program,\n Statement,\n VariableDeclarator,\n} from 'oxc-parser'\nimport { parseSync, visitorKeys } from 'oxc-parser'\n\nimport { analyzeDependencies } from './analyzer.js'\nimport { isSourceCodeFile, toDisplayPath } from './path-utils.js'\nimport type {\n AnalyzeOptions,\n ReactSymbolKind,\n ReactUsageEdge,\n ReactUsageEntry,\n ReactUsageFilter,\n ReactUsageGraph,\n ReactUsageLocation,\n ReactUsageNode,\n} from './types.js'\n\ninterface PendingReactUsageNode {\n readonly id: string\n readonly name: string\n readonly kind: ReactSymbolKind\n readonly filePath: string\n readonly declaration: OxcFunction | ArrowFunctionExpression\n readonly exportNames: Set<string>\n readonly componentReferences: Set<string>\n readonly hookReferences: Set<string>\n}\n\ninterface PendingReactUsageEntry {\n readonly referenceName: string\n readonly location: ReactUsageLocation\n}\n\ninterface ImportBinding {\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n}\n\ninterface FileAnalysis {\n readonly filePath: string\n readonly importsByLocalName: Map<string, ImportBinding>\n readonly exportsByName: Map<string, string>\n readonly renderEntries: readonly PendingReactUsageEntry[]\n readonly symbolsById: Map<string, PendingReactUsageNode>\n readonly symbolsByName: Map<string, PendingReactUsageNode>\n}\n\ninterface SerializedReactUsageNode {\n readonly id: string\n readonly name: string\n readonly symbolKind: ReactSymbolKind | 'circular'\n readonly filePath: string\n readonly exportNames: readonly string[]\n readonly usages: readonly SerializedReactUsageEdge[]\n}\n\ninterface SerializedReactUsageEntry {\n readonly targetId: string\n readonly filePath: string\n readonly line: number\n readonly column: number\n readonly node: SerializedReactUsageNode\n}\n\ninterface SerializedReactUsageEdge {\n readonly kind: ReactUsageEdge['kind']\n readonly targetId: string\n readonly node: SerializedReactUsageNode\n}\n\nconst FUNCTION_NODE_TYPES = new Set([\n 'FunctionDeclaration',\n 'FunctionExpression',\n 'ArrowFunctionExpression',\n 'TSDeclareFunction',\n 'TSEmptyBodyFunctionExpression',\n])\n\nexport function analyzeReactUsage(\n entryFile: string,\n options: AnalyzeOptions = {},\n): ReactUsageGraph {\n const dependencyGraph = analyzeDependencies(entryFile, options)\n const reachableFiles = new Set<string>([\n dependencyGraph.entryId,\n ...dependencyGraph.nodes.keys(),\n ])\n const fileAnalyses = new Map<string, FileAnalysis>()\n\n for (const filePath of [...reachableFiles].sort()) {\n if (!isSourceCodeFile(filePath) || filePath.endsWith('.d.ts')) {\n continue\n }\n\n const sourceText = fs.readFileSync(filePath, 'utf8')\n const parseResult = parseSync(filePath, sourceText, {\n astType: 'ts',\n sourceType: 'unambiguous',\n })\n\n const dependencyNode = dependencyGraph.nodes.get(filePath)\n const sourceDependencies = new Map<string, string>()\n dependencyNode?.dependencies.forEach((dependency) => {\n if (dependency.kind === 'source') {\n sourceDependencies.set(dependency.specifier, dependency.target)\n }\n })\n\n fileAnalyses.set(\n filePath,\n analyzeReactFile(\n parseResult.program,\n filePath,\n sourceText,\n sourceDependencies,\n ),\n )\n }\n\n const nodes = new Map<string, ReactUsageNode>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n nodes.set(symbol.id, {\n id: symbol.id,\n name: symbol.name,\n kind: symbol.kind,\n filePath: symbol.filePath,\n exportNames: [...symbol.exportNames].sort(),\n usages: [],\n })\n }\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n fileAnalysis.importsByLocalName.forEach((binding, localName) => {\n if (binding.sourcePath !== undefined) {\n return\n }\n\n if (!isHookName(localName) && !isHookName(binding.importedName)) {\n return\n }\n\n const externalNode = createExternalHookNode(binding, localName)\n if (!nodes.has(externalNode.id)) {\n nodes.set(externalNode.id, externalNode)\n }\n })\n }\n\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const symbol of fileAnalysis.symbolsById.values()) {\n const usages = new Map<string, ReactUsageEdge>()\n\n symbol.componentReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'component',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`render:${targetId}`, {\n kind: 'render',\n target: targetId,\n })\n }\n })\n\n symbol.hookReferences.forEach((referenceName) => {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n referenceName,\n 'hook',\n )\n if (targetId !== undefined && targetId !== symbol.id) {\n usages.set(`hook:${targetId}`, {\n kind: 'hook-call',\n target: targetId,\n })\n }\n })\n\n const node = nodes.get(symbol.id)\n if (node === undefined) {\n continue\n }\n\n const sortedUsages = [...usages.values()].sort((left, right) =>\n compareReactNodeIds(left.target, right.target, nodes),\n )\n\n nodes.set(symbol.id, {\n ...node,\n usages: sortedUsages,\n })\n }\n }\n\n const entriesByKey = new Map<string, ReactUsageEntry>()\n for (const fileAnalysis of fileAnalyses.values()) {\n for (const entry of fileAnalysis.renderEntries) {\n const targetId = resolveReactReference(\n fileAnalysis,\n fileAnalyses,\n entry.referenceName,\n 'component',\n )\n if (targetId === undefined) {\n continue\n }\n\n const key = `${entry.location.filePath}:${entry.location.line}:${entry.location.column}:${targetId}`\n entriesByKey.set(key, {\n target: targetId,\n location: entry.location,\n })\n }\n }\n\n const entries = [...entriesByKey.values()].sort((left, right) =>\n compareReactUsageEntries(left, right, nodes),\n )\n\n return {\n cwd: dependencyGraph.cwd,\n entryId: dependencyGraph.entryId,\n nodes,\n entries,\n }\n}\n\nexport function graphToSerializableReactTree(\n graph: ReactUsageGraph,\n options: {\n readonly filter?: ReactUsageFilter\n } = {},\n): object {\n const filter = options.filter ?? 'all'\n const entries = getReactUsageEntries(graph, filter)\n const roots =\n entries.length > 0\n ? entries.map((entry) =>\n serializeReactUsageNode(entry.target, graph, filter, new Set()),\n )\n : getReactUsageRoots(graph, filter).map((rootId) =>\n serializeReactUsageNode(rootId, graph, filter, new Set()),\n )\n\n return {\n kind: 'react-usage',\n entries: entries.map((entry) =>\n serializeReactUsageEntry(entry, graph, filter),\n ),\n roots,\n }\n}\n\nexport function getReactUsageEntries(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEntry[] {\n if (filter === 'hook') {\n return []\n }\n\n return graph.entries.filter((entry) => {\n const targetNode = graph.nodes.get(entry.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nexport function getReactUsageRoots(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): string[] {\n const entries = getReactUsageEntries(graph, filter)\n if (entries.length > 0) {\n return [...new Set(entries.map((entry) => entry.target))]\n }\n\n const filteredNodes = getFilteredReactUsageNodes(graph, filter)\n const inboundCounts = new Map<string, number>()\n\n filteredNodes.forEach((node) => {\n inboundCounts.set(node.id, 0)\n })\n\n filteredNodes.forEach((node) => {\n getFilteredUsages(node, graph, filter).forEach((usage) => {\n inboundCounts.set(\n usage.target,\n (inboundCounts.get(usage.target) ?? 0) + 1,\n )\n })\n })\n\n const roots = filteredNodes\n .filter((node) => (inboundCounts.get(node.id) ?? 0) === 0)\n .map((node) => node.id)\n\n if (roots.length > 0) {\n return roots.sort((left, right) =>\n compareReactNodeIds(left, right, graph.nodes),\n )\n }\n\n return filteredNodes\n .map((node) => node.id)\n .sort((left, right) => compareReactNodeIds(left, right, graph.nodes))\n}\n\nexport function getFilteredUsages(\n node: ReactUsageNode,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter = 'all',\n): ReactUsageEdge[] {\n return node.usages.filter((usage) => {\n const targetNode = graph.nodes.get(usage.target)\n return targetNode !== undefined && matchesReactFilter(targetNode, filter)\n })\n}\n\nfunction analyzeReactFile(\n program: Program,\n filePath: string,\n sourceText: string,\n sourceDependencies: ReadonlyMap<string, string>,\n): FileAnalysis {\n const symbolsByName = new Map<string, PendingReactUsageNode>()\n\n program.body.forEach((statement) => {\n collectTopLevelReactSymbols(statement, filePath, symbolsByName)\n })\n\n const importsByLocalName = new Map<string, ImportBinding>()\n const exportsByName = new Map<string, string>()\n const renderEntries = collectRenderEntries(program, filePath, sourceText)\n\n program.body.forEach((statement) => {\n collectImportsAndExports(\n statement,\n sourceDependencies,\n symbolsByName,\n importsByLocalName,\n exportsByName,\n )\n })\n\n symbolsByName.forEach((symbol) => {\n analyzeSymbolUsages(symbol)\n })\n\n return {\n filePath,\n importsByLocalName,\n exportsByName,\n renderEntries,\n symbolsById: new Map(\n [...symbolsByName.values()].map((symbol) => [symbol.id, symbol]),\n ),\n symbolsByName,\n }\n}\n\nfunction collectRenderEntries(\n program: Program,\n filePath: string,\n sourceText: string,\n): PendingReactUsageEntry[] {\n const entries = new Map<string, PendingReactUsageEntry>()\n\n program.body.forEach((statement) => {\n collectStatementRenderEntries(statement, filePath, sourceText, entries)\n })\n\n return [...entries.values()].sort(comparePendingReactUsageEntries)\n}\n\nfunction collectStatementRenderEntries(\n statement: Statement,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n): void {\n collectNodeRenderEntries(statement, filePath, sourceText, entries, false)\n}\n\nfunction collectNodeRenderEntries(\n node: Node,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n hasComponentAncestor: boolean,\n): void {\n if (FUNCTION_NODE_TYPES.has(node.type)) {\n return\n }\n\n let nextHasComponentAncestor = hasComponentAncestor\n\n if (node.type === 'JSXElement') {\n const referenceName = getComponentReferenceName(node)\n if (referenceName !== undefined) {\n if (!hasComponentAncestor) {\n addPendingRenderEntry(\n entries,\n referenceName,\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n nextHasComponentAncestor = true\n }\n } else if (node.type === 'CallExpression') {\n const referenceName = getCreateElementComponentReferenceName(node)\n if (referenceName !== undefined) {\n if (!hasComponentAncestor) {\n addPendingRenderEntry(\n entries,\n referenceName,\n createReactUsageLocation(filePath, sourceText, node.start),\n )\n }\n nextHasComponentAncestor = true\n }\n }\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n collectRenderEntryChild(\n value,\n filePath,\n sourceText,\n entries,\n nextHasComponentAncestor,\n )\n })\n}\n\nfunction collectRenderEntryChild(\n value: unknown,\n filePath: string,\n sourceText: string,\n entries: Map<string, PendingReactUsageEntry>,\n hasComponentAncestor: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n collectRenderEntryChild(\n entry,\n filePath,\n sourceText,\n entries,\n hasComponentAncestor,\n )\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n collectNodeRenderEntries(\n value,\n filePath,\n sourceText,\n entries,\n hasComponentAncestor,\n )\n}\n\nfunction addPendingRenderEntry(\n entries: Map<string, PendingReactUsageEntry>,\n referenceName: string,\n location: ReactUsageLocation,\n): void {\n const key = `${location.filePath}:${location.line}:${location.column}:${referenceName}`\n entries.set(key, {\n referenceName,\n location,\n })\n}\n\nfunction createReactUsageLocation(\n filePath: string,\n sourceText: string,\n offset: number,\n): ReactUsageLocation {\n return {\n filePath,\n ...offsetToLineAndColumn(sourceText, offset),\n }\n}\n\nfunction offsetToLineAndColumn(\n sourceText: string,\n offset: number,\n): Pick<ReactUsageLocation, 'line' | 'column'> {\n let line = 1\n let column = 1\n\n for (let index = 0; index < offset && index < sourceText.length; index += 1) {\n if (sourceText[index] === '\\n') {\n line += 1\n column = 1\n continue\n }\n\n column += 1\n }\n\n return { line, column }\n}\n\nfunction collectTopLevelReactSymbols(\n statement: Statement,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n switch (statement.type) {\n case 'FunctionDeclaration':\n addFunctionSymbol(statement, filePath, symbolsByName)\n return\n case 'VariableDeclaration':\n statement.declarations.forEach((declarator) => {\n addVariableSymbol(declarator, filePath, symbolsByName)\n })\n return\n case 'ExportNamedDeclaration':\n if (statement.declaration !== null) {\n collectTopLevelReactSymbols(\n statement.declaration,\n filePath,\n symbolsByName,\n )\n }\n return\n case 'ExportDefaultDeclaration':\n addDefaultExportSymbol(statement, filePath, symbolsByName)\n return\n default:\n return\n }\n}\n\nfunction addFunctionSymbol(\n declaration: OxcFunction,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n const name = declaration.id?.name\n if (name === undefined) {\n return\n }\n\n const kind = classifyReactSymbol(name, declaration)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration),\n )\n}\n\nfunction addVariableSymbol(\n declarator: VariableDeclarator,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (declarator.id.type !== 'Identifier' || declarator.init === null) {\n return\n }\n\n if (\n declarator.init.type !== 'ArrowFunctionExpression' &&\n declarator.init.type !== 'FunctionExpression'\n ) {\n return\n }\n\n const name = declarator.id.name\n const kind = classifyReactSymbol(name, declarator.init)\n if (kind === undefined) {\n return\n }\n\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declarator.init),\n )\n}\n\nfunction addDefaultExportSymbol(\n declaration: ExportDefaultDeclaration,\n filePath: string,\n symbolsByName: Map<string, PendingReactUsageNode>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n addFunctionSymbol(declaration.declaration, filePath, symbolsByName)\n } else if (declaration.declaration.type === 'ArrowFunctionExpression') {\n const name = 'default'\n const kind = declaration.declaration.body\n ? classifyReactSymbol(name, declaration.declaration)\n : undefined\n if (kind !== undefined) {\n symbolsByName.set(\n name,\n createPendingSymbol(filePath, name, kind, declaration.declaration),\n )\n }\n }\n}\n\nfunction createPendingSymbol(\n filePath: string,\n name: string,\n kind: ReactSymbolKind,\n declaration: OxcFunction | ArrowFunctionExpression,\n): PendingReactUsageNode {\n return {\n id: `${filePath}#${kind}:${name}`,\n name,\n kind,\n filePath,\n declaration,\n exportNames: new Set<string>(),\n componentReferences: new Set<string>(),\n hookReferences: new Set<string>(),\n }\n}\n\nfunction collectImportsAndExports(\n statement: Statement,\n sourceDependencies: ReadonlyMap<string, string>,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n importsByLocalName: Map<string, ImportBinding>,\n exportsByName: Map<string, string>,\n): void {\n switch (statement.type) {\n case 'ImportDeclaration':\n collectImportBindings(statement, sourceDependencies, importsByLocalName)\n return\n case 'ExportNamedDeclaration':\n collectNamedExports(statement, symbolsByName, exportsByName)\n return\n case 'ExportDefaultDeclaration':\n collectDefaultExport(statement, symbolsByName, exportsByName)\n return\n default:\n return\n }\n}\n\nfunction collectImportBindings(\n declaration: ImportDeclaration,\n sourceDependencies: ReadonlyMap<string, string>,\n importsByLocalName: Map<string, ImportBinding>,\n): void {\n if (declaration.importKind === 'type') {\n return\n }\n\n const sourceSpecifier = declaration.source.value\n const sourcePath = sourceDependencies.get(declaration.source.value)\n\n declaration.specifiers.forEach((specifier) => {\n const binding = getImportBinding(specifier, sourceSpecifier, sourcePath)\n if (binding === undefined) {\n return\n }\n\n importsByLocalName.set(binding.localName, {\n importedName: binding.importedName,\n sourceSpecifier: binding.sourceSpecifier,\n ...(binding.sourcePath === undefined\n ? {}\n : { sourcePath: binding.sourcePath }),\n })\n })\n}\n\nfunction getImportBinding(\n specifier: ImportDeclarationSpecifier,\n sourceSpecifier: string,\n sourcePath: string | undefined,\n):\n | {\n readonly localName: string\n readonly importedName: string\n readonly sourceSpecifier: string\n readonly sourcePath?: string\n }\n | undefined {\n if (specifier.type === 'ImportSpecifier') {\n if (specifier.importKind === 'type') {\n return undefined\n }\n\n return {\n localName: specifier.local.name,\n importedName: toModuleExportName(specifier.imported),\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n if (specifier.type === 'ImportDefaultSpecifier') {\n return {\n localName: specifier.local.name,\n importedName: 'default',\n sourceSpecifier,\n ...(sourcePath === undefined ? {} : { sourcePath }),\n }\n }\n\n return undefined\n}\n\nfunction collectNamedExports(\n declaration: ExportNamedDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (declaration.exportKind === 'type') {\n return\n }\n\n if (declaration.declaration !== null) {\n if (declaration.declaration.type === 'FunctionDeclaration') {\n const name = declaration.declaration.id?.name\n if (name !== undefined) {\n addExportBinding(name, name, symbolsByName, exportsByName)\n }\n } else if (declaration.declaration.type === 'VariableDeclaration') {\n declaration.declaration.declarations.forEach((declarator) => {\n if (declarator.id.type === 'Identifier') {\n addExportBinding(\n declarator.id.name,\n declarator.id.name,\n symbolsByName,\n exportsByName,\n )\n }\n })\n }\n\n return\n }\n\n if (declaration.source !== null) {\n return\n }\n\n declaration.specifiers.forEach((specifier) => {\n if (specifier.exportKind === 'type') {\n return\n }\n\n const localName = toModuleExportName(specifier.local)\n const exportedName = toModuleExportName(specifier.exported)\n addExportBinding(localName, exportedName, symbolsByName, exportsByName)\n })\n}\n\nfunction collectDefaultExport(\n declaration: ExportDefaultDeclaration,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n if (\n declaration.declaration.type === 'FunctionDeclaration' ||\n declaration.declaration.type === 'FunctionExpression'\n ) {\n const localName = declaration.declaration.id?.name\n if (localName !== undefined) {\n addExportBinding(localName, 'default', symbolsByName, exportsByName)\n }\n return\n }\n\n if (declaration.declaration.type === 'Identifier') {\n addExportBinding(\n declaration.declaration.name,\n 'default',\n symbolsByName,\n exportsByName,\n )\n return\n }\n\n if (declaration.declaration.type === 'ArrowFunctionExpression') {\n addExportBinding('default', 'default', symbolsByName, exportsByName)\n }\n}\n\nfunction addExportBinding(\n localName: string,\n exportedName: string,\n symbolsByName: ReadonlyMap<string, PendingReactUsageNode>,\n exportsByName: Map<string, string>,\n): void {\n const symbol = symbolsByName.get(localName)\n if (symbol === undefined) {\n return\n }\n\n symbol.exportNames.add(exportedName)\n exportsByName.set(exportedName, symbol.id)\n}\n\nfunction analyzeSymbolUsages(symbol: PendingReactUsageNode): void {\n const root =\n symbol.declaration.type === 'ArrowFunctionExpression'\n ? symbol.declaration.body\n : symbol.declaration.body\n\n if (root === null) {\n return\n }\n\n walkReactUsageTree(root, (node) => {\n if (node.type === 'JSXElement') {\n const name = getComponentReferenceName(node)\n if (name !== undefined) {\n symbol.componentReferences.add(name)\n }\n return\n }\n\n if (node.type === 'CallExpression') {\n const hookReference = getHookReferenceName(node)\n if (hookReference !== undefined) {\n symbol.hookReferences.add(hookReference)\n }\n\n const componentReference = getCreateElementComponentReferenceName(node)\n if (componentReference !== undefined) {\n symbol.componentReferences.add(componentReference)\n }\n }\n })\n}\n\nfunction classifyReactSymbol(\n name: string,\n declaration: OxcFunction | ArrowFunctionExpression,\n): ReactSymbolKind | undefined {\n if (isHookName(name)) {\n return 'hook'\n }\n\n if (isComponentName(name) && returnsReactElement(declaration)) {\n return 'component'\n }\n\n return undefined\n}\n\nfunction returnsReactElement(\n declaration: OxcFunction | ArrowFunctionExpression,\n): boolean {\n if (\n declaration.type === 'ArrowFunctionExpression' &&\n declaration.expression\n ) {\n return containsReactElementLikeExpression(declaration.body as Expression)\n }\n\n const body = declaration.body\n if (body === null) {\n return false\n }\n\n let found = false\n walkReactUsageTree(body, (node) => {\n if (node.type !== 'ReturnStatement' || node.argument === null) {\n return\n }\n\n if (containsReactElementLikeExpression(node.argument)) {\n found = true\n }\n })\n\n return found\n}\n\nfunction containsReactElementLikeExpression(expression: Expression): boolean {\n let found = false\n\n walkNode(expression, (node) => {\n if (\n node.type === 'JSXElement' ||\n node.type === 'JSXFragment' ||\n (node.type === 'CallExpression' && isReactCreateElementCall(node))\n ) {\n found = true\n }\n })\n\n return found\n}\n\nfunction getComponentReferenceName(node: JSXElement): string | undefined {\n const name = getJsxName(node.openingElement.name)\n return name !== undefined && isComponentName(name) ? name : undefined\n}\n\nfunction getHookReferenceName(node: CallExpression): string | undefined {\n const calleeName = getIdentifierName(node.callee)\n return calleeName !== undefined && isHookName(calleeName)\n ? calleeName\n : undefined\n}\n\nfunction getCreateElementComponentReferenceName(\n node: CallExpression,\n): string | undefined {\n if (!isReactCreateElementCall(node)) {\n return undefined\n }\n\n const [firstArgument] = node.arguments\n if (firstArgument === undefined || firstArgument.type !== 'Identifier') {\n return undefined\n }\n\n return isComponentName(firstArgument.name) ? firstArgument.name : undefined\n}\n\nfunction isReactCreateElementCall(node: CallExpression): boolean {\n const callee = unwrapExpression(node.callee)\n if (callee.type !== 'MemberExpression' || callee.computed) {\n return false\n }\n\n return (\n callee.object.type === 'Identifier' &&\n callee.object.name === 'React' &&\n callee.property.name === 'createElement'\n )\n}\n\nfunction getJsxName(name: JSXElementName): string | undefined {\n if (name.type === 'JSXIdentifier') {\n return name.name\n }\n\n return undefined\n}\n\nfunction getIdentifierName(expression: Expression): string | undefined {\n const unwrapped = unwrapExpression(expression)\n return unwrapped.type === 'Identifier' ? unwrapped.name : undefined\n}\n\nfunction unwrapExpression(expression: Expression): Expression {\n let current = expression\n\n while (true) {\n if (\n current.type === 'ParenthesizedExpression' ||\n current.type === 'TSAsExpression' ||\n current.type === 'TSSatisfiesExpression' ||\n current.type === 'TSTypeAssertion' ||\n current.type === 'TSNonNullExpression'\n ) {\n current = current.expression\n continue\n }\n\n return current\n }\n}\n\nfunction walkReactUsageTree(\n root: FunctionBody | Expression | JSXFragment | JSXElement,\n visit: (node: Node) => void,\n): void {\n walkNode(root, visit, true)\n}\n\nfunction walkNode(\n node: Node,\n visit: (node: Node) => void,\n allowNestedFunctions = false,\n): void {\n visit(node)\n\n const keys = visitorKeys[node.type]\n if (keys === undefined) {\n return\n }\n\n keys.forEach((key) => {\n const value = (node as unknown as Record<string, unknown>)[key]\n walkChild(value, visit, allowNestedFunctions)\n })\n}\n\nfunction walkChild(\n value: unknown,\n visit: (node: Node) => void,\n allowNestedFunctions: boolean,\n): void {\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n walkChild(entry, visit, allowNestedFunctions)\n })\n return\n }\n\n if (!isNode(value)) {\n return\n }\n\n if (!allowNestedFunctions && FUNCTION_NODE_TYPES.has(value.type)) {\n return\n }\n\n walkNode(value, visit, false)\n}\n\nfunction isNode(value: unknown): value is Node {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n typeof (value as { type: unknown }).type === 'string'\n )\n}\n\nfunction resolveReactReference(\n fileAnalysis: FileAnalysis,\n fileAnalyses: ReadonlyMap<string, FileAnalysis>,\n name: string,\n kind: ReactSymbolKind,\n): string | undefined {\n const localSymbol = fileAnalysis.symbolsByName.get(name)\n if (localSymbol !== undefined && localSymbol.kind === kind) {\n return localSymbol.id\n }\n\n const importBinding = fileAnalysis.importsByLocalName.get(name)\n if (importBinding === undefined) {\n return undefined\n }\n\n if (importBinding.sourcePath === undefined) {\n return kind === 'hook'\n ? getExternalHookNodeId(importBinding, name)\n : undefined\n }\n\n const sourceFileAnalysis = fileAnalyses.get(importBinding.sourcePath)\n if (sourceFileAnalysis === undefined) {\n return undefined\n }\n\n const targetId = sourceFileAnalysis.exportsByName.get(\n importBinding.importedName,\n )\n if (targetId === undefined) {\n return undefined\n }\n\n const targetSymbol = sourceFileAnalysis.symbolsById.get(targetId)\n return targetSymbol?.kind === kind ? targetId : undefined\n}\n\nfunction createExternalHookNode(\n binding: ImportBinding,\n localName: string,\n): ReactUsageNode {\n const name = getExternalHookName(binding, localName)\n\n return {\n id: getExternalHookNodeId(binding, localName),\n name,\n kind: 'hook',\n filePath: binding.sourceSpecifier,\n exportNames: [binding.importedName],\n usages: [],\n }\n}\n\nfunction getExternalHookNodeId(\n binding: ImportBinding,\n localName: string,\n): string {\n return `external:${binding.sourceSpecifier}#hook:${getExternalHookName(binding, localName)}`\n}\n\nfunction getExternalHookName(\n binding: ImportBinding,\n localName: string,\n): string {\n return binding.importedName === 'default' ? localName : binding.importedName\n}\n\nfunction getFilteredReactUsageNodes(\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): ReactUsageNode[] {\n return [...graph.nodes.values()]\n .filter((node) => matchesReactFilter(node, filter))\n .sort((left, right) => compareReactNodes(left, right))\n}\n\nfunction matchesReactFilter(\n node: ReactUsageNode,\n filter: ReactUsageFilter,\n): boolean {\n return filter === 'all' || node.kind === filter\n}\n\nfunction serializeReactUsageNode(\n nodeId: string,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n visited: Set<string>,\n): SerializedReactUsageNode {\n const node = graph.nodes.get(nodeId)\n if (node === undefined) {\n return {\n id: nodeId,\n name: nodeId,\n symbolKind: 'circular',\n filePath: '',\n exportNames: [],\n usages: [],\n }\n }\n\n if (visited.has(nodeId)) {\n return {\n id: node.id,\n name: node.name,\n symbolKind: 'circular',\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: [],\n }\n }\n\n const nextVisited = new Set(visited)\n nextVisited.add(nodeId)\n\n return {\n id: node.id,\n name: node.name,\n symbolKind: node.kind,\n filePath: toDisplayPath(node.filePath, graph.cwd),\n exportNames: node.exportNames,\n usages: getFilteredUsages(node, graph, filter).map((usage) => ({\n kind: usage.kind,\n targetId: usage.target,\n node: serializeReactUsageNode(usage.target, graph, filter, nextVisited),\n })),\n }\n}\n\nfunction serializeReactUsageEntry(\n entry: ReactUsageEntry,\n graph: ReactUsageGraph,\n filter: ReactUsageFilter,\n): SerializedReactUsageEntry {\n return {\n targetId: entry.target,\n filePath: toDisplayPath(entry.location.filePath, graph.cwd),\n line: entry.location.line,\n column: entry.location.column,\n node: serializeReactUsageNode(entry.target, graph, filter, new Set()),\n }\n}\n\nfunction compareReactNodeIds(\n leftId: string,\n rightId: string,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n const left = nodes.get(leftId)\n const right = nodes.get(rightId)\n\n if (left === undefined || right === undefined) {\n return leftId.localeCompare(rightId)\n }\n\n return compareReactNodes(left, right)\n}\n\nfunction compareReactUsageEntries(\n left: ReactUsageEntry,\n right: ReactUsageEntry,\n nodes: ReadonlyMap<string, ReactUsageNode>,\n): number {\n return (\n left.location.filePath.localeCompare(right.location.filePath) ||\n left.location.line - right.location.line ||\n left.location.column - right.location.column ||\n compareReactNodeIds(left.target, right.target, nodes)\n )\n}\n\nfunction comparePendingReactUsageEntries(\n left: PendingReactUsageEntry,\n right: PendingReactUsageEntry,\n): number {\n return (\n left.location.filePath.localeCompare(right.location.filePath) ||\n left.location.line - right.location.line ||\n left.location.column - right.location.column ||\n left.referenceName.localeCompare(right.referenceName)\n )\n}\n\nfunction compareReactNodes(\n left: ReactUsageNode,\n right: ReactUsageNode,\n): number {\n return (\n left.filePath.localeCompare(right.filePath) ||\n left.name.localeCompare(right.name) ||\n left.kind.localeCompare(right.kind)\n )\n}\n\nfunction toModuleExportName(name: ModuleExportName): string {\n return name.type === 'Literal' ? name.value : name.name\n}\n\nfunction isHookName(name: string): boolean {\n return /^use[A-Z0-9]/.test(name)\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name)\n}\n","import process from 'node:process'\n\nimport type { ColorMode, ReactSymbolKind } from './types.js'\n\nconst ANSI_RESET = '\\u001B[0m'\nconst ANSI_COMPONENT = '\\u001B[36m'\nconst ANSI_HOOK = '\\u001B[35m'\nconst ANSI_UNUSED = '\\u001B[38;5;214m'\n\ninterface ResolveColorSupportOptions {\n readonly forceColor?: string | undefined\n readonly isTTY?: boolean | undefined\n readonly noColor?: string | undefined\n}\n\nexport function resolveColorSupport(\n mode: ColorMode = 'auto',\n options: ResolveColorSupportOptions = {},\n): boolean {\n if (mode === true) {\n return true\n }\n\n if (mode === false) {\n return false\n }\n\n const forceColor =\n 'forceColor' in options ? options.forceColor : process.env.FORCE_COLOR\n if (forceColor !== undefined) {\n return forceColor !== '0'\n }\n\n const noColor = 'noColor' in options ? options.noColor : process.env.NO_COLOR\n if (noColor !== undefined) {\n return false\n }\n\n const isTTY = 'isTTY' in options ? options.isTTY : process.stdout.isTTY\n return isTTY === true\n}\n\nexport function colorizeUnusedMarker(text: string, enabled: boolean): string {\n if (!enabled) {\n return text\n }\n\n return text.replaceAll('(unused)', `${ANSI_UNUSED}(unused)${ANSI_RESET}`)\n}\n\nexport function formatReactSymbolLabel(\n name: string,\n kind: ReactSymbolKind,\n enabled: boolean,\n): string {\n const label = `${name} [${kind}]`\n if (!enabled) {\n return label\n }\n\n const color = kind === 'component' ? ANSI_COMPONENT : ANSI_HOOK\n return `${color}${label}${ANSI_RESET}`\n}\n","import { formatReactSymbolLabel, resolveColorSupport } from './color.js'\nimport { toDisplayPath } from './path-utils.js'\nimport {\n getFilteredUsages,\n getReactUsageEntries,\n getReactUsageRoots,\n} from './react-analyzer.js'\nimport type {\n PrintReactTreeOptions,\n ReactUsageEdge,\n ReactUsageEntry,\n ReactUsageGraph,\n ReactUsageNode,\n} from './types.js'\n\nexport function printReactUsageTree(\n graph: ReactUsageGraph,\n options: PrintReactTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const color = resolveColorSupport(options.color)\n const filter = options.filter ?? 'all'\n const entries = getReactUsageEntries(graph, filter)\n\n if (entries.length > 0) {\n return renderReactUsageEntries(graph, entries, cwd, filter, color)\n }\n\n const roots = getReactUsageRoots(graph, filter)\n if (roots.length === 0) {\n return 'No React symbols found.'\n }\n\n const lines: string[] = []\n roots.forEach((rootId, index) => {\n const root = graph.nodes.get(rootId)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactNodeLabel(root, cwd, color))\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n color,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < roots.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderReactUsageEntries(\n graph: ReactUsageGraph,\n entries: readonly ReactUsageEntry[],\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n color: boolean,\n): string {\n const lines: string[] = []\n\n entries.forEach((entry, index) => {\n const root = graph.nodes.get(entry.target)\n if (root === undefined) {\n return\n }\n\n lines.push(formatReactEntryLabel(entry, cwd))\n lines.push(formatReactNodeLabel(root, cwd, color))\n\n const usages = getFilteredUsages(root, graph, filter)\n usages.forEach((usage, usageIndex) => {\n lines.push(\n ...renderUsage(\n usage,\n graph,\n cwd,\n filter,\n color,\n new Set([root.id]),\n '',\n usageIndex === usages.length - 1,\n ),\n )\n })\n\n if (index < entries.length - 1) {\n lines.push('')\n }\n })\n\n return lines.join('\\n')\n}\n\nfunction renderUsage(\n usage: ReactUsageEdge,\n graph: ReactUsageGraph,\n cwd: string,\n filter: NonNullable<PrintReactTreeOptions['filter']>,\n color: boolean,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const target = graph.nodes.get(usage.target)\n\n if (target === undefined) {\n return [`${branch}${usage.target}`]\n }\n\n if (visited.has(target.id)) {\n return [`${branch}${formatReactNodeLabel(target, cwd, color)} (circular)`]\n }\n\n const childLines = [`${branch}${formatReactNodeLabel(target, cwd, color)}`]\n const nextVisited = new Set(visited)\n nextVisited.add(target.id)\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const childUsages = getFilteredUsages(target, graph, filter)\n\n childUsages.forEach((childUsage, index) => {\n childLines.push(\n ...renderUsage(\n childUsage,\n graph,\n cwd,\n filter,\n color,\n nextVisited,\n nextPrefix,\n index === childUsages.length - 1,\n ),\n )\n })\n\n return childLines\n}\n\nfunction formatReactNodeLabel(\n node: ReactUsageNode,\n cwd: string,\n color: boolean,\n): string {\n return `${formatReactSymbolLabel(node.name, node.kind, color)} (${toDisplayPath(node.filePath, cwd)})`\n}\n\nfunction formatReactEntryLabel(entry: ReactUsageEntry, cwd: string): string {\n return `${toDisplayPath(entry.location.filePath, cwd)}:${entry.location.line}:${entry.location.column}`\n}\n","import { colorizeUnusedMarker, resolveColorSupport } from './color.js'\nimport { toDisplayPath } from './path-utils.js'\nimport type {\n DependencyEdge,\n DependencyGraph,\n PrintTreeOptions,\n} from './types.js'\n\nexport function printDependencyTree(\n graph: DependencyGraph,\n options: PrintTreeOptions = {},\n): string {\n const cwd = options.cwd ?? graph.cwd\n const color = resolveColorSupport(options.color)\n const includeExternals = options.includeExternals ?? false\n const omitUnused = options.omitUnused ?? false\n const rootLines = [toDisplayPath(graph.entryId, cwd)]\n const visited = new Set<string>([graph.entryId])\n const entryNode = graph.nodes.get(graph.entryId)\n\n if (entryNode === undefined) {\n return rootLines.join('\\n')\n }\n\n const rootDependencies = filterDependencies(\n entryNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n rootDependencies.forEach((dependency, index) => {\n const isLast = index === rootDependencies.length - 1\n const lines = renderDependency(\n dependency,\n graph,\n visited,\n '',\n isLast,\n includeExternals,\n omitUnused,\n color,\n cwd,\n )\n rootLines.push(...lines)\n })\n\n return rootLines.join('\\n')\n}\n\nfunction renderDependency(\n dependency: DependencyEdge,\n graph: DependencyGraph,\n visited: ReadonlySet<string>,\n prefix: string,\n isLast: boolean,\n includeExternals: boolean,\n omitUnused: boolean,\n color: boolean,\n cwd: string,\n): string[] {\n const branch = `${prefix}${isLast ? '└─ ' : '├─ '}`\n const label = formatDependencyLabel(dependency, cwd, color)\n\n if (dependency.kind !== 'source') {\n return [`${branch}${label}`]\n }\n\n if (visited.has(dependency.target)) {\n return [`${branch}${label} (circular)`]\n }\n\n const childNode = graph.nodes.get(dependency.target)\n if (childNode === undefined) {\n return [`${branch}${label}`]\n }\n\n const nextPrefix = `${prefix}${isLast ? ' ' : '│ '}`\n const nextVisited = new Set(visited)\n nextVisited.add(dependency.target)\n\n const childLines = [`${branch}${label}`]\n const childDependencies = filterDependencies(\n childNode.dependencies,\n includeExternals,\n omitUnused,\n )\n\n childDependencies.forEach((childDependency, index) => {\n const isChildLast = index === childDependencies.length - 1\n childLines.push(\n ...renderDependency(\n childDependency,\n graph,\n nextVisited,\n nextPrefix,\n isChildLast,\n includeExternals,\n omitUnused,\n color,\n cwd,\n ),\n )\n })\n\n return childLines\n}\n\nfunction filterDependencies(\n dependencies: readonly DependencyEdge[],\n includeExternals: boolean,\n omitUnused: boolean,\n): DependencyEdge[] {\n return dependencies.filter((dependency) => {\n if (omitUnused && dependency.unused) {\n return false\n }\n\n if (dependency.kind === 'source' || dependency.kind === 'missing') {\n return true\n }\n\n return includeExternals\n })\n}\n\nfunction formatDependencyLabel(\n dependency: DependencyEdge,\n cwd: string,\n color: boolean,\n): string {\n const prefixes: string[] = []\n if (dependency.isTypeOnly) {\n prefixes.push('type')\n }\n\n if (dependency.referenceKind === 'require') {\n prefixes.push('require')\n } else if (dependency.referenceKind === 'dynamic-import') {\n prefixes.push('dynamic')\n } else if (dependency.referenceKind === 'export') {\n prefixes.push('re-export')\n } else if (dependency.referenceKind === 'import-equals') {\n prefixes.push('import=')\n }\n\n const annotation = prefixes.length > 0 ? `[${prefixes.join(', ')}] ` : ''\n\n if (dependency.kind === 'source') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${toDisplayPath(dependency.target, cwd)}`,\n dependency.unused,\n ),\n color,\n )\n }\n\n if (dependency.kind === 'missing') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.specifier} [missing]`,\n dependency.unused,\n ),\n color,\n )\n }\n\n if (dependency.kind === 'builtin') {\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.target} [builtin]`,\n dependency.unused,\n ),\n color,\n )\n }\n\n return colorizeUnusedMarker(\n withUnusedSuffix(\n `${annotation}${dependency.target} [external]`,\n dependency.unused,\n ),\n color,\n )\n}\n\nfunction withUnusedSuffix(label: string, unused: boolean): string {\n return unused ? `${label} (unused)` : label\n}\n"],"mappings":"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"}
|