dependency-graph-analyzer 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/LICENSE +21 -0
- package/README.MD +0 -0
- package/dist/analyzer.d.ts +22 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +178 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/graph.d.ts +14 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +132 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/resolvers.d.ts +22 -0
- package/dist/resolvers.d.ts.map +1 -0
- package/dist/resolvers.js +27 -0
- package/dist/resolvers.js.map +1 -0
- package/dist/schema.d.ts +2 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +55 -0
- package/dist/schema.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +22 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/visualizer.d.ts +18 -0
- package/dist/visualizer.d.ts.map +1 -0
- package/dist/visualizer.js +160 -0
- package/dist/visualizer.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Apollo87z
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.MD
ADDED
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Graph } from 'graphlib';
|
|
2
|
+
import { AnalysisResult, Cycle, StronglyConnectedComponent, TopologicalOrder, CriticalPackage } from './types';
|
|
3
|
+
export declare class GraphAnalyzer {
|
|
4
|
+
private graph;
|
|
5
|
+
constructor(graph: Graph);
|
|
6
|
+
analyze(): AnalysisResult;
|
|
7
|
+
findcycles(): Cycle[];
|
|
8
|
+
findcomponents(): StronglyConnectedComponent[];
|
|
9
|
+
topsort(): TopologicalOrder;
|
|
10
|
+
getcritical(limit?: number): CriticalPackage[];
|
|
11
|
+
detectcycle(start: string): string[] | null;
|
|
12
|
+
getstats(): {
|
|
13
|
+
totalNodes: number;
|
|
14
|
+
totalEdges: number;
|
|
15
|
+
hasCycles: boolean;
|
|
16
|
+
};
|
|
17
|
+
getdeps(node: string): string[];
|
|
18
|
+
getdependents(node: string): string[];
|
|
19
|
+
findpath(from: string, to: string): string[] | null;
|
|
20
|
+
subgraph(nodes: string[]): Graph;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAO,MAAM,UAAU,CAAC;AACtC,OAAO,EACL,cAAc,EACd,KAAK,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EAChB,MAAM,SAAS,CAAC;AAEjB,qBAAa,aAAa;IACxB,OAAO,CAAC,KAAK,CAAQ;gBAET,KAAK,EAAE,KAAK;IAIxB,OAAO,IAAI,cAAc;IAgBzB,UAAU,IAAI,KAAK,EAAE;IAyBrB,cAAc,IAAI,0BAA0B,EAAE;IAiB9C,OAAO,IAAI,gBAAgB;IAe3B,WAAW,CAAC,KAAK,GAAE,MAAW,GAAG,eAAe,EAAE;IAsBlD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAkC3C,QAAQ;;;;;IAYR,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAI/B,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAIrC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IA4BnD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK;CAoBjC"}
|
package/dist/analyzer.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphAnalyzer = void 0;
|
|
4
|
+
const graphlib_1 = require("graphlib");
|
|
5
|
+
class GraphAnalyzer {
|
|
6
|
+
constructor(graph) {
|
|
7
|
+
this.graph = graph;
|
|
8
|
+
}
|
|
9
|
+
analyze() {
|
|
10
|
+
const cycles = this.findcycles();
|
|
11
|
+
const components = this.findcomponents();
|
|
12
|
+
const topological = this.topsort();
|
|
13
|
+
const critical = this.getcritical();
|
|
14
|
+
const stats = this.getstats();
|
|
15
|
+
return {
|
|
16
|
+
cycles,
|
|
17
|
+
components,
|
|
18
|
+
topological,
|
|
19
|
+
critical,
|
|
20
|
+
stats
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
findcycles() {
|
|
24
|
+
const cycles = [];
|
|
25
|
+
const components = graphlib_1.alg.tarjan(this.graph);
|
|
26
|
+
for (const comp of components) {
|
|
27
|
+
if (comp.length > 1) {
|
|
28
|
+
cycles.push({
|
|
29
|
+
nodes: comp,
|
|
30
|
+
severity: 'ERROR'
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
else if (comp.length === 1) {
|
|
34
|
+
const node = comp[0];
|
|
35
|
+
const next = this.graph.successors(node) || [];
|
|
36
|
+
if (next.includes(node)) {
|
|
37
|
+
cycles.push({
|
|
38
|
+
nodes: [node],
|
|
39
|
+
severity: 'WARNING'
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return cycles;
|
|
45
|
+
}
|
|
46
|
+
findcomponents() {
|
|
47
|
+
const components = graphlib_1.alg.tarjan(this.graph);
|
|
48
|
+
const result = [];
|
|
49
|
+
for (const comp of components) {
|
|
50
|
+
if (comp.length > 1) {
|
|
51
|
+
result.push({
|
|
52
|
+
nodes: comp,
|
|
53
|
+
size: comp.length
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
result.sort((a, b) => b.size - a.size);
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
topsort() {
|
|
61
|
+
try {
|
|
62
|
+
const order = graphlib_1.alg.topsort(this.graph);
|
|
63
|
+
return {
|
|
64
|
+
order,
|
|
65
|
+
valid: true
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
return {
|
|
70
|
+
order: [],
|
|
71
|
+
valid: false
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
getcritical(limit = 10) {
|
|
76
|
+
const nodes = this.graph.nodes();
|
|
77
|
+
const pkgs = [];
|
|
78
|
+
for (const node of nodes) {
|
|
79
|
+
const deps = this.graph.predecessors(node) || [];
|
|
80
|
+
pkgs.push({
|
|
81
|
+
name: node,
|
|
82
|
+
dependents: deps.length,
|
|
83
|
+
rank: 0
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
pkgs.sort((a, b) => b.dependents - a.dependents);
|
|
87
|
+
for (let i = 0; i < pkgs.length; i++) {
|
|
88
|
+
pkgs[i].rank = i + 1;
|
|
89
|
+
}
|
|
90
|
+
return pkgs.slice(0, limit);
|
|
91
|
+
}
|
|
92
|
+
detectcycle(start) {
|
|
93
|
+
const visited = new Set();
|
|
94
|
+
const stack = new Set();
|
|
95
|
+
const path = [];
|
|
96
|
+
const dfs = (node) => {
|
|
97
|
+
visited.add(node);
|
|
98
|
+
stack.add(node);
|
|
99
|
+
path.push(node);
|
|
100
|
+
const next = this.graph.successors(node) || [];
|
|
101
|
+
for (const n of next) {
|
|
102
|
+
if (!visited.has(n)) {
|
|
103
|
+
if (dfs(n)) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (stack.has(n)) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
stack.delete(node);
|
|
112
|
+
path.pop();
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
if (dfs(start)) {
|
|
116
|
+
return path;
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
getstats() {
|
|
121
|
+
const nodes = this.graph.nodes();
|
|
122
|
+
const edges = this.graph.edges();
|
|
123
|
+
const cycles = this.findcycles();
|
|
124
|
+
return {
|
|
125
|
+
totalNodes: nodes.length,
|
|
126
|
+
totalEdges: edges.length,
|
|
127
|
+
hasCycles: cycles.length > 0
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
getdeps(node) {
|
|
131
|
+
return this.graph.successors(node) || [];
|
|
132
|
+
}
|
|
133
|
+
getdependents(node) {
|
|
134
|
+
return this.graph.predecessors(node) || [];
|
|
135
|
+
}
|
|
136
|
+
findpath(from, to) {
|
|
137
|
+
const queue = [{ node: from, path: [from] }];
|
|
138
|
+
const visited = new Set();
|
|
139
|
+
while (queue.length > 0) {
|
|
140
|
+
const current = queue.shift();
|
|
141
|
+
if (current.node === to) {
|
|
142
|
+
return current.path;
|
|
143
|
+
}
|
|
144
|
+
if (visited.has(current.node))
|
|
145
|
+
continue;
|
|
146
|
+
visited.add(current.node);
|
|
147
|
+
const next = this.graph.successors(current.node) || [];
|
|
148
|
+
for (const n of next) {
|
|
149
|
+
if (!visited.has(n)) {
|
|
150
|
+
queue.push({
|
|
151
|
+
node: n,
|
|
152
|
+
path: [...current.path, n]
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
subgraph(nodes) {
|
|
160
|
+
const g = new graphlib_1.Graph({ directed: true });
|
|
161
|
+
for (const node of nodes) {
|
|
162
|
+
if (this.graph.hasNode(node)) {
|
|
163
|
+
g.setNode(node, this.graph.node(node));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (const node of nodes) {
|
|
167
|
+
const next = this.graph.successors(node) || [];
|
|
168
|
+
for (const n of next) {
|
|
169
|
+
if (nodes.includes(n)) {
|
|
170
|
+
g.setEdge(node, n);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return g;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.GraphAnalyzer = GraphAnalyzer;
|
|
178
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Graph } from 'graphlib';
|
|
2
|
+
import { DependencyInput, PackageVersion } from './types';
|
|
3
|
+
export declare class DependencyGraph {
|
|
4
|
+
private graph;
|
|
5
|
+
constructor();
|
|
6
|
+
build(input: DependencyInput): Graph;
|
|
7
|
+
buildsimple(deps: Record<string, string[]>): Graph;
|
|
8
|
+
getgraph(): Graph;
|
|
9
|
+
resolveversions(input: DependencyInput): Record<string, string>;
|
|
10
|
+
pickver(available: PackageVersion[], constraint: string): string | null;
|
|
11
|
+
vercmp(a: string, b: string): number;
|
|
12
|
+
findpkg(available: Record<string, PackageVersion[]>, pkg: string, ver: string): PackageVersion | null;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,eAAe,EAAa,cAAc,EAAE,MAAM,SAAS,CAAC;AAErE,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAQ;;IAMrB,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,KAAK;IAyBpC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK;IAclD,QAAQ,IAAI,KAAK;IAIjB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IA4C/D,OAAO,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA6BvE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAapC,OAAO,CACL,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,EAC3C,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GACV,cAAc,GAAG,IAAI;CAQzB"}
|
package/dist/graph.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DependencyGraph = void 0;
|
|
4
|
+
const graphlib_1 = require("graphlib");
|
|
5
|
+
class DependencyGraph {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.graph = new graphlib_1.Graph({ directed: true });
|
|
8
|
+
}
|
|
9
|
+
build(input) {
|
|
10
|
+
this.graph = new graphlib_1.Graph({ directed: true });
|
|
11
|
+
const resolved = this.resolveversions(input);
|
|
12
|
+
for (const pkg in resolved) {
|
|
13
|
+
const ver = resolved[pkg];
|
|
14
|
+
const nid = `${pkg}@${ver}`;
|
|
15
|
+
this.graph.setNode(nid, { name: pkg, version: ver });
|
|
16
|
+
const data = this.findpkg(input.available, pkg, ver);
|
|
17
|
+
if (data && data.requires) {
|
|
18
|
+
for (const dep in data.requires) {
|
|
19
|
+
const depver = resolved[dep];
|
|
20
|
+
if (depver) {
|
|
21
|
+
const depid = `${dep}@${depver}`;
|
|
22
|
+
this.graph.setEdge(nid, depid);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return this.graph;
|
|
28
|
+
}
|
|
29
|
+
buildsimple(deps) {
|
|
30
|
+
this.graph = new graphlib_1.Graph({ directed: true });
|
|
31
|
+
for (const node in deps) {
|
|
32
|
+
this.graph.setNode(node);
|
|
33
|
+
for (const dep of deps[node]) {
|
|
34
|
+
this.graph.setNode(dep);
|
|
35
|
+
this.graph.setEdge(node, dep);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return this.graph;
|
|
39
|
+
}
|
|
40
|
+
getgraph() {
|
|
41
|
+
return this.graph;
|
|
42
|
+
}
|
|
43
|
+
resolveversions(input) {
|
|
44
|
+
const resolved = {};
|
|
45
|
+
for (const pkg in input.requirements) {
|
|
46
|
+
const constraint = input.requirements[pkg];
|
|
47
|
+
const available = input.available[pkg];
|
|
48
|
+
if (available && available.length > 0) {
|
|
49
|
+
const ver = this.pickver(available, constraint);
|
|
50
|
+
if (ver) {
|
|
51
|
+
resolved[pkg] = ver;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const queue = Object.keys(resolved);
|
|
56
|
+
const visited = new Set();
|
|
57
|
+
while (queue.length > 0) {
|
|
58
|
+
const current = queue.shift();
|
|
59
|
+
if (visited.has(current))
|
|
60
|
+
continue;
|
|
61
|
+
visited.add(current);
|
|
62
|
+
const ver = resolved[current];
|
|
63
|
+
const data = this.findpkg(input.available, current, ver);
|
|
64
|
+
if (data && data.requires) {
|
|
65
|
+
for (const dep in data.requires) {
|
|
66
|
+
if (!resolved[dep]) {
|
|
67
|
+
const available = input.available[dep];
|
|
68
|
+
if (available && available.length > 0) {
|
|
69
|
+
const depver = this.pickver(available, data.requires[dep]);
|
|
70
|
+
if (depver) {
|
|
71
|
+
resolved[dep] = depver;
|
|
72
|
+
queue.push(dep);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return resolved;
|
|
80
|
+
}
|
|
81
|
+
pickver(available, constraint) {
|
|
82
|
+
if (available.length === 0)
|
|
83
|
+
return null;
|
|
84
|
+
if (constraint.startsWith('>=')) {
|
|
85
|
+
const minver = constraint.substring(2).trim();
|
|
86
|
+
const matching = [];
|
|
87
|
+
for (const p of available) {
|
|
88
|
+
if (this.vercmp(p.version, minver) >= 0) {
|
|
89
|
+
matching.push(p);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (matching.length > 0) {
|
|
93
|
+
matching.sort((a, b) => this.vercmp(b.version, a.version));
|
|
94
|
+
return matching[0].version;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (constraint.startsWith('==') || constraint.startsWith('=')) {
|
|
98
|
+
const exact = constraint.replace(/^==?/, '').trim();
|
|
99
|
+
for (const p of available) {
|
|
100
|
+
if (p.version === exact)
|
|
101
|
+
return p.version;
|
|
102
|
+
}
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
available.sort((a, b) => this.vercmp(b.version, a.version));
|
|
106
|
+
return available[0].version;
|
|
107
|
+
}
|
|
108
|
+
vercmp(a, b) {
|
|
109
|
+
const ap = a.split('.').map(Number);
|
|
110
|
+
const bp = b.split('.').map(Number);
|
|
111
|
+
const maxlen = Math.max(ap.length, bp.length);
|
|
112
|
+
for (let i = 0; i < maxlen; i++) {
|
|
113
|
+
const av = ap[i] || 0;
|
|
114
|
+
const bv = bp[i] || 0;
|
|
115
|
+
if (av !== bv)
|
|
116
|
+
return av - bv;
|
|
117
|
+
}
|
|
118
|
+
return 0;
|
|
119
|
+
}
|
|
120
|
+
findpkg(available, pkg, ver) {
|
|
121
|
+
const versions = available[pkg];
|
|
122
|
+
if (!versions)
|
|
123
|
+
return null;
|
|
124
|
+
for (const v of versions) {
|
|
125
|
+
if (v.version === ver)
|
|
126
|
+
return v;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
exports.DependencyGraph = DependencyGraph;
|
|
132
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../src/graph.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DependencyGraph } from './graph';
|
|
2
|
+
export { GraphAnalyzer } from './analyzer';
|
|
3
|
+
export { GraphVisualizer } from './visualizer';
|
|
4
|
+
export type { PackageVersion, DependencyInput, GraphNode, Cycle, StronglyConnectedComponent, TopologicalOrder, CriticalPackage, AnalysisResult, VisualizationResult } from './types';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAG/C,YAAY,EACV,cAAc,EACd,eAAe,EACf,SAAS,EACT,KAAK,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,mBAAmB,EACpB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GraphVisualizer = exports.GraphAnalyzer = exports.DependencyGraph = void 0;
|
|
4
|
+
var graph_1 = require("./graph");
|
|
5
|
+
Object.defineProperty(exports, "DependencyGraph", { enumerable: true, get: function () { return graph_1.DependencyGraph; } });
|
|
6
|
+
var analyzer_1 = require("./analyzer");
|
|
7
|
+
Object.defineProperty(exports, "GraphAnalyzer", { enumerable: true, get: function () { return analyzer_1.GraphAnalyzer; } });
|
|
8
|
+
var visualizer_1 = require("./visualizer");
|
|
9
|
+
Object.defineProperty(exports, "GraphVisualizer", { enumerable: true, get: function () { return visualizer_1.GraphVisualizer; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iCAA0C;AAAjC,wGAAA,eAAe,OAAA;AACxB,uCAA2C;AAAlC,yGAAA,aAAa,OAAA;AACtB,2CAA+C;AAAtC,6GAAA,eAAe,OAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const resolvers: {
|
|
2
|
+
Query: {
|
|
3
|
+
analyze: (_: any, { dependenciesJson }: {
|
|
4
|
+
dependenciesJson: string;
|
|
5
|
+
}) => Promise<{
|
|
6
|
+
visualization: {
|
|
7
|
+
dot: string;
|
|
8
|
+
svg: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
cycles: import("./types").Cycle[];
|
|
11
|
+
components: import("./types").StronglyConnectedComponent[];
|
|
12
|
+
topological: import("./types").TopologicalOrder;
|
|
13
|
+
critical: import("./types").CriticalPackage[];
|
|
14
|
+
stats: {
|
|
15
|
+
totalNodes: number;
|
|
16
|
+
totalEdges: number;
|
|
17
|
+
hasCycles: boolean;
|
|
18
|
+
};
|
|
19
|
+
}>;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=resolvers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../src/resolvers.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS;;qBAEC,GAAG,wBAAwB;YAAE,gBAAgB,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;;;;;;;CAqB7E,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolvers = void 0;
|
|
4
|
+
const graph_1 = require("./graph");
|
|
5
|
+
const analyzer_1 = require("./analyzer");
|
|
6
|
+
const visualizer_1 = require("./visualizer");
|
|
7
|
+
exports.resolvers = {
|
|
8
|
+
Query: {
|
|
9
|
+
analyze: async (_, { dependenciesJson }) => {
|
|
10
|
+
const dependencies = JSON.parse(dependenciesJson);
|
|
11
|
+
const graph = new graph_1.DependencyGraph();
|
|
12
|
+
const g = graph.buildsimple(dependencies);
|
|
13
|
+
const analyzer = new analyzer_1.GraphAnalyzer(g);
|
|
14
|
+
const analysis = analyzer.analyze();
|
|
15
|
+
const visualizer = new visualizer_1.GraphVisualizer(g);
|
|
16
|
+
const vizResult = await visualizer.visualize('svg', true, analysis.cycles);
|
|
17
|
+
return {
|
|
18
|
+
...analysis,
|
|
19
|
+
visualization: {
|
|
20
|
+
dot: vizResult.dot,
|
|
21
|
+
svg: vizResult.svg
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=resolvers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.js","sourceRoot":"","sources":["../src/resolvers.ts"],"names":[],"mappings":";;;AAAA,mCAA0C;AAC1C,yCAA2C;AAC3C,6CAA+C;AAElC,QAAA,SAAS,GAAG;IACvB,KAAK,EAAE;QACL,OAAO,EAAE,KAAK,EAAE,CAAM,EAAE,EAAE,gBAAgB,EAAgC,EAAE,EAAE;YAC5E,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;YAElD,MAAM,KAAK,GAAG,IAAI,uBAAe,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YAE1C,MAAM,QAAQ,GAAG,IAAI,wBAAa,CAAC,CAAC,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;YAEpC,MAAM,UAAU,GAAG,IAAI,4BAAe,CAAC,CAAC,CAAC,CAAC;YAC1C,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;YAE3E,OAAO;gBACL,GAAG,QAAQ;gBACX,aAAa,EAAE;oBACb,GAAG,EAAE,SAAS,CAAC,GAAG;oBAClB,GAAG,EAAE,SAAS,CAAC,GAAG;iBACnB;aACF,CAAC;QACJ,CAAC;KACF;CACF,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const typeDefs = "#graphql\n type Query {\n analyze(dependenciesJson: String!): AnalysisResult!\n }\n\n type AnalysisResult {\n cycles: [Cycle!]!\n components: [StronglyConnectedComponent!]!\n topological: TopologicalOrder!\n critical: [CriticalPackage!]!\n stats: Stats!\n visualization: Visualization!\n }\n\n type Cycle {\n nodes: [String!]!\n severity: Severity!\n }\n\n enum Severity {\n ERROR\n WARNING\n }\n\n type StronglyConnectedComponent {\n nodes: [String!]!\n size: Int!\n }\n\n type TopologicalOrder {\n order: [String!]!\n valid: Boolean!\n }\n\n type CriticalPackage {\n name: String!\n dependents: Int!\n rank: Int!\n }\n\n type Stats {\n totalNodes: Int!\n totalEdges: Int!\n hasCycles: Boolean!\n }\n\n type Visualization {\n dot: String!\n svg: String\n }\n";
|
|
2
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,m1BAkDpB,CAAC"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.typeDefs = void 0;
|
|
4
|
+
exports.typeDefs = `#graphql
|
|
5
|
+
type Query {
|
|
6
|
+
analyze(dependenciesJson: String!): AnalysisResult!
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type AnalysisResult {
|
|
10
|
+
cycles: [Cycle!]!
|
|
11
|
+
components: [StronglyConnectedComponent!]!
|
|
12
|
+
topological: TopologicalOrder!
|
|
13
|
+
critical: [CriticalPackage!]!
|
|
14
|
+
stats: Stats!
|
|
15
|
+
visualization: Visualization!
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type Cycle {
|
|
19
|
+
nodes: [String!]!
|
|
20
|
+
severity: Severity!
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
enum Severity {
|
|
24
|
+
ERROR
|
|
25
|
+
WARNING
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type StronglyConnectedComponent {
|
|
29
|
+
nodes: [String!]!
|
|
30
|
+
size: Int!
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type TopologicalOrder {
|
|
34
|
+
order: [String!]!
|
|
35
|
+
valid: Boolean!
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type CriticalPackage {
|
|
39
|
+
name: String!
|
|
40
|
+
dependents: Int!
|
|
41
|
+
rank: Int!
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type Stats {
|
|
45
|
+
totalNodes: Int!
|
|
46
|
+
totalEdges: Int!
|
|
47
|
+
hasCycles: Boolean!
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type Visualization {
|
|
51
|
+
dot: String!
|
|
52
|
+
svg: String
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;AAAa,QAAA,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDvB,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const server_1 = require("@apollo/server");
|
|
4
|
+
const standalone_1 = require("@apollo/server/standalone");
|
|
5
|
+
const schema_1 = require("./schema");
|
|
6
|
+
const resolvers_1 = require("./resolvers");
|
|
7
|
+
async function startServer() {
|
|
8
|
+
const server = new server_1.ApolloServer({
|
|
9
|
+
typeDefs: schema_1.typeDefs,
|
|
10
|
+
resolvers: resolvers_1.resolvers,
|
|
11
|
+
});
|
|
12
|
+
const port = Number(process.env.PORT) || 8092;
|
|
13
|
+
const { url } = await (0, standalone_1.startStandaloneServer)(server, {
|
|
14
|
+
listen: { port },
|
|
15
|
+
});
|
|
16
|
+
console.log(` Server ready at: ${url}`);
|
|
17
|
+
}
|
|
18
|
+
startServer().catch((error) => {
|
|
19
|
+
console.error('Failed to start server:', error);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;AAAA,2CAA8C;AAC9C,0DAAkE;AAClE,qCAAoC;AACpC,2CAAwC;AAExC,KAAK,UAAU,WAAW;IACxB,MAAM,MAAM,GAAG,IAAI,qBAAY,CAAC;QAC9B,QAAQ,EAAR,iBAAQ;QACR,SAAS,EAAT,qBAAS;KACV,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAE9C,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,IAAA,kCAAqB,EAAC,MAAM,EAAE;QAClD,MAAM,EAAE,EAAE,IAAI,EAAE;KACjB,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface PackageVersion {
|
|
2
|
+
version: string;
|
|
3
|
+
requires: Record<string, string>;
|
|
4
|
+
}
|
|
5
|
+
export interface DependencyInput {
|
|
6
|
+
requirements: Record<string, string>;
|
|
7
|
+
available: Record<string, PackageVersion[]>;
|
|
8
|
+
}
|
|
9
|
+
export interface GraphNode {
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Cycle {
|
|
14
|
+
nodes: string[];
|
|
15
|
+
severity: 'ERROR' | 'WARNING';
|
|
16
|
+
}
|
|
17
|
+
export interface StronglyConnectedComponent {
|
|
18
|
+
nodes: string[];
|
|
19
|
+
size: number;
|
|
20
|
+
}
|
|
21
|
+
export interface TopologicalOrder {
|
|
22
|
+
order: string[];
|
|
23
|
+
valid: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface CriticalPackage {
|
|
26
|
+
name: string;
|
|
27
|
+
dependents: number;
|
|
28
|
+
rank: number;
|
|
29
|
+
}
|
|
30
|
+
export interface AnalysisResult {
|
|
31
|
+
cycles: Cycle[];
|
|
32
|
+
components: StronglyConnectedComponent[];
|
|
33
|
+
topological: TopologicalOrder;
|
|
34
|
+
critical: CriticalPackage[];
|
|
35
|
+
stats: {
|
|
36
|
+
totalNodes: number;
|
|
37
|
+
totalEdges: number;
|
|
38
|
+
hasCycles: boolean;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export interface VisualizationResult {
|
|
42
|
+
dot: string;
|
|
43
|
+
svg?: string;
|
|
44
|
+
png?: Buffer;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,0BAA0B,EAAE,CAAC;IACzC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Graph } from 'graphlib';
|
|
2
|
+
import { VisualizationResult, Cycle } from './types';
|
|
3
|
+
export declare class GraphVisualizer {
|
|
4
|
+
private graph;
|
|
5
|
+
constructor(graph: Graph);
|
|
6
|
+
visualize(format?: 'svg' | 'png' | 'dot', highlightCycles?: boolean, cycles?: Cycle[]): Promise<VisualizationResult>;
|
|
7
|
+
generateDOT(highlightCycles?: boolean, cycles?: Cycle[]): string;
|
|
8
|
+
generateSimpleDOT(): string;
|
|
9
|
+
private formatNodeLabel;
|
|
10
|
+
private findCycleEdges;
|
|
11
|
+
renderToFile(outputPath: string, format?: 'svg' | 'png'): Promise<void>;
|
|
12
|
+
getGraphStats(): {
|
|
13
|
+
nodes: number;
|
|
14
|
+
edges: number;
|
|
15
|
+
density: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=visualizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualizer.d.ts","sourceRoot":"","sources":["../src/visualizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErD,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAQ;gBAET,KAAK,EAAE,KAAK;IAIlB,SAAS,CACb,MAAM,GAAE,KAAK,GAAG,KAAK,GAAG,KAAa,EACrC,eAAe,GAAE,OAAc,EAC/B,MAAM,GAAE,KAAK,EAAO,GACnB,OAAO,CAAC,mBAAmB,CAAC;IAsB/B,WAAW,CAAC,eAAe,GAAE,OAAc,EAAE,MAAM,GAAE,KAAK,EAAO,GAAG,MAAM;IAgD1E,iBAAiB,IAAI,MAAM;IAkB3B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,cAAc;IAqBhB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,GAAE,KAAK,GAAG,KAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAcpF,aAAa,IAAI;QACf,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB;CAQF"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.GraphVisualizer = void 0;
|
|
37
|
+
const viz_1 = require("@viz-js/viz");
|
|
38
|
+
class GraphVisualizer {
|
|
39
|
+
constructor(graph) {
|
|
40
|
+
this.graph = graph;
|
|
41
|
+
}
|
|
42
|
+
async visualize(format = 'svg', highlightCycles = true, cycles = []) {
|
|
43
|
+
const dot = this.generateDOT(highlightCycles, cycles);
|
|
44
|
+
if (format === 'dot') {
|
|
45
|
+
return { dot };
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const viz = await (0, viz_1.instance)();
|
|
49
|
+
const svg = viz.renderString(dot, { format: 'svg' });
|
|
50
|
+
if (format === 'svg') {
|
|
51
|
+
return { dot, svg };
|
|
52
|
+
}
|
|
53
|
+
return { dot, svg };
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('GraphViz rendering error:', error);
|
|
57
|
+
return { dot };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
generateDOT(highlightCycles = true, cycles = []) {
|
|
61
|
+
const lines = [];
|
|
62
|
+
lines.push('digraph dependencies {');
|
|
63
|
+
lines.push(' rankdir=LR;');
|
|
64
|
+
lines.push(' node [shape=box, style=rounded];');
|
|
65
|
+
lines.push('');
|
|
66
|
+
const cycleNodes = new Set();
|
|
67
|
+
if (highlightCycles) {
|
|
68
|
+
for (const cycle of cycles) {
|
|
69
|
+
for (const node of cycle.nodes) {
|
|
70
|
+
cycleNodes.add(node);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const nodes = this.graph.nodes();
|
|
75
|
+
for (const node of nodes) {
|
|
76
|
+
const isCyclic = cycleNodes.has(node);
|
|
77
|
+
const label = this.formatNodeLabel(node);
|
|
78
|
+
if (isCyclic) {
|
|
79
|
+
lines.push(` "${node}" [label="${label}", fillcolor="#ffcccc", style="filled,rounded"];`);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
lines.push(` "${node}" [label="${label}"];`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
lines.push('');
|
|
86
|
+
const edges = this.graph.edges();
|
|
87
|
+
const cycleEdges = this.findCycleEdges(cycles);
|
|
88
|
+
for (const edge of edges) {
|
|
89
|
+
const edgeKey = `${edge.v}->${edge.w}`;
|
|
90
|
+
const isCyclicEdge = cycleEdges.has(edgeKey);
|
|
91
|
+
if (isCyclicEdge) {
|
|
92
|
+
lines.push(` "${edge.v}" -> "${edge.w}" [color=red, penwidth=2.0];`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
lines.push(` "${edge.v}" -> "${edge.w}";`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
lines.push('}');
|
|
99
|
+
return lines.join('\n');
|
|
100
|
+
}
|
|
101
|
+
generateSimpleDOT() {
|
|
102
|
+
const lines = [];
|
|
103
|
+
lines.push('digraph dependencies {');
|
|
104
|
+
const nodes = this.graph.nodes();
|
|
105
|
+
for (const node of nodes) {
|
|
106
|
+
lines.push(` "${node}";`);
|
|
107
|
+
}
|
|
108
|
+
const edges = this.graph.edges();
|
|
109
|
+
for (const edge of edges) {
|
|
110
|
+
lines.push(` "${edge.v}" -> "${edge.w}";`);
|
|
111
|
+
}
|
|
112
|
+
lines.push('}');
|
|
113
|
+
return lines.join('\n');
|
|
114
|
+
}
|
|
115
|
+
formatNodeLabel(node) {
|
|
116
|
+
if (node.includes('@')) {
|
|
117
|
+
const [pkg, version] = node.split('@');
|
|
118
|
+
return `${pkg}\\n${version}`;
|
|
119
|
+
}
|
|
120
|
+
return node;
|
|
121
|
+
}
|
|
122
|
+
findCycleEdges(cycles) {
|
|
123
|
+
const cycleEdges = new Set();
|
|
124
|
+
for (const cycle of cycles) {
|
|
125
|
+
const nodes = cycle.nodes;
|
|
126
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
127
|
+
const current = nodes[i];
|
|
128
|
+
const successors = this.graph.successors(current) || [];
|
|
129
|
+
for (const successor of successors) {
|
|
130
|
+
if (nodes.includes(successor)) {
|
|
131
|
+
cycleEdges.add(`${current}->${successor}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return cycleEdges;
|
|
137
|
+
}
|
|
138
|
+
async renderToFile(outputPath, format = 'svg') {
|
|
139
|
+
const result = await this.visualize(format);
|
|
140
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
141
|
+
if (format === 'svg' && result.svg) {
|
|
142
|
+
await fs.writeFile(outputPath, result.svg);
|
|
143
|
+
}
|
|
144
|
+
else if (format === 'png' && result.png) {
|
|
145
|
+
await fs.writeFile(outputPath, result.png);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
await fs.writeFile(outputPath, result.dot);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
getGraphStats() {
|
|
152
|
+
const nodes = this.graph.nodes().length;
|
|
153
|
+
const edges = this.graph.edges().length;
|
|
154
|
+
const maxEdges = nodes * (nodes - 1);
|
|
155
|
+
const density = maxEdges > 0 ? edges / maxEdges : 0;
|
|
156
|
+
return { nodes, edges, density };
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
exports.GraphVisualizer = GraphVisualizer;
|
|
160
|
+
//# sourceMappingURL=visualizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualizer.js","sourceRoot":"","sources":["../src/visualizer.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dependency-graph-analyzer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Universal dependency graph analyzer with cycle detection, Tarjan's algorithm, and GraphViz visualization",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"depgraph": "./dist/server.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"start": "node dist/server.js",
|
|
18
|
+
"dev": "ts-node src/server.ts",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"dependency",
|
|
23
|
+
"graph",
|
|
24
|
+
"analyzer",
|
|
25
|
+
"tarjan",
|
|
26
|
+
"topological-sort",
|
|
27
|
+
"graphviz",
|
|
28
|
+
"circular-dependencies",
|
|
29
|
+
"cycle-detection",
|
|
30
|
+
"graphql",
|
|
31
|
+
"typescript"
|
|
32
|
+
],
|
|
33
|
+
"author": "Shehan <shehan87h@gmail.com>",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/Apollo87z/dependency-graph-analyzer.git"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/Apollo87z/dependency-graph-analyzer/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/Apollo87z/dependency-graph-analyzer#readme",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@apollo/server": "^5.3.0",
|
|
48
|
+
"@viz-js/viz": "^3.24.0",
|
|
49
|
+
"graphlib": "^2.1.8",
|
|
50
|
+
"graphql": "^16.12.0",
|
|
51
|
+
"graphql-scalars": "^1.25.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/graphlib": "^2.1.12",
|
|
55
|
+
"@types/node": "^20.0.0",
|
|
56
|
+
"ts-node": "^10.9.2",
|
|
57
|
+
"typescript": "^5.9.3"
|
|
58
|
+
}
|
|
59
|
+
}
|