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.

91 lines 3.98 kB
#!/usr/bin/env node import { Command } from 'commander'; import chalk from 'chalk'; import figlet from 'figlet'; import { generateReactHtmlReport } from '../generators/react-html-generator.js'; import { parseSarifFile } from '../core/sarif-parser.js'; import { validateInputFile, validateOutputPath } from '../utils/validators.js'; // Banner function function displayBanner() { console.log(chalk.cyan(figlet.textSync('SARIF EXPLORER', { font: 'Standard', horizontalLayout: 'default', verticalLayout: 'default' }))); console.log(chalk.gray('Convert SARIF reports to interactive HTML viewer\n')); } const program = new Command(); program .name('sarif-explorer') .description('Convert SARIF reports to interactive HTML viewer') .version('1.0.0') .option('-i, --input <path>', 'Path to SARIF report file', '') .option('-o, --output <path>', 'Path for generated HTML file', '') .option('-s, --source-dir <path>', 'Source directory for loading artifact files (default: SARIF file directory)', '') .option('--no-snippets', 'Exclude code snippets in the report') .option('-v, --verbose', 'Enable verbose logging', false) .action(async (options) => { try { const { input, output, sourceDir, snippets, verbose } = options; if (verbose) { console.log(chalk.blue('🔍 SARIF Explorer - Starting conversion process...')); } // Validate input file if (!input) { console.error(chalk.red('❌ Error: Input file path is required')); console.log(chalk.yellow('Usage: sarif-explorer --input path/to/report.sarif --output report.html')); process.exit(1); } if (!output) { console.error(chalk.red('❌ Error: Output file path is required')); console.log(chalk.yellow('Usage: sarif-explorer --input path/to/report.sarif --output report.html')); process.exit(1); } // Validate input file exists and is readable await validateInputFile(input); // Validate output directory is writable await validateOutputPath(output); // Prepare parse options const parseOptions = { sourceDir: sourceDir || undefined, includeSnippets: snippets, verbose }; if (verbose) { console.log(chalk.blue(`📁 Reading SARIF file: ${input}`)); if (sourceDir) { console.log(chalk.blue(`📂 Source directory: ${sourceDir}`)); } if (!snippets) { console.log(chalk.blue(`🚫 Code snippets disabled`)); } } // Parse SARIF file const sarifData = await parseSarifFile(input, parseOptions); if (verbose) { console.log(chalk.green(`✅ Parsed SARIF file successfully`)); console.log(chalk.blue(`📊 Found ${sarifData.files.length} files with issues`)); console.log(chalk.blue(`🚨 Total violations: ${sarifData.totalViolations}`)); } // Generate HTML report if (verbose) { console.log(chalk.blue(`🔄 Generating HTML report...`)); } await generateReactHtmlReport(sarifData, output); console.log(chalk.green(`✅ SARIF report generated successfully!`)); console.log(chalk.blue(`📄 Output file: ${output}`)); console.log(chalk.blue(`📊 Files with issues: ${sarifData.files.length}`)); console.log(chalk.blue(`🚨 Total violations: ${sarifData.totalViolations}`)); } catch (error) { console.error(chalk.red(`❌ Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`)); if (options.verbose && error instanceof Error && error.stack) { console.error(chalk.gray(error.stack)); } process.exit(1); } }); // Display banner displayBanner(); program.parse(); //# sourceMappingURL=index.js.map