@apollo/federation-internals
Version:
Apollo Federation internal utilities
191 lines • 6.71 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ARGUMENT_COMPOSITION_STRATEGIES = exports.convertEmptyToTrue = exports.dnfConjunction = void 0;
const definitions_1 = require("./definitions");
const types_1 = require("./types");
const values_1 = require("./values");
function supportFixedTypes(types) {
return (schema, type) => {
const supported = types(schema);
return supported.some((t) => (0, types_1.sameType)(t, type))
? { valid: true }
: { valid: false, supportedMsg: `type(s) ${supported.join(', ')}` };
};
}
function supportAnyNonNullNestedArray() {
return (_, type) => (0, definitions_1.isNonNullType)(type) && (0, definitions_1.isListType)(type.ofType)
&& (0, definitions_1.isNonNullType)(type.ofType.ofType) && (0, definitions_1.isListType)(type.ofType.ofType.ofType)
? { valid: true }
: { valid: false, supportedMsg: 'non nullable nested list types of any type' };
}
function supportAnyNonNullArray() {
return (_, type) => (0, definitions_1.isNonNullType)(type) && (0, definitions_1.isListType)(type.ofType)
? { valid: true }
: { valid: false, supportedMsg: 'non nullable list types of any type' };
}
function supportAnyArray() {
return (_, type) => (0, definitions_1.isListType)(type) || ((0, definitions_1.isNonNullType)(type) && (0, definitions_1.isListType)(type.ofType))
? { valid: true }
: { valid: false, supportedMsg: 'list types of any type' };
}
function mergeNullableValues(mergeValues) {
return (values) => {
const nonNullValues = values.filter((v) => v !== null && v !== undefined);
return nonNullValues.length > 0
? mergeValues(nonNullValues)
: undefined;
};
}
function unionValues(values) {
return values.reduce((acc, next) => {
const newValues = next.filter((v1) => !acc.some((v2) => (0, values_1.valueEquals)(v1, v2)));
return acc.concat(newValues);
}, []);
}
function dnfConjunction(values) {
if (values.length == 0) {
return [];
}
for (let i = 0; i < values.length; i++) {
values[i] = convertEmptyToTrue(dnfCopy(values[i]));
}
const filtered = filterNestedArrayDuplicates(values);
let result = filtered[0];
for (let i = 1; i < filtered.length; i++) {
const current = filtered[i];
const accumulator = [];
const seen = new Set;
for (const accElement of result) {
for (const currentElement of current) {
const filteredElement = currentElement.filter((e) => !accElement.includes(e));
const candidate = [...accElement, ...filteredElement].sort();
const key = JSON.stringify(candidate);
if (!seen.has(key)) {
seen.add(key);
accumulator.push(candidate);
}
}
}
result = deduplicateSubsumedValues(accumulator);
}
return result;
}
exports.dnfConjunction = dnfConjunction;
function filterNestedArrayDuplicates(values) {
const filtered = [];
const seen = new Set;
values.forEach((value) => {
value.forEach((inner) => {
inner.sort();
});
value.sort((a, b) => {
const left = JSON.stringify(a);
const right = JSON.stringify(b);
return left > right ? 1 : left < right ? -1 : 0;
});
const key = JSON.stringify(value);
if (!seen.has(key)) {
seen.add(key);
filtered.push(value);
}
});
return filtered;
}
function deduplicateSubsumedValues(values) {
const result = [];
values.sort((first, second) => {
if (first.length < second.length) {
return -1;
}
else if (first.length > second.length) {
return 1;
}
else {
return 0;
}
});
for (const candidate of values) {
const entry = new Set(candidate);
let redundant = false;
for (const r of result) {
if (r.every(e => entry.has(e))) {
redundant = true;
break;
}
}
if (!redundant) {
result.push(candidate);
}
}
return result;
}
function dnfCopy(value) {
const newValue = new Array(value.length);
for (let i = 0; i < value.length; i++) {
newValue[i] = value[i].slice();
}
return newValue;
}
function convertEmptyToTrue(value) {
return value.length === 0 ? [[]] : value;
}
exports.convertEmptyToTrue = convertEmptyToTrue;
exports.ARGUMENT_COMPOSITION_STRATEGIES = {
MAX: {
name: 'MAX',
isTypeSupported: supportFixedTypes((schema) => [new definitions_1.NonNullType(schema.intType())]),
mergeValues: (values) => Math.max(...values),
},
MIN: {
name: 'MIN',
isTypeSupported: supportFixedTypes((schema) => [new definitions_1.NonNullType(schema.intType())]),
mergeValues: (values) => Math.min(...values),
},
INTERSECTION: {
name: 'INTERSECTION',
isTypeSupported: supportAnyNonNullArray(),
mergeValues: (values) => {
var _a;
return (_a = values.reduce((acc, next) => {
if (acc === undefined) {
return next;
}
else {
return acc.filter((v1) => next.some((v2) => (0, values_1.valueEquals)(v1, v2)));
}
}, undefined)) !== null && _a !== void 0 ? _a : [];
},
},
UNION: {
name: 'UNION',
isTypeSupported: supportAnyNonNullArray(),
mergeValues: unionValues,
},
NULLABLE_AND: {
name: 'NULLABLE_AND',
isTypeSupported: supportFixedTypes((schema) => [
schema.booleanType(),
new definitions_1.NonNullType(schema.booleanType())
]),
mergeValues: mergeNullableValues((values) => values.every((v) => v)),
},
NULLABLE_MAX: {
name: 'NULLABLE_MAX',
isTypeSupported: supportFixedTypes((schema) => [
schema.intType(),
new definitions_1.NonNullType(schema.intType())
]),
mergeValues: mergeNullableValues((values) => Math.max(...values))
},
NULLABLE_UNION: {
name: 'NULLABLE_UNION',
isTypeSupported: supportAnyArray(),
mergeValues: mergeNullableValues(unionValues),
},
DNF_CONJUNCTION: {
name: 'DNF_CONJUNCTION',
isTypeSupported: supportAnyNonNullNestedArray(),
mergeValues: dnfConjunction
}
};
//# sourceMappingURL=argumentCompositionStrategies.js.map