@nexus-ioc/graph-analyzer 0.1.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +112 -0
  2. package/LICENSE +21 -0
  3. package/README.md +742 -0
  4. package/dist/analyzer/circular-dependency-detector.d.ts +94 -0
  5. package/dist/analyzer/circular-dependency-detector.js +203 -0
  6. package/dist/analyzer/circular-dependency-detector.js.map +1 -0
  7. package/dist/analyzer/module-depth-analyzer.d.ts +117 -0
  8. package/dist/analyzer/module-depth-analyzer.js +221 -0
  9. package/dist/analyzer/module-depth-analyzer.js.map +1 -0
  10. package/dist/analyzer/provider-scope-analyzer.d.ts +91 -0
  11. package/dist/analyzer/provider-scope-analyzer.js +137 -0
  12. package/dist/analyzer/provider-scope-analyzer.js.map +1 -0
  13. package/dist/analyzer/unused-provider-detector.d.ts +73 -0
  14. package/dist/analyzer/unused-provider-detector.js +147 -0
  15. package/dist/analyzer/unused-provider-detector.js.map +1 -0
  16. package/dist/cli.d.ts +2 -0
  17. package/dist/cli.js +537 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/config/config-loader.d.ts +27 -0
  20. package/dist/config/config-loader.js +205 -0
  21. package/dist/config/config-loader.js.map +1 -0
  22. package/dist/config/config-schema.d.ts +83 -0
  23. package/dist/config/config-schema.js +97 -0
  24. package/dist/config/config-schema.js.map +1 -0
  25. package/dist/index.d.ts +41 -0
  26. package/dist/index.js +50 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/interfaces/graph-output.interface.d.ts +126 -0
  29. package/dist/interfaces/graph-output.interface.js +3 -0
  30. package/dist/interfaces/graph-output.interface.js.map +1 -0
  31. package/dist/interfaces/providers.interface.d.ts +10 -0
  32. package/dist/interfaces/providers.interface.js +3 -0
  33. package/dist/interfaces/providers.interface.js.map +1 -0
  34. package/dist/parser/dependency-extractor.d.ts +88 -0
  35. package/dist/parser/dependency-extractor.js +334 -0
  36. package/dist/parser/dependency-extractor.js.map +1 -0
  37. package/dist/parser/parse-entry-file.d.ts +15 -0
  38. package/dist/parser/parse-entry-file.js +46 -0
  39. package/dist/parser/parse-entry-file.js.map +1 -0
  40. package/dist/parser/parse-imports.d.ts +15 -0
  41. package/dist/parser/parse-imports.js +65 -0
  42. package/dist/parser/parse-imports.js.map +1 -0
  43. package/dist/parser/parse-ns-module.d.ts +39 -0
  44. package/dist/parser/parse-ns-module.js +122 -0
  45. package/dist/parser/parse-ns-module.js.map +1 -0
  46. package/dist/parser/parse-provider.d.ts +2 -0
  47. package/dist/parser/parse-provider.js +7 -0
  48. package/dist/parser/parse-provider.js.map +1 -0
  49. package/dist/parser/parse-ts-config.d.ts +10 -0
  50. package/dist/parser/parse-ts-config.js +40 -0
  51. package/dist/parser/parse-ts-config.js.map +1 -0
  52. package/dist/parser/parser-rec.d.ts +1 -0
  53. package/dist/parser/parser-rec.js +52 -0
  54. package/dist/parser/parser-rec.js.map +1 -0
  55. package/dist/parser/parser.d.ts +1 -0
  56. package/dist/parser/parser.js +61 -0
  57. package/dist/parser/parser.js.map +1 -0
  58. package/dist/parser/provider/class-parser.d.ts +20 -0
  59. package/dist/parser/provider/class-parser.js +137 -0
  60. package/dist/parser/provider/class-parser.js.map +1 -0
  61. package/dist/parser/provider/providers-parser.d.ts +9 -0
  62. package/dist/parser/provider/providers-parser.js +32 -0
  63. package/dist/parser/provider/providers-parser.js.map +1 -0
  64. package/dist/parser/provider/use-class-parser.d.ts +25 -0
  65. package/dist/parser/provider/use-class-parser.js +161 -0
  66. package/dist/parser/provider/use-class-parser.js.map +1 -0
  67. package/dist/parser/provider/use-factory-parser.d.ts +15 -0
  68. package/dist/parser/provider/use-factory-parser.js +53 -0
  69. package/dist/parser/provider/use-factory-parser.js.map +1 -0
  70. package/dist/parser/provider/use-value-parser.d.ts +13 -0
  71. package/dist/parser/provider/use-value-parser.js +41 -0
  72. package/dist/parser/provider/use-value-parser.js.map +1 -0
  73. package/dist/parser/rules.d.ts +10 -0
  74. package/dist/parser/rules.js +37 -0
  75. package/dist/parser/rules.js.map +1 -0
  76. package/dist/utils/error-formatter.d.ts +27 -0
  77. package/dist/utils/error-formatter.js +177 -0
  78. package/dist/utils/error-formatter.js.map +1 -0
  79. package/dist/utils/validator.d.ts +45 -0
  80. package/dist/utils/validator.js +252 -0
  81. package/dist/utils/validator.js.map +1 -0
  82. package/dist/visualize/generator.d.ts +26 -0
  83. package/dist/visualize/generator.js +75 -0
  84. package/dist/visualize/generator.js.map +1 -0
  85. package/dist/visualize/graph-analyzer.d.ts +126 -0
  86. package/dist/visualize/graph-analyzer.js +199 -0
  87. package/dist/visualize/graph-analyzer.js.map +1 -0
  88. package/dist/visualize/html-generator.d.ts +71 -0
  89. package/dist/visualize/html-generator.js +1312 -0
  90. package/dist/visualize/html-generator.js.map +1 -0
  91. package/dist/visualize/json-formatter.d.ts +106 -0
  92. package/dist/visualize/json-formatter.js +252 -0
  93. package/dist/visualize/json-formatter.js.map +1 -0
  94. package/docs/API_REFERENCE.md +747 -0
  95. package/docs/ARCHITECTURE.md +486 -0
  96. package/docs/CLI_GUIDE.md +576 -0
  97. package/docs/HTML_VISUALIZATION.md +365 -0
  98. package/package.json +85 -0
