tdepend 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 (68) hide show
  1. package/README.md +167 -0
  2. package/dist/analysis/reporter.d.ts +22 -0
  3. package/dist/analysis/reporter.js +116 -0
  4. package/dist/analysis/reporter.js.map +1 -0
  5. package/dist/api/analyze.d.ts +75 -0
  6. package/dist/api/analyze.js +121 -0
  7. package/dist/api/analyze.js.map +1 -0
  8. package/dist/api/export.d.ts +50 -0
  9. package/dist/api/export.js +53 -0
  10. package/dist/api/export.js.map +1 -0
  11. package/dist/api/serialization.d.ts +28 -0
  12. package/dist/api/serialization.js +71 -0
  13. package/dist/api/serialization.js.map +1 -0
  14. package/dist/cli/index.d.ts +2 -0
  15. package/dist/cli/index.js +134 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/config/loadConfig.d.ts +10 -0
  18. package/dist/config/loadConfig.js +56 -0
  19. package/dist/config/loadConfig.js.map +1 -0
  20. package/dist/config/schema.d.ts +35 -0
  21. package/dist/config/schema.js +58 -0
  22. package/dist/config/schema.js.map +1 -0
  23. package/dist/graph/cycleDetector.d.ts +2 -0
  24. package/dist/graph/cycleDetector.js +56 -0
  25. package/dist/graph/cycleDetector.js.map +1 -0
  26. package/dist/graph/dependencyGraph.d.ts +10 -0
  27. package/dist/graph/dependencyGraph.js +41 -0
  28. package/dist/graph/dependencyGraph.js.map +1 -0
  29. package/dist/index.d.ts +26 -0
  30. package/dist/index.js +41 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/metrics/abstractness.d.ts +2 -0
  33. package/dist/metrics/abstractness.js +10 -0
  34. package/dist/metrics/abstractness.js.map +1 -0
  35. package/dist/metrics/distance.d.ts +1 -0
  36. package/dist/metrics/distance.js +7 -0
  37. package/dist/metrics/distance.js.map +1 -0
  38. package/dist/metrics/index.d.ts +4 -0
  39. package/dist/metrics/index.js +30 -0
  40. package/dist/metrics/index.js.map +1 -0
  41. package/dist/metrics/instability.d.ts +1 -0
  42. package/dist/metrics/instability.js +8 -0
  43. package/dist/metrics/instability.js.map +1 -0
  44. package/dist/parser/fileScanner.d.ts +8 -0
  45. package/dist/parser/fileScanner.js +22 -0
  46. package/dist/parser/fileScanner.js.map +1 -0
  47. package/dist/parser/tsParser.d.ts +18 -0
  48. package/dist/parser/tsParser.js +158 -0
  49. package/dist/parser/tsParser.js.map +1 -0
  50. package/dist/types/api.d.ts +74 -0
  51. package/dist/types/api.js +3 -0
  52. package/dist/types/api.js.map +1 -0
  53. package/dist/types/graph.d.ts +14 -0
  54. package/dist/types/graph.js +3 -0
  55. package/dist/types/graph.js.map +1 -0
  56. package/dist/types/parser.d.ts +26 -0
  57. package/dist/types/parser.js +3 -0
  58. package/dist/types/parser.js.map +1 -0
  59. package/dist/utils/deepMerge.d.ts +1 -0
  60. package/dist/utils/deepMerge.js +23 -0
  61. package/dist/utils/deepMerge.js.map +1 -0
  62. package/dist/utils/log.d.ts +2 -0
  63. package/dist/utils/log.js +9 -0
  64. package/dist/utils/log.js.map +1 -0
  65. package/dist/utils/pathUtils.d.ts +12 -0
  66. package/dist/utils/pathUtils.js +27 -0
  67. package/dist/utils/pathUtils.js.map +1 -0
  68. package/package.json +77 -0
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # TDepend
2
+
3
+ TDepend is a JDepend-inspired dependency analysis tool for the TypeScript ecosystem.
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ ## Features
8
+
9
+ - 📊 Compute architectural metrics (Ca, Ce, Abstractness, Instability, Distance)
10
+ - 🔄 Detect circular dependencies
11
+ - 📏 Threshold-based quality gates for CI/CD
12
+ - 🎯 Scoped analysis (module/namespace/class)
13
+ - ⚙️ Fully config-driven with sensible defaults
14
+ - 🚀 CI mode with JSON output
15
+ - 📦 Zero runtime dependencies for analysis
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install -g tdepend
21
+ # or
22
+ pnpm add -g tdepend
23
+ # or
24
+ yarn global add tdepend
25
+ ```
26
+
27
+ ## Quick Start
28
+
29
+ ### CLI Usage
30
+
31
+ ```bash
32
+ # Analyze your TypeScript project
33
+ tdepend analyze
34
+
35
+ # Use custom config file
36
+ tdepend analyze --config my-config.json
37
+
38
+ # CI mode with JSON output
39
+ tdepend analyze --ci
40
+
41
+ # Export full analysis to JSON file
42
+ tdepend analyze --export analysis-result.json
43
+ ```
44
+
45
+ ### Library Usage
46
+
47
+ TDepend can also be used programmatically as a library:
48
+
49
+ ```typescript
50
+ import { analyze, exportToFile } from 'tdepend';
51
+
52
+ // Analyze a project
53
+ const result = await analyze({
54
+ rootDir: 'src',
55
+ include: ['src/**/*.ts'],
56
+ failOnCycle: true
57
+ });
58
+
59
+ console.log(`Analyzed ${result.modules.length} modules`);
60
+ console.log(`Found ${result.cycles.length} cycles`);
61
+
62
+ // Export results to JSON
63
+ await exportToFile(result, 'architecture-snapshot.json');
64
+
65
+ // Access detailed metrics
66
+ for (const metric of result.metrics) {
67
+ if (metric.distance > 0.8) {
68
+ console.log(`${metric.filePath}: D=${metric.distance.toFixed(2)}`);
69
+ }
70
+ }
71
+ ```
72
+
73
+ #### API Reference
74
+
75
+ **Main Functions:**
76
+ - `analyze(options?)` - Analyze a TypeScript project
77
+ - `analyzeWithConfig(config)` - Analyze using a full config object
78
+ - `exportToFile(result, filePath, options?)` - Export analysis to JSON file
79
+ - `exportToJson(result, options?)` - Convert analysis to JSON string
80
+
81
+ **Core Building Blocks:**
82
+ - `DependencyGraph` - Graph data structure
83
+ - `detectCycles(graph)` - Cycle detection
84
+ - `computeAllMetrics(graph, modules, cycles)` - Metric computation
85
+ - `parseProject(files)` - Parse TypeScript files
86
+ - `scanFiles(config)` - Scan files matching patterns
87
+
88
+ See the [examples](./examples) directory for more usage patterns.
89
+
90
+ ## Configuration
91
+
92
+ TDepend looks for `tdepend.config.json` in the current directory.
93
+
94
+ ### Config File Example
95
+
96
+ ```json
97
+ {
98
+ "rootDir": "src",
99
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
100
+ "exclude": ["**/*.test.ts", "**/*.spec.ts", "dist"],
101
+ "metrics": {
102
+ "enabled": ["coupling", "abstractness", "distance", "cycles"],
103
+ "thresholds": {
104
+ "distance": 0.6
105
+ }
106
+ },
107
+ "analysis": {
108
+ "target": null,
109
+ "value": null
110
+ },
111
+ "ci": {
112
+ "failOnThreshold": true,
113
+ "outputFormat": "json"
114
+ }
115
+ }
116
+ ```
117
+
118
+ ### Configuration Options
119
+
120
+ - **rootDir**: Root directory for analysis (default: `"src"`)
121
+ - **include**: Glob patterns for files to include (default: `["src/**/*.ts", "src/**/*.tsx"]`)
122
+ - **exclude**: Glob patterns for files to exclude (default: `["**/*.test.ts", "**/*.spec.ts", "dist"]`)
123
+ - **metrics.enabled**: Array of metrics to compute (options: `"coupling"`, `"abstractness"`, `"distance"`, `"cycles"`)
124
+ - **metrics.thresholds.distance**: Maximum allowed distance from main sequence (default: `0.6`)
125
+ - **analysis.target**: Scope analysis to `"module"`, `"class"`, or `"namespace"` (default: `null`)
126
+ - **analysis.value**: Value for the target scope (default: `null`)
127
+ - **ci.failOnThreshold**: Exit with code 1 on threshold violations (default: `true`)
128
+ - **ci.failOnCycle**: Exit with code 1 when cycles are detected (default: `false`)
129
+ - **ci.outputFormat**: Output format - `"console"` or `"json"` (default: `"console"`)
130
+
131
+ ## Development
132
+
133
+ ```bash
134
+ # Install dependencies
135
+ pnpm install
136
+
137
+ # Build
138
+ pnpm run build
139
+
140
+ # Run tests
141
+ pnpm test
142
+
143
+ # Format code
144
+ pnpm format
145
+ ```
146
+
147
+ ## Project Structure
148
+ ```
149
+ src/
150
+ api/ # Public library API
151
+ cli/ # CLI entry point
152
+ config/ # Configuration loading and validation
153
+ parser/ # TypeScript file parsing
154
+ graph/ # Dependency graph and cycle detection
155
+ metrics/ # Metric computation
156
+ analysis/ # Reporting
157
+ utils/ # Utilities
158
+ tests/ # Test files
159
+ types/ # Type definitions
160
+ index.ts # Library entry point
161
+
162
+ dist/ # Compiled output
163
+ examples/ # Usage examples
164
+ ```
165
+
166
+ ## License
167
+ MIT
@@ -0,0 +1,22 @@
1
+ import type { ParsedModule } from '../types/parser';
2
+ import type { ModuleMetrics } from '../types/graph';
3
+ import type { TDependConfig } from '../config/schema';
4
+ export interface AnalysisReport {
5
+ summary: {
6
+ totalModules: number;
7
+ totalImports: number;
8
+ totalExports: number;
9
+ totalClasses: number;
10
+ totalInterfaces: number;
11
+ cyclesDetected: number;
12
+ };
13
+ metrics: ModuleMetrics[];
14
+ violations: {
15
+ cycles: string[][];
16
+ thresholdExceeded: ModuleMetrics[];
17
+ };
18
+ success: boolean;
19
+ }
20
+ export declare function generateReport(modules: ParsedModule[], metrics: ModuleMetrics[], cycles: string[][], config: TDependConfig): AnalysisReport;
21
+ export declare function formatConsoleOutput(report: AnalysisReport, config: TDependConfig): void;
22
+ export declare function formatJsonOutput(report: AnalysisReport): string;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateReport = generateReport;
4
+ exports.formatConsoleOutput = formatConsoleOutput;
5
+ exports.formatJsonOutput = formatJsonOutput;
6
+ function generateReport(modules, metrics, cycles, config) {
7
+ const totalImports = modules.reduce((sum, m) => sum + m.imports.length, 0);
8
+ const totalExports = modules.reduce((sum, m) => sum + m.exports.length, 0);
9
+ const totalClasses = modules.reduce((sum, m) => sum + m.classes.length, 0);
10
+ const totalInterfaces = modules.reduce((sum, m) => sum + m.interfaces, 0);
11
+ const thresholdViolations = metrics.filter((m) => m.distance > config.metrics.thresholds.distance);
12
+ const hasCycleViolation = cycles.length > 0 && config.ci.failOnCycle;
13
+ const hasThresholdViolation = thresholdViolations.length > 0 && config.ci.failOnThreshold;
14
+ return {
15
+ summary: {
16
+ totalModules: modules.length,
17
+ totalImports,
18
+ totalExports,
19
+ totalClasses,
20
+ totalInterfaces,
21
+ cyclesDetected: cycles.length,
22
+ },
23
+ metrics,
24
+ violations: {
25
+ cycles,
26
+ thresholdExceeded: thresholdViolations,
27
+ },
28
+ success: !hasCycleViolation && !hasThresholdViolation,
29
+ };
30
+ }
31
+ function getZoneLabel(abstractness, instability) {
32
+ if (abstractness < 0.5 && instability < 0.5)
33
+ return ' (Zone of Pain)';
34
+ if (abstractness > 0.5 && instability > 0.5)
35
+ return ' (Zone of Uselessness)';
36
+ return '';
37
+ }
38
+ function displaySummary(summary) {
39
+ console.log('\n📊 Summary:');
40
+ console.log(` Total imports: ${summary.totalImports}`);
41
+ console.log(` Total exports: ${summary.totalExports}`);
42
+ console.log(` Total classes: ${summary.totalClasses}`);
43
+ console.log(` Total interfaces: ${summary.totalInterfaces}`);
44
+ console.log(` Cycles detected: ${summary.cyclesDetected}`);
45
+ }
46
+ function displayCycles(cycles) {
47
+ if (cycles.length === 0)
48
+ return;
49
+ console.log('\n⚠️ Cycles:');
50
+ for (const cycle of cycles) {
51
+ const fileNames = cycle.map((p) => p.split('/').pop()).join(' → ');
52
+ console.log(` - ${fileNames}`);
53
+ }
54
+ }
55
+ function displayTopMetrics(metrics) {
56
+ const sortedByCa = [...metrics].sort((a, b) => b.Ca - a.Ca);
57
+ const sortedByCe = [...metrics].sort((a, b) => b.Ce - a.Ce);
58
+ const sortedByDistance = [...metrics].sort((a, b) => b.distance - a.distance);
59
+ if (sortedByCa.length > 0) {
60
+ console.log('\n📥 Top modules by Ca (Afferent Coupling):');
61
+ for (const m of sortedByCa.slice(0, 3)) {
62
+ const fileName = m.filePath.split('/').pop();
63
+ console.log(` - ${fileName}: Ca=${m.Ca}, Ce=${m.Ce}`);
64
+ }
65
+ }
66
+ if (sortedByCe.length > 0) {
67
+ console.log('\n📤 Top modules by Ce (Efferent Coupling):');
68
+ for (const m of sortedByCe.slice(0, 3)) {
69
+ const fileName = m.filePath.split('/').pop();
70
+ console.log(` - ${fileName}: Ca=${m.Ca}, Ce=${m.Ce}`);
71
+ }
72
+ }
73
+ if (sortedByDistance.length > 0) {
74
+ console.log('\n📏 Modules by Distance from Main Sequence:');
75
+ for (const m of sortedByDistance.slice(0, 5)) {
76
+ const fileName = m.filePath.split('/').pop();
77
+ const zone = getZoneLabel(m.abstractness, m.instability);
78
+ console.log(` - ${fileName}: D=${m.distance.toFixed(2)}, A=${m.abstractness.toFixed(2)}, I=${m.instability.toFixed(2)}${zone}`);
79
+ }
80
+ }
81
+ }
82
+ function displayThresholdViolations(violations, threshold) {
83
+ if (violations.length === 0)
84
+ return;
85
+ console.log(`\n⚠️ ${violations.length} module(s) exceed distance threshold (${threshold}):`);
86
+ for (const m of violations.slice(0, 5)) {
87
+ const fileName = m.filePath.split('/').pop();
88
+ console.log(` - ${fileName}: D=${m.distance.toFixed(2)}`);
89
+ }
90
+ if (violations.length > 5) {
91
+ console.log(` ... and ${violations.length - 5} more`);
92
+ }
93
+ }
94
+ function formatConsoleOutput(report, config) {
95
+ displaySummary(report.summary);
96
+ displayCycles(report.violations.cycles);
97
+ displayTopMetrics(report.metrics);
98
+ displayThresholdViolations(report.violations.thresholdExceeded, config.metrics.thresholds.distance);
99
+ }
100
+ function formatJsonOutput(report) {
101
+ return JSON.stringify({
102
+ success: report.success,
103
+ summary: report.summary,
104
+ metrics: report.metrics,
105
+ violations: {
106
+ cycles: report.violations.cycles,
107
+ thresholdExceeded: report.violations.thresholdExceeded.map((m) => ({
108
+ filePath: m.filePath,
109
+ distance: m.distance,
110
+ abstractness: m.abstractness,
111
+ instability: m.instability,
112
+ })),
113
+ },
114
+ }, null, 2);
115
+ }
116
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/analysis/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import type { TDependConfig } from '../config/schema';
2
+ import type { AnalysisResult } from '../types/api';
3
+ /**
4
+ * Options for the analyze() function.
5
+ * These options are merged with config file settings (if any).
6
+ */
7
+ export interface AnalyzeOptions {
8
+ /** Root directory to analyze (default: 'src') */
9
+ rootDir?: string;
10
+ /** Glob patterns for files to include (default: ['src/**\/*.ts', 'src/**\/*.tsx']) */
11
+ include?: string[];
12
+ /** Glob patterns for files to exclude (default: ['**\/*.test.ts', '**\/*.spec.ts', 'dist']) */
13
+ exclude?: string[];
14
+ /** Path to config file. If not provided, looks for tdepend.config.json */
15
+ config?: string;
16
+ /** Fail analysis if cycles are detected (default: false) */
17
+ failOnCycle?: boolean;
18
+ /** Fail analysis if distance threshold is exceeded (default: true) */
19
+ failOnThreshold?: boolean;
20
+ }
21
+ /**
22
+ * Analyzes a TypeScript project and returns complete dependency analysis.
23
+ *
24
+ * This is the main entry point for programmatic usage of tdepend.
25
+ * It orchestrates the entire analysis pipeline:
26
+ * 1. Load and merge configuration
27
+ * 2. Scan files matching include/exclude patterns
28
+ * 3. Parse TypeScript modules
29
+ * 4. Build dependency graph
30
+ * 5. Detect cycles
31
+ * 6. Compute metrics (coupling, abstractness, instability, distance)
32
+ * 7. Generate report with violations
33
+ *
34
+ * @param options - Analysis options (merged with config file if present)
35
+ * @returns Complete analysis result with modules, graph, metrics, and report
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import { analyze } from 'tdepend';
40
+ *
41
+ * const result = await analyze({
42
+ * rootDir: 'src',
43
+ * include: ['src/**\/*.ts'],
44
+ * failOnCycle: true
45
+ * });
46
+ *
47
+ * console.log(`Analyzed ${result.modules.length} modules`);
48
+ * console.log(`Found ${result.cycles.length} cycles`);
49
+ * ```
50
+ */
51
+ export declare function analyze(options?: AnalyzeOptions): Promise<AnalysisResult>;
52
+ /**
53
+ * Analyzes a TypeScript project using a provided configuration object.
54
+ *
55
+ * This is useful when you want full control over the configuration
56
+ * without loading from a file or merging with defaults.
57
+ *
58
+ * @param config - Complete TDependConfig object
59
+ * @returns Complete analysis result with modules, graph, metrics, and report
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * import { analyzeWithConfig, defaultConfig } from 'tdepend';
64
+ *
65
+ * const result = await analyzeWithConfig({
66
+ * ...defaultConfig,
67
+ * rootDir: 'src',
68
+ * ci: {
69
+ * ...defaultConfig.ci,
70
+ * failOnCycle: true
71
+ * }
72
+ * });
73
+ * ```
74
+ */
75
+ export declare function analyzeWithConfig(config: TDependConfig): Promise<AnalysisResult>;
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyze = analyze;
4
+ exports.analyzeWithConfig = analyzeWithConfig;
5
+ const loadConfig_1 = require("../config/loadConfig");
6
+ const fileScanner_1 = require("../parser/fileScanner");
7
+ const tsParser_1 = require("../parser/tsParser");
8
+ const dependencyGraph_1 = require("../graph/dependencyGraph");
9
+ const cycleDetector_1 = require("../graph/cycleDetector");
10
+ const metrics_1 = require("../metrics");
11
+ const reporter_1 = require("../analysis/reporter");
12
+ const deepMerge_1 = require("../utils/deepMerge");
13
+ /**
14
+ * Analyzes a TypeScript project and returns complete dependency analysis.
15
+ *
16
+ * This is the main entry point for programmatic usage of tdepend.
17
+ * It orchestrates the entire analysis pipeline:
18
+ * 1. Load and merge configuration
19
+ * 2. Scan files matching include/exclude patterns
20
+ * 3. Parse TypeScript modules
21
+ * 4. Build dependency graph
22
+ * 5. Detect cycles
23
+ * 6. Compute metrics (coupling, abstractness, instability, distance)
24
+ * 7. Generate report with violations
25
+ *
26
+ * @param options - Analysis options (merged with config file if present)
27
+ * @returns Complete analysis result with modules, graph, metrics, and report
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * import { analyze } from 'tdepend';
32
+ *
33
+ * const result = await analyze({
34
+ * rootDir: 'src',
35
+ * include: ['src/**\/*.ts'],
36
+ * failOnCycle: true
37
+ * });
38
+ *
39
+ * console.log(`Analyzed ${result.modules.length} modules`);
40
+ * console.log(`Found ${result.cycles.length} cycles`);
41
+ * ```
42
+ */
43
+ async function analyze(options = {}) {
44
+ // Load config from file (or use defaults if no file exists)
45
+ const baseConfig = options.config ? (0, loadConfig_1.loadConfig)(options.config) : (0, loadConfig_1.loadConfig)();
46
+ // Create partial config from options
47
+ const optionsConfig = {};
48
+ if (options.rootDir !== undefined) {
49
+ optionsConfig.rootDir = options.rootDir;
50
+ }
51
+ if (options.include !== undefined) {
52
+ optionsConfig.include = options.include;
53
+ }
54
+ if (options.exclude !== undefined) {
55
+ optionsConfig.exclude = options.exclude;
56
+ }
57
+ if (options.failOnCycle !== undefined || options.failOnThreshold !== undefined) {
58
+ optionsConfig.ci = {
59
+ ...baseConfig.ci,
60
+ ...(options.failOnCycle !== undefined && { failOnCycle: options.failOnCycle }),
61
+ ...(options.failOnThreshold !== undefined && { failOnThreshold: options.failOnThreshold }),
62
+ };
63
+ }
64
+ // Merge configs (options override file config)
65
+ const config = (0, deepMerge_1.deepMerge)(baseConfig, optionsConfig);
66
+ // Run analysis pipeline
67
+ const files = await (0, fileScanner_1.scanFiles)(config);
68
+ const modules = (0, tsParser_1.parseProject)(files);
69
+ const graph = new dependencyGraph_1.DependencyGraph(modules);
70
+ const cycles = (0, cycleDetector_1.detectCycles)(graph);
71
+ const metrics = (0, metrics_1.computeAllMetrics)(graph, modules, cycles);
72
+ const report = (0, reporter_1.generateReport)(modules, metrics, cycles, config);
73
+ return {
74
+ modules,
75
+ graph,
76
+ cycles,
77
+ metrics,
78
+ report,
79
+ config,
80
+ };
81
+ }
82
+ /**
83
+ * Analyzes a TypeScript project using a provided configuration object.
84
+ *
85
+ * This is useful when you want full control over the configuration
86
+ * without loading from a file or merging with defaults.
87
+ *
88
+ * @param config - Complete TDependConfig object
89
+ * @returns Complete analysis result with modules, graph, metrics, and report
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { analyzeWithConfig, defaultConfig } from 'tdepend';
94
+ *
95
+ * const result = await analyzeWithConfig({
96
+ * ...defaultConfig,
97
+ * rootDir: 'src',
98
+ * ci: {
99
+ * ...defaultConfig.ci,
100
+ * failOnCycle: true
101
+ * }
102
+ * });
103
+ * ```
104
+ */
105
+ async function analyzeWithConfig(config) {
106
+ const files = await (0, fileScanner_1.scanFiles)(config);
107
+ const modules = (0, tsParser_1.parseProject)(files);
108
+ const graph = new dependencyGraph_1.DependencyGraph(modules);
109
+ const cycles = (0, cycleDetector_1.detectCycles)(graph);
110
+ const metrics = (0, metrics_1.computeAllMetrics)(graph, modules, cycles);
111
+ const report = (0, reporter_1.generateReport)(modules, metrics, cycles, config);
112
+ return {
113
+ modules,
114
+ graph,
115
+ cycles,
116
+ metrics,
117
+ report,
118
+ config,
119
+ };
120
+ }
121
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/api/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { AnalysisResult } from '../types/api';
2
+ /**
3
+ * Options for exporting analysis results.
4
+ */
5
+ export interface ExportOptions {
6
+ /**
7
+ * Whether to pretty-print the JSON output.
8
+ * @default true
9
+ */
10
+ pretty?: boolean;
11
+ }
12
+ /**
13
+ * Exports analysis results to a JSON file.
14
+ *
15
+ * This function converts the analysis result to a serializable format
16
+ * (fixing Set serialization issues) and writes it to the specified file.
17
+ *
18
+ * @param result - The analysis result to export
19
+ * @param filePath - Path where the JSON file should be written
20
+ * @param options - Export options (pretty-printing, etc.)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { analyze, exportToFile } from 'tdepend';
25
+ *
26
+ * const result = await analyze({ rootDir: 'src' });
27
+ * await exportToFile(result, 'architecture-snapshot.json');
28
+ * ```
29
+ */
30
+ export declare function exportToFile(result: AnalysisResult, filePath: string, options?: ExportOptions): Promise<void>;
31
+ /**
32
+ * Converts analysis results to a JSON string.
33
+ *
34
+ * This function converts the analysis result to a serializable format
35
+ * and returns it as a JSON string (does not write to file).
36
+ *
37
+ * @param result - The analysis result to export
38
+ * @param options - Export options (pretty-printing, etc.)
39
+ * @returns JSON string representation of the analysis result
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * import { analyze, exportToJson } from 'tdepend';
44
+ *
45
+ * const result = await analyze({ rootDir: 'src' });
46
+ * const json = exportToJson(result, { pretty: false }); // Compact JSON
47
+ * console.log(json);
48
+ * ```
49
+ */
50
+ export declare function exportToJson(result: AnalysisResult, options?: ExportOptions): string;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.exportToFile = exportToFile;
4
+ exports.exportToJson = exportToJson;
5
+ const promises_1 = require("fs/promises");
6
+ const serialization_1 = require("./serialization");
7
+ /**
8
+ * Exports analysis results to a JSON file.
9
+ *
10
+ * This function converts the analysis result to a serializable format
11
+ * (fixing Set serialization issues) and writes it to the specified file.
12
+ *
13
+ * @param result - The analysis result to export
14
+ * @param filePath - Path where the JSON file should be written
15
+ * @param options - Export options (pretty-printing, etc.)
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { analyze, exportToFile } from 'tdepend';
20
+ *
21
+ * const result = await analyze({ rootDir: 'src' });
22
+ * await exportToFile(result, 'architecture-snapshot.json');
23
+ * ```
24
+ */
25
+ async function exportToFile(result, filePath, options = {}) {
26
+ const json = exportToJson(result, options);
27
+ await (0, promises_1.writeFile)(filePath, json, 'utf-8');
28
+ }
29
+ /**
30
+ * Converts analysis results to a JSON string.
31
+ *
32
+ * This function converts the analysis result to a serializable format
33
+ * and returns it as a JSON string (does not write to file).
34
+ *
35
+ * @param result - The analysis result to export
36
+ * @param options - Export options (pretty-printing, etc.)
37
+ * @returns JSON string representation of the analysis result
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * import { analyze, exportToJson } from 'tdepend';
42
+ *
43
+ * const result = await analyze({ rootDir: 'src' });
44
+ * const json = exportToJson(result, { pretty: false }); // Compact JSON
45
+ * console.log(json);
46
+ * ```
47
+ */
48
+ function exportToJson(result, options = {}) {
49
+ const serialized = (0, serialization_1.toSerializable)(result);
50
+ const indent = options.pretty !== false ? 2 : 0;
51
+ return JSON.stringify(serialized, null, indent);
52
+ }
53
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/api/export.ts"],"names":[],"mappings":";;AAiCA,oCAOC;AAqBD,oCAIC;AAjED,0CAAwC;AACxC,mDAAiD;AAcjD;;;;;;;;;;;;;;;;;GAiBG;AACI,KAAK,UAAU,YAAY,CAChC,MAAsB,EACtB,QAAgB,EAChB,UAAyB,EAAE;IAE3B,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,IAAA,oBAAS,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,YAAY,CAAC,MAAsB,EAAE,UAAyB,EAAE;IAC9E,MAAM,UAAU,GAAG,IAAA,8BAAc,EAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { DependencyGraph } from '../graph/dependencyGraph';
2
+ import type { AnalysisResult, SerializableAnalysisResult, SerializableDependencyGraph, SerializableCycle } from '../types/api';
3
+ /**
4
+ * Converts a DependencyGraph with Sets to a serializable format with Arrays.
5
+ * @param graph - The dependency graph to serialize
6
+ * @returns Serializable graph with array-based relationships
7
+ */
8
+ export declare function serializeGraph(graph: DependencyGraph): SerializableDependencyGraph;
9
+ /**
10
+ * Normalizes a cycle for consistent identification across runs.
11
+ * Creates a unique ID based on the cycle's contents and rotates the cycle
12
+ * to start with the lexicographically smallest file path.
13
+ *
14
+ * @param cycle - Array of file paths forming a cycle
15
+ * @returns Normalized cycle with unique ID
16
+ */
17
+ export declare function normalizeCycle(cycle: string[]): SerializableCycle;
18
+ /**
19
+ * Converts an AnalysisResult with rich objects to a fully serializable format.
20
+ * This includes:
21
+ * - Converting Sets to Arrays in the dependency graph
22
+ * - Normalizing cycles with unique IDs
23
+ * - Adding version and timestamp metadata
24
+ *
25
+ * @param result - The analysis result to serialize
26
+ * @returns Fully serializable result ready for JSON.stringify
27
+ */
28
+ export declare function toSerializable(result: AnalysisResult): SerializableAnalysisResult;