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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeAllMetrics = computeAllMetrics;
|
|
4
|
+
const abstractness_1 = require("./abstractness");
|
|
5
|
+
const distance_1 = require("./distance");
|
|
6
|
+
const instability_1 = require("./instability");
|
|
7
|
+
function computeAllMetrics(graph, modules, cycles) {
|
|
8
|
+
const moduleMap = new Map(modules.map((m) => [m.filePath, m]));
|
|
9
|
+
const metrics = [];
|
|
10
|
+
for (const node of graph.getAllNodes()) {
|
|
11
|
+
const module = moduleMap.get(node.filePath);
|
|
12
|
+
const moduleCycles = cycles.filter((cycle) => cycle.includes(node.filePath));
|
|
13
|
+
const Ca = node.dependents.size;
|
|
14
|
+
const Ce = node.dependencies.size;
|
|
15
|
+
const abstractness = module ? (0, abstractness_1.computeAbstractness)(module) : 0;
|
|
16
|
+
const instability = (0, instability_1.computeInstability)(Ca, Ce);
|
|
17
|
+
const distance = (0, distance_1.computeDistance)(abstractness, instability);
|
|
18
|
+
metrics.push({
|
|
19
|
+
filePath: node.filePath,
|
|
20
|
+
Ca,
|
|
21
|
+
Ce,
|
|
22
|
+
cycles: moduleCycles,
|
|
23
|
+
abstractness,
|
|
24
|
+
instability,
|
|
25
|
+
distance,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return metrics;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/metrics/index.ts"],"names":[],"mappings":";;AAOA,8CA8BC;AAlCD,iDAAqD;AACrD,yCAA6C;AAC7C,+CAAmD;AAEnD,SAAgB,iBAAiB,CAC/B,KAAsB,EACtB,OAAuB,EACvB,MAAkB;IAElB,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAE7E,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAChC,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;QAClC,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,IAAA,kCAAmB,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,IAAA,gCAAkB,EAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAA,0BAAe,EAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAE5D,OAAO,CAAC,IAAI,CAAC;YACX,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,EAAE;YACF,EAAE;YACF,MAAM,EAAE,YAAY;YACpB,YAAY;YACZ,WAAW;YACX,QAAQ;SACT,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function computeInstability(Ca: number, Ce: number): number;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.computeInstability = computeInstability;
|
|
4
|
+
function computeInstability(Ca, Ce) {
|
|
5
|
+
const total = Ca + Ce;
|
|
6
|
+
return total === 0 ? 0 : Ce / total;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=instability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instability.js","sourceRoot":"","sources":["../../src/metrics/instability.ts"],"names":[],"mappings":";;AAAA,gDAGC;AAHD,SAAgB,kBAAkB,CAAC,EAAU,EAAE,EAAU;IACvD,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,CAAC;IACtB,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TDependConfig } from '../config/schema';
|
|
2
|
+
/**
|
|
3
|
+
* Scan files based on include/exclude patterns from config
|
|
4
|
+
*
|
|
5
|
+
* @param config - TDepend configuration with include/exclude patterns
|
|
6
|
+
* @returns Array of normalized absolute file paths
|
|
7
|
+
*/
|
|
8
|
+
export declare function scanFiles(config: TDependConfig): Promise<string[]>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.scanFiles = scanFiles;
|
|
4
|
+
const glob_1 = require("glob");
|
|
5
|
+
const pathUtils_1 = require("../utils/pathUtils");
|
|
6
|
+
/**
|
|
7
|
+
* Scan files based on include/exclude patterns from config
|
|
8
|
+
*
|
|
9
|
+
* @param config - TDepend configuration with include/exclude patterns
|
|
10
|
+
* @returns Array of normalized absolute file paths
|
|
11
|
+
*/
|
|
12
|
+
async function scanFiles(config) {
|
|
13
|
+
const { include, exclude } = config;
|
|
14
|
+
// Scan files matching include patterns
|
|
15
|
+
const files = await (0, glob_1.glob)(include, {
|
|
16
|
+
ignore: exclude,
|
|
17
|
+
absolute: true,
|
|
18
|
+
nodir: true,
|
|
19
|
+
});
|
|
20
|
+
return files.map((file) => (0, pathUtils_1.normalizePath)(file));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=fileScanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileScanner.js","sourceRoot":"","sources":["../../src/parser/fileScanner.ts"],"names":[],"mappings":";;AAWA,8BAWC;AAtBD,+BAA4B;AAG5B,kDAAmD;AAEnD;;;;;GAKG;AACI,KAAK,UAAU,SAAS,CAAC,MAAqB;IACnD,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAEpC,uCAAuC;IACvC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC,OAAO,EAAE;QAChC,MAAM,EAAE,OAAO;QACf,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,IAAI;KACZ,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,yBAAa,EAAC,IAAI,CAAC,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Project } from 'ts-morph';
|
|
2
|
+
import type { ParsedModule } from '../types/parser';
|
|
3
|
+
/**
|
|
4
|
+
* Parse multiple TypeScript files in a project
|
|
5
|
+
*
|
|
6
|
+
* @param filePaths - Array of file paths to parse
|
|
7
|
+
* @param tsConfigPath - Optional path to tsconfig.json
|
|
8
|
+
* @returns Array of ParsedModule objects
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseProject(filePaths: string[], tsConfigPath?: string): ParsedModule[];
|
|
11
|
+
/**
|
|
12
|
+
* Parse a single TypeScript file
|
|
13
|
+
*
|
|
14
|
+
* @param filePath - Path to the file to parse
|
|
15
|
+
* @param project - Optional ts-morph Project instance
|
|
16
|
+
* @returns ParsedModule with extracted information
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseFile(filePath: string, project?: Project): ParsedModule;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseProject = parseProject;
|
|
4
|
+
exports.parseFile = parseFile;
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const ts_morph_1 = require("ts-morph");
|
|
7
|
+
const pathUtils_1 = require("../utils/pathUtils");
|
|
8
|
+
function extractImports(sourceFile, filePath) {
|
|
9
|
+
const imports = [];
|
|
10
|
+
const importDeclarations = sourceFile.getImportDeclarations();
|
|
11
|
+
for (const importDecl of importDeclarations) {
|
|
12
|
+
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
13
|
+
if ((0, pathUtils_1.isRelativeImport)(moduleSpecifier)) {
|
|
14
|
+
const resolvedPath = resolveImportPath(moduleSpecifier, filePath);
|
|
15
|
+
if (resolvedPath) {
|
|
16
|
+
imports.push(resolvedPath);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
else if (!(0, pathUtils_1.isExternalModule)(moduleSpecifier)) {
|
|
20
|
+
// Handle absolute imports (potential path aliases)
|
|
21
|
+
// For now, we'll skip these - full path alias resolution needs tsconfig
|
|
22
|
+
// This will be enhanced if needed
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return imports;
|
|
26
|
+
}
|
|
27
|
+
function extractClasses(sourceFile, filePath) {
|
|
28
|
+
const classes = [];
|
|
29
|
+
const exports = [];
|
|
30
|
+
const classDeclarations = sourceFile.getClasses();
|
|
31
|
+
for (const classDecl of classDeclarations) {
|
|
32
|
+
const name = classDecl.getName();
|
|
33
|
+
if (name) {
|
|
34
|
+
const isAbstract = classDecl.isAbstract();
|
|
35
|
+
const isExported = classDecl.isExported();
|
|
36
|
+
classes.push({
|
|
37
|
+
name,
|
|
38
|
+
isAbstract,
|
|
39
|
+
isExported,
|
|
40
|
+
filePath,
|
|
41
|
+
});
|
|
42
|
+
if (isExported) {
|
|
43
|
+
exports.push(name);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { classes, exports };
|
|
48
|
+
}
|
|
49
|
+
function extractInterfaces(sourceFile) {
|
|
50
|
+
const exports = [];
|
|
51
|
+
let interfaces = 0;
|
|
52
|
+
const interfaceDeclarations = sourceFile.getInterfaces();
|
|
53
|
+
for (const interfaceDecl of interfaceDeclarations) {
|
|
54
|
+
const name = interfaceDecl.getName();
|
|
55
|
+
if (interfaceDecl.isExported()) {
|
|
56
|
+
exports.push(name);
|
|
57
|
+
interfaces++;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
interfaces++;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return { interfaces, exports };
|
|
64
|
+
}
|
|
65
|
+
function extractNamespaces(sourceFile, filePath) {
|
|
66
|
+
const namespaces = [];
|
|
67
|
+
const exports = [];
|
|
68
|
+
const namespaceDeclarations = sourceFile.getModules();
|
|
69
|
+
for (const namespaceDecl of namespaceDeclarations) {
|
|
70
|
+
const name = namespaceDecl.getName();
|
|
71
|
+
namespaces.push({
|
|
72
|
+
name,
|
|
73
|
+
filePath,
|
|
74
|
+
});
|
|
75
|
+
if (namespaceDecl.isExported()) {
|
|
76
|
+
exports.push(name);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { namespaces, exports };
|
|
80
|
+
}
|
|
81
|
+
function extractOtherExports(sourceFile, existingExports) {
|
|
82
|
+
const otherExports = [];
|
|
83
|
+
const exportedDeclarations = sourceFile.getExportedDeclarations();
|
|
84
|
+
for (const [name, declarations] of exportedDeclarations) {
|
|
85
|
+
if (existingExports.includes(name)) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (declarations.length > 0) {
|
|
89
|
+
otherExports.push(name);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return otherExports;
|
|
93
|
+
}
|
|
94
|
+
function parseSourceFile(sourceFile) {
|
|
95
|
+
const filePath = (0, pathUtils_1.normalizePath)(sourceFile.getFilePath());
|
|
96
|
+
const imports = extractImports(sourceFile, filePath);
|
|
97
|
+
const { classes, exports: classExports } = extractClasses(sourceFile, filePath);
|
|
98
|
+
const { interfaces, exports: interfaceExports } = extractInterfaces(sourceFile);
|
|
99
|
+
const { namespaces, exports: namespaceExports } = extractNamespaces(sourceFile, filePath);
|
|
100
|
+
const allExports = [...classExports, ...interfaceExports, ...namespaceExports];
|
|
101
|
+
const otherExports = extractOtherExports(sourceFile, allExports);
|
|
102
|
+
const exports = [...allExports, ...otherExports];
|
|
103
|
+
const totalTypes = classes.length + interfaces;
|
|
104
|
+
return {
|
|
105
|
+
filePath,
|
|
106
|
+
imports,
|
|
107
|
+
exports,
|
|
108
|
+
classes,
|
|
109
|
+
namespaces,
|
|
110
|
+
interfaces,
|
|
111
|
+
totalTypes,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function resolveImportPath(importSpecifier, fromFile) {
|
|
115
|
+
const dir = (0, node_path_1.dirname)(fromFile);
|
|
116
|
+
// Resolve relative to the importing file
|
|
117
|
+
const resolvedPath = (0, node_path_1.resolve)(dir, importSpecifier);
|
|
118
|
+
// Try .ts as default extension for TypeScript projects
|
|
119
|
+
const pathWithTs = resolvedPath + '.ts';
|
|
120
|
+
return (0, pathUtils_1.normalizePath)(pathWithTs);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Parse multiple TypeScript files in a project
|
|
124
|
+
*
|
|
125
|
+
* @param filePaths - Array of file paths to parse
|
|
126
|
+
* @param tsConfigPath - Optional path to tsconfig.json
|
|
127
|
+
* @returns Array of ParsedModule objects
|
|
128
|
+
*/
|
|
129
|
+
function parseProject(filePaths, tsConfigPath) {
|
|
130
|
+
const project = new ts_morph_1.Project({
|
|
131
|
+
tsConfigFilePath: tsConfigPath,
|
|
132
|
+
skipAddingFilesFromTsConfig: true,
|
|
133
|
+
});
|
|
134
|
+
// Add all files to the project
|
|
135
|
+
for (const filePath of filePaths) {
|
|
136
|
+
project.addSourceFileAtPath(filePath);
|
|
137
|
+
}
|
|
138
|
+
const modules = [];
|
|
139
|
+
const sourceFiles = project.getSourceFiles();
|
|
140
|
+
for (const sourceFile of sourceFiles) {
|
|
141
|
+
const parsedModule = parseSourceFile(sourceFile);
|
|
142
|
+
modules.push(parsedModule);
|
|
143
|
+
}
|
|
144
|
+
return modules;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Parse a single TypeScript file
|
|
148
|
+
*
|
|
149
|
+
* @param filePath - Path to the file to parse
|
|
150
|
+
* @param project - Optional ts-morph Project instance
|
|
151
|
+
* @returns ParsedModule with extracted information
|
|
152
|
+
*/
|
|
153
|
+
function parseFile(filePath, project) {
|
|
154
|
+
const proj = project || new ts_morph_1.Project();
|
|
155
|
+
const sourceFile = proj.addSourceFileAtPath(filePath);
|
|
156
|
+
return parseSourceFile(sourceFile);
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=tsParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsParser.js","sourceRoot":"","sources":["../../src/parser/tsParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { DependencyGraph } from '../graph/dependencyGraph';
|
|
2
|
+
import type { ParsedModule } from './parser';
|
|
3
|
+
import type { ModuleMetrics } from './graph';
|
|
4
|
+
import type { AnalysisReport } from '../analysis/reporter';
|
|
5
|
+
import type { TDependConfig } from '../config/schema';
|
|
6
|
+
/**
|
|
7
|
+
* Main result returned by the analyze() function.
|
|
8
|
+
* Contains rich objects (DependencyGraph with Sets) suitable for programmatic use.
|
|
9
|
+
*/
|
|
10
|
+
export interface AnalysisResult {
|
|
11
|
+
/** Parsed modules with imports, exports, classes, etc. */
|
|
12
|
+
modules: ParsedModule[];
|
|
13
|
+
/** Dependency graph with Set-based relationships */
|
|
14
|
+
graph: DependencyGraph;
|
|
15
|
+
/** Detected dependency cycles */
|
|
16
|
+
cycles: string[][];
|
|
17
|
+
/** Computed metrics for each module */
|
|
18
|
+
metrics: ModuleMetrics[];
|
|
19
|
+
/** Generated analysis report with summary and violations */
|
|
20
|
+
report: AnalysisReport;
|
|
21
|
+
/** Configuration used for this analysis */
|
|
22
|
+
config: TDependConfig;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Serializable version of DependencyNode with Arrays instead of Sets.
|
|
26
|
+
*/
|
|
27
|
+
export interface SerializableDependencyNode {
|
|
28
|
+
/** File path of this module */
|
|
29
|
+
filePath: string;
|
|
30
|
+
/** Modules that this module depends on (outgoing dependencies) */
|
|
31
|
+
dependencies: string[];
|
|
32
|
+
/** Modules that depend on this module (incoming dependencies) */
|
|
33
|
+
dependents: string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Serializable dependency graph with array-based relationships.
|
|
37
|
+
*/
|
|
38
|
+
export interface SerializableDependencyGraph {
|
|
39
|
+
/** All nodes in the dependency graph */
|
|
40
|
+
nodes: SerializableDependencyNode[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Normalized cycle with stable identification.
|
|
44
|
+
*/
|
|
45
|
+
export interface SerializableCycle {
|
|
46
|
+
/** Unique identifier (hash of sorted file paths) */
|
|
47
|
+
id: string;
|
|
48
|
+
/** File paths forming the cycle (normalized to start with lexicographically smallest) */
|
|
49
|
+
nodes: string[];
|
|
50
|
+
/** Number of nodes in the cycle */
|
|
51
|
+
length: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Complete serializable analysis result suitable for JSON export.
|
|
55
|
+
* All Sets are converted to Arrays for proper JSON serialization.
|
|
56
|
+
*/
|
|
57
|
+
export interface SerializableAnalysisResult {
|
|
58
|
+
/** Format version for compatibility checking */
|
|
59
|
+
version: string;
|
|
60
|
+
/** ISO 8601 timestamp of when this analysis was generated */
|
|
61
|
+
timestamp: string;
|
|
62
|
+
/** Configuration used for this analysis */
|
|
63
|
+
config: TDependConfig;
|
|
64
|
+
/** Parsed modules with imports, exports, classes, etc. */
|
|
65
|
+
modules: ParsedModule[];
|
|
66
|
+
/** Serializable dependency graph */
|
|
67
|
+
graph: SerializableDependencyGraph;
|
|
68
|
+
/** Normalized cycles with unique IDs */
|
|
69
|
+
cycles: SerializableCycle[];
|
|
70
|
+
/** Computed metrics for each module */
|
|
71
|
+
metrics: ModuleMetrics[];
|
|
72
|
+
/** Generated analysis report with summary and violations */
|
|
73
|
+
report: AnalysisReport;
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/types/api.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface DependencyNode {
|
|
2
|
+
filePath: string;
|
|
3
|
+
dependencies: Set<string>;
|
|
4
|
+
dependents: Set<string>;
|
|
5
|
+
}
|
|
6
|
+
export interface ModuleMetrics {
|
|
7
|
+
filePath: string;
|
|
8
|
+
Ca: number;
|
|
9
|
+
Ce: number;
|
|
10
|
+
cycles: string[][];
|
|
11
|
+
abstractness: number;
|
|
12
|
+
instability: number;
|
|
13
|
+
distance: number;
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/types/graph.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ParsedClass {
|
|
2
|
+
name: string;
|
|
3
|
+
isAbstract: boolean;
|
|
4
|
+
isExported: boolean;
|
|
5
|
+
filePath: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ParsedNamespace {
|
|
8
|
+
name: string;
|
|
9
|
+
filePath: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ParsedModule {
|
|
12
|
+
/** Normalized absolute path to the module file */
|
|
13
|
+
filePath: string;
|
|
14
|
+
/** Resolved import paths (normalized file paths) */
|
|
15
|
+
imports: string[];
|
|
16
|
+
/** Names of exported symbols */
|
|
17
|
+
exports: string[];
|
|
18
|
+
/** Parsed classes in this module */
|
|
19
|
+
classes: ParsedClass[];
|
|
20
|
+
/** Parsed namespaces in this module */
|
|
21
|
+
namespaces: ParsedNamespace[];
|
|
22
|
+
/** Count of interfaces (for abstractness calculation) */
|
|
23
|
+
interfaces: number;
|
|
24
|
+
/** Total count of types (classes + interfaces) */
|
|
25
|
+
totalTypes: number;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/types/parser.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deepMerge<T extends Record<string, unknown>>(target: T, source: Partial<T>): T;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deepMerge = deepMerge;
|
|
4
|
+
function deepMerge(target, source) {
|
|
5
|
+
const result = { ...target };
|
|
6
|
+
for (const key in source) {
|
|
7
|
+
const sourceValue = source[key];
|
|
8
|
+
const targetValue = result[key];
|
|
9
|
+
if (sourceValue &&
|
|
10
|
+
typeof sourceValue === 'object' &&
|
|
11
|
+
!Array.isArray(sourceValue) &&
|
|
12
|
+
targetValue &&
|
|
13
|
+
typeof targetValue === 'object' &&
|
|
14
|
+
!Array.isArray(targetValue)) {
|
|
15
|
+
result[key] = deepMerge(targetValue, sourceValue);
|
|
16
|
+
}
|
|
17
|
+
else if (sourceValue !== undefined) {
|
|
18
|
+
result[key] = sourceValue;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=deepMerge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deepMerge.js","sourceRoot":"","sources":["../../src/utils/deepMerge.ts"],"names":[],"mappings":";;AAAA,8BAyBC;AAzBD,SAAgB,SAAS,CAAoC,MAAS,EAAE,MAAkB;IACxF,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAEhC,IACE,WAAW;YACX,OAAO,WAAW,KAAK,QAAQ;YAC/B,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAC3B,WAAW;YACX,OAAO,WAAW,KAAK,QAAQ;YAC/B,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAC3B,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CACrB,WAAsC,EACtC,WAAsC,CACR,CAAC;QACnC,CAAC;aAAM,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,GAAG,WAA0C,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/utils/log.ts"],"names":[],"mappings":";;AAEA,kBAIC;AAJD,SAAgB,GAAG,CAAC,MAAqB,EAAE,OAAe;IACxD,IAAI,MAAM,CAAC,EAAE,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a file path to an absolute, cross-platform path
|
|
3
|
+
*/
|
|
4
|
+
export declare function normalizePath(filePath: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Check if an import specifier is a relative import
|
|
7
|
+
*/
|
|
8
|
+
export declare function isRelativeImport(importSpecifier: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Check if an import specifier is an external module
|
|
11
|
+
*/
|
|
12
|
+
export declare function isExternalModule(importSpecifier: string): boolean;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizePath = normalizePath;
|
|
4
|
+
exports.isRelativeImport = isRelativeImport;
|
|
5
|
+
exports.isExternalModule = isExternalModule;
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
/**
|
|
8
|
+
* Normalize a file path to an absolute, cross-platform path
|
|
9
|
+
*/
|
|
10
|
+
function normalizePath(filePath) {
|
|
11
|
+
const absolutePath = (0, node_path_1.isAbsolute)(filePath) ? filePath : (0, node_path_1.resolve)(filePath);
|
|
12
|
+
return (0, node_path_1.normalize)(absolutePath);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Check if an import specifier is a relative import
|
|
16
|
+
*/
|
|
17
|
+
function isRelativeImport(importSpecifier) {
|
|
18
|
+
return importSpecifier.startsWith('./') || importSpecifier.startsWith('../');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if an import specifier is an external module
|
|
22
|
+
*/
|
|
23
|
+
function isExternalModule(importSpecifier) {
|
|
24
|
+
// External if it doesn't start with . or /
|
|
25
|
+
return !importSpecifier.startsWith('.') && !importSpecifier.startsWith('/');
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=pathUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathUtils.js","sourceRoot":"","sources":["../../src/utils/pathUtils.ts"],"names":[],"mappings":";;AAKA,sCAGC;AAKD,4CAEC;AAKD,4CAGC;AAvBD,yCAA2D;AAE3D;;GAEG;AACH,SAAgB,aAAa,CAAC,QAAgB;IAC5C,MAAM,YAAY,GAAG,IAAA,sBAAU,EAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAA,mBAAO,EAAC,QAAQ,CAAC,CAAC;IACzE,OAAO,IAAA,qBAAS,EAAC,YAAY,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,eAAuB;IACtD,OAAO,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAC/E,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,eAAuB;IACtD,2CAA2C;IAC3C,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AAC9E,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tdepend",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "JDepend-inspired dependency analysis tool for TypeScript",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"tdepend": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./cli": {
|
|
17
|
+
"import": "./dist/cli/index.js",
|
|
18
|
+
"require": "./dist/cli/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"dependency",
|
|
27
|
+
"analysis",
|
|
28
|
+
"typescript",
|
|
29
|
+
"cli",
|
|
30
|
+
"library",
|
|
31
|
+
"api",
|
|
32
|
+
"jdepend",
|
|
33
|
+
"metrics",
|
|
34
|
+
"architecture",
|
|
35
|
+
"coupling",
|
|
36
|
+
"abstractness",
|
|
37
|
+
"instability",
|
|
38
|
+
"dependency-analysis",
|
|
39
|
+
"code-quality"
|
|
40
|
+
],
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/dvmhmdsd/tdepend.git"
|
|
44
|
+
},
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/dvmhmdsd/tdepend/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://github.com/dvmhmdsd/tdepend#readme",
|
|
49
|
+
"author": "Mohamed Saad <mohamed.tarif999@gmail.com>",
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"packageManager": "pnpm@8.15.4",
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=20.0.0"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"commander": "^12.0.0",
|
|
57
|
+
"glob": "^13.0.0",
|
|
58
|
+
"ts-morph": "^27.0.2",
|
|
59
|
+
"zod": "^4.1.13"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/glob": "^9.0.0",
|
|
63
|
+
"@types/node": "^20.11.30",
|
|
64
|
+
"prettier": "^3.1.1",
|
|
65
|
+
"ts-node": "^10.9.2",
|
|
66
|
+
"typescript": "^5.6.3",
|
|
67
|
+
"vitest": "^1.6.0"
|
|
68
|
+
},
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "tsc -p tsconfig.json",
|
|
71
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
72
|
+
"dev": "ts-node src/cli/index.ts analyze --help",
|
|
73
|
+
"cli": "node dist/cli/index.js",
|
|
74
|
+
"test": "vitest run",
|
|
75
|
+
"format": "prettier --write ."
|
|
76
|
+
}
|
|
77
|
+
}
|