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.
- package/README.md +167 -0
- package/dist/analysis/reporter.d.ts +22 -0
- package/dist/analysis/reporter.js +116 -0
- package/dist/analysis/reporter.js.map +1 -0
- package/dist/api/analyze.d.ts +75 -0
- package/dist/api/analyze.js +121 -0
- package/dist/api/analyze.js.map +1 -0
- package/dist/api/export.d.ts +50 -0
- package/dist/api/export.js +53 -0
- package/dist/api/export.js.map +1 -0
- package/dist/api/serialization.d.ts +28 -0
- package/dist/api/serialization.js +71 -0
- package/dist/api/serialization.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +134 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/loadConfig.d.ts +10 -0
- package/dist/config/loadConfig.js +56 -0
- package/dist/config/loadConfig.js.map +1 -0
- package/dist/config/schema.d.ts +35 -0
- package/dist/config/schema.js +58 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/graph/cycleDetector.d.ts +2 -0
- package/dist/graph/cycleDetector.js +56 -0
- package/dist/graph/cycleDetector.js.map +1 -0
- package/dist/graph/dependencyGraph.d.ts +10 -0
- package/dist/graph/dependencyGraph.js +41 -0
- package/dist/graph/dependencyGraph.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/abstractness.d.ts +2 -0
- package/dist/metrics/abstractness.js +10 -0
- package/dist/metrics/abstractness.js.map +1 -0
- package/dist/metrics/distance.d.ts +1 -0
- package/dist/metrics/distance.js +7 -0
- package/dist/metrics/distance.js.map +1 -0
- package/dist/metrics/index.d.ts +4 -0
- package/dist/metrics/index.js +30 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instability.d.ts +1 -0
- package/dist/metrics/instability.js +8 -0
- package/dist/metrics/instability.js.map +1 -0
- package/dist/parser/fileScanner.d.ts +8 -0
- package/dist/parser/fileScanner.js +22 -0
- package/dist/parser/fileScanner.js.map +1 -0
- package/dist/parser/tsParser.d.ts +18 -0
- package/dist/parser/tsParser.js +158 -0
- package/dist/parser/tsParser.js.map +1 -0
- package/dist/types/api.d.ts +74 -0
- package/dist/types/api.js +3 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/graph.d.ts +14 -0
- package/dist/types/graph.js +3 -0
- package/dist/types/graph.js.map +1 -0
- package/dist/types/parser.d.ts +26 -0
- package/dist/types/parser.js +3 -0
- package/dist/types/parser.js.map +1 -0
- package/dist/utils/deepMerge.d.ts +1 -0
- package/dist/utils/deepMerge.js +23 -0
- package/dist/utils/deepMerge.js.map +1 -0
- package/dist/utils/log.d.ts +2 -0
- package/dist/utils/log.js +9 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/pathUtils.d.ts +12 -0
- package/dist/utils/pathUtils.js +27 -0
- package/dist/utils/pathUtils.js.map +1 -0
- 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
|
+
[](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":";;AAqBA,wCAmCC;AA2ED,kDAQC;AAED,4CAmBC;AA3ID,SAAgB,cAAc,CAC5B,OAAuB,EACvB,OAAwB,EACxB,MAAkB,EAClB,MAAqB;IAErB,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAE1E,MAAM,mBAAmB,GAAG,OAAO,CAAC,MAAM,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CACvD,CAAC;IAEF,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC;IACrE,MAAM,qBAAqB,GACzB,mBAAmB,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC;IAE9D,OAAO;QACL,OAAO,EAAE;YACP,YAAY,EAAE,OAAO,CAAC,MAAM;YAC5B,YAAY;YACZ,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,cAAc,EAAE,MAAM,CAAC,MAAM;SAC9B;QACD,OAAO;QACP,UAAU,EAAE;YACV,MAAM;YACN,iBAAiB,EAAE,mBAAmB;SACvC;QACD,OAAO,EAAE,CAAC,iBAAiB,IAAI,CAAC,qBAAqB;KACtD,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,YAAoB,EAAE,WAAmB;IAC7D,IAAI,YAAY,GAAG,GAAG,IAAI,WAAW,GAAG,GAAG;QAAE,OAAO,iBAAiB,CAAC;IACtE,IAAI,YAAY,GAAG,GAAG,IAAI,WAAW,GAAG,GAAG;QAAE,OAAO,wBAAwB,CAAC;IAC7E,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,cAAc,CAAC,OAAkC;IACxD,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,aAAa,CAAC,MAAkB;IACvC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEhC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,OAAO,SAAS,EAAE,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAwB;IACjD,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAC5D,MAAM,gBAAgB,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAE9E,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CACT,OAAO,QAAQ,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CACpH,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,UAA2B,EAAE,SAAiB;IAChF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEpC,OAAO,CAAC,GAAG,CACT,SAAS,UAAU,CAAC,MAAM,yCAAyC,SAAS,IAAI,CACjF,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,OAAO,QAAQ,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,SAAgB,mBAAmB,CAAC,MAAsB,EAAE,MAAqB;IAC/E,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC/B,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACxC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClC,0BAA0B,CACxB,MAAM,CAAC,UAAU,CAAC,iBAAiB,EACnC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CACnC,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,MAAsB;IACrD,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE;YACV,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;YAChC,iBAAiB,EAAE,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACjE,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,YAAY,EAAE,CAAC,CAAC,YAAY;gBAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;aAC3B,CAAC,CAAC;SACJ;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -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;
|