@nexus-ioc/graph-analyzer 0.1.0 → 0.2.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 (97) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +63 -26
  3. package/dist/analyzer/circular-dependency-detector.d.ts +29 -9
  4. package/dist/analyzer/circular-dependency-detector.js +106 -63
  5. package/dist/analyzer/circular-dependency-detector.js.map +1 -1
  6. package/dist/analyzer/module-depth-analyzer.d.ts +10 -13
  7. package/dist/analyzer/module-depth-analyzer.js +40 -52
  8. package/dist/analyzer/module-depth-analyzer.js.map +1 -1
  9. package/dist/analyzer/provider-scope-analyzer.d.ts +7 -44
  10. package/dist/analyzer/provider-scope-analyzer.js +13 -84
  11. package/dist/analyzer/provider-scope-analyzer.js.map +1 -1
  12. package/dist/analyzer/unused-provider-detector.d.ts +11 -9
  13. package/dist/analyzer/unused-provider-detector.js +35 -55
  14. package/dist/analyzer/unused-provider-detector.js.map +1 -1
  15. package/dist/cli.js +34 -129
  16. package/dist/cli.js.map +1 -1
  17. package/dist/config/config-loader.js +3 -27
  18. package/dist/config/config-loader.js.map +1 -1
  19. package/dist/config/config-schema.d.ts +2 -16
  20. package/dist/config/config-schema.js +0 -18
  21. package/dist/config/config-schema.js.map +1 -1
  22. package/dist/graph/build-nexus-graph-model.d.ts +13 -0
  23. package/dist/graph/build-nexus-graph-model.js +202 -0
  24. package/dist/graph/build-nexus-graph-model.js.map +1 -0
  25. package/dist/graph/nexus-graph-model.d.ts +112 -0
  26. package/dist/graph/nexus-graph-model.js +10 -0
  27. package/dist/graph/nexus-graph-model.js.map +1 -0
  28. package/dist/graph/scope-resolution.d.ts +16 -0
  29. package/dist/graph/scope-resolution.js +46 -0
  30. package/dist/graph/scope-resolution.js.map +1 -0
  31. package/dist/index.d.ts +27 -29
  32. package/dist/index.js +34 -34
  33. package/dist/index.js.map +1 -1
  34. package/dist/interfaces/graph-output.interface.d.ts +49 -14
  35. package/dist/utils/error-formatter.js +1 -6
  36. package/dist/utils/error-formatter.js.map +1 -1
  37. package/dist/utils/validator.d.ts +0 -5
  38. package/dist/utils/validator.js +0 -60
  39. package/dist/utils/validator.js.map +1 -1
  40. package/dist/visualize/json-formatter.d.ts +5 -6
  41. package/dist/visualize/json-formatter.js +49 -47
  42. package/dist/visualize/json-formatter.js.map +1 -1
  43. package/package.json +5 -4
  44. package/dist/interfaces/providers.interface.d.ts +0 -10
  45. package/dist/interfaces/providers.interface.js +0 -3
  46. package/dist/interfaces/providers.interface.js.map +0 -1
  47. package/dist/parser/dependency-extractor.d.ts +0 -88
  48. package/dist/parser/dependency-extractor.js +0 -334
  49. package/dist/parser/dependency-extractor.js.map +0 -1
  50. package/dist/parser/parse-entry-file.d.ts +0 -15
  51. package/dist/parser/parse-entry-file.js +0 -46
  52. package/dist/parser/parse-entry-file.js.map +0 -1
  53. package/dist/parser/parse-imports.d.ts +0 -15
  54. package/dist/parser/parse-imports.js +0 -65
  55. package/dist/parser/parse-imports.js.map +0 -1
  56. package/dist/parser/parse-ns-module.d.ts +0 -39
  57. package/dist/parser/parse-ns-module.js +0 -122
  58. package/dist/parser/parse-ns-module.js.map +0 -1
  59. package/dist/parser/parse-provider.d.ts +0 -2
  60. package/dist/parser/parse-provider.js +0 -7
  61. package/dist/parser/parse-provider.js.map +0 -1
  62. package/dist/parser/parse-ts-config.d.ts +0 -10
  63. package/dist/parser/parse-ts-config.js +0 -40
  64. package/dist/parser/parse-ts-config.js.map +0 -1
  65. package/dist/parser/parser-rec.d.ts +0 -1
  66. package/dist/parser/parser-rec.js +0 -52
  67. package/dist/parser/parser-rec.js.map +0 -1
  68. package/dist/parser/parser.d.ts +0 -1
  69. package/dist/parser/parser.js +0 -61
  70. package/dist/parser/parser.js.map +0 -1
  71. package/dist/parser/provider/class-parser.d.ts +0 -20
  72. package/dist/parser/provider/class-parser.js +0 -137
  73. package/dist/parser/provider/class-parser.js.map +0 -1
  74. package/dist/parser/provider/providers-parser.d.ts +0 -9
  75. package/dist/parser/provider/providers-parser.js +0 -32
  76. package/dist/parser/provider/providers-parser.js.map +0 -1
  77. package/dist/parser/provider/use-class-parser.d.ts +0 -25
  78. package/dist/parser/provider/use-class-parser.js +0 -161
  79. package/dist/parser/provider/use-class-parser.js.map +0 -1
  80. package/dist/parser/provider/use-factory-parser.d.ts +0 -15
  81. package/dist/parser/provider/use-factory-parser.js +0 -53
  82. package/dist/parser/provider/use-factory-parser.js.map +0 -1
  83. package/dist/parser/provider/use-value-parser.d.ts +0 -13
  84. package/dist/parser/provider/use-value-parser.js +0 -41
  85. package/dist/parser/provider/use-value-parser.js.map +0 -1
  86. package/dist/parser/rules.d.ts +0 -10
  87. package/dist/parser/rules.js +0 -37
  88. package/dist/parser/rules.js.map +0 -1
  89. package/dist/visualize/generator.d.ts +0 -26
  90. package/dist/visualize/generator.js +0 -75
  91. package/dist/visualize/generator.js.map +0 -1
  92. package/dist/visualize/graph-analyzer.d.ts +0 -126
  93. package/dist/visualize/graph-analyzer.js +0 -199
  94. package/dist/visualize/graph-analyzer.js.map +0 -1
  95. package/dist/visualize/html-generator.d.ts +0 -71
  96. package/dist/visualize/html-generator.js +0 -1312
  97. package/dist/visualize/html-generator.js.map +0 -1
