@behavioral-contracts/verify-cli 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-prompt-generator.d.ts +16 -0
- package/dist/ai-prompt-generator.d.ts.map +1 -0
- package/dist/ai-prompt-generator.js +481 -0
- package/dist/ai-prompt-generator.js.map +1 -0
- package/dist/analyzer.d.ts +41 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +93 -1
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzers/event-listener-analyzer.d.ts +39 -4
- package/dist/analyzers/event-listener-analyzer.d.ts.map +1 -1
- package/dist/analyzers/event-listener-analyzer.js +123 -10
- package/dist/analyzers/event-listener-analyzer.js.map +1 -1
- package/dist/cli/suppressions.d.ts +9 -0
- package/dist/cli/suppressions.d.ts.map +1 -0
- package/dist/cli/suppressions.js +242 -0
- package/dist/cli/suppressions.js.map +1 -0
- package/dist/index.js +93 -38
- package/dist/index.js.map +1 -1
- package/dist/suppressions/config-loader.d.ts +47 -0
- package/dist/suppressions/config-loader.d.ts.map +1 -0
- package/dist/suppressions/config-loader.js +214 -0
- package/dist/suppressions/config-loader.js.map +1 -0
- package/dist/suppressions/dead-suppression-detector.d.ts +45 -0
- package/dist/suppressions/dead-suppression-detector.d.ts.map +1 -0
- package/dist/suppressions/dead-suppression-detector.js +101 -0
- package/dist/suppressions/dead-suppression-detector.js.map +1 -0
- package/dist/suppressions/index.d.ts +12 -0
- package/dist/suppressions/index.d.ts.map +1 -0
- package/dist/suppressions/index.js +18 -0
- package/dist/suppressions/index.js.map +1 -0
- package/dist/suppressions/manifest.d.ts +114 -0
- package/dist/suppressions/manifest.d.ts.map +1 -0
- package/dist/suppressions/manifest.js +281 -0
- package/dist/suppressions/manifest.js.map +1 -0
- package/dist/suppressions/matcher.d.ts +73 -0
- package/dist/suppressions/matcher.d.ts.map +1 -0
- package/dist/suppressions/matcher.js +163 -0
- package/dist/suppressions/matcher.js.map +1 -0
- package/dist/suppressions/parser.d.ts +59 -0
- package/dist/suppressions/parser.d.ts.map +1 -0
- package/dist/suppressions/parser.js +156 -0
- package/dist/suppressions/parser.js.map +1 -0
- package/dist/suppressions/types.d.ts +121 -0
- package/dist/suppressions/types.d.ts.map +1 -0
- package/dist/suppressions/types.js +8 -0
- package/dist/suppressions/types.js.map +1 -0
- package/package.json +4 -2
|
@@ -42,13 +42,16 @@ export class EventListenerAnalyzer {
|
|
|
42
42
|
* 2. Find all .on(), .addEventListener(), .once() calls for tracked instances
|
|
43
43
|
* 3. Check if all required listeners are attached
|
|
44
44
|
* 4. Report violations for missing required listeners
|
|
45
|
+
*
|
|
46
|
+
* @param functionNode - The node to analyze (SourceFile for module-level, FunctionDeclaration for function-level)
|
|
47
|
+
* @param moduleLevelOnly - If true, stop traversal at function boundaries (for module-level analysis)
|
|
45
48
|
*/
|
|
46
|
-
analyze(functionNode) {
|
|
49
|
+
analyze(functionNode, moduleLevelOnly = false) {
|
|
47
50
|
const violations = [];
|
|
48
51
|
// Step 1: Find all instance declarations requiring event listeners
|
|
49
|
-
this.findInstanceDeclarations(functionNode);
|
|
52
|
+
this.findInstanceDeclarations(functionNode, moduleLevelOnly);
|
|
50
53
|
// Step 2: Find all event listener attachments
|
|
51
|
-
this.findEventListeners(functionNode);
|
|
54
|
+
this.findEventListeners(functionNode, moduleLevelOnly);
|
|
52
55
|
// Step 3: Validate all required listeners are attached
|
|
53
56
|
for (const [varName, instance] of this.trackedInstances.entries()) {
|
|
54
57
|
for (const requiredListener of instance.requiredListeners) {
|
|
@@ -72,22 +75,35 @@ export class EventListenerAnalyzer {
|
|
|
72
75
|
* Find all instance declarations from contracts with required event listeners
|
|
73
76
|
*
|
|
74
77
|
* Patterns detected:
|
|
75
|
-
* - const ws = new WebSocket(url)
|
|
76
|
-
* - const queue = new Queue('tasks')
|
|
77
|
-
* -
|
|
78
|
+
* - const ws = new WebSocket(url) ← Constructor pattern
|
|
79
|
+
* - const queue = new Queue('tasks') ← Constructor pattern
|
|
80
|
+
* - const archive = archiver('zip') ← Factory pattern (NEW)
|
|
81
|
+
* - const socket = io(url) ← Factory pattern (NEW)
|
|
82
|
+
* - const client = createClient() ← Factory pattern (NEW)
|
|
83
|
+
* - this.client = axios.create() ← Property assignment
|
|
84
|
+
*
|
|
85
|
+
* @param moduleLevelOnly - If true, stop traversal at function boundaries
|
|
78
86
|
*/
|
|
79
|
-
findInstanceDeclarations(node) {
|
|
87
|
+
findInstanceDeclarations(node, moduleLevelOnly = false) {
|
|
80
88
|
const self = this;
|
|
81
89
|
function visit(node) {
|
|
82
|
-
//
|
|
90
|
+
// If module-level only, stop at function boundaries
|
|
91
|
+
if (moduleLevelOnly && self.isFunctionLike(node)) {
|
|
92
|
+
return; // Don't traverse into functions
|
|
93
|
+
}
|
|
94
|
+
// Pattern: const ws = new WebSocket(url) OR const archive = archiver('zip')
|
|
83
95
|
if (ts.isVariableDeclaration(node) && node.initializer) {
|
|
84
96
|
self.checkNewExpression(node);
|
|
97
|
+
self.checkFactoryMethodCall(node);
|
|
85
98
|
}
|
|
86
|
-
// Pattern: this.ws = new WebSocket(url)
|
|
99
|
+
// Pattern: this.ws = new WebSocket(url) OR this.archive = archiver('zip')
|
|
87
100
|
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
|
|
88
101
|
if (ts.isNewExpression(node.right)) {
|
|
89
102
|
self.checkNewExpressionForAssignment(node);
|
|
90
103
|
}
|
|
104
|
+
if (ts.isCallExpression(node.right)) {
|
|
105
|
+
self.checkFactoryMethodCallForAssignment(node);
|
|
106
|
+
}
|
|
91
107
|
}
|
|
92
108
|
ts.forEachChild(node, visit);
|
|
93
109
|
}
|
|
@@ -181,6 +197,88 @@ export class EventListenerAnalyzer {
|
|
|
181
197
|
}
|
|
182
198
|
return null;
|
|
183
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Check if a factory method call creates an instance requiring event listeners
|
|
202
|
+
*
|
|
203
|
+
* Patterns:
|
|
204
|
+
* - const archive = archiver('zip')
|
|
205
|
+
* - const socket = io(url)
|
|
206
|
+
* - const client = createClient()
|
|
207
|
+
*/
|
|
208
|
+
checkFactoryMethodCall(declaration) {
|
|
209
|
+
if (!declaration.initializer || !ts.isCallExpression(declaration.initializer)) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const callExpr = declaration.initializer;
|
|
213
|
+
const functionName = this.getFunctionName(callExpr);
|
|
214
|
+
if (!functionName)
|
|
215
|
+
return;
|
|
216
|
+
// Check if any contract declares this factory method with required event listeners
|
|
217
|
+
for (const [packageName, contract] of this.contracts.entries()) {
|
|
218
|
+
if (!contract.detection?.required_event_listeners)
|
|
219
|
+
continue;
|
|
220
|
+
if (!contract.detection.factory_methods?.includes(functionName))
|
|
221
|
+
continue;
|
|
222
|
+
// This factory method creates instances requiring event listeners - track it
|
|
223
|
+
const varName = declaration.name.getText(this.sourceFile);
|
|
224
|
+
this.trackedInstances.set(varName, {
|
|
225
|
+
packageName,
|
|
226
|
+
className: functionName, // Use factory method name as "className"
|
|
227
|
+
requiredListeners: contract.detection.required_event_listeners,
|
|
228
|
+
declarationNode: declaration,
|
|
229
|
+
attachedEvents: new Set(),
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Check factory method call in assignment: this.archive = archiver('zip')
|
|
235
|
+
*/
|
|
236
|
+
checkFactoryMethodCallForAssignment(assignment) {
|
|
237
|
+
if (!ts.isCallExpression(assignment.right))
|
|
238
|
+
return;
|
|
239
|
+
const callExpr = assignment.right;
|
|
240
|
+
const functionName = this.getFunctionName(callExpr);
|
|
241
|
+
if (!functionName)
|
|
242
|
+
return;
|
|
243
|
+
// Check if any contract declares this factory method with required event listeners
|
|
244
|
+
for (const [packageName, contract] of this.contracts.entries()) {
|
|
245
|
+
if (!contract.detection?.required_event_listeners)
|
|
246
|
+
continue;
|
|
247
|
+
if (!contract.detection.factory_methods?.includes(functionName))
|
|
248
|
+
continue;
|
|
249
|
+
// Extract variable name from left side (e.g., "archive" from "this.archive")
|
|
250
|
+
const varName = this.getVariableNameFromExpression(assignment.left);
|
|
251
|
+
if (!varName)
|
|
252
|
+
return;
|
|
253
|
+
this.trackedInstances.set(varName, {
|
|
254
|
+
packageName,
|
|
255
|
+
className: functionName, // Use factory method name as "className"
|
|
256
|
+
requiredListeners: contract.detection.required_event_listeners,
|
|
257
|
+
declarationNode: assignment,
|
|
258
|
+
attachedEvents: new Set(),
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Extract function name from call expression
|
|
264
|
+
*
|
|
265
|
+
* Examples:
|
|
266
|
+
* - archiver('zip') → "archiver"
|
|
267
|
+
* - io(url) → "io"
|
|
268
|
+
* - redis.createClient() → "createClient"
|
|
269
|
+
*/
|
|
270
|
+
getFunctionName(callExpr) {
|
|
271
|
+
const expr = callExpr.expression;
|
|
272
|
+
// Direct function call: archiver('zip')
|
|
273
|
+
if (ts.isIdentifier(expr)) {
|
|
274
|
+
return expr.text;
|
|
275
|
+
}
|
|
276
|
+
// Property access: redis.createClient()
|
|
277
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
278
|
+
return expr.name.text;
|
|
279
|
+
}
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
184
282
|
/**
|
|
185
283
|
* Find all event listener attachments
|
|
186
284
|
*
|
|
@@ -190,9 +288,13 @@ export class EventListenerAnalyzer {
|
|
|
190
288
|
* - ws.once('error', handler)
|
|
191
289
|
* - this.ws.on('error', handler)
|
|
192
290
|
*/
|
|
193
|
-
findEventListeners(node) {
|
|
291
|
+
findEventListeners(node, moduleLevelOnly = false) {
|
|
194
292
|
const self = this;
|
|
195
293
|
function visit(node) {
|
|
294
|
+
// If module-level only, stop at function boundaries
|
|
295
|
+
if (moduleLevelOnly && self.isFunctionLike(node)) {
|
|
296
|
+
return; // Don't traverse into functions
|
|
297
|
+
}
|
|
196
298
|
if (ts.isCallExpression(node)) {
|
|
197
299
|
self.checkEventListenerCall(node);
|
|
198
300
|
}
|
|
@@ -249,5 +351,16 @@ export class EventListenerAnalyzer {
|
|
|
249
351
|
}
|
|
250
352
|
return null;
|
|
251
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Check if a node is a function-like construct
|
|
356
|
+
* Used to stop traversal at function boundaries in module-level analysis
|
|
357
|
+
*/
|
|
358
|
+
isFunctionLike(node) {
|
|
359
|
+
return (ts.isFunctionDeclaration(node) ||
|
|
360
|
+
ts.isFunctionExpression(node) ||
|
|
361
|
+
ts.isArrowFunction(node) ||
|
|
362
|
+
ts.isMethodDeclaration(node) ||
|
|
363
|
+
ts.isConstructorDeclaration(node));
|
|
364
|
+
}
|
|
252
365
|
}
|
|
253
366
|
//# sourceMappingURL=event-listener-analyzer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-listener-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/event-listener-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAoBjC,MAAM,OAAO,qBAAqB;IACxB,UAAU,CAAgB;IAC1B,SAAS,CAA+B;IAChD,mFAAmF;IAEnF,4CAA4C;IACpC,gBAAgB,GAAiC,IAAI,GAAG,EAAE,CAAC;IAEnE,YACE,UAAyB,EACzB,SAAuC,EACvC,YAA4B,CAAE,mDAAmD;;QAEjF,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,8EAA8E;IAChF,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"event-listener-analyzer.js","sourceRoot":"","sources":["../../src/analyzers/event-listener-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.d.ts","sourceRoot":"","sources":["../../src/cli/suppressions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAWnD"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Commands for Suppression Management
|
|
3
|
+
*/
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import { loadManifestSync, getActiveSuppressions, getDeadSuppressions, detectDeadSuppressions, removeDeadSuppressionsFromManifest, getSuppressionStats } from '../suppressions/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Create suppressions subcommand
|
|
10
|
+
*/
|
|
11
|
+
export function createSuppressionsCommand() {
|
|
12
|
+
const suppressions = new Command('suppressions');
|
|
13
|
+
suppressions
|
|
14
|
+
.description('Manage behavioral contract suppressions')
|
|
15
|
+
.addCommand(createListCommand())
|
|
16
|
+
.addCommand(createShowCommand())
|
|
17
|
+
.addCommand(createCleanCommand())
|
|
18
|
+
.addCommand(createStatsCommand());
|
|
19
|
+
return suppressions;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* List all suppressions
|
|
23
|
+
*/
|
|
24
|
+
function createListCommand() {
|
|
25
|
+
const list = new Command('list');
|
|
26
|
+
list
|
|
27
|
+
.description('List all suppressions')
|
|
28
|
+
.option('--dead', 'Show only dead suppressions')
|
|
29
|
+
.option('--active', 'Show only active suppressions')
|
|
30
|
+
.option('--json', 'Output as JSON')
|
|
31
|
+
.option('--project <path>', 'Project root directory', process.cwd())
|
|
32
|
+
.action((options) => {
|
|
33
|
+
const projectRoot = path.resolve(options.project);
|
|
34
|
+
try {
|
|
35
|
+
const manifest = loadManifestSync(projectRoot);
|
|
36
|
+
let suppressions;
|
|
37
|
+
if (options.dead) {
|
|
38
|
+
suppressions = getDeadSuppressions(manifest);
|
|
39
|
+
}
|
|
40
|
+
else if (options.active) {
|
|
41
|
+
suppressions = getActiveSuppressions(manifest);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
suppressions = manifest.suppressions;
|
|
45
|
+
}
|
|
46
|
+
if (options.json) {
|
|
47
|
+
console.log(JSON.stringify(suppressions, null, 2));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
printSuppressionsList(suppressions, options);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return list;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Show specific suppression
|
|
62
|
+
*/
|
|
63
|
+
function createShowCommand() {
|
|
64
|
+
const show = new Command('show');
|
|
65
|
+
show
|
|
66
|
+
.description('Show details of a specific suppression')
|
|
67
|
+
.argument('<location>', 'Suppression location (format: file:line or suppression-id)')
|
|
68
|
+
.option('--project <path>', 'Project root directory', process.cwd())
|
|
69
|
+
.action((location, options) => {
|
|
70
|
+
const projectRoot = path.resolve(options.project);
|
|
71
|
+
try {
|
|
72
|
+
const manifest = loadManifestSync(projectRoot);
|
|
73
|
+
// Parse location (file:line or suppression-id)
|
|
74
|
+
let suppression;
|
|
75
|
+
if (location.includes(':')) {
|
|
76
|
+
const [file, lineStr] = location.split(':');
|
|
77
|
+
const line = parseInt(lineStr, 10);
|
|
78
|
+
suppression = manifest.suppressions.find(s => s.file === file && s.line === line);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
suppression = manifest.suppressions.find(s => s.id === location);
|
|
82
|
+
}
|
|
83
|
+
if (!suppression) {
|
|
84
|
+
console.error(chalk.red(`No suppression found at: ${location}`));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
printSuppressionDetails(suppression);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
return show;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Clean up dead suppressions
|
|
98
|
+
*/
|
|
99
|
+
function createCleanCommand() {
|
|
100
|
+
const clean = new Command('clean');
|
|
101
|
+
clean
|
|
102
|
+
.description('Remove dead suppressions from manifest and optionally from code')
|
|
103
|
+
.option('--auto', 'Automatically clean without confirmation')
|
|
104
|
+
.option('--manifest-only', 'Only update manifest, do not modify code')
|
|
105
|
+
.option('--project <path>', 'Project root directory', process.cwd())
|
|
106
|
+
.action(async (options) => {
|
|
107
|
+
const projectRoot = path.resolve(options.project);
|
|
108
|
+
try {
|
|
109
|
+
const deadSuppressions = detectDeadSuppressions(projectRoot, '1.1.0');
|
|
110
|
+
if (deadSuppressions.length === 0) {
|
|
111
|
+
console.log(chalk.green('✨ No dead suppressions found!'));
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
console.log(chalk.yellow(`Found ${deadSuppressions.length} dead suppressions:\n`));
|
|
115
|
+
// Show dead suppressions
|
|
116
|
+
deadSuppressions.forEach((dead, index) => {
|
|
117
|
+
console.log(chalk.dim(`${index + 1}. ${dead.suppression.file}:${dead.suppression.line}`));
|
|
118
|
+
console.log(chalk.dim(` Package: ${dead.suppression.package}/${dead.suppression.postconditionId}`));
|
|
119
|
+
console.log(chalk.dim(` Reason: ${dead.improvementReason || 'Analyzer improved'}\n`));
|
|
120
|
+
});
|
|
121
|
+
if (!options.auto) {
|
|
122
|
+
console.log(chalk.yellow('Run with --auto to remove these suppressions'));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Remove from manifest
|
|
126
|
+
const removed = removeDeadSuppressionsFromManifest(projectRoot);
|
|
127
|
+
console.log(chalk.green(`✅ Removed ${removed} dead suppressions from manifest`));
|
|
128
|
+
if (!options.manifestOnly) {
|
|
129
|
+
console.log(chalk.yellow('\n⚠️ Note: Inline comments must be removed manually.'));
|
|
130
|
+
console.log(chalk.dim('The following lines should be removed:\n'));
|
|
131
|
+
deadSuppressions.forEach(dead => {
|
|
132
|
+
console.log(chalk.dim(` ${dead.suppression.file}:${dead.suppression.line - 1}`));
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return clean;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Show suppression statistics
|
|
145
|
+
*/
|
|
146
|
+
function createStatsCommand() {
|
|
147
|
+
const stats = new Command('stats');
|
|
148
|
+
stats
|
|
149
|
+
.description('Show suppression statistics')
|
|
150
|
+
.option('--json', 'Output as JSON')
|
|
151
|
+
.option('--project <path>', 'Project root directory', process.cwd())
|
|
152
|
+
.action((options) => {
|
|
153
|
+
const projectRoot = path.resolve(options.project);
|
|
154
|
+
try {
|
|
155
|
+
const statsData = getSuppressionStats(projectRoot);
|
|
156
|
+
if (options.json) {
|
|
157
|
+
console.log(JSON.stringify({
|
|
158
|
+
...statsData,
|
|
159
|
+
byPackage: Object.fromEntries(statsData.byPackage)
|
|
160
|
+
}, null, 2));
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
printStats(statsData);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
return stats;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Print suppressions list
|
|
175
|
+
*/
|
|
176
|
+
function printSuppressionsList(suppressions, options) {
|
|
177
|
+
if (suppressions.length === 0) {
|
|
178
|
+
console.log(chalk.dim('No suppressions found.'));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const title = options.dead
|
|
182
|
+
? '💀 Dead Suppressions'
|
|
183
|
+
: options.active
|
|
184
|
+
? '✅ Active Suppressions'
|
|
185
|
+
: '📋 All Suppressions';
|
|
186
|
+
console.log(chalk.bold(`\n${title} (${suppressions.length} total)\n`));
|
|
187
|
+
suppressions.forEach((s, index) => {
|
|
188
|
+
const status = s.stillViolates
|
|
189
|
+
? chalk.green('✓ Active')
|
|
190
|
+
: chalk.red('✗ Dead');
|
|
191
|
+
console.log(`${index + 1}. ${chalk.cyan(s.file)}:${chalk.yellow(s.line)}`);
|
|
192
|
+
console.log(` ${status} | ${s.package}/${s.postconditionId}`);
|
|
193
|
+
console.log(chalk.dim(` Reason: ${s.reason}`));
|
|
194
|
+
console.log(chalk.dim(` Suppressed: ${new Date(s.suppressedAt).toLocaleDateString()}\n`));
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Print suppression details
|
|
199
|
+
*/
|
|
200
|
+
function printSuppressionDetails(suppression) {
|
|
201
|
+
console.log(chalk.bold('\n📍 Suppression Details\n'));
|
|
202
|
+
console.log(`${chalk.bold('ID:')} ${suppression.id}`);
|
|
203
|
+
console.log(`${chalk.bold('Location:')} ${chalk.cyan(suppression.file)}:${chalk.yellow(suppression.line)}`);
|
|
204
|
+
console.log(`${chalk.bold('Package:')} ${suppression.package}`);
|
|
205
|
+
console.log(`${chalk.bold('Postcondition:')} ${suppression.postconditionId}`);
|
|
206
|
+
console.log(`${chalk.bold('Status:')} ${suppression.stillViolates ? chalk.green('Active') : chalk.red('Dead')}`);
|
|
207
|
+
console.log(`${chalk.bold('Reason:')} ${suppression.reason}`);
|
|
208
|
+
console.log(`${chalk.bold('Suppressed At:')} ${new Date(suppression.suppressedAt).toLocaleString()}`);
|
|
209
|
+
console.log(`${chalk.bold('Suppressed By:')} ${suppression.suppressedBy}`);
|
|
210
|
+
console.log(`${chalk.bold('Last Checked:')} ${new Date(suppression.lastChecked).toLocaleString()}`);
|
|
211
|
+
console.log(`${chalk.bold('Analyzer Version:')} ${suppression.analyzerVersion}`);
|
|
212
|
+
if (!suppression.stillViolates) {
|
|
213
|
+
console.log(chalk.yellow('\n⚠️ This suppression is dead and can be removed!'));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Print statistics
|
|
218
|
+
*/
|
|
219
|
+
function printStats(stats) {
|
|
220
|
+
console.log(chalk.bold('\n📊 Suppression Statistics\n'));
|
|
221
|
+
console.log(`${chalk.bold('Total Suppressions:')} ${stats.totalSuppressions}`);
|
|
222
|
+
console.log(`${chalk.bold('Active:')} ${chalk.green(stats.activeSuppressions.toString())}`);
|
|
223
|
+
console.log(`${chalk.bold('Dead:')} ${chalk.red(stats.deadSuppressions.toString())}`);
|
|
224
|
+
console.log(chalk.bold('\n📦 By Source:\n'));
|
|
225
|
+
console.log(` Inline Comments: ${stats.bySource.inlineComment}`);
|
|
226
|
+
console.log(` Config File: ${stats.bySource.configFile}`);
|
|
227
|
+
console.log(` AI Agent: ${stats.bySource.aiAgent}`);
|
|
228
|
+
console.log(` CLI: ${stats.bySource.cli}`);
|
|
229
|
+
if (stats.byPackage.size > 0) {
|
|
230
|
+
console.log(chalk.bold('\n📚 By Package:\n'));
|
|
231
|
+
const sortedPackages = Array.from(stats.byPackage.entries())
|
|
232
|
+
.sort((a, b) => b[1] - a[1]);
|
|
233
|
+
sortedPackages.forEach(([pkg, count]) => {
|
|
234
|
+
console.log(` ${pkg}: ${count}`);
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
if (stats.deadSuppressions > 0) {
|
|
238
|
+
console.log(chalk.yellow(`\n⚠️ You have ${stats.deadSuppressions} dead suppressions that can be cleaned up.`));
|
|
239
|
+
console.log(chalk.dim(' Run: verify-cli suppressions clean --auto'));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=suppressions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppressions.js","sourceRoot":"","sources":["../../src/cli/suppressions.ts"],"names":[],"mappings":"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"}
|