@ebowwa/dependency-graph 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/dist/analysis.d.ts +31 -0
- package/dist/analysis.d.ts.map +1 -0
- package/dist/analysis.js +151 -0
- package/dist/analysis.js.map +1 -0
- package/dist/builder.d.ts +61 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +281 -0
- package/dist/builder.js.map +1 -0
- package/dist/formatters.d.ts +27 -0
- package/dist/formatters.d.ts.map +1 -0
- package/dist/formatters.js +145 -0
- package/dist/formatters.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
- package/src/analysis.ts +188 -0
- package/src/builder.ts +366 -0
- package/src/formatters.ts +191 -0
- package/src/index.ts +56 -0
- package/src/types.ts +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @ebowwa/dependency-graph
|
|
2
|
+
|
|
3
|
+
Core dependency graph analysis and visualization for monorepos.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @ebowwa/dependency-graph
|
|
9
|
+
# or
|
|
10
|
+
npm install @ebowwa/dependency-graph
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import {
|
|
17
|
+
DependencyGraphBuilder,
|
|
18
|
+
formatGraph,
|
|
19
|
+
analyzeImpact,
|
|
20
|
+
findCircularDependencies,
|
|
21
|
+
findUnusedPackages,
|
|
22
|
+
getPackageInfo
|
|
23
|
+
} from '@ebowwa/dependency-graph';
|
|
24
|
+
|
|
25
|
+
// Build the graph
|
|
26
|
+
const builder = new DependencyGraphBuilder('/path/to/monorepo');
|
|
27
|
+
const graph = await builder.build({
|
|
28
|
+
includeDevDependencies: false,
|
|
29
|
+
analyzeImports: true,
|
|
30
|
+
excludePatterns: ['^@types/', '^@eslint/']
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Format as Mermaid diagram
|
|
34
|
+
const mermaid = formatGraph(graph, 'mermaid');
|
|
35
|
+
|
|
36
|
+
// Format as ASCII tree
|
|
37
|
+
const tree = formatGraph(graph, 'tree');
|
|
38
|
+
|
|
39
|
+
// Find circular dependencies
|
|
40
|
+
const cycles = findCircularDependencies(graph, 10);
|
|
41
|
+
|
|
42
|
+
// Analyze impact of changing a package
|
|
43
|
+
const impact = analyzeImpact(graph, '@ebowwa/terminal', true);
|
|
44
|
+
console.log(`Direct: ${impact.direct}`);
|
|
45
|
+
console.log(`Transitive: ${impact.transitive}`);
|
|
46
|
+
|
|
47
|
+
// Find unused packages
|
|
48
|
+
const unused = findUnusedPackages(graph);
|
|
49
|
+
|
|
50
|
+
// Get package info
|
|
51
|
+
const info = getPackageInfo(graph, '@ebowwa/ssh');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### `DependencyGraphBuilder`
|
|
57
|
+
|
|
58
|
+
Builds dependency graphs from package.json and import analysis.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const builder = new DependencyGraphBuilder(monorepoRoot);
|
|
62
|
+
const graph = await builder.build(options);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Options:**
|
|
66
|
+
- `includeDevDependencies` - Include devDependencies (default: false)
|
|
67
|
+
- `analyzeImports` - Analyze TypeScript/JavaScript imports (default: true)
|
|
68
|
+
- `excludePatterns` - Regex patterns to exclude (default: [])
|
|
69
|
+
|
|
70
|
+
### Formatters
|
|
71
|
+
|
|
72
|
+
- `formatGraph(graph, format)` - Format graph (json, mermaid, dot, tree)
|
|
73
|
+
- `formatAsJson(graph)` - JSON output
|
|
74
|
+
- `formatAsMermaid(graph)` - Mermaid diagram
|
|
75
|
+
- `formatAsDot(graph)` - Graphviz DOT format
|
|
76
|
+
- `formatAsTree(graph)` - ASCII tree visualization
|
|
77
|
+
|
|
78
|
+
### Analysis
|
|
79
|
+
|
|
80
|
+
- `findCircularDependencies(graph, maxDepth)` - Find dependency cycles
|
|
81
|
+
- `analyzeImpact(graph, packageName, includeTransitive)` - Impact analysis
|
|
82
|
+
- `findUnusedPackages(graph, includeExternal)` - Find packages with no dependents
|
|
83
|
+
- `getPackageInfo(graph, packageName)` - Get detailed package info
|
|
84
|
+
- `getWorkspacePackages(graph)` - Get all workspace packages
|
|
85
|
+
- `getExternalDependencies(graph)` - Get all external dependencies
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ebowwa/dependency-graph - Analysis Functions
|
|
3
|
+
*
|
|
4
|
+
* Circular dependency detection, impact analysis, unused code detection
|
|
5
|
+
*/
|
|
6
|
+
import type { DependencyGraph, ImpactResult, PackageInfo } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Find circular dependencies using DFS
|
|
9
|
+
*/
|
|
10
|
+
export declare function findCircularDependencies(graph: DependencyGraph, maxDepth?: number): string[][];
|
|
11
|
+
/**
|
|
12
|
+
* Analyze the impact of changing a package
|
|
13
|
+
*/
|
|
14
|
+
export declare function analyzeImpact(graph: DependencyGraph, packageName: string, includeTransitive?: boolean): ImpactResult;
|
|
15
|
+
/**
|
|
16
|
+
* Find potentially unused packages (no dependents)
|
|
17
|
+
*/
|
|
18
|
+
export declare function findUnusedPackages(graph: DependencyGraph, includeExternal?: boolean): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Get detailed information about a specific package
|
|
21
|
+
*/
|
|
22
|
+
export declare function getPackageInfo(graph: DependencyGraph, packageName: string): PackageInfo | null;
|
|
23
|
+
/**
|
|
24
|
+
* Get all workspace packages
|
|
25
|
+
*/
|
|
26
|
+
export declare function getWorkspacePackages(graph: DependencyGraph): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Get all external dependencies
|
|
29
|
+
*/
|
|
30
|
+
export declare function getExternalDependencies(graph: DependencyGraph): string[];
|
|
31
|
+
//# sourceMappingURL=analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.d.ts","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE7E;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,eAAe,EACtB,QAAQ,GAAE,MAAW,GACpB,MAAM,EAAE,EAAE,CAsCZ;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,EACnB,iBAAiB,GAAE,OAAc,GAChC,YAAY,CA0Bd;AAoBD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,eAAe,GAAE,OAAe,GAC/B,MAAM,EAAE,CAaV;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,MAAM,GAClB,WAAW,GAAG,IAAI,CA2BpB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE,CAQrE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,EAAE,CAQxE"}
|
package/dist/analysis.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ebowwa/dependency-graph - Analysis Functions
|
|
3
|
+
*
|
|
4
|
+
* Circular dependency detection, impact analysis, unused code detection
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Find circular dependencies using DFS
|
|
8
|
+
*/
|
|
9
|
+
export function findCircularDependencies(graph, maxDepth = 10) {
|
|
10
|
+
const cycles = [];
|
|
11
|
+
const visited = new Set();
|
|
12
|
+
const recursionStack = new Set();
|
|
13
|
+
function dfs(node, path) {
|
|
14
|
+
if (path.length > maxDepth)
|
|
15
|
+
return;
|
|
16
|
+
visited.add(node);
|
|
17
|
+
recursionStack.add(node);
|
|
18
|
+
path.push(node);
|
|
19
|
+
// Check all outgoing edges
|
|
20
|
+
for (const edge of graph.edges) {
|
|
21
|
+
if (edge.from === node) {
|
|
22
|
+
if (recursionStack.has(edge.to)) {
|
|
23
|
+
// Found a cycle
|
|
24
|
+
const cycleStart = path.indexOf(edge.to);
|
|
25
|
+
if (cycleStart >= 0) {
|
|
26
|
+
cycles.push([...path.slice(cycleStart), edge.to]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
else if (!visited.has(edge.to)) {
|
|
30
|
+
dfs(edge.to, [...path]);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
recursionStack.delete(node);
|
|
35
|
+
}
|
|
36
|
+
// Start DFS from each workspace node
|
|
37
|
+
for (const [name, node] of graph.nodes) {
|
|
38
|
+
if (node.type === "workspace" && !visited.has(name)) {
|
|
39
|
+
dfs(name, []);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return cycles;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Analyze the impact of changing a package
|
|
46
|
+
*/
|
|
47
|
+
export function analyzeImpact(graph, packageName, includeTransitive = true) {
|
|
48
|
+
const direct = [];
|
|
49
|
+
const transitive = [];
|
|
50
|
+
const visited = new Set();
|
|
51
|
+
// Get direct dependents
|
|
52
|
+
const directDependents = graph.reverseEdges.get(packageName);
|
|
53
|
+
if (directDependents) {
|
|
54
|
+
for (const dep of directDependents) {
|
|
55
|
+
direct.push(dep);
|
|
56
|
+
visited.add(dep);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Get transitive dependents
|
|
60
|
+
if (includeTransitive) {
|
|
61
|
+
for (const dep of direct) {
|
|
62
|
+
collectTransitive(graph, dep, visited, transitive);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
direct,
|
|
67
|
+
transitive,
|
|
68
|
+
all: Array.from(visited),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function collectTransitive(graph, packageName, visited, result) {
|
|
72
|
+
const dependents = graph.reverseEdges.get(packageName);
|
|
73
|
+
if (!dependents)
|
|
74
|
+
return;
|
|
75
|
+
for (const dep of dependents) {
|
|
76
|
+
if (!visited.has(dep)) {
|
|
77
|
+
visited.add(dep);
|
|
78
|
+
result.push(dep);
|
|
79
|
+
collectTransitive(graph, dep, visited, result);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Find potentially unused packages (no dependents)
|
|
85
|
+
*/
|
|
86
|
+
export function findUnusedPackages(graph, includeExternal = false) {
|
|
87
|
+
const unused = [];
|
|
88
|
+
for (const [name, node] of graph.nodes) {
|
|
89
|
+
if (node.type === "workspace" || includeExternal) {
|
|
90
|
+
const dependents = graph.reverseEdges.get(name);
|
|
91
|
+
if (!dependents || dependents.size === 0) {
|
|
92
|
+
unused.push(name);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return unused;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get detailed information about a specific package
|
|
100
|
+
*/
|
|
101
|
+
export function getPackageInfo(graph, packageName) {
|
|
102
|
+
const node = graph.nodes.get(packageName);
|
|
103
|
+
if (!node)
|
|
104
|
+
return null;
|
|
105
|
+
// Get dependencies
|
|
106
|
+
const dependencies = graph.edges
|
|
107
|
+
.filter((e) => e.from === packageName)
|
|
108
|
+
.map((edge) => {
|
|
109
|
+
const depNode = graph.nodes.get(edge.to);
|
|
110
|
+
return {
|
|
111
|
+
name: edge.to,
|
|
112
|
+
type: edge.type,
|
|
113
|
+
version: depNode?.version,
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
// Get dependents
|
|
117
|
+
const dependents = Array.from(graph.reverseEdges.get(packageName) || []);
|
|
118
|
+
return {
|
|
119
|
+
name: packageName,
|
|
120
|
+
type: node.type,
|
|
121
|
+
path: node.path || "N/A",
|
|
122
|
+
version: node.version,
|
|
123
|
+
dependencies,
|
|
124
|
+
dependents,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get all workspace packages
|
|
129
|
+
*/
|
|
130
|
+
export function getWorkspacePackages(graph) {
|
|
131
|
+
const packages = [];
|
|
132
|
+
for (const [name, node] of graph.nodes) {
|
|
133
|
+
if (node.type === "workspace") {
|
|
134
|
+
packages.push(name);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return packages;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get all external dependencies
|
|
141
|
+
*/
|
|
142
|
+
export function getExternalDependencies(graph) {
|
|
143
|
+
const deps = [];
|
|
144
|
+
for (const [name, node] of graph.nodes) {
|
|
145
|
+
if (node.type === "external") {
|
|
146
|
+
deps.push(name);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return deps;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=analysis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.js","sourceRoot":"","sources":["../src/analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ebowwa/dependency-graph - Graph Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds dependency graphs from package.json and import analysis
|
|
5
|
+
*/
|
|
6
|
+
import type { DependencyGraph, BuildOptions } from "./types.js";
|
|
7
|
+
export declare class DependencyGraphBuilder {
|
|
8
|
+
private monorepoRoot;
|
|
9
|
+
private graph;
|
|
10
|
+
private packageCache;
|
|
11
|
+
constructor(monorepoRoot: string);
|
|
12
|
+
/**
|
|
13
|
+
* Build the complete dependency graph
|
|
14
|
+
*/
|
|
15
|
+
build(options?: BuildOptions): Promise<DependencyGraph>;
|
|
16
|
+
/**
|
|
17
|
+
* Discover all package.json files in the monorepo
|
|
18
|
+
*/
|
|
19
|
+
private discoverPackages;
|
|
20
|
+
/**
|
|
21
|
+
* Recursively search for package.json files
|
|
22
|
+
*/
|
|
23
|
+
private searchDirectory;
|
|
24
|
+
/**
|
|
25
|
+
* Analyze package.json dependencies
|
|
26
|
+
*/
|
|
27
|
+
private analyzePackageDependencies;
|
|
28
|
+
/**
|
|
29
|
+
* Analyze TypeScript/JavaScript imports
|
|
30
|
+
*/
|
|
31
|
+
private analyzeImports;
|
|
32
|
+
/**
|
|
33
|
+
* Recursively analyze imports in a directory
|
|
34
|
+
*/
|
|
35
|
+
private analyzeImportsInDirectory;
|
|
36
|
+
/**
|
|
37
|
+
* Analyze imports in a single file
|
|
38
|
+
*/
|
|
39
|
+
private analyzeImportsInFile;
|
|
40
|
+
/**
|
|
41
|
+
* Add a node to the graph
|
|
42
|
+
*/
|
|
43
|
+
private addNode;
|
|
44
|
+
/**
|
|
45
|
+
* Add an edge to the graph
|
|
46
|
+
*/
|
|
47
|
+
private addEdge;
|
|
48
|
+
/**
|
|
49
|
+
* Build reverse edges for impact analysis
|
|
50
|
+
*/
|
|
51
|
+
private buildReverseEdges;
|
|
52
|
+
/**
|
|
53
|
+
* Get the built graph
|
|
54
|
+
*/
|
|
55
|
+
getGraph(): DependencyGraph;
|
|
56
|
+
/**
|
|
57
|
+
* Get the monorepo root
|
|
58
|
+
*/
|
|
59
|
+
getMonorepoRoot(): string;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EACV,eAAe,EAGf,YAAY,EACb,MAAM,YAAY,CAAC;AAQpB,qBAAa,sBAAsB;IACjC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,YAAY,CAA0E;gBAElF,YAAY,EAAE,MAAM;IAShC;;OAEG;IACG,KAAK,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,eAAe,CAAC;IAkCjE;;OAEG;YACW,gBAAgB;IAqB9B;;OAEG;YACW,eAAe;IAuD7B;;OAEG;YACW,0BAA0B;IA+CxC;;OAEG;YACW,cAAc;IAa5B;;OAEG;YACW,yBAAyB;IA8BvC;;OAEG;YACW,oBAAoB;IA4ClC;;OAEG;IACH,OAAO,CAAC,OAAO;IAYf;;OAEG;IACH,OAAO,CAAC,OAAO;IAsBf;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,QAAQ,IAAI,eAAe;IAI3B;;OAEG;IACH,eAAe,IAAI,MAAM;CAG1B"}
|
package/dist/builder.js
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ebowwa/dependency-graph - Graph Builder
|
|
3
|
+
*
|
|
4
|
+
* Builds dependency graphs from package.json and import analysis
|
|
5
|
+
*/
|
|
6
|
+
import { readdirSync, readFileSync, existsSync } from "node:fs";
|
|
7
|
+
import { join, dirname, relative } from "node:path";
|
|
8
|
+
export class DependencyGraphBuilder {
|
|
9
|
+
monorepoRoot;
|
|
10
|
+
graph;
|
|
11
|
+
packageCache = new Map();
|
|
12
|
+
constructor(monorepoRoot) {
|
|
13
|
+
this.monorepoRoot = monorepoRoot;
|
|
14
|
+
this.graph = {
|
|
15
|
+
nodes: new Map(),
|
|
16
|
+
edges: [],
|
|
17
|
+
reverseEdges: new Map(),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build the complete dependency graph
|
|
22
|
+
*/
|
|
23
|
+
async build(options = {}) {
|
|
24
|
+
const { includeDevDependencies = false, analyzeImports = true, excludePatterns = [], } = options;
|
|
25
|
+
// Discover all packages in the monorepo
|
|
26
|
+
const packages = await this.discoverPackages();
|
|
27
|
+
// Add nodes for all packages
|
|
28
|
+
for (const pkg of packages) {
|
|
29
|
+
this.addNode(pkg.name, pkg.path, "workspace", pkg.version);
|
|
30
|
+
}
|
|
31
|
+
// Analyze dependencies for each package
|
|
32
|
+
for (const pkg of packages) {
|
|
33
|
+
await this.analyzePackageDependencies(pkg, includeDevDependencies, excludePatterns);
|
|
34
|
+
if (analyzeImports) {
|
|
35
|
+
await this.analyzeImports(pkg);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Build reverse edges for impact analysis
|
|
39
|
+
this.buildReverseEdges();
|
|
40
|
+
return this.graph;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Discover all package.json files in the monorepo
|
|
44
|
+
*/
|
|
45
|
+
async discoverPackages() {
|
|
46
|
+
const packages = [];
|
|
47
|
+
const seen = new Set();
|
|
48
|
+
// Search in common locations
|
|
49
|
+
const searchPaths = [
|
|
50
|
+
this.monorepoRoot,
|
|
51
|
+
join(this.monorepoRoot, "packages"),
|
|
52
|
+
join(this.monorepoRoot, "packages/src"),
|
|
53
|
+
join(this.monorepoRoot, "apps"),
|
|
54
|
+
join(this.monorepoRoot, "MCP/packages"),
|
|
55
|
+
];
|
|
56
|
+
for (const searchPath of searchPaths) {
|
|
57
|
+
if (!existsSync(searchPath))
|
|
58
|
+
continue;
|
|
59
|
+
await this.searchDirectory(searchPath, packages, seen, 0, 4);
|
|
60
|
+
}
|
|
61
|
+
return packages;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Recursively search for package.json files
|
|
65
|
+
*/
|
|
66
|
+
async searchDirectory(dir, packages, seen, depth, maxDepth) {
|
|
67
|
+
if (depth > maxDepth)
|
|
68
|
+
return;
|
|
69
|
+
try {
|
|
70
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
// Skip node_modules and hidden dirs
|
|
73
|
+
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
74
|
+
continue;
|
|
75
|
+
if (entry.name === "dist" || entry.name === "build")
|
|
76
|
+
continue;
|
|
77
|
+
const fullPath = join(dir, entry.name);
|
|
78
|
+
if (entry.isDirectory()) {
|
|
79
|
+
await this.searchDirectory(fullPath, packages, seen, depth + 1, maxDepth);
|
|
80
|
+
}
|
|
81
|
+
else if (entry.name === "package.json") {
|
|
82
|
+
const packageDir = dirname(fullPath);
|
|
83
|
+
const relativePath = relative(this.monorepoRoot, packageDir);
|
|
84
|
+
if (seen.has(relativePath))
|
|
85
|
+
continue;
|
|
86
|
+
seen.add(relativePath);
|
|
87
|
+
try {
|
|
88
|
+
const pkg = JSON.parse(readFileSync(fullPath, "utf-8"));
|
|
89
|
+
if (pkg.name && !pkg.private) {
|
|
90
|
+
packages.push({
|
|
91
|
+
name: pkg.name,
|
|
92
|
+
path: relativePath,
|
|
93
|
+
version: pkg.version || "0.0.0",
|
|
94
|
+
});
|
|
95
|
+
this.packageCache.set(pkg.name, { path: relativePath, pkg });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Invalid package.json, skip
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Directory not accessible, skip
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Analyze package.json dependencies
|
|
110
|
+
*/
|
|
111
|
+
async analyzePackageDependencies(pkg, includeDev, excludePatterns) {
|
|
112
|
+
const pkgPath = join(this.monorepoRoot, pkg.path, "package.json");
|
|
113
|
+
if (!existsSync(pkgPath))
|
|
114
|
+
return;
|
|
115
|
+
const packageJson = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
116
|
+
const depTypes = ["dependencies"];
|
|
117
|
+
if (includeDev)
|
|
118
|
+
depTypes.push("devDependencies", "peerDependencies", "optionalDependencies");
|
|
119
|
+
for (const depType of depTypes) {
|
|
120
|
+
const deps = packageJson[depType];
|
|
121
|
+
if (!deps)
|
|
122
|
+
continue;
|
|
123
|
+
for (const [depName, depVersion] of Object.entries(deps)) {
|
|
124
|
+
// Check if this matches any exclude pattern
|
|
125
|
+
if (excludePatterns.some((pattern) => depName.match(pattern)))
|
|
126
|
+
continue;
|
|
127
|
+
const isWorkspace = depVersion === "workspace:*" ||
|
|
128
|
+
depVersion === "workspace:^" ||
|
|
129
|
+
depVersion === "workspace:~";
|
|
130
|
+
if (isWorkspace) {
|
|
131
|
+
// This is a workspace dependency
|
|
132
|
+
const targetPkg = this.packageCache.get(depName);
|
|
133
|
+
if (targetPkg) {
|
|
134
|
+
this.addEdge(pkg.name, depName, "workspace");
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
else if (this.packageCache.has(depName)) {
|
|
138
|
+
// It's a local package but not using workspace: protocol
|
|
139
|
+
this.addEdge(pkg.name, depName, "workspace");
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// External dependency
|
|
143
|
+
this.addNode(depName, "", "external", depVersion);
|
|
144
|
+
this.addEdge(pkg.name, depName, "external");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Analyze TypeScript/JavaScript imports
|
|
151
|
+
*/
|
|
152
|
+
async analyzeImports(pkg) {
|
|
153
|
+
const pkgDir = join(this.monorepoRoot, pkg.path);
|
|
154
|
+
// Common source directories
|
|
155
|
+
const sourceDirs = ["src", "lib", ""];
|
|
156
|
+
for (const sourceDir of sourceDirs) {
|
|
157
|
+
const searchPath = sourceDir ? join(pkgDir, sourceDir) : pkgDir;
|
|
158
|
+
if (!existsSync(searchPath))
|
|
159
|
+
continue;
|
|
160
|
+
await this.analyzeImportsInDirectory(pkg.name, searchPath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Recursively analyze imports in a directory
|
|
165
|
+
*/
|
|
166
|
+
async analyzeImportsInDirectory(packageName, dir) {
|
|
167
|
+
try {
|
|
168
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
169
|
+
for (const entry of entries) {
|
|
170
|
+
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
171
|
+
continue;
|
|
172
|
+
if (entry.name === "dist" || entry.name === "build")
|
|
173
|
+
continue;
|
|
174
|
+
const fullPath = join(dir, entry.name);
|
|
175
|
+
if (entry.isDirectory()) {
|
|
176
|
+
await this.analyzeImportsInDirectory(packageName, fullPath);
|
|
177
|
+
}
|
|
178
|
+
else if (entry.name.endsWith(".ts") ||
|
|
179
|
+
entry.name.endsWith(".tsx") ||
|
|
180
|
+
entry.name.endsWith(".js") ||
|
|
181
|
+
entry.name.endsWith(".jsx") ||
|
|
182
|
+
entry.name.endsWith(".mjs")) {
|
|
183
|
+
await this.analyzeImportsInFile(packageName, fullPath);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
// Directory not accessible
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Analyze imports in a single file
|
|
193
|
+
*/
|
|
194
|
+
async analyzeImportsInFile(packageName, filePath) {
|
|
195
|
+
try {
|
|
196
|
+
const content = readFileSync(filePath, "utf-8");
|
|
197
|
+
// Match various import patterns
|
|
198
|
+
const importPatterns = [
|
|
199
|
+
// ES imports: import ... from '...' | import ... from "..."
|
|
200
|
+
/import\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s*,?\s*)*\s+from\s+['"]([^'"]+)['"]/g,
|
|
201
|
+
// Dynamic imports: import('...')
|
|
202
|
+
/import\(['"]([^'"]+)['"]\)/g,
|
|
203
|
+
// require(): require('...') | require("...")
|
|
204
|
+
/require\(['"]([^'"]+)['"]\)/g,
|
|
205
|
+
// Export from: export ... from '...'
|
|
206
|
+
/export\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+)\s+from\s+)?['"]([^'"]+)['"]/g,
|
|
207
|
+
];
|
|
208
|
+
for (const pattern of importPatterns) {
|
|
209
|
+
let match;
|
|
210
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
211
|
+
const importPath = match[1];
|
|
212
|
+
// Skip relative imports
|
|
213
|
+
if (importPath.startsWith(".") || importPath.startsWith("/"))
|
|
214
|
+
continue;
|
|
215
|
+
// Check if this is a known workspace package
|
|
216
|
+
for (const [pkgName, pkgData] of this.packageCache) {
|
|
217
|
+
if (importPath === pkgName ||
|
|
218
|
+
importPath.startsWith(pkgName + "/")) {
|
|
219
|
+
this.addEdge(packageName, pkgName, "import", importPath);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// File not readable
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Add a node to the graph
|
|
232
|
+
*/
|
|
233
|
+
addNode(name, path, type, version) {
|
|
234
|
+
if (!this.graph.nodes.has(name)) {
|
|
235
|
+
this.graph.nodes.set(name, { name, path, type, version });
|
|
236
|
+
this.graph.reverseEdges.set(name, new Set());
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Add an edge to the graph
|
|
241
|
+
*/
|
|
242
|
+
addEdge(from, to, type, importPath) {
|
|
243
|
+
// Skip self-references
|
|
244
|
+
if (from === to)
|
|
245
|
+
return;
|
|
246
|
+
// Check if edge already exists
|
|
247
|
+
const existing = this.graph.edges.find((e) => e.from === from && e.to === to);
|
|
248
|
+
if (existing)
|
|
249
|
+
return;
|
|
250
|
+
this.graph.edges.push({ from, to, type, importPath });
|
|
251
|
+
// Update reverse edges
|
|
252
|
+
if (!this.graph.reverseEdges.has(to)) {
|
|
253
|
+
this.graph.reverseEdges.set(to, new Set());
|
|
254
|
+
}
|
|
255
|
+
this.graph.reverseEdges.get(to).add(from);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Build reverse edges for impact analysis
|
|
259
|
+
*/
|
|
260
|
+
buildReverseEdges() {
|
|
261
|
+
for (const [to, dependents] of this.graph.reverseEdges) {
|
|
262
|
+
// Ensure node exists
|
|
263
|
+
if (!this.graph.nodes.has(to)) {
|
|
264
|
+
this.graph.nodes.set(to, { name: to, path: "", type: "external" });
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Get the built graph
|
|
270
|
+
*/
|
|
271
|
+
getGraph() {
|
|
272
|
+
return this.graph;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Get the monorepo root
|
|
276
|
+
*/
|
|
277
|
+
getMonorepoRoot() {
|
|
278
|
+
return this.monorepoRoot;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAcpD,MAAM,OAAO,sBAAsB;IACzB,YAAY,CAAS;IACrB,KAAK,CAAkB;IACvB,YAAY,GAAgE,IAAI,GAAG,EAAE,CAAC;IAE9F,YAAY,YAAoB;QAC9B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG;YACX,KAAK,EAAE,IAAI,GAAG,EAAE;YAChB,KAAK,EAAE,EAAE;YACT,YAAY,EAAE,IAAI,GAAG,EAAE;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,UAAwB,EAAE;QACpC,MAAM,EACJ,sBAAsB,GAAG,KAAK,EAC9B,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,EAAE,GACrB,GAAG,OAAO,CAAC;QAEZ,wCAAwC;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE/C,6BAA6B;QAC7B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7D,CAAC;QAED,wCAAwC;QACxC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,0BAA0B,CACnC,GAAG,EACH,sBAAsB,EACtB,eAAe,CAChB,CAAC;YAEF,IAAI,cAAc,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,gBAAgB;QAC5B,MAAM,QAAQ,GAAkB,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/B,6BAA6B;QAC7B,MAAM,WAAW,GAAG;YAClB,IAAI,CAAC,YAAY;YACjB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;YAC/B,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC;SACxC,CAAC;QAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;gBAAE,SAAS;YACtC,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,eAAe,CAC3B,GAAW,EACX,QAAuB,EACvB,IAAiB,EACjB,KAAa,EACb,QAAgB;QAEhB,IAAI,KAAK,GAAG,QAAQ;YAAE,OAAO;QAE7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAE1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,oCAAoC;gBACpC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAC7D,SAAS;gBACX,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;oBAAE,SAAS;gBAE9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,MAAM,IAAI,CAAC,eAAe,CACxB,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,KAAK,GAAG,CAAC,EACT,QAAQ,CACT,CAAC;gBACJ,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBACzC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;oBACrC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;oBAE7D,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC;wBAAE,SAAS;oBACrC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;oBAEvB,IAAI,CAAC;wBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;wBACxD,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;4BAC7B,QAAQ,CAAC,IAAI,CAAC;gCACZ,IAAI,EAAE,GAAG,CAAC,IAAI;gCACd,IAAI,EAAE,YAAY;gCAClB,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,OAAO;6BAChC,CAAC,CAAC;4BACH,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC;wBAC/D,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,6BAA6B;oBAC/B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,0BAA0B,CACtC,GAAgB,EAChB,UAAmB,EACnB,eAAyB;QAEzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAClE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO;QAEjC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAE/D,MAAM,QAAQ,GAAG,CAAC,cAAc,CAAC,CAAC;QAClC,IAAI,UAAU;YACZ,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;QAE/E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAChD,IAA8B,CAC/B,EAAE,CAAC;gBACF,4CAA4C;gBAC5C,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBAAE,SAAS;gBAExE,MAAM,WAAW,GACf,UAAU,KAAK,aAAa;oBAC5B,UAAU,KAAK,aAAa;oBAC5B,UAAU,KAAK,aAAa,CAAC;gBAE/B,IAAI,WAAW,EAAE,CAAC;oBAChB,iCAAiC;oBACjC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACjD,IAAI,SAAS,EAAE,CAAC;wBACd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;oBAC/C,CAAC;gBACH,CAAC;qBAAM,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC1C,yDAAyD;oBACzD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;gBAC/C,CAAC;qBAAM,CAAC;oBACN,sBAAsB;oBACtB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,UAAoB,CAAC,CAAC;oBAC5D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,GAAgB;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAEjD,4BAA4B;QAC5B,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAEtC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;gBAAE,SAAS;YACtC,MAAM,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,yBAAyB,CACrC,WAAmB,EACnB,GAAW;QAEX,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAE1D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAC1E,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;oBAAE,SAAS;gBAE9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAEvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,MAAM,IAAI,CAAC,yBAAyB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAC9D,CAAC;qBAAM,IACL,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAC3B,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC3B,CAAC;oBACD,MAAM,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,oBAAoB,CAChC,WAAmB,EACnB,QAAgB;QAEhB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEhD,gCAAgC;YAChC,MAAM,cAAc,GAAG;gBACrB,4DAA4D;gBAC5D,kFAAkF;gBAClF,iCAAiC;gBACjC,6BAA6B;gBAC7B,6CAA6C;gBAC7C,8BAA8B;gBAC9B,qCAAqC;gBACrC,sEAAsE;aACvE,CAAC;YAEF,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC;gBACV,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBAChD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBAE5B,wBAAwB;oBACxB,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;wBAAE,SAAS;oBAEvE,6CAA6C;oBAC7C,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACnD,IACE,UAAU,KAAK,OAAO;4BACtB,UAAU,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,EACpC,CAAC;4BACD,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;4BACzD,MAAM;wBACR,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;IACH,CAAC;IAED;;OAEG;IACK,OAAO,CACb,IAAY,EACZ,IAAY,EACZ,IAA0C,EAC1C,OAAgB;QAEhB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1D,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,OAAO,CACb,IAAY,EACZ,EAAU,EACV,IAAyC,EACzC,UAAmB;QAEnB,uBAAuB;QACvB,IAAI,IAAI,KAAK,EAAE;YAAE,OAAO;QAExB,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAI,QAAQ;YAAE,OAAO;QAErB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAEtD,uBAAuB;QACvB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACK,iBAAiB;QACvB,KAAK,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACvD,qBAAqB;YACrB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ebowwa/dependency-graph - Output Formatters
|
|
3
|
+
*
|
|
4
|
+
* Format dependency graphs for various output formats
|
|
5
|
+
*/
|
|
6
|
+
import type { DependencyGraph, OutputFormat } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* Format the graph for output
|
|
9
|
+
*/
|
|
10
|
+
export declare function formatGraph(graph: DependencyGraph, format: OutputFormat): string;
|
|
11
|
+
/**
|
|
12
|
+
* Format as JSON
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatAsJson(graph: DependencyGraph): string;
|
|
15
|
+
/**
|
|
16
|
+
* Format as Mermaid diagram
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatAsMermaid(graph: DependencyGraph): string;
|
|
19
|
+
/**
|
|
20
|
+
* Format as Graphviz DOT
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatAsDot(graph: DependencyGraph): string;
|
|
23
|
+
/**
|
|
24
|
+
* Format as ASCII tree
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatAsTree(graph: DependencyGraph): string;
|
|
27
|
+
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../src/formatters.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CAYhF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAS3D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAqC9D;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAqB1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAoC3D"}
|