@@ -11,7 +11,7 @@ exports.ModuleDepthAnalyzer = void 0;
11
11
  *
12
12
  * @example
13
13
  * ```typescript
14
- * const analyzer = new ModuleDepthAnalyzer(modulesGraph);
14
+ * const analyzer = new ModuleDepthAnalyzer(graphModel);
15
15
  * const analysis = analyzer.analyze();
16
16
  *
17
17
  * console.log(`Max depth: ${analysis.maxDepth}`);
@@ -26,11 +26,11 @@ class ModuleDepthAnalyzer {
26
26
  /**
27
27
  * Create a new ModuleDepthAnalyzer instance
28
28
  *
29
- * @param graph - Map of module names to parsed modules
29
+ * @param graphModel - The application's graph model
30
30
  * @param deepModuleThreshold - Custom threshold for deep modules (optional)
31
31
  */
32
- constructor(graph, deepModuleThreshold = 5) {
33
- this.graph = graph;
32
+ constructor(graphModel, deepModuleThreshold = 5) {
33
+ this.graphModel = graphModel;
34
34
  this.deepModuleThreshold = deepModuleThreshold;
35
35
  }
36
36
  /**
@@ -39,12 +39,14 @@ class ModuleDepthAnalyzer {
39
39
  * @returns ModuleDepthAnalysis with all calculated metrics
40
40
  */
41
41
  analyze() {
42
- const modules = this.getModules();
43
- if (modules.length === 0) {
42
+ if (this.graphModel.modules.size === 0) {
44
43
  return this.createEmptyAnalysis();
45
44
  }
46
45
  // Calculate depth for each module
47
46
  const moduleDepths = this.calculateModuleDepths();
47
+ if (moduleDepths.size === 0) {
48
+ return this.createEmptyAnalysis();
49
+ }
48
50
  // Calculate complexity metrics
49
51
  const moduleDetails = this.calculateComplexityMetrics(moduleDepths);
50
52
  // Group modules by depth level
@@ -66,69 +68,58 @@ class ModuleDepthAnalyzer {
66
68
  };
67
69
  }
68
70
  /**
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
71
+ * Calculate depth for each module (by id) using BFS from entry point
82
72
  */
83
73
  calculateModuleDepths() {
84
74
  const depths = new Map();
85
- const entry = this.graph.get("entry");
86
- if (!entry || !entry.name) {
75
+ const entryModuleId = this.graphModel.entryModuleId;
76
+ if (!entryModuleId || !this.graphModel.modules.has(entryModuleId)) {
87
77
  return depths;
88
78
  }
89
79
  // Start BFS from entry module
90
80
  const queue = [
91
- { name: entry.name, depth: 0 },
81
+ { id: entryModuleId, depth: 0 },
92
82
  ];
93
83
  const visited = new Set();
94
84
  while (queue.length > 0) {
95
85
  const current = queue.shift();
96
- if (visited.has(current.name)) {
86
+ if (visited.has(current.id)) {
97
87
  continue;
98
88
  }
99
- visited.add(current.name);
100
- depths.set(current.name, current.depth);
89
+ visited.add(current.id);
90
+ depths.set(current.id, current.depth);
101
91
  // Get module from graph
102
- const module = this.graph.get(current.name);
103
- if (!module || !("imports" in module)) {
92
+ const module = this.graphModel.modules.get(current.id);
93
+ if (!module) {
104
94
  continue;
105
95
  }
106
96
  // 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 });
97
+ for (const importedModule of module.imports) {
98
+ if (!visited.has(importedModule.id)) {
99
+ queue.push({ id: importedModule.id, depth: current.depth + 1 });
110
100
  }
111
101
  }
112
102
  }
113
103
  return depths;
114
104
  }
115
105
  /**
116
- * Calculate complexity metrics for each module
106
+ * Calculate complexity metrics for each module. `moduleDepths` is keyed
107
+ * by id; the returned `ModuleDepthInfo[]` reports display names, as before.
117
108
  */
118
109
  calculateComplexityMetrics(moduleDepths) {
119
110
  const moduleDetails = [];
120
111
  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)) {
112
+ for (const [moduleId, depth] of moduleDepths.entries()) {
113
+ const module = this.graphModel.modules.get(moduleId);
114
+ if (!module) {
124
115
  continue;
125
116
  }
126
117
  const directImports = module.imports.length;
127
- const transitiveDependencies = this.calculateTransitiveDependencies(moduleName);
128
- const fanIn = fanInMap.get(moduleName) || 0;
118
+ const transitiveDependencies = this.calculateTransitiveDependencies(moduleId);
119
+ const fanIn = fanInMap.get(moduleId) || 0;
129
120
  const fanOut = directImports;
130
121
  moduleDetails.push({
131
- name: moduleName,
122
+ name: module.name,
132
123
  depth,
133
124
  directImports,
134
125
  transitiveDependencies,
@@ -139,17 +130,14 @@ class ModuleDepthAnalyzer {
139
130
  return moduleDetails;
140
131
  }
141
132
  /**
142
- * Calculate fan-in for all modules (how many modules depend on each module)
133
+ * Calculate fan-in for all modules (how many modules depend on each
134
+ * module), keyed by id
143
135
  */
144
136
  calculateFanIn() {
145
137
  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);
138
+ for (const module of this.graphModel.modules.values()) {
139
+ for (const importedModule of module.imports) {
140
+ fanInMap.set(importedModule.id, (fanInMap.get(importedModule.id) || 0) + 1);
153
141
  }
154
142
  }
155
143
  return fanInMap;
@@ -157,22 +145,22 @@ class ModuleDepthAnalyzer {
157
145
  /**
158
146
  * Calculate transitive dependencies for a module (all modules it depends on)
159
147
  */
160
- calculateTransitiveDependencies(moduleName) {
148
+ calculateTransitiveDependencies(moduleId) {
161
149
  const visited = new Set();
162
- const queue = [moduleName];
150
+ const queue = [moduleId];
163
151
  while (queue.length > 0) {
164
152
  const current = queue.shift();
165
153
  if (visited.has(current)) {
166
154
  continue;
167
155
  }
168
156
  visited.add(current);
169
- const module = this.graph.get(current);
170
- if (!module || !("imports" in module)) {
157
+ const module = this.graphModel.modules.get(current);
158
+ if (!module) {
171
159
  continue;
172
160
  }
173
- for (const importName of module.imports) {
174
- if (!visited.has(importName)) {
175
- queue.push(importName);
161
+ for (const importedModule of module.imports) {
162
+ if (!visited.has(importedModule.id)) {
163
+ queue.push(importedModule.id);
176
164
  }
177
165
  }
178
166
  }
@@ -1 +1 @@
1
- {"version":3,"file":"module-depth-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/module-depth-analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"module-depth-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/module-depth-analyzer.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,8 @@
1
- import type { ParseEntryFile } from "../parser/parse-entry-file";
2
- import type { ParseNsModule } from "../parser/parse-ns-module";
1
+ import type { NexusGraphModel } from "../graph/nexus-graph-model";
3
2
  /**
4
3
  * Provider scope types
5
4
  */
6
- export type ProviderScope = "Singleton" | "Request";
5
+ export type ProviderScope = "Singleton" | "Transient";
7
6
  /**
8
7
  * Information about a provider's scope
9
8
  */
@@ -19,27 +18,6 @@ export interface ProviderScopeInfo {
19
18
  /** Dependencies of this provider */
20
19
  dependencies: string[];
21
20
  }
22
- /**
23
- * Scope mismatch issue
24
- */
25
- export interface ScopeMismatch {
26
- /** Provider with scope issue */
27
- provider: string;
28
- /** Provider's scope */
29
- providerScope: ProviderScope;
30
- /** Module that registers the provider */
31
- module: string;
32
- /** Dependency that causes the mismatch */
33
- dependency: string;
34
- /** Dependency's scope */
35
- dependencyScope: ProviderScope;
36
- /** Severity of the issue */
37
- severity: "error" | "warning";
38
- /** Description of the issue */
39
- message: string;
40
- /** Suggestions for fixing the issue */
41
- suggestions: string[];
42
- }
43
21
  /**
44
22
  * Provider scope analysis results
45
23
  */
@@ -50,24 +28,17 @@ export interface ProviderScopeAnalysis {
50
28
  totalProviders: number;
51
29
  /** Number of singleton providers */
52
30
  singletonProviders: number;
53
- /** Number of request-scoped providers */
54
- requestProviders: number;
55
- /** Scope mismatches detected */
56
- scopeMismatches: ScopeMismatch[];
31
+ /** Number of transient providers */
32
+ transientProviders: number;
57
33
  /** All provider scope information */
58
34
  providerScopes: ProviderScopeInfo[];
59
35
  }
60
36
  /**
61
- * Analyzes provider scopes and detects scope-related issues
62
- *
63
- * This analyzer identifies:
64
- * - Singleton providers depending on request-scoped providers (scope mismatch)
65
- * - Potential memory leaks from scope misuse
66
- * - Scope optimization opportunities
37
+ * Reports each provider's scope (Singleton or Transient).
67
38
  */
68
39
  export declare class ProviderScopeAnalyzer {
69
- private readonly graph;
70
- constructor(graph: Map<string, ParseNsModule | ParseEntryFile>);
40
+ private readonly graphModel;
41
+ constructor(graphModel: NexusGraphModel);
71
42
  /**
72
43
  * Analyze provider scopes and detect issues
73
44
  */
@@ -80,12 +51,4 @@ export declare class ProviderScopeAnalyzer {
80
51
  * Extract scope from provider
81
52
  */
82
53
  private extractProviderScope;
83
- /**
84
- * Extract dependency tokens from provider
85
- */
86
- private extractDependencyTokens;
87
- /**
88
- * Detect scope mismatches in provider dependencies
89
- */
90
- private detectScopeMismatches;
91
54
  }
@@ -2,16 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ProviderScopeAnalyzer = void 0;
4
4
  /**
5
- * Analyzes provider scopes and detects scope-related issues
6
- *
7
- * This analyzer identifies:
8
- * - Singleton providers depending on request-scoped providers (scope mismatch)
9
- * - Potential memory leaks from scope misuse
10
- * - Scope optimization opportunities
5
+ * Reports each provider's scope (Singleton or Transient).
11
6
  */
12
7
  class ProviderScopeAnalyzer {
13
- constructor(graph) {
14
- this.graph = graph;
8
+ constructor(graphModel) {
9
+ this.graphModel = graphModel;
15
10
  }
16
11
  /**
17
12
  * Analyze provider scopes and detect issues
@@ -19,17 +14,14 @@ class ProviderScopeAnalyzer {
19
14
  analyze() {
20
15
  // Build provider scope map
21
16
  const providerScopes = this.buildProviderScopeMap();
22
- // Detect scope mismatches
23
- const scopeMismatches = this.detectScopeMismatches(providerScopes);
24
17
  // Calculate statistics
25
18
  const singletonCount = providerScopes.filter((p) => p.scope === "Singleton").length;
26
- const requestCount = providerScopes.filter((p) => p.scope === "Request").length;
19
+ const transientCount = providerScopes.filter((p) => p.scope === "Transient").length;
27
20
  return {
28
21
  hasScopeAnalysis: true,
29
22
  totalProviders: providerScopes.length,
30
23
  singletonProviders: singletonCount,
31
- requestProviders: requestCount,
32
- scopeMismatches,
24
+ transientProviders: transientCount,
33
25
  providerScopes,
34
26
  };
35
27
  }
@@ -38,20 +30,15 @@ class ProviderScopeAnalyzer {
38
30
  */
39
31
  buildProviderScopeMap() {
40
32
  const providerScopes = [];
41
- for (const [key, value] of this.graph.entries()) {
42
- if (key === "entry")
43
- continue;
44
- const parseNsModule = value;
45
- if (!parseNsModule.providers)
46
- continue;
47
- for (const provider of parseNsModule.providers) {
48
- if (!provider.token)
49
- continue;
33
+ for (const module of this.graphModel.modules.values()) {
34
+ for (const provider of module.providers) {
50
35
  const scope = this.extractProviderScope(provider);
51
- const dependencies = this.extractDependencyTokens(provider);
36
+ const dependencies = provider.dependencies
37
+ .filter((dep) => !dep.optional)
38
+ .map((dep) => dep.token);
52
39
  providerScopes.push({
53
40
  token: provider.token,
54
- module: parseNsModule.name || key,
41
+ module: module.name,
55
42
  scope,
56
43
  type: provider.type,
57
44
  dependencies,
@@ -67,71 +54,13 @@ class ProviderScopeAnalyzer {
67
54
  // Check if scope is explicitly defined (applies to all provider types)
68
55
  if (provider.scope) {
69
56
  const scopeStr = provider.scope.toLowerCase();
70
- if (scopeStr.includes("request") || scopeStr === "1") {
71
- return "Request";
57
+ if (scopeStr.includes("transient") || scopeStr === "2") {
58
+ return "Transient";
72
59
  }
73
60
  }
74
61
  // Default to Singleton for all provider types
75
62
  return "Singleton";
76
63
  }
77
- /**
78
- * Extract dependency tokens from provider
79
- */
80
- extractDependencyTokens(provider) {
81
- const tokens = [];
82
- // Extract from dependencies array (Class and UseClass providers)
83
- if (provider.dependencies && Array.isArray(provider.dependencies)) {
84
- for (const dep of provider.dependencies) {
85
- if (dep.token && !dep.optional) {
86
- tokens.push(dep.token);
87
- }
88
- }
89
- }
90
- // Extract from inject array (UseFactory providers)
91
- if (provider.inject && Array.isArray(provider.inject)) {
92
- tokens.push(...provider.inject);
93
- }
94
- return tokens;
95
- }
96
- /**
97
- * Detect scope mismatches in provider dependencies
98
- */
99
- detectScopeMismatches(providerScopes) {
100
- const mismatches = [];
101
- const scopeMap = new Map();
102
- // Build lookup map
103
- for (const provider of providerScopes) {
104
- scopeMap.set(provider.token, provider);
105
- }
106
- // Check each provider's dependencies
107
- for (const provider of providerScopes) {
108
- // Only check Singleton providers (they shouldn't depend on Request-scoped)
109
- if (provider.scope !== "Singleton") {
110
- continue;
111
- }
112
- for (const depToken of provider.dependencies) {
113
- const dependency = scopeMap.get(depToken);
114
- // If dependency is Request-scoped, this is a scope mismatch
115
- if (dependency && dependency.scope === "Request") {
116
- mismatches.push({
117
- provider: provider.token,
118
- providerScope: provider.scope,
119
- module: provider.module,
120
- dependency: depToken,
121
- dependencyScope: dependency.scope,
122
- severity: "error",
123
- message: `Singleton provider '${provider.token}' depends on Request-scoped provider '${depToken}'. This can cause memory leaks and unexpected behavior.`,
124
- suggestions: [
125
- `Change '${provider.token}' to Request scope`,
126
- `Change '${depToken}' to Singleton scope if it doesn't need request-specific state`,
127
- "Use a factory or lazy injection to resolve the dependency per request",
128
- ],
129
- });
130
- }
131
- }
132
- }
133
- return mismatches;
134
- }
135
64
  }
