UNPKG

vibe-guard

Version:

šŸ›”ļø Vibe-Guard Security Scanner - Catch security issues before they catch you!

122 lines • 5.31 kB
"use strict"; 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