@liendev/parser 0.39.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/dist/ast/chunker.d.ts +30 -0
- package/dist/ast/chunker.d.ts.map +1 -0
- package/dist/ast/chunker.js +310 -0
- package/dist/ast/chunker.js.map +1 -0
- package/dist/ast/complexity/cognitive.d.ts +16 -0
- package/dist/ast/complexity/cognitive.d.ts.map +1 -0
- package/dist/ast/complexity/cognitive.js +137 -0
- package/dist/ast/complexity/cognitive.js.map +1 -0
- package/dist/ast/complexity/cyclomatic.d.ts +12 -0
- package/dist/ast/complexity/cyclomatic.d.ts.map +1 -0
- package/dist/ast/complexity/cyclomatic.js +54 -0
- package/dist/ast/complexity/cyclomatic.js.map +1 -0
- package/dist/ast/complexity/halstead.d.ts +56 -0
- package/dist/ast/complexity/halstead.d.ts.map +1 -0
- package/dist/ast/complexity/halstead.js +196 -0
- package/dist/ast/complexity/halstead.js.map +1 -0
- package/dist/ast/complexity/index.d.ts +13 -0
- package/dist/ast/complexity/index.d.ts.map +1 -0
- package/dist/ast/complexity/index.js +12 -0
- package/dist/ast/complexity/index.js.map +1 -0
- package/dist/ast/extractors/index.d.ts +35 -0
- package/dist/ast/extractors/index.d.ts.map +1 -0
- package/dist/ast/extractors/index.js +41 -0
- package/dist/ast/extractors/index.js.map +1 -0
- package/dist/ast/extractors/symbol-helpers.d.ts +20 -0
- package/dist/ast/extractors/symbol-helpers.d.ts.map +1 -0
- package/dist/ast/extractors/symbol-helpers.js +58 -0
- package/dist/ast/extractors/symbol-helpers.js.map +1 -0
- package/dist/ast/extractors/types.d.ts +108 -0
- package/dist/ast/extractors/types.d.ts.map +1 -0
- package/dist/ast/extractors/types.js +2 -0
- package/dist/ast/extractors/types.js.map +1 -0
- package/dist/ast/languages/javascript.d.ts +134 -0
- package/dist/ast/languages/javascript.d.ts.map +1 -0
- package/dist/ast/languages/javascript.js +787 -0
- package/dist/ast/languages/javascript.js.map +1 -0
- package/dist/ast/languages/php.d.ts +84 -0
- package/dist/ast/languages/php.d.ts.map +1 -0
- package/dist/ast/languages/php.js +452 -0
- package/dist/ast/languages/php.js.map +1 -0
- package/dist/ast/languages/python.d.ts +96 -0
- package/dist/ast/languages/python.d.ts.map +1 -0
- package/dist/ast/languages/python.js +448 -0
- package/dist/ast/languages/python.js.map +1 -0
- package/dist/ast/languages/registry.d.ts +30 -0
- package/dist/ast/languages/registry.d.ts.map +1 -0
- package/dist/ast/languages/registry.js +95 -0
- package/dist/ast/languages/registry.js.map +1 -0
- package/dist/ast/languages/rust.d.ts +113 -0
- package/dist/ast/languages/rust.d.ts.map +1 -0
- package/dist/ast/languages/rust.js +614 -0
- package/dist/ast/languages/rust.js.map +1 -0
- package/dist/ast/languages/types.d.ts +52 -0
- package/dist/ast/languages/types.d.ts.map +1 -0
- package/dist/ast/languages/types.js +2 -0
- package/dist/ast/languages/types.js.map +1 -0
- package/dist/ast/languages/typescript.d.ts +3 -0
- package/dist/ast/languages/typescript.d.ts.map +1 -0
- package/dist/ast/languages/typescript.js +134 -0
- package/dist/ast/languages/typescript.js.map +1 -0
- package/dist/ast/parser.d.ts +29 -0
- package/dist/ast/parser.d.ts.map +1 -0
- package/dist/ast/parser.js +67 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/ast/symbols.d.ts +74 -0
- package/dist/ast/symbols.d.ts.map +1 -0
- package/dist/ast/symbols.js +171 -0
- package/dist/ast/symbols.js.map +1 -0
- package/dist/ast/traversers/index.d.ts +19 -0
- package/dist/ast/traversers/index.d.ts.map +1 -0
- package/dist/ast/traversers/index.js +21 -0
- package/dist/ast/traversers/index.js.map +1 -0
- package/dist/ast/traversers/types.d.ts +98 -0
- package/dist/ast/traversers/types.d.ts.map +1 -0
- package/dist/ast/traversers/types.js +2 -0
- package/dist/ast/traversers/types.js.map +1 -0
- package/dist/ast/types.d.ts +54 -0
- package/dist/ast/types.d.ts.map +1 -0
- package/dist/ast/types.js +2 -0
- package/dist/ast/types.js.map +1 -0
- package/dist/chunk-only-index.d.ts +25 -0
- package/dist/chunk-only-index.d.ts.map +1 -0
- package/dist/chunk-only-index.js +107 -0
- package/dist/chunk-only-index.js.map +1 -0
- package/dist/chunker.d.ts +12 -0
- package/dist/chunker.d.ts.map +1 -0
- package/dist/chunker.js +98 -0
- package/dist/chunker.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +11 -0
- package/dist/constants.js.map +1 -0
- package/dist/content-hash.d.ts +20 -0
- package/dist/content-hash.d.ts.map +1 -0
- package/dist/content-hash.js +91 -0
- package/dist/content-hash.js.map +1 -0
- package/dist/dependency-analyzer.d.ts +79 -0
- package/dist/dependency-analyzer.d.ts.map +1 -0
- package/dist/dependency-analyzer.js +408 -0
- package/dist/dependency-analyzer.js.map +1 -0
- package/dist/ecosystem-presets.d.ts +32 -0
- package/dist/ecosystem-presets.d.ts.map +1 -0
- package/dist/ecosystem-presets.js +325 -0
- package/dist/ecosystem-presets.js.map +1 -0
- package/dist/gitignore.d.ts +22 -0
- package/dist/gitignore.d.ts.map +1 -0
- package/dist/gitignore.js +128 -0
- package/dist/gitignore.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -0
- package/dist/insights/chunk-complexity.d.ts +89 -0
- package/dist/insights/chunk-complexity.d.ts.map +1 -0
- package/dist/insights/chunk-complexity.js +332 -0
- package/dist/insights/chunk-complexity.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/json-template-chunker.d.ts +12 -0
- package/dist/json-template-chunker.d.ts.map +1 -0
- package/dist/json-template-chunker.js +87 -0
- package/dist/json-template-chunker.js.map +1 -0
- package/dist/liquid-chunker.d.ts +16 -0
- package/dist/liquid-chunker.d.ts.map +1 -0
- package/dist/liquid-chunker.js +274 -0
- package/dist/liquid-chunker.js.map +1 -0
- package/dist/scanner.d.ts +16 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +95 -0
- package/dist/scanner.js.map +1 -0
- package/dist/symbol-extractor.d.ts +18 -0
- package/dist/symbol-extractor.d.ts.map +1 -0
- package/dist/symbol-extractor.js +343 -0
- package/dist/symbol-extractor.js.map +1 -0
- package/dist/test-associations.d.ts +16 -0
- package/dist/test-associations.d.ts.map +1 -0
- package/dist/test-associations.js +43 -0
- package/dist/test-associations.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/path-matching.d.ts +71 -0
- package/dist/utils/path-matching.d.ts.map +1 -0
- package/dist/utils/path-matching.js +258 -0
- package/dist/utils/path-matching.js.map +1 -0
- package/dist/utils/repo-id.d.ts +6 -0
- package/dist/utils/repo-id.d.ts.map +1 -0
- package/dist/utils/repo-id.js +12 -0
- package/dist/utils/repo-id.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { CodeChunk } from './types.js';
|
|
2
|
+
import type { RiskLevel } from './insights/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Risk level thresholds for dependent count.
|
|
5
|
+
* Based on impact analysis: more dependents = higher risk of breaking changes.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEPENDENT_COUNT_THRESHOLDS: {
|
|
8
|
+
readonly LOW: 5;
|
|
9
|
+
readonly MEDIUM: 15;
|
|
10
|
+
readonly HIGH: 30;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Complexity thresholds for risk assessment.
|
|
14
|
+
* Based on cyclomatic complexity: higher complexity = harder to change safely.
|
|
15
|
+
*/
|
|
16
|
+
export declare const COMPLEXITY_THRESHOLDS: {
|
|
17
|
+
readonly HIGH_COMPLEXITY_DEPENDENT: 10;
|
|
18
|
+
readonly CRITICAL_AVG: 15;
|
|
19
|
+
readonly CRITICAL_MAX: 25;
|
|
20
|
+
readonly HIGH_AVG: 10;
|
|
21
|
+
readonly HIGH_MAX: 20;
|
|
22
|
+
readonly MEDIUM_AVG: 6;
|
|
23
|
+
readonly MEDIUM_MAX: 15;
|
|
24
|
+
};
|
|
25
|
+
export interface FileComplexityInfo {
|
|
26
|
+
filepath: string;
|
|
27
|
+
avgComplexity: number;
|
|
28
|
+
maxComplexity: number;
|
|
29
|
+
complexityScore: number;
|
|
30
|
+
chunksWithComplexity: number;
|
|
31
|
+
}
|
|
32
|
+
export interface DependencyAnalysisResult {
|
|
33
|
+
dependents: Array<{
|
|
34
|
+
filepath: string;
|
|
35
|
+
isTestFile: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
dependentCount: number;
|
|
38
|
+
riskLevel: RiskLevel;
|
|
39
|
+
complexityMetrics?: {
|
|
40
|
+
averageComplexity: number;
|
|
41
|
+
maxComplexity: number;
|
|
42
|
+
filesWithComplexityData: number;
|
|
43
|
+
highComplexityDependents: Array<{
|
|
44
|
+
filepath: string;
|
|
45
|
+
maxComplexity: number;
|
|
46
|
+
avgComplexity: number;
|
|
47
|
+
}>;
|
|
48
|
+
complexityRiskBoost: RiskLevel;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Check if a single chunk imports from the given source path.
|
|
53
|
+
* Checks both `importedSymbols` keys and raw `imports` array.
|
|
54
|
+
*/
|
|
55
|
+
export declare function chunkImportsFrom(chunk: CodeChunk, sourcePath: string, normalizePathCached: (path: string) => string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Group chunks by their normalized file path.
|
|
58
|
+
*/
|
|
59
|
+
export declare function groupChunksByNormalizedPath(chunks: CodeChunk[], normalizePathCached: (path: string) => string): Map<string, CodeChunk[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if a file (given its chunks) is a re-exporter from a source path.
|
|
62
|
+
* A re-exporter has both imports from the source and exports.
|
|
63
|
+
*/
|
|
64
|
+
export declare function fileIsReExporter(chunks: CodeChunk[], sourcePath: string, normalizePathCached: (path: string) => string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Find transitive dependents through re-export chains using BFS.
|
|
67
|
+
* Bounded to MAX_REEXPORT_DEPTH.
|
|
68
|
+
*/
|
|
69
|
+
export declare function findTransitiveDependents(reExporterPaths: string[], importIndex: Map<string, CodeChunk[]>, normalizedTarget: string, normalizePathCached: (path: string) => string, allChunksByFile: Map<string, CodeChunk[]>, existingFiles: Set<string>): CodeChunk[];
|
|
70
|
+
/**
|
|
71
|
+
* Analyzes dependencies for a given file by finding all chunks that import it.
|
|
72
|
+
*
|
|
73
|
+
* @param targetFilepath - The file to analyze dependencies for
|
|
74
|
+
* @param allChunks - All chunks from the vector database
|
|
75
|
+
* @param workspaceRoot - The workspace root directory
|
|
76
|
+
* @returns Dependency analysis including dependents, count, and risk level
|
|
77
|
+
*/
|
|
78
|
+
export declare function analyzeDependencies(targetFilepath: string, allChunks: CodeChunk[], workspaceRoot: string): DependencyAnalysisResult;
|
|
79
|
+
//# sourceMappingURL=dependency-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-analyzer.d.ts","sourceRoot":"","sources":["../src/dependency-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAIrD;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;CAI7B,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;CAQxB,CAAC;AAEX,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,KAAK,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,SAAS,CAAC;IACrB,iBAAiB,CAAC,EAAE;QAClB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,uBAAuB,EAAE,MAAM,CAAC;QAChC,wBAAwB,EAAE,KAAK,CAAC;YAC9B,QAAQ,EAAE,MAAM,CAAC;YACjB,aAAa,EAAE,MAAM,CAAC;YACtB,aAAa,EAAE,MAAM,CAAC;SACvB,CAAC,CAAC;QACH,mBAAmB,EAAE,SAAS,CAAC;KAChC,CAAC;CACH;AAoPD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,EAClB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC5C,OAAO,CAcT;AASD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,EAAE,EACnB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC5C,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAY1B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EAAE,EACnB,UAAU,EAAE,MAAM,EAClB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC5C,OAAO,CAaT;AAsDD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,eAAe,EAAE,MAAM,EAAE,EACzB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EACrC,gBAAgB,EAAE,MAAM,EACxB,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAC7C,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,EACzC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB,SAAS,EAAE,CA+Bb;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,SAAS,EAAE,EACtB,aAAa,EAAE,MAAM,GACpB,wBAAwB,CAqE1B"}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { normalizePath, getCanonicalPath, matchesFile, isTestFile } from './utils/path-matching.js';
|
|
2
|
+
import { RISK_ORDER } from './insights/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Risk level thresholds for dependent count.
|
|
5
|
+
* Based on impact analysis: more dependents = higher risk of breaking changes.
|
|
6
|
+
*/
|
|
7
|
+
export const DEPENDENT_COUNT_THRESHOLDS = {
|
|
8
|
+
LOW: 5, // Few dependents, safe to change
|
|
9
|
+
MEDIUM: 15, // Moderate impact, review dependents
|
|
10
|
+
HIGH: 30, // High impact, careful planning needed
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Complexity thresholds for risk assessment.
|
|
14
|
+
* Based on cyclomatic complexity: higher complexity = harder to change safely.
|
|
15
|
+
*/
|
|
16
|
+
export const COMPLEXITY_THRESHOLDS = {
|
|
17
|
+
HIGH_COMPLEXITY_DEPENDENT: 10, // Individual file is complex
|
|
18
|
+
CRITICAL_AVG: 15, // Average complexity indicates systemic complexity
|
|
19
|
+
CRITICAL_MAX: 25, // Peak complexity indicates hotspot
|
|
20
|
+
HIGH_AVG: 10, // Moderately complex on average
|
|
21
|
+
HIGH_MAX: 20, // Some complex functions exist
|
|
22
|
+
MEDIUM_AVG: 6, // Slightly above simple code
|
|
23
|
+
MEDIUM_MAX: 15, // Occasional branching
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Creates a cached path normalizer to avoid repeated string operations.
|
|
27
|
+
*
|
|
28
|
+
* @param workspaceRoot - The workspace root directory for path normalization
|
|
29
|
+
* @returns A function that normalizes and caches file paths
|
|
30
|
+
*/
|
|
31
|
+
function createPathNormalizer(workspaceRoot) {
|
|
32
|
+
const cache = new Map();
|
|
33
|
+
return (path) => {
|
|
34
|
+
const cached = cache.get(path);
|
|
35
|
+
if (cached !== undefined)
|
|
36
|
+
return cached;
|
|
37
|
+
const normalized = normalizePath(path, workspaceRoot);
|
|
38
|
+
cache.set(path, normalized);
|
|
39
|
+
return normalized;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Builds an index mapping normalized import paths to chunks that import them.
|
|
44
|
+
* Enables O(1) lookup instead of O(n*m) iteration.
|
|
45
|
+
*
|
|
46
|
+
* @param chunks - All chunks from the vector database
|
|
47
|
+
* @param normalizePathCached - Cached path normalization function
|
|
48
|
+
* @returns Map of normalized import paths to chunks that import them
|
|
49
|
+
*/
|
|
50
|
+
function buildImportIndex(chunks, normalizePathCached) {
|
|
51
|
+
const importIndex = new Map();
|
|
52
|
+
for (const chunk of chunks) {
|
|
53
|
+
const imports = chunk.metadata.imports || [];
|
|
54
|
+
for (const imp of imports) {
|
|
55
|
+
const normalizedImport = normalizePathCached(imp);
|
|
56
|
+
let chunkList = importIndex.get(normalizedImport);
|
|
57
|
+
if (!chunkList) {
|
|
58
|
+
chunkList = [];
|
|
59
|
+
importIndex.set(normalizedImport, chunkList);
|
|
60
|
+
}
|
|
61
|
+
chunkList.push(chunk);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return importIndex;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Finds all chunks that import the target file using index + fuzzy matching.
|
|
68
|
+
*
|
|
69
|
+
* @param normalizedTarget - The normalized path of the target file
|
|
70
|
+
* @param importIndex - Index mapping import paths to chunks
|
|
71
|
+
* @returns Array of chunks that import the target file (deduplicated)
|
|
72
|
+
*/
|
|
73
|
+
function findDependentChunks(normalizedTarget, importIndex) {
|
|
74
|
+
const dependentChunks = [];
|
|
75
|
+
const seenChunkIds = new Set();
|
|
76
|
+
const addChunk = (chunk) => {
|
|
77
|
+
const chunkId = `${chunk.metadata.file}:${chunk.metadata.startLine}-${chunk.metadata.endLine}`;
|
|
78
|
+
if (!seenChunkIds.has(chunkId)) {
|
|
79
|
+
dependentChunks.push(chunk);
|
|
80
|
+
seenChunkIds.add(chunkId);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
// Direct index lookup (fastest path)
|
|
84
|
+
const directMatches = importIndex.get(normalizedTarget);
|
|
85
|
+
if (directMatches) {
|
|
86
|
+
for (const chunk of directMatches) {
|
|
87
|
+
addChunk(chunk);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Fuzzy match for relative imports and path variations
|
|
91
|
+
// Note: This is O(M) where M = unique import paths. For large codebases with many
|
|
92
|
+
// violations, consider caching fuzzy match results at a higher level.
|
|
93
|
+
for (const [normalizedImport, chunks] of importIndex.entries()) {
|
|
94
|
+
if (normalizedImport !== normalizedTarget && matchesFile(normalizedImport, normalizedTarget)) {
|
|
95
|
+
for (const chunk of chunks) {
|
|
96
|
+
addChunk(chunk);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return dependentChunks;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Groups chunks by their canonical file path.
|
|
104
|
+
*
|
|
105
|
+
* @param chunks - Array of chunks to group
|
|
106
|
+
* @param workspaceRoot - The workspace root directory
|
|
107
|
+
* @returns Map of canonical file paths to their chunks
|
|
108
|
+
*/
|
|
109
|
+
function groupChunksByFile(chunks, workspaceRoot) {
|
|
110
|
+
const chunksByFile = new Map();
|
|
111
|
+
for (const chunk of chunks) {
|
|
112
|
+
const canonical = getCanonicalPath(chunk.metadata.file, workspaceRoot);
|
|
113
|
+
let existing = chunksByFile.get(canonical);
|
|
114
|
+
if (!existing) {
|
|
115
|
+
existing = [];
|
|
116
|
+
chunksByFile.set(canonical, existing);
|
|
117
|
+
}
|
|
118
|
+
existing.push(chunk);
|
|
119
|
+
}
|
|
120
|
+
return chunksByFile;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Calculates complexity metrics for each file based on its chunks.
|
|
124
|
+
*
|
|
125
|
+
* @param chunksByFile - Map of file paths to their chunks
|
|
126
|
+
* @returns Array of complexity info for files with complexity data
|
|
127
|
+
*/
|
|
128
|
+
function calculateFileComplexities(chunksByFile) {
|
|
129
|
+
const fileComplexities = [];
|
|
130
|
+
for (const [filepath, chunks] of chunksByFile.entries()) {
|
|
131
|
+
const complexities = chunks
|
|
132
|
+
.map(c => c.metadata.complexity)
|
|
133
|
+
.filter((c) => typeof c === 'number' && c > 0);
|
|
134
|
+
if (complexities.length > 0) {
|
|
135
|
+
const sum = complexities.reduce((a, b) => a + b, 0);
|
|
136
|
+
const avg = sum / complexities.length;
|
|
137
|
+
const max = Math.max(...complexities);
|
|
138
|
+
fileComplexities.push({
|
|
139
|
+
filepath,
|
|
140
|
+
avgComplexity: Math.round(avg * 10) / 10,
|
|
141
|
+
maxComplexity: max,
|
|
142
|
+
complexityScore: sum,
|
|
143
|
+
chunksWithComplexity: complexities.length,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return fileComplexities;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Calculates overall complexity metrics from per-file data.
|
|
151
|
+
*
|
|
152
|
+
* @param fileComplexities - Array of per-file complexity info
|
|
153
|
+
* @returns Aggregated complexity metrics, or undefined if no data
|
|
154
|
+
*/
|
|
155
|
+
function calculateOverallComplexityMetrics(fileComplexities) {
|
|
156
|
+
if (fileComplexities.length === 0) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
const allAvgs = fileComplexities.map(f => f.avgComplexity);
|
|
160
|
+
const allMaxes = fileComplexities.map(f => f.maxComplexity);
|
|
161
|
+
const totalAvg = allAvgs.reduce((a, b) => a + b, 0) / allAvgs.length;
|
|
162
|
+
const globalMax = Math.max(...allMaxes);
|
|
163
|
+
// Identify high-complexity dependents (top 5)
|
|
164
|
+
const highComplexityDependents = fileComplexities
|
|
165
|
+
.filter(f => f.maxComplexity > COMPLEXITY_THRESHOLDS.HIGH_COMPLEXITY_DEPENDENT)
|
|
166
|
+
.sort((a, b) => b.maxComplexity - a.maxComplexity)
|
|
167
|
+
.slice(0, 5)
|
|
168
|
+
.map(f => ({
|
|
169
|
+
filepath: f.filepath,
|
|
170
|
+
maxComplexity: f.maxComplexity,
|
|
171
|
+
avgComplexity: f.avgComplexity,
|
|
172
|
+
}));
|
|
173
|
+
// Calculate complexity-based risk boost
|
|
174
|
+
const complexityRiskBoost = calculateComplexityRiskBoost(totalAvg, globalMax);
|
|
175
|
+
return {
|
|
176
|
+
averageComplexity: Math.round(totalAvg * 10) / 10,
|
|
177
|
+
maxComplexity: globalMax,
|
|
178
|
+
filesWithComplexityData: fileComplexities.length,
|
|
179
|
+
highComplexityDependents,
|
|
180
|
+
complexityRiskBoost,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Determines risk level based on complexity thresholds.
|
|
185
|
+
*
|
|
186
|
+
* @param avgComplexity - Average complexity across all files
|
|
187
|
+
* @param maxComplexity - Maximum complexity found in any file
|
|
188
|
+
* @returns Risk level based on complexity thresholds
|
|
189
|
+
*/
|
|
190
|
+
function calculateComplexityRiskBoost(avgComplexity, maxComplexity) {
|
|
191
|
+
if (avgComplexity > COMPLEXITY_THRESHOLDS.CRITICAL_AVG ||
|
|
192
|
+
maxComplexity > COMPLEXITY_THRESHOLDS.CRITICAL_MAX) {
|
|
193
|
+
return 'critical';
|
|
194
|
+
}
|
|
195
|
+
if (avgComplexity > COMPLEXITY_THRESHOLDS.HIGH_AVG ||
|
|
196
|
+
maxComplexity > COMPLEXITY_THRESHOLDS.HIGH_MAX) {
|
|
197
|
+
return 'high';
|
|
198
|
+
}
|
|
199
|
+
if (avgComplexity > COMPLEXITY_THRESHOLDS.MEDIUM_AVG ||
|
|
200
|
+
maxComplexity > COMPLEXITY_THRESHOLDS.MEDIUM_MAX) {
|
|
201
|
+
return 'medium';
|
|
202
|
+
}
|
|
203
|
+
return 'low';
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Calculates risk level based on dependent count.
|
|
207
|
+
*
|
|
208
|
+
* @param count - Number of dependent files
|
|
209
|
+
* @returns Risk level based on dependent count thresholds
|
|
210
|
+
*/
|
|
211
|
+
function calculateRiskLevelFromCount(count) {
|
|
212
|
+
if (count <= DEPENDENT_COUNT_THRESHOLDS.LOW) {
|
|
213
|
+
return 'low';
|
|
214
|
+
}
|
|
215
|
+
if (count <= DEPENDENT_COUNT_THRESHOLDS.MEDIUM) {
|
|
216
|
+
return 'medium';
|
|
217
|
+
}
|
|
218
|
+
if (count <= DEPENDENT_COUNT_THRESHOLDS.HIGH) {
|
|
219
|
+
return 'high';
|
|
220
|
+
}
|
|
221
|
+
return 'critical';
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Maximum depth for following re-export chains.
|
|
225
|
+
* Covers real-world barrel chains (A → barrel → barrel → consumer)
|
|
226
|
+
* without risk of runaway traversal.
|
|
227
|
+
*/
|
|
228
|
+
const MAX_REEXPORT_DEPTH = 3;
|
|
229
|
+
/**
|
|
230
|
+
* Check if a single chunk imports from the given source path.
|
|
231
|
+
* Checks both `importedSymbols` keys and raw `imports` array.
|
|
232
|
+
*/
|
|
233
|
+
export function chunkImportsFrom(chunk, sourcePath, normalizePathCached) {
|
|
234
|
+
const importedSymbols = chunk.metadata.importedSymbols;
|
|
235
|
+
if (importedSymbols && typeof importedSymbols === 'object') {
|
|
236
|
+
for (const importPath of Object.keys(importedSymbols)) {
|
|
237
|
+
if (matchesFile(normalizePathCached(importPath), sourcePath))
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const imports = chunk.metadata.imports || [];
|
|
242
|
+
for (const imp of imports) {
|
|
243
|
+
if (matchesFile(normalizePathCached(imp), sourcePath))
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Check if a chunk has any exports.
|
|
250
|
+
*/
|
|
251
|
+
function chunkHasExports(chunk) {
|
|
252
|
+
return chunk.metadata.exports != null && chunk.metadata.exports.length > 0;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Group chunks by their normalized file path.
|
|
256
|
+
*/
|
|
257
|
+
export function groupChunksByNormalizedPath(chunks, normalizePathCached) {
|
|
258
|
+
const grouped = new Map();
|
|
259
|
+
for (const chunk of chunks) {
|
|
260
|
+
const canonical = normalizePathCached(chunk.metadata.file);
|
|
261
|
+
let list = grouped.get(canonical);
|
|
262
|
+
if (!list) {
|
|
263
|
+
list = [];
|
|
264
|
+
grouped.set(canonical, list);
|
|
265
|
+
}
|
|
266
|
+
list.push(chunk);
|
|
267
|
+
}
|
|
268
|
+
return grouped;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Check if a file (given its chunks) is a re-exporter from a source path.
|
|
272
|
+
* A re-exporter has both imports from the source and exports.
|
|
273
|
+
*/
|
|
274
|
+
export function fileIsReExporter(chunks, sourcePath, normalizePathCached) {
|
|
275
|
+
let importsFromSource = false;
|
|
276
|
+
let hasExports = false;
|
|
277
|
+
for (const chunk of chunks) {
|
|
278
|
+
if (!importsFromSource && chunkImportsFrom(chunk, sourcePath, normalizePathCached)) {
|
|
279
|
+
importsFromSource = true;
|
|
280
|
+
}
|
|
281
|
+
if (!hasExports && chunkHasExports(chunk)) {
|
|
282
|
+
hasExports = true;
|
|
283
|
+
}
|
|
284
|
+
if (importsFromSource && hasExports)
|
|
285
|
+
return true;
|
|
286
|
+
}
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Build a list of files that re-export from the target file.
|
|
291
|
+
*
|
|
292
|
+
* A re-exporter is a file where a symbol appears in both
|
|
293
|
+
* `importedSymbols[targetPath]` (or raw `imports`) AND `exports`.
|
|
294
|
+
*/
|
|
295
|
+
function buildReExportGraph(allChunksByFile, normalizedTarget, normalizePathCached) {
|
|
296
|
+
const reExporters = [];
|
|
297
|
+
for (const [filepath, chunks] of allChunksByFile.entries()) {
|
|
298
|
+
if (matchesFile(filepath, normalizedTarget))
|
|
299
|
+
continue;
|
|
300
|
+
if (fileIsReExporter(chunks, normalizedTarget, normalizePathCached)) {
|
|
301
|
+
reExporters.push(filepath);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return reExporters;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Process a single dependent chunk during BFS traversal.
|
|
308
|
+
* Returns the chunk if it's a new dependent, or null if already visited.
|
|
309
|
+
* If the chunk's file is itself a re-exporter, adds it to the BFS queue.
|
|
310
|
+
*/
|
|
311
|
+
function processTransitiveChunk(chunk, reExporterPath, depth, visited, allChunksByFile, normalizePathCached, queue) {
|
|
312
|
+
const chunkFile = normalizePathCached(chunk.metadata.file);
|
|
313
|
+
if (visited.has(chunkFile))
|
|
314
|
+
return null;
|
|
315
|
+
visited.add(chunkFile);
|
|
316
|
+
if (depth < MAX_REEXPORT_DEPTH) {
|
|
317
|
+
const fileChunks = allChunksByFile.get(chunkFile) || [];
|
|
318
|
+
if (fileIsReExporter(fileChunks, reExporterPath, normalizePathCached)) {
|
|
319
|
+
queue.push([chunkFile, depth + 1]);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return chunk;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Find transitive dependents through re-export chains using BFS.
|
|
326
|
+
* Bounded to MAX_REEXPORT_DEPTH.
|
|
327
|
+
*/
|
|
328
|
+
export function findTransitiveDependents(reExporterPaths, importIndex, normalizedTarget, normalizePathCached, allChunksByFile, existingFiles) {
|
|
329
|
+
const transitiveChunks = [];
|
|
330
|
+
const visited = new Set([normalizedTarget, ...existingFiles]);
|
|
331
|
+
const queue = [];
|
|
332
|
+
for (const rePath of reExporterPaths) {
|
|
333
|
+
if (!visited.has(rePath)) {
|
|
334
|
+
queue.push([rePath, 1]);
|
|
335
|
+
visited.add(rePath);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
while (queue.length > 0) {
|
|
339
|
+
const [reExporterPath, depth] = queue.shift();
|
|
340
|
+
const dependentChunks = findDependentChunks(reExporterPath, importIndex);
|
|
341
|
+
for (const chunk of dependentChunks) {
|
|
342
|
+
const result = processTransitiveChunk(chunk, reExporterPath, depth, visited, allChunksByFile, normalizePathCached, queue);
|
|
343
|
+
if (result)
|
|
344
|
+
transitiveChunks.push(result);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return transitiveChunks;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Analyzes dependencies for a given file by finding all chunks that import it.
|
|
351
|
+
*
|
|
352
|
+
* @param targetFilepath - The file to analyze dependencies for
|
|
353
|
+
* @param allChunks - All chunks from the vector database
|
|
354
|
+
* @param workspaceRoot - The workspace root directory
|
|
355
|
+
* @returns Dependency analysis including dependents, count, and risk level
|
|
356
|
+
*/
|
|
357
|
+
export function analyzeDependencies(targetFilepath, allChunks, workspaceRoot) {
|
|
358
|
+
// Create cached path normalizer
|
|
359
|
+
const normalizePathCached = createPathNormalizer(workspaceRoot);
|
|
360
|
+
// Build import index for efficient lookup
|
|
361
|
+
const importIndex = buildImportIndex(allChunks, normalizePathCached);
|
|
362
|
+
// Find all dependent chunks
|
|
363
|
+
const normalizedTarget = normalizePathCached(targetFilepath);
|
|
364
|
+
const dependentChunks = findDependentChunks(normalizedTarget, importIndex);
|
|
365
|
+
// Group by file for analysis
|
|
366
|
+
const chunksByFile = groupChunksByFile(dependentChunks, workspaceRoot);
|
|
367
|
+
// Find transitive dependents through re-export chains (barrel files)
|
|
368
|
+
const allChunksByFile = groupChunksByNormalizedPath(allChunks, normalizePathCached);
|
|
369
|
+
const reExporterPaths = buildReExportGraph(allChunksByFile, normalizedTarget, normalizePathCached);
|
|
370
|
+
if (reExporterPaths.length > 0) {
|
|
371
|
+
const existingFiles = new Set(chunksByFile.keys());
|
|
372
|
+
const transitiveChunks = findTransitiveDependents(reExporterPaths, importIndex, normalizedTarget, normalizePathCached, allChunksByFile, existingFiles);
|
|
373
|
+
if (transitiveChunks.length > 0) {
|
|
374
|
+
const transitiveByFile = groupChunksByFile(transitiveChunks, workspaceRoot);
|
|
375
|
+
for (const [fp, chunks] of transitiveByFile.entries()) {
|
|
376
|
+
if (chunksByFile.has(fp)) {
|
|
377
|
+
chunksByFile.get(fp).push(...chunks);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
chunksByFile.set(fp, chunks);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Calculate complexity metrics
|
|
386
|
+
const fileComplexities = calculateFileComplexities(chunksByFile);
|
|
387
|
+
const complexityMetrics = calculateOverallComplexityMetrics(fileComplexities);
|
|
388
|
+
// Build dependents list
|
|
389
|
+
const dependents = Array.from(chunksByFile.keys()).map(filepath => ({
|
|
390
|
+
filepath,
|
|
391
|
+
isTestFile: isTestFile(filepath),
|
|
392
|
+
}));
|
|
393
|
+
// Calculate risk level
|
|
394
|
+
let riskLevel = calculateRiskLevelFromCount(dependents.length);
|
|
395
|
+
// Boost risk level if complexity warrants it
|
|
396
|
+
if (complexityMetrics?.complexityRiskBoost) {
|
|
397
|
+
if (RISK_ORDER[complexityMetrics.complexityRiskBoost] > RISK_ORDER[riskLevel]) {
|
|
398
|
+
riskLevel = complexityMetrics.complexityRiskBoost;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
return {
|
|
402
|
+
dependents,
|
|
403
|
+
dependentCount: dependents.length,
|
|
404
|
+
riskLevel,
|
|
405
|
+
complexityMetrics,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=dependency-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../src/dependency-analyzer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,GAAG,EAAE,CAAC,EAAE,iCAAiC;IACzC,MAAM,EAAE,EAAE,EAAE,qCAAqC;IACjD,IAAI,EAAE,EAAE,EAAE,uCAAuC;CACzC,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,yBAAyB,EAAE,EAAE,EAAE,6BAA6B;IAC5D,YAAY,EAAE,EAAE,EAAE,mDAAmD;IACrE,YAAY,EAAE,EAAE,EAAE,oCAAoC;IACtD,QAAQ,EAAE,EAAE,EAAE,gCAAgC;IAC9C,QAAQ,EAAE,EAAE,EAAE,+BAA+B;IAC7C,UAAU,EAAE,CAAC,EAAE,6BAA6B;IAC5C,UAAU,EAAE,EAAE,EAAE,uBAAuB;CAC/B,CAAC;AA8BX;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,aAAqB;IACjD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,OAAO,CAAC,IAAY,EAAU,EAAE;QAC9B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACxC,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACtD,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC5B,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,gBAAgB,CACvB,MAAmB,EACnB,mBAA6C;IAE7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEnD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAClD,IAAI,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAClD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,SAAS,GAAG,EAAE,CAAC;gBACf,WAAW,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;YAC/C,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAC1B,gBAAwB,EACxB,WAAqC;IAErC,MAAM,eAAe,GAAgB,EAAE,CAAC;IACxC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAQ,EAAE;QAC1C,MAAM,OAAO,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QAC/F,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC;IAEF,qCAAqC;IACrC,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IACxD,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,kFAAkF;IAClF,sEAAsE;IACtE,KAAK,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/D,IAAI,gBAAgB,KAAK,gBAAgB,IAAI,WAAW,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,EAAE,CAAC;YAC7F,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,MAAmB,EAAE,aAAqB;IACnE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAuB,CAAC;IAEpD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QACvE,IAAI,QAAQ,GAAG,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,EAAE,CAAC;YACd,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACxC,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;GAKG;AACH,SAAS,yBAAyB,CAAC,YAAsC;IACvE,MAAM,gBAAgB,GAAyB,EAAE,CAAC;IAElD,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,YAAY,GAAG,MAAM;aACxB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;aAC/B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAE9D,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,GAAG,GAAG,YAAY,CAAC,MAAM,CAAC;YACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC;YAEtC,gBAAgB,CAAC,IAAI,CAAC;gBACpB,QAAQ;gBACR,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE;gBACxC,aAAa,EAAE,GAAG;gBAClB,eAAe,EAAE,GAAG;gBACpB,oBAAoB,EAAE,YAAY,CAAC,MAAM;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,SAAS,iCAAiC,CACxC,gBAAsC;IAEtC,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC3D,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;IAExC,8CAA8C;IAC9C,MAAM,wBAAwB,GAAG,gBAAgB;SAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,qBAAqB,CAAC,yBAAyB,CAAC;SAC9E,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC;SACjD,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACT,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,aAAa,EAAE,CAAC,CAAC,aAAa;QAC9B,aAAa,EAAE,CAAC,CAAC,aAAa;KAC/B,CAAC,CAAC,CAAC;IAEN,wCAAwC;IACxC,MAAM,mBAAmB,GAAG,4BAA4B,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAE9E,OAAO;QACL,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE;QACjD,aAAa,EAAE,SAAS;QACxB,uBAAuB,EAAE,gBAAgB,CAAC,MAAM;QAChD,wBAAwB;QACxB,mBAAmB;KACpB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,4BAA4B,CAAC,aAAqB,EAAE,aAAqB;IAChF,IACE,aAAa,GAAG,qBAAqB,CAAC,YAAY;QAClD,aAAa,GAAG,qBAAqB,CAAC,YAAY,EAClD,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IACE,aAAa,GAAG,qBAAqB,CAAC,QAAQ;QAC9C,aAAa,GAAG,qBAAqB,CAAC,QAAQ,EAC9C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IACE,aAAa,GAAG,qBAAqB,CAAC,UAAU;QAChD,aAAa,GAAG,qBAAqB,CAAC,UAAU,EAChD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,2BAA2B,CAAC,KAAa;IAChD,IAAI,KAAK,IAAI,0BAA0B,CAAC,GAAG,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,KAAK,IAAI,0BAA0B,CAAC,MAAM,EAAE,CAAC;QAC/C,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,IAAI,KAAK,IAAI,0BAA0B,CAAC,IAAI,EAAE,CAAC;QAC7C,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAgB,EAChB,UAAkB,EAClB,mBAA6C;IAE7C,MAAM,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;IACvD,IAAI,eAAe,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE,CAAC;QAC3D,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YACtD,IAAI,WAAW,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,IAAI,EAAE,CAAC;IAC7C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,WAAW,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;IACrE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,KAAgB;IACvC,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAmB,EACnB,mBAA6C;IAE7C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3D,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAmB,EACnB,UAAkB,EAClB,mBAA6C;IAE7C,IAAI,iBAAiB,GAAG,KAAK,CAAC;IAC9B,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACnF,iBAAiB,GAAG,IAAI,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,UAAU,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1C,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,iBAAiB,IAAI,UAAU;YAAE,OAAO,IAAI,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CACzB,eAAyC,EACzC,gBAAwB,EACxB,mBAA6C;IAE7C,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC;YAAE,SAAS;QACtD,IAAI,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACpE,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAC7B,KAAgB,EAChB,cAAsB,EACtB,KAAa,EACb,OAAoB,EACpB,eAAyC,EACzC,mBAA6C,EAC7C,KAA8B;IAE9B,MAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEvB,IAAI,KAAK,GAAG,kBAAkB,EAAE,CAAC;QAC/B,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QACxD,IAAI,gBAAgB,CAAC,UAAU,EAAE,cAAc,EAAE,mBAAmB,CAAC,EAAE,CAAC;YACtE,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,eAAyB,EACzB,WAAqC,EACrC,gBAAwB,EACxB,mBAA6C,EAC7C,eAAyC,EACzC,aAA0B;IAE1B,MAAM,gBAAgB,GAAgB,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,gBAAgB,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC;IAEtE,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,cAAc,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,EAAG,CAAC;QAC/C,MAAM,eAAe,GAAG,mBAAmB,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAEzE,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YACpC,MAAM,MAAM,GAAG,sBAAsB,CACnC,KAAK,EACL,cAAc,EACd,KAAK,EACL,OAAO,EACP,eAAe,EACf,mBAAmB,EACnB,KAAK,CACN,CAAC;YACF,IAAI,MAAM;gBAAE,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,cAAsB,EACtB,SAAsB,EACtB,aAAqB;IAErB,gCAAgC;IAChC,MAAM,mBAAmB,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;IAEhE,0CAA0C;IAC1C,MAAM,WAAW,GAAG,gBAAgB,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAErE,4BAA4B;IAC5B,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAC7D,MAAM,eAAe,GAAG,mBAAmB,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAE3E,6BAA6B;IAC7B,MAAM,YAAY,GAAG,iBAAiB,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;IAEvE,qEAAqE;IACrE,MAAM,eAAe,GAAG,2BAA2B,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;IACpF,MAAM,eAAe,GAAG,kBAAkB,CACxC,eAAe,EACf,gBAAgB,EAChB,mBAAmB,CACpB,CAAC;IACF,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;QACnD,MAAM,gBAAgB,GAAG,wBAAwB,CAC/C,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,aAAa,CACd,CAAC;QACF,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;YAC5E,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,gBAAgB,CAAC,OAAO,EAAE,EAAE,CAAC;gBACtD,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzB,YAAY,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;gBACxC,CAAC;qBAAM,CAAC;oBACN,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC;IACjE,MAAM,iBAAiB,GAAG,iCAAiC,CAAC,gBAAgB,CAAC,CAAC;IAE9E,wBAAwB;IACxB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAClE,QAAQ;QACR,UAAU,EAAE,UAAU,CAAC,QAAQ,CAAC;KACjC,CAAC,CAAC,CAAC;IAEJ,uBAAuB;IACvB,IAAI,SAAS,GAAG,2BAA2B,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAE/D,6CAA6C;IAC7C,IAAI,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;QAC3C,IAAI,UAAU,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9E,SAAS,GAAG,iBAAiB,CAAC,mBAAmB,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU;QACV,cAAc,EAAE,UAAU,CAAC,MAAM;QACjC,SAAS;QACT,iBAAiB;KAClB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* An ecosystem preset defines marker files and exclude patterns
|
|
3
|
+
* for a specific development ecosystem.
|
|
4
|
+
*/
|
|
5
|
+
export interface EcosystemPreset {
|
|
6
|
+
name: string;
|
|
7
|
+
markerFiles: string[];
|
|
8
|
+
excludePatterns: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Predefined ecosystem presets.
|
|
12
|
+
* Each preset checks for marker files and provides exclude patterns
|
|
13
|
+
* for common build artifacts, caches, and generated files.
|
|
14
|
+
*/
|
|
15
|
+
export declare const ECOSYSTEM_PRESETS: EcosystemPreset[];
|
|
16
|
+
/**
|
|
17
|
+
* Detect which ecosystems are present in a project by checking for marker files.
|
|
18
|
+
* Checks rootDir and immediate subdirectories (depth 1) for monorepo support.
|
|
19
|
+
*
|
|
20
|
+
* @param rootDir - Project root directory
|
|
21
|
+
* @returns Array of matched ecosystem names
|
|
22
|
+
*/
|
|
23
|
+
export declare function detectEcosystems(rootDir: string): Promise<string[]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get merged exclude patterns for the given ecosystem names.
|
|
26
|
+
* Returns a deduplicated array of exclude patterns.
|
|
27
|
+
*
|
|
28
|
+
* @param ecosystemNames - Array of ecosystem names (e.g. ['nodejs', 'python'])
|
|
29
|
+
* @returns Deduplicated exclude patterns
|
|
30
|
+
*/
|
|
31
|
+
export declare function getEcosystemExcludePatterns(ecosystemNames: string[]): string[];
|
|
32
|
+
//# sourceMappingURL=ecosystem-presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecosystem-presets.d.ts","sourceRoot":"","sources":["../src/ecosystem-presets.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,eAAe,EAwM9C,CAAC;AAgFF;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBzE;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAa9E"}
|