136
65
  exports.ProviderScopeAnalyzer = ProviderScopeAnalyzer;
137
66
  //# sourceMappingURL=provider-scope-analyzer.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider-scope-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/provider-scope-analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"provider-scope-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/provider-scope-analyzer.ts"],"names":[],"mappings":";;;AA0CA;;GAEG;AACH,MAAa,qBAAqB;IACjC,YAA6B,UAA2B;QAA3B,eAAU,GAAV,UAAU,CAAiB;IAAG,CAAC;IAE5D;;OAEG;IACH,OAAO;QACN,2BAA2B;QAC3B,MAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAEpD,uBAAuB;QACvB,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,WAAW,CAC9B,CAAC,MAAM,CAAC;QACT,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAC3C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,WAAW,CAC9B,CAAC,MAAM,CAAC;QAET,OAAO;YACN,gBAAgB,EAAE,IAAI;YACtB,cAAc,EAAE,cAAc,CAAC,MAAM;YACrC,kBAAkB,EAAE,cAAc;YAClC,kBAAkB,EAAE,cAAc;YAClC,cAAc;SACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB;QAC5B,MAAM,cAAc,GAAwB,EAAE,CAAC;QAE/C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YACvD,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACzC,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;gBAClD,MAAM,YAAY,GAAG,QAAQ,CAAC,YAAY;qBACxC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC;qBAC9B,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAE1B,cAAc,CAAC,IAAI,CAAC;oBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;oBACrB,MAAM,EAAE,MAAM,CAAC,IAAI;oBACnB,KAAK;oBACL,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,YAAY;iBACZ,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,OAAO,cAAc,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,QAA2B;QACvD,uEAAuE;QACvE,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9C,IAAI,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,KAAK,GAAG,EAAE,CAAC;gBACxD,OAAO,WAAW,CAAC;YACpB,CAAC;QACF,CAAC;QAED,8CAA8C;QAC9C,OAAO,WAAW,CAAC;IACpB,CAAC;CACD;AApED,sDAoEC"}