@@ -0,0 +1,94 @@
1
+ import type { ParseEntryFile } from "../parser/parse-entry-file";
2
+ import type { ParseNsModule } from "../parser/parse-ns-module";
3
+ /**
4
+ * Represents a circular dependency cycle
5
+ */
6
+ export interface CircularDependency {
7
+ /** Type of circular dependency */
8
+ type: "module" | "provider";
9
+ /** Path of nodes forming the cycle (e.g., ["A", "B", "C", "A"]) */
10
+ cycle: string[];
11
+ /** Severity level */
12
+ severity: "error" | "warning";
13
+ /** Human-readable description */
14
+ message: string;
15
+ }
16
+ /**
17
+ * Result of circular dependency analysis
18
+ */
19
+ export interface CircularDependencyAnalysis {
20
+ /** Whether any circular dependencies were found */
21
+ hasCircularDependencies: boolean;
22
+ /** List of all detected circular dependencies */
23
+ circularDependencies: CircularDependency[];
24
+ /** Count of module-level cycles */
25
+ moduleCircularCount: number;
26
+ /** Count of provider-level cycles */
27
+ providerCircularCount: number;
28
+ }
29
+ /**
30
+ * Detects circular dependencies in module imports and provider dependencies
31
+ *
32
+ * Uses depth-first search (DFS) to detect cycles in the dependency graph.
33
+ * Can detect both module-level circular imports and provider-level circular dependencies.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const detector = new CircularDependencyDetector(modulesGraph);
38
+ * const analysis = detector.analyze();
39
+ *
40
+ * if (analysis.hasCircularDependencies) {
41
+ * console.error(`Found ${analysis.circularDependencies.length} circular dependencies`);
42
+ * analysis.circularDependencies.forEach(cycle => {
43
+ * console.error(`${cycle.type}: ${cycle.cycle.join(' -> ')}`);
44
+ * });
45
+ * }
46
+ * ```
47
+ */
48
+ export declare class CircularDependencyDetector {
49
+ private readonly graph;
50
+ /**
51
+ * Create a new CircularDependencyDetector instance
52
+ *
53
+ * @param graph - Map of module names to parsed modules
54
+ */
55
+ constructor(graph: Map<string, ParseNsModule | ParseEntryFile>);
56
+ /**
57
+ * Analyze the dependency graph for circular dependencies
58
+ *
59
+ * Performs both module-level and provider-level circular dependency detection.
60
+ *
61
+ * @returns CircularDependencyAnalysis with all detected cycles
62
+ */
63
+ analyze(): CircularDependencyAnalysis;
64
+ /**
65
+ * Detect circular dependencies in module imports
66
+ *
67
+ * Uses DFS to find cycles in the module import graph.
68
+ * A cycle exists when a module imports another module that eventually imports back to the original.
69
+ *
70
+ * @returns Array of detected module circular dependencies
71
+ */
72
+ private detectModuleCircularDependencies;
73
+ /**
74
+ * Depth-first search for module circular dependencies
75
+ */
76
+ private dfsModules;
77
+ /**
78
+ * Detect circular dependencies in provider dependencies
79
+ *
80
+ * Uses DFS to find cycles in the provider dependency graph.
81
+ * A cycle exists when a provider depends on another provider that eventually depends back on the original.
82
+ *
83
+ * @returns Array of detected provider circular dependencies
84
+ */
85
+ private detectProviderCircularDependencies;
86
+ /**
87
+ * Build a map of provider tokens to their dependencies
88
+ */
89
+ private buildProviderDependencyMap;
90
+ /**
91
+ * Depth-first search for provider circular dependencies
92
+ */
93
+ private dfsProviders;
94
+ }
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CircularDependencyDetector = void 0;
4
+ /**
5
+ * Detects circular dependencies in module imports and provider dependencies
6
+ *
7
+ * Uses depth-first search (DFS) to detect cycles in the dependency graph.
8
+ * Can detect both module-level circular imports and provider-level circular dependencies.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const detector = new CircularDependencyDetector(modulesGraph);
13
+ * const analysis = detector.analyze();
14
+ *
15
+ * if (analysis.hasCircularDependencies) {
16
+ * console.error(`Found ${analysis.circularDependencies.length} circular dependencies`);
17
+ * analysis.circularDependencies.forEach(cycle => {
18
+ * console.error(`${cycle.type}: ${cycle.cycle.join(' -> ')}`);
19
+ * });
20
+ * }
21
+ * ```
22
+ */
23
+ class CircularDependencyDetector {
24
+ /**
25
+ * Create a new CircularDependencyDetector instance
26
+ *
27
+ * @param graph - Map of module names to parsed modules
28
+ */
29
+ constructor(graph) {
30
+ this.graph = graph;
31
+ }
32
+ /**
33
+ * Analyze the dependency graph for circular dependencies
34
+ *
35
+ * Performs both module-level and provider-level circular dependency detection.
36
+ *
37
+ * @returns CircularDependencyAnalysis with all detected cycles
38
+ */
39
+ analyze() {
40
+ const circularDependencies = [];
41
+ // Detect module-level circular imports
42
+ const moduleCycles = this.detectModuleCircularDependencies();
43
+ circularDependencies.push(...moduleCycles);
44
+ // Detect provider-level circular dependencies
45
+ const providerCycles = this.detectProviderCircularDependencies();
46
+ circularDependencies.push(...providerCycles);
47
+ return {
48
+ hasCircularDependencies: circularDependencies.length > 0,
49
+ circularDependencies,
50
+ moduleCircularCount: moduleCycles.length,
51
+ providerCircularCount: providerCycles.length,
52
+ };
53
+ }
54
+ /**
55
+ * Detect circular dependencies in module imports
56
+ *
57
+ * Uses DFS to find cycles in the module import graph.
58
+ * A cycle exists when a module imports another module that eventually imports back to the original.
59
+ *
60
+ * @returns Array of detected module circular dependencies
61
+ */
62
+ detectModuleCircularDependencies() {
63
+ const cycles = [];
64
+ const visited = new Set();
65
+ const recursionStack = new Set();
66
+ const path = [];
67
+ const entryModule = this.graph.get("entry");
68
+ if (!entryModule || !entryModule.name) {
69
+ return cycles;
70
+ }
71
+ // Start DFS from entry module
72
+ this.dfsModules(entryModule.name, visited, recursionStack, path, cycles);
73
+ return cycles;
74
+ }
75
+ /**
76
+ * Depth-first search for module circular dependencies
77
+ */
78
+ dfsModules(moduleName, visited, recursionStack, path, cycles) {
79
+ // Mark current node as visited and add to recursion stack
80
+ visited.add(moduleName);
81
+ recursionStack.add(moduleName);
82
+ path.push(moduleName);
83
+ const parseNsModule = this.graph.get(moduleName);
84
+ if (!parseNsModule) {
85
+ // Clean up and return
86
+ recursionStack.delete(moduleName);
87
+ path.pop();
88
+ return;
89
+ }
90
+ // Visit all imported modules
91
+ for (const importedModule of parseNsModule.imports) {
92
+ if (!visited.has(importedModule)) {
93
+ // Recursively visit unvisited module
94
+ this.dfsModules(importedModule, visited, recursionStack, path, cycles);
95
+ }
96
+ else if (recursionStack.has(importedModule)) {
97
+ // Found a cycle - extract the cycle path
98
+ const cycleStartIndex = path.indexOf(importedModule);
99
+ const cyclePath = path.slice(cycleStartIndex);
100
+ cyclePath.push(importedModule); // Complete the cycle
101
+ cycles.push({
102
+ type: "module",
103
+ cycle: cyclePath,
104
+ severity: "error",
105
+ message: `Circular module import detected: ${cyclePath.join(" -> ")}`,
106
+ });
107
+ }
108
+ }
109
+ // Remove from recursion stack and path
110
+ recursionStack.delete(moduleName);
111
+ path.pop();
112
+ }
113
+ /**
114
+ * Detect circular dependencies in provider dependencies
115
+ *
116
+ * Uses DFS to find cycles in the provider dependency graph.
117
+ * A cycle exists when a provider depends on another provider that eventually depends back on the original.
118
+ *
119
+ * @returns Array of detected provider circular dependencies
120
+ */
121
+ detectProviderCircularDependencies() {
122
+ const cycles = [];
123
+ const visited = new Set();
124
+ const recursionStack = new Set();
125
+ const path = [];
126
+ // Build provider dependency map
127
+ const providerDeps = this.buildProviderDependencyMap();
128
+ // Run DFS from each provider
129
+ for (const providerToken of providerDeps.keys()) {
130
+ if (!visited.has(providerToken)) {
131
+ this.dfsProviders(providerToken, providerDeps, visited, recursionStack, path, cycles);
132
+ }
133
+ }
134
+ return cycles;
135
+ }
136
+ /**
137
+ * Build a map of provider tokens to their dependencies
138
+ */
139
+ buildProviderDependencyMap() {
140
+ const providerDeps = new Map();
141
+ // Traverse all modules
142
+ for (const [key, value] of this.graph.entries()) {
143
+ if (key === "entry")
144
+ continue;
145
+ const parseNsModule = value;
146
+ if (!parseNsModule.providers)
147
+ continue;
148
+ // Extract dependencies for each provider
149
+ for (const provider of parseNsModule.providers) {
150
+ if (!provider.token)
151
+ continue;
152
+ const dependencies = [];
153
+ if (provider.dependencies && Array.isArray(provider.dependencies)) {
154
+ for (const dep of provider.dependencies) {
155
+ if (dep.token && !dep.optional) {
156
+ dependencies.push(dep.token);
157
+ }
158
+ }
159
+ }
160
+ providerDeps.set(provider.token, dependencies);
161
+ }
162
+ }
163
+ return providerDeps;
164
+ }
165
+ /**
166
+ * Depth-first search for provider circular dependencies
167
+ */
168
+ dfsProviders(providerToken, providerDeps, visited, recursionStack, path, cycles) {
169
+ // Mark current node as visited and add to recursion stack
170
+ visited.add(providerToken);
171
+ recursionStack.add(providerToken);
172
+ path.push(providerToken);
173
+ const dependencies = providerDeps.get(providerToken) || [];
174
+ // Visit all dependencies
175
+ for (const depToken of dependencies) {
176
+ if (!providerDeps.has(depToken)) {
177
+ // Dependency is not a provider (might be external), skip
178
+ continue;
179
+ }
180
+ if (!visited.has(depToken)) {
181
+ // Recursively visit unvisited dependency
182
+ this.dfsProviders(depToken, providerDeps, visited, recursionStack, path, cycles);
183
+ }
184
+ else if (recursionStack.has(depToken)) {
185
+ // Found a cycle - extract the cycle path
186
+ const cycleStartIndex = path.indexOf(depToken);
187
+ const cyclePath = path.slice(cycleStartIndex);
188
+ cyclePath.push(depToken); // Complete the cycle
189
+ cycles.push({
190
+ type: "provider",
191
+ cycle: cyclePath,
192
+ severity: "error",
193
+ message: `Circular provider dependency detected: ${cyclePath.join(" -> ")}`,
194
+ });
195
+ }
196
+ }
197
+ // Remove from recursion stack and path
198
+ recursionStack.delete(providerToken);
199
+ path.pop();
200
+ }
201
+ }
202
+ exports.CircularDependencyDetector = CircularDependencyDetector;
203
+ //# sourceMappingURL=circular-dependency-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circular-dependency-detector.js","sourceRoot":"","sources":["../../src/analyzer/circular-dependency-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import type { ParseEntryFile } from "../parser/parse-entry-file";
2
+ import type { ParseNsModule } from "../parser/parse-ns-module";
3
+ /**
4
+ * Information about a module's position in the hierarchy
5
+ */
6
+ export interface ModuleDepthInfo {
7
+ /** Module name */
8
+ name: string;
9
+ /** Depth level in the import hierarchy (0 = entry module) */
10
+ depth: number;
11
+ /** Number of direct imports */
12
+ directImports: number;
13
+ /** Number of transitive dependencies (all modules this depends on) */
14
+ transitiveDependencies: number;
15
+ /** Number of modules that directly import this module (fan-in) */
16
+ fanIn: number;
17
+ /** Number of modules this module directly imports (fan-out) */
18
+ fanOut: number;
19
+ }
20
+ /**
21
+ * Depth level information
22
+ */
23
+ export interface DepthLevel {
24
+ /** Depth level number */
25
+ level: number;
26
+ /** Modules at this depth level */
27
+ modules: string[];
28
+ /** Number of modules at this level */
29
+ count: number;
30
+ }
31
+ /**
32
+ * Result of module depth analysis
33
+ */
34
+ export interface ModuleDepthAnalysis {
35
+ /** Whether depth analysis was performed */
36
+ hasDepthAnalysis: boolean;
37
+ /** Maximum depth in the module hierarchy */
38
+ maxDepth: number;
39
+ /** Average depth across all modules */
40
+ averageDepth: number;
41
+ /** Total number of modules analyzed */
42
+ totalModules: number;
43
+ /** Modules at each depth level */
44
+ depthLevels: DepthLevel[];
45
+ /** Detailed information for each module */
46
+ moduleDetails: ModuleDepthInfo[];
47
+ /** Modules with excessive depth (potential code smell) */
48
+ deepModules: ModuleDepthInfo[];
49
+ /** Threshold used for identifying deep modules */
50
+ deepModuleThreshold: number;
51
+ }
52
+ /**
53
+ * Analyzes module hierarchy depth and complexity metrics
54
+ *
55
+ * Calculates various metrics about module organization including:
56
+ * - Depth of module import chains
57
+ * - Module complexity metrics (fan-in, fan-out)
58
+ * - Identification of overly deep hierarchies
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const analyzer = new ModuleDepthAnalyzer(modulesGraph);
63
+ * const analysis = analyzer.analyze();
64
+ *
65
+ * console.log(`Max depth: ${analysis.maxDepth}`);
66
+ * console.log(`Average depth: ${analysis.averageDepth.toFixed(2)}`);
67
+ *
68
+ * if (analysis.deepModules.length > 0) {
69
+ * console.warn(`Found ${analysis.deepModules.length} modules with excessive depth`);
70
+ * }
71
+ * ```
72
+ */
73
+ export declare class ModuleDepthAnalyzer {
74
+ private readonly graph;
75
+ private readonly deepModuleThreshold;
76
+ /**
77
+ * Create a new ModuleDepthAnalyzer instance
78
+ *
79
+ * @param graph - Map of module names to parsed modules
80
+ * @param deepModuleThreshold - Custom threshold for deep modules (optional)
81
+ */
82
+ constructor(graph: Map<string, ParseNsModule | ParseEntryFile>, deepModuleThreshold?: number);
83
+ /**
84
+ * Analyze the module hierarchy depth and complexity
85
+ *
86
+ * @returns ModuleDepthAnalysis with all calculated metrics
87
+ */
88
+ analyze(): ModuleDepthAnalysis;
89
+ /**
90
+ * Get all modules from the graph (excluding entry file)
91
+ */
92
+ private getModules;
93
+ /**
94
+ * Calculate depth for each module using BFS from entry point
95
+ */
96
+ private calculateModuleDepths;
97
+ /**
98
+ * Calculate complexity metrics for each module
99
+ */
100
+ private calculateComplexityMetrics;
101
+ /**
102
+ * Calculate fan-in for all modules (how many modules depend on each module)
103
+ */
104
+ private calculateFanIn;
105
+ /**
106
+ * Calculate transitive dependencies for a module (all modules it depends on)
107
+ */
108
+ private calculateTransitiveDependencies;
109
+ /**
110
+ * Group modules by depth level
111
+ */
112
+ private groupByDepthLevel;
113
+ /**
114
+ * Create an empty analysis result
115
+ */
116
+ private createEmptyAnalysis;
117
+ }
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ModuleDepthAnalyzer = void 0;
4
+ /**
5
+ * Analyzes module hierarchy depth and complexity metrics
6
+ *
7
+ * Calculates various metrics about module organization including:
8
+ * - Depth of module import chains
9
+ * - Module complexity metrics (fan-in, fan-out)
10
+ * - Identification of overly deep hierarchies
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const analyzer = new ModuleDepthAnalyzer(modulesGraph);
15
+ * const analysis = analyzer.analyze();
16
+ *
17
+ * console.log(`Max depth: ${analysis.maxDepth}`);
18
+ * console.log(`Average depth: ${analysis.averageDepth.toFixed(2)}`);
19
+ *
20
+ * if (analysis.deepModules.length > 0) {
21
+ * console.warn(`Found ${analysis.deepModules.length} modules with excessive depth`);
22
+ * }
23
+ * ```
24
+ */
25
+ class ModuleDepthAnalyzer {
26
+ /**
27
+ * Create a new ModuleDepthAnalyzer instance
28
+ *
29
+ * @param graph - Map of module names to parsed modules
30
+ * @param deepModuleThreshold - Custom threshold for deep modules (optional)
31
+ */
32
+ constructor(graph, deepModuleThreshold = 5) {
33
+ this.graph = graph;
34
+ this.deepModuleThreshold = deepModuleThreshold;
35
+ }
36
+ /**
37
+ * Analyze the module hierarchy depth and complexity
38
+ *
39
+ * @returns ModuleDepthAnalysis with all calculated metrics
40
+ */
41
+ analyze() {
42
+ const modules = this.getModules();
43
+ if (modules.length === 0) {
44
+ return this.createEmptyAnalysis();
45
+ }
46
+ // Calculate depth for each module
47
+ const moduleDepths = this.calculateModuleDepths();
48
+ // Calculate complexity metrics
49
+ const moduleDetails = this.calculateComplexityMetrics(moduleDepths);
50
+ // Group modules by depth level
51
+ const depthLevels = this.groupByDepthLevel(moduleDetails);
52
+ // Calculate statistics
53
+ const maxDepth = Math.max(...moduleDetails.map((m) => m.depth));
54
+ const averageDepth = moduleDetails.reduce((sum, m) => sum + m.depth, 0) / moduleDetails.length;
55
+ // Identify deep modules
56
+ const deepModules = moduleDetails.filter((m) => m.depth >= this.deepModuleThreshold);
57
+ return {
58
+ hasDepthAnalysis: true,
59
+ maxDepth,
60
+ averageDepth,
61
+ totalModules: moduleDetails.length,
62
+ depthLevels,
63
+ moduleDetails,
64
+ deepModules,
65
+ deepModuleThreshold: this.deepModuleThreshold,
66
+ };
67
+ }
68
+ /**
69
+ * Get all modules from the graph (excluding entry file)
70
+ */
71
+ getModules() {
72
+ const modules = [];
73
+ for (const [key, value] of this.graph.entries()) {
74
+ if (key !== "entry" && "imports" in value) {
75
+ modules.push(value);
76
+ }
77
+ }
78
+ return modules;
79
+ }
80
+ /**
81
+ * Calculate depth for each module using BFS from entry point
82
+ */
83
+ calculateModuleDepths() {
84
+ const depths = new Map();
85
+ const entry = this.graph.get("entry");
86
+ if (!entry || !entry.name) {
87
+ return depths;
88
+ }
89
+ // Start BFS from entry module
90
+ const queue = [
91
+ { name: entry.name, depth: 0 },
92
+ ];
93
+ const visited = new Set();
94
+ while (queue.length > 0) {
95
+ const current = queue.shift();
96
+ if (visited.has(current.name)) {
97
+ continue;
98
+ }
99
+ visited.add(current.name);
100
+ depths.set(current.name, current.depth);
101
+ // Get module from graph
102
+ const module = this.graph.get(current.name);
103
+ if (!module || !("imports" in module)) {
104
+ continue;
105
+ }
106
+ // Add all imports to queue with incremented depth
107
+ for (const importName of module.imports) {
108
+ if (!visited.has(importName)) {
109
+ queue.push({ name: importName, depth: current.depth + 1 });
110
+ }
111
+ }
112
+ }
113
+ return depths;
114
+ }
115
+ /**
116
+ * Calculate complexity metrics for each module
117
+ */
118
+ calculateComplexityMetrics(moduleDepths) {
119
+ const moduleDetails = [];
120
+ const fanInMap = this.calculateFanIn();
121
+ for (const [moduleName, depth] of moduleDepths.entries()) {
122
+ const module = this.graph.get(moduleName);
123
+ if (!module || !("imports" in module)) {
124
+ continue;
125
+ }
126
+ const directImports = module.imports.length;
127
+ const transitiveDependencies = this.calculateTransitiveDependencies(moduleName);
128
+ const fanIn = fanInMap.get(moduleName) || 0;
129
+ const fanOut = directImports;
130
+ moduleDetails.push({
131
+ name: moduleName,
132
+ depth,
133
+ directImports,
134
+ transitiveDependencies,
135
+ fanIn,
136
+ fanOut,
137
+ });
138
+ }
139
+ return moduleDetails;
140
+ }
141
+ /**
142
+ * Calculate fan-in for all modules (how many modules depend on each module)
143
+ */
144
+ calculateFanIn() {
145
+ const fanInMap = new Map();
146
+ for (const [key, value] of this.graph.entries()) {
147
+ if (key === "entry" || !("imports" in value)) {
148
+ continue;
149
+ }
150
+ const module = value;
151
+ for (const importName of module.imports) {
152
+ fanInMap.set(importName, (fanInMap.get(importName) || 0) + 1);
153
+ }
154
+ }
155
+ return fanInMap;
156
+ }
157
+ /**
158
+ * Calculate transitive dependencies for a module (all modules it depends on)
159
+ */
160
+ calculateTransitiveDependencies(moduleName) {
161
+ const visited = new Set();
162
+ const queue = [moduleName];
163
+ while (queue.length > 0) {
164
+ const current = queue.shift();
165
+ if (visited.has(current)) {
166
+ continue;
167
+ }
168
+ visited.add(current);
169
+ const module = this.graph.get(current);
170
+ if (!module || !("imports" in module)) {
171
+ continue;
172
+ }
173
+ for (const importName of module.imports) {
174
+ if (!visited.has(importName)) {
175
+ queue.push(importName);
176
+ }
177
+ }
178
+ }
179
+ // Subtract 1 to exclude the module itself
180
+ return visited.size - 1;
181
+ }
182
+ /**
183
+ * Group modules by depth level
184
+ */
185
+ groupByDepthLevel(moduleDetails) {
186
+ const levelMap = new Map();
187
+ for (const module of moduleDetails) {
188
+ const modules = levelMap.get(module.depth) || [];
189
+ modules.push(module.name);
190
+ levelMap.set(module.depth, modules);
191
+ }
192
+ const depthLevels = [];
193
+ for (const [level, modules] of levelMap.entries()) {
194
+ depthLevels.push({
195
+ level,
196
+ modules,
197
+ count: modules.length,
198
+ });
199
+ }
200
+ // Sort by level
201
+ depthLevels.sort((a, b) => a.level - b.level);
202
+ return depthLevels;
203
+ }
204
+ /**
205
+ * Create an empty analysis result
206
+ */
207
+ createEmptyAnalysis() {
208
+ return {
209
+ hasDepthAnalysis: false,
210
+ maxDepth: 0,
211
+ averageDepth: 0,
212
+ totalModules: 0,
213
+ depthLevels: [],
214
+ moduleDetails: [],
215
+ deepModules: [],
216
+ deepModuleThreshold: this.deepModuleThreshold,
217
+ };
218
+ }
219
+ }
220
+ exports.ModuleDepthAnalyzer = ModuleDepthAnalyzer;
221
+ //# sourceMappingURL=module-depth-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-depth-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/module-depth-analyzer.ts"],"names":[],"mappings":"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"}