UNPKG

deepsource-mcp-server

Version:
149 lines 5.74 kB
/** * @fileoverview ComplianceReport mapper * * Maps between DeepSource API models and domain ComplianceReport aggregates. */ import { ComplianceReport } from '../../domain/aggregates/compliance-report/compliance-report.aggregate.js'; import { asProjectKey, asGraphQLNodeId } from '../../types/branded.js'; import { IssueCount } from '../../domain/value-objects/issue-count.js'; /** * Maps the highest severity from occurrence distribution * * @param occurrence - The severity distribution * @returns The highest severity present */ function mapHighestSeverity(occurrence) { if (occurrence.critical > 0) return 'CRITICAL'; if (occurrence.major > 0) return 'MAJOR'; if (occurrence.minor > 0) return 'MINOR'; return 'INFO'; } /** * Maps the API report status to domain status * * @param apiStatus - The API status * @returns The domain report status */ function mapReportStatus(apiStatus) { const statusMap = { READY: 'READY', COMPLETED: 'READY', GENERATING: 'GENERATING', PENDING: 'GENERATING', ERROR: 'ERROR', FAILED: 'ERROR', PASSING: 'PASSING', FAILING: 'FAILING', NOOP: 'NOT_APPLICABLE', }; return statusMap[apiStatus || ''] || 'PENDING'; } /** * Maps a DeepSource API compliance report to domain ComplianceReport aggregate * * @param apiReport - The API compliance report model * @param projectKey - The project key * @param repositoryId - The repository GraphQL ID * @returns The domain ComplianceReport aggregate */ export function mapComplianceReportToDomain(apiReport, projectKey, repositoryId) { const categories = apiReport.securityIssueStats.map((stat) => { // API provides total directly, but we can also calculate it for verification const totalIssues = stat.occurrence.total || stat.occurrence.critical + stat.occurrence.major + stat.occurrence.minor; // Simple approach: treat all detected issues as non-compliant // In a real implementation, this would depend on business rules about what constitutes compliance return { name: stat.title, description: `Security category: ${stat.key}`, compliant: IssueCount.create(0), // API doesn't provide compliant count directly nonCompliant: IssueCount.create(totalIssues), issueCount: IssueCount.create(totalIssues), severity: mapHighestSeverity(stat.occurrence), }; }); const params = { projectKey: asProjectKey(projectKey), repositoryId: asGraphQLNodeId(repositoryId), reportType: apiReport.key, status: mapReportStatus(apiReport.status), categories, }; return ComplianceReport.create(params); } /** * Maps a domain ComplianceReport aggregate to persistence format * * @param report - The domain ComplianceReport aggregate * @returns The persistence model */ export function mapComplianceReportToPersistence(report) { const persistence = report.toPersistence(); return { ...persistence, projectKey: persistence.projectKey, repositoryId: persistence.repositoryId, }; } /** * Creates a category from API security issue stat * * @param stat - The API security issue statistic * @param reportType - The report type for context * @returns A compliance category */ export function createCategoryFromStat(stat, reportType) { // API provides total directly, but we can also calculate it for verification const totalIssues = stat.occurrence.total || stat.occurrence.critical + stat.occurrence.major + stat.occurrence.minor; return { name: stat.title, description: `${reportType} category: ${stat.key}`, compliant: IssueCount.create(0), // We don't have compliant count from API nonCompliant: IssueCount.create(totalIssues), issueCount: IssueCount.create(totalIssues), severity: mapHighestSeverity(stat.occurrence), }; } /** * Estimates compliance score based on issue counts * This is a simplified calculation since the API doesn't provide the exact score * * @param categories - The compliance categories * @returns Estimated compliance score (0-100) */ export function estimateComplianceScore(categories) { if (categories.length === 0) return 100; const totalIssues = categories.reduce((sum, cat) => sum + cat.issueCount.count, 0); const criticalIssues = categories.filter((cat) => cat.severity === 'CRITICAL').length; const majorIssues = categories.filter((cat) => cat.severity === 'MAJOR').length; // Simple scoring: penalize critical and major issues more heavily const penalty = criticalIssues * 20 + majorIssues * 10 + totalIssues * 2; return Math.max(0, Math.min(100, 100 - penalty)); } /** * Maps multiple API compliance reports to domain aggregates * * @param apiReports - Array of API compliance reports * @param projectKey - The project key * @param repositoryId - The repository GraphQL ID * @returns Array of domain ComplianceReport aggregates */ export function mapComplianceReportsFromList(apiReports, projectKey, repositoryId) { return apiReports.map((report) => mapComplianceReportToDomain(report, projectKey, repositoryId)); } // For backward compatibility, export a namespace with the old static methods export const ComplianceReportMapper = { toDomain: mapComplianceReportToDomain, mapStatus: mapReportStatus, mapHighestSeverity, toPersistence: mapComplianceReportToPersistence, toDomainFromList: mapComplianceReportsFromList, createCategoryFromStat, estimateComplianceScore, }; //# sourceMappingURL=compliance-report.mapper.js.map