@liendev/core 0.19.5
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 +336 -0
- package/dist/config/loader.d.ts +12 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +46 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/merge.d.ts +20 -0
- package/dist/config/merge.d.ts.map +1 -0
- package/dist/config/merge.js +71 -0
- package/dist/config/merge.js.map +1 -0
- package/dist/config/migration-manager.d.ts +46 -0
- package/dist/config/migration-manager.d.ts.map +1 -0
- package/dist/config/migration-manager.js +119 -0
- package/dist/config/migration-manager.js.map +1 -0
- package/dist/config/migration.d.ts +20 -0
- package/dist/config/migration.d.ts.map +1 -0
- package/dist/config/migration.js +155 -0
- package/dist/config/migration.js.map +1 -0
- package/dist/config/schema.d.ts +101 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +58 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/service.d.ts +122 -0
- package/dist/config/service.d.ts.map +1 -0
- package/dist/config/service.js +477 -0
- package/dist/config/service.js.map +1 -0
- package/dist/constants.d.ts +20 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +43 -0
- package/dist/constants.js.map +1 -0
- package/dist/embeddings/cache.d.ts +45 -0
- package/dist/embeddings/cache.d.ts.map +1 -0
- package/dist/embeddings/cache.js +109 -0
- package/dist/embeddings/cache.js.map +1 -0
- package/dist/embeddings/local.d.ts +10 -0
- package/dist/embeddings/local.d.ts.map +1 -0
- package/dist/embeddings/local.js +63 -0
- package/dist/embeddings/local.js.map +1 -0
- package/dist/embeddings/types.d.ts +9 -0
- package/dist/embeddings/types.d.ts.map +1 -0
- package/dist/embeddings/types.js +5 -0
- package/dist/embeddings/types.js.map +1 -0
- package/dist/errors/codes.d.ts +18 -0
- package/dist/errors/codes.d.ts.map +1 -0
- package/dist/errors/codes.js +25 -0
- package/dist/errors/codes.js.map +1 -0
- package/dist/errors/index.d.ts +85 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +134 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/frameworks/detector-service.d.ts +59 -0
- package/dist/frameworks/detector-service.d.ts.map +1 -0
- package/dist/frameworks/detector-service.js +219 -0
- package/dist/frameworks/detector-service.js.map +1 -0
- package/dist/frameworks/laravel/config.d.ts +6 -0
- package/dist/frameworks/laravel/config.d.ts.map +1 -0
- package/dist/frameworks/laravel/config.js +68 -0
- package/dist/frameworks/laravel/config.js.map +1 -0
- package/dist/frameworks/laravel/detector.d.ts +6 -0
- package/dist/frameworks/laravel/detector.d.ts.map +1 -0
- package/dist/frameworks/laravel/detector.js +96 -0
- package/dist/frameworks/laravel/detector.js.map +1 -0
- package/dist/frameworks/nodejs/config.d.ts +6 -0
- package/dist/frameworks/nodejs/config.d.ts.map +1 -0
- package/dist/frameworks/nodejs/config.js +57 -0
- package/dist/frameworks/nodejs/config.js.map +1 -0
- package/dist/frameworks/nodejs/detector.d.ts +6 -0
- package/dist/frameworks/nodejs/detector.d.ts.map +1 -0
- package/dist/frameworks/nodejs/detector.js +77 -0
- package/dist/frameworks/nodejs/detector.js.map +1 -0
- package/dist/frameworks/php/config.d.ts +6 -0
- package/dist/frameworks/php/config.d.ts.map +1 -0
- package/dist/frameworks/php/config.js +53 -0
- package/dist/frameworks/php/config.js.map +1 -0
- package/dist/frameworks/php/detector.d.ts +7 -0
- package/dist/frameworks/php/detector.d.ts.map +1 -0
- package/dist/frameworks/php/detector.js +101 -0
- package/dist/frameworks/php/detector.js.map +1 -0
- package/dist/frameworks/registry.d.ts +20 -0
- package/dist/frameworks/registry.d.ts.map +1 -0
- package/dist/frameworks/registry.js +38 -0
- package/dist/frameworks/registry.js.map +1 -0
- package/dist/frameworks/shopify/config.d.ts +6 -0
- package/dist/frameworks/shopify/config.d.ts.map +1 -0
- package/dist/frameworks/shopify/config.js +50 -0
- package/dist/frameworks/shopify/config.js.map +1 -0
- package/dist/frameworks/shopify/detector.d.ts +6 -0
- package/dist/frameworks/shopify/detector.d.ts.map +1 -0
- package/dist/frameworks/shopify/detector.js +103 -0
- package/dist/frameworks/shopify/detector.js.map +1 -0
- package/dist/frameworks/types.d.ts +51 -0
- package/dist/frameworks/types.d.ts.map +1 -0
- package/dist/frameworks/types.js +21 -0
- package/dist/frameworks/types.js.map +1 -0
- package/dist/git/tracker.d.ts +56 -0
- package/dist/git/tracker.d.ts.map +1 -0
- package/dist/git/tracker.js +189 -0
- package/dist/git/tracker.js.map +1 -0
- package/dist/git/utils.d.ts +60 -0
- package/dist/git/utils.d.ts.map +1 -0
- package/dist/git/utils.js +152 -0
- package/dist/git/utils.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/ast/chunker.d.ts +28 -0
- package/dist/indexer/ast/chunker.d.ts.map +1 -0
- package/dist/indexer/ast/chunker.js +268 -0
- package/dist/indexer/ast/chunker.js.map +1 -0
- package/dist/indexer/ast/complexity/cognitive.d.ts +16 -0
- package/dist/indexer/ast/complexity/cognitive.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/cognitive.js +106 -0
- package/dist/indexer/ast/complexity/cognitive.js.map +1 -0
- package/dist/indexer/ast/complexity/cyclomatic.d.ts +12 -0
- package/dist/indexer/ast/complexity/cyclomatic.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/cyclomatic.js +61 -0
- package/dist/indexer/ast/complexity/cyclomatic.js.map +1 -0
- package/dist/indexer/ast/complexity/halstead.d.ts +55 -0
- package/dist/indexer/ast/complexity/halstead.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/halstead.js +290 -0
- package/dist/indexer/ast/complexity/halstead.js.map +1 -0
- package/dist/indexer/ast/complexity/index.d.ts +13 -0
- package/dist/indexer/ast/complexity/index.d.ts.map +1 -0
- package/dist/indexer/ast/complexity/index.js +12 -0
- package/dist/indexer/ast/complexity/index.js.map +1 -0
- package/dist/indexer/ast/parser.d.ts +27 -0
- package/dist/indexer/ast/parser.d.ts.map +1 -0
- package/dist/indexer/ast/parser.js +103 -0
- package/dist/indexer/ast/parser.js.map +1 -0
- package/dist/indexer/ast/symbols.d.ts +17 -0
- package/dist/indexer/ast/symbols.d.ts.map +1 -0
- package/dist/indexer/ast/symbols.js +265 -0
- package/dist/indexer/ast/symbols.js.map +1 -0
- package/dist/indexer/ast/traversers/index.d.ts +19 -0
- package/dist/indexer/ast/traversers/index.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/index.js +42 -0
- package/dist/indexer/ast/traversers/index.js.map +1 -0
- package/dist/indexer/ast/traversers/php.d.ts +21 -0
- package/dist/indexer/ast/traversers/php.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/php.js +67 -0
- package/dist/indexer/ast/traversers/php.js.map +1 -0
- package/dist/indexer/ast/traversers/python.d.ts +28 -0
- package/dist/indexer/ast/traversers/python.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/python.js +67 -0
- package/dist/indexer/ast/traversers/python.js.map +1 -0
- package/dist/indexer/ast/traversers/types.d.ts +98 -0
- package/dist/indexer/ast/traversers/types.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/types.js +2 -0
- package/dist/indexer/ast/traversers/types.js.map +1 -0
- package/dist/indexer/ast/traversers/typescript.d.ts +29 -0
- package/dist/indexer/ast/traversers/typescript.d.ts.map +1 -0
- package/dist/indexer/ast/traversers/typescript.js +88 -0
- package/dist/indexer/ast/traversers/typescript.js.map +1 -0
- package/dist/indexer/ast/types.d.ts +59 -0
- package/dist/indexer/ast/types.d.ts.map +1 -0
- package/dist/indexer/ast/types.js +2 -0
- package/dist/indexer/ast/types.js.map +1 -0
- package/dist/indexer/change-detector.d.ts +17 -0
- package/dist/indexer/change-detector.d.ts.map +1 -0
- package/dist/indexer/change-detector.js +207 -0
- package/dist/indexer/change-detector.js.map +1 -0
- package/dist/indexer/chunk-batch-processor.d.ts +103 -0
- package/dist/indexer/chunk-batch-processor.d.ts.map +1 -0
- package/dist/indexer/chunk-batch-processor.js +179 -0
- package/dist/indexer/chunk-batch-processor.js.map +1 -0
- package/dist/indexer/chunker.d.ts +10 -0
- package/dist/indexer/chunker.d.ts.map +1 -0
- package/dist/indexer/chunker.js +96 -0
- package/dist/indexer/chunker.js.map +1 -0
- package/dist/indexer/dependency-analyzer.d.ts +60 -0
- package/dist/indexer/dependency-analyzer.d.ts.map +1 -0
- package/dist/indexer/dependency-analyzer.js +261 -0
- package/dist/indexer/dependency-analyzer.js.map +1 -0
- package/dist/indexer/incremental.d.ts +47 -0
- package/dist/indexer/incremental.d.ts.map +1 -0
- package/dist/indexer/incremental.js +284 -0
- package/dist/indexer/incremental.js.map +1 -0
- package/dist/indexer/index.d.ts +80 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +364 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/json-template-chunker.d.ts +9 -0
- package/dist/indexer/json-template-chunker.d.ts.map +1 -0
- package/dist/indexer/json-template-chunker.js +83 -0
- package/dist/indexer/json-template-chunker.js.map +1 -0
- package/dist/indexer/liquid-chunker.d.ts +13 -0
- package/dist/indexer/liquid-chunker.d.ts.map +1 -0
- package/dist/indexer/liquid-chunker.js +272 -0
- package/dist/indexer/liquid-chunker.js.map +1 -0
- package/dist/indexer/manifest.d.ts +122 -0
- package/dist/indexer/manifest.d.ts.map +1 -0
- package/dist/indexer/manifest.js +262 -0
- package/dist/indexer/manifest.js.map +1 -0
- package/dist/indexer/progress-tracker.d.ts +35 -0
- package/dist/indexer/progress-tracker.d.ts.map +1 -0
- package/dist/indexer/progress-tracker.js +33 -0
- package/dist/indexer/progress-tracker.js.map +1 -0
- package/dist/indexer/scanner.d.ts +16 -0
- package/dist/indexer/scanner.d.ts.map +1 -0
- package/dist/indexer/scanner.js +159 -0
- package/dist/indexer/scanner.js.map +1 -0
- package/dist/indexer/symbol-extractor.d.ts +18 -0
- package/dist/indexer/symbol-extractor.d.ts.map +1 -0
- package/dist/indexer/symbol-extractor.js +351 -0
- package/dist/indexer/symbol-extractor.js.map +1 -0
- package/dist/indexer/types.d.ts +34 -0
- package/dist/indexer/types.d.ts.map +1 -0
- package/dist/indexer/types.js +2 -0
- package/dist/indexer/types.js.map +1 -0
- package/dist/insights/complexity-analyzer.d.ts +82 -0
- package/dist/insights/complexity-analyzer.d.ts.map +1 -0
- package/dist/insights/complexity-analyzer.js +356 -0
- package/dist/insights/complexity-analyzer.js.map +1 -0
- package/dist/insights/formatters/index.d.ts +11 -0
- package/dist/insights/formatters/index.d.ts.map +1 -0
- package/dist/insights/formatters/index.js +20 -0
- package/dist/insights/formatters/index.js.map +1 -0
- package/dist/insights/formatters/json.d.ts +7 -0
- package/dist/insights/formatters/json.d.ts.map +1 -0
- package/dist/insights/formatters/json.js +14 -0
- package/dist/insights/formatters/json.js.map +1 -0
- package/dist/insights/formatters/sarif.d.ts +6 -0
- package/dist/insights/formatters/sarif.d.ts.map +1 -0
- package/dist/insights/formatters/sarif.js +113 -0
- package/dist/insights/formatters/sarif.js.map +1 -0
- package/dist/insights/formatters/text.d.ts +6 -0
- package/dist/insights/formatters/text.d.ts.map +1 -0
- package/dist/insights/formatters/text.js +154 -0
- package/dist/insights/formatters/text.js.map +1 -0
- package/dist/insights/types.d.ts +73 -0
- package/dist/insights/types.d.ts.map +1 -0
- package/dist/insights/types.js +9 -0
- package/dist/insights/types.js.map +1 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/path-matching.d.ts +69 -0
- package/dist/utils/path-matching.d.ts.map +1 -0
- package/dist/utils/path-matching.js +123 -0
- package/dist/utils/path-matching.js.map +1 -0
- package/dist/utils/result.d.ts +65 -0
- package/dist/utils/result.d.ts.map +1 -0
- package/dist/utils/result.js +67 -0
- package/dist/utils/result.js.map +1 -0
- package/dist/utils/version.d.ts +22 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +28 -0
- package/dist/utils/version.js.map +1 -0
- package/dist/vectordb/batch-insert.d.ts +14 -0
- package/dist/vectordb/batch-insert.d.ts.map +1 -0
- package/dist/vectordb/batch-insert.js +185 -0
- package/dist/vectordb/batch-insert.js.map +1 -0
- package/dist/vectordb/boosting/composer.d.ts +51 -0
- package/dist/vectordb/boosting/composer.d.ts.map +1 -0
- package/dist/vectordb/boosting/composer.js +65 -0
- package/dist/vectordb/boosting/composer.js.map +1 -0
- package/dist/vectordb/boosting/index.d.ts +22 -0
- package/dist/vectordb/boosting/index.d.ts.map +1 -0
- package/dist/vectordb/boosting/index.js +22 -0
- package/dist/vectordb/boosting/index.js.map +1 -0
- package/dist/vectordb/boosting/strategies.d.ts +40 -0
- package/dist/vectordb/boosting/strategies.d.ts.map +1 -0
- package/dist/vectordb/boosting/strategies.js +174 -0
- package/dist/vectordb/boosting/strategies.js.map +1 -0
- package/dist/vectordb/boosting/types.d.ts +20 -0
- package/dist/vectordb/boosting/types.d.ts.map +1 -0
- package/dist/vectordb/boosting/types.js +2 -0
- package/dist/vectordb/boosting/types.js.map +1 -0
- package/dist/vectordb/intent-classifier.d.ts +99 -0
- package/dist/vectordb/intent-classifier.d.ts.map +1 -0
- package/dist/vectordb/intent-classifier.js +193 -0
- package/dist/vectordb/intent-classifier.js.map +1 -0
- package/dist/vectordb/lancedb.d.ts +45 -0
- package/dist/vectordb/lancedb.d.ts.map +1 -0
- package/dist/vectordb/lancedb.js +203 -0
- package/dist/vectordb/lancedb.js.map +1 -0
- package/dist/vectordb/maintenance.d.ts +18 -0
- package/dist/vectordb/maintenance.d.ts.map +1 -0
- package/dist/vectordb/maintenance.js +87 -0
- package/dist/vectordb/maintenance.js.map +1 -0
- package/dist/vectordb/query.d.ts +34 -0
- package/dist/vectordb/query.d.ts.map +1 -0
- package/dist/vectordb/query.js +303 -0
- package/dist/vectordb/query.js.map +1 -0
- package/dist/vectordb/relevance.d.ts +15 -0
- package/dist/vectordb/relevance.d.ts.map +1 -0
- package/dist/vectordb/relevance.js +19 -0
- package/dist/vectordb/relevance.js.map +1 -0
- package/dist/vectordb/types.d.ts +29 -0
- package/dist/vectordb/types.d.ts.map +1 -0
- package/dist/vectordb/types.js +2 -0
- package/dist/vectordb/types.js.map +1 -0
- package/dist/vectordb/version.d.ts +16 -0
- package/dist/vectordb/version.d.ts.map +1 -0
- package/dist/vectordb/version.js +40 -0
- package/dist/vectordb/version.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the SARIF rule ID for a metric type
|
|
3
|
+
*/
|
|
4
|
+
function getRuleId(metricType) {
|
|
5
|
+
switch (metricType) {
|
|
6
|
+
case 'cognitive': return 'lien/high-cognitive-complexity';
|
|
7
|
+
case 'cyclomatic': return 'lien/high-cyclomatic-complexity';
|
|
8
|
+
case 'halstead_effort': return 'lien/high-halstead-effort';
|
|
9
|
+
case 'halstead_bugs': return 'lien/high-estimated-bugs';
|
|
10
|
+
default: return 'lien/high-complexity';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Format complexity report as SARIF for GitHub Code Scanning
|
|
15
|
+
*/
|
|
16
|
+
export function formatSarifReport(report) {
|
|
17
|
+
const rules = [
|
|
18
|
+
{
|
|
19
|
+
id: 'lien/high-cyclomatic-complexity',
|
|
20
|
+
shortDescription: {
|
|
21
|
+
text: 'Too many test paths',
|
|
22
|
+
},
|
|
23
|
+
fullDescription: {
|
|
24
|
+
text: 'Function or method requires too many test cases to achieve full branch coverage. Each decision point (if, switch, loop) adds a path that needs testing.',
|
|
25
|
+
},
|
|
26
|
+
help: {
|
|
27
|
+
text: 'Consider refactoring by extracting methods, using early returns, or simplifying conditional logic to reduce the number of test paths.',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'lien/high-cognitive-complexity',
|
|
32
|
+
shortDescription: {
|
|
33
|
+
text: 'High mental load',
|
|
34
|
+
},
|
|
35
|
+
fullDescription: {
|
|
36
|
+
text: 'Function or method has high mental load (deeply nested or hard to follow), requiring too much mental effort to understand and maintain.',
|
|
37
|
+
},
|
|
38
|
+
help: {
|
|
39
|
+
text: 'Consider flattening nested conditionals, extracting helper functions, or using guard clauses to reduce mental load.',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'lien/high-halstead-effort',
|
|
44
|
+
shortDescription: {
|
|
45
|
+
text: 'Long time to understand',
|
|
46
|
+
},
|
|
47
|
+
fullDescription: {
|
|
48
|
+
text: 'Function or method takes too long to understand, based on Halstead metrics (operators and operands count).',
|
|
49
|
+
},
|
|
50
|
+
help: {
|
|
51
|
+
text: 'Consider simplifying expressions, reducing variable count, or breaking into smaller functions.',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'lien/high-estimated-bugs',
|
|
56
|
+
shortDescription: {
|
|
57
|
+
text: 'High estimated bug count',
|
|
58
|
+
},
|
|
59
|
+
fullDescription: {
|
|
60
|
+
text: 'Function or method is likely to contain bugs based on Halstead metrics (Volume / 3000), which estimates bug count from code complexity.',
|
|
61
|
+
},
|
|
62
|
+
help: {
|
|
63
|
+
text: 'Consider simplifying the function, breaking into smaller units, or adding thorough test coverage.',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
const results = [];
|
|
68
|
+
// Convert violations to SARIF results
|
|
69
|
+
for (const [filepath, fileData] of Object.entries(report.files)) {
|
|
70
|
+
for (const violation of fileData.violations) {
|
|
71
|
+
const ruleId = getRuleId(violation.metricType);
|
|
72
|
+
results.push({
|
|
73
|
+
ruleId,
|
|
74
|
+
level: violation.severity,
|
|
75
|
+
message: {
|
|
76
|
+
text: `${violation.symbolName}: ${violation.message}`,
|
|
77
|
+
},
|
|
78
|
+
locations: [
|
|
79
|
+
{
|
|
80
|
+
physicalLocation: {
|
|
81
|
+
artifactLocation: {
|
|
82
|
+
uri: filepath,
|
|
83
|
+
},
|
|
84
|
+
region: {
|
|
85
|
+
startLine: violation.startLine,
|
|
86
|
+
endLine: violation.endLine,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const sarifReport = {
|
|
95
|
+
$schema: 'https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json',
|
|
96
|
+
version: '2.1.0',
|
|
97
|
+
runs: [
|
|
98
|
+
{
|
|
99
|
+
tool: {
|
|
100
|
+
driver: {
|
|
101
|
+
name: 'Lien Complexity Analyzer',
|
|
102
|
+
version: '1.0.0',
|
|
103
|
+
informationUri: 'https://github.com/liendev/lien',
|
|
104
|
+
rules,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
results,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
return JSON.stringify(sarifReport, null, 2);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=sarif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../../src/insights/formatters/sarif.ts"],"names":[],"mappings":"AA4DA;;GAEG;AACH,SAAS,SAAS,CAAC,UAAkB;IACnC,QAAQ,UAAU,EAAE,CAAC;QACnB,KAAK,WAAW,CAAC,CAAC,OAAO,gCAAgC,CAAC;QAC1D,KAAK,YAAY,CAAC,CAAC,OAAO,iCAAiC,CAAC;QAC5D,KAAK,iBAAiB,CAAC,CAAC,OAAO,2BAA2B,CAAC;QAC3D,KAAK,eAAe,CAAC,CAAC,OAAO,0BAA0B,CAAC;QACxD,OAAO,CAAC,CAAC,OAAO,sBAAsB,CAAC;IACzC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAwB;IACxD,MAAM,KAAK,GAAgB;QACzB;YACE,EAAE,EAAE,iCAAiC;YACrC,gBAAgB,EAAE;gBAChB,IAAI,EAAE,qBAAqB;aAC5B;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,yJAAyJ;aAChK;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,uIAAuI;aAC9I;SACF;QACD;YACE,EAAE,EAAE,gCAAgC;YACpC,gBAAgB,EAAE;gBAChB,IAAI,EAAE,kBAAkB;aACzB;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,yIAAyI;aAChJ;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,qHAAqH;aAC5H;SACF;QACD;YACE,EAAE,EAAE,2BAA2B;YAC/B,gBAAgB,EAAE;gBAChB,IAAI,EAAE,yBAAyB;aAChC;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,4GAA4G;aACnH;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,gGAAgG;aACvG;SACF;QACD;YACE,EAAE,EAAE,0BAA0B;YAC9B,gBAAgB,EAAE;gBAChB,IAAI,EAAE,0BAA0B;aACjC;YACD,eAAe,EAAE;gBACf,IAAI,EAAE,yIAAyI;aAChJ;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,mGAAmG;aAC1G;SACF;KACF,CAAC;IAEF,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,sCAAsC;IACtC,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAChE,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YAE/C,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM;gBACN,KAAK,EAAE,SAAS,CAAC,QAAQ;gBACzB,OAAO,EAAE;oBACP,IAAI,EAAE,GAAG,SAAS,CAAC,UAAU,KAAK,SAAS,CAAC,OAAO,EAAE;iBACtD;gBACD,SAAS,EAAE;oBACT;wBACE,gBAAgB,EAAE;4BAChB,gBAAgB,EAAE;gCAChB,GAAG,EAAE,QAAQ;6BACd;4BACD,MAAM,EAAE;gCACN,SAAS,EAAE,SAAS,CAAC,SAAS;gCAC9B,OAAO,EAAE,SAAS,CAAC,OAAO;6BAC3B;yBACF;qBACF;iBACF;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAgB;QAC/B,OAAO,EAAE,gGAAgG;QACzG,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE;YACJ;gBACE,IAAI,EAAE;oBACJ,MAAM,EAAE;wBACN,IAAI,EAAE,0BAA0B;wBAChC,OAAO,EAAE,OAAO;wBAChB,cAAc,EAAE,iCAAiC;wBACjD,KAAK;qBACN;iBACF;gBACD,OAAO;aACR;SACF;KACF,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/insights/formatters/text.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAA2C,MAAM,aAAa,CAAC;AA4IxF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAmDjE"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
/**
|
|
3
|
+
* Get the display label for a metric type
|
|
4
|
+
*/
|
|
5
|
+
function getMetricLabel(metricType) {
|
|
6
|
+
switch (metricType) {
|
|
7
|
+
case 'cognitive': return '🧠 Mental load';
|
|
8
|
+
case 'cyclomatic': return '🔀 Test paths';
|
|
9
|
+
case 'halstead_effort': return '⏱️ Time to understand';
|
|
10
|
+
case 'halstead_bugs': return '🐛 Estimated bugs';
|
|
11
|
+
default: return 'Complexity';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert Halstead effort to time in minutes
|
|
16
|
+
*/
|
|
17
|
+
function effortToMinutes(effort) {
|
|
18
|
+
return effort / 1080;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Format minutes as human-readable time
|
|
22
|
+
*/
|
|
23
|
+
function formatTime(minutes) {
|
|
24
|
+
if (minutes >= 60) {
|
|
25
|
+
const hours = Math.floor(minutes / 60);
|
|
26
|
+
const mins = Math.round(minutes % 60);
|
|
27
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
28
|
+
}
|
|
29
|
+
return `${Math.round(minutes)}m`;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Format Halstead details as additional lines
|
|
33
|
+
*/
|
|
34
|
+
function formatHalsteadDetails(violation) {
|
|
35
|
+
if (!violation.halsteadDetails)
|
|
36
|
+
return [];
|
|
37
|
+
const { volume, difficulty, effort, bugs } = violation.halsteadDetails;
|
|
38
|
+
const timeStr = formatTime(effortToMinutes(effort));
|
|
39
|
+
return [
|
|
40
|
+
chalk.dim(` 📊 Volume: ${Math.round(volume).toLocaleString()}, Difficulty: ${difficulty.toFixed(1)}`),
|
|
41
|
+
chalk.dim(` ⏱️ Time: ~${timeStr}, Est. bugs: ${bugs.toFixed(2)}`),
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
const metricFormatters = {
|
|
45
|
+
halstead_effort: (val, thresh) => ({
|
|
46
|
+
// val/thresh are already in minutes (human-scale)
|
|
47
|
+
complexity: '~' + formatTime(val),
|
|
48
|
+
threshold: formatTime(thresh),
|
|
49
|
+
}),
|
|
50
|
+
halstead_bugs: (val, thresh) => ({
|
|
51
|
+
complexity: val.toFixed(2),
|
|
52
|
+
threshold: thresh.toFixed(1),
|
|
53
|
+
}),
|
|
54
|
+
cyclomatic: (val, thresh) => ({
|
|
55
|
+
complexity: `${val} (needs ~${val} tests)`,
|
|
56
|
+
threshold: thresh.toString(),
|
|
57
|
+
}),
|
|
58
|
+
};
|
|
59
|
+
const defaultFormatter = (val, thresh) => ({
|
|
60
|
+
complexity: val.toString(),
|
|
61
|
+
threshold: thresh.toString(),
|
|
62
|
+
});
|
|
63
|
+
/**
|
|
64
|
+
* Format symbol name with appropriate suffix
|
|
65
|
+
*/
|
|
66
|
+
function formatSymbolDisplay(violation, isBold) {
|
|
67
|
+
const display = ['function', 'method'].includes(violation.symbolType)
|
|
68
|
+
? `${violation.symbolName}()`
|
|
69
|
+
: violation.symbolName;
|
|
70
|
+
return isBold ? chalk.bold(display) : display;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Format dependency impact information
|
|
74
|
+
*/
|
|
75
|
+
function formatDependencyInfo(fileData) {
|
|
76
|
+
const depCount = fileData.dependentCount ?? fileData.dependents.length;
|
|
77
|
+
if (depCount === 0)
|
|
78
|
+
return [];
|
|
79
|
+
const lines = [chalk.dim(` 📦 Imported by ${depCount} file${depCount !== 1 ? 's' : ''}`)];
|
|
80
|
+
if (fileData.dependentComplexityMetrics) {
|
|
81
|
+
const { averageComplexity, maxComplexity } = fileData.dependentComplexityMetrics;
|
|
82
|
+
lines.push(chalk.dim(` - Dependent avg complexity: ${averageComplexity}, max: ${maxComplexity}`));
|
|
83
|
+
}
|
|
84
|
+
return lines;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Format percentage over threshold
|
|
88
|
+
*/
|
|
89
|
+
function formatPercentageOver(complexity, threshold) {
|
|
90
|
+
if (threshold <= 0)
|
|
91
|
+
return 'N/A (invalid threshold)';
|
|
92
|
+
return `${Math.round(((complexity - threshold) / threshold) * 100)}% over threshold`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Format a single violation entry with its metadata
|
|
96
|
+
*/
|
|
97
|
+
function formatViolation(violation, fileData, colorFn, isBold) {
|
|
98
|
+
const symbolText = formatSymbolDisplay(violation, isBold);
|
|
99
|
+
const metricLabel = getMetricLabel(violation.metricType);
|
|
100
|
+
const formatter = metricFormatters[violation.metricType] || defaultFormatter;
|
|
101
|
+
const { complexity: complexityDisplay, threshold: thresholdDisplay } = formatter(violation.complexity, violation.threshold);
|
|
102
|
+
return [
|
|
103
|
+
colorFn(` ${violation.file}:${violation.startLine}`) + chalk.dim(' - ') + symbolText,
|
|
104
|
+
chalk.dim(` ${metricLabel}: ${complexityDisplay} (threshold: ${thresholdDisplay})`),
|
|
105
|
+
chalk.dim(` ⬆️ ${formatPercentageOver(violation.complexity, violation.threshold)}`),
|
|
106
|
+
...formatHalsteadDetails(violation),
|
|
107
|
+
...formatDependencyInfo(fileData),
|
|
108
|
+
chalk.dim(` ⚠️ Risk: ${fileData.riskLevel.toUpperCase()}`),
|
|
109
|
+
'',
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format complexity report as human-readable text with colors
|
|
114
|
+
*/
|
|
115
|
+
export function formatTextReport(report) {
|
|
116
|
+
const lines = [];
|
|
117
|
+
// Header
|
|
118
|
+
lines.push(chalk.bold('🔍 Complexity Analysis\n'));
|
|
119
|
+
// Summary
|
|
120
|
+
lines.push(chalk.bold('Summary:'));
|
|
121
|
+
lines.push(chalk.dim(' Files analyzed: ') + report.summary.filesAnalyzed.toString());
|
|
122
|
+
const errorText = `${report.summary.bySeverity.error} error${report.summary.bySeverity.error !== 1 ? 's' : ''}`;
|
|
123
|
+
const warningText = `${report.summary.bySeverity.warning} warning${report.summary.bySeverity.warning !== 1 ? 's' : ''}`;
|
|
124
|
+
lines.push(chalk.dim(' Violations: ') + `${report.summary.totalViolations} (${errorText}, ${warningText})`);
|
|
125
|
+
lines.push(chalk.dim(' Average complexity: ') + report.summary.avgComplexity.toString());
|
|
126
|
+
lines.push(chalk.dim(' Max complexity: ') + report.summary.maxComplexity.toString());
|
|
127
|
+
lines.push('');
|
|
128
|
+
// Group violations by file
|
|
129
|
+
const filesWithViolations = Object.entries(report.files)
|
|
130
|
+
.filter(([_, data]) => data.violations.length > 0)
|
|
131
|
+
.sort((a, b) => b[1].violations.length - a[1].violations.length);
|
|
132
|
+
if (filesWithViolations.length === 0) {
|
|
133
|
+
lines.push(chalk.green('✓ No violations found!'));
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
// Errors section
|
|
137
|
+
const errors = filesWithViolations.flatMap(([file, data]) => data.violations.filter(v => v.severity === 'error').map(v => ({ file, ...v })));
|
|
138
|
+
if (errors.length > 0) {
|
|
139
|
+
lines.push(chalk.red.bold('❌ Errors:\n'));
|
|
140
|
+
for (const error of errors) {
|
|
141
|
+
lines.push(...formatViolation(error, report.files[error.file], chalk.red, true));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Warnings section
|
|
145
|
+
const warnings = filesWithViolations.flatMap(([file, data]) => data.violations.filter(v => v.severity === 'warning').map(v => ({ file, ...v })));
|
|
146
|
+
if (warnings.length > 0) {
|
|
147
|
+
lines.push(chalk.yellow.bold('⚠️ Warnings:\n'));
|
|
148
|
+
for (const warning of warnings) {
|
|
149
|
+
lines.push(...formatViolation(warning, report.files[warning.file], chalk.yellow, false));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return lines.join('\n');
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/insights/formatters/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complexity analysis types for code quality insights
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Risk level ordering for comparison operations.
|
|
6
|
+
* Higher value = higher risk.
|
|
7
|
+
*/
|
|
8
|
+
export declare const RISK_ORDER: {
|
|
9
|
+
readonly low: 0;
|
|
10
|
+
readonly medium: 1;
|
|
11
|
+
readonly high: 2;
|
|
12
|
+
readonly critical: 3;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Risk level type derived from RISK_ORDER keys
|
|
16
|
+
*/
|
|
17
|
+
export type RiskLevel = keyof typeof RISK_ORDER;
|
|
18
|
+
/**
|
|
19
|
+
* Type of complexity metric being measured
|
|
20
|
+
*/
|
|
21
|
+
export type ComplexityMetricType = 'cyclomatic' | 'cognitive' | 'halstead_effort' | 'halstead_bugs';
|
|
22
|
+
/**
|
|
23
|
+
* Halstead metric details for Halstead-type violations
|
|
24
|
+
*/
|
|
25
|
+
export interface HalsteadDetails {
|
|
26
|
+
volume: number;
|
|
27
|
+
difficulty: number;
|
|
28
|
+
effort: number;
|
|
29
|
+
bugs: number;
|
|
30
|
+
}
|
|
31
|
+
export interface ComplexityViolation {
|
|
32
|
+
filepath: string;
|
|
33
|
+
startLine: number;
|
|
34
|
+
endLine: number;
|
|
35
|
+
symbolName: string;
|
|
36
|
+
symbolType: 'function' | 'method' | 'class' | 'file';
|
|
37
|
+
language: string;
|
|
38
|
+
complexity: number;
|
|
39
|
+
threshold: number;
|
|
40
|
+
severity: 'warning' | 'error';
|
|
41
|
+
message: string;
|
|
42
|
+
/** Type of complexity metric (cyclomatic vs cognitive vs halstead) */
|
|
43
|
+
metricType: ComplexityMetricType;
|
|
44
|
+
/** Halstead-specific details when metricType is halstead_* */
|
|
45
|
+
halsteadDetails?: HalsteadDetails;
|
|
46
|
+
}
|
|
47
|
+
export interface FileComplexityData {
|
|
48
|
+
violations: ComplexityViolation[];
|
|
49
|
+
dependents: string[];
|
|
50
|
+
dependentCount?: number;
|
|
51
|
+
/** Test files associated with this source file. TODO: Populate when test-to-code mapping is implemented */
|
|
52
|
+
testAssociations: string[];
|
|
53
|
+
riskLevel: RiskLevel;
|
|
54
|
+
dependentComplexityMetrics?: {
|
|
55
|
+
averageComplexity: number;
|
|
56
|
+
maxComplexity: number;
|
|
57
|
+
filesWithComplexityData: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export interface ComplexityReport {
|
|
61
|
+
summary: {
|
|
62
|
+
filesAnalyzed: number;
|
|
63
|
+
totalViolations: number;
|
|
64
|
+
bySeverity: {
|
|
65
|
+
error: number;
|
|
66
|
+
warning: number;
|
|
67
|
+
};
|
|
68
|
+
avgComplexity: number;
|
|
69
|
+
maxComplexity: number;
|
|
70
|
+
};
|
|
71
|
+
files: Record<string, FileComplexityData>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/insights/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;CAAuD,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,UAAU,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,WAAW,GAAG,iBAAiB,GAAG,eAAe,CAAC;AAEpG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,UAAU,EAAE,oBAAoB,CAAC;IACjC,8DAA8D;IAC9D,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,2GAA2G;IAC3G,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,0BAA0B,CAAC,EAAE;QAC3B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,uBAAuB,EAAE,MAAM,CAAC;KACjC,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;QACxB,UAAU,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/C,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;CAC3C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complexity analysis types for code quality insights
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Risk level ordering for comparison operations.
|
|
6
|
+
* Higher value = higher risk.
|
|
7
|
+
*/
|
|
8
|
+
export const RISK_ORDER = { low: 0, medium: 1, high: 2, critical: 3 };
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/insights/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAW,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @liendev/core types
|
|
3
|
+
*
|
|
4
|
+
* All shared types for Lien - single source of truth
|
|
5
|
+
*/
|
|
6
|
+
export type { ChunkMetadata, CodeChunk, ScanOptions } from '../indexer/types.js';
|
|
7
|
+
export type { SearchResult, VectorDBInterface } from '../vectordb/types.js';
|
|
8
|
+
export type { EmbeddingService } from '../embeddings/types.js';
|
|
9
|
+
export type { LienConfig, LegacyLienConfig, FrameworkConfig, FrameworkInstance } from '../config/schema.js';
|
|
10
|
+
export type { GitState } from '../git/tracker.js';
|
|
11
|
+
export type { RelevanceCategory } from '../vectordb/relevance.js';
|
|
12
|
+
export type { RiskLevel, ComplexityMetricType, HalsteadDetails, ComplexityViolation, FileComplexityData, ComplexityReport, } from '../insights/types.js';
|
|
13
|
+
export { RISK_ORDER } from '../insights/types.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACjF,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC5E,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,YAAY,EACV,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH,gCAAgC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path matching utilities for dependency analysis.
|
|
3
|
+
*
|
|
4
|
+
* These functions handle path normalization and matching logic used by
|
|
5
|
+
* dependency analysis to find reverse dependencies.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Normalizes a file path for comparison.
|
|
9
|
+
*
|
|
10
|
+
* - Removes quotes and trims whitespace
|
|
11
|
+
* - Converts backslashes to forward slashes
|
|
12
|
+
* - Strips file extensions (.ts, .tsx, .js, .jsx)
|
|
13
|
+
* - Converts absolute paths to relative (if within workspace root)
|
|
14
|
+
*
|
|
15
|
+
* @param path - The path to normalize
|
|
16
|
+
* @param workspaceRoot - The workspace root directory (normalized with forward slashes)
|
|
17
|
+
* @returns Normalized path
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizePath(path: string, workspaceRoot: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Checks if a pattern matches at path component boundaries.
|
|
22
|
+
*
|
|
23
|
+
* Ensures matches occur at proper boundaries (/, .) to avoid false positives like:
|
|
24
|
+
* - "logger" matching "logger-utils" ❌
|
|
25
|
+
* - "src/logger" matching "src/logger-service" ❌
|
|
26
|
+
*
|
|
27
|
+
* @param str - The string to search in
|
|
28
|
+
* @param pattern - The pattern to search for
|
|
29
|
+
* @returns True if pattern matches at a boundary
|
|
30
|
+
*/
|
|
31
|
+
export declare function matchesAtBoundary(str: string, pattern: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Determines if an import path matches a target file path.
|
|
34
|
+
*
|
|
35
|
+
* Handles various matching strategies:
|
|
36
|
+
* 1. Exact match
|
|
37
|
+
* 2. Target path appears in import (at boundaries)
|
|
38
|
+
* 3. Import path appears in target (at boundaries)
|
|
39
|
+
* 4. Relative imports (./logger vs src/utils/logger)
|
|
40
|
+
*
|
|
41
|
+
* @param normalizedImport - Normalized import path
|
|
42
|
+
* @param normalizedTarget - Normalized target file path
|
|
43
|
+
* @returns True if the import matches the target file
|
|
44
|
+
*/
|
|
45
|
+
export declare function matchesFile(normalizedImport: string, normalizedTarget: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Gets a canonical path representation (relative to workspace, with extension).
|
|
48
|
+
*
|
|
49
|
+
* @param filepath - The file path to canonicalize
|
|
50
|
+
* @param workspaceRoot - The workspace root directory (normalized with forward slashes)
|
|
51
|
+
* @returns Canonical path
|
|
52
|
+
*/
|
|
53
|
+
export declare function getCanonicalPath(filepath: string, workspaceRoot: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Determines if a file is a test file based on naming conventions.
|
|
56
|
+
*
|
|
57
|
+
* Uses precise regex patterns to avoid false positives:
|
|
58
|
+
* - Files with .test. or .spec. extensions (e.g., foo.test.ts, bar.spec.js)
|
|
59
|
+
* - Files in test/, tests/, or __tests__/ directories
|
|
60
|
+
*
|
|
61
|
+
* Avoids false positives like:
|
|
62
|
+
* - contest.ts (contains ".test." but isn't a test)
|
|
63
|
+
* - latest/config.ts (contains "/test/" but isn't a test)
|
|
64
|
+
*
|
|
65
|
+
* @param filepath - The file path to check
|
|
66
|
+
* @returns True if the file is a test file
|
|
67
|
+
*/
|
|
68
|
+
export declare function isTestFile(filepath: string): boolean;
|
|
69
|
+
//# sourceMappingURL=path-matching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-matching.d.ts","sourceRoot":"","sources":["../../src/utils/path-matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAazE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAcvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAuBvF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAMhF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGpD"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared path matching utilities for dependency analysis.
|
|
3
|
+
*
|
|
4
|
+
* These functions handle path normalization and matching logic used by
|
|
5
|
+
* dependency analysis to find reverse dependencies.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Normalizes a file path for comparison.
|
|
9
|
+
*
|
|
10
|
+
* - Removes quotes and trims whitespace
|
|
11
|
+
* - Converts backslashes to forward slashes
|
|
12
|
+
* - Strips file extensions (.ts, .tsx, .js, .jsx)
|
|
13
|
+
* - Converts absolute paths to relative (if within workspace root)
|
|
14
|
+
*
|
|
15
|
+
* @param path - The path to normalize
|
|
16
|
+
* @param workspaceRoot - The workspace root directory (normalized with forward slashes)
|
|
17
|
+
* @returns Normalized path
|
|
18
|
+
*/
|
|
19
|
+
export function normalizePath(path, workspaceRoot) {
|
|
20
|
+
let normalized = path.replace(/['"]/g, '').trim().replace(/\\/g, '/');
|
|
21
|
+
// Normalize extensions: .ts/.tsx/.js/.jsx → all treated as equivalent
|
|
22
|
+
// This handles TypeScript's ESM requirement of .js imports for .ts files
|
|
23
|
+
normalized = normalized.replace(/\.(ts|tsx|js|jsx)$/, '');
|
|
24
|
+
// Normalize to relative path if it starts with workspace root
|
|
25
|
+
if (normalized.startsWith(workspaceRoot + '/')) {
|
|
26
|
+
normalized = normalized.substring(workspaceRoot.length + 1);
|
|
27
|
+
}
|
|
28
|
+
return normalized;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Checks if a pattern matches at path component boundaries.
|
|
32
|
+
*
|
|
33
|
+
* Ensures matches occur at proper boundaries (/, .) to avoid false positives like:
|
|
34
|
+
* - "logger" matching "logger-utils" ❌
|
|
35
|
+
* - "src/logger" matching "src/logger-service" ❌
|
|
36
|
+
*
|
|
37
|
+
* @param str - The string to search in
|
|
38
|
+
* @param pattern - The pattern to search for
|
|
39
|
+
* @returns True if pattern matches at a boundary
|
|
40
|
+
*/
|
|
41
|
+
export function matchesAtBoundary(str, pattern) {
|
|
42
|
+
const index = str.indexOf(pattern);
|
|
43
|
+
if (index === -1)
|
|
44
|
+
return false;
|
|
45
|
+
// Check character before match (must be start or path separator)
|
|
46
|
+
const charBefore = index > 0 ? str[index - 1] : '/';
|
|
47
|
+
if (charBefore !== '/' && index !== 0)
|
|
48
|
+
return false;
|
|
49
|
+
// Check character after match (must be end or path separator)
|
|
50
|
+
// Extensions are already stripped during normalization, so we only need to check for '/' as a valid path separator
|
|
51
|
+
const endIndex = index + pattern.length;
|
|
52
|
+
if (endIndex === str.length)
|
|
53
|
+
return true;
|
|
54
|
+
const charAfter = str[endIndex];
|
|
55
|
+
return charAfter === '/';
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Determines if an import path matches a target file path.
|
|
59
|
+
*
|
|
60
|
+
* Handles various matching strategies:
|
|
61
|
+
* 1. Exact match
|
|
62
|
+
* 2. Target path appears in import (at boundaries)
|
|
63
|
+
* 3. Import path appears in target (at boundaries)
|
|
64
|
+
* 4. Relative imports (./logger vs src/utils/logger)
|
|
65
|
+
*
|
|
66
|
+
* @param normalizedImport - Normalized import path
|
|
67
|
+
* @param normalizedTarget - Normalized target file path
|
|
68
|
+
* @returns True if the import matches the target file
|
|
69
|
+
*/
|
|
70
|
+
export function matchesFile(normalizedImport, normalizedTarget) {
|
|
71
|
+
// Exact match
|
|
72
|
+
if (normalizedImport === normalizedTarget)
|
|
73
|
+
return true;
|
|
74
|
+
// Strategy 1: Check if target path appears in import at path boundaries
|
|
75
|
+
if (matchesAtBoundary(normalizedImport, normalizedTarget)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
// Strategy 2: Check if import path appears in target (for longer target paths)
|
|
79
|
+
if (matchesAtBoundary(normalizedTarget, normalizedImport)) {
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
// Strategy 3: Handle relative imports (./logger vs src/utils/logger)
|
|
83
|
+
// Remove leading ./ and ../ from import
|
|
84
|
+
const cleanedImport = normalizedImport.replace(/^(\.\.?\/)+/, '');
|
|
85
|
+
if (matchesAtBoundary(cleanedImport, normalizedTarget) ||
|
|
86
|
+
matchesAtBoundary(normalizedTarget, cleanedImport)) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Gets a canonical path representation (relative to workspace, with extension).
|
|
93
|
+
*
|
|
94
|
+
* @param filepath - The file path to canonicalize
|
|
95
|
+
* @param workspaceRoot - The workspace root directory (normalized with forward slashes)
|
|
96
|
+
* @returns Canonical path
|
|
97
|
+
*/
|
|
98
|
+
export function getCanonicalPath(filepath, workspaceRoot) {
|
|
99
|
+
let canonical = filepath.replace(/\\/g, '/');
|
|
100
|
+
if (canonical.startsWith(workspaceRoot + '/')) {
|
|
101
|
+
canonical = canonical.substring(workspaceRoot.length + 1);
|
|
102
|
+
}
|
|
103
|
+
return canonical;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Determines if a file is a test file based on naming conventions.
|
|
107
|
+
*
|
|
108
|
+
* Uses precise regex patterns to avoid false positives:
|
|
109
|
+
* - Files with .test. or .spec. extensions (e.g., foo.test.ts, bar.spec.js)
|
|
110
|
+
* - Files in test/, tests/, or __tests__/ directories
|
|
111
|
+
*
|
|
112
|
+
* Avoids false positives like:
|
|
113
|
+
* - contest.ts (contains ".test." but isn't a test)
|
|
114
|
+
* - latest/config.ts (contains "/test/" but isn't a test)
|
|
115
|
+
*
|
|
116
|
+
* @param filepath - The file path to check
|
|
117
|
+
* @returns True if the file is a test file
|
|
118
|
+
*/
|
|
119
|
+
export function isTestFile(filepath) {
|
|
120
|
+
return /\.(test|spec)\.[^/]+$/.test(filepath) ||
|
|
121
|
+
/(^|[/\\])(test|tests|__tests__)[/\\]/.test(filepath);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=path-matching.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-matching.js","sourceRoot":"","sources":["../../src/utils/path-matching.ts"],"names":[],"mappings":"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"}
|