@apollo/query-planner
Version:
Apollo Query Planner
169 lines • 6.85 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluateCondition = exports.removeConditionsFromSelectionSet = exports.updatedConditions = exports.conditionsOfSelectionSet = exports.mergeConditions = exports.isConstantCondition = void 0;
const federation_internals_1 = require("@apollo/federation-internals");
const query_graphs_1 = require("@apollo/query-graphs");
function isConstantCondition(cond) {
return typeof cond === 'boolean';
}
exports.isConstantCondition = isConstantCondition;
function mergeConditions(conditions1, conditions2) {
if (isConstantCondition(conditions1)) {
return conditions1 ? conditions2 : false;
}
if (isConstantCondition(conditions2)) {
return conditions2 ? conditions1 : false;
}
const merged = [...conditions1];
for (const cond2 of conditions2) {
const cond1 = conditions1.find((c1) => c1.variable.name === cond2.variable.name);
if (cond1) {
if (cond1.negated !== cond2.negated) {
return false;
}
}
else {
merged.push(cond2);
}
}
return merged;
}
exports.mergeConditions = mergeConditions;
function sameConditions(conditions1, conditions2) {
if (isConstantCondition(conditions1)) {
return isConstantCondition(conditions2) && conditions1 === conditions2;
}
if (isConstantCondition(conditions2)) {
return false;
}
return conditions1.length === conditions2.length
&& conditions1.every((cond1) => conditions2.some((cond2) => cond1.variable.name === cond2.variable.name && cond1.negated === cond2.negated));
}
function conditionsOfSelectionSet(selectionSet) {
const selections = selectionSet.selections();
if (selections.length === 0) {
return false;
}
const conditions = conditionsOfSelection(selections[0]);
for (let i = 1; i < selections.length; i++) {
const otherConditions = conditionsOfSelection(selections[i]);
if (!sameConditions(conditions, otherConditions)) {
return true;
}
}
return conditions;
}
exports.conditionsOfSelectionSet = conditionsOfSelectionSet;
function conditionsOfSelection(selection) {
const elementConditions = conditionsOfElement(selection.element);
if (!selection.selectionSet) {
return elementConditions;
}
if (isConstantCondition(elementConditions)) {
if (!elementConditions || selection.kind === 'FieldSelection') {
return elementConditions;
}
}
const selectionConditions = conditionsOfSelectionSet(selection.selectionSet);
return mergeConditions(elementConditions, selectionConditions);
}
function conditionsOfElement(element) {
const conditionals = (0, query_graphs_1.extractOperationConditionals)(element);
if (conditionals.length === 0) {
return true;
}
const conditions = [];
for (const conditional of conditionals) {
const value = conditional.value;
if (typeof value === 'boolean') {
if (value === (conditional.kind === 'skip')) {
return false;
}
}
else {
conditions.push({
variable: value,
negated: conditional.kind === 'skip',
});
}
}
if ((0, federation_internals_1.isNonEmptyArray)(conditions)) {
if (conditions.length === 2 && conditions[0].variable.name === conditions[1].variable.name) {
return false;
}
return conditions;
}
return true;
}
function updatedConditions(newConditions, handledConditions) {
if (isConstantCondition(newConditions) || isConstantCondition(handledConditions)) {
return newConditions;
}
const filtered = [];
for (const cond of newConditions) {
const handledCond = handledConditions.find((r) => cond.variable.name === r.variable.name);
if (handledCond) {
if (cond.negated !== handledCond.negated) {
return false;
}
}
else {
filtered.push(cond);
}
}
return (0, federation_internals_1.isNonEmptyArray)(filtered) ? filtered : true;
}
exports.updatedConditions = updatedConditions;
function removeConditionsFromSelectionSet(selectionSet, conditions) {
if (isConstantCondition(conditions)) {
return selectionSet;
}
return selectionSet.lazyMap((selection) => {
const updatedElement = removeConditionsOfElement(selection.element, conditions);
if (selection.selectionSet) {
const updatedSelectionSet = removeConditionsFromSelectionSet(selection.selectionSet, conditions);
if (updatedElement === selection.element) {
if (updatedSelectionSet === selection.selectionSet) {
return selection;
}
else {
return selection.withUpdatedSelectionSet(updatedSelectionSet);
}
}
else {
return (0, federation_internals_1.selectionOfElement)(updatedElement, updatedSelectionSet);
}
}
else {
return updatedElement === selection.element ? selection : (0, federation_internals_1.selectionOfElement)(updatedElement);
}
});
}
exports.removeConditionsFromSelectionSet = removeConditionsFromSelectionSet;
function removeConditionsOfElement(element, conditions) {
const updatedDirectives = element.appliedDirectives.filter((d) => !matchesConditionForKind(d, conditions, 'include') && !matchesConditionForKind(d, conditions, 'skip'));
if (updatedDirectives.length === element.appliedDirectives.length) {
return element;
}
return element.withUpdatedDirectives(updatedDirectives);
}
function matchesConditionForKind(directive, conditions, kind) {
if (directive.name !== kind) {
return false;
}
const value = directive.arguments()['if'];
return !(0, federation_internals_1.isVariable)(value) || conditions.some((cond) => cond.variable.name === value.name && cond.negated === (kind === 'skip'));
}
function evaluateCondition(condition, variables, values) {
var _a;
const variable = condition.condition;
let val = values ? values[variable] : undefined;
if (val === undefined) {
val = (_a = variables.definition(variable)) === null || _a === void 0 ? void 0 : _a.defaultValue;
}
(0, federation_internals_1.assert)(val !== undefined, () => `Missing value for variable \$${variable} (and no default found)`);
(0, federation_internals_1.assert)(typeof val === 'boolean', () => `Invalid non-boolean value ${val} for Boolean! variable \$${variable}`);
return val;
}
exports.evaluateCondition = evaluateCondition;
//# sourceMappingURL=conditions.js.map
;