vibe-guard
Version:
š”ļø Vibe-Guard Security Scanner - Catch security issues before they catch you!
122 lines ⢠5.31 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Reporter = void 0;
const Table = require('cli-table3');
const chalk_1 = __importDefault(require("chalk"));
class Reporter {
formatTable(result) {
if (result.issues.length === 0) {
return this.formatSuccess(result);
}
const table = new Table({
head: [
chalk_1.default.bold('Rule'),
chalk_1.default.bold('Severity'),
chalk_1.default.bold('File'),
chalk_1.default.bold('Line'),
chalk_1.default.bold('Message')
],
colWidths: [25, 12, 40, 8, 60],
wordWrap: true
});
result.issues.forEach(issue => {
table.push([
issue.rule,
this.colorSeverity(issue.severity),
this.truncateFilePath(issue.file),
issue.line.toString(),
issue.message
]);
});
return this.formatHeader(result) + '\n\n' + table.toString() + '\n\n' + this.formatSummary(result);
}
formatJson(result) {
return JSON.stringify(result, null, 2);
}
formatSuccess(result) {
const header = chalk_1.default.green.bold('š”ļø Vibe-Guard Security Scan Complete');
const summary = chalk_1.default.green(`ā
No security issues found in ${result.filesScanned} files`);
return `${header}\n\n${summary}\n`;
}
formatHeader(result) {
const title = chalk_1.default.red.bold('šØ Vibe-Guard Security Issues Detected');
const subtitle = chalk_1.default.yellow(`Found ${result.issuesFound} security issues in ${result.filesScanned} files`);
return `${title}\n${subtitle}`;
}
formatSummary(result) {
const { summary } = result;
const parts = [];
if (summary.critical > 0) {
parts.push(chalk_1.default.red.bold(`${summary.critical} Critical`));
}
if (summary.high > 0) {
parts.push(chalk_1.default.red(`${summary.high} High`));
}
if (summary.medium > 0) {
parts.push(chalk_1.default.yellow(`${summary.medium} Medium`));
}
if (summary.low > 0) {
parts.push(chalk_1.default.blue(`${summary.low} Low`));
}
const summaryText = parts.length > 0 ? parts.join(' | ') : 'No issues';
return chalk_1.default.bold('Summary: ') + summaryText + '\n\n' + this.formatRecommendations();
}
formatRecommendations() {
return chalk_1.default.cyan.bold('š” Recommendations:\n') +
chalk_1.default.cyan('⢠Review and fix critical and high severity issues immediately\n') +
chalk_1.default.cyan('⢠Consider implementing security linting in your CI/CD pipeline\n') +
chalk_1.default.cyan('⢠Run Vibe-Guard regularly during development\n') +
chalk_1.default.cyan('⢠Check our documentation for detailed fix suggestions');
}
colorSeverity(severity) {
switch (severity) {
case 'critical':
return chalk_1.default.red.bold('CRITICAL');
case 'high':
return chalk_1.default.red('HIGH');
case 'medium':
return chalk_1.default.yellow('MEDIUM');
case 'low':
return chalk_1.default.blue('LOW');
default:
return String(severity).toUpperCase();
}
}
truncateFilePath(filePath, maxLength = 35) {
// Normalize all slashes to '/'
let sanitizedPath = filePath.replace(/\\+/g, '/').replace(/\\/g, '/').replace(/\/+/g, '/');
// Remove '..' and multiple slashes
sanitizedPath = sanitizedPath.replace(/\.\./g, '').replace(/\/+/g, '/');
// Remove leading slashes
sanitizedPath = sanitizedPath.replace(/^\/+/, '');
if (sanitizedPath.length <= maxLength) {
return sanitizedPath;
}
const parts = sanitizedPath.split('/');
if (parts.length <= 2) {
return sanitizedPath;
}
// Show first and last parts with ... in between
const first = parts[0];
const last = parts[parts.length - 1];
const truncated = `${first}/.../${last}`;
if (truncated.length <= maxLength) {
return truncated;
}
// If still too long, just truncate from the beginning
return '...' + sanitizedPath.slice(-(maxLength - 3));
}
formatIssueDetails(issue) {
const header = chalk_1.default.red.bold(`\nšØ ${issue.rule} (${this.colorSeverity(issue.severity)})`);
const location = chalk_1.default.gray(`š ${issue.file}:${issue.line}:${issue.column}`);
const message = chalk_1.default.white(`š¬ ${issue.message}`);
const code = chalk_1.default.gray(`š Code: ${issue.code}`);
const suggestion = chalk_1.default.green(`š” Suggestion: ${issue.suggestion}`);
return `${header}\n${location}\n${message}\n${code}\n${suggestion}\n`;
}
}
exports.Reporter = Reporter;
//# sourceMappingURL=reporter.js.map