@apollo/federation-internals 2.4.6 → 2.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/operations.d.ts +39 -112
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +349 -304
- package/dist/operations.js.map +1 -1
- package/package.json +1 -1
- package/src/operations.ts +635 -516
package/dist/operations.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.operationToDocument = exports.parseSelectionSet = exports.parseOperation = exports.operationFromDocument = exports.FragmentSelection = exports.FieldSelection = exports.selectionOfElement = exports.selectionSetOfElement = exports.selectionSetOf = exports.allFieldDefinitionsInSelectionSet = exports.MutableSelectionSet = exports.SelectionSetUpdates = exports.SelectionSet = exports.NamedFragments = exports.NamedFragmentDefinition = exports.Operation = exports.concatOperationPaths = exports.conditionalDirectivesInOperationPath = exports.sameOperationPaths = exports.operationPathToStringPath = exports.FragmentElement = exports.Field = void 0;
|
|
3
|
+
exports.operationToDocument = exports.parseSelectionSet = exports.parseOperation = exports.operationFromDocument = exports.FragmentSelection = exports.FieldSelection = exports.selectionOfElement = exports.selectionSetOfElement = exports.selectionSetOf = exports.allFieldDefinitionsInSelectionSet = exports.MutableSelectionSet = exports.SelectionSetUpdates = exports.SelectionSet = exports.ContainsResult = exports.NamedFragments = exports.NamedFragmentDefinition = exports.Operation = exports.concatOperationPaths = exports.conditionalDirectivesInOperationPath = exports.sameOperationPaths = exports.operationPathToStringPath = exports.FragmentElement = exports.Field = void 0;
|
|
4
4
|
const graphql_1 = require("graphql");
|
|
5
5
|
const definitions_1 = require("./definitions");
|
|
6
6
|
const federation_1 = require("./federation");
|
|
@@ -442,16 +442,92 @@ function isUselessFollowupElement(first, followup, conditionals) {
|
|
|
442
442
|
&& (followup.appliedDirectives.length === 0 || (0, definitions_1.isDirectiveApplicationsSubset)(conditionals, followup.appliedDirectives))
|
|
443
443
|
&& (0, types_1.isSubtype)(followup.typeCondition, typeOfFirst);
|
|
444
444
|
}
|
|
445
|
+
function computeFragmentsDependents(fragments) {
|
|
446
|
+
const reverseDeps = new utils_1.SetMultiMap();
|
|
447
|
+
for (const fragment of fragments.definitions()) {
|
|
448
|
+
for (const dependency of fragment.fragmentUsages().keys()) {
|
|
449
|
+
reverseDeps.add(dependency, fragment.name);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return reverseDeps;
|
|
453
|
+
}
|
|
454
|
+
function clearKeptFragments(usages, fragments, minUsagesToOptimize) {
|
|
455
|
+
let toCheck = Array.from(usages.entries()).filter(([_, count]) => count >= minUsagesToOptimize).map(([name, _]) => name);
|
|
456
|
+
while (toCheck.length > 0) {
|
|
457
|
+
const newToCheck = [];
|
|
458
|
+
for (const name of toCheck) {
|
|
459
|
+
usages.delete(name);
|
|
460
|
+
const ownUsages = fragments.get(name).fragmentUsages();
|
|
461
|
+
for (const [otherName, otherCount] of ownUsages.entries()) {
|
|
462
|
+
const prevCount = usages.get(otherName);
|
|
463
|
+
if (prevCount !== undefined) {
|
|
464
|
+
const newCount = prevCount + otherCount;
|
|
465
|
+
usages.set(otherName, newCount);
|
|
466
|
+
if (prevCount < minUsagesToOptimize && newCount >= minUsagesToOptimize) {
|
|
467
|
+
newToCheck.push(otherName);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
toCheck = newToCheck;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function computeFragmentsToKeep(selectionSet, fragments, minUsagesToOptimize) {
|
|
476
|
+
const usages = new Map();
|
|
477
|
+
selectionSet.collectUsedFragmentNames(usages);
|
|
478
|
+
if (usages.size === 0) {
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
481
|
+
for (const fragment of fragments.definitions()) {
|
|
482
|
+
if (usages.get(fragment.name) === undefined) {
|
|
483
|
+
usages.set(fragment.name, 0);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
const reverseDependencies = computeFragmentsDependents(fragments);
|
|
487
|
+
const toExpand = new Set;
|
|
488
|
+
let shouldContinue = true;
|
|
489
|
+
while (shouldContinue) {
|
|
490
|
+
shouldContinue = false;
|
|
491
|
+
clearKeptFragments(usages, fragments, minUsagesToOptimize);
|
|
492
|
+
for (const name of (0, utils_1.mapKeys)(usages)) {
|
|
493
|
+
const count = usages.get(name);
|
|
494
|
+
if (count === 0) {
|
|
495
|
+
continue;
|
|
496
|
+
}
|
|
497
|
+
if (count >= minUsagesToOptimize) {
|
|
498
|
+
shouldContinue = true;
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
const fragmentsUsingName = reverseDependencies.get(name);
|
|
502
|
+
if (!fragmentsUsingName || [...fragmentsUsingName].every((fragName) => toExpand.has(fragName) || !usages.get(fragName))) {
|
|
503
|
+
toExpand.add(name);
|
|
504
|
+
usages.delete(name);
|
|
505
|
+
shouldContinue = true;
|
|
506
|
+
const nameUsages = fragments.get(name).fragmentUsages();
|
|
507
|
+
for (const [otherName, otherCount] of nameUsages.entries()) {
|
|
508
|
+
const prev = usages.get(otherName);
|
|
509
|
+
if (prev !== undefined) {
|
|
510
|
+
usages.set(otherName, prev + count * otherCount);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
for (const name of usages.keys()) {
|
|
517
|
+
toExpand.add(name);
|
|
518
|
+
}
|
|
519
|
+
return toExpand.size === 0 ? fragments : fragments.filter((f) => !toExpand.has(f.name));
|
|
520
|
+
}
|
|
445
521
|
class Operation {
|
|
446
|
-
constructor(schema, rootKind, selectionSet, variableDefinitions, name) {
|
|
522
|
+
constructor(schema, rootKind, selectionSet, variableDefinitions, fragments, name) {
|
|
447
523
|
this.schema = schema;
|
|
448
524
|
this.rootKind = rootKind;
|
|
449
525
|
this.selectionSet = selectionSet;
|
|
450
526
|
this.variableDefinitions = variableDefinitions;
|
|
527
|
+
this.fragments = fragments;
|
|
451
528
|
this.name = name;
|
|
452
529
|
}
|
|
453
530
|
optimize(fragments, minUsagesToOptimize = 2) {
|
|
454
|
-
var _a;
|
|
455
531
|
(0, utils_1.assert)(minUsagesToOptimize >= 1, `Expected 'minUsagesToOptimize' to be at least 1, but got ${minUsagesToOptimize}`);
|
|
456
532
|
if (!fragments || fragments.isEmpty()) {
|
|
457
533
|
return this;
|
|
@@ -460,50 +536,41 @@ class Operation {
|
|
|
460
536
|
if (optimizedSelection === this.selectionSet) {
|
|
461
537
|
return this;
|
|
462
538
|
}
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if (!usages.has(fragment)) {
|
|
467
|
-
usages.set(fragment, 0);
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
const toDeoptimize = (0, utils_1.mapEntries)(usages).filter(([_, count]) => count < minUsagesToOptimize).map(([name]) => name);
|
|
471
|
-
if (toDeoptimize.length > 0) {
|
|
472
|
-
const newFragments = (_a = optimizedSelection.fragments) === null || _a === void 0 ? void 0 : _a.without(toDeoptimize);
|
|
473
|
-
optimizedSelection = optimizedSelection.expandFragments(toDeoptimize, newFragments);
|
|
474
|
-
optimizedSelection = optimizedSelection.trimUnsatisfiableBranches(optimizedSelection.parentType);
|
|
539
|
+
const finalFragments = computeFragmentsToKeep(optimizedSelection, fragments, minUsagesToOptimize);
|
|
540
|
+
if (finalFragments === null || (finalFragments === null || finalFragments === void 0 ? void 0 : finalFragments.size) === fragments.size) {
|
|
541
|
+
return new Operation(this.schema, this.rootKind, optimizedSelection, this.variableDefinitions, finalFragments !== null && finalFragments !== void 0 ? finalFragments : undefined, this.name);
|
|
475
542
|
}
|
|
476
|
-
|
|
543
|
+
optimizedSelection = optimizedSelection.expandFragments(finalFragments);
|
|
544
|
+
optimizedSelection = optimizedSelection.trimUnsatisfiableBranches(optimizedSelection.parentType);
|
|
545
|
+
return new Operation(this.schema, this.rootKind, optimizedSelection, this.variableDefinitions, finalFragments, this.name);
|
|
477
546
|
}
|
|
478
547
|
expandAllFragments() {
|
|
479
|
-
const expandedSelections = this.selectionSet.
|
|
548
|
+
const expandedSelections = this.selectionSet.expandFragments();
|
|
480
549
|
if (expandedSelections === this.selectionSet) {
|
|
481
550
|
return this;
|
|
482
551
|
}
|
|
483
|
-
return new Operation(this.schema, this.rootKind, expandedSelections, this.variableDefinitions, this.name);
|
|
552
|
+
return new Operation(this.schema, this.rootKind, expandedSelections, this.variableDefinitions, undefined, this.name);
|
|
484
553
|
}
|
|
485
554
|
trimUnsatisfiableBranches() {
|
|
486
555
|
const trimmedSelections = this.selectionSet.trimUnsatisfiableBranches(this.selectionSet.parentType);
|
|
487
556
|
if (trimmedSelections === this.selectionSet) {
|
|
488
557
|
return this;
|
|
489
558
|
}
|
|
490
|
-
return new Operation(this.schema, this.rootKind, trimmedSelections, this.variableDefinitions, this.name);
|
|
559
|
+
return new Operation(this.schema, this.rootKind, trimmedSelections, this.variableDefinitions, this.fragments, this.name);
|
|
491
560
|
}
|
|
492
561
|
withoutDefer(labelsToRemove) {
|
|
493
|
-
(0, utils_1.assert)(!this.selectionSet.fragments || this.selectionSet.fragments.isEmpty(), 'Removing @defer currently only work on "expanded" selections (no named fragments)');
|
|
494
562
|
const updated = this.selectionSet.withoutDefer(labelsToRemove);
|
|
495
563
|
return updated == this.selectionSet
|
|
496
564
|
? this
|
|
497
|
-
: new Operation(this.schema, this.rootKind, updated, this.variableDefinitions, this.name);
|
|
565
|
+
: new Operation(this.schema, this.rootKind, updated, this.variableDefinitions, this.fragments, this.name);
|
|
498
566
|
}
|
|
499
567
|
withNormalizedDefer() {
|
|
500
|
-
(0, utils_1.assert)(!this.selectionSet.fragments || this.selectionSet.fragments.isEmpty(), 'Assigning @defer lables currently only work on "expanded" selections (no named fragments)');
|
|
501
568
|
const normalizer = new DeferNormalizer();
|
|
502
569
|
const { hasDefers, hasNonLabelledOrConditionalDefers } = normalizer.init(this.selectionSet);
|
|
503
570
|
let updatedOperation = this;
|
|
504
571
|
if (hasNonLabelledOrConditionalDefers) {
|
|
505
572
|
const updated = this.selectionSet.withNormalizedDefer(normalizer);
|
|
506
|
-
updatedOperation = new Operation(this.schema, this.rootKind, updated, this.variableDefinitions, this.name);
|
|
573
|
+
updatedOperation = new Operation(this.schema, this.rootKind, updated, this.variableDefinitions, this.fragments, this.name);
|
|
507
574
|
}
|
|
508
575
|
return {
|
|
509
576
|
operation: updatedOperation,
|
|
@@ -522,7 +589,7 @@ class Operation {
|
|
|
522
589
|
return defaultedVariableValues;
|
|
523
590
|
}
|
|
524
591
|
toString(expandFragments = false, prettyPrint = true) {
|
|
525
|
-
return this.selectionSet.toOperationString(this.rootKind, this.variableDefinitions, this.name, expandFragments, prettyPrint);
|
|
592
|
+
return this.selectionSet.toOperationString(this.rootKind, this.variableDefinitions, this.fragments, this.name, expandFragments, prettyPrint);
|
|
526
593
|
}
|
|
527
594
|
}
|
|
528
595
|
exports.Operation = Operation;
|
|
@@ -531,7 +598,7 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
531
598
|
super(schema, directives);
|
|
532
599
|
this.name = name;
|
|
533
600
|
this.typeCondition = typeCondition;
|
|
534
|
-
this.
|
|
601
|
+
this.expandedSelectionSetsAtTypesCache = new Map();
|
|
535
602
|
}
|
|
536
603
|
setSelectionSet(selectionSet) {
|
|
537
604
|
(0, utils_1.assert)(!this._selectionSet, 'Attempting to set the selection set of a fragment definition already built');
|
|
@@ -543,11 +610,28 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
543
610
|
(0, utils_1.assert)(this._selectionSet, () => `Trying to access fragment definition ${this.name} before it is fully built`);
|
|
544
611
|
return this._selectionSet;
|
|
545
612
|
}
|
|
613
|
+
expandedSelectionSet() {
|
|
614
|
+
if (!this._expandedSelectionSet) {
|
|
615
|
+
this._expandedSelectionSet = this.selectionSet.expandFragments().trimUnsatisfiableBranches(this.typeCondition);
|
|
616
|
+
}
|
|
617
|
+
return this._expandedSelectionSet;
|
|
618
|
+
}
|
|
546
619
|
withUpdatedSelectionSet(newSelectionSet) {
|
|
547
620
|
return new NamedFragmentDefinition(this.schema(), this.name, this.typeCondition).setSelectionSet(newSelectionSet);
|
|
548
621
|
}
|
|
622
|
+
fragmentUsages() {
|
|
623
|
+
if (!this._fragmentUsages) {
|
|
624
|
+
this._fragmentUsages = new Map();
|
|
625
|
+
this.selectionSet.collectUsedFragmentNames(this._fragmentUsages);
|
|
626
|
+
}
|
|
627
|
+
return this._fragmentUsages;
|
|
628
|
+
}
|
|
549
629
|
collectUsedFragmentNames(collector) {
|
|
550
|
-
this.
|
|
630
|
+
const usages = this.fragmentUsages();
|
|
631
|
+
for (const [name, count] of usages.entries()) {
|
|
632
|
+
const prevCount = collector.get(name);
|
|
633
|
+
collector.set(name, prevCount ? prevCount + count : count);
|
|
634
|
+
}
|
|
551
635
|
}
|
|
552
636
|
toFragmentDefinitionNode() {
|
|
553
637
|
return {
|
|
@@ -567,21 +651,49 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
567
651
|
};
|
|
568
652
|
}
|
|
569
653
|
canApplyAtType(type) {
|
|
570
|
-
|
|
654
|
+
if ((0, types_1.sameType)(type, this.typeCondition)) {
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
657
|
+
if (!(0, definitions_1.isAbstractType)(this.typeCondition)) {
|
|
658
|
+
return false;
|
|
659
|
+
}
|
|
660
|
+
const conditionRuntimes = (0, definitions_1.possibleRuntimeTypes)(this.typeCondition);
|
|
661
|
+
const typeRuntimes = (0, definitions_1.possibleRuntimeTypes)(type);
|
|
662
|
+
return conditionRuntimes.length >= typeRuntimes.length
|
|
663
|
+
&& typeRuntimes.every((t1) => conditionRuntimes.some((t2) => (0, types_1.sameType)(t1, t2)));
|
|
571
664
|
}
|
|
572
|
-
|
|
665
|
+
expandedSelectionSetAtType(type) {
|
|
666
|
+
const expandedSelectionSet = this.expandedSelectionSet();
|
|
573
667
|
if ((0, types_1.sameType)(type, this.typeCondition) || (0, definitions_1.isObjectType)(this.typeCondition)) {
|
|
574
|
-
return
|
|
668
|
+
return expandedSelectionSet;
|
|
575
669
|
}
|
|
576
670
|
if (!(0, definitions_1.isObjectType)(type)) {
|
|
577
|
-
return
|
|
671
|
+
return expandedSelectionSet;
|
|
578
672
|
}
|
|
579
|
-
let
|
|
580
|
-
if (!
|
|
581
|
-
|
|
582
|
-
this.
|
|
673
|
+
let selectionAtType = this.expandedSelectionSetsAtTypesCache.get(type.name);
|
|
674
|
+
if (!selectionAtType) {
|
|
675
|
+
selectionAtType = expandedSelectionSet.trimUnsatisfiableBranches(type, { recursive: false });
|
|
676
|
+
this.expandedSelectionSetsAtTypesCache.set(type.name, selectionAtType);
|
|
583
677
|
}
|
|
584
|
-
return
|
|
678
|
+
return selectionAtType;
|
|
679
|
+
}
|
|
680
|
+
includes(otherFragment) {
|
|
681
|
+
if (this.name === otherFragment) {
|
|
682
|
+
return false;
|
|
683
|
+
}
|
|
684
|
+
if (!this._includedFragmentNames) {
|
|
685
|
+
this._includedFragmentNames = this.computeIncludedFragmentNames();
|
|
686
|
+
}
|
|
687
|
+
return this._includedFragmentNames.has(otherFragment);
|
|
688
|
+
}
|
|
689
|
+
computeIncludedFragmentNames() {
|
|
690
|
+
const included = new Set();
|
|
691
|
+
for (const selection of this.selectionSet.selections()) {
|
|
692
|
+
if (selection instanceof FragmentSpreadSelection) {
|
|
693
|
+
included.add(selection.namedFragment.name);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return included;
|
|
585
697
|
}
|
|
586
698
|
toString(indent) {
|
|
587
699
|
return (indent !== null && indent !== void 0 ? indent : '') + `fragment ${this.name} on ${this.typeCondition}${this.appliedDirectivesToString()} ${this.selectionSet.toString(false, true, indent)}`;
|
|
@@ -593,7 +705,10 @@ class NamedFragments {
|
|
|
593
705
|
this.fragments = new utils_1.MapWithCachedArrays();
|
|
594
706
|
}
|
|
595
707
|
isEmpty() {
|
|
596
|
-
return this.
|
|
708
|
+
return this.size === 0;
|
|
709
|
+
}
|
|
710
|
+
get size() {
|
|
711
|
+
return this.fragments.size;
|
|
597
712
|
}
|
|
598
713
|
names() {
|
|
599
714
|
return this.fragments.keys();
|
|
@@ -612,22 +727,6 @@ class NamedFragments {
|
|
|
612
727
|
maybeApplyingAtType(type) {
|
|
613
728
|
return this.fragments.values().filter(f => f.canApplyAtType(type));
|
|
614
729
|
}
|
|
615
|
-
without(names) {
|
|
616
|
-
if (!names.some(n => this.fragments.has(n))) {
|
|
617
|
-
return this;
|
|
618
|
-
}
|
|
619
|
-
const newFragments = new NamedFragments();
|
|
620
|
-
for (const fragment of this.fragments.values()) {
|
|
621
|
-
if (!names.includes(fragment.name)) {
|
|
622
|
-
const updatedSelectionSet = fragment.selectionSet.expandFragments(names, newFragments);
|
|
623
|
-
const newFragment = updatedSelectionSet === fragment.selectionSet
|
|
624
|
-
? fragment
|
|
625
|
-
: fragment.withUpdatedSelectionSet(updatedSelectionSet);
|
|
626
|
-
newFragments.add(newFragment);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
return newFragments.isEmpty() ? undefined : newFragments;
|
|
630
|
-
}
|
|
631
730
|
get(name) {
|
|
632
731
|
return this.fragments.get(name);
|
|
633
732
|
}
|
|
@@ -644,45 +743,70 @@ class NamedFragments {
|
|
|
644
743
|
}
|
|
645
744
|
return mapped;
|
|
646
745
|
}
|
|
647
|
-
|
|
746
|
+
mapInDependencyOrder(mapper) {
|
|
648
747
|
const fragmentsMap = new Map();
|
|
649
|
-
const removedFragments = new Set();
|
|
650
748
|
for (const fragment of this.definitions()) {
|
|
651
|
-
const mappedSelectionSet = mapper(fragment.selectionSet.expandAllFragments().trimUnsatisfiableBranches(fragment.typeCondition));
|
|
652
|
-
if (!mappedSelectionSet) {
|
|
653
|
-
removedFragments.add(fragment.name);
|
|
654
|
-
continue;
|
|
655
|
-
}
|
|
656
|
-
const otherFragmentsUsages = new Map();
|
|
657
|
-
fragment.collectUsedFragmentNames(otherFragmentsUsages);
|
|
658
749
|
fragmentsMap.set(fragment.name, {
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
dependsOn: Array.from(otherFragmentsUsages.keys()),
|
|
750
|
+
fragment,
|
|
751
|
+
dependsOn: Array.from(fragment.fragmentUsages().keys()),
|
|
662
752
|
});
|
|
663
753
|
}
|
|
754
|
+
const removedFragments = new Set();
|
|
664
755
|
const mappedFragments = new NamedFragments();
|
|
665
756
|
while (fragmentsMap.size > 0) {
|
|
666
757
|
for (const [name, info] of fragmentsMap) {
|
|
667
758
|
if (info.dependsOn.every((n) => mappedFragments.has(n) || removedFragments.has(n))) {
|
|
668
|
-
const
|
|
669
|
-
mappedFragments.add(recreateFct(info.original, reoptimizedSelectionSet));
|
|
759
|
+
const mapped = mapper(info.fragment, mappedFragments);
|
|
670
760
|
fragmentsMap.delete(name);
|
|
761
|
+
if (!mapped) {
|
|
762
|
+
removedFragments.add(name);
|
|
763
|
+
}
|
|
764
|
+
else {
|
|
765
|
+
mappedFragments.add(mapped);
|
|
766
|
+
}
|
|
767
|
+
break;
|
|
671
768
|
}
|
|
672
769
|
}
|
|
673
770
|
}
|
|
674
771
|
return mappedFragments.isEmpty() ? undefined : mappedFragments;
|
|
675
772
|
}
|
|
773
|
+
mapToExpandedSelectionSets(mapper) {
|
|
774
|
+
return this.mapInDependencyOrder((fragment, newFragments) => {
|
|
775
|
+
const mappedSelectionSet = mapper(fragment.selectionSet.expandFragments().trimUnsatisfiableBranches(fragment.typeCondition));
|
|
776
|
+
if (!mappedSelectionSet) {
|
|
777
|
+
return undefined;
|
|
778
|
+
}
|
|
779
|
+
const reoptimizedSelectionSet = mappedSelectionSet.optimize(newFragments);
|
|
780
|
+
return fragment.withUpdatedSelectionSet(reoptimizedSelectionSet);
|
|
781
|
+
});
|
|
782
|
+
}
|
|
676
783
|
rebaseOn(schema) {
|
|
677
|
-
return this.
|
|
678
|
-
const rebasedType = schema.type(
|
|
784
|
+
return this.mapInDependencyOrder((fragment, newFragments) => {
|
|
785
|
+
const rebasedType = schema.type(fragment.selectionSet.parentType.name);
|
|
679
786
|
try {
|
|
680
|
-
|
|
787
|
+
if (!rebasedType || !(0, definitions_1.isCompositeType)(rebasedType)) {
|
|
788
|
+
return undefined;
|
|
789
|
+
}
|
|
790
|
+
const rebasedSelection = fragment.selectionSet.rebaseOn(rebasedType, newFragments);
|
|
791
|
+
return new NamedFragmentDefinition(schema, fragment.name, rebasedType).setSelectionSet(rebasedSelection);
|
|
681
792
|
}
|
|
682
793
|
catch (e) {
|
|
683
794
|
return undefined;
|
|
684
795
|
}
|
|
685
|
-
}
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
filter(predicate) {
|
|
799
|
+
return this.mapInDependencyOrder((fragment, newFragments) => {
|
|
800
|
+
if (predicate(fragment)) {
|
|
801
|
+
const updatedSelectionSet = fragment.selectionSet.expandFragments(newFragments);
|
|
802
|
+
return updatedSelectionSet === fragment.selectionSet
|
|
803
|
+
? fragment
|
|
804
|
+
: fragment.withUpdatedSelectionSet(updatedSelectionSet);
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
return undefined;
|
|
808
|
+
}
|
|
809
|
+
});
|
|
686
810
|
}
|
|
687
811
|
validate(variableDefinitions) {
|
|
688
812
|
for (const fragment of this.fragments.values()) {
|
|
@@ -743,10 +867,15 @@ class DeferNormalizer {
|
|
|
743
867
|
this.deferConditions.add(condition.name, label);
|
|
744
868
|
}
|
|
745
869
|
}
|
|
870
|
+
var ContainsResult;
|
|
871
|
+
(function (ContainsResult) {
|
|
872
|
+
ContainsResult[ContainsResult["NOT_CONTAINED"] = 0] = "NOT_CONTAINED";
|
|
873
|
+
ContainsResult[ContainsResult["STRICTLY_CONTAINED"] = 1] = "STRICTLY_CONTAINED";
|
|
874
|
+
ContainsResult[ContainsResult["EQUAL"] = 2] = "EQUAL";
|
|
875
|
+
})(ContainsResult = exports.ContainsResult || (exports.ContainsResult = {}));
|
|
746
876
|
class SelectionSet {
|
|
747
|
-
constructor(parentType, keyedSelections = new Map()
|
|
877
|
+
constructor(parentType, keyedSelections = new Map()) {
|
|
748
878
|
this.parentType = parentType;
|
|
749
|
-
this.fragments = fragments;
|
|
750
879
|
this._keyedSelections = keyedSelections;
|
|
751
880
|
this._selections = (0, utils_1.mapValues)(keyedSelections);
|
|
752
881
|
}
|
|
@@ -802,21 +931,14 @@ class SelectionSet {
|
|
|
802
931
|
const wrapped = new InlineFragmentSelection(new FragmentElement(this.parentType, this.parentType), this);
|
|
803
932
|
const optimized = wrapped.optimize(fragments);
|
|
804
933
|
return optimized instanceof FragmentSpreadSelection
|
|
805
|
-
? selectionSetOf(this.parentType, optimized
|
|
934
|
+
? selectionSetOf(this.parentType, optimized)
|
|
806
935
|
: optimized.selectionSet;
|
|
807
936
|
}
|
|
808
937
|
optimizeSelections(fragments) {
|
|
809
|
-
|
|
810
|
-
return this.lazyMap((selection) => selection.optimize(fragments), { fragments });
|
|
938
|
+
return this.lazyMap((selection) => selection.optimize(fragments));
|
|
811
939
|
}
|
|
812
|
-
|
|
813
|
-
return this.lazyMap((selection) => selection.
|
|
814
|
-
}
|
|
815
|
-
expandFragments(names, updatedFragments) {
|
|
816
|
-
if (names.length === 0) {
|
|
817
|
-
return this;
|
|
818
|
-
}
|
|
819
|
-
return this.lazyMap((selection) => selection.expandFragments(names, updatedFragments), { fragments: updatedFragments !== null && updatedFragments !== void 0 ? updatedFragments : null });
|
|
940
|
+
expandFragments(updatedFragments) {
|
|
941
|
+
return this.lazyMap((selection) => selection.expandFragments(updatedFragments));
|
|
820
942
|
}
|
|
821
943
|
trimUnsatisfiableBranches(parentType, options) {
|
|
822
944
|
return this.lazyMap((selection) => selection.trimUnsatisfiableBranches(parentType, options), { parentType });
|
|
@@ -824,8 +946,6 @@ class SelectionSet {
|
|
|
824
946
|
lazyMap(mapper, options) {
|
|
825
947
|
var _a;
|
|
826
948
|
const selections = this.selections();
|
|
827
|
-
const updatedFragments = options === null || options === void 0 ? void 0 : options.fragments;
|
|
828
|
-
const newFragments = updatedFragments === undefined ? this.fragments : (updatedFragments !== null && updatedFragments !== void 0 ? updatedFragments : undefined);
|
|
829
949
|
let updatedSelections = undefined;
|
|
830
950
|
for (let i = 0; i < selections.length; i++) {
|
|
831
951
|
const selection = selections[i];
|
|
@@ -841,19 +961,14 @@ class SelectionSet {
|
|
|
841
961
|
}
|
|
842
962
|
}
|
|
843
963
|
if (!updatedSelections) {
|
|
844
|
-
return this
|
|
964
|
+
return this;
|
|
845
965
|
}
|
|
846
|
-
return updatedSelections.toSelectionSet((_a = options === null || options === void 0 ? void 0 : options.parentType) !== null && _a !== void 0 ? _a : this.parentType
|
|
847
|
-
}
|
|
848
|
-
withUpdatedFragments(newFragments) {
|
|
849
|
-
return this.fragments === newFragments ? this : new SelectionSet(this.parentType, this._keyedSelections, newFragments);
|
|
966
|
+
return updatedSelections.toSelectionSet((_a = options === null || options === void 0 ? void 0 : options.parentType) !== null && _a !== void 0 ? _a : this.parentType);
|
|
850
967
|
}
|
|
851
968
|
withoutDefer(labelsToRemove) {
|
|
852
|
-
(0, utils_1.assert)(!this.fragments, 'Not yet supported');
|
|
853
969
|
return this.lazyMap((selection) => selection.withoutDefer(labelsToRemove));
|
|
854
970
|
}
|
|
855
971
|
withNormalizedDefer(normalizer) {
|
|
856
|
-
(0, utils_1.assert)(!this.fragments, 'Not yet supported');
|
|
857
972
|
return this.lazyMap((selection) => selection.withNormalizedDefer(normalizer));
|
|
858
973
|
}
|
|
859
974
|
hasDefer() {
|
|
@@ -866,15 +981,15 @@ class SelectionSet {
|
|
|
866
981
|
const updated = this.filter((selection) => { var _a; return ((_a = selection.selectionSet) === null || _a === void 0 ? void 0 : _a.isEmpty()) !== true; });
|
|
867
982
|
return updated.isEmpty() ? undefined : updated;
|
|
868
983
|
}
|
|
869
|
-
rebaseOn(parentType) {
|
|
984
|
+
rebaseOn(parentType, fragments) {
|
|
870
985
|
if (this.parentType === parentType) {
|
|
871
986
|
return this;
|
|
872
987
|
}
|
|
873
988
|
const newSelections = new Map();
|
|
874
989
|
for (const selection of this.selections()) {
|
|
875
|
-
newSelections.set(selection.key(), selection.rebaseOn(parentType));
|
|
990
|
+
newSelections.set(selection.key(), selection.rebaseOn(parentType, fragments));
|
|
876
991
|
}
|
|
877
|
-
return new SelectionSet(parentType, newSelections
|
|
992
|
+
return new SelectionSet(parentType, newSelections);
|
|
878
993
|
}
|
|
879
994
|
equals(that) {
|
|
880
995
|
if (this === that) {
|
|
@@ -891,61 +1006,30 @@ class SelectionSet {
|
|
|
891
1006
|
}
|
|
892
1007
|
return true;
|
|
893
1008
|
}
|
|
894
|
-
triviallyNestedSelectionsForKey(parentType, key) {
|
|
895
|
-
const found = [];
|
|
896
|
-
for (const selection of this.selections()) {
|
|
897
|
-
if (selection.isUnecessaryInlineFragment(parentType)) {
|
|
898
|
-
const selectionForKey = selection.selectionSet._keyedSelections.get(key);
|
|
899
|
-
if (selectionForKey) {
|
|
900
|
-
found.push(selectionForKey);
|
|
901
|
-
}
|
|
902
|
-
for (const nestedSelection of selection.selectionSet.triviallyNestedSelectionsForKey(parentType, key)) {
|
|
903
|
-
found.push(nestedSelection);
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
return found;
|
|
908
|
-
}
|
|
909
|
-
mergeSameKeySelections(selections) {
|
|
910
|
-
if (selections.length === 0) {
|
|
911
|
-
return undefined;
|
|
912
|
-
}
|
|
913
|
-
const first = selections[0];
|
|
914
|
-
if (!first.selectionSet || (first instanceof FragmentSpreadSelection) || selections.length === 1) {
|
|
915
|
-
return first;
|
|
916
|
-
}
|
|
917
|
-
const mergedSubselections = new SelectionSetUpdates();
|
|
918
|
-
for (const selection of selections) {
|
|
919
|
-
mergedSubselections.add(selection.selectionSet);
|
|
920
|
-
}
|
|
921
|
-
if (first.kind === 'FieldSelection') {
|
|
922
|
-
const rebasedField = first.element.rebaseOn(this.parentType);
|
|
923
|
-
return new FieldSelection(rebasedField, mergedSubselections.toSelectionSet(rebasedField.baseType()));
|
|
924
|
-
}
|
|
925
|
-
else {
|
|
926
|
-
const rebasedFragment = first.element.rebaseOn(this.parentType);
|
|
927
|
-
return new InlineFragmentSelection(rebasedFragment, mergedSubselections.toSelectionSet(rebasedFragment.castedType()));
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
1009
|
contains(that) {
|
|
1010
|
+
if (that._selections.length > this._selections.length) {
|
|
1011
|
+
return ContainsResult.NOT_CONTAINED;
|
|
1012
|
+
}
|
|
1013
|
+
let isEqual = true;
|
|
931
1014
|
for (const [key, thatSelection] of that._keyedSelections) {
|
|
932
1015
|
const thisSelection = this._keyedSelections.get(key);
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
&& !(thatSelection.isUnecessaryInlineFragment(this.parentType) && this.contains(thatSelection.selectionSet))) {
|
|
937
|
-
return false;
|
|
1016
|
+
const selectionResult = thisSelection === null || thisSelection === void 0 ? void 0 : thisSelection.contains(thatSelection);
|
|
1017
|
+
if (selectionResult === undefined || selectionResult === ContainsResult.NOT_CONTAINED) {
|
|
1018
|
+
return ContainsResult.NOT_CONTAINED;
|
|
938
1019
|
}
|
|
1020
|
+
isEqual && (isEqual = selectionResult === ContainsResult.EQUAL);
|
|
939
1021
|
}
|
|
940
|
-
return
|
|
1022
|
+
return isEqual && that._selections.length === this._selections.length
|
|
1023
|
+
? ContainsResult.EQUAL
|
|
1024
|
+
: ContainsResult.STRICTLY_CONTAINED;
|
|
941
1025
|
}
|
|
942
|
-
diffWithNamedFragmentIfContained(candidate, parentType) {
|
|
943
|
-
const that = candidate.
|
|
1026
|
+
diffWithNamedFragmentIfContained(candidate, parentType, fragments) {
|
|
1027
|
+
const that = candidate.expandedSelectionSetAtType(parentType);
|
|
944
1028
|
if (that.isEmpty() || (that.selections().length === 1 && that.selections()[0].isTypenameField())) {
|
|
945
1029
|
return { contains: false };
|
|
946
1030
|
}
|
|
947
1031
|
if (this.contains(that)) {
|
|
948
|
-
let updatedThis = this.expandFragments(
|
|
1032
|
+
let updatedThis = this.expandFragments(fragments.filter((f) => f.name !== candidate.name));
|
|
949
1033
|
if (updatedThis !== this) {
|
|
950
1034
|
updatedThis = updatedThis.trimUnsatisfiableBranches(parentType);
|
|
951
1035
|
}
|
|
@@ -958,25 +1042,17 @@ class SelectionSet {
|
|
|
958
1042
|
const updated = new SelectionSetUpdates();
|
|
959
1043
|
for (const [key, thisSelection] of this._keyedSelections) {
|
|
960
1044
|
const thatSelection = that._keyedSelections.get(key);
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
const expanded = thisSelection.selectionSet.expandAllFragments().trimUnsatisfiableBranches(this.parentType);
|
|
966
|
-
if (expanded.minus(that).isEmpty()) {
|
|
967
|
-
continue;
|
|
968
|
-
}
|
|
1045
|
+
if (thatSelection) {
|
|
1046
|
+
const remainder = thisSelection.minus(thatSelection);
|
|
1047
|
+
if (remainder) {
|
|
1048
|
+
updated.add(remainder);
|
|
969
1049
|
}
|
|
970
|
-
updated.add(thisSelection);
|
|
971
1050
|
}
|
|
972
1051
|
else {
|
|
973
|
-
|
|
974
|
-
if (selectionDiff) {
|
|
975
|
-
updated.add(selectionDiff);
|
|
976
|
-
}
|
|
1052
|
+
updated.add(thisSelection);
|
|
977
1053
|
}
|
|
978
1054
|
}
|
|
979
|
-
return updated.toSelectionSet(this.parentType
|
|
1055
|
+
return updated.toSelectionSet(this.parentType);
|
|
980
1056
|
}
|
|
981
1057
|
canRebaseOn(parentTypeToTest) {
|
|
982
1058
|
return this.selections().every((selection) => selection.canAddTo(parentTypeToTest));
|
|
@@ -1046,10 +1122,10 @@ class SelectionSet {
|
|
|
1046
1122
|
}
|
|
1047
1123
|
return false;
|
|
1048
1124
|
}
|
|
1049
|
-
toOperationString(rootKind, variableDefinitions, operationName, expandFragments = false, prettyPrint = true) {
|
|
1125
|
+
toOperationString(rootKind, variableDefinitions, fragments, operationName, expandFragments = false, prettyPrint = true) {
|
|
1050
1126
|
const indent = prettyPrint ? '' : undefined;
|
|
1051
|
-
const fragmentsDefinitions = !expandFragments &&
|
|
1052
|
-
?
|
|
1127
|
+
const fragmentsDefinitions = !expandFragments && fragments && !fragments.isEmpty()
|
|
1128
|
+
? fragments.toString(indent) + "\n\n"
|
|
1053
1129
|
: "";
|
|
1054
1130
|
if (rootKind == "query" && !operationName && variableDefinitions.isEmpty()) {
|
|
1055
1131
|
return fragmentsDefinitions + this.toString(expandFragments, true, indent);
|
|
@@ -1184,7 +1260,7 @@ function makeSelection(parentType, updates, fragments) {
|
|
|
1184
1260
|
(0, utils_1.assert)(updates.length > 0, 'Should not be called without any updates');
|
|
1185
1261
|
const first = updates[0];
|
|
1186
1262
|
if (updates.length === 1 && first instanceof AbstractSelection) {
|
|
1187
|
-
return first.rebaseOn(parentType);
|
|
1263
|
+
return first.rebaseOn(parentType, fragments);
|
|
1188
1264
|
}
|
|
1189
1265
|
const element = updateElement(first).rebaseOn(parentType);
|
|
1190
1266
|
const subSelectionParentType = element.kind === 'Field' ? element.baseType() : element.castedType();
|
|
@@ -1223,7 +1299,7 @@ function makeSelectionSet(parentType, keyedUpdates, fragments) {
|
|
|
1223
1299
|
for (const [key, updates] of keyedUpdates.entries()) {
|
|
1224
1300
|
selections.set(key, makeSelection(parentType, updates, fragments));
|
|
1225
1301
|
}
|
|
1226
|
-
return new SelectionSet(parentType, selections
|
|
1302
|
+
return new SelectionSet(parentType, selections);
|
|
1227
1303
|
}
|
|
1228
1304
|
class MutableSelectionSet {
|
|
1229
1305
|
constructor(parentType, _updates, memoizer) {
|
|
@@ -1299,14 +1375,14 @@ function allFieldDefinitionsInSelectionSet(selection) {
|
|
|
1299
1375
|
return allFields;
|
|
1300
1376
|
}
|
|
1301
1377
|
exports.allFieldDefinitionsInSelectionSet = allFieldDefinitionsInSelectionSet;
|
|
1302
|
-
function selectionSetOf(parentType, selection
|
|
1378
|
+
function selectionSetOf(parentType, selection) {
|
|
1303
1379
|
const map = new Map();
|
|
1304
1380
|
map.set(selection.key(), selection);
|
|
1305
|
-
return new SelectionSet(parentType, map
|
|
1381
|
+
return new SelectionSet(parentType, map);
|
|
1306
1382
|
}
|
|
1307
1383
|
exports.selectionSetOf = selectionSetOf;
|
|
1308
|
-
function selectionSetOfElement(element, subSelection
|
|
1309
|
-
return selectionSetOf(element.parentType, selectionOfElement(element, subSelection)
|
|
1384
|
+
function selectionSetOfElement(element, subSelection) {
|
|
1385
|
+
return selectionSetOf(element.parentType, selectionOfElement(element, subSelection));
|
|
1310
1386
|
}
|
|
1311
1387
|
exports.selectionSetOfElement = selectionSetOfElement;
|
|
1312
1388
|
function selectionOfElement(element, subSelection) {
|
|
@@ -1332,10 +1408,6 @@ class AbstractSelection {
|
|
|
1332
1408
|
var _a;
|
|
1333
1409
|
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.collectUsedFragmentNames(collector);
|
|
1334
1410
|
}
|
|
1335
|
-
namedFragments() {
|
|
1336
|
-
var _a;
|
|
1337
|
-
return (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.fragments;
|
|
1338
|
-
}
|
|
1339
1411
|
withUpdatedSelectionSet(selectionSet) {
|
|
1340
1412
|
return this.withUpdatedComponents(this.element, selectionSet);
|
|
1341
1413
|
}
|
|
@@ -1351,6 +1423,9 @@ class AbstractSelection {
|
|
|
1351
1423
|
? this.us()
|
|
1352
1424
|
: this.withUpdatedSelectionSet(updatedSelectionSet);
|
|
1353
1425
|
}
|
|
1426
|
+
isFragmentSpread() {
|
|
1427
|
+
return false;
|
|
1428
|
+
}
|
|
1354
1429
|
minus(that) {
|
|
1355
1430
|
if (this.selectionSet && that.selectionSet) {
|
|
1356
1431
|
const updatedSubSelectionSet = this.selectionSet.minus(that.selectionSet);
|
|
@@ -1360,29 +1435,38 @@ class AbstractSelection {
|
|
|
1360
1435
|
}
|
|
1361
1436
|
return undefined;
|
|
1362
1437
|
}
|
|
1363
|
-
|
|
1364
|
-
(0, utils_1.assert)(false, `UNSUPPORTED`);
|
|
1365
|
-
}
|
|
1366
|
-
tryOptimizeSubselectionWithFragments({ parentType, subSelection, fragments, fragmentFilter, }) {
|
|
1438
|
+
tryOptimizeSubselectionWithFragments({ parentType, subSelection, fragments, canUseFullMatchingFragment, }) {
|
|
1367
1439
|
let candidates = fragments.maybeApplyingAtType(parentType);
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
const { spread, optimizedSelection, hasDiff } = this.tryOptimizeSubselectionOnce({ parentType, subSelection, candidates, fragments });
|
|
1374
|
-
if (optimizedSelection) {
|
|
1375
|
-
subSelection = optimizedSelection;
|
|
1440
|
+
const applyingFragments = [];
|
|
1441
|
+
for (const candidate of candidates) {
|
|
1442
|
+
const fragmentSSet = candidate.expandedSelectionSetAtType(parentType);
|
|
1443
|
+
if (fragmentSSet.isEmpty() || (fragmentSSet.selections().length === 1 && fragmentSSet.selections()[0].isTypenameField())) {
|
|
1444
|
+
continue;
|
|
1376
1445
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1446
|
+
const res = subSelection.contains(fragmentSSet);
|
|
1447
|
+
if (res === ContainsResult.EQUAL) {
|
|
1448
|
+
if (canUseFullMatchingFragment(candidate)) {
|
|
1449
|
+
return candidate;
|
|
1450
|
+
}
|
|
1451
|
+
if (candidate.appliedDirectives.length === 0) {
|
|
1452
|
+
applyingFragments.push(candidate);
|
|
1453
|
+
}
|
|
1379
1454
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
candidates = candidates.filter((c) => c !== (spread === null || spread === void 0 ? void 0 : spread.namedFragment));
|
|
1455
|
+
else if (res === ContainsResult.STRICTLY_CONTAINED && candidate.appliedDirectives.length === 0) {
|
|
1456
|
+
applyingFragments.push(candidate);
|
|
1383
1457
|
}
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1458
|
+
}
|
|
1459
|
+
if (applyingFragments.length === 0) {
|
|
1460
|
+
return subSelection;
|
|
1461
|
+
}
|
|
1462
|
+
const filteredApplyingFragments = applyingFragments.filter((f) => !applyingFragments.some((o) => o.includes(f.name)));
|
|
1463
|
+
let notCoveredByFragments = subSelection;
|
|
1464
|
+
const optimized = new SelectionSetUpdates();
|
|
1465
|
+
for (const fragment of filteredApplyingFragments) {
|
|
1466
|
+
notCoveredByFragments = notCoveredByFragments.minus(fragment.expandedSelectionSetAtType(parentType));
|
|
1467
|
+
optimized.add(new FragmentSpreadSelection(parentType, fragments, fragment, []));
|
|
1468
|
+
}
|
|
1469
|
+
return optimized.add(notCoveredByFragments).toSelectionSet(parentType, fragments);
|
|
1386
1470
|
}
|
|
1387
1471
|
}
|
|
1388
1472
|
class FieldSelection extends AbstractSelection {
|
|
@@ -1407,35 +1491,29 @@ class FieldSelection extends AbstractSelection {
|
|
|
1407
1491
|
return this.element.key();
|
|
1408
1492
|
}
|
|
1409
1493
|
optimize(fragments) {
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1494
|
+
const fieldBaseType = (0, definitions_1.baseType)(this.element.definition.type);
|
|
1495
|
+
if (!(0, definitions_1.isCompositeType)(fieldBaseType) || !this.selectionSet) {
|
|
1496
|
+
return this;
|
|
1497
|
+
}
|
|
1498
|
+
let optimizedSelection = this.selectionSet;
|
|
1499
|
+
if ((0, definitions_1.isCompositeType)(fieldBaseType) && this.selectionSet) {
|
|
1413
1500
|
const optimized = this.tryOptimizeSubselectionWithFragments({
|
|
1414
1501
|
parentType: fieldBaseType,
|
|
1415
|
-
subSelection:
|
|
1502
|
+
subSelection: this.selectionSet,
|
|
1416
1503
|
fragments,
|
|
1417
|
-
|
|
1504
|
+
canUseFullMatchingFragment: (fragment) => fragment.appliedDirectives.length === 0,
|
|
1418
1505
|
});
|
|
1419
|
-
|
|
1420
|
-
|
|
1506
|
+
if (optimized instanceof NamedFragmentDefinition) {
|
|
1507
|
+
optimizedSelection = selectionSetOf(fieldBaseType, new FragmentSpreadSelection(fieldBaseType, fragments, optimized, []));
|
|
1508
|
+
}
|
|
1509
|
+
else {
|
|
1510
|
+
optimizedSelection = optimized;
|
|
1511
|
+
}
|
|
1421
1512
|
}
|
|
1513
|
+
optimizedSelection = optimizedSelection.optimize(fragments);
|
|
1422
1514
|
return this.selectionSet === optimizedSelection
|
|
1423
1515
|
? this
|
|
1424
|
-
:
|
|
1425
|
-
}
|
|
1426
|
-
tryOptimizeSubselectionOnce({ parentType, subSelection, candidates, fragments, }) {
|
|
1427
|
-
let optimizedSelection = subSelection;
|
|
1428
|
-
for (const candidate of candidates) {
|
|
1429
|
-
const { contains, diff } = optimizedSelection.diffWithNamedFragmentIfContained(candidate, parentType);
|
|
1430
|
-
if (contains) {
|
|
1431
|
-
const spread = new FragmentSpreadSelection(parentType, fragments, candidate, []);
|
|
1432
|
-
optimizedSelection = diff
|
|
1433
|
-
? new SelectionSetUpdates().add(spread).add(diff).toSelectionSet(parentType, fragments)
|
|
1434
|
-
: selectionSetOf(parentType, spread);
|
|
1435
|
-
return { spread, optimizedSelection, hasDiff: !!diff };
|
|
1436
|
-
}
|
|
1437
|
-
}
|
|
1438
|
-
return {};
|
|
1516
|
+
: this.withUpdatedSelectionSet(optimizedSelection);
|
|
1439
1517
|
}
|
|
1440
1518
|
filter(predicate) {
|
|
1441
1519
|
if (!this.selectionSet) {
|
|
@@ -1453,7 +1531,7 @@ class FieldSelection extends AbstractSelection {
|
|
|
1453
1531
|
validate(this.element.isLeafField() || (this.selectionSet && !this.selectionSet.isEmpty()), () => `Invalid empty selection set for field "${this.element.definition.coordinate}" of non-leaf type ${this.element.definition.type}`, this.element.definition.sourceAST);
|
|
1454
1532
|
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.validate(variableDefinitions);
|
|
1455
1533
|
}
|
|
1456
|
-
rebaseOn(parentType) {
|
|
1534
|
+
rebaseOn(parentType, fragments) {
|
|
1457
1535
|
if (this.element.parentType === parentType) {
|
|
1458
1536
|
return this;
|
|
1459
1537
|
}
|
|
@@ -1466,7 +1544,7 @@ class FieldSelection extends AbstractSelection {
|
|
|
1466
1544
|
return this.withUpdatedElement(rebasedElement);
|
|
1467
1545
|
}
|
|
1468
1546
|
validate((0, definitions_1.isCompositeType)(rebasedBase), () => `Cannot rebase field selection ${this} on ${parentType}: rebased field base return type ${rebasedBase} is not composite`);
|
|
1469
|
-
return this.withUpdatedComponents(rebasedElement, this.selectionSet.rebaseOn(rebasedBase));
|
|
1547
|
+
return this.withUpdatedComponents(rebasedElement, this.selectionSet.rebaseOn(rebasedBase, fragments));
|
|
1470
1548
|
}
|
|
1471
1549
|
canAddTo(parentType) {
|
|
1472
1550
|
if (this.element.parentType === parentType) {
|
|
@@ -1508,9 +1586,6 @@ class FieldSelection extends AbstractSelection {
|
|
|
1508
1586
|
var _a;
|
|
1509
1587
|
return !!((_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.hasDefer());
|
|
1510
1588
|
}
|
|
1511
|
-
expandAllFragments() {
|
|
1512
|
-
return this.mapToSelectionSet((s) => s.expandAllFragments());
|
|
1513
|
-
}
|
|
1514
1589
|
trimUnsatisfiableBranches(_, options) {
|
|
1515
1590
|
var _a, _b;
|
|
1516
1591
|
if (!this.selectionSet) {
|
|
@@ -1526,8 +1601,8 @@ class FieldSelection extends AbstractSelection {
|
|
|
1526
1601
|
return trimmed;
|
|
1527
1602
|
}
|
|
1528
1603
|
}
|
|
1529
|
-
expandFragments(
|
|
1530
|
-
return this.mapToSelectionSet((s) => s.expandFragments(
|
|
1604
|
+
expandFragments(updatedFragments) {
|
|
1605
|
+
return this.mapToSelectionSet((s) => s.expandFragments(updatedFragments));
|
|
1531
1606
|
}
|
|
1532
1607
|
equals(that) {
|
|
1533
1608
|
if (this === that) {
|
|
@@ -1543,15 +1618,14 @@ class FieldSelection extends AbstractSelection {
|
|
|
1543
1618
|
}
|
|
1544
1619
|
contains(that) {
|
|
1545
1620
|
if (!(that instanceof FieldSelection) || !this.element.equals(that.element)) {
|
|
1546
|
-
return
|
|
1621
|
+
return ContainsResult.NOT_CONTAINED;
|
|
1547
1622
|
}
|
|
1548
|
-
if (!
|
|
1549
|
-
|
|
1623
|
+
if (!this.selectionSet) {
|
|
1624
|
+
(0, utils_1.assert)(!that.selectionSet, '`this` and `that` have the same element, so if one does not have a sub-selection, neither should the other one');
|
|
1625
|
+
return ContainsResult.EQUAL;
|
|
1550
1626
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
isUnecessaryInlineFragment(_) {
|
|
1554
|
-
return false;
|
|
1627
|
+
(0, utils_1.assert)(that.selectionSet, '`this` and `that` have the same element, so if one has sub-selection, the other one should too');
|
|
1628
|
+
return this.selectionSet.contains(that.selectionSet);
|
|
1555
1629
|
}
|
|
1556
1630
|
toString(expandFragments = true, indent) {
|
|
1557
1631
|
return (indent !== null && indent !== void 0 ? indent : '') + this.element + (this.selectionSet ? ' ' + this.selectionSet.toString(expandFragments, true, indent) : '');
|
|
@@ -1584,12 +1658,6 @@ class FragmentSelection extends AbstractSelection {
|
|
|
1584
1658
|
hasDefer() {
|
|
1585
1659
|
return this.element.hasDefer() || this.selectionSet.hasDefer();
|
|
1586
1660
|
}
|
|
1587
|
-
isUnecessaryInlineFragment(parentType) {
|
|
1588
|
-
return this.element.appliedDirectives.length === 0
|
|
1589
|
-
&& !!this.element.typeCondition
|
|
1590
|
-
&& (this.element.typeCondition.name === parentType.name
|
|
1591
|
-
|| ((0, definitions_1.isObjectType)(parentType) && (0, definitions_1.possibleRuntimeTypes)(this.element.typeCondition).some((t) => t.name === parentType.name)));
|
|
1592
|
-
}
|
|
1593
1661
|
}
|
|
1594
1662
|
exports.FragmentSelection = FragmentSelection;
|
|
1595
1663
|
class InlineFragmentSelection extends FragmentSelection {
|
|
@@ -1611,7 +1679,7 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1611
1679
|
validate(!this.selectionSet.isEmpty(), () => `Invalid empty selection set for fragment "${this.element}"`);
|
|
1612
1680
|
this.selectionSet.validate(variableDefinitions);
|
|
1613
1681
|
}
|
|
1614
|
-
rebaseOn(parentType) {
|
|
1682
|
+
rebaseOn(parentType, fragments) {
|
|
1615
1683
|
if (this.parentType === parentType) {
|
|
1616
1684
|
return this;
|
|
1617
1685
|
}
|
|
@@ -1620,7 +1688,7 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1620
1688
|
if (rebasedCastedType === this.selectionSet.parentType) {
|
|
1621
1689
|
return this.withUpdatedElement(rebasedFragment);
|
|
1622
1690
|
}
|
|
1623
|
-
return this.withUpdatedComponents(rebasedFragment, this.selectionSet.rebaseOn(rebasedCastedType));
|
|
1691
|
+
return this.withUpdatedComponents(rebasedFragment, this.selectionSet.rebaseOn(rebasedCastedType, fragments));
|
|
1624
1692
|
}
|
|
1625
1693
|
canAddTo(parentType) {
|
|
1626
1694
|
if (this.element.parentType === parentType) {
|
|
@@ -1653,52 +1721,39 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1653
1721
|
};
|
|
1654
1722
|
}
|
|
1655
1723
|
optimize(fragments) {
|
|
1656
|
-
let optimizedSelection = this.selectionSet
|
|
1724
|
+
let optimizedSelection = this.selectionSet;
|
|
1657
1725
|
const typeCondition = this.element.typeCondition;
|
|
1658
1726
|
if (typeCondition) {
|
|
1659
1727
|
const optimized = this.tryOptimizeSubselectionWithFragments({
|
|
1660
1728
|
parentType: typeCondition,
|
|
1661
1729
|
subSelection: optimizedSelection,
|
|
1662
1730
|
fragments,
|
|
1731
|
+
canUseFullMatchingFragment: (fragment) => {
|
|
1732
|
+
return fragment.appliedDirectives.length === 0
|
|
1733
|
+
|| ((0, types_1.sameType)(typeCondition, fragment.typeCondition)
|
|
1734
|
+
&& fragment.appliedDirectives.every((d) => this.element.appliedDirectives.some((s) => (0, definitions_1.sameDirectiveApplication)(d, s))));
|
|
1735
|
+
},
|
|
1663
1736
|
});
|
|
1664
|
-
if (optimized instanceof
|
|
1665
|
-
|
|
1666
|
-
}
|
|
1667
|
-
optimizedSelection = optimized;
|
|
1668
|
-
}
|
|
1669
|
-
return this.selectionSet === optimizedSelection
|
|
1670
|
-
? this
|
|
1671
|
-
: new InlineFragmentSelection(this.element, optimizedSelection);
|
|
1672
|
-
}
|
|
1673
|
-
tryOptimizeSubselectionOnce({ parentType, subSelection, candidates, fragments, }) {
|
|
1674
|
-
let optimizedSelection = subSelection;
|
|
1675
|
-
for (const candidate of candidates) {
|
|
1676
|
-
const { contains, diff } = optimizedSelection.diffWithNamedFragmentIfContained(candidate, parentType);
|
|
1677
|
-
if (contains) {
|
|
1678
|
-
if (!diff && (0, types_1.sameType)(this.element.typeCondition, candidate.typeCondition)) {
|
|
1737
|
+
if (optimized instanceof NamedFragmentDefinition) {
|
|
1738
|
+
if ((0, types_1.sameType)(typeCondition, optimized.typeCondition)) {
|
|
1679
1739
|
let spreadDirectives = this.element.appliedDirectives;
|
|
1680
|
-
if (
|
|
1681
|
-
|
|
1682
|
-
if (!isSubset) {
|
|
1683
|
-
continue;
|
|
1684
|
-
}
|
|
1685
|
-
spreadDirectives = difference;
|
|
1740
|
+
if (optimized.appliedDirectives) {
|
|
1741
|
+
spreadDirectives = spreadDirectives.filter((s) => !optimized.appliedDirectives.some((d) => (0, definitions_1.sameDirectiveApplication)(d, s)));
|
|
1686
1742
|
}
|
|
1687
|
-
return
|
|
1688
|
-
spread: new FragmentSpreadSelection(this.parentType, fragments, candidate, spreadDirectives),
|
|
1689
|
-
};
|
|
1743
|
+
return new FragmentSpreadSelection(this.parentType, fragments, optimized, spreadDirectives);
|
|
1690
1744
|
}
|
|
1691
|
-
|
|
1692
|
-
|
|
1745
|
+
else {
|
|
1746
|
+
optimizedSelection = selectionSetOf(typeCondition, new FragmentSpreadSelection(typeCondition, fragments, optimized, []));
|
|
1693
1747
|
}
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
: selectionSetOf(parentType, spread);
|
|
1698
|
-
return { spread, optimizedSelection, hasDiff: !!diff };
|
|
1748
|
+
}
|
|
1749
|
+
else {
|
|
1750
|
+
optimizedSelection = optimized;
|
|
1699
1751
|
}
|
|
1700
1752
|
}
|
|
1701
|
-
|
|
1753
|
+
optimizedSelection = optimizedSelection.optimizeSelections(fragments);
|
|
1754
|
+
return this.selectionSet === optimizedSelection
|
|
1755
|
+
? this
|
|
1756
|
+
: new InlineFragmentSelection(this.element, optimizedSelection);
|
|
1702
1757
|
}
|
|
1703
1758
|
withoutDefer(labelsToRemove) {
|
|
1704
1759
|
const newSelection = this.selectionSet.withoutDefer(labelsToRemove);
|
|
@@ -1778,11 +1833,8 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1778
1833
|
}
|
|
1779
1834
|
return this.selectionSet === trimmedSelectionSet ? this : this.withUpdatedSelectionSet(trimmedSelectionSet);
|
|
1780
1835
|
}
|
|
1781
|
-
|
|
1782
|
-
return this.mapToSelectionSet((s) => s.
|
|
1783
|
-
}
|
|
1784
|
-
expandFragments(names, updatedFragments) {
|
|
1785
|
-
return this.mapToSelectionSet((s) => s.expandFragments(names, updatedFragments));
|
|
1836
|
+
expandFragments(updatedFragments) {
|
|
1837
|
+
return this.mapToSelectionSet((s) => s.expandFragments(updatedFragments));
|
|
1786
1838
|
}
|
|
1787
1839
|
equals(that) {
|
|
1788
1840
|
if (this === that) {
|
|
@@ -1793,22 +1845,15 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1793
1845
|
&& this.selectionSet.equals(that.selectionSet);
|
|
1794
1846
|
}
|
|
1795
1847
|
contains(that) {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1848
|
+
if (!(that instanceof FragmentSelection) || !this.element.equals(that.element)) {
|
|
1849
|
+
return ContainsResult.NOT_CONTAINED;
|
|
1850
|
+
}
|
|
1851
|
+
return this.selectionSet.contains(that.selectionSet);
|
|
1799
1852
|
}
|
|
1800
1853
|
toString(expandFragments = true, indent) {
|
|
1801
1854
|
return (indent !== null && indent !== void 0 ? indent : '') + this.element + ' ' + this.selectionSet.toString(expandFragments, true, indent);
|
|
1802
1855
|
}
|
|
1803
1856
|
}
|
|
1804
|
-
function diffDirectives(superset, maybeSubset) {
|
|
1805
|
-
if (maybeSubset.every((d) => superset.some((s) => (0, definitions_1.sameDirectiveApplication)(d, s)))) {
|
|
1806
|
-
return { isSubset: true, difference: superset.filter((s) => !maybeSubset.some((d) => (0, definitions_1.sameDirectiveApplication)(d, s))) };
|
|
1807
|
-
}
|
|
1808
|
-
else {
|
|
1809
|
-
return { isSubset: false, difference: [] };
|
|
1810
|
-
}
|
|
1811
|
-
}
|
|
1812
1857
|
class FragmentSpreadSelection extends FragmentSelection {
|
|
1813
1858
|
constructor(sourceType, fragments, namedFragment, spreadDirectives) {
|
|
1814
1859
|
super(new FragmentElement(sourceType, namedFragment.typeCondition, namedFragment.appliedDirectives.concat(spreadDirectives)));
|
|
@@ -1816,6 +1861,9 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1816
1861
|
this.namedFragment = namedFragment;
|
|
1817
1862
|
this.spreadDirectives = spreadDirectives;
|
|
1818
1863
|
}
|
|
1864
|
+
isFragmentSpread() {
|
|
1865
|
+
return true;
|
|
1866
|
+
}
|
|
1819
1867
|
get selectionSet() {
|
|
1820
1868
|
return this.namedFragment.selectionSet;
|
|
1821
1869
|
}
|
|
@@ -1829,10 +1877,8 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1829
1877
|
(0, utils_1.assert)(false, `Unsupported`);
|
|
1830
1878
|
}
|
|
1831
1879
|
trimUnsatisfiableBranches(parentType) {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
namedFragments() {
|
|
1835
|
-
return this.fragments;
|
|
1880
|
+
(0, utils_1.assert)(parentType.schema() === this.parentType.schema(), 'Should not try to trim using a type from another schema');
|
|
1881
|
+
return this.rebaseOn(parentType, this.fragments);
|
|
1836
1882
|
}
|
|
1837
1883
|
validate() {
|
|
1838
1884
|
this.validateDeferAndStream();
|
|
@@ -1859,32 +1905,29 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1859
1905
|
optimize(_) {
|
|
1860
1906
|
return this;
|
|
1861
1907
|
}
|
|
1862
|
-
rebaseOn(parentType) {
|
|
1908
|
+
rebaseOn(parentType, fragments) {
|
|
1863
1909
|
if (this.parentType === parentType) {
|
|
1864
1910
|
return this;
|
|
1865
1911
|
}
|
|
1866
|
-
|
|
1912
|
+
(0, utils_1.assert)(fragments || this.parentType.schema() === parentType.schema(), `Must provide fragments is rebasing on other schema`);
|
|
1913
|
+
const newFragments = fragments !== null && fragments !== void 0 ? fragments : this.fragments;
|
|
1914
|
+
const namedFragment = newFragments.get(this.namedFragment.name);
|
|
1915
|
+
(0, utils_1.assert)(namedFragment, () => `Cannot rebase ${this} if it isn't part of the provided fragments`);
|
|
1916
|
+
return new FragmentSpreadSelection(parentType, newFragments, namedFragment, this.spreadDirectives);
|
|
1867
1917
|
}
|
|
1868
1918
|
canAddTo(_) {
|
|
1869
1919
|
return true;
|
|
1870
1920
|
}
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
return (0, types_1.sameType)(this.parentType, this.namedFragment.typeCondition) && this.element.appliedDirectives.length === 0
|
|
1874
|
-
? expandedSubSelections.selections()
|
|
1875
|
-
: new InlineFragmentSelection(this.element, expandedSubSelections);
|
|
1876
|
-
}
|
|
1877
|
-
expandFragments(names, updatedFragments) {
|
|
1878
|
-
if (!names.includes(this.namedFragment.name)) {
|
|
1921
|
+
expandFragments(updatedFragments) {
|
|
1922
|
+
if (updatedFragments === null || updatedFragments === void 0 ? void 0 : updatedFragments.has(this.namedFragment.name)) {
|
|
1879
1923
|
return this;
|
|
1880
1924
|
}
|
|
1881
|
-
const expandedSubSelections = this.selectionSet.expandFragments(
|
|
1925
|
+
const expandedSubSelections = this.selectionSet.expandFragments(updatedFragments);
|
|
1882
1926
|
return (0, types_1.sameType)(this.parentType, this.namedFragment.typeCondition) && this.element.appliedDirectives.length === 0
|
|
1883
1927
|
? expandedSubSelections.selections()
|
|
1884
1928
|
: new InlineFragmentSelection(this.element, expandedSubSelections);
|
|
1885
1929
|
}
|
|
1886
1930
|
collectUsedFragmentNames(collector) {
|
|
1887
|
-
this.selectionSet.collectUsedFragmentNames(collector);
|
|
1888
1931
|
const usageCount = collector.get(this.namedFragment.name);
|
|
1889
1932
|
collector.set(this.namedFragment.name, usageCount === undefined ? 1 : usageCount + 1);
|
|
1890
1933
|
}
|
|
@@ -1908,11 +1951,12 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1908
1951
|
}
|
|
1909
1952
|
contains(that) {
|
|
1910
1953
|
if (this.equals(that)) {
|
|
1911
|
-
return
|
|
1954
|
+
return ContainsResult.EQUAL;
|
|
1912
1955
|
}
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1956
|
+
if (!(that instanceof FragmentSelection) || !this.element.equals(that.element)) {
|
|
1957
|
+
return ContainsResult.NOT_CONTAINED;
|
|
1958
|
+
}
|
|
1959
|
+
return this.selectionSet.contains(that.selectionSet);
|
|
1916
1960
|
}
|
|
1917
1961
|
toString(expandFragments = true, indent) {
|
|
1918
1962
|
if (expandFragments) {
|
|
@@ -1927,7 +1971,7 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1927
1971
|
}
|
|
1928
1972
|
function selectionSetOfNode(parentType, node, variableDefinitions, fragments, fieldAccessor = (type, name) => type.field(name)) {
|
|
1929
1973
|
if (node.selections.length === 1) {
|
|
1930
|
-
return selectionSetOf(parentType, selectionOfNode(parentType, node.selections[0], variableDefinitions, fragments, fieldAccessor)
|
|
1974
|
+
return selectionSetOf(parentType, selectionOfNode(parentType, node.selections[0], variableDefinitions, fragments, fieldAccessor));
|
|
1931
1975
|
}
|
|
1932
1976
|
const selections = new SelectionSetUpdates();
|
|
1933
1977
|
for (const selectionNode of node.selections) {
|
|
@@ -2018,13 +2062,14 @@ function operationFromAST({ schema, operation, variableDefinitions, fragments, v
|
|
|
2018
2062
|
var _a;
|
|
2019
2063
|
const rootType = schema.schemaDefinition.root(operation.operation);
|
|
2020
2064
|
validate(rootType, () => `The schema has no "${operation.operation}" root type defined`);
|
|
2065
|
+
const fragmentsIfAny = fragments.isEmpty() ? undefined : fragments;
|
|
2021
2066
|
return new Operation(schema, operation.operation, parseSelectionSet({
|
|
2022
2067
|
parentType: rootType.type,
|
|
2023
2068
|
source: operation.selectionSet,
|
|
2024
2069
|
variableDefinitions,
|
|
2025
|
-
fragments:
|
|
2070
|
+
fragments: fragmentsIfAny,
|
|
2026
2071
|
validate: validateInput,
|
|
2027
|
-
}), variableDefinitions, (_a = operation.name) === null || _a === void 0 ? void 0 : _a.value);
|
|
2072
|
+
}), variableDefinitions, fragmentsIfAny, (_a = operation.name) === null || _a === void 0 ? void 0 : _a.value);
|
|
2028
2073
|
}
|
|
2029
2074
|
function parseOperation(schema, operation, options) {
|
|
2030
2075
|
return operationFromDocument(schema, (0, graphql_1.parse)(operation), options);
|
|
@@ -2056,8 +2101,8 @@ function operationToDocument(operation) {
|
|
|
2056
2101
|
selectionSet: operation.selectionSet.toSelectionSetNode(),
|
|
2057
2102
|
variableDefinitions: operation.variableDefinitions.toVariableDefinitionNodes(),
|
|
2058
2103
|
};
|
|
2059
|
-
const fragmentASTs = operation.
|
|
2060
|
-
? (_a = operation.
|
|
2104
|
+
const fragmentASTs = operation.fragments
|
|
2105
|
+
? (_a = operation.fragments) === null || _a === void 0 ? void 0 : _a.toFragmentDefinitionNodes()
|
|
2061
2106
|
: [];
|
|
2062
2107
|
return {
|
|
2063
2108
|
kind: graphql_1.Kind.DOCUMENT,
|