lsp-intelligence 0.2.1 → 0.3.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/adapters/express/index.d.ts +9 -0
- package/dist/adapters/express/index.js +46 -0
- package/dist/adapters/express/index.js.map +1 -0
- package/dist/adapters/next/index.d.ts +10 -0
- package/dist/adapters/next/index.js +67 -0
- package/dist/adapters/next/index.js.map +1 -0
- package/dist/adapters/react/index.d.ts +11 -0
- package/dist/adapters/react/index.js +133 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/registry.d.ts +22 -0
- package/dist/adapters/registry.js +101 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/types.d.ts +97 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/analysis/ts/applyVirtualEdit.d.ts +27 -0
- package/dist/analysis/ts/applyVirtualEdit.js +235 -0
- package/dist/analysis/ts/applyVirtualEdit.js.map +1 -0
- package/dist/analysis/ts/changeRecipes.d.ts +52 -0
- package/dist/analysis/ts/changeRecipes.js +14 -0
- package/dist/analysis/ts/changeRecipes.js.map +1 -0
- package/dist/analysis/ts/compatibility.d.ts +54 -0
- package/dist/analysis/ts/compatibility.js +113 -0
- package/dist/analysis/ts/compatibility.js.map +1 -0
- package/dist/analysis/ts/diffDeclarationShape.d.ts +26 -0
- package/dist/analysis/ts/diffDeclarationShape.js +114 -0
- package/dist/analysis/ts/diffDeclarationShape.js.map +1 -0
- package/dist/analysis/ts/exhaustiveness.d.ts +49 -0
- package/dist/analysis/ts/exhaustiveness.js +158 -0
- package/dist/analysis/ts/exhaustiveness.js.map +1 -0
- package/dist/analysis/ts/extractDeclarationShape.d.ts +30 -0
- package/dist/analysis/ts/extractDeclarationShape.js +127 -0
- package/dist/analysis/ts/extractDeclarationShape.js.map +1 -0
- package/dist/analysis/ts/extractExports.d.ts +19 -0
- package/dist/analysis/ts/extractExports.js +178 -0
- package/dist/analysis/ts/extractExports.js.map +1 -0
- package/dist/analysis/ts/extractRoutes.d.ts +12 -0
- package/dist/analysis/ts/extractRoutes.js +165 -0
- package/dist/analysis/ts/extractRoutes.js.map +1 -0
- package/dist/analysis/ts/parseSourceFile.d.ts +5 -1
- package/dist/analysis/ts/parseSourceFile.js +6 -2
- package/dist/analysis/ts/parseSourceFile.js.map +1 -1
- package/dist/analysis/ts/program/CheckerQueries.d.ts +56 -0
- package/dist/analysis/ts/program/CheckerQueries.js +187 -0
- package/dist/analysis/ts/program/CheckerQueries.js.map +1 -0
- package/dist/analysis/ts/program/ProgramManager.d.ts +27 -0
- package/dist/analysis/ts/program/ProgramManager.js +147 -0
- package/dist/analysis/ts/program/ProgramManager.js.map +1 -0
- package/dist/analysis/ts/program/TypeFacts.d.ts +58 -0
- package/dist/analysis/ts/program/TypeFacts.js +68 -0
- package/dist/analysis/ts/program/TypeFacts.js.map +1 -0
- package/dist/analysis/ts/typeState.d.ts +46 -0
- package/dist/analysis/ts/typeState.js +108 -0
- package/dist/analysis/ts/typeState.js.map +1 -0
- package/dist/ast/diffDeclarationShapes.js +25 -11
- package/dist/ast/diffDeclarationShapes.js.map +1 -1
- package/dist/ast/extractExportDeclarations.js +8 -3
- package/dist/ast/extractExportDeclarations.js.map +1 -1
- package/dist/cache/CacheSchema.d.ts +30 -0
- package/dist/cache/CacheSchema.js +9 -0
- package/dist/cache/CacheSchema.js.map +1 -0
- package/dist/cache/CacheStore.d.ts +22 -0
- package/dist/cache/CacheStore.js +111 -0
- package/dist/cache/CacheStore.js.map +1 -0
- package/dist/cache/SemanticCache.d.ts +38 -0
- package/dist/cache/SemanticCache.js +87 -0
- package/dist/cache/SemanticCache.js.map +1 -0
- package/dist/cache/SnapshotFingerprint.d.ts +17 -0
- package/dist/cache/SnapshotFingerprint.js +14 -0
- package/dist/cache/SnapshotFingerprint.js.map +1 -0
- package/dist/engine/DocumentManager.d.ts +16 -0
- package/dist/engine/DocumentManager.js +32 -0
- package/dist/engine/DocumentManager.js.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/search/adapters/http.d.ts +9 -3
- package/dist/search/adapters/http.js +7 -52
- package/dist/search/adapters/http.js.map +1 -1
- package/dist/search/adapters/react.d.ts +8 -8
- package/dist/search/adapters/react.js +3 -88
- package/dist/search/adapters/react.js.map +1 -1
- package/dist/search/adapters/registry.d.ts +7 -4
- package/dist/search/adapters/registry.js +7 -17
- package/dist/search/adapters/registry.js.map +1 -1
- package/dist/search/expand/graphExpansion.js +47 -14
- package/dist/search/expand/graphExpansion.js.map +1 -1
- package/dist/search/index/declarationIndex.d.ts +3 -1
- package/dist/search/index/declarationIndex.js +4 -2
- package/dist/search/index/declarationIndex.js.map +1 -1
- package/dist/search/index/routeIndex.d.ts +6 -0
- package/dist/search/index/routeIndex.js +19 -0
- package/dist/search/index/routeIndex.js.map +1 -0
- package/dist/search/index/usageIndex.d.ts +3 -1
- package/dist/search/index/usageIndex.js +4 -2
- package/dist/search/index/usageIndex.js.map +1 -1
- package/dist/search/index/workspaceIndex.d.ts +7 -1
- package/dist/search/index/workspaceIndex.js +54 -14
- package/dist/search/index/workspaceIndex.js.map +1 -1
- package/dist/search/query/compileEffectiveSearchSpec.js +9 -0
- package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -1
- package/dist/search/query/parseQuery.js +5 -1
- package/dist/search/query/parseQuery.js.map +1 -1
- package/dist/search/query/planQuery.js +14 -4
- package/dist/search/query/planQuery.js.map +1 -1
- package/dist/search/ranking/mergeCandidates.d.ts +1 -0
- package/dist/search/ranking/mergeCandidates.js +16 -0
- package/dist/search/ranking/mergeCandidates.js.map +1 -1
- package/dist/search/retrievers/routeRetriever.d.ts +7 -0
- package/dist/search/retrievers/routeRetriever.js +64 -0
- package/dist/search/retrievers/routeRetriever.js.map +1 -0
- package/dist/search/types.d.ts +16 -4
- package/dist/session/OverlayStore.d.ts +15 -0
- package/dist/session/OverlayStore.js +46 -0
- package/dist/session/OverlayStore.js.map +1 -0
- package/dist/session/SnapshotResolver.d.ts +31 -0
- package/dist/session/SnapshotResolver.js +50 -0
- package/dist/session/SnapshotResolver.js.map +1 -0
- package/dist/session/WorkspaceSnapshot.d.ts +21 -0
- package/dist/session/WorkspaceSnapshot.js +2 -0
- package/dist/session/WorkspaceSnapshot.js.map +1 -0
- package/dist/tools/composites/apiGuard.d.ts +4 -0
- package/dist/tools/composites/apiGuard.js +158 -24
- package/dist/tools/composites/apiGuard.js.map +1 -1
- package/dist/tools/composites/findCode.js +12 -2
- package/dist/tools/composites/findCode.js.map +1 -1
- package/dist/tools/composites/rootCauseTrace.js +89 -13
- package/dist/tools/composites/rootCauseTrace.js.map +1 -1
- package/dist/workflows/simulateChange.d.ts +44 -0
- package/dist/workflows/simulateChange.js +194 -0
- package/dist/workflows/simulateChange.js.map +1 -0
- package/dist/workflows/verifyChangeSet.d.ts +58 -0
- package/dist/workflows/verifyChangeSet.js +300 -0
- package/dist/workflows/verifyChangeSet.js.map +1 -0
- package/package.json +6 -4
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Phase 2D — Switch exhaustiveness intelligence.
|
|
4
|
+
*
|
|
5
|
+
* Answers questions that a graph product cannot answer from structure alone:
|
|
6
|
+
* - "Which switches break if I add/remove this enum member?"
|
|
7
|
+
* - "Is this switch exhaustive over its enum?"
|
|
8
|
+
*
|
|
9
|
+
* Builds on the TypeScript checker (Phase 2C) for accurate type information.
|
|
10
|
+
*/
|
|
11
|
+
export interface SwitchExhaustivenessResult {
|
|
12
|
+
filePath: string;
|
|
13
|
+
/** 1-indexed line number of the switch keyword */
|
|
14
|
+
line: number;
|
|
15
|
+
/** Enum members that are explicitly handled in this switch */
|
|
16
|
+
handledMembers: string[];
|
|
17
|
+
/** Enum members NOT handled (and no default case covers them) */
|
|
18
|
+
missingMembers: string[];
|
|
19
|
+
/** True if there is a default case (covers missing members at runtime) */
|
|
20
|
+
hasDefaultCase: boolean;
|
|
21
|
+
/** Whether the switch is exhaustive — all members covered OR has default */
|
|
22
|
+
isExhaustive: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Find all non-exhaustive switch statements for a given enum across the program.
|
|
26
|
+
* "Non-exhaustive" means: missing at least one enum member AND no default case.
|
|
27
|
+
*
|
|
28
|
+
* This is the core "smarter than a graph" query: the TypeScript checker knows
|
|
29
|
+
* which type is being switched on, and we can verify coverage precisely.
|
|
30
|
+
*/
|
|
31
|
+
export declare function findNonExhaustiveSwitches(program: ts.Program, enumFilePath: string, enumName: string): SwitchExhaustivenessResult[];
|
|
32
|
+
/**
|
|
33
|
+
* Predict the exhaustiveness impact of adding a new enum member.
|
|
34
|
+
* Returns which switches would become non-exhaustive — i.e., they currently
|
|
35
|
+
* handle all members but would miss the new one.
|
|
36
|
+
*/
|
|
37
|
+
export declare function predictAddedMemberImpact(program: ts.Program, enumFilePath: string, enumName: string, newMemberName: string): {
|
|
38
|
+
affectedSwitches: Array<{
|
|
39
|
+
filePath: string;
|
|
40
|
+
line: number;
|
|
41
|
+
missingMember: string;
|
|
42
|
+
}>;
|
|
43
|
+
safeCount: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Get all switch exhaustiveness results for an enum, including exhaustive ones.
|
|
47
|
+
* Useful for a full picture: which files use this enum in a switch.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getAllSwitchResults(program: ts.Program, enumFilePath: string, enumName: string): SwitchExhaustivenessResult[];
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Find all non-exhaustive switch statements for a given enum across the program.
|
|
4
|
+
* "Non-exhaustive" means: missing at least one enum member AND no default case.
|
|
5
|
+
*
|
|
6
|
+
* This is the core "smarter than a graph" query: the TypeScript checker knows
|
|
7
|
+
* which type is being switched on, and we can verify coverage precisely.
|
|
8
|
+
*/
|
|
9
|
+
export function findNonExhaustiveSwitches(program, enumFilePath, enumName) {
|
|
10
|
+
const checker = program.getTypeChecker();
|
|
11
|
+
const allMembers = getEnumMembers(program, enumFilePath, enumName);
|
|
12
|
+
if (!allMembers)
|
|
13
|
+
return [];
|
|
14
|
+
const results = [];
|
|
15
|
+
for (const sf of program.getSourceFiles()) {
|
|
16
|
+
if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
|
|
17
|
+
continue;
|
|
18
|
+
ts.forEachChild(sf, function visitNode(node) {
|
|
19
|
+
if (ts.isSwitchStatement(node)) {
|
|
20
|
+
const result = analyzeSwitchForEnum(node, sf, checker, enumName, allMembers);
|
|
21
|
+
if (result)
|
|
22
|
+
results.push({ filePath: sf.fileName, ...result });
|
|
23
|
+
}
|
|
24
|
+
ts.forEachChild(node, visitNode);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return results.filter((r) => !r.isExhaustive);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Predict the exhaustiveness impact of adding a new enum member.
|
|
31
|
+
* Returns which switches would become non-exhaustive — i.e., they currently
|
|
32
|
+
* handle all members but would miss the new one.
|
|
33
|
+
*/
|
|
34
|
+
export function predictAddedMemberImpact(program, enumFilePath, enumName, newMemberName) {
|
|
35
|
+
const checker = program.getTypeChecker();
|
|
36
|
+
const currentMembers = getEnumMembers(program, enumFilePath, enumName);
|
|
37
|
+
if (!currentMembers)
|
|
38
|
+
return { affectedSwitches: [], safeCount: 0 };
|
|
39
|
+
const affectedSwitches = [];
|
|
40
|
+
let safeCount = 0;
|
|
41
|
+
for (const sf of program.getSourceFiles()) {
|
|
42
|
+
if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
|
|
43
|
+
continue;
|
|
44
|
+
ts.forEachChild(sf, function visitNode(node) {
|
|
45
|
+
if (ts.isSwitchStatement(node)) {
|
|
46
|
+
const result = analyzeSwitchForEnum(node, sf, checker, enumName, currentMembers);
|
|
47
|
+
if (result && result.handledMembers.length > 0) {
|
|
48
|
+
// This switch uses the enum
|
|
49
|
+
if (!result.hasDefaultCase) {
|
|
50
|
+
// No default — adding a new member would make it non-exhaustive
|
|
51
|
+
affectedSwitches.push({ filePath: sf.fileName, line: result.line, missingMember: newMemberName });
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
safeCount++;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
ts.forEachChild(node, visitNode);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return { affectedSwitches, safeCount };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get all switch exhaustiveness results for an enum, including exhaustive ones.
|
|
65
|
+
* Useful for a full picture: which files use this enum in a switch.
|
|
66
|
+
*/
|
|
67
|
+
export function getAllSwitchResults(program, enumFilePath, enumName) {
|
|
68
|
+
const checker = program.getTypeChecker();
|
|
69
|
+
const allMembers = getEnumMembers(program, enumFilePath, enumName);
|
|
70
|
+
if (!allMembers)
|
|
71
|
+
return [];
|
|
72
|
+
const results = [];
|
|
73
|
+
for (const sf of program.getSourceFiles()) {
|
|
74
|
+
if (sf.fileName.includes('node_modules') || sf.fileName.endsWith('.d.ts'))
|
|
75
|
+
continue;
|
|
76
|
+
ts.forEachChild(sf, function visitNode(node) {
|
|
77
|
+
if (ts.isSwitchStatement(node)) {
|
|
78
|
+
const result = analyzeSwitchForEnum(node, sf, checker, enumName, allMembers);
|
|
79
|
+
if (result)
|
|
80
|
+
results.push({ filePath: sf.fileName, ...result });
|
|
81
|
+
}
|
|
82
|
+
ts.forEachChild(node, visitNode);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return results;
|
|
86
|
+
}
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Internal helpers
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
function getEnumMembers(program, filePath, enumName) {
|
|
91
|
+
const sf = program.getSourceFile(filePath);
|
|
92
|
+
if (!sf)
|
|
93
|
+
return null;
|
|
94
|
+
let members = null;
|
|
95
|
+
ts.forEachChild(sf, (node) => {
|
|
96
|
+
if (ts.isEnumDeclaration(node) && node.name.text === enumName) {
|
|
97
|
+
members = node.members.map((m) => (ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sf)));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return members;
|
|
101
|
+
}
|
|
102
|
+
function analyzeSwitchForEnum(node, sf, checker, enumName, allMembers) {
|
|
103
|
+
// Check if the switch expression uses the enum type
|
|
104
|
+
const switchType = checker.getTypeAtLocation(node.expression);
|
|
105
|
+
const typeSym = switchType.getSymbol() ?? switchType.aliasSymbol;
|
|
106
|
+
const typeStr = checker.typeToString(switchType);
|
|
107
|
+
const usesEnum = typeSym?.name === enumName || typeStr === enumName;
|
|
108
|
+
if (!usesEnum) {
|
|
109
|
+
// Also check if any case clause uses EnumName.Member pattern
|
|
110
|
+
const hasMemberAccess = hasCaseWithEnumAccess(node, enumName, allMembers, sf);
|
|
111
|
+
if (!hasMemberAccess)
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const handled = new Set();
|
|
115
|
+
let hasDefaultCase = false;
|
|
116
|
+
for (const clause of node.caseBlock.clauses) {
|
|
117
|
+
if (ts.isDefaultClause(clause)) {
|
|
118
|
+
hasDefaultCase = true;
|
|
119
|
+
}
|
|
120
|
+
else if (ts.isCaseClause(clause)) {
|
|
121
|
+
const memberName = extractEnumMemberFromExpr(clause.expression, enumName, sf);
|
|
122
|
+
if (memberName && allMembers.includes(memberName)) {
|
|
123
|
+
handled.add(memberName);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (handled.size === 0 && !hasDefaultCase)
|
|
128
|
+
return null; // Not actually using this enum
|
|
129
|
+
const missingMembers = allMembers.filter((m) => !handled.has(m));
|
|
130
|
+
const line = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
|
|
131
|
+
return {
|
|
132
|
+
line,
|
|
133
|
+
handledMembers: [...handled],
|
|
134
|
+
missingMembers,
|
|
135
|
+
hasDefaultCase,
|
|
136
|
+
isExhaustive: missingMembers.length === 0 || hasDefaultCase,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function extractEnumMemberFromExpr(expr, enumName, sf) {
|
|
140
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
141
|
+
const obj = expr.expression;
|
|
142
|
+
if (ts.isIdentifier(obj) && obj.text === enumName) {
|
|
143
|
+
return expr.name.text;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
function hasCaseWithEnumAccess(node, enumName, members, sf) {
|
|
149
|
+
for (const clause of node.caseBlock.clauses) {
|
|
150
|
+
if (ts.isCaseClause(clause)) {
|
|
151
|
+
const m = extractEnumMemberFromExpr(clause.expression, enumName, sf);
|
|
152
|
+
if (m && members.includes(m))
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=exhaustiveness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exhaustiveness.js","sourceRoot":"","sources":["../../../src/analysis/ts/exhaustiveness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import type { ExportedDeclaration } from './extractExports.js';
|
|
3
|
+
export interface ParamShape {
|
|
4
|
+
name: string;
|
|
5
|
+
optional: boolean;
|
|
6
|
+
rest: boolean;
|
|
7
|
+
typeText?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface MemberShape {
|
|
10
|
+
name: string;
|
|
11
|
+
optional?: boolean;
|
|
12
|
+
typeText?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface DeclarationShape {
|
|
15
|
+
name: string;
|
|
16
|
+
kind: ExportedDeclaration['kind'];
|
|
17
|
+
line: number;
|
|
18
|
+
signatureText: string;
|
|
19
|
+
params?: ParamShape[];
|
|
20
|
+
returnTypeText?: string;
|
|
21
|
+
members?: MemberShape[];
|
|
22
|
+
enumMembers?: string[];
|
|
23
|
+
exportedAs?: string[];
|
|
24
|
+
moduleSpecifier?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Extract the shape of an exported declaration for diffing.
|
|
28
|
+
* Works on the TS AST node near the export's line.
|
|
29
|
+
*/
|
|
30
|
+
export declare function extractDeclarationShape(sf: ts.SourceFile, exp: ExportedDeclaration): DeclarationShape;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Extract the shape of an exported declaration for diffing.
|
|
4
|
+
* Works on the TS AST node near the export's line.
|
|
5
|
+
*/
|
|
6
|
+
export function extractDeclarationShape(sf, exp) {
|
|
7
|
+
const base = {
|
|
8
|
+
name: exp.name,
|
|
9
|
+
kind: exp.kind,
|
|
10
|
+
line: exp.line,
|
|
11
|
+
signatureText: '',
|
|
12
|
+
exportedAs: exp.exportedAs,
|
|
13
|
+
moduleSpecifier: exp.moduleSpecifier,
|
|
14
|
+
};
|
|
15
|
+
// Find the node at the export's line
|
|
16
|
+
const node = findNodeAtLine(sf, exp.line - 1);
|
|
17
|
+
if (!node)
|
|
18
|
+
return { ...base, signatureText: `${exp.kind} ${exp.name}` };
|
|
19
|
+
// Function
|
|
20
|
+
if (ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {
|
|
21
|
+
base.params = extractParams(node);
|
|
22
|
+
base.returnTypeText = node.type ? node.type.getText(sf) : undefined;
|
|
23
|
+
base.signatureText = `function ${exp.name}(${formatParams(base.params)}): ${base.returnTypeText ?? 'unknown'}`;
|
|
24
|
+
return base;
|
|
25
|
+
}
|
|
26
|
+
// Method (inside class)
|
|
27
|
+
if (ts.isMethodDeclaration(node)) {
|
|
28
|
+
base.params = extractParams(node);
|
|
29
|
+
base.returnTypeText = node.type ? node.type.getText(sf) : undefined;
|
|
30
|
+
base.signatureText = `method ${exp.name}(${formatParams(base.params)})`;
|
|
31
|
+
return base;
|
|
32
|
+
}
|
|
33
|
+
// Interface
|
|
34
|
+
if (ts.isInterfaceDeclaration(node)) {
|
|
35
|
+
base.members = extractMembers(node, sf);
|
|
36
|
+
base.signatureText = `interface ${exp.name} { ${base.members.map((m) => m.name).join(', ')} }`;
|
|
37
|
+
return base;
|
|
38
|
+
}
|
|
39
|
+
// Type alias
|
|
40
|
+
if (ts.isTypeAliasDeclaration(node)) {
|
|
41
|
+
base.signatureText = `type ${exp.name} = ${node.type.getText(sf).substring(0, 100)}`;
|
|
42
|
+
return base;
|
|
43
|
+
}
|
|
44
|
+
// Enum
|
|
45
|
+
if (ts.isEnumDeclaration(node)) {
|
|
46
|
+
base.enumMembers = node.members.map((m) => ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sf));
|
|
47
|
+
base.signatureText = `enum ${exp.name} { ${base.enumMembers.join(', ')} }`;
|
|
48
|
+
return base;
|
|
49
|
+
}
|
|
50
|
+
// Variable
|
|
51
|
+
if (ts.isVariableStatement(node)) {
|
|
52
|
+
for (const decl of node.declarationList.declarations) {
|
|
53
|
+
if (ts.isIdentifier(decl.name) && decl.name.text === exp.name) {
|
|
54
|
+
if (decl.initializer && (ts.isArrowFunction(decl.initializer) || ts.isFunctionExpression(decl.initializer))) {
|
|
55
|
+
base.params = extractParams(decl.initializer);
|
|
56
|
+
base.returnTypeText = decl.initializer.type ? decl.initializer.type.getText(sf) : undefined;
|
|
57
|
+
base.signatureText = `const ${exp.name} = (${formatParams(base.params)}) => ${base.returnTypeText ?? '...'}`;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
base.signatureText = `const ${exp.name}: ${decl.type?.getText(sf) ?? 'unknown'}`;
|
|
61
|
+
}
|
|
62
|
+
return base;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Class
|
|
67
|
+
if (ts.isClassDeclaration(node)) {
|
|
68
|
+
base.members = [];
|
|
69
|
+
for (const member of node.members) {
|
|
70
|
+
if (ts.isMethodDeclaration(member) && ts.isIdentifier(member.name)) {
|
|
71
|
+
base.members.push({ name: member.name.text });
|
|
72
|
+
}
|
|
73
|
+
else if (ts.isPropertyDeclaration(member) && ts.isIdentifier(member.name)) {
|
|
74
|
+
base.members.push({
|
|
75
|
+
name: member.name.text,
|
|
76
|
+
optional: !!member.questionToken,
|
|
77
|
+
typeText: member.type?.getText(sf),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
base.signatureText = `class ${exp.name} { ${base.members.map((m) => m.name).join(', ')} }`;
|
|
82
|
+
return base;
|
|
83
|
+
}
|
|
84
|
+
base.signatureText = `${exp.kind} ${exp.name}`;
|
|
85
|
+
return base;
|
|
86
|
+
}
|
|
87
|
+
function extractParams(node) {
|
|
88
|
+
return node.parameters.map((p) => ({
|
|
89
|
+
name: ts.isIdentifier(p.name) ? p.name.text : p.name.getText(),
|
|
90
|
+
optional: !!p.questionToken || !!p.initializer,
|
|
91
|
+
rest: !!p.dotDotDotToken,
|
|
92
|
+
typeText: p.type?.getText() ?? undefined,
|
|
93
|
+
}));
|
|
94
|
+
}
|
|
95
|
+
function extractMembers(node, sf) {
|
|
96
|
+
return node.members
|
|
97
|
+
.filter((m) => ts.isPropertySignature(m))
|
|
98
|
+
.map((m) => ({
|
|
99
|
+
name: ts.isIdentifier(m.name) ? m.name.text : m.name.getText(sf),
|
|
100
|
+
optional: !!m.questionToken,
|
|
101
|
+
typeText: m.type?.getText(sf),
|
|
102
|
+
}));
|
|
103
|
+
}
|
|
104
|
+
function formatParams(params) {
|
|
105
|
+
return params.map((p) => `${p.rest ? '...' : ''}${p.name}${p.optional ? '?' : ''}`).join(', ');
|
|
106
|
+
}
|
|
107
|
+
function findNodeAtLine(sf, line0) {
|
|
108
|
+
let found;
|
|
109
|
+
function visit(node) {
|
|
110
|
+
if (found)
|
|
111
|
+
return;
|
|
112
|
+
const nodeLine = sf.getLineAndCharacterOfPosition(node.getStart(sf)).line;
|
|
113
|
+
if (nodeLine === line0 || nodeLine === line0 + 1 || nodeLine === line0 - 1) {
|
|
114
|
+
// Prefer specific declaration types
|
|
115
|
+
if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) ||
|
|
116
|
+
ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) ||
|
|
117
|
+
ts.isEnumDeclaration(node) || ts.isVariableStatement(node)) {
|
|
118
|
+
found = node;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
ts.forEachChild(node, visit);
|
|
123
|
+
}
|
|
124
|
+
visit(sf);
|
|
125
|
+
return found;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=extractDeclarationShape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractDeclarationShape.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractDeclarationShape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Exported declaration — the shared type used by api_guard and root_cause_trace.
|
|
4
|
+
*/
|
|
5
|
+
export interface ExportedDeclaration {
|
|
6
|
+
name: string;
|
|
7
|
+
exportedAs: string[];
|
|
8
|
+
kind: 'function' | 'class' | 'interface' | 'type' | 'enum' | 'const' | 'var' | 'default' | 'reexport' | 'cjs' | 'unknown';
|
|
9
|
+
filePath: string;
|
|
10
|
+
line: number;
|
|
11
|
+
isTypeOnly?: boolean;
|
|
12
|
+
moduleSpecifier?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extract all exports from a TypeScript/JavaScript source file using the TS AST.
|
|
16
|
+
* Supports ESM (export function, export const, export { }, export * from, export default)
|
|
17
|
+
* and basic CJS (module.exports, exports.foo).
|
|
18
|
+
*/
|
|
19
|
+
export declare function extractExports(sf: ts.SourceFile): ExportedDeclaration[];
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Extract all exports from a TypeScript/JavaScript source file using the TS AST.
|
|
4
|
+
* Supports ESM (export function, export const, export { }, export * from, export default)
|
|
5
|
+
* and basic CJS (module.exports, exports.foo).
|
|
6
|
+
*/
|
|
7
|
+
export function extractExports(sf) {
|
|
8
|
+
const exports = [];
|
|
9
|
+
const filePath = sf.fileName;
|
|
10
|
+
function visit(node) {
|
|
11
|
+
// ESM: export function foo() {}
|
|
12
|
+
if (ts.isFunctionDeclaration(node) && hasExportModifier(node) && node.name) {
|
|
13
|
+
exports.push({
|
|
14
|
+
name: node.name.text,
|
|
15
|
+
exportedAs: [node.name.text],
|
|
16
|
+
kind: 'function',
|
|
17
|
+
filePath,
|
|
18
|
+
line: lineOf(node, sf),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
// ESM: export class Foo {}
|
|
22
|
+
if (ts.isClassDeclaration(node) && hasExportModifier(node) && node.name) {
|
|
23
|
+
exports.push({
|
|
24
|
+
name: node.name.text,
|
|
25
|
+
exportedAs: [node.name.text],
|
|
26
|
+
kind: 'class',
|
|
27
|
+
filePath,
|
|
28
|
+
line: lineOf(node, sf),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// ESM: export interface Foo {}
|
|
32
|
+
if (ts.isInterfaceDeclaration(node) && hasExportModifier(node)) {
|
|
33
|
+
exports.push({
|
|
34
|
+
name: node.name.text,
|
|
35
|
+
exportedAs: [node.name.text],
|
|
36
|
+
kind: 'interface',
|
|
37
|
+
filePath,
|
|
38
|
+
line: lineOf(node, sf),
|
|
39
|
+
isTypeOnly: true,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// ESM: export type Foo = ...
|
|
43
|
+
if (ts.isTypeAliasDeclaration(node) && hasExportModifier(node)) {
|
|
44
|
+
exports.push({
|
|
45
|
+
name: node.name.text,
|
|
46
|
+
exportedAs: [node.name.text],
|
|
47
|
+
kind: 'type',
|
|
48
|
+
filePath,
|
|
49
|
+
line: lineOf(node, sf),
|
|
50
|
+
isTypeOnly: true,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
// ESM: export enum Foo {}
|
|
54
|
+
if (ts.isEnumDeclaration(node) && hasExportModifier(node)) {
|
|
55
|
+
exports.push({
|
|
56
|
+
name: node.name.text,
|
|
57
|
+
exportedAs: [node.name.text],
|
|
58
|
+
kind: 'enum',
|
|
59
|
+
filePath,
|
|
60
|
+
line: lineOf(node, sf),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// ESM: export const foo = ..., export let bar = ...
|
|
64
|
+
if (ts.isVariableStatement(node) && hasExportModifier(node)) {
|
|
65
|
+
for (const decl of node.declarationList.declarations) {
|
|
66
|
+
if (ts.isIdentifier(decl.name)) {
|
|
67
|
+
exports.push({
|
|
68
|
+
name: decl.name.text,
|
|
69
|
+
exportedAs: [decl.name.text],
|
|
70
|
+
kind: node.declarationList.flags & ts.NodeFlags.Const ? 'const' : 'var',
|
|
71
|
+
filePath,
|
|
72
|
+
line: lineOf(node, sf),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// ESM: export default ...
|
|
78
|
+
if (ts.isExportAssignment(node) && !node.isExportEquals) {
|
|
79
|
+
const name = ts.isIdentifier(node.expression) ? node.expression.text : 'default';
|
|
80
|
+
exports.push({
|
|
81
|
+
name,
|
|
82
|
+
exportedAs: ['default'],
|
|
83
|
+
kind: 'default',
|
|
84
|
+
filePath,
|
|
85
|
+
line: lineOf(node, sf),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
// ESM: export { foo, bar as baz }
|
|
89
|
+
if (ts.isExportDeclaration(node)) {
|
|
90
|
+
const moduleSpec = node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)
|
|
91
|
+
? node.moduleSpecifier.text : undefined;
|
|
92
|
+
if (node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
93
|
+
for (const spec of node.exportClause.elements) {
|
|
94
|
+
const localName = (spec.propertyName ?? spec.name).text;
|
|
95
|
+
const exportedName = spec.name.text;
|
|
96
|
+
exports.push({
|
|
97
|
+
name: localName,
|
|
98
|
+
exportedAs: [exportedName],
|
|
99
|
+
kind: moduleSpec ? 'reexport' : 'unknown',
|
|
100
|
+
filePath,
|
|
101
|
+
line: lineOf(spec, sf),
|
|
102
|
+
isTypeOnly: node.isTypeOnly || spec.isTypeOnly,
|
|
103
|
+
moduleSpecifier: moduleSpec,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (!node.exportClause && moduleSpec) {
|
|
108
|
+
// export * from '...'
|
|
109
|
+
exports.push({
|
|
110
|
+
name: '*',
|
|
111
|
+
exportedAs: ['*'],
|
|
112
|
+
kind: 'reexport',
|
|
113
|
+
filePath,
|
|
114
|
+
line: lineOf(node, sf),
|
|
115
|
+
moduleSpecifier: moduleSpec,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// CJS: module.exports = ... or module.exports.foo = ...
|
|
120
|
+
if (ts.isExpressionStatement(node) && ts.isBinaryExpression(node.expression)) {
|
|
121
|
+
const left = node.expression.left;
|
|
122
|
+
if (ts.isPropertyAccessExpression(left)) {
|
|
123
|
+
const text = getPropertyChain(left);
|
|
124
|
+
if (text === 'module.exports') {
|
|
125
|
+
exports.push({
|
|
126
|
+
name: 'default',
|
|
127
|
+
exportedAs: ['default'],
|
|
128
|
+
kind: 'cjs',
|
|
129
|
+
filePath,
|
|
130
|
+
line: lineOf(node, sf),
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else if (text.startsWith('module.exports.')) {
|
|
134
|
+
const name = text.slice('module.exports.'.length);
|
|
135
|
+
exports.push({
|
|
136
|
+
name,
|
|
137
|
+
exportedAs: [name],
|
|
138
|
+
kind: 'cjs',
|
|
139
|
+
filePath,
|
|
140
|
+
line: lineOf(node, sf),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if (text.startsWith('exports.')) {
|
|
144
|
+
const name = text.slice('exports.'.length);
|
|
145
|
+
exports.push({
|
|
146
|
+
name,
|
|
147
|
+
exportedAs: [name],
|
|
148
|
+
kind: 'cjs',
|
|
149
|
+
filePath,
|
|
150
|
+
line: lineOf(node, sf),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
ts.forEachChild(node, visit);
|
|
156
|
+
}
|
|
157
|
+
visit(sf);
|
|
158
|
+
return exports;
|
|
159
|
+
}
|
|
160
|
+
function hasExportModifier(node) {
|
|
161
|
+
const mods = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;
|
|
162
|
+
return mods?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
|
|
163
|
+
}
|
|
164
|
+
function lineOf(node, sf) {
|
|
165
|
+
return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
|
|
166
|
+
}
|
|
167
|
+
function getPropertyChain(node) {
|
|
168
|
+
const parts = [node.name.text];
|
|
169
|
+
let current = node.expression;
|
|
170
|
+
while (ts.isPropertyAccessExpression(current)) {
|
|
171
|
+
parts.unshift(current.name.text);
|
|
172
|
+
current = current.expression;
|
|
173
|
+
}
|
|
174
|
+
if (ts.isIdentifier(current))
|
|
175
|
+
parts.unshift(current.text);
|
|
176
|
+
return parts.join('.');
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=extractExports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractExports.js","sourceRoot":"","sources":["../../../src/analysis/ts/extractExports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import ts from 'typescript';
|
|
2
|
+
import type { RouteIndexEntry } from '../../search/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extract route definitions from a TypeScript/JavaScript source file.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Express/Fastify: app.get('/path', handler), router.post(...)
|
|
8
|
+
* - Next.js App Router: exported GET/POST/etc in route.ts files
|
|
9
|
+
* - Next.js Pages API: default export in pages/api/** files
|
|
10
|
+
* - Route maps: object literals with path/method/handler fields
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractRoutes(sf: ts.SourceFile): RouteIndexEntry[];
|