UNPKG

sarif-explorer

Version:

A modern SARIF report viewer that converts SARIF files into interactive, shareable HTML reports with file explorer, collapsible issue lists, and code snippets.

95 lines (92 loc) 3.4 kB
import fs from 'fs/promises'; /** * Generate HTML report from SARIF data */ export async function generateHtmlReport(sarifData, outputPath) { // TODO: Implement HTML generation in Phase 3 // For now, create a basic placeholder HTML const htmlContent = generateBasicHtml(sarifData); // Write the HTML file await fs.writeFile(outputPath, htmlContent, 'utf8'); } /** * Generate basic HTML content (placeholder implementation) */ function generateBasicHtml(sarifData) { const { files, fileViolations, totalViolations, statistics } = sarifData; return `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SARIF Report</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .header { background: #f0f0f0; padding: 20px; border-radius: 5px; } .stats { display: flex; gap: 20px; margin: 20px 0; } .stat { background: #e0e0e0; padding: 10px; border-radius: 3px; } .file { margin: 20px 0; border: 1px solid #ccc; border-radius: 5px; } .file-header { background: #f5f5f5; padding: 10px; font-weight: bold; } .violation { margin: 10px; padding: 10px; border-left: 4px solid #ff4444; } .violation.error { border-left-color: #ff4444; } .violation.warning { border-left-color: #ff8800; } .violation.info { border-left-color: #0176d3; } .code-snippet { background: #f8f8f8; padding: 10px; font-family: monospace; white-space: pre; } </style> </head> <body> <div class="header"> <h1>SARIF Report</h1> <p>Generated by SARIF Explorer</p> </div> <div class="stats"> <div class="stat">Files with Issues: ${files.length}</div> <div class="stat">Total Violations: ${totalViolations}</div> <div class="stat">Errors: ${statistics.errorCount}</div> <div class="stat">Warnings: ${statistics.warningCount}</div> <div class="stat">Info: ${statistics.infoCount}</div> </div> ${files.map(file => generateFileHtml(file, fileViolations[file])).join('')} <script> // TODO: Add interactive functionality in Phase 3 console.log('SARIF Report loaded'); </script> </body> </html>`; } /** * Generate HTML for a single file */ function generateFileHtml(fileName, violations) { return ` <div class="file"> <div class="file-header">${escapeHtml(fileName)} (${violations.length} violations)</div> ${violations.map(violation => generateViolationHtml(violation)).join('')} </div> `; } /** * Generate HTML for a single violation */ function generateViolationHtml(violation) { return ` <div class="violation ${violation.level}"> <div><strong>${escapeHtml(violation.ruleId)}</strong> (${violation.level})</div> <div>${escapeHtml(violation.message)}</div> <div>Line ${violation.line}, Column ${violation.column}</div> ${violation.snippet ? `<div class="code-snippet">${escapeHtml(violation.snippet)}</div>` : ''} </div> `; } /** * Escape HTML to prevent XSS */ function escapeHtml(text) { return text .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&#039;'); } //# sourceMappingURL=html-generator.js.map