UNPKG

arela

Version:

AI-powered CTO with multi-agent orchestration, code summarization, visual testing (web + mobile) for blazing fast development.

215 lines • 7.74 kB
/** * Format and report contract generation results */ import pc from 'picocolors'; /** * Display contract generation report */ export function displayContractReport(report) { console.log(pc.bold(pc.cyan('\nšŸ” API Contract Analysis Results\n'))); // Summary statistics displaySummary(report); // Matched endpoints displayMatches(report); // Drift issues displayDrift(report); // Slice details if (report.slices.length > 0) { displaySlices(report.slices); } // Footer displayFooter(report); } /** * Display summary statistics */ function displaySummary(report) { console.log(pc.gray('Summary:')); console.log(pc.cyan(` šŸ“Š Backend Endpoints: ${report.totalEndpoints}`)); console.log(pc.cyan(` šŸ“Š Frontend API Calls: ${report.totalCalls}`)); console.log(pc.green(` āœ… Matched: ${report.matchedCount} (${calculatePercentage(report.matchedCount, report.totalEndpoints)}%)`)); if (report.unmatchedCalls.length > 0) { console.log(pc.yellow(` āš ļø Unmatched Calls: ${report.unmatchedCalls.length}`)); } if (report.unmatchedEndpoints.length > 0) { console.log(pc.yellow(` āš ļø Unmatched Endpoints: ${report.unmatchedEndpoints.length}`)); } console.log(''); } /** * Display matched endpoints */ function displayMatches(report) { if (report.matchedCount === 0) { console.log(pc.yellow('āŒ No matched endpoints found\n')); return; } console.log(pc.bold(`āœ… Matched Endpoints (${report.matchedCount}):`)); // Show first 10 matches const matchCount = Math.min(10, report.matchedCount); // Reconstruct matches from slices for display let displayedCount = 0; for (const slice of report.slices) { for (const match of slice.matches) { if (displayedCount < matchCount) { const method = match.endpoint.method.padEnd(6); const path = match.endpoint.path; const calls = match.calls.length; console.log(` ${pc.cyan(method)} ${path} ${pc.gray(`(${calls} call${calls !== 1 ? 's' : ''})`)}`); displayedCount++; } } } if (report.matchedCount > matchCount) { console.log(pc.gray(` ... and ${report.matchedCount - matchCount} more`)); } console.log(''); } /** * Display drift issues */ function displayDrift(report) { if (report.driftIssues.length === 0) { console.log(pc.green('āœ… No drift issues detected!\n')); return; } console.log(pc.bold(pc.red(`āŒ Schema Drift Detected (${report.driftIssues.length}):`))); // Group by severity const bySeverity = groupDriftBySeverity(report.driftIssues); // Display critical issues if (bySeverity.critical.length > 0) { console.log(pc.red(`\n šŸ”“ Critical (${bySeverity.critical.length}):`)); for (const issue of bySeverity.critical.slice(0, 3)) { console.log(` ${issue.message}`); if (issue.suggestion) { console.log(pc.gray(` šŸ’” ${issue.suggestion}`)); } } if (bySeverity.critical.length > 3) { console.log(pc.gray(` ... and ${bySeverity.critical.length - 3} more`)); } } // Display high severity issues if (bySeverity.high.length > 0) { console.log(pc.yellow(`\n 🟠 High (${bySeverity.high.length}):`)); for (const issue of bySeverity.high.slice(0, 3)) { console.log(` ${issue.message}`); if (issue.suggestion) { console.log(pc.gray(` šŸ’” ${issue.suggestion}`)); } } if (bySeverity.high.length > 3) { console.log(pc.gray(` ... and ${bySeverity.high.length - 3} more`)); } } // Display medium severity issues if (bySeverity.medium.length > 0) { console.log(pc.blue(`\n 🟔 Medium (${bySeverity.medium.length}):`)); for (const issue of bySeverity.medium.slice(0, 2)) { console.log(` ${issue.message}`); if (issue.suggestion) { console.log(pc.gray(` šŸ’” ${issue.suggestion}`)); } } if (bySeverity.medium.length > 2) { console.log(pc.gray(` ... and ${bySeverity.medium.length - 2} more`)); } } console.log(''); } /** * Display slice details */ function displaySlices(slices) { console.log(pc.bold(`šŸ“¦ Contracts Per Slice (${slices.length}):`)); for (const slice of slices) { const endpointCount = slice.endpoints.length; const matchCount = slice.matches.length; const driftCount = slice.drift.length; let icon = 'āœ…'; if (driftCount > 0) { icon = pc.red('āŒ'); } else if (matchCount === 0) { icon = pc.yellow('āš ļø '); } console.log(` ${icon} ${slice.name.padEnd(15)} ${endpointCount} endpoints, ${matchCount} matched, ${driftCount} drift issues`); } console.log(''); } /** * Display footer with next steps */ function displayFooter(report) { console.log(pc.bold('šŸ“‹ Next Steps:')); if (report.driftIssues.length > 0) { console.log(pc.yellow(' 1. Fix schema drift issues')); console.log(pc.gray(` - ${report.driftIssues.length} issue${report.driftIssues.length !== 1 ? 's' : ''} to resolve`)); } console.log(pc.cyan(' 2. Review generated OpenAPI specs')); console.log(pc.gray(` - ${report.specs.length} spec${report.specs.length !== 1 ? 's' : ''} generated`)); console.log(pc.cyan(' 3. Set up contract testing')); console.log(pc.gray(' - Use Dredd or Prism for validation')); console.log(pc.cyan(' 4. Generate documentation')); console.log(pc.gray(' - Use Swagger UI with generated specs')); console.log(pc.gray(`\nā±ļø Analysis completed in ${report.duration}ms\n`)); } /** * Group drift issues by severity */ function groupDriftBySeverity(issues) { return { critical: issues.filter(i => i.severity === 'critical'), high: issues.filter(i => i.severity === 'high'), medium: issues.filter(i => i.severity === 'medium'), low: issues.filter(i => i.severity === 'low'), }; } /** * Calculate percentage */ function calculatePercentage(current, total) { if (total === 0) return 0; return Math.round((current / total) * 100); } /** * Export results as JSON */ export function reportToJson(report) { return JSON.stringify(report, null, 2); } /** * Export results as CSV */ export function reportToCsv(report) { const lines = []; // Header lines.push('Slice,Endpoints,Calls,Matched,Drift'); // Slice data for (const slice of report.slices) { lines.push(`${slice.name},${slice.endpoints.length},${slice.calls.length},${slice.matches.length},${slice.drift.length}`); } // Total lines.push(`TOTAL,${report.totalEndpoints},${report.totalCalls},${report.matchedCount},${report.driftIssues.length}`); return lines.join('\n'); } /** * Create summary statistics */ export function getSummaryStats(report) { return { title: 'API Contract Generation Summary', timestamp: report.generatedAt, duration: `${report.duration}ms`, stats: { totalEndpoints: report.totalEndpoints, totalCalls: report.totalCalls, matchedPercentage: `${calculatePercentage(report.matchedCount, report.totalEndpoints)}%`, driftIssuesCount: report.driftIssues.length, sliceCount: report.slices.length, specCount: report.specs.length, }, }; } //# sourceMappingURL=reporter.js.map