@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,205 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadConfigFile = loadConfigFile;
4
+ exports.findConfigFile = findConfigFile;
5
+ exports.loadConfig = loadConfig;
6
+ exports.generateConfigFile = generateConfigFile;
7
+ const tslib_1 = require("tslib");
8
+ const fs = tslib_1.__importStar(require("node:fs"));
9
+ const path = tslib_1.__importStar(require("node:path"));
10
+ const config_schema_1 = require("./config-schema");
11
+ /**
12
+ * Configuration file names to search for (in order of priority)
13
+ */
14
+ const CONFIG_FILE_NAMES = [
15
+ ".graph-analyzer.json",
16
+ "graph-analyzer.config.json",
17
+ "graph-analyzer.config.js",
18
+ ];
19
+ /**
20
+ * Loads configuration from a file
21
+ * @param configPath - Path to configuration file
22
+ * @returns Parsed configuration object
23
+ * @throws Error if file cannot be read or parsed
24
+ */
25
+ function loadConfigFile(configPath) {
26
+ if (!fs.existsSync(configPath)) {
27
+ throw new Error(`Configuration file not found: ${configPath}`);
28
+ }
29
+ const ext = path.extname(configPath);
30
+ try {
31
+ if (ext === ".json") {
32
+ return loadJsonConfig(configPath);
33
+ }
34
+ if (ext === ".js") {
35
+ return loadJsConfig(configPath);
36
+ }
37
+ throw new Error(`Unsupported configuration file format: ${ext}. Use .json or .js`);
38
+ }
39
+ catch (error) {
40
+ if (error instanceof Error) {
41
+ throw new Error(`Failed to load configuration: ${error.message}`);
42
+ }
43
+ throw error;
44
+ }
45
+ }
46
+ /**
47
+ * Loads JSON configuration file
48
+ */
49
+ function loadJsonConfig(configPath) {
50
+ const content = fs.readFileSync(configPath, "utf8");
51
+ const config = JSON.parse(content);
52
+ const errors = (0, config_schema_1.validateConfig)(config);
53
+ if (errors.length > 0) {
54
+ throw new Error(`Invalid configuration:\n${errors.map((e) => ` - ${e}`).join("\n")}`);
55
+ }
56
+ return config;
57
+ }
58
+ /**
59
+ * Loads JavaScript configuration file
60
+ */
61
+ function loadJsConfig(configPath) {
62
+ // Clear require cache to allow reloading
63
+ delete require.cache[path.resolve(configPath)];
64
+ // biome-ignore lint/security/noGlobalEval: Configuration files need to be evaluated
65
+ const config = require(path.resolve(configPath));
66
+ // Handle both module.exports and default export
67
+ const actualConfig = config.default || config;
68
+ const errors = (0, config_schema_1.validateConfig)(actualConfig);
69
+ if (errors.length > 0) {
70
+ throw new Error(`Invalid configuration:\n${errors.map((e) => ` - ${e}`).join("\n")}`);
71
+ }
72
+ return actualConfig;
73
+ }
74
+ /**
75
+ * Searches for a configuration file in the current directory and parent directories
76
+ * @param startDir - Directory to start searching from
77
+ * @returns Path to configuration file or null if not found
78
+ */
79
+ function findConfigFile(startDir = process.cwd()) {
80
+ let currentDir = path.resolve(startDir);
81
+ while (true) {
82
+ // Check each config file name in order
83
+ for (const fileName of CONFIG_FILE_NAMES) {
84
+ const configPath = path.join(currentDir, fileName);
85
+ if (fs.existsSync(configPath)) {
86
+ return configPath;
87
+ }
88
+ }
89
+ // Move to parent directory
90
+ const parentDir = path.dirname(currentDir);
91
+ if (parentDir === currentDir) {
92
+ // Reached root directory
93
+ break;
94
+ }
95
+ currentDir = parentDir;
96
+ }
97
+ return null;
98
+ }
99
+ /**
100
+ * Loads configuration from file or returns empty config if not found
101
+ * @param configPath - Optional explicit path to config file
102
+ * @param searchDir - Directory to start searching for config file
103
+ * @returns Configuration object
104
+ */
105
+ function loadConfig(configPath, searchDir) {
106
+ // If explicit path provided, use it
107
+ if (configPath) {
108
+ return loadConfigFile(configPath);
109
+ }
110
+ // Otherwise search for config file
111
+ const foundPath = findConfigFile(searchDir);
112
+ if (foundPath) {
113
+ return loadConfigFile(foundPath);
114
+ }
115
+ // No config file found, return empty config
116
+ return {};
117
+ }
118
+ /**
119
+ * Generates a default configuration file
120
+ * @param outputPath - Path where to write the config file
121
+ * @param format - Format of the config file (json or js)
122
+ */
123
+ function generateConfigFile(outputPath, format = "json") {
124
+ const dir = path.dirname(outputPath);
125
+ if (!fs.existsSync(dir)) {
126
+ fs.mkdirSync(dir, { recursive: true });
127
+ }
128
+ if (format === "json") {
129
+ const config = {
130
+ $schema: "Configuration for @nexus-ioc/graph-analyzer - see https://github.com/Isqanderm/ioc/tree/main/packages/graph-analyzer",
131
+ entryFile: "src/main.ts",
132
+ tsConfig: "./tsconfig.json",
133
+ output: "./graph",
134
+ format: "both",
135
+ ideProtocol: "vscode",
136
+ darkTheme: false,
137
+ verbose: false,
138
+ quiet: false,
139
+ };
140
+ fs.writeFileSync(outputPath, JSON.stringify(config, null, 2), "utf8");
141
+ }
142
+ else {
143
+ const jsContent = `/**
144
+ * Configuration for @nexus-ioc/graph-analyzer
145
+ * @see https://github.com/Isqanderm/ioc/tree/main/packages/graph-analyzer
146
+ */
147
+ module.exports = {
148
+ /**
149
+ * Path to the entry point file
150
+ * @type {string}
151
+ */
152
+ entryFile: 'src/main.ts',
153
+
154
+ /**
155
+ * Path to tsconfig.json
156
+ * @type {string}
157
+ */
158
+ tsConfig: './tsconfig.json',
159
+
160
+ /**
161
+ * Output file path (extension will be added based on format)
162
+ * @type {string}
163
+ */
164
+ output: './graph',
165
+
166
+ /**
167
+ * Output format: 'json', 'png', 'html', or 'both'
168
+ * @type {'json' | 'png' | 'html' | 'both'}
169
+ * @default 'both'
170
+ */
171
+ format: 'both',
172
+
173
+ /**
174
+ * IDE protocol for clickable links in HTML output
175
+ * @type {'vscode' | 'webstorm' | 'idea'}
176
+ * @default 'vscode'
177
+ */
178
+ ideProtocol: 'vscode',
179
+
180
+ /**
181
+ * Use dark theme for HTML output
182
+ * @type {boolean}
183
+ * @default false
184
+ */
185
+ darkTheme: false,
186
+
187
+ /**
188
+ * Show detailed progress information
189
+ * @type {boolean}
190
+ * @default false
191
+ */
192
+ verbose: false,
193
+
194
+ /**
195
+ * Suppress all output except errors
196
+ * @type {boolean}
197
+ * @default false
198
+ */
199
+ quiet: false,
200
+ };
201
+ `;
202
+ fs.writeFileSync(outputPath, jsContent, "utf8");
203
+ }
204
+ }
205
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Configuration schema for graph-analyzer
3
+ */
4
+ export interface GraphAnalyzerConfig {
5
+ /**
6
+ * Path to the entry point file
7
+ */
8
+ entryFile?: string;
9
+ /**
10
+ * Path to tsconfig.json
11
+ */
12
+ tsConfig?: string;
13
+ /**
14
+ * Output file path
15
+ */
16
+ output?: string;
17
+ /**
18
+ * Output format: json, png, html, or both
19
+ * @default "both"
20
+ */
21
+ format?: "json" | "png" | "html" | "both";
22
+ /**
23
+ * IDE protocol for clickable links in HTML output
24
+ * @default "vscode"
25
+ */
26
+ ideProtocol?: "vscode" | "webstorm" | "idea";
27
+ /**
28
+ * Use dark theme for HTML output
29
+ * @default false
30
+ */
31
+ darkTheme?: boolean;
32
+ /**
33
+ * Show detailed progress information
34
+ * @default false
35
+ */
36
+ verbose?: boolean;
37
+ /**
38
+ * Suppress all output except errors
39
+ * @default false
40
+ */
41
+ quiet?: boolean;
42
+ /**
43
+ * Detect circular dependencies in modules and providers
44
+ * @default false
45
+ */
46
+ checkCircular?: boolean;
47
+ /**
48
+ * Detect providers that are registered but never injected
49
+ * @default false
50
+ */
51
+ checkUnused?: boolean;
52
+ /**
53
+ * Analyze module hierarchy depth and complexity metrics
54
+ * @default false
55
+ */
56
+ checkDepth?: boolean;
57
+ /**
58
+ * Threshold for identifying deep modules
59
+ * @default 5
60
+ */
61
+ deepModuleThreshold?: number;
62
+ /**
63
+ * Analyze provider scopes and detect scope mismatches
64
+ * @default false
65
+ */
66
+ checkScope?: boolean;
67
+ }
68
+ /**
69
+ * Default configuration values
70
+ */
71
+ export declare const DEFAULT_CONFIG: Partial<GraphAnalyzerConfig>;
72
+ /**
73
+ * Validates a configuration object
74
+ * @param config - Configuration to validate
75
+ * @returns Array of validation errors (empty if valid)
76
+ */
77
+ export declare function validateConfig(config: unknown): string[];
78
+ /**
79
+ * Merges multiple configuration objects with priority (later configs override earlier ones)
80
+ * @param configs - Configuration objects to merge
81
+ * @returns Merged configuration
82
+ */
83
+ export declare function mergeConfigs(...configs: Array<Partial<GraphAnalyzerConfig>>): Partial<GraphAnalyzerConfig>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * Configuration schema for graph-analyzer
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_CONFIG = void 0;
7
+ exports.validateConfig = validateConfig;
8
+ exports.mergeConfigs = mergeConfigs;
9
+ /**
10
+ * Default configuration values
11
+ */
12
+ exports.DEFAULT_CONFIG = {
13
+ format: "both",
14
+ ideProtocol: "vscode",
15
+ darkTheme: false,
16
+ verbose: false,
17
+ quiet: false,
18
+ checkCircular: false,
19
+ checkUnused: false,
20
+ checkDepth: false,
21
+ deepModuleThreshold: 5,
22
+ checkScope: false,
23
+ };
24
+ /**
25
+ * Validates a configuration object
26
+ * @param config - Configuration to validate
27
+ * @returns Array of validation errors (empty if valid)
28
+ */
29
+ function validateConfig(config) {
30
+ const errors = [];
31
+ if (typeof config !== "object" || config === null) {
32
+ errors.push("Configuration must be an object");
33
+ return errors;
34
+ }
35
+ const cfg = config;
36
+ // Validate format
37
+ if (cfg.format !== undefined) {
38
+ const validFormats = ["json", "png", "html", "both"];
39
+ if (!validFormats.includes(cfg.format)) {
40
+ errors.push(`Invalid format: ${cfg.format}. Must be one of: ${validFormats.join(", ")}`);
41
+ }
42
+ }
43
+ // Validate ideProtocol
44
+ if (cfg.ideProtocol !== undefined) {
45
+ const validProtocols = ["vscode", "webstorm", "idea"];
46
+ if (!validProtocols.includes(cfg.ideProtocol)) {
47
+ errors.push(`Invalid ideProtocol: ${cfg.ideProtocol}. Must be one of: ${validProtocols.join(", ")}`);
48
+ }
49
+ }
50
+ // Validate boolean fields
51
+ const booleanFields = [
52
+ "darkTheme",
53
+ "verbose",
54
+ "quiet",
55
+ "checkCircular",
56
+ "checkUnused",
57
+ "checkDepth",
58
+ "checkScope",
59
+ ];
60
+ for (const field of booleanFields) {
61
+ if (cfg[field] !== undefined && typeof cfg[field] !== "boolean") {
62
+ errors.push(`${field} must be a boolean`);
63
+ }
64
+ }
65
+ // Validate number fields
66
+ if (cfg.deepModuleThreshold !== undefined &&
67
+ (typeof cfg.deepModuleThreshold !== "number" || cfg.deepModuleThreshold < 1)) {
68
+ errors.push("deepModuleThreshold must be a positive number");
69
+ }
70
+ // Validate string fields
71
+ const stringFields = ["entryFile", "tsConfig", "output"];
72
+ for (const field of stringFields) {
73
+ if (cfg[field] !== undefined && typeof cfg[field] !== "string") {
74
+ errors.push(`${field} must be a string`);
75
+ }
76
+ }
77
+ return errors;
78
+ }
79
+ /**
80
+ * Merges multiple configuration objects with priority (later configs override earlier ones)
81
+ * @param configs - Configuration objects to merge
82
+ * @returns Merged configuration
83
+ */
84
+ function mergeConfigs(...configs) {
85
+ const merged = {};
86
+ for (const config of configs) {
87
+ for (const key in config) {
88
+ const value = config[key];
89
+ if (value !== undefined) {
90
+ // biome-ignore lint/suspicious/noExplicitAny: Dynamic config merging
91
+ merged[key] = value;
92
+ }
93
+ }
94
+ }
95
+ return merged;
96
+ }
97
+ //# sourceMappingURL=config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../../src/config/config-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * Nexus IoC Graph Analyzer - Static analysis tool for dependency injection graphs
4
+ *
5
+ * This package provides tools to analyze and visualize Nexus IoC dependency injection graphs
6
+ * without executing code. It uses TypeScript's AST to extract metadata about modules, providers,
7
+ * and their dependencies.
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { GraphAnalyzer, ParseEntryFile, ParseTsConfig } from 'graph-analyzer';
12
+ *
13
+ * // Parse entry file
14
+ * const tsConfig = new ParseTsConfig(configContent, basePath);
15
+ * const entryFile = new ParseEntryFile(sourceFile, 'src/main.ts', tsConfig);
16
+ * entryFile.parse();
17
+ *
18
+ * // Build graph and analyze
19
+ * const graph = new Map();
20
+ * graph.set('entry', entryFile);
21
+ *
22
+ * const analyzer = new GraphAnalyzer(graph, 'src/main.ts', {
23
+ * outputFormat: 'json'
24
+ * });
25
+ *
26
+ * const output = analyzer.parse();
27
+ * ```
28
+ */
29
+ export type { GraphMetadata, GraphOutput, ModuleInfo, ProviderInfo, } from "./interfaces/graph-output.interface";
30
+ export type { ProvidersInterface } from "./interfaces/providers.interface";
31
+ export type { Dependency } from "./parser/dependency-extractor";
32
+ export { DependencyExtractor } from "./parser/dependency-extractor";
33
+ export { ParseEntryFile } from "./parser/parse-entry-file";
34
+ export { ParseNsModule } from "./parser/parse-ns-module";
35
+ export { ParseTsConfig } from "./parser/parse-ts-config";
36
+ export { GraphGenerator } from "./visualize/generator";
37
+ export type { GraphAnalyzerOptions } from "./visualize/graph-analyzer";
38
+ export { GraphAnalyzer } from "./visualize/graph-analyzer";
39
+ export type { HtmlGeneratorOptions } from "./visualize/html-generator";
40
+ export { HtmlGenerator } from "./visualize/html-generator";
41
+ export { JsonFormatter } from "./visualize/json-formatter";
package/dist/index.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ /**
3
+ * @packageDocumentation
4
+ * Nexus IoC Graph Analyzer - Static analysis tool for dependency injection graphs
5
+ *
6
+ * This package provides tools to analyze and visualize Nexus IoC dependency injection graphs
7
+ * without executing code. It uses TypeScript's AST to extract metadata about modules, providers,
8
+ * and their dependencies.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { GraphAnalyzer, ParseEntryFile, ParseTsConfig } from 'graph-analyzer';
13
+ *
14
+ * // Parse entry file
15
+ * const tsConfig = new ParseTsConfig(configContent, basePath);
16
+ * const entryFile = new ParseEntryFile(sourceFile, 'src/main.ts', tsConfig);
17
+ * entryFile.parse();
18
+ *
19
+ * // Build graph and analyze
20
+ * const graph = new Map();
21
+ * graph.set('entry', entryFile);
22
+ *
23
+ * const analyzer = new GraphAnalyzer(graph, 'src/main.ts', {
24
+ * outputFormat: 'json'
25
+ * });
26
+ *
27
+ * const output = analyzer.parse();
28
+ * ```
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.JsonFormatter = exports.HtmlGenerator = exports.GraphAnalyzer = exports.GraphGenerator = exports.ParseTsConfig = exports.ParseNsModule = exports.ParseEntryFile = exports.DependencyExtractor = void 0;
32
+ var dependency_extractor_1 = require("./parser/dependency-extractor");
33
+ Object.defineProperty(exports, "DependencyExtractor", { enumerable: true, get: function () { return dependency_extractor_1.DependencyExtractor; } });
34
+ // Parser exports
35
+ var parse_entry_file_1 = require("./parser/parse-entry-file");
36
+ Object.defineProperty(exports, "ParseEntryFile", { enumerable: true, get: function () { return parse_entry_file_1.ParseEntryFile; } });
37
+ var parse_ns_module_1 = require("./parser/parse-ns-module");
38
+ Object.defineProperty(exports, "ParseNsModule", { enumerable: true, get: function () { return parse_ns_module_1.ParseNsModule; } });
39
+ var parse_ts_config_1 = require("./parser/parse-ts-config");
40
+ Object.defineProperty(exports, "ParseTsConfig", { enumerable: true, get: function () { return parse_ts_config_1.ParseTsConfig; } });
41
+ var generator_1 = require("./visualize/generator");
42
+ Object.defineProperty(exports, "GraphGenerator", { enumerable: true, get: function () { return generator_1.GraphGenerator; } });
43
+ // Main exports for programmatic use
44
+ var graph_analyzer_1 = require("./visualize/graph-analyzer");
45
+ Object.defineProperty(exports, "GraphAnalyzer", { enumerable: true, get: function () { return graph_analyzer_1.GraphAnalyzer; } });
46
+ var html_generator_1 = require("./visualize/html-generator");
47
+ Object.defineProperty(exports, "HtmlGenerator", { enumerable: true, get: function () { return html_generator_1.HtmlGenerator; } });
48
+ var json_formatter_1 = require("./visualize/json-formatter");
49
+ Object.defineProperty(exports, "JsonFormatter", { enumerable: true, get: function () { return json_formatter_1.JsonFormatter; } });
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;;;AAWH,sEAAoE;AAA3D,2HAAA,mBAAmB,OAAA;AAC5B,iBAAiB;AACjB,8DAA2D;AAAlD,kHAAA,cAAc,OAAA;AACvB,4DAAyD;AAAhD,gHAAA,aAAa,OAAA;AACtB,4DAAyD;AAAhD,gHAAA,aAAa,OAAA;AACtB,mDAAuD;AAA9C,2GAAA,cAAc,OAAA;AAEvB,oCAAoC;AACpC,6DAA2D;AAAlD,+GAAA,aAAa,OAAA;AAEtB,6DAA2D;AAAlD,+GAAA,aAAa,OAAA;AACtB,6DAA2D;AAAlD,+GAAA,aAAa,OAAA"}
@@ -0,0 +1,126 @@
1
+ import type { CircularDependency } from "../analyzer/circular-dependency-detector";
2
+ import type { DepthLevel, ModuleDepthInfo } from "../analyzer/module-depth-analyzer";
3
+ import type { ProviderScopeInfo, ScopeMismatch } from "../analyzer/provider-scope-analyzer";
4
+ import type { UnusedProvider } from "../analyzer/unused-provider-detector";
5
+ import type { Dependency } from "../parser/dependency-extractor";
6
+ /**
7
+ * Complete dependency graph output format
8
+ *
9
+ * This is the main output structure returned by the graph analyzer.
10
+ * It contains all information about modules, providers, and their dependencies.
11
+ */
12
+ export interface GraphOutput {
13
+ /** Array of all modules in the dependency graph */
14
+ modules: ModuleInfo[];
15
+ /** Array of all providers across all modules */
16
+ providers: ProviderInfo[];
17
+ /** Metadata about the analysis run */
18
+ metadata: GraphMetadata;
19
+ /** Analysis results (optional, only included when analysis is enabled) */
20
+ analysis?: GraphAnalysis;
21
+ }
22
+ /**
23
+ * Analysis results for the dependency graph
24
+ *
25
+ * Contains results from various analysis features like circular dependency detection,
26
+ * unused provider detection, module depth analysis, and provider scope analysis.
27
+ */
28
+ export interface GraphAnalysis {
29
+ /** Circular dependency analysis results */
30
+ circularDependencies?: CircularDependency[];
31
+ /** Unused provider analysis results */
32
+ unusedProviders?: UnusedProvider[];
33
+ /** Module depth analysis results */
34
+ depthAnalysis?: {
35
+ /** Maximum depth in the module hierarchy */
36
+ maxDepth: number;
37
+ /** Average depth across all modules */
38
+ averageDepth: number;
39
+ /** Total number of modules analyzed */
40
+ totalModules: number;
41
+ /** Modules at each depth level */
42
+ depthLevels: DepthLevel[];
43
+ /** Detailed information for each module */
44
+ moduleDetails: ModuleDepthInfo[];
45
+ /** Modules with excessive depth (potential code smell) */
46
+ deepModules: ModuleDepthInfo[];
47
+ /** Threshold used for identifying deep modules */
48
+ deepModuleThreshold: number;
49
+ };
50
+ /** Provider scope analysis results */
51
+ scopeAnalysis?: {
52
+ /** Total number of providers analyzed */
53
+ totalProviders: number;
54
+ /** Number of singleton providers */
55
+ singletonProviders: number;
56
+ /** Number of request-scoped providers */
57
+ requestProviders: number;
58
+ /** Scope mismatches detected */
59
+ scopeMismatches: ScopeMismatch[];
60
+ /** All provider scope information */
61
+ providerScopes: ProviderScopeInfo[];
62
+ };
63
+ }
64
+ /**
65
+ * Metadata about the dependency graph analysis
66
+ *
67
+ * Contains information about when and how the analysis was performed,
68
+ * along with summary statistics.
69
+ */
70
+ export interface GraphMetadata {
71
+ /** Path to the application entry point file */
72
+ entryPoint: string;
73
+ /** Name of the root module */
74
+ rootModule: string;
75
+ /** ISO timestamp of when the analysis was performed */
76
+ analyzedAt: string;
77
+ /** Version of the graph analyzer */
78
+ version: string;
79
+ /** Total number of modules in the graph */
80
+ totalModules: number;
81
+ /** Total number of providers across all modules */
82
+ totalProviders: number;
83
+ }
84
+ /**
85
+ * Information about a single module in the dependency graph
86
+ *
87
+ * Represents a Nexus IoC module decorated with @NsModule.
88
+ */
89
+ export interface ModuleInfo {
90
+ /** Module name (class name) */
91
+ name: string;
92
+ /** File path where the module is defined */
93
+ path: string;
94
+ /** Names of modules imported by this module */
95
+ imports: string[];
96
+ /** Tokens of providers exported by this module */
97
+ exports: string[];
98
+ /** Tokens of providers registered in this module */
99
+ providers: string[];
100
+ /** Whether this module is marked as global */
101
+ isGlobal: boolean;
102
+ }
103
+ /**
104
+ * Information about a single provider in the dependency graph
105
+ *
106
+ * Represents a provider registered in a Nexus IoC module.
107
+ * Can be a class, value, factory, or class-based provider.
108
+ */
109
+ export interface ProviderInfo {
110
+ /** Provider token (identifier used for injection) */
111
+ token: string;
112
+ /** Type of provider */
113
+ type: "Class" | "UseValue" | "UseFactory" | "UseClass";
114
+ /** Name of the module that registers this provider */
115
+ module: string;
116
+ /** Lifecycle scope of the provider (only for class providers) */
117
+ scope?: "Singleton" | "Request" | "Transient";
118
+ /** Dependencies required by this provider */
119
+ dependencies: Dependency[];
120
+ /** Static value (only for UseValue providers) */
121
+ value?: string;
122
+ /** Factory function name (only for UseFactory providers) */
123
+ factory?: string;
124
+ /** Implementation class name (only for UseClass providers) */
125
+ useClass?: string;
126
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=graph-output.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-output.interface.js","sourceRoot":"","sources":["../../src/interfaces/graph-output.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ import type { Dependency } from "../parser/dependency-extractor";
2
+ export interface ProvidersInterface {
3
+ parse(): this;
4
+ token: string | null;
5
+ value?: string | null;
6
+ scope?: string | null;
7
+ inject?: string[];
8
+ type: string;
9
+ dependencies?: Dependency[];
10
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=providers.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.interface.js","sourceRoot":"","sources":["../../src/interfaces/providers.interface.ts"],"names":[],"mappings":""}