UNPKG

@dawans/promptshield

Version:

Secure your LLM stack with enterprise-grade RulePacks for AI safety scanning

136 lines (135 loc) 8.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TableRenderer = void 0; const Result_1 = require("../../../../shared/types/Result"); const Violation_1 = require("../../../../shared/types/Violation"); const ScanMetrics_1 = require("../../../../shared/types/ScanMetrics"); /** * Table format renderer */ class TableRenderer { /** * Renders a report to table format */ async render(report) { try { const violations = report.getFilteredViolations(); const summary = Violation_1.ViolationUtils.createSummary(violations); const metrics = report.scanResult.metrics; let output = ''; // Header output += '┌─────────────────────────────────────────────────────────────────────────────────┐\n'; output += '│ PromptShield Scan Report │\n'; output += '└─────────────────────────────────────────────────────────────────────────────────┘\n\n'; // Summary table output += '📊 SUMMARY\n'; output += '┌─────────────────────┬─────────────────────────────────────────────────────────┐\n'; output += '│ Metric │ Value │\n'; output += '├─────────────────────┼─────────────────────────────────────────────────────────┤\n'; output += `│ Total Violations │ ${summary.total.toString().padEnd(55)} │\n`; output += `│ Objects Scanned │ ${metrics.objectsScanned.toString().padEnd(55)} │\n`; output += `│ Processing Time │ ${ScanMetrics_1.ScanMetricsUtils.formatProcessingTime(metrics.processingTime).padEnd(55)} │\n`; output += `│ Memory Usage │ ${ScanMetrics_1.ScanMetricsUtils.formatMemoryUsage(metrics.memoryUsage).padEnd(55)} │\n`; output += `│ Rules Applied │ ${metrics.rulesApplied.toString().padEnd(55)} │\n`; output += '└─────────────────────┴─────────────────────────────────────────────────────────┘\n\n'; // Severity breakdown if (summary.total > 0) { output += '🚨 SEVERITY BREAKDOWN\n'; output += '┌─────────────────────┬─────────────────────────────────────────────────────────┐\n'; output += '│ Severity │ Count │\n'; output += '├─────────────────────┼─────────────────────────────────────────────────────────┤\n'; for (const [severity, count] of Object.entries(summary.bySeverity)) { const emoji = this.getSeverityEmoji(severity); const severityText = `${emoji} ${severity}`; output += `│ ${severityText.padEnd(19)}${count.toString().padEnd(55)} │\n`; } output += '└─────────────────────┴─────────────────────────────────────────────────────────┘\n\n'; } // Violations table if (violations.length > 0) { output += '🔍 VIOLATIONS\n'; output += '┌─────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┐\n'; output += '│ Rule ID │ Severity │ Category │ Message │\n'; output += '├─────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤\n'; for (const violation of violations) { const emoji = this.getSeverityEmoji(violation.severity); const ruleId = this.truncateText(violation.ruleId, 19); const severity = `${emoji} ${violation.severity}`.padEnd(19); const category = this.truncateText(violation.category, 19); const message = this.truncateText(violation.message, 19); output += `│ ${ruleId}${severity}${category}${message} │\n`; } output += '└─────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┘\n\n'; } else { output += '✅ NO VIOLATIONS FOUND\n'; output += '┌─────────────────────────────────────────────────────────────────────────────────┐\n'; output += '│ No safety violations detected in the scanned content. │\n'; output += '└─────────────────────────────────────────────────────────────────────────────────┘\n\n'; } // Footer output += `Generated at ${new Date().toISOString()} by PromptShield v1.0.0\n`; return (0, Result_1.ok)(output); } catch (error) { return (0, Result_1.err)(new Error(`Failed to render table report: ${error}`)); } } /** * Gets the output format this renderer handles */ getFormat() { return 'table'; } /** * Checks if this renderer supports streaming */ supportsStreaming() { return false; } /** * Gets emoji for severity level */ getSeverityEmoji(severity) { switch (severity.toLowerCase()) { case 'critical': return '🔴'; case 'high': return '🟠'; case 'medium': return '🟡'; case 'low': return '🟢'; default: return '⚪'; } } /** * Truncates text to fit in table cells */ truncateText(text, maxLength) { if (text.length <= maxLength) { return text.padEnd(maxLength); } return text.substring(0, maxLength - 3) + '...'; } } exports.TableRenderer = TableRenderer;