tdepend 0.2.0 → 0.3.1
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/LICENSE +21 -0
- package/README.md +212 -116
- package/dist/api/analyze.d.ts +8 -68
- package/dist/api/analyze.js +33 -108
- package/dist/api/analyze.js.map +1 -1
- package/dist/api/explain.d.ts +22 -0
- package/dist/api/explain.js +38 -0
- package/dist/api/explain.js.map +1 -0
- package/dist/api/export.d.ts +4 -47
- package/dist/api/export.js +6 -45
- package/dist/api/export.js.map +1 -1
- package/dist/api/serialization.d.ts +6 -26
- package/dist/api/serialization.js +68 -58
- package/dist/api/serialization.js.map +1 -1
- package/dist/cli/index.js +11 -129
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/run.d.ts +12 -0
- package/dist/cli/run.js +112 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/config/loadConfig.d.ts +10 -10
- package/dist/config/loadConfig.js +73 -36
- package/dist/config/loadConfig.js.map +1 -1
- package/dist/config/schema.d.ts +59 -29
- package/dist/config/schema.js +45 -51
- package/dist/config/schema.js.map +1 -1
- package/dist/errors.d.ts +9 -0
- package/dist/errors.js +21 -0
- package/dist/errors.js.map +1 -0
- package/dist/files/collectFiles.d.ts +21 -0
- package/dist/files/collectFiles.js +189 -0
- package/dist/files/collectFiles.js.map +1 -0
- package/dist/fs.d.ts +16 -0
- package/dist/fs.js +50 -0
- package/dist/fs.js.map +1 -0
- package/dist/graph/buildFileGraph.d.ts +33 -0
- package/dist/graph/buildFileGraph.js +163 -0
- package/dist/graph/buildFileGraph.js.map +1 -0
- package/dist/graph/fileGraph.d.ts +20 -0
- package/dist/graph/fileGraph.js +75 -0
- package/dist/graph/fileGraph.js.map +1 -0
- package/dist/index.d.ts +10 -21
- package/dist/index.js +6 -29
- package/dist/index.js.map +1 -1
- package/dist/output/analyzeText.d.ts +7 -0
- package/dist/output/analyzeText.js +91 -0
- package/dist/output/analyzeText.js.map +1 -0
- package/dist/parser/extractSites.d.ts +3 -0
- package/dist/parser/extractSites.js +704 -0
- package/dist/parser/extractSites.js.map +1 -0
- package/dist/parser/loadsTarget.d.ts +10 -0
- package/dist/parser/loadsTarget.js +304 -0
- package/dist/parser/loadsTarget.js.map +1 -0
- package/dist/parser/types.d.ts +30 -0
- package/dist/{types/graph.js → parser/types.js} +1 -1
- package/dist/parser/types.js.map +1 -0
- package/dist/project/discoverProject.d.ts +2 -0
- package/dist/project/discoverProject.js +477 -0
- package/dist/project/discoverProject.js.map +1 -0
- package/dist/project/gitignore.d.ts +13 -0
- package/dist/project/gitignore.js +138 -0
- package/dist/project/gitignore.js.map +1 -0
- package/dist/project/types.d.ts +44 -0
- package/dist/{types/parser.js → project/types.js} +1 -1
- package/dist/project/types.js.map +1 -0
- package/dist/resolver/createResolver.d.ts +4 -0
- package/dist/resolver/createResolver.js +276 -0
- package/dist/resolver/createResolver.js.map +1 -0
- package/dist/resolver/types.d.ts +28 -0
- package/dist/resolver/types.js +3 -0
- package/dist/resolver/types.js.map +1 -0
- package/dist/resolver/workspaceHost.d.ts +12 -0
- package/dist/resolver/workspaceHost.js +253 -0
- package/dist/resolver/workspaceHost.js.map +1 -0
- package/dist/types/api.d.ts +71 -64
- package/package.json +24 -25
- package/dist/analysis/reporter.d.ts +0 -22
- package/dist/analysis/reporter.js +0 -116
- package/dist/analysis/reporter.js.map +0 -1
- package/dist/graph/cycleDetector.d.ts +0 -2
- package/dist/graph/cycleDetector.js +0 -56
- package/dist/graph/cycleDetector.js.map +0 -1
- package/dist/graph/dependencyGraph.d.ts +0 -10
- package/dist/graph/dependencyGraph.js +0 -41
- package/dist/graph/dependencyGraph.js.map +0 -1
- package/dist/metrics/abstractness.d.ts +0 -2
- package/dist/metrics/abstractness.js +0 -10
- package/dist/metrics/abstractness.js.map +0 -1
- package/dist/metrics/distance.d.ts +0 -1
- package/dist/metrics/distance.js +0 -7
- package/dist/metrics/distance.js.map +0 -1
- package/dist/metrics/index.d.ts +0 -4
- package/dist/metrics/index.js +0 -30
- package/dist/metrics/index.js.map +0 -1
- package/dist/metrics/instability.d.ts +0 -1
- package/dist/metrics/instability.js +0 -8
- package/dist/metrics/instability.js.map +0 -1
- package/dist/parser/fileScanner.d.ts +0 -8
- package/dist/parser/fileScanner.js +0 -22
- package/dist/parser/fileScanner.js.map +0 -1
- package/dist/parser/tsParser.d.ts +0 -18
- package/dist/parser/tsParser.js +0 -158
- package/dist/parser/tsParser.js.map +0 -1
- package/dist/types/graph.d.ts +0 -14
- package/dist/types/graph.js.map +0 -1
- package/dist/types/parser.d.ts +0 -26
- package/dist/types/parser.js.map +0 -1
- package/dist/utils/deepMerge.d.ts +0 -1
- package/dist/utils/deepMerge.js +0 -23
- package/dist/utils/deepMerge.js.map +0 -1
- package/dist/utils/log.d.ts +0 -2
- package/dist/utils/log.js +0 -9
- package/dist/utils/log.js.map +0 -1
- package/dist/utils/pathUtils.d.ts +0 -12
- package/dist/utils/pathUtils.js +0 -27
- package/dist/utils/pathUtils.js.map +0 -1
package/dist/api/analyze.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/api/analyze.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/api/analyze.ts"],"names":[],"mappings":";;AAyBA,0BA8BC;AAvDD,yCAAmD;AAEnD,qDAAkD;AAClD,sCAAwC;AACxC,wDAA0F;AAC1F,8BAA8C;AAC9C,4DAAyD;AACzD,gEAA6D;AAC7D,+DAA4D;AAY5D;;;;GAIG;AACI,KAAK,UAAU,OAAO,CAAC,UAA0B,EAAE;IACxD,MAAM,OAAO,GAAG,IAAA,mBAAW,EAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,uBAAU,EAAC,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAA,mBAAW,EAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAClF,IAAI,CAAC,IAAA,UAAK,EAAC,IAAA,mBAAc,GAAE,EAAE,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,oBAAW,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,GAAG,GAAG,IAAA,iCAAe,EAAC,OAAO,EAAE;QACnC,UAAU,EAAE,IAAA,mCAAoB,EAAC,4BAAa,EAAE,MAAM,CAAC,OAAO,CAAC;QAC/D,gBAAgB,EAAE,IAAA,mCAAoB,EAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC;KAC3D,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,IAAA,2BAAY,EAAC,GAAG,EAAE;QAC9B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,4BAAa;KAC3B,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAA,+BAAc,EAAC,GAAG,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAA,+BAAc,EAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE;QACtF,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC,CAAC;IAEH,OAAO;QACL,GAAG;QACH,KAAK;QACL,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { EdgeKind, LoadReason } from '../parser/types';
|
|
2
|
+
import type { ResolutionClass, Target } from '../resolver/types';
|
|
3
|
+
import { type AnalyzeOptions } from './analyze';
|
|
4
|
+
export interface ExplainRow {
|
|
5
|
+
specifier: string;
|
|
6
|
+
line: number;
|
|
7
|
+
column: number;
|
|
8
|
+
kind: EdgeKind;
|
|
9
|
+
loadsTarget: boolean;
|
|
10
|
+
loadsTargetBy: LoadReason | null;
|
|
11
|
+
loadReason: string;
|
|
12
|
+
class: ResolutionClass;
|
|
13
|
+
target: Target | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Lists every import in one file with its syntactic kind, whether it loads its
|
|
17
|
+
* target at runtime (and why), and how it resolved. This is the debugging view
|
|
18
|
+
* for the graph and the runtime-load contract.
|
|
19
|
+
*/
|
|
20
|
+
export declare function explainFile(options: AnalyzeOptions & {
|
|
21
|
+
file: string;
|
|
22
|
+
}): Promise<ExplainRow[]>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.explainFile = explainFile;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const fs_1 = require("../fs");
|
|
7
|
+
const analyze_1 = require("./analyze");
|
|
8
|
+
/**
|
|
9
|
+
* Lists every import in one file with its syntactic kind, whether it loads its
|
|
10
|
+
* target at runtime (and why), and how it resolved. This is the debugging view
|
|
11
|
+
* for the graph and the runtime-load contract.
|
|
12
|
+
*/
|
|
13
|
+
async function explainFile(options) {
|
|
14
|
+
const result = await (0, analyze_1.analyze)(options);
|
|
15
|
+
const file = toRootRelative(result.ctx.rootDir, options.file);
|
|
16
|
+
if (!result.files.files.includes(file)) {
|
|
17
|
+
throw new errors_1.ConfigError(`File is not in the analysis set: ${file}`);
|
|
18
|
+
}
|
|
19
|
+
return result.sites
|
|
20
|
+
.filter((record) => record.file === file)
|
|
21
|
+
.map((record) => ({
|
|
22
|
+
specifier: record.site.specifier,
|
|
23
|
+
line: record.site.line,
|
|
24
|
+
column: record.site.column,
|
|
25
|
+
kind: record.site.kind,
|
|
26
|
+
loadsTarget: record.site.loadsTarget === true,
|
|
27
|
+
loadsTargetBy: record.site.loadsTargetBy ?? null,
|
|
28
|
+
loadReason: record.site.loadReason ?? '',
|
|
29
|
+
class: record.resolution.class,
|
|
30
|
+
target: record.resolution.target,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
function toRootRelative(rootDir, file) {
|
|
34
|
+
if ((0, node_path_1.isAbsolute)(file))
|
|
35
|
+
return (0, fs_1.toPosix)((0, node_path_1.relative)(rootDir, file));
|
|
36
|
+
return (0, fs_1.toPosix)(file.replace(/^\.\//, ''));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=explain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/api/explain.ts"],"names":[],"mappings":";;AAyBA,kCAsBC;AA/CD,yCAAiD;AAEjD,sCAAwC;AACxC,8BAAgC;AAGhC,uCAAyD;AAczD;;;;GAIG;AACI,KAAK,UAAU,WAAW,CAC/B,OAA0C;IAE1C,MAAM,MAAM,GAAG,MAAM,IAAA,iBAAO,EAAC,OAAO,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,oBAAW,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,MAAM,CAAC,KAAK;SAChB,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;SACxC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS;QAChC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;QACtB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;QAC1B,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI;QACtB,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,IAAI;QAC7C,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,aAAa,IAAI,IAAI;QAChD,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE;QACxC,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK;QAC9B,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM;KACjC,CAAC,CAAC,CAAC;AACR,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,IAAY;IACnD,IAAI,IAAA,sBAAU,EAAC,IAAI,CAAC;QAAE,OAAO,IAAA,YAAO,EAAC,IAAA,oBAAQ,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9D,OAAO,IAAA,YAAO,EAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
package/dist/api/export.d.ts
CHANGED
|
@@ -1,50 +1,7 @@
|
|
|
1
1
|
import type { AnalysisResult } from '../types/api';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Writes the versioned JSON export of an analysis to a file. The output is
|
|
4
|
+
* pretty-printed and ends with a newline; two runs on the same inputs write
|
|
5
|
+
* byte-identical files.
|
|
4
6
|
*/
|
|
5
|
-
export
|
|
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;
|
|
7
|
+
export declare function exportToFile(result: AnalysisResult, path: string): Promise<void>;
|
package/dist/api/export.js
CHANGED
|
@@ -1,53 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.exportToFile = exportToFile;
|
|
4
|
-
|
|
5
|
-
const promises_1 = require("fs/promises");
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
6
5
|
const serialization_1 = require("./serialization");
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
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
|
-
* ```
|
|
7
|
+
* Writes the versioned JSON export of an analysis to a file. The output is
|
|
8
|
+
* pretty-printed and ends with a newline; two runs on the same inputs write
|
|
9
|
+
* byte-identical files.
|
|
24
10
|
*/
|
|
25
|
-
async function exportToFile(result,
|
|
26
|
-
|
|
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);
|
|
11
|
+
async function exportToFile(result, path) {
|
|
12
|
+
await (0, promises_1.writeFile)(path, `${JSON.stringify((0, serialization_1.toSerializable)(result), null, 2)}\n`, 'utf-8');
|
|
52
13
|
}
|
|
53
14
|
//# sourceMappingURL=export.js.map
|
package/dist/api/export.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/api/export.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/api/export.ts"],"names":[],"mappings":";;AAUA,oCAEC;AAZD,+CAA6C;AAG7C,mDAAiD;AAEjD;;;;GAIG;AACI,KAAK,UAAU,YAAY,CAAC,MAAsB,EAAE,IAAY;IACrE,MAAM,IAAA,oBAAS,EAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAA,8BAAc,EAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -1,28 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { AnalysisResult, SerializableAnalysisResult, SerializableDependencyGraph, SerializableCycle } from '../types/api';
|
|
1
|
+
import type { AnalysisResult, SerializableResult } from '../types/api';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Projects an analysis into its versioned, fully sorted export shape. The
|
|
4
|
+
* parser's `ts.Node` references and the project context are dropped here, so
|
|
5
|
+
* the result is plain data with no timestamp.
|
|
7
6
|
*/
|
|
8
|
-
export declare function
|
|
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;
|
|
7
|
+
export declare function toSerializable(result: AnalysisResult): SerializableResult;
|
|
8
|
+
export declare function discoveryWarnings(result: AnalysisResult): string[];
|
|
@@ -1,71 +1,81 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.serializeGraph = serializeGraph;
|
|
4
|
-
exports.normalizeCycle = normalizeCycle;
|
|
5
3
|
exports.toSerializable = toSerializable;
|
|
6
|
-
|
|
4
|
+
exports.discoveryWarnings = discoveryWarnings;
|
|
7
5
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Projects an analysis into its versioned, fully sorted export shape. The
|
|
7
|
+
* parser's `ts.Node` references and the project context are dropped here, so
|
|
8
|
+
* the result is plain data with no timestamp.
|
|
11
9
|
*/
|
|
12
|
-
function
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
function toSerializable(result) {
|
|
11
|
+
return {
|
|
12
|
+
version: 1,
|
|
13
|
+
files: result.graph.files(),
|
|
14
|
+
edges: result.graph.edges().map(serializeEdge),
|
|
15
|
+
sites: [...result.sites].sort(compareRecords).map(serializeSite),
|
|
16
|
+
report: serializeReport(result),
|
|
17
|
+
};
|
|
19
18
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* Creates a unique ID based on the cycle's contents and rotates the cycle
|
|
23
|
-
* to start with the lexicographically smallest file path.
|
|
24
|
-
*
|
|
25
|
-
* @param cycle - Array of file paths forming a cycle
|
|
26
|
-
* @returns Normalized cycle with unique ID
|
|
27
|
-
*/
|
|
28
|
-
function normalizeCycle(cycle) {
|
|
29
|
-
if (cycle.length === 0) {
|
|
30
|
-
return {
|
|
31
|
-
id: '',
|
|
32
|
-
nodes: [],
|
|
33
|
-
length: 0,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
// Create stable ID by hashing sorted paths
|
|
37
|
-
const sorted = [...cycle].sort();
|
|
38
|
-
const id = (0, crypto_1.createHash)('sha256').update(sorted.join('|')).digest('hex').slice(0, 16);
|
|
39
|
-
// Rotate cycle to start with lexicographically smallest element
|
|
40
|
-
const minPath = sorted[0];
|
|
41
|
-
const minIndex = cycle.indexOf(minPath);
|
|
42
|
-
const normalized = [...cycle.slice(minIndex), ...cycle.slice(0, minIndex)];
|
|
19
|
+
function serializeSite(record) {
|
|
20
|
+
const { site, resolution } = record;
|
|
43
21
|
return {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
22
|
+
file: record.file,
|
|
23
|
+
specifier: site.specifier,
|
|
24
|
+
line: site.line,
|
|
25
|
+
column: site.column,
|
|
26
|
+
kind: site.kind,
|
|
27
|
+
form: site.form,
|
|
28
|
+
deferred: site.deferred === true,
|
|
29
|
+
unsupported: site.unsupported ?? null,
|
|
30
|
+
loadsTarget: site.loadsTarget === true,
|
|
31
|
+
loadsTargetBy: site.loadsTargetBy ?? null,
|
|
32
|
+
class: resolution.class,
|
|
33
|
+
reason: resolution.reason ?? null,
|
|
34
|
+
target: resolution.target,
|
|
35
|
+
mapped: resolution.mapped?.from ?? null,
|
|
36
|
+
requested: resolution.requested ?? null,
|
|
47
37
|
};
|
|
48
38
|
}
|
|
49
|
-
|
|
50
|
-
* Converts an AnalysisResult with rich objects to a fully serializable format.
|
|
51
|
-
* This includes:
|
|
52
|
-
* - Converting Sets to Arrays in the dependency graph
|
|
53
|
-
* - Normalizing cycles with unique IDs
|
|
54
|
-
* - Adding version and timestamp metadata
|
|
55
|
-
*
|
|
56
|
-
* @param result - The analysis result to serialize
|
|
57
|
-
* @returns Fully serializable result ready for JSON.stringify
|
|
58
|
-
*/
|
|
59
|
-
function toSerializable(result) {
|
|
39
|
+
function serializeEdge(edge) {
|
|
60
40
|
return {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
cycles: result.cycles.map(normalizeCycle),
|
|
67
|
-
metrics: result.metrics,
|
|
68
|
-
report: result.report,
|
|
41
|
+
from: edge.from,
|
|
42
|
+
to: edge.to,
|
|
43
|
+
runtime: edge.runtime,
|
|
44
|
+
mapped: edge.mapped,
|
|
45
|
+
kinds: [...new Set(edge.sites.map((site) => site.kind))].sort(),
|
|
69
46
|
};
|
|
70
47
|
}
|
|
48
|
+
function serializeReport(result) {
|
|
49
|
+
return {
|
|
50
|
+
stats: { ...result.report.stats },
|
|
51
|
+
unresolved: result.report.unresolved.map(siteLocation),
|
|
52
|
+
ignoredByDir: { ...result.report.ignoredByDir },
|
|
53
|
+
unsupported: result.report.unsupported.map(serializeUnsupported),
|
|
54
|
+
selfImports: [...result.report.selfImports],
|
|
55
|
+
uncovered: [...result.report.uncovered],
|
|
56
|
+
skipped: result.report.skipped.map((entry) => ({ file: entry.file, reason: entry.reason })),
|
|
57
|
+
warnings: discoveryWarnings(result),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function discoveryWarnings(result) {
|
|
61
|
+
return [...result.ctx.warnings, ...result.ctx.unsupported.map((name) => `unsupported: ${name}`)];
|
|
62
|
+
}
|
|
63
|
+
function siteLocation(record) {
|
|
64
|
+
return {
|
|
65
|
+
file: record.file,
|
|
66
|
+
line: record.site.line,
|
|
67
|
+
column: record.site.column,
|
|
68
|
+
specifier: record.site.specifier,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function serializeUnsupported(record) {
|
|
72
|
+
return { ...siteLocation(record), reason: record.resolution.reason ?? '' };
|
|
73
|
+
}
|
|
74
|
+
function compareRecords(a, b) {
|
|
75
|
+
if (a.file !== b.file)
|
|
76
|
+
return a.file < b.file ? -1 : 1;
|
|
77
|
+
if (a.site.line !== b.site.line)
|
|
78
|
+
return a.site.line - b.site.line;
|
|
79
|
+
return a.site.column - b.site.column;
|
|
80
|
+
}
|
|
71
81
|
//# sourceMappingURL=serialization.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../../src/api/serialization.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../../src/api/serialization.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,134 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
(0, log_1.log)(config, '✓ Configuration loaded successfully');
|
|
16
|
-
(0, log_1.log)(config, ` Root directory: ${config.rootDir}`);
|
|
17
|
-
(0, log_1.log)(config, ` Enabled metrics: ${config.metrics.enabled.join(', ')}`);
|
|
18
|
-
if (config.analysis.target) {
|
|
19
|
-
(0, log_1.log)(config, ` Analysis scope: ${config.analysis.target} = ${config.analysis.value}`);
|
|
20
|
-
}
|
|
21
|
-
(0, log_1.log)(config, '\n📁 Scanning files...');
|
|
22
|
-
const files = await (0, fileScanner_1.scanFiles)(config);
|
|
23
|
-
(0, log_1.log)(config, `✓ Found ${files.length} TypeScript files`);
|
|
24
|
-
if (files.length === 0) {
|
|
25
|
-
(0, log_1.log)(config, '\n⚠ No files found matching the configured patterns.');
|
|
26
|
-
process.exitCode = 0;
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
(0, log_1.log)(config, '\n📝 Parsing modules...');
|
|
30
|
-
const modules = (0, tsParser_1.parseProject)(files);
|
|
31
|
-
(0, log_1.log)(config, `✓ Parsed ${modules.length} modules`);
|
|
32
|
-
(0, log_1.log)(config, '\n🔗 Building dependency graph...');
|
|
33
|
-
const graph = new dependencyGraph_1.DependencyGraph(modules);
|
|
34
|
-
(0, log_1.log)(config, '✓ Dependency graph built');
|
|
35
|
-
(0, log_1.log)(config, '\n🔄 Detecting cycles...');
|
|
36
|
-
const cycles = (0, cycleDetector_1.detectCycles)(graph);
|
|
37
|
-
(0, log_1.log)(config, `✓ Found ${cycles.length} cycle(s)`);
|
|
38
|
-
if (checkCyclesAndFail(cycles, config.ci.failOnCycle)) {
|
|
39
|
-
if (config.ci.outputFormat !== 'json') {
|
|
40
|
-
process.exitCode = 1;
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
(0, log_1.log)(config, '\n📐 Computing metrics...');
|
|
45
|
-
const metrics = (0, metrics_1.computeAllMetrics)(graph, modules, cycles);
|
|
46
|
-
(0, log_1.log)(config, '✓ Metrics computed');
|
|
47
|
-
const report = (0, reporter_1.generateReport)(modules, metrics, cycles, config);
|
|
48
|
-
// Create AnalysisResult for potential export
|
|
49
|
-
const result = {
|
|
50
|
-
modules,
|
|
51
|
-
graph,
|
|
52
|
-
cycles,
|
|
53
|
-
metrics,
|
|
54
|
-
report,
|
|
55
|
-
config,
|
|
56
|
-
};
|
|
57
|
-
if (config.ci.outputFormat === 'json') {
|
|
58
|
-
console.log((0, reporter_1.formatJsonOutput)(report));
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
(0, reporter_1.formatConsoleOutput)(report, config);
|
|
62
|
-
}
|
|
63
|
-
if (!report.success) {
|
|
64
|
-
if (config.ci.outputFormat !== 'json') {
|
|
65
|
-
console.error(report.violations.cycles.length > 0 && config.ci.failOnCycle
|
|
66
|
-
? '\n❌ Error: Cycles detected in dependency graph'
|
|
67
|
-
: '\n❌ Error: Modules exceed distance threshold');
|
|
68
|
-
}
|
|
69
|
-
process.exitCode = 1;
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
process.exitCode = 0;
|
|
73
|
-
}
|
|
74
|
-
return result;
|
|
75
|
-
}
|
|
76
|
-
function checkCyclesAndFail(cycles, failOnCycle) {
|
|
77
|
-
if (cycles.length > 0 && failOnCycle) {
|
|
78
|
-
console.error('\n❌ Error: Cycles detected in dependency graph');
|
|
79
|
-
for (const cycle of cycles) {
|
|
80
|
-
const fileNames = cycle.map((p) => p.split('/').pop()).join(' → ');
|
|
81
|
-
console.error(` - ${fileNames}`);
|
|
82
|
-
}
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
const program = new commander_1.Command();
|
|
88
|
-
program
|
|
89
|
-
.name('tdepend')
|
|
90
|
-
.description('TDepend: TypeScript dependency analysis tool')
|
|
91
|
-
.version('0.1.0');
|
|
92
|
-
program
|
|
93
|
-
.command('analyze')
|
|
94
|
-
.description('Analyze a TypeScript project for dependencies and metrics')
|
|
95
|
-
.option('-c, --config <path>', 'Path to config file (tdepend.config.json)')
|
|
96
|
-
.option('--class <name>', 'Analyze a specific class by name')
|
|
97
|
-
.option('--namespace <name>', 'Analyze a specific namespace by name')
|
|
98
|
-
.option('--ci', 'Run in CI mode with JSON output and strict exit codes')
|
|
99
|
-
.option('-e, --export <path>', 'Export full analysis to JSON file')
|
|
100
|
-
.option('-o, --output <path>', 'Alias for --export')
|
|
101
|
-
.argument('[target]', 'Optional module/file path to analyze')
|
|
102
|
-
.action(async (target, options) => {
|
|
103
|
-
try {
|
|
104
|
-
const config = (0, loadConfig_1.loadConfig)(options.config);
|
|
105
|
-
if (options.ci) {
|
|
106
|
-
config.ci.outputFormat = 'json';
|
|
107
|
-
}
|
|
108
|
-
if (target) {
|
|
109
|
-
config.analysis.target = 'module';
|
|
110
|
-
config.analysis.value = target;
|
|
111
|
-
}
|
|
112
|
-
if (options.class) {
|
|
113
|
-
config.analysis.target = 'class';
|
|
114
|
-
config.analysis.value = options.class;
|
|
115
|
-
}
|
|
116
|
-
if (options.namespace) {
|
|
117
|
-
config.analysis.target = 'namespace';
|
|
118
|
-
config.analysis.value = options.namespace;
|
|
119
|
-
}
|
|
120
|
-
const result = await runAnalysis(config);
|
|
121
|
-
// Handle export if requested
|
|
122
|
-
if (result && (options.export || options.output)) {
|
|
123
|
-
const exportPath = options.export || options.output;
|
|
124
|
-
await (0, export_1.exportToFile)(result, exportPath);
|
|
125
|
-
(0, log_1.log)(config, `\n✓ Analysis exported to ${exportPath}`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
130
|
-
process.exitCode = 1;
|
|
131
|
-
}
|
|
4
|
+
const run_1 = require("./run");
|
|
5
|
+
void (0, run_1.runCli)(process.argv.slice(2), {
|
|
6
|
+
cwd: process.cwd(),
|
|
7
|
+
stdout: (message) => {
|
|
8
|
+
process.stdout.write(message);
|
|
9
|
+
},
|
|
10
|
+
stderr: (message) => {
|
|
11
|
+
process.stderr.write(message);
|
|
12
|
+
},
|
|
13
|
+
}).then((code) => {
|
|
14
|
+
process.exitCode = code;
|
|
132
15
|
});
|
|
133
|
-
program.parse();
|
|
134
16
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,+BAA+B;AAE/B,KAAK,IAAA,YAAM,EAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACjC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;CACF,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CliIo {
|
|
2
|
+
cwd: string;
|
|
3
|
+
stdout(s: string): void;
|
|
4
|
+
stderr(s: string): void;
|
|
5
|
+
}
|
|
6
|
+
type ExitCode = 0 | 1 | 2;
|
|
7
|
+
/**
|
|
8
|
+
* Runs the CLI and resolves to its exit code. Only the commands that exist at
|
|
9
|
+
* this milestone are registered: `analyze` and `explain`.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runCli(argv: string[], io: CliIo): Promise<ExitCode>;
|
|
12
|
+
export {};
|