@@ -1,5 +1,4 @@
1
- import type { ParseEntryFile } from "../parser/parse-entry-file";
2
- import type { ParseNsModule } from "../parser/parse-ns-module";
1
+ import type { NexusGraphModel } from "../graph/nexus-graph-model";
3
2
  /**
4
3
  * Information about an unused provider
5
4
  */
@@ -38,7 +37,7 @@ export interface UnusedProviderAnalysis {
38
37
  *
39
38
  * @example
40
39
  * ```typescript
41
- * const detector = new UnusedProviderDetector(modulesGraph);
40
+ * const detector = new UnusedProviderDetector(graphModel);
42
41
  * const analysis = detector.analyze();
43
42
  *
44
43
  * if (analysis.hasUnusedProviders) {
@@ -50,8 +49,8 @@ export interface UnusedProviderAnalysis {
50
49
  * ```
51
50
  */
52
51
  export declare class UnusedProviderDetector {
53
- private readonly graph;
54
- constructor(graph: Map<string, ParseNsModule | ParseEntryFile>);
52
+ private readonly graphModel;
53
+ constructor(graphModel: NexusGraphModel);
55
54
  /**
56
55
  * Analyze the graph for unused providers
57
56
  *
@@ -59,13 +58,16 @@ export declare class UnusedProviderDetector {
59
58
  */
60
59
  analyze(): UnusedProviderAnalysis;
61
60
  /**
62
- * Build a set of all provider tokens that are injected as dependencies
61
+ * Build a set of all provider ids that are injected as dependencies.
62
+ * Keyed by `GraphProviderDependency.tokenId` (collision-free), not the
63
+ * rendered `token` — two different provider classes named alike must
64
+ * not collapse into one set entry.
63
65
  */
64
- private buildInjectedTokensSet;
66
+ private buildInjectedIdsSet;
65
67
  /**
66
- * Build a set of all provider tokens that are exported from modules
68
+ * Build a set of all provider/module ids that are exported from modules
67
69
  */
68
- private buildExportedTokensSet;
70
+ private buildExportedIdsSet;
69
71
  /**
70
72
  * Generate suggestions for resolving an unused provider
71
73
  */
@@ -11,7 +11,7 @@ exports.UnusedProviderDetector = void 0;
11
11
  *
12
12
  * @example
13
13
  * ```typescript
14
- * const detector = new UnusedProviderDetector(modulesGraph);
14
+ * const detector = new UnusedProviderDetector(graphModel);
15
15
  * const analysis = detector.analyze();
16
16
  *
17
17
  * if (analysis.hasUnusedProviders) {
@@ -23,8 +23,8 @@ exports.UnusedProviderDetector = void 0;
23
23
  * ```
24
24
  */
25
25
  class UnusedProviderDetector {
26
- constructor(graph) {
27
- this.graph = graph;
26
+ constructor(graphModel) {
27
+ this.graphModel = graphModel;
28
28
  }
29
29
  /**
30
30
  * Analyze the graph for unused providers
@@ -33,42 +33,33 @@ class UnusedProviderDetector {
33
33
  */
34
34
  analyze() {
35
35
  const unusedProviders = [];
36
- // Build a set of all injected provider tokens
37
- const injectedTokens = this.buildInjectedTokensSet();
38
- // Build a set of all exported provider tokens
39
- const exportedTokens = this.buildExportedTokensSet();
36
+ // Build a set of all injected provider ids
37
+ const injectedIds = this.buildInjectedIdsSet();
38
+ // Build a set of all exported provider/module ids
39
+ const exportedIds = this.buildExportedIdsSet();
40
40
  // Check each module for unused providers
41
- for (const [moduleName, module] of this.graph) {
42
- if (moduleName === "entry")
43
- continue;
44
- const nsModule = module;
45
- if (!nsModule.providers || nsModule.providers.length === 0)
46
- continue;
41
+ for (const module of this.graphModel.modules.values()) {
47
42
  // Check each provider in the module
48
- for (const provider of nsModule.providers) {
43
+ for (const provider of module.providers) {
49
44
  const token = provider.token;
50
- // Skip providers with null tokens
51
- if (!token)
52
- continue;
53
45
  // Skip if the provider is injected somewhere
54
- if (injectedTokens.has(token))
46
+ if (injectedIds.has(provider.id))
55
47
  continue;
56
48
  // Skip if the provider is exported (it may be used externally)
57
- if (exportedTokens.has(token))
49
+ const isExported = exportedIds.has(provider.id);
50
+ if (isExported)
58
51
  continue;
59
52
  // Skip if the module is global (providers may be used across the app)
60
- if (nsModule.isGlobal)
53
+ if (module.isGlobal)
61
54
  continue;
62
55
  // This provider is unused
63
- const suggestions = this.generateSuggestions(token, moduleName, exportedTokens.has(token), nsModule.isGlobal);
64
- // Normalize provider type to match expected union type
65
- const providerType = provider.type;
56
+ const suggestions = this.generateSuggestions(token, module.name, isExported, module.isGlobal);
66
57
  unusedProviders.push({
67
58
  token,
68
- module: moduleName,
69
- type: providerType,
59
+ module: module.name,
60
+ type: provider.type,
70
61
  severity: "warning",
71
- message: `Provider '${token}' is registered in '${moduleName}' but never injected`,
62
+ message: `Provider '${token}' is registered in '${module.name}' but never injected`,
72
63
  suggestions,
73
64
  });
74
65
  }
@@ -80,47 +71,36 @@ class UnusedProviderDetector {
80
71
  };
81
72
  }
82
73
  /**
83
- * Build a set of all provider tokens that are injected as dependencies
74
+ * Build a set of all provider ids that are injected as dependencies.
75
+ * Keyed by `GraphProviderDependency.tokenId` (collision-free), not the
76
+ * rendered `token` — two different provider classes named alike must
77
+ * not collapse into one set entry.
84
78
  */
85
- buildInjectedTokensSet() {
86
- const injectedTokens = new Set();
87
- for (const [moduleName, module] of this.graph) {
88
- if (moduleName === "entry")
89
- continue;
90
- const nsModule = module;
91
- if (!nsModule.providers)
92
- continue;
93
- // Check dependencies of each provider
94
- for (const provider of nsModule.providers) {
95
- if (!provider.dependencies)
96
- continue;
79
+ buildInjectedIdsSet() {
80
+ const injectedIds = new Set();
81
+ for (const module of this.graphModel.modules.values()) {
82
+ for (const provider of module.providers) {
97
83
  for (const dependency of provider.dependencies) {
98
84
  // Skip optional dependencies as they may not be required
99
- if (!dependency.optional) {
100
- injectedTokens.add(dependency.token);
85
+ if (!dependency.optional && dependency.tokenId) {
86
+ injectedIds.add(dependency.tokenId);
101
87
  }
102
88
  }
103
89
  }
104
90
  }
105
- return injectedTokens;
91
+ return injectedIds;
106
92
  }
107
93
  /**
108
- * Build a set of all provider tokens that are exported from modules
94
+ * Build a set of all provider/module ids that are exported from modules
109
95
  */
110
- buildExportedTokensSet() {
111
- const exportedTokens = new Set();
112
- for (const [moduleName, module] of this.graph) {
113
- if (moduleName === "entry")
114
- continue;
115
- const nsModule = module;
116
- if (!nsModule.exports)
117
- continue;
118
- // Add all exported tokens
119
- for (const exportedToken of nsModule.exports) {
120
- exportedTokens.add(exportedToken);
96
+ buildExportedIdsSet() {
97
+ const exportedIds = new Set();
98
+ for (const module of this.graphModel.modules.values()) {
99
+ for (const exportedEntry of module.exports) {
100
+ exportedIds.add(exportedEntry.id);
121
101
  }
122
102
  }
123
- return exportedTokens;
103
+ return exportedIds;
124
104
  }
125
105
  /**
126
106
  * Generate suggestions for resolving an unused provider