Skip to main content
Glama
quality-metrics.mapper.ts6.26 kB
/** * @fileoverview QualityMetrics mapper * * Maps between DeepSource API models and domain QualityMetrics aggregates. */ import { QualityMetrics } from '../../domain/aggregates/quality-metrics/quality-metrics.aggregate.js'; import { RepositoryMetric, RepositoryMetricItem, MetricKey } from '../../models/metrics.js'; import { MetricConfiguration, CreateQualityMetricsParams, MetricHistoryEntry, ThresholdStatus, } from '../../domain/aggregates/quality-metrics/quality-metrics.types.js'; import { asProjectKey, asGraphQLNodeId } from '../../types/branded.js'; import { ThresholdValue } from '../../domain/value-objects/threshold-value.js'; import { MetricValue } from '../../domain/value-objects/metric-value.js'; /** * Maps a single metric item to a domain QualityMetrics aggregate * * @param apiMetric - The API metric model * @param item - The specific metric item * @param projectKey - The project key * @param repositoryId - The repository GraphQL ID * @returns The domain QualityMetrics aggregate */ export function mapQualityMetricToDomain( apiMetric: RepositoryMetric, item: RepositoryMetricItem, projectKey: string, repositoryId: string ): QualityMetrics { const configuration: MetricConfiguration = { name: apiMetric.name, description: apiMetric.description, shortcode: apiMetric.shortcode, metricKey: item.key as MetricKey, // Cast to MetricKey unit: apiMetric.unit, minAllowed: apiMetric.minValueAllowed, maxAllowed: apiMetric.maxValueAllowed, positiveDirection: apiMetric.positiveDirection, isReported: apiMetric.isReported, isThresholdEnforced: apiMetric.isThresholdEnforced, threshold: item.threshold !== null ? ThresholdValue.create( item.threshold, apiMetric.unit, apiMetric.minValueAllowed, apiMetric.maxValueAllowed ) : null, }; const params: CreateQualityMetricsParams = { projectKey: asProjectKey(projectKey), repositoryId: asGraphQLNodeId(repositoryId), configuration, }; if (item.latestValue !== null) { params.currentValue = MetricValue.create( item.latestValue, apiMetric.unit, item.latestValueDisplay, new Date() // API doesn't provide measurement time ); } return QualityMetrics.create(params); } /** * Maps a DeepSource API metric to domain QualityMetrics aggregates * * Since one API metric can have multiple items (e.g., per language), * this returns an array of QualityMetrics aggregates. * * @param apiMetric - The API metric model * @param projectKey - The project key * @param repositoryId - The repository GraphQL ID * @returns Array of domain QualityMetrics aggregates */ export function mapQualityMetricsToDomainList( apiMetric: RepositoryMetric, projectKey: string, repositoryId: string ): QualityMetrics[] { return apiMetric.items.map((item) => mapQualityMetricToDomain(apiMetric, item, projectKey, repositoryId) ); } /** * Maps API threshold status to domain threshold status * * @param apiStatus - The API threshold status * @returns The domain threshold status */ export function mapThresholdStatus(apiStatus: string): ThresholdStatus { const statusMap: Record<string, ThresholdStatus> = { PASSING: 'PASSING', FAILING: 'FAILING', UNKNOWN: 'UNKNOWN', }; return statusMap[apiStatus] || 'UNKNOWN'; } /** * Maps a domain QualityMetrics aggregate to persistence format * * @param metrics - The domain QualityMetrics aggregate * @returns The persistence model */ export function mapQualityMetricsToPersistence(metrics: QualityMetrics): { id: string; projectKey: string; repositoryId: string; configuration: MetricConfiguration; currentValue: MetricValue | null; history: MetricHistoryEntry[]; lastUpdated: Date; } { const persistence = metrics.toPersistence(); return { ...persistence, projectKey: persistence.projectKey as string, repositoryId: persistence.repositoryId as string, }; } /** * Creates a metric history entry from API data * * @param value - The metric value * @param threshold - The threshold at the time (optional) * @param commitOid - The commit SHA * @param recordedAt - When the metric was recorded * @param unit - The metric unit * @returns A metric history entry */ export function createMetricHistoryEntry( value: number, threshold: number | null, commitOid: string, recordedAt: Date, unit: string, minAllowed = 0, maxAllowed = 100 ): MetricHistoryEntry { const metricValue = MetricValue.create( value, unit, undefined, // Use default display value recordedAt ); const thresholdValue = threshold !== null ? ThresholdValue.create(threshold, unit, minAllowed, maxAllowed) : null; // Determine threshold status based on value and threshold let thresholdStatus: ThresholdStatus = 'UNKNOWN'; if (thresholdValue && metricValue && threshold !== null) { // This is simplified - actual logic would need to consider metric direction thresholdStatus = value >= threshold ? 'PASSING' : 'FAILING'; } return { value: metricValue, threshold: thresholdValue, thresholdStatus, commitOid, recordedAt, }; } /** * Maps multiple API metrics to domain aggregates * * @param apiMetrics - Array of API metric models * @param projectKey - The project key * @param repositoryId - The repository GraphQL ID * @returns Array of domain QualityMetrics aggregates */ export function mapQualityMetricsFromList( apiMetrics: RepositoryMetric[], projectKey: string, repositoryId: string ): QualityMetrics[] { const allMetrics: QualityMetrics[] = []; for (const apiMetric of apiMetrics) { const domainMetrics = mapQualityMetricsToDomainList(apiMetric, projectKey, repositoryId); allMetrics.push(...domainMetrics); } return allMetrics; } // For backward compatibility, export a namespace with the old static methods export const QualityMetricsMapper = { toDomain: mapQualityMetricToDomain, toDomainList: mapQualityMetricsToDomainList, mapThresholdStatus, toPersistence: mapQualityMetricsToPersistence, createHistoryEntry: createMetricHistoryEntry, toDomainFromList: mapQualityMetricsFromList, };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sapientpants/deepsource-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server