code-auditor-mcp 1.20.0 → 2.0.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/GoAdapter.d.ts +53 -0
- package/dist/adapters/GoAdapter.d.ts.map +1 -0
- package/dist/adapters/GoAdapter.js +602 -0
- package/dist/adapters/GoAdapter.js.map +1 -0
- package/dist/adapters/GoConfig.d.ts +35 -0
- package/dist/adapters/GoConfig.d.ts.map +1 -0
- package/dist/adapters/GoConfig.js +155 -0
- package/dist/adapters/GoConfig.js.map +1 -0
- package/dist/adapters/LanguageAdapter.d.ts +135 -0
- package/dist/adapters/LanguageAdapter.d.ts.map +1 -0
- package/dist/adapters/LanguageAdapter.js +47 -0
- package/dist/adapters/LanguageAdapter.js.map +1 -0
- package/dist/adapters/TypeScriptAdapter.d.ts +43 -0
- package/dist/adapters/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/adapters/TypeScriptAdapter.js +386 -0
- package/dist/adapters/TypeScriptAdapter.js.map +1 -0
- package/dist/adapters/UniversalAnalyzer.d.ts +42 -0
- package/dist/adapters/UniversalAnalyzer.d.ts.map +1 -0
- package/dist/adapters/UniversalAnalyzer.js +103 -0
- package/dist/adapters/UniversalAnalyzer.js.map +1 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts +48 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.js +178 -0
- package/dist/adapters/UniversalSOLIDAnalyzer.js.map +1 -0
- package/dist/adapters/solidAnalyzerCompat.d.ts +21 -0
- package/dist/adapters/solidAnalyzerCompat.d.ts.map +1 -0
- package/dist/adapters/solidAnalyzerCompat.js +78 -0
- package/dist/adapters/solidAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts +103 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.js +425 -0
- package/dist/analyzers/cross-language/APIContractAnalyzer.js.map +1 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts +117 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js +618 -0
- package/dist/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.js.map +1 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts +129 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +473 -0
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts +126 -0
- package/dist/analyzers/cross-language/SchemaValidator.d.ts.map +1 -0
- package/dist/analyzers/cross-language/SchemaValidator.js +522 -0
- package/dist/analyzers/cross-language/SchemaValidator.js.map +1 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.js +59 -0
- package/dist/analyzers/dataAccessAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/documentationAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/documentationAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/documentationAnalyzerCompat.js +52 -0
- package/dist/analyzers/documentationAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/dryAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/dryAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/dryAnalyzerCompat.js +44 -0
- package/dist/analyzers/dryAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/schemaAnalyzer.d.ts +21 -0
- package/dist/analyzers/schemaAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/schemaAnalyzer.js +405 -0
- package/dist/analyzers/schemaAnalyzer.js.map +1 -0
- package/dist/analyzers/schemaAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/schemaAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/schemaAnalyzerCompat.js +69 -0
- package/dist/analyzers/schemaAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/solidAnalyzerCompat.d.ts +20 -0
- package/dist/analyzers/solidAnalyzerCompat.d.ts.map +1 -0
- package/dist/analyzers/solidAnalyzerCompat.js +78 -0
- package/dist/analyzers/solidAnalyzerCompat.js.map +1 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +71 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +276 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +82 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +489 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts +48 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +175 -0
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +64 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +286 -0
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts +119 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +812 -0
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -0
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +23 -7
- package/dist/auditRunner.js.map +1 -1
- package/dist/codeIndexDB-enhanced.d.ts +80 -0
- package/dist/codeIndexDB-enhanced.d.ts.map +1 -0
- package/dist/codeIndexDB-enhanced.js +488 -0
- package/dist/codeIndexDB-enhanced.js.map +1 -0
- package/dist/codeIndexDb.d.ts +70 -1
- package/dist/codeIndexDb.d.ts.map +1 -1
- package/dist/codeIndexDb.js +199 -2
- package/dist/codeIndexDb.js.map +1 -1
- package/dist/config/defaults.js +1 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/languages/LanguageOrchestrator.d.ts +181 -0
- package/dist/languages/LanguageOrchestrator.d.ts.map +1 -0
- package/dist/languages/LanguageOrchestrator.js +365 -0
- package/dist/languages/LanguageOrchestrator.js.map +1 -0
- package/dist/languages/LanguageRegistry.d.ts +43 -0
- package/dist/languages/LanguageRegistry.d.ts.map +1 -0
- package/dist/languages/LanguageRegistry.js +86 -0
- package/dist/languages/LanguageRegistry.js.map +1 -0
- package/dist/languages/RuntimeManager.d.ts +181 -0
- package/dist/languages/RuntimeManager.d.ts.map +1 -0
- package/dist/languages/RuntimeManager.js +841 -0
- package/dist/languages/RuntimeManager.js.map +1 -0
- package/dist/languages/UniversalAnalyzer.d.ts +37 -0
- package/dist/languages/UniversalAnalyzer.d.ts.map +1 -0
- package/dist/languages/UniversalAnalyzer.js +101 -0
- package/dist/languages/UniversalAnalyzer.js.map +1 -0
- package/dist/languages/go/GoAdapter.d.ts +57 -0
- package/dist/languages/go/GoAdapter.d.ts.map +1 -0
- package/dist/languages/go/GoAdapter.js +360 -0
- package/dist/languages/go/GoAdapter.js.map +1 -0
- package/dist/languages/index.d.ts +13 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +23 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/types.d.ts +182 -0
- package/dist/languages/types.d.ts.map +1 -0
- package/dist/languages/types.js +5 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/languages/typescript/TypeScriptAdapter.d.ts +108 -0
- package/dist/languages/typescript/TypeScriptAdapter.d.ts.map +1 -0
- package/dist/languages/typescript/TypeScriptAdapter.js +567 -0
- package/dist/languages/typescript/TypeScriptAdapter.js.map +1 -0
- package/dist/languages/typescript/test-extraction.d.ts +2 -0
- package/dist/languages/typescript/test-extraction.d.ts.map +1 -0
- package/dist/languages/typescript/test-extraction.js +36 -0
- package/dist/languages/typescript/test-extraction.js.map +1 -0
- package/dist/mcp-hybrid.d.ts +10 -0
- package/dist/mcp-hybrid.d.ts.map +1 -0
- package/dist/mcp-hybrid.js +41 -0
- package/dist/mcp-hybrid.js.map +1 -0
- package/dist/mcp-index.d.ts +11 -0
- package/dist/mcp-index.d.ts.map +1 -0
- package/dist/mcp-index.js +101 -0
- package/dist/mcp-index.js.map +1 -0
- package/dist/mcp-tools/workflowGuide.d.ts.map +1 -1
- package/dist/mcp-tools/workflowGuide.js +67 -10
- package/dist/mcp-tools/workflowGuide.js.map +1 -1
- package/dist/mcp-tools-shared.d.ts +49 -0
- package/dist/mcp-tools-shared.d.ts.map +1 -0
- package/dist/mcp-tools-shared.js +1282 -0
- package/dist/mcp-tools-shared.js.map +1 -0
- package/dist/mcp-ui-server.d.ts +27 -0
- package/dist/mcp-ui-server.d.ts.map +1 -0
- package/dist/mcp-ui-server.js +484 -0
- package/dist/mcp-ui-server.js.map +1 -0
- package/dist/mcp-ui-simple.d.ts +27 -0
- package/dist/mcp-ui-simple.d.ts.map +1 -0
- package/dist/mcp-ui-simple.js +425 -0
- package/dist/mcp-ui-simple.js.map +1 -0
- package/dist/mcp.js +7 -4
- package/dist/mcp.js.map +1 -1
- package/dist/services/SchemaParser.d.ts +89 -0
- package/dist/services/SchemaParser.d.ts.map +1 -0
- package/dist/services/SchemaParser.js +434 -0
- package/dist/services/SchemaParser.js.map +1 -0
- package/dist/types/crossLanguage.d.ts +267 -0
- package/dist/types/crossLanguage.d.ts.map +1 -0
- package/dist/types/crossLanguage.js +6 -0
- package/dist/types/crossLanguage.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/fileDiscovery.d.ts +6 -0
- package/dist/utils/fileDiscovery.d.ts.map +1 -1
- package/dist/utils/fileDiscovery.js +12 -1
- package/dist/utils/fileDiscovery.js.map +1 -1
- package/examples/schema-example.json +364 -0
- package/examples/schema-example.yaml +137 -0
- package/package.json +10 -3
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Contract Analyzer for Cross-Language Validation
|
|
3
|
+
* Detects mismatches between frontend and backend APIs
|
|
4
|
+
*/
|
|
5
|
+
export class APIContractAnalyzer {
|
|
6
|
+
endpoints = [];
|
|
7
|
+
calls = [];
|
|
8
|
+
/**
|
|
9
|
+
* Analyze API contracts and find violations
|
|
10
|
+
*/
|
|
11
|
+
async analyzeContracts(endpoints, calls) {
|
|
12
|
+
this.endpoints = endpoints;
|
|
13
|
+
this.calls = calls;
|
|
14
|
+
const violations = [];
|
|
15
|
+
console.log(`[APIContractAnalyzer] Analyzing ${endpoints.length} endpoints and ${calls.length} API calls`);
|
|
16
|
+
// Find unmatched API calls
|
|
17
|
+
violations.push(...await this.findUnmatchedCalls());
|
|
18
|
+
// Validate matched endpoint-call pairs
|
|
19
|
+
violations.push(...await this.validateMatchedPairs());
|
|
20
|
+
// Check for deprecated API usage
|
|
21
|
+
violations.push(...await this.checkDeprecatedUsage());
|
|
22
|
+
// Validate authentication requirements
|
|
23
|
+
violations.push(...await this.validateAuthentication());
|
|
24
|
+
console.log(`[APIContractAnalyzer] Found ${violations.length} contract violations`);
|
|
25
|
+
return violations;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Extract API endpoints from code entities
|
|
29
|
+
*/
|
|
30
|
+
static extractEndpoints(entities) {
|
|
31
|
+
const endpoints = [];
|
|
32
|
+
for (const entity of entities) {
|
|
33
|
+
// Go endpoints (Gin, Echo, etc.)
|
|
34
|
+
if (entity.language === 'go' && entity.type === 'function') {
|
|
35
|
+
const endpoint = this.extractGoEndpoint(entity);
|
|
36
|
+
if (endpoint)
|
|
37
|
+
endpoints.push(endpoint);
|
|
38
|
+
}
|
|
39
|
+
// TypeScript endpoints (Express, Fastify, etc.)
|
|
40
|
+
if (entity.language === 'typescript' && entity.type === 'function') {
|
|
41
|
+
const endpoint = this.extractTypeScriptEndpoint(entity);
|
|
42
|
+
if (endpoint)
|
|
43
|
+
endpoints.push(endpoint);
|
|
44
|
+
}
|
|
45
|
+
// Python endpoints (FastAPI, Flask, etc.)
|
|
46
|
+
if (entity.language === 'python' && entity.type === 'function') {
|
|
47
|
+
const endpoint = this.extractPythonEndpoint(entity);
|
|
48
|
+
if (endpoint)
|
|
49
|
+
endpoints.push(endpoint);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return endpoints;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract API calls from code entities
|
|
56
|
+
*/
|
|
57
|
+
static extractAPICalls(entities) {
|
|
58
|
+
const calls = [];
|
|
59
|
+
for (const entity of entities) {
|
|
60
|
+
// TypeScript/JavaScript API calls (fetch, axios, etc.)
|
|
61
|
+
if ((entity.language === 'typescript' || entity.language === 'javascript') && entity.type === 'function') {
|
|
62
|
+
const call = this.extractTypeScriptAPICall(entity);
|
|
63
|
+
if (call)
|
|
64
|
+
calls.push(call);
|
|
65
|
+
}
|
|
66
|
+
// Go API calls (http.Client, etc.)
|
|
67
|
+
if (entity.language === 'go' && entity.type === 'function') {
|
|
68
|
+
const call = this.extractGoAPICall(entity);
|
|
69
|
+
if (call)
|
|
70
|
+
calls.push(call);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return calls;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Find API calls that don't have matching endpoints
|
|
77
|
+
*/
|
|
78
|
+
async findUnmatchedCalls() {
|
|
79
|
+
const violations = [];
|
|
80
|
+
for (const call of this.calls) {
|
|
81
|
+
const matchingEndpoint = this.findMatchingEndpoint(call);
|
|
82
|
+
if (!matchingEndpoint) {
|
|
83
|
+
violations.push({
|
|
84
|
+
file: call.file,
|
|
85
|
+
line: call.line,
|
|
86
|
+
severity: 'warning',
|
|
87
|
+
message: `API call to ${call.method} ${call.url} has no matching endpoint`,
|
|
88
|
+
contractType: 'missing-endpoint',
|
|
89
|
+
call,
|
|
90
|
+
details: {
|
|
91
|
+
method: call.method,
|
|
92
|
+
url: call.url,
|
|
93
|
+
language: call.language
|
|
94
|
+
},
|
|
95
|
+
suggestion: 'Ensure the endpoint exists or update the API call',
|
|
96
|
+
analyzer: 'api-contract',
|
|
97
|
+
category: 'cross-language-api'
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return violations;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Validate matched endpoint-call pairs for compatibility
|
|
105
|
+
*/
|
|
106
|
+
async validateMatchedPairs() {
|
|
107
|
+
const violations = [];
|
|
108
|
+
for (const call of this.calls) {
|
|
109
|
+
const endpoint = this.findMatchingEndpoint(call);
|
|
110
|
+
if (!endpoint)
|
|
111
|
+
continue;
|
|
112
|
+
// Validate HTTP method
|
|
113
|
+
if (call.method.toUpperCase() !== endpoint.method) {
|
|
114
|
+
violations.push({
|
|
115
|
+
file: call.file,
|
|
116
|
+
line: call.line,
|
|
117
|
+
severity: 'critical',
|
|
118
|
+
message: `HTTP method mismatch: call uses ${call.method}, endpoint expects ${endpoint.method}`,
|
|
119
|
+
contractType: 'method-mismatch',
|
|
120
|
+
endpoint,
|
|
121
|
+
call,
|
|
122
|
+
details: {
|
|
123
|
+
expectedMethod: endpoint.method,
|
|
124
|
+
actualMethod: call.method
|
|
125
|
+
},
|
|
126
|
+
suggestion: `Change the API call method to ${endpoint.method}`,
|
|
127
|
+
analyzer: 'api-contract',
|
|
128
|
+
category: 'cross-language-api'
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Validate response type compatibility
|
|
132
|
+
if (endpoint.responseSchema && call.expectedResponseType) {
|
|
133
|
+
const typeViolations = this.validateTypeCompatibility(endpoint.responseSchema, call.expectedResponseType, endpoint, call);
|
|
134
|
+
violations.push(...typeViolations);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return violations;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Check for usage of deprecated APIs
|
|
141
|
+
*/
|
|
142
|
+
async checkDeprecatedUsage() {
|
|
143
|
+
const violations = [];
|
|
144
|
+
for (const call of this.calls) {
|
|
145
|
+
const endpoint = this.findMatchingEndpoint(call);
|
|
146
|
+
if (endpoint?.deprecated) {
|
|
147
|
+
violations.push({
|
|
148
|
+
file: call.file,
|
|
149
|
+
line: call.line,
|
|
150
|
+
severity: 'warning',
|
|
151
|
+
message: `Using deprecated API endpoint: ${endpoint.method} ${endpoint.path}`,
|
|
152
|
+
contractType: 'type-mismatch', // Reusing type for deprecated
|
|
153
|
+
endpoint,
|
|
154
|
+
call,
|
|
155
|
+
details: {
|
|
156
|
+
deprecatedEndpoint: `${endpoint.method} ${endpoint.path}`,
|
|
157
|
+
endpointFile: endpoint.file
|
|
158
|
+
},
|
|
159
|
+
suggestion: 'Update to use the current API version',
|
|
160
|
+
analyzer: 'api-contract',
|
|
161
|
+
category: 'cross-language-api'
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return violations;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Validate authentication requirements
|
|
169
|
+
*/
|
|
170
|
+
async validateAuthentication() {
|
|
171
|
+
const violations = [];
|
|
172
|
+
for (const call of this.calls) {
|
|
173
|
+
const endpoint = this.findMatchingEndpoint(call);
|
|
174
|
+
if (!endpoint)
|
|
175
|
+
continue;
|
|
176
|
+
if (endpoint.authentication && !this.callHasAuthentication(call)) {
|
|
177
|
+
violations.push({
|
|
178
|
+
file: call.file,
|
|
179
|
+
line: call.line,
|
|
180
|
+
severity: 'critical',
|
|
181
|
+
message: `API call missing required authentication for endpoint ${endpoint.method} ${endpoint.path}`,
|
|
182
|
+
contractType: 'auth-mismatch',
|
|
183
|
+
endpoint,
|
|
184
|
+
call,
|
|
185
|
+
details: {
|
|
186
|
+
requiredAuth: endpoint.authentication,
|
|
187
|
+
endpointFile: endpoint.file
|
|
188
|
+
},
|
|
189
|
+
suggestion: `Add ${endpoint.authentication} authentication to the API call`,
|
|
190
|
+
analyzer: 'api-contract',
|
|
191
|
+
category: 'cross-language-api'
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return violations;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Find matching endpoint for an API call
|
|
199
|
+
*/
|
|
200
|
+
findMatchingEndpoint(call) {
|
|
201
|
+
for (const endpoint of this.endpoints) {
|
|
202
|
+
if (this.pathsMatch(endpoint.path, call.url) &&
|
|
203
|
+
endpoint.method === call.method.toUpperCase()) {
|
|
204
|
+
return endpoint;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Check if two API paths match (handling path parameters)
|
|
211
|
+
*/
|
|
212
|
+
pathsMatch(endpointPath, callUrl) {
|
|
213
|
+
// Simple path matching - in practice would need more sophisticated logic
|
|
214
|
+
// Handle path parameters like /users/:id matching /users/123
|
|
215
|
+
const endpointParts = endpointPath.split('/');
|
|
216
|
+
const callParts = callUrl.split('/').map(part => part.split('?')[0]); // Remove query params
|
|
217
|
+
if (endpointParts.length !== callParts.length) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
for (let i = 0; i < endpointParts.length; i++) {
|
|
221
|
+
const endpointPart = endpointParts[i];
|
|
222
|
+
const callPart = callParts[i];
|
|
223
|
+
// Skip parameter parts (starting with : or {})
|
|
224
|
+
if (endpointPart.startsWith(':') ||
|
|
225
|
+
(endpointPart.startsWith('{') && endpointPart.endsWith('}'))) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (endpointPart !== callPart) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Validate type compatibility between endpoint and call
|
|
236
|
+
*/
|
|
237
|
+
validateTypeCompatibility(endpointSchema, callType, endpoint, call) {
|
|
238
|
+
const violations = [];
|
|
239
|
+
// Simplified type checking - in practice would need full schema validation
|
|
240
|
+
if (endpointSchema.type === 'object' && callType.includes('[]')) {
|
|
241
|
+
violations.push({
|
|
242
|
+
file: call.file,
|
|
243
|
+
line: call.line,
|
|
244
|
+
severity: 'critical',
|
|
245
|
+
message: `Type mismatch: endpoint returns object, call expects array`,
|
|
246
|
+
contractType: 'type-mismatch',
|
|
247
|
+
endpoint,
|
|
248
|
+
call,
|
|
249
|
+
expectedType: 'object',
|
|
250
|
+
actualType: 'array',
|
|
251
|
+
details: {
|
|
252
|
+
endpointSchema: endpointSchema,
|
|
253
|
+
callType: callType
|
|
254
|
+
},
|
|
255
|
+
suggestion: 'Update the API call to handle object response instead of array',
|
|
256
|
+
analyzer: 'api-contract',
|
|
257
|
+
category: 'cross-language-api'
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return violations;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Check if an API call includes authentication
|
|
264
|
+
*/
|
|
265
|
+
callHasAuthentication(call) {
|
|
266
|
+
// Simplified check - would analyze the actual code for auth headers/tokens
|
|
267
|
+
return call.file.includes('auth') ||
|
|
268
|
+
call.id.toLowerCase().includes('token') ||
|
|
269
|
+
call.id.toLowerCase().includes('bearer');
|
|
270
|
+
}
|
|
271
|
+
// Static methods for extracting endpoints and calls from entities
|
|
272
|
+
static extractGoEndpoint(entity) {
|
|
273
|
+
// Look for HTTP handler patterns in Go
|
|
274
|
+
if (entity.signature?.includes('gin.Context') ||
|
|
275
|
+
entity.signature?.includes('echo.Context') ||
|
|
276
|
+
entity.signature?.includes('http.ResponseWriter')) {
|
|
277
|
+
// Extract method and path from function name or comments
|
|
278
|
+
const method = this.extractMethodFromGo(entity);
|
|
279
|
+
const path = this.extractPathFromGo(entity);
|
|
280
|
+
if (method && path) {
|
|
281
|
+
return {
|
|
282
|
+
id: entity.id,
|
|
283
|
+
method: method,
|
|
284
|
+
path,
|
|
285
|
+
language: 'go',
|
|
286
|
+
file: entity.file,
|
|
287
|
+
line: entity.startLine || 0,
|
|
288
|
+
// Would extract schemas from struct tags or comments
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
static extractTypeScriptEndpoint(entity) {
|
|
295
|
+
// Look for Express/Fastify handler patterns
|
|
296
|
+
if (entity.signature?.includes('Request') && entity.signature?.includes('Response')) {
|
|
297
|
+
const method = this.extractMethodFromTypeScript(entity);
|
|
298
|
+
const path = this.extractPathFromTypeScript(entity);
|
|
299
|
+
if (method && path) {
|
|
300
|
+
return {
|
|
301
|
+
id: entity.id,
|
|
302
|
+
method: method,
|
|
303
|
+
path,
|
|
304
|
+
language: 'typescript',
|
|
305
|
+
file: entity.file,
|
|
306
|
+
line: entity.startLine || 0,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
static extractPythonEndpoint(entity) {
|
|
313
|
+
// Look for FastAPI/Flask patterns
|
|
314
|
+
if (entity.metadata?.decorators?.some((d) => d.includes('@app.') || d.includes('@router.'))) {
|
|
315
|
+
const method = this.extractMethodFromPython(entity);
|
|
316
|
+
const path = this.extractPathFromPython(entity);
|
|
317
|
+
if (method && path) {
|
|
318
|
+
return {
|
|
319
|
+
id: entity.id,
|
|
320
|
+
method: method,
|
|
321
|
+
path,
|
|
322
|
+
language: 'python',
|
|
323
|
+
file: entity.file,
|
|
324
|
+
line: entity.startLine || 0,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
static extractTypeScriptAPICall(entity) {
|
|
331
|
+
// Look for fetch/axios patterns
|
|
332
|
+
if (entity.purpose?.includes('fetch') ||
|
|
333
|
+
entity.purpose?.includes('axios') ||
|
|
334
|
+
entity.name.toLowerCase().includes('api') ||
|
|
335
|
+
entity.name.toLowerCase().includes('request')) {
|
|
336
|
+
const method = this.extractCallMethodFromTypeScript(entity);
|
|
337
|
+
const url = this.extractUrlFromTypeScript(entity);
|
|
338
|
+
if (method && url) {
|
|
339
|
+
return {
|
|
340
|
+
id: entity.id,
|
|
341
|
+
method,
|
|
342
|
+
url,
|
|
343
|
+
language: 'typescript',
|
|
344
|
+
file: entity.file,
|
|
345
|
+
line: entity.startLine || 0,
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
static extractGoAPICall(entity) {
|
|
352
|
+
// Look for http.Client patterns
|
|
353
|
+
if (entity.signature?.includes('http.Client') ||
|
|
354
|
+
entity.purpose?.includes('HTTP') ||
|
|
355
|
+
entity.name.toLowerCase().includes('request')) {
|
|
356
|
+
const method = this.extractCallMethodFromGo(entity);
|
|
357
|
+
const url = this.extractUrlFromGo(entity);
|
|
358
|
+
if (method && url) {
|
|
359
|
+
return {
|
|
360
|
+
id: entity.id,
|
|
361
|
+
method,
|
|
362
|
+
url,
|
|
363
|
+
language: 'go',
|
|
364
|
+
file: entity.file,
|
|
365
|
+
line: entity.startLine || 0,
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
// Helper methods for extracting HTTP info from code patterns
|
|
372
|
+
static extractMethodFromGo(entity) {
|
|
373
|
+
const name = entity.name.toLowerCase();
|
|
374
|
+
if (name.includes('get'))
|
|
375
|
+
return 'GET';
|
|
376
|
+
if (name.includes('post'))
|
|
377
|
+
return 'POST';
|
|
378
|
+
if (name.includes('put'))
|
|
379
|
+
return 'PUT';
|
|
380
|
+
if (name.includes('delete'))
|
|
381
|
+
return 'DELETE';
|
|
382
|
+
if (name.includes('patch'))
|
|
383
|
+
return 'PATCH';
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
static extractPathFromGo(entity) {
|
|
387
|
+
// Extract from function name like GetUserByID -> /user/:id
|
|
388
|
+
const name = entity.name;
|
|
389
|
+
if (name.startsWith('Get') && name.includes('By')) {
|
|
390
|
+
const resource = name.substring(3).split('By')[0].toLowerCase();
|
|
391
|
+
return `/${resource}/:id`;
|
|
392
|
+
}
|
|
393
|
+
if (name.startsWith('List')) {
|
|
394
|
+
const resource = name.substring(4).toLowerCase() + 's';
|
|
395
|
+
return `/${resource}`;
|
|
396
|
+
}
|
|
397
|
+
return '/api/' + name.toLowerCase();
|
|
398
|
+
}
|
|
399
|
+
static extractMethodFromTypeScript(entity) {
|
|
400
|
+
return this.extractMethodFromGo(entity); // Same logic
|
|
401
|
+
}
|
|
402
|
+
static extractPathFromTypeScript(entity) {
|
|
403
|
+
return this.extractPathFromGo(entity); // Same logic
|
|
404
|
+
}
|
|
405
|
+
static extractMethodFromPython(entity) {
|
|
406
|
+
return this.extractMethodFromGo(entity); // Same logic
|
|
407
|
+
}
|
|
408
|
+
static extractPathFromPython(entity) {
|
|
409
|
+
return this.extractPathFromGo(entity); // Same logic
|
|
410
|
+
}
|
|
411
|
+
static extractCallMethodFromTypeScript(entity) {
|
|
412
|
+
return this.extractMethodFromGo(entity); // Same logic
|
|
413
|
+
}
|
|
414
|
+
static extractUrlFromTypeScript(entity) {
|
|
415
|
+
// Extract from function name or purpose
|
|
416
|
+
return this.extractPathFromGo(entity);
|
|
417
|
+
}
|
|
418
|
+
static extractCallMethodFromGo(entity) {
|
|
419
|
+
return this.extractMethodFromGo(entity); // Same logic
|
|
420
|
+
}
|
|
421
|
+
static extractUrlFromGo(entity) {
|
|
422
|
+
return this.extractPathFromGo(entity); // Same logic
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
//# sourceMappingURL=APIContractAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"APIContractAnalyzer.js","sourceRoot":"","sources":["../../../src/analyzers/cross-language/APIContractAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-Language SOLID Analyzer
|
|
3
|
+
* Enhanced SOLID principle analysis that works across multiple languages
|
|
4
|
+
* using the cross-language entity model
|
|
5
|
+
*/
|
|
6
|
+
import { CrossLanguageEntity, CrossReference } from '../../types/crossLanguage.js';
|
|
7
|
+
import { Violation } from '../../types.js';
|
|
8
|
+
export interface CrossLanguageSOLIDConfig {
|
|
9
|
+
maxResponsibilities: number;
|
|
10
|
+
maxDependencies: number;
|
|
11
|
+
maxInterfaceMembers: number;
|
|
12
|
+
maxComplexity: number;
|
|
13
|
+
maxParameters: number;
|
|
14
|
+
checkAbstractions: boolean;
|
|
15
|
+
checkPolymorphism: boolean;
|
|
16
|
+
enableCrossLanguageAnalysis: boolean;
|
|
17
|
+
minCrossLanguageViolationConfidence: number;
|
|
18
|
+
}
|
|
19
|
+
export interface CrossLanguageSOLIDViolation extends Violation {
|
|
20
|
+
principle: 'SRP' | 'OCP' | 'LSP' | 'ISP' | 'DIP';
|
|
21
|
+
entityId: string;
|
|
22
|
+
entityName: string;
|
|
23
|
+
entityType: string;
|
|
24
|
+
language: string;
|
|
25
|
+
crossLanguageIssue: boolean;
|
|
26
|
+
relatedEntities?: Array<{
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
language: string;
|
|
30
|
+
relationship: string;
|
|
31
|
+
}>;
|
|
32
|
+
responsibilityCount?: number;
|
|
33
|
+
dependencyCount?: number;
|
|
34
|
+
memberCount?: number;
|
|
35
|
+
confidence: number;
|
|
36
|
+
}
|
|
37
|
+
export declare class CrossLanguageSOLIDAnalyzer {
|
|
38
|
+
private config;
|
|
39
|
+
constructor(config?: Partial<CrossLanguageSOLIDConfig>);
|
|
40
|
+
/**
|
|
41
|
+
* Analyze SOLID principles across multiple languages
|
|
42
|
+
*/
|
|
43
|
+
analyze(entities: CrossLanguageEntity[], references: CrossReference[]): Promise<CrossLanguageSOLIDViolation[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Single Responsibility Principle - Enhanced for cross-language
|
|
46
|
+
*/
|
|
47
|
+
private analyzeSingleResponsibility;
|
|
48
|
+
/**
|
|
49
|
+
* Open/Closed Principle - Cross-language switch detection
|
|
50
|
+
*/
|
|
51
|
+
private analyzeOpenClosed;
|
|
52
|
+
/**
|
|
53
|
+
* Liskov Substitution Principle - Cross-language inheritance analysis
|
|
54
|
+
*/
|
|
55
|
+
private analyzeLiskovSubstitution;
|
|
56
|
+
/**
|
|
57
|
+
* Interface Segregation Principle - Cross-language interface analysis
|
|
58
|
+
*/
|
|
59
|
+
private analyzeInterfaceSegregation;
|
|
60
|
+
/**
|
|
61
|
+
* Dependency Inversion Principle - Cross-language abstraction analysis
|
|
62
|
+
*/
|
|
63
|
+
private analyzeDependencyInversion;
|
|
64
|
+
/**
|
|
65
|
+
* Cross-Language specific SOLID violations
|
|
66
|
+
*/
|
|
67
|
+
private analyzeCrossLanguageSOLID;
|
|
68
|
+
/**
|
|
69
|
+
* Count responsibilities considering cross-language factors
|
|
70
|
+
*/
|
|
71
|
+
private countResponsibilities;
|
|
72
|
+
/**
|
|
73
|
+
* Detect polymorphism opportunities across languages
|
|
74
|
+
*/
|
|
75
|
+
private detectPolymorphismOpportunities;
|
|
76
|
+
/**
|
|
77
|
+
* Find cross-language inheritance hierarchies
|
|
78
|
+
*/
|
|
79
|
+
private findCrossLanguageHierarchies;
|
|
80
|
+
/**
|
|
81
|
+
* Build hierarchy from inheritance relationships
|
|
82
|
+
*/
|
|
83
|
+
private buildHierarchy;
|
|
84
|
+
/**
|
|
85
|
+
* Analyze hierarchy for LSP violations
|
|
86
|
+
*/
|
|
87
|
+
private analyzeHierarchyForLSP;
|
|
88
|
+
/**
|
|
89
|
+
* Analyze interface usage across languages
|
|
90
|
+
*/
|
|
91
|
+
private analyzeInterfaceUsage;
|
|
92
|
+
/**
|
|
93
|
+
* Analyze dependencies for DIP violations
|
|
94
|
+
*/
|
|
95
|
+
private analyzeDependencies;
|
|
96
|
+
/**
|
|
97
|
+
* Check if entity is concrete type
|
|
98
|
+
*/
|
|
99
|
+
private isConcreteType;
|
|
100
|
+
/**
|
|
101
|
+
* Detect API boundary violations
|
|
102
|
+
*/
|
|
103
|
+
private detectAPIBoundaryViolations;
|
|
104
|
+
/**
|
|
105
|
+
* Detect responsibility leakage across languages
|
|
106
|
+
*/
|
|
107
|
+
private detectResponsibilityLeakage;
|
|
108
|
+
/**
|
|
109
|
+
* Detect distributed interface violations
|
|
110
|
+
*/
|
|
111
|
+
private detectDistributedInterfaceViolations;
|
|
112
|
+
private generateSRPSuggestion;
|
|
113
|
+
private generateOCPSuggestion;
|
|
114
|
+
private generateISPSuggestion;
|
|
115
|
+
private generateDIPSuggestion;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=CrossLanguageSOLIDAnalyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrossLanguageSOLIDAnalyzer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/cross-language/CrossLanguageSOLIDAnalyzer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnF,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,WAAW,wBAAwB;IACvC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,2BAA2B,EAAE,OAAO,CAAC;IACrC,mCAAmC,EAAE,MAAM,CAAC;CAC7C;AAED,MAAM,WAAW,2BAA4B,SAAQ,SAAS;IAC5D,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,CAAC,EAAE,KAAK,CAAC;QACtB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,GAAE,OAAO,CAAC,wBAAwB,CAAM;IAe1D;;OAEG;IACG,OAAO,CACX,QAAQ,EAAE,mBAAmB,EAAE,EAC/B,UAAU,EAAE,cAAc,EAAE,GAC3B,OAAO,CAAC,2BAA2B,EAAE,CAAC;IAqBzC;;OAEG;YACW,2BAA2B;IAwCzC;;OAEG;YACW,iBAAiB;IAwC/B;;OAEG;YACW,yBAAyB;IAgBvC;;OAEG;YACW,2BAA2B;IA0CzC;;OAEG;YACW,0BAA0B;IA4CxC;;OAEG;YACW,yBAAyB;IAkBvC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsE7B;;OAEG;IACH,OAAO,CAAC,+BAA+B;IA6DvC;;OAEG;IACH,OAAO,CAAC,4BAA4B;IA2CpC;;OAEG;IACH,OAAO,CAAC,cAAc;IAgCtB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuD9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA6C7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA0C3B;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAwCnC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAsCnC;;OAEG;IACH,OAAO,CAAC,oCAAoC;IA6C5C,OAAO,CAAC,qBAAqB;IAiB7B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,qBAAqB;CAU9B"}
|