code-auditor-mcp 1.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/LICENSE +21 -0
- package/README.md +362 -0
- package/configs/hhra-compat.json +168 -0
- package/dist/analyzers/analyzerUtils.d.ts +69 -0
- package/dist/analyzers/analyzerUtils.d.ts.map +1 -0
- package/dist/analyzers/analyzerUtils.js +188 -0
- package/dist/analyzers/analyzerUtils.js.map +1 -0
- package/dist/analyzers/dataAccessAnalyzer.d.ts +46 -0
- package/dist/analyzers/dataAccessAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/dataAccessAnalyzer.js +448 -0
- package/dist/analyzers/dataAccessAnalyzer.js.map +1 -0
- package/dist/analyzers/dryAnalyzer.d.ts +30 -0
- package/dist/analyzers/dryAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/dryAnalyzer.js +537 -0
- package/dist/analyzers/dryAnalyzer.js.map +1 -0
- package/dist/analyzers/solidAnalyzer.d.ts +23 -0
- package/dist/analyzers/solidAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/solidAnalyzer.js +355 -0
- package/dist/analyzers/solidAnalyzer.js.map +1 -0
- package/dist/auditRunner.d.ts +20 -0
- package/dist/auditRunner.d.ts.map +1 -0
- package/dist/auditRunner.js +214 -0
- package/dist/auditRunner.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +38 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/configLoader.d.ts +19 -0
- package/dist/config/configLoader.d.ts.map +1 -0
- package/dist/config/configLoader.js +124 -0
- package/dist/config/configLoader.js.map +1 -0
- package/dist/config/defaults.d.ts +69 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +142 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-standalone.d.ts +3 -0
- package/dist/mcp-standalone.d.ts.map +1 -0
- package/dist/mcp-standalone.js +171 -0
- package/dist/mcp-standalone.js.map +1 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +340 -0
- package/dist/mcp.js.map +1 -0
- package/dist/reporting/csvReportGenerator.d.ts +29 -0
- package/dist/reporting/csvReportGenerator.d.ts.map +1 -0
- package/dist/reporting/csvReportGenerator.js +182 -0
- package/dist/reporting/csvReportGenerator.js.map +1 -0
- package/dist/reporting/htmlReportGenerator.d.ts +18 -0
- package/dist/reporting/htmlReportGenerator.d.ts.map +1 -0
- package/dist/reporting/htmlReportGenerator.js +352 -0
- package/dist/reporting/htmlReportGenerator.js.map +1 -0
- package/dist/reporting/jsonReportGenerator.d.ts +23 -0
- package/dist/reporting/jsonReportGenerator.d.ts.map +1 -0
- package/dist/reporting/jsonReportGenerator.js +103 -0
- package/dist/reporting/jsonReportGenerator.js.map +1 -0
- package/dist/reporting/reportGenerator.d.ts +21 -0
- package/dist/reporting/reportGenerator.d.ts.map +1 -0
- package/dist/reporting/reportGenerator.js +53 -0
- package/dist/reporting/reportGenerator.js.map +1 -0
- package/dist/types.d.ts +246 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/astParser.d.ts +71 -0
- package/dist/utils/astParser.d.ts.map +1 -0
- package/dist/utils/astParser.js +244 -0
- package/dist/utils/astParser.js.map +1 -0
- package/dist/utils/astUtils.d.ts +89 -0
- package/dist/utils/astUtils.d.ts.map +1 -0
- package/dist/utils/astUtils.js +289 -0
- package/dist/utils/astUtils.js.map +1 -0
- package/dist/utils/fileDiscovery.d.ts +58 -0
- package/dist/utils/fileDiscovery.d.ts.map +1 -0
- package/dist/utils/fileDiscovery.js +203 -0
- package/dist/utils/fileDiscovery.js.map +1 -0
- package/examples/.auditrc.example.json +61 -0
- package/examples/.auditrc.json +201 -0
- package/examples/nextjs.auditrc.json +65 -0
- package/examples/node-api.auditrc.json +82 -0
- package/examples/react.auditrc.json +59 -0
- package/package.json +62 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SOLID Principles Analyzer - Functional Implementation
|
|
3
|
+
* Detects violations of SOLID principles in TypeScript/JavaScript code
|
|
4
|
+
*/
|
|
5
|
+
import * as ts from 'typescript';
|
|
6
|
+
import { createViolation, getNodePosition, findNodesOfType, getNodeName, traverseAST, processFiles } from './analyzerUtils.js';
|
|
7
|
+
/**
|
|
8
|
+
* Default configuration
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_CONFIG = {
|
|
11
|
+
maxMethodsPerClass: 10,
|
|
12
|
+
maxLinesPerMethod: 50,
|
|
13
|
+
maxParametersPerMethod: 4,
|
|
14
|
+
maxClassComplexity: 50,
|
|
15
|
+
maxInterfaceMembers: 10,
|
|
16
|
+
checkDependencyInversion: true,
|
|
17
|
+
checkInterfaceSegregation: true,
|
|
18
|
+
checkLiskovSubstitution: true
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Analyze a file for SOLID violations
|
|
22
|
+
*/
|
|
23
|
+
const analyzeFile = (filePath, sourceFile, config) => {
|
|
24
|
+
const violations = [];
|
|
25
|
+
// Check Single Responsibility Principle
|
|
26
|
+
const classes = findNodesOfType(sourceFile, ts.isClassDeclaration);
|
|
27
|
+
classes.forEach(cls => {
|
|
28
|
+
violations.push(...checkSingleResponsibility(cls, sourceFile, filePath, config));
|
|
29
|
+
});
|
|
30
|
+
// Check Open/Closed Principle
|
|
31
|
+
traverseAST(sourceFile, node => {
|
|
32
|
+
violations.push(...checkOpenClosed(node, sourceFile, filePath, config));
|
|
33
|
+
});
|
|
34
|
+
// Check Liskov Substitution Principle
|
|
35
|
+
if (config.checkLiskovSubstitution) {
|
|
36
|
+
violations.push(...checkLiskovSubstitution(sourceFile, filePath, config));
|
|
37
|
+
}
|
|
38
|
+
// Check Interface Segregation Principle
|
|
39
|
+
if (config.checkInterfaceSegregation) {
|
|
40
|
+
const interfaces = findNodesOfType(sourceFile, ts.isInterfaceDeclaration);
|
|
41
|
+
interfaces.forEach(iface => {
|
|
42
|
+
violations.push(...checkInterfaceSegregation(iface, sourceFile, filePath, config));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// Check Dependency Inversion Principle
|
|
46
|
+
if (config.checkDependencyInversion) {
|
|
47
|
+
violations.push(...checkDependencyInversion(sourceFile, filePath, config));
|
|
48
|
+
}
|
|
49
|
+
return violations;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Check Single Responsibility Principle
|
|
53
|
+
*/
|
|
54
|
+
function checkSingleResponsibility(node, sourceFile, filePath, config) {
|
|
55
|
+
const violations = [];
|
|
56
|
+
const className = getNodeName(node) || 'Anonymous';
|
|
57
|
+
// Count methods
|
|
58
|
+
const methods = findNodesOfType(node, ts.isMethodDeclaration);
|
|
59
|
+
const publicMethods = methods.filter(m => !m.modifiers?.some(mod => mod.kind === ts.SyntaxKind.PrivateKeyword));
|
|
60
|
+
if (publicMethods.length > config.maxMethodsPerClass) {
|
|
61
|
+
const { line, column } = getNodePosition(sourceFile, node);
|
|
62
|
+
violations.push(createViolation({
|
|
63
|
+
analyzer: 'solid',
|
|
64
|
+
file: filePath,
|
|
65
|
+
line,
|
|
66
|
+
column,
|
|
67
|
+
severity: 'warning',
|
|
68
|
+
message: `Class "${className}" has ${publicMethods.length} public methods (max: ${config.maxMethodsPerClass})`,
|
|
69
|
+
type: 'solid',
|
|
70
|
+
principle: 'single-responsibility',
|
|
71
|
+
recommendation: 'Consider splitting this class into smaller, more focused classes',
|
|
72
|
+
details: {
|
|
73
|
+
className,
|
|
74
|
+
methodCount: publicMethods.length,
|
|
75
|
+
threshold: config.maxMethodsPerClass
|
|
76
|
+
}
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
// Check for multiple responsibilities
|
|
80
|
+
const responsibilities = detectResponsibilities(node);
|
|
81
|
+
if (responsibilities.length > 1) {
|
|
82
|
+
const { line, column } = getNodePosition(sourceFile, node);
|
|
83
|
+
violations.push(createViolation({
|
|
84
|
+
analyzer: 'solid',
|
|
85
|
+
file: filePath,
|
|
86
|
+
line,
|
|
87
|
+
column,
|
|
88
|
+
severity: 'warning',
|
|
89
|
+
message: `Class "${className}" appears to have multiple responsibilities`,
|
|
90
|
+
type: 'solid',
|
|
91
|
+
principle: 'single-responsibility',
|
|
92
|
+
recommendation: `Consider splitting based on: ${responsibilities.join(', ')}`,
|
|
93
|
+
details: {
|
|
94
|
+
className,
|
|
95
|
+
responsibilities
|
|
96
|
+
}
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
99
|
+
return violations;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Check Open/Closed Principle
|
|
103
|
+
*/
|
|
104
|
+
function checkOpenClosed(node, sourceFile, filePath, config) {
|
|
105
|
+
const violations = [];
|
|
106
|
+
// Check for long if-else chains
|
|
107
|
+
if (ts.isIfStatement(node)) {
|
|
108
|
+
const chainLength = countIfElseChain(node);
|
|
109
|
+
if (chainLength > 3) {
|
|
110
|
+
const { line, column } = getNodePosition(sourceFile, node);
|
|
111
|
+
violations.push(createViolation({
|
|
112
|
+
analyzer: 'solid',
|
|
113
|
+
file: filePath,
|
|
114
|
+
line,
|
|
115
|
+
column,
|
|
116
|
+
severity: 'warning',
|
|
117
|
+
message: `Long if-else chain (${chainLength} branches) violates Open/Closed Principle`,
|
|
118
|
+
type: 'solid',
|
|
119
|
+
principle: 'open-closed',
|
|
120
|
+
recommendation: 'Consider using polymorphism, strategy pattern, or a mapping object',
|
|
121
|
+
details: {
|
|
122
|
+
chainLength
|
|
123
|
+
}
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Check for switch statements with many cases
|
|
128
|
+
if (ts.isSwitchStatement(node)) {
|
|
129
|
+
const cases = findNodesOfType(node, ts.isCaseClause);
|
|
130
|
+
if (cases.length > 5) {
|
|
131
|
+
const { line, column } = getNodePosition(sourceFile, node);
|
|
132
|
+
violations.push(createViolation({
|
|
133
|
+
analyzer: 'solid',
|
|
134
|
+
file: filePath,
|
|
135
|
+
line,
|
|
136
|
+
column,
|
|
137
|
+
severity: 'warning',
|
|
138
|
+
message: `Switch statement with ${cases.length} cases violates Open/Closed Principle`,
|
|
139
|
+
type: 'solid',
|
|
140
|
+
principle: 'open-closed',
|
|
141
|
+
recommendation: 'Consider using polymorphism or a strategy pattern',
|
|
142
|
+
details: {
|
|
143
|
+
caseCount: cases.length
|
|
144
|
+
}
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return violations;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Check Liskov Substitution Principle
|
|
152
|
+
*/
|
|
153
|
+
function checkLiskovSubstitution(sourceFile, filePath, config) {
|
|
154
|
+
const violations = [];
|
|
155
|
+
// Find method overrides that throw errors
|
|
156
|
+
traverseAST(sourceFile, node => {
|
|
157
|
+
if (ts.isMethodDeclaration(node) && node.modifiers?.some(m => m.kind === ts.SyntaxKind.OverrideKeyword)) {
|
|
158
|
+
const hasThrow = findNodesOfType(node, ts.isThrowStatement).length > 0;
|
|
159
|
+
const isNotImplemented = node.body?.statements.length === 0 ||
|
|
160
|
+
(node.body?.statements.length === 1 && ts.isThrowStatement(node.body.statements[0]));
|
|
161
|
+
if (hasThrow || isNotImplemented) {
|
|
162
|
+
const { line, column } = getNodePosition(sourceFile, node);
|
|
163
|
+
const methodName = getNodeName(node) || 'unknown';
|
|
164
|
+
violations.push(createViolation({
|
|
165
|
+
analyzer: 'solid',
|
|
166
|
+
file: filePath,
|
|
167
|
+
line,
|
|
168
|
+
column,
|
|
169
|
+
severity: 'critical',
|
|
170
|
+
message: 'Method override throws error or is not implemented',
|
|
171
|
+
type: 'solid',
|
|
172
|
+
principle: 'liskov-substitution',
|
|
173
|
+
recommendation: 'All overridden methods should maintain behavioral compatibility with base class',
|
|
174
|
+
details: {
|
|
175
|
+
methodName
|
|
176
|
+
}
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return violations;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Check Interface Segregation Principle
|
|
185
|
+
*/
|
|
186
|
+
function checkInterfaceSegregation(node, sourceFile, filePath, config) {
|
|
187
|
+
const violations = [];
|
|
188
|
+
const interfaceName = getNodeName(node) || 'Anonymous';
|
|
189
|
+
if (node.members.length > config.maxInterfaceMembers) {
|
|
190
|
+
const { line, column } = getNodePosition(sourceFile, node);
|
|
191
|
+
violations.push(createViolation({
|
|
192
|
+
analyzer: 'solid',
|
|
193
|
+
file: filePath,
|
|
194
|
+
line,
|
|
195
|
+
column,
|
|
196
|
+
severity: 'critical',
|
|
197
|
+
message: `Interface "${interfaceName}" has too many members (${node.members.length})`,
|
|
198
|
+
type: 'solid',
|
|
199
|
+
principle: 'interface-segregation',
|
|
200
|
+
recommendation: 'Split this interface into smaller, more focused interfaces',
|
|
201
|
+
details: {
|
|
202
|
+
interfaceName,
|
|
203
|
+
memberCount: node.members.length,
|
|
204
|
+
threshold: config.maxInterfaceMembers
|
|
205
|
+
}
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
return violations;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Check Dependency Inversion Principle
|
|
212
|
+
*/
|
|
213
|
+
function checkDependencyInversion(sourceFile, filePath, config) {
|
|
214
|
+
const violations = [];
|
|
215
|
+
// Check for direct imports of concrete implementations
|
|
216
|
+
const imports = findNodesOfType(sourceFile, ts.isImportDeclaration);
|
|
217
|
+
imports.forEach(imp => {
|
|
218
|
+
const moduleSpecifier = imp.moduleSpecifier;
|
|
219
|
+
if (ts.isStringLiteral(moduleSpecifier)) {
|
|
220
|
+
const importPath = moduleSpecifier.text;
|
|
221
|
+
// Check for concrete implementation imports
|
|
222
|
+
if (isConcreteDependency(importPath)) {
|
|
223
|
+
const { line, column } = getNodePosition(sourceFile, imp);
|
|
224
|
+
violations.push(createViolation({
|
|
225
|
+
analyzer: 'solid',
|
|
226
|
+
file: filePath,
|
|
227
|
+
line,
|
|
228
|
+
column,
|
|
229
|
+
severity: 'warning',
|
|
230
|
+
message: `Direct import of concrete implementation: "${importPath}"`,
|
|
231
|
+
type: 'solid',
|
|
232
|
+
principle: 'dependency-inversion',
|
|
233
|
+
recommendation: 'Depend on abstractions (interfaces) rather than concrete implementations',
|
|
234
|
+
details: {
|
|
235
|
+
importPath
|
|
236
|
+
}
|
|
237
|
+
}));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
// Check for 'new' expressions (direct instantiation)
|
|
242
|
+
const newExpressions = findNodesOfType(sourceFile, ts.isNewExpression);
|
|
243
|
+
newExpressions.forEach(expr => {
|
|
244
|
+
if (ts.isIdentifier(expr.expression)) {
|
|
245
|
+
const className = expr.expression.text;
|
|
246
|
+
if (isConcreteClass(className)) {
|
|
247
|
+
const { line, column } = getNodePosition(sourceFile, expr);
|
|
248
|
+
violations.push(createViolation({
|
|
249
|
+
analyzer: 'solid',
|
|
250
|
+
file: filePath,
|
|
251
|
+
line,
|
|
252
|
+
column,
|
|
253
|
+
severity: 'warning',
|
|
254
|
+
message: `Direct instantiation of concrete class "${className}"`,
|
|
255
|
+
type: 'solid',
|
|
256
|
+
principle: 'dependency-inversion',
|
|
257
|
+
recommendation: 'Consider using dependency injection or factory pattern',
|
|
258
|
+
details: {
|
|
259
|
+
className
|
|
260
|
+
}
|
|
261
|
+
}));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
return violations;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Helper: Detect responsibilities in a class
|
|
269
|
+
*/
|
|
270
|
+
function detectResponsibilities(node) {
|
|
271
|
+
const responsibilities = new Set();
|
|
272
|
+
const methods = findNodesOfType(node, ts.isMethodDeclaration);
|
|
273
|
+
methods.forEach(method => {
|
|
274
|
+
const name = getNodeName(method)?.toLowerCase() || '';
|
|
275
|
+
// Detect different concerns
|
|
276
|
+
if (name.includes('save') || name.includes('load') || name.includes('persist')) {
|
|
277
|
+
responsibilities.add('data persistence');
|
|
278
|
+
}
|
|
279
|
+
if (name.includes('validate') || name.includes('check')) {
|
|
280
|
+
responsibilities.add('validation');
|
|
281
|
+
}
|
|
282
|
+
if (name.includes('render') || name.includes('display') || name.includes('show')) {
|
|
283
|
+
responsibilities.add('presentation');
|
|
284
|
+
}
|
|
285
|
+
if (name.includes('send') || name.includes('fetch') || name.includes('request')) {
|
|
286
|
+
responsibilities.add('communication');
|
|
287
|
+
}
|
|
288
|
+
if (name.includes('calculate') || name.includes('compute') || name.includes('process')) {
|
|
289
|
+
responsibilities.add('business logic');
|
|
290
|
+
}
|
|
291
|
+
if (name.includes('log') || name.includes('track') || name.includes('monitor')) {
|
|
292
|
+
responsibilities.add('logging/monitoring');
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
// Check for too many public methods as a responsibility
|
|
296
|
+
const publicMethods = methods.filter(m => !m.modifiers?.some(mod => mod.kind === ts.SyntaxKind.PrivateKeyword));
|
|
297
|
+
if (publicMethods.length > 10) {
|
|
298
|
+
responsibilities.add('too many methods');
|
|
299
|
+
}
|
|
300
|
+
return Array.from(responsibilities);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Helper: Count if-else chain length
|
|
304
|
+
*/
|
|
305
|
+
function countIfElseChain(node) {
|
|
306
|
+
let count = 1;
|
|
307
|
+
let current = node.elseStatement;
|
|
308
|
+
while (current) {
|
|
309
|
+
count++;
|
|
310
|
+
if (ts.isIfStatement(current)) {
|
|
311
|
+
current = current.elseStatement;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return count;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Helper: Check if import is a concrete dependency
|
|
321
|
+
*/
|
|
322
|
+
function isConcreteDependency(importPath) {
|
|
323
|
+
// Common concrete dependencies
|
|
324
|
+
const concretePatterns = [
|
|
325
|
+
'mysql', 'postgres', 'mongodb', 'redis',
|
|
326
|
+
'express', 'axios', 'fs', 'path', 'crypto',
|
|
327
|
+
'aws-sdk', 'stripe', 'twilio'
|
|
328
|
+
];
|
|
329
|
+
return concretePatterns.some(pattern => importPath.includes(pattern));
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Helper: Check if class name represents concrete implementation
|
|
333
|
+
*/
|
|
334
|
+
function isConcreteClass(className) {
|
|
335
|
+
// Skip common allowed instantiations
|
|
336
|
+
const allowed = ['Date', 'Error', 'Array', 'Map', 'Set', 'Promise', 'RegExp'];
|
|
337
|
+
if (allowed.includes(className))
|
|
338
|
+
return false;
|
|
339
|
+
// Concrete if it doesn't start with 'I' or end with 'Interface'
|
|
340
|
+
return !className.startsWith('I') && !className.endsWith('Interface');
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* SOLID analyzer definition
|
|
344
|
+
*/
|
|
345
|
+
export const solidAnalyzer = {
|
|
346
|
+
name: 'solid',
|
|
347
|
+
defaultConfig: DEFAULT_CONFIG,
|
|
348
|
+
analyze: async (files, config, options, progressCallback) => {
|
|
349
|
+
const mergedConfig = { ...DEFAULT_CONFIG, ...config };
|
|
350
|
+
return processFiles(files, analyzeFile, 'solid', mergedConfig, progressCallback ?
|
|
351
|
+
(current, total, file) => progressCallback({ current, total, analyzer: 'solid', file }) :
|
|
352
|
+
undefined);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
//# sourceMappingURL=solidAnalyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solidAnalyzer.js","sourceRoot":"","sources":["../../src/analyzers/solidAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Runner (Functional)
|
|
3
|
+
* Main orchestrator for running code audits
|
|
4
|
+
*/
|
|
5
|
+
import { AuditResult, AuditRunnerOptions, AnalyzerDefinition } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Create an audit runner with the given options
|
|
8
|
+
*/
|
|
9
|
+
export declare function createAuditRunner(options?: AuditRunnerOptions): {
|
|
10
|
+
registerAnalyzer: (analyzer: AnalyzerDefinition) => void;
|
|
11
|
+
loadConfiguration: (configPath: string) => Promise<AuditRunnerOptions>;
|
|
12
|
+
run: (runOptions?: AuditRunnerOptions) => Promise<AuditResult>;
|
|
13
|
+
generateReport: (result: AuditResult, format: string) => Promise<string>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Run audit with default runner (convenience function)
|
|
17
|
+
*/
|
|
18
|
+
export declare function runAudit(options?: AuditRunnerOptions): Promise<AuditResult>;
|
|
19
|
+
export { AuditProgress, AuditRunnerOptions } from './types.js';
|
|
20
|
+
//# sourceMappingURL=auditRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auditRunner.d.ts","sourceRoot":"","sources":["../src/auditRunner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAuBpB;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB;iCAM5B,kBAAkB,KAAG,IAAI;oCAOhB,MAAM,KAAG,OAAO,CAAC,kBAAkB,CAAC;uBAQjD,kBAAkB,KAAG,OAAO,CAAC,WAAW,CAAC;6BAsF1B,WAAW,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;EAU7F;AA8FD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAGjF;AAED,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit Runner (Functional)
|
|
3
|
+
* Main orchestrator for running code audits
|
|
4
|
+
*/
|
|
5
|
+
import { discoverFiles } from './utils/fileDiscovery.js';
|
|
6
|
+
import { loadConfig } from './config/configLoader.js';
|
|
7
|
+
import { generateReport } from './reporting/reportGenerator.js';
|
|
8
|
+
// Import analyzer definitions
|
|
9
|
+
import { solidAnalyzer } from './analyzers/solidAnalyzer.js';
|
|
10
|
+
import { dryAnalyzer } from './analyzers/dryAnalyzer.js';
|
|
11
|
+
// import { securityAnalyzer } from './analyzers/securityAnalyzer.js';
|
|
12
|
+
// import { componentAnalyzer } from './analyzers/componentAnalyzer.js';
|
|
13
|
+
import { dataAccessAnalyzer } from './analyzers/dataAccessAnalyzer.js';
|
|
14
|
+
/**
|
|
15
|
+
* Default analyzer registry
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_ANALYZERS = {
|
|
18
|
+
'solid': solidAnalyzer,
|
|
19
|
+
'dry': dryAnalyzer,
|
|
20
|
+
// 'security': securityAnalyzer,
|
|
21
|
+
// 'component': componentAnalyzer,
|
|
22
|
+
'data-access': dataAccessAnalyzer
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Create an audit runner with the given options
|
|
26
|
+
*/
|
|
27
|
+
export function createAuditRunner(options = {}) {
|
|
28
|
+
const analyzerRegistry = { ...DEFAULT_ANALYZERS };
|
|
29
|
+
/**
|
|
30
|
+
* Register a custom analyzer
|
|
31
|
+
*/
|
|
32
|
+
function registerAnalyzer(analyzer) {
|
|
33
|
+
analyzerRegistry[analyzer.name] = analyzer;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Load configuration from file
|
|
37
|
+
*/
|
|
38
|
+
async function loadConfiguration(configPath) {
|
|
39
|
+
const config = await loadConfig({ configPath });
|
|
40
|
+
return { ...options, ...config };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Run the audit
|
|
44
|
+
*/
|
|
45
|
+
async function run(runOptions) {
|
|
46
|
+
const mergedOptions = { ...options, ...runOptions };
|
|
47
|
+
const startTime = Date.now();
|
|
48
|
+
// Report progress
|
|
49
|
+
reportProgress(mergedOptions, {
|
|
50
|
+
phase: 'discovery',
|
|
51
|
+
message: 'Discovering files...'
|
|
52
|
+
});
|
|
53
|
+
// Discover files
|
|
54
|
+
const files = await discoverProjectFiles(mergedOptions);
|
|
55
|
+
// Run analyzers
|
|
56
|
+
const analyzerResults = {};
|
|
57
|
+
const enabledAnalyzers = getEnabledAnalyzers(mergedOptions, analyzerRegistry);
|
|
58
|
+
for (const analyzerName of enabledAnalyzers) {
|
|
59
|
+
const analyzer = analyzerRegistry[analyzerName];
|
|
60
|
+
if (!analyzer) {
|
|
61
|
+
console.warn(`Unknown analyzer: ${analyzerName}`);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
reportProgress(mergedOptions, {
|
|
65
|
+
phase: 'analysis',
|
|
66
|
+
analyzer: analyzerName,
|
|
67
|
+
message: `Running ${analyzerName} analyzer...`
|
|
68
|
+
});
|
|
69
|
+
try {
|
|
70
|
+
const result = await analyzer.analyze(files, mergedOptions.analyzerConfigs?.[analyzerName] || {}, mergedOptions, (progress) => {
|
|
71
|
+
reportProgress(mergedOptions, {
|
|
72
|
+
phase: 'analysis',
|
|
73
|
+
analyzer: analyzerName,
|
|
74
|
+
current: progress.current,
|
|
75
|
+
total: progress.total,
|
|
76
|
+
message: `Analyzing ${progress.file}...`
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
analyzerResults[analyzerName] = result;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
reportError(mergedOptions, error, `${analyzerName} analyzer`);
|
|
83
|
+
analyzerResults[analyzerName] = {
|
|
84
|
+
violations: [],
|
|
85
|
+
filesProcessed: 0,
|
|
86
|
+
executionTime: 0,
|
|
87
|
+
errors: [{ file: 'analyzer', error: error.message }]
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Generate summary
|
|
92
|
+
const summary = generateSummary(analyzerResults);
|
|
93
|
+
// Create result
|
|
94
|
+
const result = {
|
|
95
|
+
timestamp: new Date(),
|
|
96
|
+
summary,
|
|
97
|
+
analyzerResults,
|
|
98
|
+
recommendations: [],
|
|
99
|
+
metadata: {
|
|
100
|
+
auditDuration: Date.now() - startTime,
|
|
101
|
+
filesAnalyzed: files.length,
|
|
102
|
+
analyzersRun: enabledAnalyzers,
|
|
103
|
+
configUsed: mergedOptions
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
// Report completion
|
|
107
|
+
reportProgress(mergedOptions, {
|
|
108
|
+
phase: 'reporting',
|
|
109
|
+
message: 'Generating reports...'
|
|
110
|
+
});
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Generate report in specified format
|
|
115
|
+
*/
|
|
116
|
+
async function generateReportForResult(result, format) {
|
|
117
|
+
return generateReport(result, format);
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
registerAnalyzer,
|
|
121
|
+
loadConfiguration,
|
|
122
|
+
run,
|
|
123
|
+
generateReport: generateReportForResult
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Discover files to analyze
|
|
128
|
+
*/
|
|
129
|
+
async function discoverProjectFiles(options) {
|
|
130
|
+
const rootDir = options.projectRoot || process.cwd();
|
|
131
|
+
return discoverFiles(rootDir, {
|
|
132
|
+
includePaths: options.includePaths,
|
|
133
|
+
excludePaths: options.excludePaths,
|
|
134
|
+
excludeDirs: undefined // This will use DEFAULT_EXCLUDED_DIRS which includes node_modules
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get list of enabled analyzers
|
|
139
|
+
*/
|
|
140
|
+
function getEnabledAnalyzers(options, registry) {
|
|
141
|
+
if (options.enabledAnalyzers && options.enabledAnalyzers.length > 0) {
|
|
142
|
+
return options.enabledAnalyzers;
|
|
143
|
+
}
|
|
144
|
+
return Object.keys(registry);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Generate audit summary
|
|
148
|
+
*/
|
|
149
|
+
function generateSummary(analyzerResults) {
|
|
150
|
+
let totalViolations = 0;
|
|
151
|
+
let criticalIssues = 0;
|
|
152
|
+
let warnings = 0;
|
|
153
|
+
let suggestions = 0;
|
|
154
|
+
const violationsByCategory = {};
|
|
155
|
+
for (const [analyzer, result] of Object.entries(analyzerResults)) {
|
|
156
|
+
for (const violation of result.violations) {
|
|
157
|
+
totalViolations++;
|
|
158
|
+
switch (violation.severity) {
|
|
159
|
+
case 'critical':
|
|
160
|
+
criticalIssues++;
|
|
161
|
+
break;
|
|
162
|
+
case 'warning':
|
|
163
|
+
warnings++;
|
|
164
|
+
break;
|
|
165
|
+
case 'suggestion':
|
|
166
|
+
suggestions++;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
const category = violation.type || analyzer;
|
|
170
|
+
violationsByCategory[category] = (violationsByCategory[category] || 0) + 1;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
totalFiles: 0,
|
|
175
|
+
totalViolations,
|
|
176
|
+
criticalIssues,
|
|
177
|
+
warnings,
|
|
178
|
+
suggestions,
|
|
179
|
+
violationsByCategory,
|
|
180
|
+
topIssues: []
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Report progress
|
|
185
|
+
*/
|
|
186
|
+
function reportProgress(options, progress) {
|
|
187
|
+
if (options.progressCallback) {
|
|
188
|
+
options.progressCallback({
|
|
189
|
+
current: 0,
|
|
190
|
+
total: 0,
|
|
191
|
+
analyzer: '',
|
|
192
|
+
...progress
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Report error
|
|
198
|
+
*/
|
|
199
|
+
function reportError(options, error, context) {
|
|
200
|
+
if (options.errorCallback) {
|
|
201
|
+
options.errorCallback(error, context);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
console.error(`Error in ${context}:`, error);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Run audit with default runner (convenience function)
|
|
209
|
+
*/
|
|
210
|
+
export async function runAudit(options) {
|
|
211
|
+
const runner = createAuditRunner(options);
|
|
212
|
+
return runner.run();
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=auditRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auditRunner.js","sourceRoot":"","sources":["../src/auditRunner.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;GAEG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Code Auditor CLI
|
|
4
|
+
*/
|
|
5
|
+
import { createAuditRunner } from './auditRunner.js';
|
|
6
|
+
import { parseArgs } from 'util';
|
|
7
|
+
async function main() {
|
|
8
|
+
console.log('🔍 Code Quality Audit Tool');
|
|
9
|
+
console.log('══════════════════════════════════════════════════');
|
|
10
|
+
const { values } = parseArgs({
|
|
11
|
+
options: {
|
|
12
|
+
help: { type: 'boolean', short: 'h' }
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
if (values.help) {
|
|
16
|
+
console.log(`
|
|
17
|
+
Usage: code-audit [options]
|
|
18
|
+
|
|
19
|
+
Options:
|
|
20
|
+
-h, --help Show help
|
|
21
|
+
`);
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const runner = createAuditRunner();
|
|
26
|
+
const result = await runner.run();
|
|
27
|
+
console.log(`\nFound ${result.summary.totalViolations} violations`);
|
|
28
|
+
console.log(`Critical: ${result.summary.criticalIssues}`);
|
|
29
|
+
console.log(`Warnings: ${result.summary.warnings}`);
|
|
30
|
+
console.log(`Suggestions: ${result.summary.suggestions}`);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.error('Error:', error);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
main();
|
|
38
|
+
//# sourceMappingURL=cli.js.map
|