@shvmgyl15/tsgraph 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/changes/index.test.js +2 -6
- package/dist/changes/index.test.js.map +1 -1
- package/dist/cli/index.js +184 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/git/index.test.js +4 -6
- package/dist/git/index.test.js.map +1 -1
- package/dist/opencode/index.js +1 -1
- package/dist/opencode/index.js.map +1 -1
- package/dist/opencode/index.test.js +2 -2
- package/dist/opencode/index.test.js.map +1 -1
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +12 -4
- package/dist/search/index.js.map +1 -1
- package/package.json +16 -1
- package/AGENTS.md +0 -64
- package/TODOS.md +0 -61
- package/opencode.json +0 -24
- package/src/analysis/analysis.test.ts +0 -405
- package/src/analysis/complexity.ts +0 -107
- package/src/analysis/coupling.ts +0 -106
- package/src/analysis/hotspot.ts +0 -52
- package/src/analysis/index.ts +0 -17
- package/src/boundaries/index.test.ts +0 -335
- package/src/boundaries/index.ts +0 -137
- package/src/changes/index.test.ts +0 -114
- package/src/changes/index.ts +0 -95
- package/src/cli/index.ts +0 -736
- package/src/git/index.test.ts +0 -92
- package/src/git/index.ts +0 -86
- package/src/graph/types.test.ts +0 -383
- package/src/graph/types.ts +0 -353
- package/src/mcp/mcp.test.ts +0 -176
- package/src/mcp/server.ts +0 -217
- package/src/nextjs/index.ts +0 -23
- package/src/nextjs/nextjs.test.ts +0 -233
- package/src/nextjs/pages.ts +0 -43
- package/src/nextjs/react.ts +0 -100
- package/src/nextjs/router.ts +0 -102
- package/src/nextjs/routes.ts +0 -69
- package/src/opencode/index.test.ts +0 -90
- package/src/opencode/index.ts +0 -83
- package/src/parser/index.ts +0 -339
- package/src/parser/parser.test.ts +0 -282
- package/src/plan/index.test.ts +0 -162
- package/src/plan/index.ts +0 -161
- package/src/report/index.ts +0 -128
- package/src/scanner/index.ts +0 -97
- package/src/scanner/scanner.test.ts +0 -135
- package/src/search/index.ts +0 -163
- package/src/search/search.test.ts +0 -512
- package/src/traversal/index.ts +0 -5
- package/src/traversal/traversal.test.ts +0 -266
- package/src/traversal/traversal.ts +0 -185
- package/tsconfig.json +0 -20
- package/vitest.config.ts +0 -7
|
@@ -1,512 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import fs from "node:fs";
|
|
4
|
-
import os from "node:os";
|
|
5
|
-
import {
|
|
6
|
-
makeGraph,
|
|
7
|
-
makeSymbolNode,
|
|
8
|
-
makeCallEdge,
|
|
9
|
-
makeImportEdge,
|
|
10
|
-
makePackageNode,
|
|
11
|
-
makeFileNode,
|
|
12
|
-
serialize,
|
|
13
|
-
} from "../graph/types.js";
|
|
14
|
-
import {
|
|
15
|
-
loadGraph,
|
|
16
|
-
findCallers,
|
|
17
|
-
findCallees,
|
|
18
|
-
findNode,
|
|
19
|
-
readSource,
|
|
20
|
-
querySymbols,
|
|
21
|
-
findImports,
|
|
22
|
-
findPublic,
|
|
23
|
-
focusPackage,
|
|
24
|
-
context,
|
|
25
|
-
} from "./index.js";
|
|
26
|
-
|
|
27
|
-
function createTempDir(): string {
|
|
28
|
-
return fs.mkdtempSync(path.join(os.tmpdir(), "tsgraph-test-"));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const baseSymbols = [
|
|
32
|
-
makeSymbolNode({
|
|
33
|
-
id: "src/main.ts::serve",
|
|
34
|
-
name: "serve",
|
|
35
|
-
kind: "function",
|
|
36
|
-
file: "src/main.ts",
|
|
37
|
-
line: 10,
|
|
38
|
-
endLine: 20,
|
|
39
|
-
packageName: "app",
|
|
40
|
-
isExported: true,
|
|
41
|
-
}),
|
|
42
|
-
makeSymbolNode({
|
|
43
|
-
id: "src/main.ts::greet",
|
|
44
|
-
name: "greet",
|
|
45
|
-
kind: "function",
|
|
46
|
-
file: "src/main.ts",
|
|
47
|
-
line: 22,
|
|
48
|
-
endLine: 25,
|
|
49
|
-
packageName: "app",
|
|
50
|
-
isExported: true,
|
|
51
|
-
}),
|
|
52
|
-
makeSymbolNode({
|
|
53
|
-
id: "src/main.ts::log",
|
|
54
|
-
name: "log",
|
|
55
|
-
kind: "function",
|
|
56
|
-
file: "src/main.ts",
|
|
57
|
-
line: 27,
|
|
58
|
-
endLine: 29,
|
|
59
|
-
packageName: "app",
|
|
60
|
-
isExported: false,
|
|
61
|
-
}),
|
|
62
|
-
makeSymbolNode({
|
|
63
|
-
id: "src/utils.ts::helper",
|
|
64
|
-
name: "helper",
|
|
65
|
-
kind: "function",
|
|
66
|
-
file: "src/utils.ts",
|
|
67
|
-
line: 5,
|
|
68
|
-
endLine: 7,
|
|
69
|
-
packageName: "app",
|
|
70
|
-
isExported: false,
|
|
71
|
-
}),
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
const baseCalls = [
|
|
75
|
-
makeCallEdge({
|
|
76
|
-
callerSymbolId: "src/main.ts::serve",
|
|
77
|
-
callerName: "serve",
|
|
78
|
-
calleeRaw: "greet",
|
|
79
|
-
file: "src/main.ts",
|
|
80
|
-
line: 12,
|
|
81
|
-
}),
|
|
82
|
-
makeCallEdge({
|
|
83
|
-
callerSymbolId: "src/main.ts::serve",
|
|
84
|
-
callerName: "serve",
|
|
85
|
-
calleeRaw: "log",
|
|
86
|
-
file: "src/main.ts",
|
|
87
|
-
line: 14,
|
|
88
|
-
}),
|
|
89
|
-
makeCallEdge({
|
|
90
|
-
callerSymbolId: "src/main.ts::greet",
|
|
91
|
-
callerName: "greet",
|
|
92
|
-
calleeRaw: "log",
|
|
93
|
-
file: "src/main.ts",
|
|
94
|
-
line: 23,
|
|
95
|
-
}),
|
|
96
|
-
];
|
|
97
|
-
|
|
98
|
-
const baseImports = [
|
|
99
|
-
makeImportEdge({
|
|
100
|
-
fromFile: "src/main.ts",
|
|
101
|
-
fromPackage: "app",
|
|
102
|
-
importPath: "react",
|
|
103
|
-
alias: "React",
|
|
104
|
-
isDefault: true,
|
|
105
|
-
}),
|
|
106
|
-
makeImportEdge({
|
|
107
|
-
fromFile: "src/main.ts",
|
|
108
|
-
fromPackage: "app",
|
|
109
|
-
importPath: "react",
|
|
110
|
-
alias: "useState",
|
|
111
|
-
isDefault: false,
|
|
112
|
-
}),
|
|
113
|
-
makeImportEdge({
|
|
114
|
-
fromFile: "src/utils.ts",
|
|
115
|
-
fromPackage: "app",
|
|
116
|
-
importPath: "lodash",
|
|
117
|
-
alias: "_",
|
|
118
|
-
isDefault: true,
|
|
119
|
-
}),
|
|
120
|
-
];
|
|
121
|
-
|
|
122
|
-
function buildTestGraph() {
|
|
123
|
-
return makeGraph({
|
|
124
|
-
root: "/test",
|
|
125
|
-
packages: [
|
|
126
|
-
makePackageNode({ name: "app" }),
|
|
127
|
-
makePackageNode({ name: "lib" }),
|
|
128
|
-
],
|
|
129
|
-
files: [
|
|
130
|
-
makeFileNode({ path: "src/main.ts", packageName: "app" }),
|
|
131
|
-
makeFileNode({ path: "src/utils.ts", packageName: "app" }),
|
|
132
|
-
],
|
|
133
|
-
symbols: baseSymbols,
|
|
134
|
-
calls: baseCalls,
|
|
135
|
-
imports: baseImports,
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
describe("loadGraph", () => {
|
|
140
|
-
it("round-trips from serialized file", () => {
|
|
141
|
-
const dir = createTempDir();
|
|
142
|
-
const graphPath = path.join(dir, "graph.json");
|
|
143
|
-
const original = buildTestGraph();
|
|
144
|
-
fs.writeFileSync(graphPath, serialize(original), "utf-8");
|
|
145
|
-
|
|
146
|
-
const loaded = loadGraph(graphPath);
|
|
147
|
-
expect(loaded.version).toBe(original.version);
|
|
148
|
-
expect(loaded.symbols).toHaveLength(original.symbols.length);
|
|
149
|
-
expect(loaded.calls).toHaveLength(original.calls.length);
|
|
150
|
-
fs.rmSync(dir, { recursive: true });
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it("throws on missing file", () => {
|
|
154
|
-
expect(() => loadGraph("/nonexistent/graph.json")).toThrow();
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
describe("findCallers", () => {
|
|
159
|
-
it("finds callers of a referenced symbol", () => {
|
|
160
|
-
const graph = buildTestGraph();
|
|
161
|
-
const results = findCallers(graph, "greet");
|
|
162
|
-
expect(results).toHaveLength(1);
|
|
163
|
-
expect(results[0].callerSymbol.name).toBe("serve");
|
|
164
|
-
expect(results[0].edges).toHaveLength(1);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
it("finds multiple callers of a symbol", () => {
|
|
168
|
-
const graph = buildTestGraph();
|
|
169
|
-
const results = findCallers(graph, "log");
|
|
170
|
-
expect(results).toHaveLength(2);
|
|
171
|
-
const names = results.map((r) => r.callerSymbol.name).sort();
|
|
172
|
-
expect(names).toEqual(["greet", "serve"]);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("returns empty for unreferenced symbol", () => {
|
|
176
|
-
const graph = buildTestGraph();
|
|
177
|
-
const results = findCallers(graph, "helper");
|
|
178
|
-
expect(results).toHaveLength(0);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it("returns empty for unknown symbol", () => {
|
|
182
|
-
const graph = buildTestGraph();
|
|
183
|
-
const results = findCallers(graph, "nonexistent");
|
|
184
|
-
expect(results).toHaveLength(0);
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
describe("findCallees", () => {
|
|
189
|
-
it("finds callees of a function", () => {
|
|
190
|
-
const graph = buildTestGraph();
|
|
191
|
-
const results = findCallees(graph, "serve");
|
|
192
|
-
expect(results).toHaveLength(2);
|
|
193
|
-
const names = results.map((r) => r.calleeRaw).sort();
|
|
194
|
-
expect(names).toEqual(["greet", "log"]);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it("finds callees with multiple call sites", () => {
|
|
198
|
-
const graph = buildTestGraph();
|
|
199
|
-
const results = findCallees(graph, "greet");
|
|
200
|
-
expect(results).toHaveLength(1);
|
|
201
|
-
expect(results[0].calleeRaw).toBe("log");
|
|
202
|
-
expect(results[0].edges).toHaveLength(1);
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it("returns empty for leaf function", () => {
|
|
206
|
-
const graph = buildTestGraph();
|
|
207
|
-
const results = findCallees(graph, "log");
|
|
208
|
-
expect(results).toHaveLength(0);
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
it("returns empty for unknown symbol", () => {
|
|
212
|
-
const graph = buildTestGraph();
|
|
213
|
-
const results = findCallees(graph, "noop");
|
|
214
|
-
expect(results).toHaveLength(0);
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
describe("findNode", () => {
|
|
219
|
-
it("finds a symbol by exact name", () => {
|
|
220
|
-
const graph = buildTestGraph();
|
|
221
|
-
const n = findNode(graph, "serve");
|
|
222
|
-
expect(n).toBeTruthy();
|
|
223
|
-
expect(n!.kind).toBe("function");
|
|
224
|
-
expect(n!.file).toBe("src/main.ts");
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it("returns undefined for missing symbol", () => {
|
|
228
|
-
const graph = buildTestGraph();
|
|
229
|
-
const n = findNode(graph, "noop");
|
|
230
|
-
expect(n).toBeUndefined();
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it("returns first match when names collide", () => {
|
|
234
|
-
const graph = buildTestGraph();
|
|
235
|
-
// Two symbols with same name in different files
|
|
236
|
-
graph.symbols.push(
|
|
237
|
-
makeSymbolNode({
|
|
238
|
-
id: "src/other.ts::serve",
|
|
239
|
-
name: "serve",
|
|
240
|
-
file: "src/other.ts",
|
|
241
|
-
}),
|
|
242
|
-
);
|
|
243
|
-
const n = findNode(graph, "serve");
|
|
244
|
-
expect(n).toBeTruthy();
|
|
245
|
-
expect(n!.file).toBe("src/main.ts"); // first in array
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
describe("readSource", () => {
|
|
250
|
-
it("extracts the correct line range from a file", () => {
|
|
251
|
-
const dir = createTempDir();
|
|
252
|
-
const root = dir;
|
|
253
|
-
const filePath = path.join(root, "src/main.ts");
|
|
254
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
255
|
-
fs.writeFileSync(filePath, [
|
|
256
|
-
"line 1",
|
|
257
|
-
"line 2",
|
|
258
|
-
"line 3",
|
|
259
|
-
"line 4",
|
|
260
|
-
"line 5",
|
|
261
|
-
].join("\n"), "utf-8");
|
|
262
|
-
|
|
263
|
-
const graph = makeGraph({
|
|
264
|
-
root,
|
|
265
|
-
files: [makeFileNode({ path: "src/main.ts" })],
|
|
266
|
-
symbols: [
|
|
267
|
-
makeSymbolNode({
|
|
268
|
-
id: "src/main.ts::foo",
|
|
269
|
-
name: "foo",
|
|
270
|
-
file: "src/main.ts",
|
|
271
|
-
line: 2,
|
|
272
|
-
endLine: 4,
|
|
273
|
-
}),
|
|
274
|
-
],
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
const sym = graph.symbols[0];
|
|
278
|
-
const src = readSource(graph, sym);
|
|
279
|
-
expect(src).toContain("line 2");
|
|
280
|
-
expect(src).toContain("line 3");
|
|
281
|
-
expect(src).toContain("line 4");
|
|
282
|
-
expect(src).not.toContain("line 1");
|
|
283
|
-
expect(src).not.toContain("line 5");
|
|
284
|
-
|
|
285
|
-
// should include line numbers
|
|
286
|
-
expect(src).toMatch(/^2 /m);
|
|
287
|
-
expect(src).toMatch(/^3 /m);
|
|
288
|
-
expect(src).toMatch(/^4 /m);
|
|
289
|
-
|
|
290
|
-
fs.rmSync(dir, { recursive: true });
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
it("throws on missing file", () => {
|
|
294
|
-
const graph = makeGraph({
|
|
295
|
-
root: "/nonexistent",
|
|
296
|
-
symbols: [
|
|
297
|
-
makeSymbolNode({ name: "foo", file: "foo.ts", line: 1, endLine: 3 }),
|
|
298
|
-
],
|
|
299
|
-
});
|
|
300
|
-
expect(() => readSource(graph, graph.symbols[0])).toThrow();
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
describe("querySymbols", () => {
|
|
305
|
-
it("matches symbol name case-insensitively", () => {
|
|
306
|
-
const graph = buildTestGraph();
|
|
307
|
-
const results = querySymbols(graph, "GREET");
|
|
308
|
-
expect(results).toHaveLength(1);
|
|
309
|
-
expect(results[0].name).toBe("greet");
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
it("matches file path", () => {
|
|
313
|
-
const graph = buildTestGraph();
|
|
314
|
-
const results = querySymbols(graph, "utils");
|
|
315
|
-
expect(results).toHaveLength(1);
|
|
316
|
-
expect(results[0].name).toBe("helper");
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it("matches package name", () => {
|
|
320
|
-
const graph = buildTestGraph();
|
|
321
|
-
const results = querySymbols(graph, "app");
|
|
322
|
-
// all 4 symbols are in package "app"
|
|
323
|
-
expect(results.length).toBeGreaterThanOrEqual(4);
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
it("returns all symbols for empty pattern", () => {
|
|
327
|
-
const graph = buildTestGraph();
|
|
328
|
-
const results = querySymbols(graph, "");
|
|
329
|
-
expect(results).toHaveLength(graph.symbols.length);
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
it("returns empty for no match", () => {
|
|
333
|
-
const graph = buildTestGraph();
|
|
334
|
-
const results = querySymbols(graph, "zzznone");
|
|
335
|
-
expect(results).toHaveLength(0);
|
|
336
|
-
});
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
describe("findImports", () => {
|
|
340
|
-
it("matches import path substring", () => {
|
|
341
|
-
const graph = buildTestGraph();
|
|
342
|
-
const results = findImports(graph, "react");
|
|
343
|
-
expect(results).toHaveLength(2);
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
it("returns empty for no match", () => {
|
|
347
|
-
const graph = buildTestGraph();
|
|
348
|
-
const results = findImports(graph, "noop");
|
|
349
|
-
expect(results).toHaveLength(0);
|
|
350
|
-
});
|
|
351
|
-
|
|
352
|
-
it("is case-insensitive", () => {
|
|
353
|
-
const graph = buildTestGraph();
|
|
354
|
-
const results = findImports(graph, "LODASH");
|
|
355
|
-
expect(results).toHaveLength(1);
|
|
356
|
-
expect(results[0].importPath).toBe("lodash");
|
|
357
|
-
});
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
describe("findPublic", () => {
|
|
361
|
-
it("returns only exported symbols", () => {
|
|
362
|
-
const graph = buildTestGraph();
|
|
363
|
-
const results = findPublic(graph);
|
|
364
|
-
expect(results).toHaveLength(2);
|
|
365
|
-
expect(results.every((s) => s.isExported)).toBe(true);
|
|
366
|
-
const names = results.map((s) => s.name).sort();
|
|
367
|
-
expect(names).toEqual(["greet", "serve"]);
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
it("scopes to a package when specified", () => {
|
|
371
|
-
const graph = buildTestGraph();
|
|
372
|
-
// Add an exported symbol in package "lib"
|
|
373
|
-
graph.symbols.push(
|
|
374
|
-
makeSymbolNode({
|
|
375
|
-
id: "lib/helper.ts::run",
|
|
376
|
-
name: "run",
|
|
377
|
-
kind: "function",
|
|
378
|
-
packageName: "lib",
|
|
379
|
-
isExported: true,
|
|
380
|
-
}),
|
|
381
|
-
);
|
|
382
|
-
const results = findPublic(graph, "lib");
|
|
383
|
-
expect(results).toHaveLength(1);
|
|
384
|
-
expect(results[0].name).toBe("run");
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
it("returns empty when no exported symbols in package", () => {
|
|
388
|
-
const graph = buildTestGraph();
|
|
389
|
-
const results = findPublic(graph, "missing-pkg");
|
|
390
|
-
expect(results).toHaveLength(0);
|
|
391
|
-
});
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
describe("focusPackage", () => {
|
|
395
|
-
it("returns package assets", () => {
|
|
396
|
-
const graph = buildTestGraph();
|
|
397
|
-
const result = focusPackage(graph, "app");
|
|
398
|
-
expect(result).toBeTruthy();
|
|
399
|
-
expect(result!.pkg.name).toBe("app");
|
|
400
|
-
expect(result!.files).toHaveLength(2);
|
|
401
|
-
expect(result!.symbols).toHaveLength(4);
|
|
402
|
-
expect(result!.imports).toHaveLength(3);
|
|
403
|
-
});
|
|
404
|
-
|
|
405
|
-
it("returns undefined for missing package", () => {
|
|
406
|
-
const graph = buildTestGraph();
|
|
407
|
-
const result = focusPackage(graph, "no-pkg");
|
|
408
|
-
expect(result).toBeUndefined();
|
|
409
|
-
});
|
|
410
|
-
});
|
|
411
|
-
|
|
412
|
-
describe("context", () => {
|
|
413
|
-
it("bundles node, source, callers, and callees", () => {
|
|
414
|
-
const dir = createTempDir();
|
|
415
|
-
const root = dir;
|
|
416
|
-
const filePath = path.join(root, "src/main.ts");
|
|
417
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
418
|
-
const fileLines = [
|
|
419
|
-
"",
|
|
420
|
-
"",
|
|
421
|
-
"",
|
|
422
|
-
"",
|
|
423
|
-
"",
|
|
424
|
-
"",
|
|
425
|
-
"",
|
|
426
|
-
"",
|
|
427
|
-
"",
|
|
428
|
-
"function serve() {",
|
|
429
|
-
" greet();",
|
|
430
|
-
" log();",
|
|
431
|
-
"}",
|
|
432
|
-
"",
|
|
433
|
-
"",
|
|
434
|
-
"function greet() {",
|
|
435
|
-
" log();",
|
|
436
|
-
"}",
|
|
437
|
-
];
|
|
438
|
-
fs.writeFileSync(filePath, fileLines.join("\n"), "utf-8");
|
|
439
|
-
|
|
440
|
-
const graph = makeGraph({
|
|
441
|
-
root,
|
|
442
|
-
packages: [makePackageNode({ name: "app" })],
|
|
443
|
-
files: [makeFileNode({ path: "src/main.ts", packageName: "app" })],
|
|
444
|
-
symbols: [
|
|
445
|
-
makeSymbolNode({
|
|
446
|
-
id: "src/main.ts::serve",
|
|
447
|
-
name: "serve",
|
|
448
|
-
kind: "function",
|
|
449
|
-
file: "src/main.ts",
|
|
450
|
-
line: 10,
|
|
451
|
-
endLine: 13,
|
|
452
|
-
packageName: "app",
|
|
453
|
-
isExported: true,
|
|
454
|
-
}),
|
|
455
|
-
makeSymbolNode({
|
|
456
|
-
id: "src/main.ts::greet",
|
|
457
|
-
name: "greet",
|
|
458
|
-
kind: "function",
|
|
459
|
-
file: "src/main.ts",
|
|
460
|
-
line: 16,
|
|
461
|
-
endLine: 18,
|
|
462
|
-
packageName: "app",
|
|
463
|
-
isExported: true,
|
|
464
|
-
}),
|
|
465
|
-
],
|
|
466
|
-
calls: [
|
|
467
|
-
makeCallEdge({
|
|
468
|
-
callerSymbolId: "src/main.ts::serve",
|
|
469
|
-
callerName: "serve",
|
|
470
|
-
calleeRaw: "greet",
|
|
471
|
-
file: "src/main.ts",
|
|
472
|
-
line: 11,
|
|
473
|
-
}),
|
|
474
|
-
makeCallEdge({
|
|
475
|
-
callerSymbolId: "src/main.ts::serve",
|
|
476
|
-
callerName: "serve",
|
|
477
|
-
calleeRaw: "log",
|
|
478
|
-
file: "src/main.ts",
|
|
479
|
-
line: 12,
|
|
480
|
-
}),
|
|
481
|
-
],
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
const ctx = context(graph, "serve");
|
|
485
|
-
expect(ctx.node).toBeTruthy();
|
|
486
|
-
expect(ctx.node!.name).toBe("serve");
|
|
487
|
-
expect(ctx.source).toBeTruthy();
|
|
488
|
-
expect(ctx.source).toContain("greet");
|
|
489
|
-
expect(ctx.callers).toHaveLength(0);
|
|
490
|
-
expect(ctx.callees).toHaveLength(2);
|
|
491
|
-
|
|
492
|
-
fs.rmSync(dir, { recursive: true });
|
|
493
|
-
});
|
|
494
|
-
|
|
495
|
-
it("returns empty source when file is missing", () => {
|
|
496
|
-
const graph = buildTestGraph();
|
|
497
|
-
const ctx = context(graph, "serve");
|
|
498
|
-
expect(ctx.node).toBeTruthy();
|
|
499
|
-
expect(ctx.source).toBeUndefined();
|
|
500
|
-
expect(ctx.callers).toHaveLength(0);
|
|
501
|
-
expect(ctx.callees).toHaveLength(2);
|
|
502
|
-
});
|
|
503
|
-
|
|
504
|
-
it("returns partial result for missing symbol", () => {
|
|
505
|
-
const graph = buildTestGraph();
|
|
506
|
-
const ctx = context(graph, "noop");
|
|
507
|
-
expect(ctx.node).toBeUndefined();
|
|
508
|
-
expect(ctx.source).toBeUndefined();
|
|
509
|
-
expect(ctx.callers).toHaveLength(0);
|
|
510
|
-
expect(ctx.callees).toHaveLength(0);
|
|
511
|
-
});
|
|
512
|
-
});
|
package/src/traversal/index.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import { impact, findPath, findOrphans, trace } from "./traversal.js";
|
|
2
|
-
import type { ImpactNode, PathNode, OrphanResult, TraceResult, TraceMatch } from "./traversal.js";
|
|
3
|
-
|
|
4
|
-
export { impact, findPath, findOrphans, trace };
|
|
5
|
-
export type { ImpactNode, PathNode, OrphanResult, TraceResult, TraceMatch };
|