@graphql-tools/merge
Version:
A set of utils for faster development of GraphQL tools
88 lines (87 loc) • 3.59 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeDirective = exports.mergeDirectives = void 0;
const utils_1 = require("@graphql-tools/utils");
function directiveAlreadyExists(directivesArr, otherDirective) {
return !!directivesArr.find(directive => directive.name.value === otherDirective.name.value);
}
function isRepeatableDirective(directive, directives) {
return !!directives?.[directive.name.value]?.repeatable;
}
function nameAlreadyExists(name, namesArr) {
return namesArr.some(({ value }) => value === name.value);
}
function mergeArguments(a1, a2) {
const result = [...a2];
for (const argument of a1) {
const existingIndex = result.findIndex(a => a.name.value === argument.name.value);
if (existingIndex > -1) {
const existingArg = result[existingIndex];
if (existingArg.value.kind === 'ListValue') {
const source = existingArg.value.values;
const target = argument.value.values;
// merge values of two lists
existingArg.value.values = deduplicateLists(source, target, (targetVal, source) => {
const value = targetVal.value;
return !value || !source.some((sourceVal) => sourceVal.value === value);
});
}
else {
existingArg.value = argument.value;
}
}
else {
result.push(argument);
}
}
return result;
}
function deduplicateDirectives(directives, definitions) {
return directives
.map((directive, i, all) => {
const firstAt = all.findIndex(d => d.name.value === directive.name.value);
if (firstAt !== i && !isRepeatableDirective(directive, definitions)) {
const dup = all[firstAt];
directive.arguments = mergeArguments(directive.arguments, dup.arguments);
return null;
}
return directive;
})
.filter(utils_1.isSome);
}
function mergeDirectives(d1 = [], d2 = [], config, directives) {
const reverseOrder = config && config.reverseDirectives;
const asNext = reverseOrder ? d1 : d2;
const asFirst = reverseOrder ? d2 : d1;
const result = deduplicateDirectives([...asNext], directives);
for (const directive of asFirst) {
if (directiveAlreadyExists(result, directive) &&
!isRepeatableDirective(directive, directives)) {
const existingDirectiveIndex = result.findIndex(d => d.name.value === directive.name.value);
const existingDirective = result[existingDirectiveIndex];
result[existingDirectiveIndex].arguments = mergeArguments(directive.arguments || [], existingDirective.arguments || []);
}
else {
result.push(directive);
}
}
return result;
}
exports.mergeDirectives = mergeDirectives;
function mergeDirective(node, existingNode) {
if (existingNode) {
return {
...node,
arguments: deduplicateLists(existingNode.arguments || [], node.arguments || [], (arg, existingArgs) => !nameAlreadyExists(arg.name, existingArgs.map(a => a.name))),
locations: [
...existingNode.locations,
...node.locations.filter(name => !nameAlreadyExists(name, existingNode.locations)),
],
};
}
return node;
}
exports.mergeDirective = mergeDirective;
function deduplicateLists(source, target, filterFn) {
return source.concat(target.filter(val => filterFn(val, source)));
}
;