dependency-graph-analyzer 1.0.0 → 1.0.1
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 +677 -0
- package/dist/server.js +1 -0
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
package/README.MD
CHANGED
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# Dependency Graph Analyzer
|
|
8
|
+
|
|
9
|
+
### Universal dependency graph analysis with cycle detection, Tarjan's algorithm, and GraphViz visualization
|
|
10
|
+
|
|
11
|
+
[](https://nodejs.org/)
|
|
12
|
+
[](https://www.typescriptlang.org/)
|
|
13
|
+
[](https://www.npmjs.com/package/dependency-graph-analyzer)
|
|
14
|
+
[](https://opensource.org/licenses/MIT)
|
|
15
|
+
[](https://graphql.org/)
|
|
16
|
+
[](https://dep-graph-analyzer.shehan.io/graphql)
|
|
17
|
+
|
|
18
|
+
[Live Demo](https://dep-graph-analyzer.shehan.io/graphql) • [Installation](#-installation) • [Quick Start](#-quick-start) • [API Reference](#-api-reference) • [Examples](#-examples)
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🎯 Overview
|
|
25
|
+
|
|
26
|
+
Dependency Graph Analyzer is a **powerful TypeScript library and GraphQL API** that analyzes dependency graphs to detect cycles, find strongly connected components, and visualize relationships.
|
|
27
|
+
|
|
28
|
+
**It answers the questions:**
|
|
29
|
+
> - ✅ Are there circular dependencies in my system?
|
|
30
|
+
> - ✅ What's the correct build/install order?
|
|
31
|
+
> - ✅ Which packages are most critical?
|
|
32
|
+
> - ✅ How do my components relate to each other?
|
|
33
|
+
|
|
34
|
+
### Why This Tool?
|
|
35
|
+
|
|
36
|
+
- **Tarjan's Algorithm** — Find strongly connected components in linear time O(V+E)
|
|
37
|
+
- **Cycle Detection** — Identify circular dependencies with severity levels
|
|
38
|
+
- **Topological Sort** — Get valid dependency ordering
|
|
39
|
+
- **GraphViz Integration** — Beautiful SVG visualizations with highlighted cycles
|
|
40
|
+
- **Universal** — Works for software packages, microservices, courses, teams, or any dependency system
|
|
41
|
+
- **GraphQL API** — Query exactly what you need, nothing more
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## ✨ Features
|
|
46
|
+
|
|
47
|
+
| Feature | Description |
|
|
48
|
+
|---------|-------------|
|
|
49
|
+
| **Cycle Detection** | Finds all circular dependencies with ERROR/WARNING severity |
|
|
50
|
+
| **Tarjan's Algorithm** | Computes strongly connected components efficiently |
|
|
51
|
+
| **Topological Sorting** | Returns valid dependency order (if no cycles exist) |
|
|
52
|
+
| **Critical Package Analysis** | Ranks packages by number of dependents |
|
|
53
|
+
| **GraphViz Visualization** | Generates DOT format and SVG images |
|
|
54
|
+
| **GraphQL API** | Flexible query interface - request only what you need |
|
|
55
|
+
| **TypeScript** | Full type safety and IntelliSense support |
|
|
56
|
+
| **Live API** | Production-ready endpoint at https://dep-graph-analyzer.shehan.io/graphql |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## 📦 Installation
|
|
61
|
+
|
|
62
|
+
### Option 1: Use the Live API (No Installation Required!)
|
|
63
|
+
|
|
64
|
+
Simply send GraphQL queries to:
|
|
65
|
+
```
|
|
66
|
+
https://dep-graph-analyzer.shehan.io/graphql
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Quick Test:**
|
|
70
|
+
```bash
|
|
71
|
+
curl -X POST https://dep-graph-analyzer.shehan.io/graphql \
|
|
72
|
+
-H "Content-Type: application/json" \
|
|
73
|
+
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"C\\\"]}\") { stats { totalNodes hasCycles } } }"}'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Option 2: Install via NPM ✅
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npm install dependency-graph-analyzer
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Then use it in your code:**
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { DependencyGraph, GraphAnalyzer, GraphVisualizer } from 'dependency-graph-analyzer';
|
|
86
|
+
|
|
87
|
+
const graph = new DependencyGraph();
|
|
88
|
+
const g = graph.buildsimple({ 'A': ['B'], 'B': ['C'] });
|
|
89
|
+
|
|
90
|
+
const analyzer = new GraphAnalyzer(g);
|
|
91
|
+
const result = analyzer.analyze();
|
|
92
|
+
|
|
93
|
+
console.log(result.stats); // { totalNodes: 3, totalEdges: 2, hasCycles: false }
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Option 3: Install from Source
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Clone the repository
|
|
100
|
+
git clone https://github.com/yourusername/dependency-graph-analyzer.git
|
|
101
|
+
cd dependency-graph-analyzer
|
|
102
|
+
|
|
103
|
+
# Install dependencies
|
|
104
|
+
npm install
|
|
105
|
+
|
|
106
|
+
# Build the project
|
|
107
|
+
npm run build
|
|
108
|
+
|
|
109
|
+
# Run locally
|
|
110
|
+
npm start
|
|
111
|
+
# Server will start at http://localhost:8092/graphql
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 🚀 Quick Start
|
|
117
|
+
|
|
118
|
+
### Using the Live GraphQL API
|
|
119
|
+
|
|
120
|
+
**Open in Browser:**
|
|
121
|
+
Visit [https://dep-graph-analyzer.shehan.io/graphql](https://dep-graph-analyzer.shehan.io/graphql)
|
|
122
|
+
|
|
123
|
+
**Example Query:**
|
|
124
|
+
```graphql
|
|
125
|
+
query {
|
|
126
|
+
analyze(dependenciesJson: "{\"A\": [\"B\", \"C\"], \"B\": [\"D\"], \"C\": [\"D\"], \"D\": [\"A\"]}") {
|
|
127
|
+
stats {
|
|
128
|
+
totalNodes
|
|
129
|
+
totalEdges
|
|
130
|
+
hasCycles
|
|
131
|
+
}
|
|
132
|
+
cycles {
|
|
133
|
+
nodes
|
|
134
|
+
severity
|
|
135
|
+
}
|
|
136
|
+
topological {
|
|
137
|
+
valid
|
|
138
|
+
order
|
|
139
|
+
}
|
|
140
|
+
critical {
|
|
141
|
+
name
|
|
142
|
+
dependents
|
|
143
|
+
rank
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Response:**
|
|
150
|
+
```json
|
|
151
|
+
{
|
|
152
|
+
"data": {
|
|
153
|
+
"analyze": {
|
|
154
|
+
"stats": {
|
|
155
|
+
"totalNodes": 4,
|
|
156
|
+
"totalEdges": 5,
|
|
157
|
+
"hasCycles": true
|
|
158
|
+
},
|
|
159
|
+
"cycles": [
|
|
160
|
+
{
|
|
161
|
+
"nodes": ["D", "C", "B", "A"],
|
|
162
|
+
"severity": "ERROR"
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"topological": {
|
|
166
|
+
"valid": false,
|
|
167
|
+
"order": []
|
|
168
|
+
},
|
|
169
|
+
"critical": [
|
|
170
|
+
{
|
|
171
|
+
"name": "C",
|
|
172
|
+
"dependents": 2,
|
|
173
|
+
"rank": 1
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Using as a TypeScript/JavaScript Library
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { DependencyGraph, GraphAnalyzer, GraphVisualizer } from 'dependency-graph-analyzer';
|
|
185
|
+
|
|
186
|
+
// Define your dependencies
|
|
187
|
+
const dependencies = {
|
|
188
|
+
'Frontend': ['React', 'API Client'],
|
|
189
|
+
'React': ['API Client'],
|
|
190
|
+
'API Client': ['API Server'],
|
|
191
|
+
'Backend': ['Database', 'API Server'],
|
|
192
|
+
'API Server': ['Business Logic'],
|
|
193
|
+
'Business Logic': ['Database'],
|
|
194
|
+
'Database': []
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// Build the graph
|
|
198
|
+
const graph = new DependencyGraph();
|
|
199
|
+
const g = graph.buildsimple(dependencies);
|
|
200
|
+
|
|
201
|
+
// Analyze it
|
|
202
|
+
const analyzer = new GraphAnalyzer(g);
|
|
203
|
+
const analysis = analyzer.analyze();
|
|
204
|
+
|
|
205
|
+
// Check for cycles
|
|
206
|
+
if (analysis.stats.hasCycles) {
|
|
207
|
+
console.log('❌ Circular dependencies found:', analysis.cycles);
|
|
208
|
+
} else {
|
|
209
|
+
console.log('✅ No cycles! Install order:', analysis.topological.order);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Find critical packages
|
|
213
|
+
console.log('Most critical packages:', analysis.critical.slice(0, 3));
|
|
214
|
+
|
|
215
|
+
// Generate visualization
|
|
216
|
+
const visualizer = new GraphVisualizer(g);
|
|
217
|
+
const result = await visualizer.visualize('svg', true, analysis.cycles);
|
|
218
|
+
console.log('SVG:', result.svg);
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 🌐 API Reference
|
|
224
|
+
|
|
225
|
+
### Live GraphQL Endpoint
|
|
226
|
+
|
|
227
|
+
**Production URL:** `https://dep-graph-analyzer.shehan.io/graphql`
|
|
228
|
+
|
|
229
|
+
**Local Development:** `http://localhost:8092/graphql` (after running `npm start`)
|
|
230
|
+
|
|
231
|
+
### GraphQL Schema
|
|
232
|
+
|
|
233
|
+
```graphql
|
|
234
|
+
type Query {
|
|
235
|
+
analyze(dependenciesJson: String!): AnalysisResult!
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
type AnalysisResult {
|
|
239
|
+
cycles: [Cycle!]!
|
|
240
|
+
components: [StronglyConnectedComponent!]!
|
|
241
|
+
topological: TopologicalOrder!
|
|
242
|
+
critical: [CriticalPackage!]!
|
|
243
|
+
stats: Stats!
|
|
244
|
+
visualization: Visualization!
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
type Cycle {
|
|
248
|
+
nodes: [String!]!
|
|
249
|
+
severity: Severity! # ERROR or WARNING
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
type StronglyConnectedComponent {
|
|
253
|
+
nodes: [String!]!
|
|
254
|
+
size: Int!
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
type TopologicalOrder {
|
|
258
|
+
order: [String!]!
|
|
259
|
+
valid: Boolean!
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
type CriticalPackage {
|
|
263
|
+
name: String!
|
|
264
|
+
dependents: Int!
|
|
265
|
+
rank: Int!
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
type Stats {
|
|
269
|
+
totalNodes: Int!
|
|
270
|
+
totalEdges: Int!
|
|
271
|
+
hasCycles: Boolean!
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
type Visualization {
|
|
275
|
+
dot: String! # GraphViz DOT format
|
|
276
|
+
svg: String # SVG image (can be rendered in browser)
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### Query Examples
|
|
281
|
+
|
|
282
|
+
**Get only statistics:**
|
|
283
|
+
```graphql
|
|
284
|
+
query {
|
|
285
|
+
analyze(dependenciesJson: "{\"A\": [\"B\"], \"B\": [\"C\"]}") {
|
|
286
|
+
stats {
|
|
287
|
+
totalNodes
|
|
288
|
+
hasCycles
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Get only cycles:**
|
|
295
|
+
```graphql
|
|
296
|
+
query {
|
|
297
|
+
analyze(dependenciesJson: "{\"express\": [\"body-parser\"], \"body-parser\": [\"express\"]}") {
|
|
298
|
+
cycles {
|
|
299
|
+
nodes
|
|
300
|
+
severity
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Get visualization only:**
|
|
307
|
+
```graphql
|
|
308
|
+
query {
|
|
309
|
+
analyze(dependenciesJson: "{\"A\": [\"B\"], \"B\": [\"C\"]}") {
|
|
310
|
+
visualization {
|
|
311
|
+
svg
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
**Get everything:**
|
|
318
|
+
```graphql
|
|
319
|
+
query {
|
|
320
|
+
analyze(dependenciesJson: "{\"A\": [\"B\"]}") {
|
|
321
|
+
stats { totalNodes totalEdges hasCycles }
|
|
322
|
+
cycles { nodes severity }
|
|
323
|
+
components { nodes size }
|
|
324
|
+
topological { order valid }
|
|
325
|
+
critical { name dependents rank }
|
|
326
|
+
visualization { svg dot }
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
---
|
|
332
|
+
|
|
333
|
+
## 📚 Use Cases & Examples
|
|
334
|
+
|
|
335
|
+
### Example 1: Software Package Dependencies
|
|
336
|
+
|
|
337
|
+
**Scenario:** Analyze npm package circular dependencies
|
|
338
|
+
|
|
339
|
+
```graphql
|
|
340
|
+
query {
|
|
341
|
+
analyze(dependenciesJson: "{\"express\": [\"body-parser\"], \"body-parser\": [\"express\"], \"morgan\": [\"express\"], \"cors\": []}") {
|
|
342
|
+
cycles {
|
|
343
|
+
nodes
|
|
344
|
+
severity
|
|
345
|
+
}
|
|
346
|
+
stats {
|
|
347
|
+
hasCycles
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
**Expected:** Detects cycle between express ↔ body-parser
|
|
354
|
+
|
|
355
|
+
### Example 2: Microservices Architecture
|
|
356
|
+
|
|
357
|
+
**Scenario:** Visualize service dependencies and find tightly coupled components
|
|
358
|
+
|
|
359
|
+
```graphql
|
|
360
|
+
query {
|
|
361
|
+
analyze(dependenciesJson: "{\"api-gateway\": [\"auth-service\", \"user-service\"], \"auth-service\": [\"database\", \"cache\"], \"user-service\": [\"database\", \"email-service\"], \"email-service\": [\"queue\"], \"database\": [], \"cache\": [], \"queue\": []}") {
|
|
362
|
+
stats {
|
|
363
|
+
totalNodes
|
|
364
|
+
hasCycles
|
|
365
|
+
}
|
|
366
|
+
topological {
|
|
367
|
+
order
|
|
368
|
+
}
|
|
369
|
+
critical {
|
|
370
|
+
name
|
|
371
|
+
dependents
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Expected:** Database is most critical (3 dependents), no cycles, valid order
|
|
378
|
+
|
|
379
|
+
### Example 3: Course Prerequisites
|
|
380
|
+
|
|
381
|
+
**Scenario:** Plan academic path with prerequisite constraints
|
|
382
|
+
|
|
383
|
+
```graphql
|
|
384
|
+
query {
|
|
385
|
+
analyze(dependenciesJson: "{\"Advanced AI\": [\"Machine Learning\", \"Linear Algebra\"], \"Machine Learning\": [\"Statistics\", \"Python Programming\"], \"Deep Learning\": [\"Machine Learning\", \"Calculus\"], \"Statistics\": [\"Math 101\"], \"Linear Algebra\": [\"Math 101\"], \"Calculus\": [\"Math 101\"], \"Python Programming\": [], \"Math 101\": []}") {
|
|
386
|
+
topological {
|
|
387
|
+
order
|
|
388
|
+
valid
|
|
389
|
+
}
|
|
390
|
+
critical {
|
|
391
|
+
name
|
|
392
|
+
dependents
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Expected:** Math 101 and Machine Learning are most critical, clear learning path
|
|
399
|
+
|
|
400
|
+
### Example 4: Build System with Circular Dependency (Error Case)
|
|
401
|
+
|
|
402
|
+
**Scenario:** Detect circular build dependencies in monorepo
|
|
403
|
+
|
|
404
|
+
```graphql
|
|
405
|
+
query {
|
|
406
|
+
analyze(dependenciesJson: "{\"app\": [\"lib-a\", \"lib-b\"], \"lib-a\": [\"lib-c\"], \"lib-b\": [\"lib-c\"], \"lib-c\": [\"lib-a\"]}") {
|
|
407
|
+
stats {
|
|
408
|
+
hasCycles
|
|
409
|
+
}
|
|
410
|
+
cycles {
|
|
411
|
+
nodes
|
|
412
|
+
severity
|
|
413
|
+
}
|
|
414
|
+
components {
|
|
415
|
+
nodes
|
|
416
|
+
size
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
**Expected:** Cycle detected: lib-a → lib-c → lib-a
|
|
423
|
+
|
|
424
|
+
### Example 5: Full Stack Architecture Visualization
|
|
425
|
+
|
|
426
|
+
**Scenario:** Generate architecture diagram with SVG
|
|
427
|
+
|
|
428
|
+
```graphql
|
|
429
|
+
query {
|
|
430
|
+
analyze(dependenciesJson: "{\"Frontend\": [\"React\", \"API Client\"], \"React\": [\"API Client\"], \"API Client\": [\"API Server\"], \"Backend\": [\"Database\", \"API Server\"], \"API Server\": [\"Business Logic\"], \"Business Logic\": [\"Database\"], \"Database\": []}") {
|
|
431
|
+
stats {
|
|
432
|
+
totalNodes
|
|
433
|
+
totalEdges
|
|
434
|
+
hasCycles
|
|
435
|
+
}
|
|
436
|
+
topological {
|
|
437
|
+
order
|
|
438
|
+
}
|
|
439
|
+
visualization {
|
|
440
|
+
svg
|
|
441
|
+
dot
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
**Expected:** Clean architecture, no cycles, SVG showing layered design
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## 🧪 Testing
|
|
452
|
+
|
|
453
|
+
### Test in Browser (GraphQL Playground)
|
|
454
|
+
|
|
455
|
+
1. Visit: https://dep-graph-analyzer.shehan.io/graphql
|
|
456
|
+
2. Paste any query from examples above
|
|
457
|
+
3. Click "Run"
|
|
458
|
+
4. See results instantly!
|
|
459
|
+
|
|
460
|
+
### Test with curl
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
# Simple test
|
|
464
|
+
curl -X POST https://dep-graph-analyzer.shehan.io/graphql \
|
|
465
|
+
-H "Content-Type: application/json" \
|
|
466
|
+
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"C\\\"]}\") { stats { totalNodes hasCycles } } }"}'
|
|
467
|
+
|
|
468
|
+
# With cycles
|
|
469
|
+
curl -X POST https://dep-graph-analyzer.shehan.io/graphql \
|
|
470
|
+
-H "Content-Type: application/json" \
|
|
471
|
+
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"A\\\"]}\") { cycles { nodes severity } } }"}'
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Test with Postman
|
|
475
|
+
|
|
476
|
+
1. **Method:** POST
|
|
477
|
+
2. **URL:** `https://dep-graph-analyzer.shehan.io/graphql`
|
|
478
|
+
3. **Headers:**
|
|
479
|
+
- `Content-Type: application/json`
|
|
480
|
+
4. **Body (raw JSON):**
|
|
481
|
+
```json
|
|
482
|
+
{
|
|
483
|
+
"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"], \\\"B\\\": [\\\"C\\\"]}\") { stats { totalNodes hasCycles } topological { order } } }"
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Test with JavaScript/Node.js
|
|
488
|
+
|
|
489
|
+
```javascript
|
|
490
|
+
const query = `
|
|
491
|
+
query {
|
|
492
|
+
analyze(dependenciesJson: "{\\"A\\": [\\"B\\"], \\"B\\": [\\"C\\"]}") {
|
|
493
|
+
stats { totalNodes hasCycles }
|
|
494
|
+
topological { order }
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
`;
|
|
498
|
+
|
|
499
|
+
fetch('https://dep-graph-analyzer.shehan.io/graphql', {
|
|
500
|
+
method: 'POST',
|
|
501
|
+
headers: { 'Content-Type': 'application/json' },
|
|
502
|
+
body: JSON.stringify({ query })
|
|
503
|
+
})
|
|
504
|
+
.then(res => res.json())
|
|
505
|
+
.then(data => console.log(data));
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Test with Python
|
|
509
|
+
|
|
510
|
+
```python
|
|
511
|
+
import requests
|
|
512
|
+
|
|
513
|
+
query = """
|
|
514
|
+
query {
|
|
515
|
+
analyze(dependenciesJson: "{\\"A\\": [\\"B\\"], \\"B\\": [\\"C\\"]}") {
|
|
516
|
+
stats { totalNodes hasCycles }
|
|
517
|
+
topological { order }
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
"""
|
|
521
|
+
|
|
522
|
+
response = requests.post(
|
|
523
|
+
'https://dep-graph-analyzer.shehan.io/graphql',
|
|
524
|
+
json={'query': query},
|
|
525
|
+
headers={'Content-Type': 'application/json'}
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
print(response.json())
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Run Local Tests
|
|
532
|
+
|
|
533
|
+
If you've cloned the repository:
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
# Run test suite
|
|
537
|
+
npm test
|
|
538
|
+
|
|
539
|
+
# Start local server
|
|
540
|
+
npm run dev
|
|
541
|
+
|
|
542
|
+
# Test locally
|
|
543
|
+
curl -X POST http://localhost:8092/graphql \
|
|
544
|
+
-H "Content-Type: application/json" \
|
|
545
|
+
-d '{"query": "query { analyze(dependenciesJson: \"{\\\"A\\\": [\\\"B\\\"]}\") { stats { totalNodes } } }"}'
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## 📖 Real-World Test Scenarios
|
|
551
|
+
|
|
552
|
+
See [examples/REAL_WORLD_TESTS.md](examples/REAL_WORLD_TESTS.md) for 10+ real-world test cases including:
|
|
553
|
+
|
|
554
|
+
- ✅ Python Django dependencies
|
|
555
|
+
- ✅ Node.js circular dependencies
|
|
556
|
+
- ✅ Microservices architecture
|
|
557
|
+
- ✅ Course prerequisites
|
|
558
|
+
- ✅ Build system cycles
|
|
559
|
+
- ✅ Team skill dependencies
|
|
560
|
+
- ✅ Monorepo analysis
|
|
561
|
+
- ✅ Diamond dependency problem
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
## 🔧 Local Development
|
|
566
|
+
|
|
567
|
+
### Setup
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
# Clone repository
|
|
571
|
+
git clone https://github.com/yourusername/dependency-graph-analyzer.git
|
|
572
|
+
cd dependency-graph-analyzer
|
|
573
|
+
|
|
574
|
+
# Install dependencies
|
|
575
|
+
npm install
|
|
576
|
+
|
|
577
|
+
# Build TypeScript
|
|
578
|
+
npm run build
|
|
579
|
+
|
|
580
|
+
# Start development server
|
|
581
|
+
npm run dev
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Project Structure
|
|
585
|
+
|
|
586
|
+
```
|
|
587
|
+
dependency-graph-analyzer/
|
|
588
|
+
├── src/
|
|
589
|
+
│ ├── types.ts # TypeScript interfaces
|
|
590
|
+
│ ├── graph.ts # Graph building (buildsimple, build)
|
|
591
|
+
│ ├── analyzer.ts # Tarjan's, cycles, topsort, getcritical
|
|
592
|
+
│ ├── visualizer.ts # GraphViz integration
|
|
593
|
+
│ ├── schema.ts # GraphQL schema
|
|
594
|
+
│ ├── resolvers.ts # GraphQL resolvers
|
|
595
|
+
│ ├── server.ts # Apollo Server
|
|
596
|
+
│ └── index.ts # Library exports
|
|
597
|
+
├── examples/
|
|
598
|
+
│ ├── test.ts # Example usage
|
|
599
|
+
│ ├── viewer.html # SVG viewer
|
|
600
|
+
│ └── REAL_WORLD_TESTS.md # Test scenarios
|
|
601
|
+
├── dist/ # Compiled JavaScript (gitignored)
|
|
602
|
+
├── package.json
|
|
603
|
+
├── tsconfig.json
|
|
604
|
+
├── Procfile # Heroku deployment
|
|
605
|
+
└── README.md
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Available Scripts
|
|
609
|
+
|
|
610
|
+
```bash
|
|
611
|
+
npm run build # Compile TypeScript to JavaScript
|
|
612
|
+
npm start # Run production server (dist/server.js)
|
|
613
|
+
npm run dev # Run development server with ts-node
|
|
614
|
+
npm test # Run test suite
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
## 🤝 Contributing
|
|
620
|
+
|
|
621
|
+
Contributions are welcome! Here's how:
|
|
622
|
+
|
|
623
|
+
1. Fork the repository
|
|
624
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
625
|
+
3. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
626
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
627
|
+
5. Open a Pull Request
|
|
628
|
+
|
|
629
|
+
---
|
|
630
|
+
|
|
631
|
+
## 📄 License
|
|
632
|
+
|
|
633
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## 🙋 Support
|
|
638
|
+
|
|
639
|
+
- **Issues**: [GitHub Issues](https://github.com/yourusername/dependency-graph-analyzer/issues)
|
|
640
|
+
- **Live API**: [https://dep-graph-analyzer.shehan.io/graphql](https://dep-graph-analyzer.shehan.io/graphql)
|
|
641
|
+
- **Author**: [@yourusername](https://github.com/yourusername)
|
|
642
|
+
- **Email**: shehan87h@gmail.com
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## 🌟 Acknowledgments
|
|
647
|
+
|
|
648
|
+
- Built with [graphlib](https://github.com/dagrejs/graphlib) for graph operations
|
|
649
|
+
- Visualization powered by [GraphViz](https://graphviz.org/) via [@viz-js/viz](https://github.com/viz-js/viz)
|
|
650
|
+
- GraphQL API with [Apollo Server](https://www.apollographql.com/docs/apollo-server/)
|
|
651
|
+
- Deployed on [Heroku](https://www.heroku.com/)
|
|
652
|
+
- Inspired by the need for universal dependency analysis across all domains
|
|
653
|
+
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
## 🚀 Key Features Recap
|
|
657
|
+
|
|
658
|
+
✅ **Tarjan's Algorithm** - O(V+E) complexity for finding SCCs
|
|
659
|
+
✅ **Cycle Detection** - ERROR/WARNING severity levels
|
|
660
|
+
✅ **Topological Sort** - Valid build/install ordering
|
|
661
|
+
✅ **Critical Analysis** - Identify most-depended-on packages
|
|
662
|
+
✅ **GraphViz Visualization** - SVG/DOT format with cycle highlighting
|
|
663
|
+
✅ **GraphQL API** - Query exactly what you need
|
|
664
|
+
✅ **TypeScript** - Full type safety
|
|
665
|
+
✅ **Live & Production-Ready** - https://dep-graph-analyzer.shehan.io/graphql
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
<div align="center">
|
|
670
|
+
|
|
671
|
+
**Made by [Shehan Horadagoda](https://github.com/yourusername)**
|
|
672
|
+
|
|
673
|
+
⭐ Star this repo if you find it useful!
|
|
674
|
+
|
|
675
|
+
[Try it now →](https://dep-graph-analyzer.shehan.io/graphql)
|
|
676
|
+
|
|
677
|
+
</div>
|
package/dist/server.js
CHANGED
package/dist/server.js.map
CHANGED
|
@@ -1 +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;
|
|
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;IAEH,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;IAAA,CAAC;AAC5C,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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dependency-graph-analyzer",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Universal dependency graph analyzer with cycle detection, Tarjan's algorithm, and GraphViz visualization",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -56,4 +56,4 @@
|
|
|
56
56
|
"ts-node": "^10.9.2",
|
|
57
57
|
"typescript": "^5.9.3"
|
|
58
58
|
}
|
|
59
|
-
}
|
|
59
|
+
}
|