@graphql-inspector/action
Version:
GraphQL Inspector functionality for GitHub Actions
66 lines (65 loc) • 2.37 kB
JavaScript
import { CriticalityLevel, diff as diffSchemas } from '@graphql-inspector/core';
import { fetch } from '@whatwg-node/fetch';
import { getLocationByPath } from './location.js';
import { AnnotationLevel, CheckConclusion, } from './types.js';
import { isNil, parseEndpoint } from './utils.js';
export async function diff({ path, schemas, sources, interceptor, pullRequests, ref, rules, config, }) {
let changes = await diffSchemas(schemas.old, schemas.new, rules, config);
let forcedConclusion = null;
if (!changes?.length) {
return {
conclusion: CheckConclusion.Success,
};
}
if (!isNil(interceptor)) {
const interceptionResult = await interceptChanges(interceptor, {
pullRequests,
ref,
changes,
});
changes = interceptionResult.changes || [];
forcedConclusion = interceptionResult.conclusion || null;
}
const annotations = await Promise.all(changes.map(change => annotate({ path, change, source: sources.new })));
let conclusion = CheckConclusion.Success;
if (changes.some(change => change.criticality.level === CriticalityLevel.Breaking)) {
conclusion = CheckConclusion.Failure;
}
if (forcedConclusion) {
conclusion = forcedConclusion;
}
return {
conclusion,
annotations,
changes,
};
}
const levelMap = {
[CriticalityLevel.Breaking]: AnnotationLevel.Failure,
[CriticalityLevel.Dangerous]: AnnotationLevel.Warning,
[CriticalityLevel.NonBreaking]: AnnotationLevel.Notice,
};
function annotate({ path, change, source, }) {
const level = change.criticality.level;
const loc = change.path
? getLocationByPath({ path: change.path, source })
: { line: 1, column: 1 };
return {
title: change.message,
annotation_level: levelMap[level],
path,
message: change.criticality.reason || change.message,
start_line: loc.line,
end_line: loc.line,
};
}
async function interceptChanges(interceptor, payload) {
const endpoint = parseEndpoint(interceptor);
const response = await fetch(endpoint.url, {
method: endpoint.method,
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
return data;
}