gitblast 0.0.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/dist/analyzer.d.ts +12 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +140 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/ast-analyzer.d.ts +12 -0
- package/dist/ast-analyzer.d.ts.map +1 -0
- package/dist/ast-analyzer.js +274 -0
- package/dist/ast-analyzer.js.map +1 -0
- package/dist/blast-radius.d.ts +17 -0
- package/dist/blast-radius.d.ts.map +1 -0
- package/dist/blast-radius.js +82 -0
- package/dist/blast-radius.js.map +1 -0
- package/dist/call-graph.d.ts +8 -0
- package/dist/call-graph.d.ts.map +1 -0
- package/dist/call-graph.js +252 -0
- package/dist/call-graph.js.map +1 -0
- package/dist/call-resolver.d.ts +18 -0
- package/dist/call-resolver.d.ts.map +1 -0
- package/dist/call-resolver.js +130 -0
- package/dist/call-resolver.js.map +1 -0
- package/dist/file-scanner.d.ts +2 -0
- package/dist/file-scanner.d.ts.map +1 -0
- package/dist/file-scanner.js +42 -0
- package/dist/file-scanner.js.map +1 -0
- package/dist/function-blast-radius.d.ts +7 -0
- package/dist/function-blast-radius.d.ts.map +1 -0
- package/dist/function-blast-radius.js +52 -0
- package/dist/function-blast-radius.js.map +1 -0
- package/dist/git.d.ts +27 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +69 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +385 -0
- package/dist/index.js.map +1 -0
- package/dist/tool-runner.d.ts +65 -0
- package/dist/tool-runner.d.ts.map +1 -0
- package/dist/tool-runner.js +178 -0
- package/dist/tool-runner.js.map +1 -0
- package/dist/types.d.ts +92 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/web/assets/index-BEQJnpxt.js +17 -0
- package/dist/web/assets/index-CqmVdlle.css +1 -0
- package/dist/web/index.html +14 -0
- package/dist/web/vite.svg +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GraphData } from "./types.js";
|
|
2
|
+
export type { GraphData, FileNode, DependencyEdge, DirectoryNode, ExportInfo, ImportInfo, BlastRadiusResult, BlastRadiusEntry, FunctionScope, CallEdge, FunctionBlastRadiusResult, FunctionBlastRadiusEntry, } from "./types.js";
|
|
3
|
+
export { computeBlastRadius } from "./blast-radius.js";
|
|
4
|
+
export { computeFunctionBlastRadius } from "./function-blast-radius.js";
|
|
5
|
+
export { runTools, loadCachedTools } from "./tool-runner.js";
|
|
6
|
+
export type { ToolResults, KnipResult, DepCruiserResult, JscpdResult } from "./tool-runner.js";
|
|
7
|
+
export { getGitInfo, getGitDiff, checkoutBranch, isGitRepo } from "./git.js";
|
|
8
|
+
export type { GitInfo, GitDiff } from "./git.js";
|
|
9
|
+
export { computeAggregateBlastRadius } from "./blast-radius.js";
|
|
10
|
+
export type { AggregateBlastRadiusResult } from "./blast-radius.js";
|
|
11
|
+
export declare function analyzeRepo(rootDir: string, onProgress?: (message: string, current: number, total: number) => void): Promise<GraphData>;
|
|
12
|
+
//# sourceMappingURL=analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,SAAS,EAOV,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,SAAS,EACT,QAAQ,EACR,cAAc,EACd,aAAa,EACb,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC7E,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAChE,YAAY,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AA8BpE,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACrE,OAAO,CAAC,SAAS,CAAC,CAoHpB"}
|
package/dist/analyzer.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
2
|
+
import { join, dirname, relative, basename, extname } from "node:path";
|
|
3
|
+
import { ResolverFactory } from "oxc-resolver";
|
|
4
|
+
import { scanFiles } from "./file-scanner.js";
|
|
5
|
+
import { initParser, analyzeFileWithCalls } from "./ast-analyzer.js";
|
|
6
|
+
import { resolveCallEdges } from "./call-resolver.js";
|
|
7
|
+
export { computeBlastRadius } from "./blast-radius.js";
|
|
8
|
+
export { computeFunctionBlastRadius } from "./function-blast-radius.js";
|
|
9
|
+
export { runTools, loadCachedTools } from "./tool-runner.js";
|
|
10
|
+
export { getGitInfo, getGitDiff, checkoutBranch, isGitRepo } from "./git.js";
|
|
11
|
+
export { computeAggregateBlastRadius } from "./blast-radius.js";
|
|
12
|
+
function getLanguage(filePath) {
|
|
13
|
+
const ext = extname(filePath);
|
|
14
|
+
switch (ext) {
|
|
15
|
+
case ".ts": return "typescript";
|
|
16
|
+
case ".tsx": return "tsx";
|
|
17
|
+
case ".jsx": return "jsx";
|
|
18
|
+
default: return "javascript";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function createResolver(rootDir) {
|
|
22
|
+
// Check for tsconfig.json
|
|
23
|
+
const tsconfigPath = join(rootDir, "tsconfig.json");
|
|
24
|
+
const hasTsconfig = existsSync(tsconfigPath);
|
|
25
|
+
return new ResolverFactory({
|
|
26
|
+
extensions: [".ts", ".tsx", ".js", ".jsx", ".json"],
|
|
27
|
+
extensionAlias: {
|
|
28
|
+
".js": [".ts", ".tsx", ".js"],
|
|
29
|
+
".jsx": [".tsx", ".jsx"],
|
|
30
|
+
},
|
|
31
|
+
mainFields: ["module", "main"],
|
|
32
|
+
mainFiles: ["index"],
|
|
33
|
+
conditionNames: ["import", "module", "default"],
|
|
34
|
+
tsconfig: hasTsconfig ? { configFile: tsconfigPath, references: "auto" } : undefined,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export async function analyzeRepo(rootDir, onProgress) {
|
|
38
|
+
await initParser();
|
|
39
|
+
const files = await scanFiles(rootDir);
|
|
40
|
+
const resolver = createResolver(rootDir);
|
|
41
|
+
onProgress?.("Scanning files...", 0, files.length);
|
|
42
|
+
const nodes = [];
|
|
43
|
+
const edgeMap = new Map();
|
|
44
|
+
const callDataByFile = new Map();
|
|
45
|
+
const allScopes = [];
|
|
46
|
+
for (let i = 0; i < files.length; i++) {
|
|
47
|
+
const relPath = files[i];
|
|
48
|
+
const absPath = join(rootDir, relPath);
|
|
49
|
+
const content = readFileSync(absPath, "utf-8");
|
|
50
|
+
onProgress?.(`Analyzing ${relPath}`, i + 1, files.length);
|
|
51
|
+
const { exports, imports, callData } = analyzeFileWithCalls(relPath, content);
|
|
52
|
+
callDataByFile.set(relPath, callData);
|
|
53
|
+
allScopes.push(...callData.scopes);
|
|
54
|
+
// Resolve import paths
|
|
55
|
+
const resolvedImports = imports.map((imp) => {
|
|
56
|
+
if (imp.isExternal)
|
|
57
|
+
return imp;
|
|
58
|
+
try {
|
|
59
|
+
const result = resolver.sync(dirname(absPath), imp.source);
|
|
60
|
+
if (result.path) {
|
|
61
|
+
const resolvedRel = relative(rootDir, result.path);
|
|
62
|
+
// Only include if the resolved file is within our scanned files
|
|
63
|
+
if (files.includes(resolvedRel)) {
|
|
64
|
+
return { ...imp, resolvedPath: resolvedRel };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Resolution failed — treat as external
|
|
70
|
+
}
|
|
71
|
+
return imp;
|
|
72
|
+
});
|
|
73
|
+
const linesOfCode = content.split("\n").length;
|
|
74
|
+
nodes.push({
|
|
75
|
+
id: relPath,
|
|
76
|
+
filePath: absPath,
|
|
77
|
+
directory: dirname(relPath) === "." ? "" : dirname(relPath),
|
|
78
|
+
fileName: basename(relPath),
|
|
79
|
+
language: getLanguage(relPath),
|
|
80
|
+
exports,
|
|
81
|
+
imports: resolvedImports,
|
|
82
|
+
linesOfCode,
|
|
83
|
+
});
|
|
84
|
+
// Build edges from resolved imports
|
|
85
|
+
for (const imp of resolvedImports) {
|
|
86
|
+
if (imp.resolvedPath && !imp.isExternal) {
|
|
87
|
+
const edgeKey = `${relPath}->${imp.resolvedPath}`;
|
|
88
|
+
const existing = edgeMap.get(edgeKey);
|
|
89
|
+
if (existing) {
|
|
90
|
+
// Merge imported names
|
|
91
|
+
for (const name of imp.names) {
|
|
92
|
+
if (!existing.imports.includes(name)) {
|
|
93
|
+
existing.imports.push(name);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
edgeMap.set(edgeKey, {
|
|
99
|
+
source: relPath,
|
|
100
|
+
target: imp.resolvedPath,
|
|
101
|
+
imports: [...imp.names],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Resolve cross-file call edges
|
|
108
|
+
const fileInfoMap = new Map(nodes.map((n) => [n.id, { fileId: n.id, imports: n.imports, exports: n.exports }]));
|
|
109
|
+
const callEdges = resolveCallEdges(callDataByFile, fileInfoMap);
|
|
110
|
+
// Build directory tree
|
|
111
|
+
const dirSet = new Set();
|
|
112
|
+
for (const node of nodes) {
|
|
113
|
+
let dir = node.directory;
|
|
114
|
+
while (dir && dir !== ".") {
|
|
115
|
+
dirSet.add(dir);
|
|
116
|
+
dir = dirname(dir) === "." ? "" : dirname(dir);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const directories = Array.from(dirSet)
|
|
120
|
+
.sort()
|
|
121
|
+
.map((dir) => {
|
|
122
|
+
const parent = dirname(dir);
|
|
123
|
+
return {
|
|
124
|
+
id: dir,
|
|
125
|
+
name: basename(dir),
|
|
126
|
+
parentDir: parent === "." || parent === dir ? null : parent,
|
|
127
|
+
depth: dir.split("/").length,
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
rootDir,
|
|
132
|
+
analyzedAt: new Date().toISOString(),
|
|
133
|
+
nodes,
|
|
134
|
+
edges: Array.from(edgeMap.values()),
|
|
135
|
+
directories,
|
|
136
|
+
scopes: allScopes,
|
|
137
|
+
callEdges,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExportInfo, ImportInfo, FileCallData } from "./types.js";
|
|
2
|
+
export declare function initParser(): Promise<void>;
|
|
3
|
+
export declare function analyzeFile(filePath: string, content: string): {
|
|
4
|
+
exports: ExportInfo[];
|
|
5
|
+
imports: ImportInfo[];
|
|
6
|
+
};
|
|
7
|
+
export declare function analyzeFileWithCalls(fileId: string, content: string): {
|
|
8
|
+
exports: ExportInfo[];
|
|
9
|
+
imports: ImportInfo[];
|
|
10
|
+
callData: FileCallData;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=ast-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-analyzer.d.ts","sourceRoot":"","sources":["../src/ast-analyzer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AASvE,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAYhD;AAkCD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,CAelD;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAuB1E"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import Parser from "web-tree-sitter";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { join, dirname, extname } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { extractCallData } from "./call-graph.js";
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
let tsLanguage = null;
|
|
8
|
+
let tsxLanguage = null;
|
|
9
|
+
let initialized = false;
|
|
10
|
+
export async function initParser() {
|
|
11
|
+
if (initialized)
|
|
12
|
+
return;
|
|
13
|
+
await Parser.init();
|
|
14
|
+
// Find wasm files from tree-sitter-typescript package
|
|
15
|
+
const tsWasmPath = findWasmPath("tree-sitter-typescript.wasm");
|
|
16
|
+
const tsxWasmPath = findWasmPath("tree-sitter-tsx.wasm");
|
|
17
|
+
tsLanguage = await Parser.Language.load(tsWasmPath);
|
|
18
|
+
tsxLanguage = await Parser.Language.load(tsxWasmPath);
|
|
19
|
+
initialized = true;
|
|
20
|
+
}
|
|
21
|
+
function findWasmPath(filename) {
|
|
22
|
+
// Look in common locations relative to this package
|
|
23
|
+
const candidates = [
|
|
24
|
+
join(__dirname, "..", "node_modules", "tree-sitter-typescript", filename),
|
|
25
|
+
join(__dirname, "..", "..", "..", "node_modules", "tree-sitter-typescript", filename),
|
|
26
|
+
];
|
|
27
|
+
for (const p of candidates) {
|
|
28
|
+
try {
|
|
29
|
+
readFileSync(p);
|
|
30
|
+
return p;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// try next
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
throw new Error(`Could not find ${filename}. Searched: ${candidates.join(", ")}`);
|
|
37
|
+
}
|
|
38
|
+
function getLanguageForFile(filePath) {
|
|
39
|
+
const ext = extname(filePath);
|
|
40
|
+
switch (ext) {
|
|
41
|
+
case ".ts":
|
|
42
|
+
return tsLanguage;
|
|
43
|
+
case ".tsx":
|
|
44
|
+
case ".jsx":
|
|
45
|
+
return tsxLanguage;
|
|
46
|
+
case ".js":
|
|
47
|
+
return tsLanguage; // TS parser handles JS fine
|
|
48
|
+
default:
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function analyzeFile(filePath, content) {
|
|
53
|
+
const language = getLanguageForFile(filePath);
|
|
54
|
+
if (!language)
|
|
55
|
+
return { exports: [], imports: [] };
|
|
56
|
+
const parser = new Parser();
|
|
57
|
+
parser.setLanguage(language);
|
|
58
|
+
const tree = parser.parse(content);
|
|
59
|
+
const exports = extractExports(tree.rootNode);
|
|
60
|
+
const imports = extractImports(tree.rootNode);
|
|
61
|
+
parser.delete();
|
|
62
|
+
tree.delete();
|
|
63
|
+
return { exports, imports };
|
|
64
|
+
}
|
|
65
|
+
export function analyzeFileWithCalls(fileId, content) {
|
|
66
|
+
const language = getLanguageForFile(fileId);
|
|
67
|
+
if (!language) {
|
|
68
|
+
return {
|
|
69
|
+
exports: [],
|
|
70
|
+
imports: [],
|
|
71
|
+
callData: { fileId, scopes: [], callSites: [] },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const parser = new Parser();
|
|
75
|
+
parser.setLanguage(language);
|
|
76
|
+
const tree = parser.parse(content);
|
|
77
|
+
const exports = extractExports(tree.rootNode);
|
|
78
|
+
const imports = extractImports(tree.rootNode);
|
|
79
|
+
const exportedNames = new Set(exports.map((e) => e.name));
|
|
80
|
+
const callData = extractCallData(fileId, tree.rootNode, exportedNames);
|
|
81
|
+
parser.delete();
|
|
82
|
+
tree.delete();
|
|
83
|
+
return { exports, imports, callData };
|
|
84
|
+
}
|
|
85
|
+
function extractImports(rootNode) {
|
|
86
|
+
const imports = [];
|
|
87
|
+
for (const node of rootNode.children) {
|
|
88
|
+
if (node.type === "import_statement") {
|
|
89
|
+
const info = parseImportStatement(node);
|
|
90
|
+
if (info)
|
|
91
|
+
imports.push(info);
|
|
92
|
+
}
|
|
93
|
+
// Re-exports also create dependencies: export { x } from './foo'
|
|
94
|
+
if (node.type === "export_statement") {
|
|
95
|
+
const sourceNode = node.childForFieldName("source");
|
|
96
|
+
if (sourceNode) {
|
|
97
|
+
const info = parseReexport(node, sourceNode);
|
|
98
|
+
if (info)
|
|
99
|
+
imports.push(info);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return imports;
|
|
104
|
+
}
|
|
105
|
+
function parseReexport(node, sourceNode) {
|
|
106
|
+
const source = sourceNode.text.replace(/^['"]|['"]$/g, "");
|
|
107
|
+
const names = [];
|
|
108
|
+
for (const child of node.children) {
|
|
109
|
+
if (child.type === "export_clause") {
|
|
110
|
+
for (const spec of child.namedChildren) {
|
|
111
|
+
if (spec.type === "export_specifier") {
|
|
112
|
+
const nameNode = spec.childForFieldName("name");
|
|
113
|
+
if (nameNode)
|
|
114
|
+
names.push(nameNode.text);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// export * from './foo'
|
|
119
|
+
if (child.text === "*") {
|
|
120
|
+
names.push("*");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const isExternal = !source.startsWith(".") && !source.startsWith("/");
|
|
124
|
+
return {
|
|
125
|
+
names,
|
|
126
|
+
source,
|
|
127
|
+
resolvedPath: null,
|
|
128
|
+
isDefault: false,
|
|
129
|
+
isNamespace: names.includes("*"),
|
|
130
|
+
isExternal,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function parseImportStatement(node) {
|
|
134
|
+
const sourceNode = node.childForFieldName("source");
|
|
135
|
+
if (!sourceNode)
|
|
136
|
+
return null;
|
|
137
|
+
// Strip quotes from the source string
|
|
138
|
+
const source = sourceNode.text.replace(/^['"]|['"]$/g, "");
|
|
139
|
+
const names = [];
|
|
140
|
+
let isDefault = false;
|
|
141
|
+
let isNamespace = false;
|
|
142
|
+
for (const child of node.children) {
|
|
143
|
+
if (child.type === "import_clause") {
|
|
144
|
+
for (const clauseChild of child.children) {
|
|
145
|
+
if (clauseChild.type === "identifier") {
|
|
146
|
+
// Default import: import Foo from '...'
|
|
147
|
+
names.push(clauseChild.text);
|
|
148
|
+
isDefault = true;
|
|
149
|
+
}
|
|
150
|
+
else if (clauseChild.type === "named_imports") {
|
|
151
|
+
// Named imports: import { a, b } from '...'
|
|
152
|
+
for (const spec of clauseChild.namedChildren) {
|
|
153
|
+
if (spec.type === "import_specifier") {
|
|
154
|
+
const nameNode = spec.childForFieldName("name");
|
|
155
|
+
const aliasNode = spec.childForFieldName("alias");
|
|
156
|
+
names.push(nameNode?.text ?? spec.text);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (clauseChild.type === "namespace_import") {
|
|
161
|
+
// Namespace import: import * as X from '...'
|
|
162
|
+
isNamespace = true;
|
|
163
|
+
const nameNode = clauseChild.namedChildren.find((c) => c.type === "identifier");
|
|
164
|
+
if (nameNode)
|
|
165
|
+
names.push(nameNode.text);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const isExternal = !source.startsWith(".") && !source.startsWith("/");
|
|
171
|
+
return {
|
|
172
|
+
names,
|
|
173
|
+
source,
|
|
174
|
+
resolvedPath: null, // resolved later
|
|
175
|
+
isDefault,
|
|
176
|
+
isNamespace,
|
|
177
|
+
isExternal,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function extractExports(rootNode) {
|
|
181
|
+
const exports = [];
|
|
182
|
+
for (const node of rootNode.children) {
|
|
183
|
+
if (node.type === "export_statement") {
|
|
184
|
+
const exported = parseExportStatement(node);
|
|
185
|
+
exports.push(...exported);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return exports;
|
|
189
|
+
}
|
|
190
|
+
function parseExportStatement(node) {
|
|
191
|
+
const results = [];
|
|
192
|
+
const line = node.startPosition.row + 1;
|
|
193
|
+
for (const child of node.children) {
|
|
194
|
+
switch (child.type) {
|
|
195
|
+
case "function_declaration":
|
|
196
|
+
case "function_signature": {
|
|
197
|
+
const name = child.childForFieldName("name");
|
|
198
|
+
if (name)
|
|
199
|
+
results.push({ name: name.text, kind: "function", line });
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
case "class_declaration": {
|
|
203
|
+
const name = child.childForFieldName("name");
|
|
204
|
+
if (name)
|
|
205
|
+
results.push({ name: name.text, kind: "class", line });
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
case "lexical_declaration": {
|
|
209
|
+
// export const foo = ..., export let bar = ...
|
|
210
|
+
for (const declarator of child.namedChildren) {
|
|
211
|
+
if (declarator.type === "variable_declarator") {
|
|
212
|
+
const name = declarator.childForFieldName("name");
|
|
213
|
+
if (name)
|
|
214
|
+
results.push({ name: name.text, kind: "variable", line });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
case "variable_declaration": {
|
|
220
|
+
for (const declarator of child.namedChildren) {
|
|
221
|
+
if (declarator.type === "variable_declarator") {
|
|
222
|
+
const name = declarator.childForFieldName("name");
|
|
223
|
+
if (name)
|
|
224
|
+
results.push({ name: name.text, kind: "variable", line });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
case "interface_declaration": {
|
|
230
|
+
const name = child.childForFieldName("name");
|
|
231
|
+
if (name)
|
|
232
|
+
results.push({ name: name.text, kind: "interface", line });
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
case "type_alias_declaration": {
|
|
236
|
+
const name = child.childForFieldName("name");
|
|
237
|
+
if (name)
|
|
238
|
+
results.push({ name: name.text, kind: "type", line });
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
case "enum_declaration": {
|
|
242
|
+
const name = child.childForFieldName("name");
|
|
243
|
+
if (name)
|
|
244
|
+
results.push({ name: name.text, kind: "enum", line });
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
case "export_clause": {
|
|
248
|
+
// export { a, b, c }
|
|
249
|
+
for (const spec of child.namedChildren) {
|
|
250
|
+
if (spec.type === "export_specifier") {
|
|
251
|
+
const name = spec.childForFieldName("name");
|
|
252
|
+
if (name)
|
|
253
|
+
results.push({ name: name.text, kind: "unknown", line });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
default: {
|
|
259
|
+
// export default ...
|
|
260
|
+
if (child.text === "default") {
|
|
261
|
+
// Look for the next sibling to determine what's being exported
|
|
262
|
+
const next = child.nextNamedSibling;
|
|
263
|
+
const kind = next?.type === "function_declaration" ? "function"
|
|
264
|
+
: next?.type === "class_declaration" ? "class"
|
|
265
|
+
: "unknown";
|
|
266
|
+
const name = next?.childForFieldName("name")?.text ?? "default";
|
|
267
|
+
results.push({ name, kind: "default", line });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return results;
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=ast-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ast-analyzer.js","sourceRoot":"","sources":["../src/ast-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DependencyEdge, BlastRadiusResult, BlastRadiusEntry } from "./types.js";
|
|
2
|
+
export interface AggregateBlastRadiusResult {
|
|
3
|
+
sourceFiles: string[];
|
|
4
|
+
affected: BlastRadiusEntry[];
|
|
5
|
+
totalAffected: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Compute aggregate blast radius across multiple changed files.
|
|
9
|
+
* BFS from all source files, de-duplicating affected files (min depth wins).
|
|
10
|
+
*/
|
|
11
|
+
export declare function computeAggregateBlastRadius(fileIds: string[], edges: DependencyEdge[]): AggregateBlastRadiusResult;
|
|
12
|
+
/**
|
|
13
|
+
* Compute the blast radius of a file change.
|
|
14
|
+
* BFS through reverse dependency edges to find all downstream dependents.
|
|
15
|
+
*/
|
|
16
|
+
export declare function computeBlastRadius(fileId: string, edges: DependencyEdge[]): BlastRadiusResult;
|
|
17
|
+
//# sourceMappingURL=blast-radius.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blast-radius.d.ts","sourceRoot":"","sources":["../src/blast-radius.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEtF,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,cAAc,EAAE,GACtB,0BAA0B,CA+C5B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EAAE,GACtB,iBAAiB,CAsCnB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute aggregate blast radius across multiple changed files.
|
|
3
|
+
* BFS from all source files, de-duplicating affected files (min depth wins).
|
|
4
|
+
*/
|
|
5
|
+
export function computeAggregateBlastRadius(fileIds, edges) {
|
|
6
|
+
const reverseEdges = new Map();
|
|
7
|
+
for (const edge of edges) {
|
|
8
|
+
const existing = reverseEdges.get(edge.target) ?? [];
|
|
9
|
+
existing.push({ source: edge.source, imports: edge.imports });
|
|
10
|
+
reverseEdges.set(edge.target, existing);
|
|
11
|
+
}
|
|
12
|
+
const visited = new Set();
|
|
13
|
+
const depthMap = new Map();
|
|
14
|
+
const importsMap = new Map();
|
|
15
|
+
const queue = [];
|
|
16
|
+
for (const fileId of fileIds) {
|
|
17
|
+
visited.add(fileId);
|
|
18
|
+
queue.push({ fileId, depth: 0 });
|
|
19
|
+
}
|
|
20
|
+
while (queue.length > 0) {
|
|
21
|
+
const current = queue.shift();
|
|
22
|
+
const dependents = reverseEdges.get(current.fileId) ?? [];
|
|
23
|
+
for (const dep of dependents) {
|
|
24
|
+
if (visited.has(dep.source)) {
|
|
25
|
+
// Update depth if this path is shorter
|
|
26
|
+
const existing = depthMap.get(dep.source);
|
|
27
|
+
if (existing !== undefined && current.depth + 1 < existing) {
|
|
28
|
+
depthMap.set(dep.source, current.depth + 1);
|
|
29
|
+
}
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
visited.add(dep.source);
|
|
33
|
+
depthMap.set(dep.source, current.depth + 1);
|
|
34
|
+
importsMap.set(dep.source, dep.imports);
|
|
35
|
+
queue.push({ fileId: dep.source, depth: current.depth + 1 });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const affected = Array.from(depthMap.entries()).map(([fileId, depth]) => ({
|
|
39
|
+
fileId,
|
|
40
|
+
depth,
|
|
41
|
+
importedNames: importsMap.get(fileId) ?? [],
|
|
42
|
+
}));
|
|
43
|
+
affected.sort((a, b) => a.depth - b.depth || a.fileId.localeCompare(b.fileId));
|
|
44
|
+
return { sourceFiles: fileIds, affected, totalAffected: affected.length };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Compute the blast radius of a file change.
|
|
48
|
+
* BFS through reverse dependency edges to find all downstream dependents.
|
|
49
|
+
*/
|
|
50
|
+
export function computeBlastRadius(fileId, edges) {
|
|
51
|
+
// Build reverse adjacency map: target -> [{source, imports}]
|
|
52
|
+
const reverseEdges = new Map();
|
|
53
|
+
for (const edge of edges) {
|
|
54
|
+
const existing = reverseEdges.get(edge.target) ?? [];
|
|
55
|
+
existing.push({ source: edge.source, imports: edge.imports });
|
|
56
|
+
reverseEdges.set(edge.target, existing);
|
|
57
|
+
}
|
|
58
|
+
// BFS from the source file through reverse edges
|
|
59
|
+
const visited = new Set();
|
|
60
|
+
const queue = [{ fileId, depth: 0 }];
|
|
61
|
+
const affected = [];
|
|
62
|
+
visited.add(fileId);
|
|
63
|
+
while (queue.length > 0) {
|
|
64
|
+
const current = queue.shift();
|
|
65
|
+
const dependents = reverseEdges.get(current.fileId) ?? [];
|
|
66
|
+
for (const dep of dependents) {
|
|
67
|
+
if (visited.has(dep.source))
|
|
68
|
+
continue;
|
|
69
|
+
visited.add(dep.source);
|
|
70
|
+
affected.push({
|
|
71
|
+
fileId: dep.source,
|
|
72
|
+
depth: current.depth + 1,
|
|
73
|
+
importedNames: dep.imports,
|
|
74
|
+
});
|
|
75
|
+
queue.push({ fileId: dep.source, depth: current.depth + 1 });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Sort by depth then alphabetically
|
|
79
|
+
affected.sort((a, b) => a.depth - b.depth || a.fileId.localeCompare(b.fileId));
|
|
80
|
+
return { sourceFile: fileId, affected };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=blast-radius.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blast-radius.js","sourceRoot":"","sources":["../src/blast-radius.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type Parser from "web-tree-sitter";
|
|
2
|
+
import type { FileCallData } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Walk the full AST of a parsed file to extract function scopes and call sites.
|
|
5
|
+
* Uses a scope stack to track which function each call site belongs to.
|
|
6
|
+
*/
|
|
7
|
+
export declare function extractCallData(fileId: string, rootNode: Parser.SyntaxNode, exportedNames: Set<string>): FileCallData;
|
|
8
|
+
//# sourceMappingURL=call-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAC1C,OAAO,KAAK,EAA8B,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3E;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,CAAC,UAAU,EAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB,YAAY,CAiNd"}
|