deepsource-mcp-server
Version:
Model Context Protocol server for DeepSource
134 lines • 5 kB
JavaScript
/**
* @fileoverview AnalysisRun mapper
*
* Maps between DeepSource API models and domain AnalysisRun aggregates.
*/
import { AnalysisRun } from '../../domain/aggregates/analysis-run/analysis-run.aggregate.js';
import { asRunId, asProjectKey, asCommitOid, asBranchName, asAnalyzerShortcode, asGraphQLNodeId, } from '../../types/branded.js';
import { IssueCount } from '../../domain/value-objects/issue-count.js';
/**
* Maps API status to domain status
*
* @param apiStatus - The API status
* @returns The domain status
*/
function mapApiStatusToDomain(apiStatus) {
// API uses different status names than domain
const statusMap = {
PENDING: 'PENDING',
READY: 'RUNNING',
SUCCESS: 'SUCCESS',
FAILURE: 'FAILURE',
TIMEOUT: 'TIMEOUT',
CANCEL: 'CANCELLED',
CANCELLED: 'CANCELLED',
SKIPPED: 'SKIPPED',
};
return statusMap[apiStatus] || 'FAILURE';
}
/**
* Maps API category to domain category
*
* @param apiCategory - The API category
* @returns The domain category
*/
function mapApiCategoryToDomain(apiCategory) {
// Map API categories to domain categories
const categoryMap = {
'anti-pattern': 'ANTI_PATTERN',
'bug-risk': 'BUG_RISK',
bug_risk: 'BUG_RISK', // Support both hyphen and underscore
coverage: 'COVERAGE',
documentation: 'DOCUMENTATION',
performance: 'PERFORMANCE',
security: 'SECURITY',
style: 'STYLE',
typecheck: 'TYPE_CHECK',
'type-check': 'TYPE_CHECK', // Support both forms
};
return categoryMap[apiCategory.toLowerCase()] || 'OTHER';
}
/**
* Maps a DeepSource API run to a domain AnalysisRun aggregate
*
* @param apiRun - The API run model
* @param projectKey - The project key (not available in API response)
* @returns The domain AnalysisRun aggregate
*/
export function mapAnalysisRunToDomain(apiRun, projectKey) {
const commitInfo = {
oid: asCommitOid(apiRun.commitOid),
branch: asBranchName(apiRun.branchName),
baseOid: asCommitOid(apiRun.baseOid),
};
// Map API status to domain status
const status = mapApiStatusToDomain(apiRun.status);
// Map issue distributions
const analyzerDistributions = apiRun.summary.occurrenceDistributionByAnalyzer?.map((dist) => ({
analyzerShortcode: asAnalyzerShortcode(dist.analyzerShortcode),
introduced: IssueCount.create(dist.introduced),
resolved: IssueCount.create(0), // API doesn't provide resolved by analyzer
suppressed: IssueCount.create(0), // API doesn't provide suppressed by analyzer
})) || [];
const categoryDistributions = apiRun.summary.occurrenceDistributionByCategory?.map((dist) => ({
category: mapApiCategoryToDomain(dist.category),
introduced: IssueCount.create(dist.introduced),
resolved: IssueCount.create(0), // API doesn't provide resolved by category
suppressed: IssueCount.create(0), // API doesn't provide suppressed by category
})) || [];
const summary = {
totalIntroduced: IssueCount.create(apiRun.summary.occurrencesIntroduced),
totalResolved: IssueCount.create(apiRun.summary.occurrencesResolved),
totalSuppressed: IssueCount.create(apiRun.summary.occurrencesSuppressed),
byAnalyzer: analyzerDistributions,
byCategory: categoryDistributions,
};
const run = AnalysisRun.fromPersistence({
runId: asRunId(apiRun.runUid),
projectKey: asProjectKey(projectKey),
repositoryId: asGraphQLNodeId(apiRun.repository.id),
commitInfo,
status,
timestamps: (() => {
const ts = {
createdAt: new Date(apiRun.createdAt),
};
if (status !== 'PENDING') {
ts.startedAt = new Date(apiRun.updatedAt);
}
if (apiRun.finishedAt) {
ts.finishedAt = new Date(apiRun.finishedAt);
}
return ts;
})(),
summary,
issues: [], // Issues are fetched separately if needed
});
return run;
}
/**
* Maps a domain AnalysisRun aggregate to persistence format
*
* @param run - The domain AnalysisRun aggregate
* @returns The persistence model
*/
export function mapAnalysisRunToPersistence(run) {
return run.toPersistence();
}
/**
* Maps multiple API runs to domain aggregates
*
* @param apiRuns - Array of API run models
* @param projectKey - The project key for all runs
* @returns Array of domain AnalysisRun aggregates
*/
export function mapAnalysisRunsToDomainList(apiRuns, projectKey) {
return apiRuns.map((run) => mapAnalysisRunToDomain(run, projectKey));
}
// For backward compatibility, export a namespace with the old static methods
export const AnalysisRunMapper = {
toDomain: mapAnalysisRunToDomain,
toPersistence: mapAnalysisRunToPersistence,
toDomainList: mapAnalysisRunsToDomainList,
};
//# sourceMappingURL=analysis-run.mapper.js.map