@apollo/federation-internals 2.4.7 → 2.4.9
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/coreSpec.js +1 -1
- package/dist/coreSpec.js.map +1 -1
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +3 -0
- package/dist/definitions.js.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
- package/dist/extractSubgraphsFromSupergraph.js +25 -7
- package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
- package/dist/federationSpec.js +2 -2
- package/dist/federationSpec.js.map +1 -1
- package/dist/operations.d.ts +108 -32
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +462 -173
- package/dist/operations.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/definitions.ts +4 -0
- package/src/extractSubgraphsFromSupergraph.ts +36 -10
- package/src/operations.ts +844 -296
- package/src/types.ts +22 -1
package/dist/operations.js
CHANGED
|
@@ -25,6 +25,9 @@ class AbstractOperationElement extends definitions_1.DirectiveTargetElement {
|
|
|
25
25
|
this.collectVariablesInElement(collector);
|
|
26
26
|
this.collectVariablesInAppliedDirectives(collector);
|
|
27
27
|
}
|
|
28
|
+
rebaseOnOrError(parentType) {
|
|
29
|
+
return this.rebaseOn({ parentType, errorIfCannotRebase: true });
|
|
30
|
+
}
|
|
28
31
|
addAttachement(key, value) {
|
|
29
32
|
if (!this.attachements) {
|
|
30
33
|
this.attachements = new Map();
|
|
@@ -162,7 +165,7 @@ class Field extends AbstractOperationElement {
|
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
167
|
}
|
|
165
|
-
rebaseOn(parentType) {
|
|
168
|
+
rebaseOn({ parentType, errorIfCannotRebase }) {
|
|
166
169
|
const fieldParent = this.definition.parent;
|
|
167
170
|
if (parentType === fieldParent) {
|
|
168
171
|
return this;
|
|
@@ -170,9 +173,12 @@ class Field extends AbstractOperationElement {
|
|
|
170
173
|
if (this.name === definitions_1.typenameFieldName) {
|
|
171
174
|
return this.withUpdatedDefinition(parentType.typenameField());
|
|
172
175
|
}
|
|
173
|
-
validate(this.canRebaseOn(parentType), () => `Cannot add selection of field "${this.definition.coordinate}" to selection set of parent type "${parentType}"`);
|
|
174
176
|
const fieldDef = parentType.field(this.name);
|
|
175
|
-
|
|
177
|
+
const canRebase = this.canRebaseOn(parentType) && fieldDef;
|
|
178
|
+
if (!canRebase) {
|
|
179
|
+
validate(!errorIfCannotRebase, () => `Cannot add selection of field "${this.definition.coordinate}" to selection set of parent type "${parentType}"`);
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
176
182
|
return this.withUpdatedDefinition(fieldDef);
|
|
177
183
|
}
|
|
178
184
|
canRebaseOn(parentType) {
|
|
@@ -276,14 +282,17 @@ class FragmentElement extends AbstractOperationElement {
|
|
|
276
282
|
this.copyAttachementsTo(newFragment);
|
|
277
283
|
return newFragment;
|
|
278
284
|
}
|
|
279
|
-
rebaseOn(parentType) {
|
|
285
|
+
rebaseOn({ parentType, errorIfCannotRebase }) {
|
|
280
286
|
const fragmentParent = this.parentType;
|
|
281
287
|
const typeCondition = this.typeCondition;
|
|
282
288
|
if (parentType === fragmentParent) {
|
|
283
289
|
return this;
|
|
284
290
|
}
|
|
285
291
|
const { canRebase, rebasedCondition } = this.canRebaseOn(parentType);
|
|
286
|
-
|
|
292
|
+
if (!canRebase) {
|
|
293
|
+
validate(!errorIfCannotRebase, () => `Cannot add fragment of condition "${typeCondition}" (runtimes: [${(0, definitions_1.possibleRuntimeTypes)(typeCondition)}]) to parent type "${parentType}" (runtimes: ${(0, definitions_1.possibleRuntimeTypes)(parentType)})`);
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
287
296
|
return this.withUpdatedTypes(parentType, rebasedCondition);
|
|
288
297
|
}
|
|
289
298
|
canRebaseOn(parentType) {
|
|
@@ -527,6 +536,18 @@ class Operation {
|
|
|
527
536
|
this.fragments = fragments;
|
|
528
537
|
this.name = name;
|
|
529
538
|
}
|
|
539
|
+
withUpdatedSelectionSet(newSelectionSet) {
|
|
540
|
+
if (this.selectionSet === newSelectionSet) {
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
543
|
+
return new Operation(this.schema, this.rootKind, newSelectionSet, this.variableDefinitions, this.fragments, this.name);
|
|
544
|
+
}
|
|
545
|
+
withUpdatedSelectionSetAndFragments(newSelectionSet, newFragments) {
|
|
546
|
+
if (this.selectionSet === newSelectionSet && newFragments === this.fragments) {
|
|
547
|
+
return this;
|
|
548
|
+
}
|
|
549
|
+
return new Operation(this.schema, this.rootKind, newSelectionSet, this.variableDefinitions, newFragments, this.name);
|
|
550
|
+
}
|
|
530
551
|
optimize(fragments, minUsagesToOptimize = 2) {
|
|
531
552
|
(0, utils_1.assert)(minUsagesToOptimize >= 1, `Expected 'minUsagesToOptimize' to be at least 1, but got ${minUsagesToOptimize}`);
|
|
532
553
|
if (!fragments || fragments.isEmpty()) {
|
|
@@ -536,41 +557,39 @@ class Operation {
|
|
|
536
557
|
if (optimizedSelection === this.selectionSet) {
|
|
537
558
|
return this;
|
|
538
559
|
}
|
|
539
|
-
|
|
540
|
-
if (finalFragments
|
|
541
|
-
|
|
560
|
+
let finalFragments = computeFragmentsToKeep(optimizedSelection, fragments, minUsagesToOptimize);
|
|
561
|
+
if (finalFragments !== null && (finalFragments === null || finalFragments === void 0 ? void 0 : finalFragments.size) !== fragments.size) {
|
|
562
|
+
optimizedSelection = optimizedSelection.expandFragments(finalFragments);
|
|
563
|
+
optimizedSelection = optimizedSelection.normalize({ parentType: optimizedSelection.parentType });
|
|
564
|
+
if (finalFragments) {
|
|
565
|
+
let beforeRemoval;
|
|
566
|
+
do {
|
|
567
|
+
beforeRemoval = finalFragments;
|
|
568
|
+
const usages = new Map();
|
|
569
|
+
optimizedSelection.collectUsedFragmentNames(usages);
|
|
570
|
+
finalFragments.collectUsedFragmentNames(usages);
|
|
571
|
+
finalFragments = finalFragments.filter((f) => { var _a; return ((_a = usages.get(f.name)) !== null && _a !== void 0 ? _a : 0) > 0; });
|
|
572
|
+
} while (finalFragments && finalFragments.size < beforeRemoval.size);
|
|
573
|
+
}
|
|
542
574
|
}
|
|
543
|
-
|
|
544
|
-
optimizedSelection = optimizedSelection.trimUnsatisfiableBranches(optimizedSelection.parentType);
|
|
545
|
-
return new Operation(this.schema, this.rootKind, optimizedSelection, this.variableDefinitions, finalFragments, this.name);
|
|
575
|
+
return this.withUpdatedSelectionSetAndFragments(optimizedSelection, finalFragments !== null && finalFragments !== void 0 ? finalFragments : undefined);
|
|
546
576
|
}
|
|
547
577
|
expandAllFragments() {
|
|
548
|
-
const
|
|
549
|
-
|
|
550
|
-
return this;
|
|
551
|
-
}
|
|
552
|
-
return new Operation(this.schema, this.rootKind, expandedSelections, this.variableDefinitions, undefined, this.name);
|
|
578
|
+
const expanded = this.selectionSet.expandFragments();
|
|
579
|
+
return this.withUpdatedSelectionSetAndFragments(expanded.normalize({ parentType: expanded.parentType }), undefined);
|
|
553
580
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
if (trimmedSelections === this.selectionSet) {
|
|
557
|
-
return this;
|
|
558
|
-
}
|
|
559
|
-
return new Operation(this.schema, this.rootKind, trimmedSelections, this.variableDefinitions, this.fragments, this.name);
|
|
581
|
+
normalize() {
|
|
582
|
+
return this.withUpdatedSelectionSet(this.selectionSet.normalize({ parentType: this.selectionSet.parentType }));
|
|
560
583
|
}
|
|
561
584
|
withoutDefer(labelsToRemove) {
|
|
562
|
-
|
|
563
|
-
return updated == this.selectionSet
|
|
564
|
-
? this
|
|
565
|
-
: new Operation(this.schema, this.rootKind, updated, this.variableDefinitions, this.fragments, this.name);
|
|
585
|
+
return this.withUpdatedSelectionSet(this.selectionSet.withoutDefer(labelsToRemove));
|
|
566
586
|
}
|
|
567
587
|
withNormalizedDefer() {
|
|
568
588
|
const normalizer = new DeferNormalizer();
|
|
569
589
|
const { hasDefers, hasNonLabelledOrConditionalDefers } = normalizer.init(this.selectionSet);
|
|
570
590
|
let updatedOperation = this;
|
|
571
591
|
if (hasNonLabelledOrConditionalDefers) {
|
|
572
|
-
|
|
573
|
-
updatedOperation = new Operation(this.schema, this.rootKind, updated, this.variableDefinitions, this.fragments, this.name);
|
|
592
|
+
updatedOperation = this.withUpdatedSelectionSet(this.selectionSet.withNormalizedDefer(normalizer));
|
|
574
593
|
}
|
|
575
594
|
return {
|
|
576
595
|
operation: updatedOperation,
|
|
@@ -612,7 +631,7 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
612
631
|
}
|
|
613
632
|
expandedSelectionSet() {
|
|
614
633
|
if (!this._expandedSelectionSet) {
|
|
615
|
-
this._expandedSelectionSet = this.selectionSet.expandFragments().
|
|
634
|
+
this._expandedSelectionSet = this.selectionSet.expandFragments().normalize({ parentType: this.typeCondition });
|
|
616
635
|
}
|
|
617
636
|
return this._expandedSelectionSet;
|
|
618
637
|
}
|
|
@@ -650,7 +669,7 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
650
669
|
selectionSet: this.selectionSet.toSelectionSetNode()
|
|
651
670
|
};
|
|
652
671
|
}
|
|
653
|
-
|
|
672
|
+
canApplyDirectlyAtType(type) {
|
|
654
673
|
if ((0, types_1.sameType)(type, this.typeCondition)) {
|
|
655
674
|
return true;
|
|
656
675
|
}
|
|
@@ -659,23 +678,29 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
659
678
|
}
|
|
660
679
|
const conditionRuntimes = (0, definitions_1.possibleRuntimeTypes)(this.typeCondition);
|
|
661
680
|
const typeRuntimes = (0, definitions_1.possibleRuntimeTypes)(type);
|
|
662
|
-
|
|
663
|
-
|
|
681
|
+
if (conditionRuntimes.length < typeRuntimes.length
|
|
682
|
+
|| !typeRuntimes.every((t1) => conditionRuntimes.some((t2) => (0, types_1.sameType)(t1, t2)))) {
|
|
683
|
+
return false;
|
|
684
|
+
}
|
|
685
|
+
return (0, definitions_1.isObjectType)(type) || (0, definitions_1.isUnionType)(this.typeCondition);
|
|
664
686
|
}
|
|
665
687
|
expandedSelectionSetAtType(type) {
|
|
666
|
-
const expandedSelectionSet = this.expandedSelectionSet();
|
|
667
688
|
if ((0, types_1.sameType)(type, this.typeCondition) || (0, definitions_1.isObjectType)(this.typeCondition)) {
|
|
668
|
-
return expandedSelectionSet;
|
|
669
|
-
}
|
|
670
|
-
if (!(0, definitions_1.isObjectType)(type)) {
|
|
671
|
-
return expandedSelectionSet;
|
|
689
|
+
return { selectionSet: this.expandedSelectionSet() };
|
|
672
690
|
}
|
|
673
|
-
let
|
|
674
|
-
if (!
|
|
675
|
-
|
|
676
|
-
this.expandedSelectionSetsAtTypesCache.set(type.name,
|
|
691
|
+
let cached = this.expandedSelectionSetsAtTypesCache.get(type.name);
|
|
692
|
+
if (!cached) {
|
|
693
|
+
cached = this.computeExpandedSelectionSetAtType(type);
|
|
694
|
+
this.expandedSelectionSetsAtTypesCache.set(type.name, cached);
|
|
677
695
|
}
|
|
678
|
-
return
|
|
696
|
+
return cached;
|
|
697
|
+
}
|
|
698
|
+
computeExpandedSelectionSetAtType(type) {
|
|
699
|
+
const expandedSelectionSet = this.expandedSelectionSet();
|
|
700
|
+
const selectionSet = expandedSelectionSet.normalize({ parentType: type, recursive: false });
|
|
701
|
+
const trimmed = expandedSelectionSet.minus(selectionSet);
|
|
702
|
+
const validator = trimmed.isEmpty() ? undefined : FieldsConflictValidator.build(trimmed);
|
|
703
|
+
return { selectionSet, validator };
|
|
679
704
|
}
|
|
680
705
|
includes(otherFragment) {
|
|
681
706
|
if (this.name === otherFragment) {
|
|
@@ -696,7 +721,7 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
696
721
|
return included;
|
|
697
722
|
}
|
|
698
723
|
toString(indent) {
|
|
699
|
-
return
|
|
724
|
+
return `fragment ${this.name} on ${this.typeCondition}${this.appliedDirectivesToString()} ${this.selectionSet.toString(false, true, indent)}`;
|
|
700
725
|
}
|
|
701
726
|
}
|
|
702
727
|
exports.NamedFragmentDefinition = NamedFragmentDefinition;
|
|
@@ -724,8 +749,8 @@ class NamedFragments {
|
|
|
724
749
|
this.fragments.set(fragment.name, fragment);
|
|
725
750
|
}
|
|
726
751
|
}
|
|
727
|
-
|
|
728
|
-
return this.fragments.values().filter(f => f.
|
|
752
|
+
maybeApplyingDirectlyAtType(type) {
|
|
753
|
+
return this.fragments.values().filter(f => f.canApplyDirectlyAtType(type));
|
|
729
754
|
}
|
|
730
755
|
get(name) {
|
|
731
756
|
return this.fragments.get(name);
|
|
@@ -736,6 +761,11 @@ class NamedFragments {
|
|
|
736
761
|
definitions() {
|
|
737
762
|
return this.fragments.values();
|
|
738
763
|
}
|
|
764
|
+
collectUsedFragmentNames(collector) {
|
|
765
|
+
for (const fragment of this.definitions()) {
|
|
766
|
+
fragment.collectUsedFragmentNames(collector);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
739
769
|
map(mapper) {
|
|
740
770
|
const mapped = new NamedFragments();
|
|
741
771
|
for (const def of this.fragments.values()) {
|
|
@@ -772,7 +802,7 @@ class NamedFragments {
|
|
|
772
802
|
}
|
|
773
803
|
mapToExpandedSelectionSets(mapper) {
|
|
774
804
|
return this.mapInDependencyOrder((fragment, newFragments) => {
|
|
775
|
-
const mappedSelectionSet = mapper(fragment.selectionSet.expandFragments().
|
|
805
|
+
const mappedSelectionSet = mapper(fragment.selectionSet.expandFragments().normalize({ parentType: fragment.typeCondition }));
|
|
776
806
|
if (!mappedSelectionSet) {
|
|
777
807
|
return undefined;
|
|
778
808
|
}
|
|
@@ -780,19 +810,28 @@ class NamedFragments {
|
|
|
780
810
|
return fragment.withUpdatedSelectionSet(reoptimizedSelectionSet);
|
|
781
811
|
});
|
|
782
812
|
}
|
|
813
|
+
selectionSetIsWorthUsing(selectionSet) {
|
|
814
|
+
const selections = selectionSet.selections();
|
|
815
|
+
if (selections.length === 0) {
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
818
|
+
if (selections.length === 1) {
|
|
819
|
+
const s = selections[0];
|
|
820
|
+
return !(s.kind === 'FieldSelection' && s.element.isLeafField());
|
|
821
|
+
}
|
|
822
|
+
return true;
|
|
823
|
+
}
|
|
783
824
|
rebaseOn(schema) {
|
|
784
825
|
return this.mapInDependencyOrder((fragment, newFragments) => {
|
|
785
826
|
const rebasedType = schema.type(fragment.selectionSet.parentType.name);
|
|
786
|
-
|
|
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);
|
|
792
|
-
}
|
|
793
|
-
catch (e) {
|
|
827
|
+
if (!rebasedType || !(0, definitions_1.isCompositeType)(rebasedType)) {
|
|
794
828
|
return undefined;
|
|
795
829
|
}
|
|
830
|
+
const rebasedSelection = fragment.selectionSet.rebaseOn({ parentType: rebasedType, fragments: newFragments, errorIfCannotRebase: false });
|
|
831
|
+
return this.selectionSetIsWorthUsing(rebasedSelection)
|
|
832
|
+
? new NamedFragmentDefinition(schema, fragment.name, rebasedType).setSelectionSet(rebasedSelection)
|
|
833
|
+
: undefined;
|
|
834
|
+
;
|
|
796
835
|
});
|
|
797
836
|
}
|
|
798
837
|
filter(predicate) {
|
|
@@ -872,7 +911,7 @@ var ContainsResult;
|
|
|
872
911
|
ContainsResult[ContainsResult["NOT_CONTAINED"] = 0] = "NOT_CONTAINED";
|
|
873
912
|
ContainsResult[ContainsResult["STRICTLY_CONTAINED"] = 1] = "STRICTLY_CONTAINED";
|
|
874
913
|
ContainsResult[ContainsResult["EQUAL"] = 2] = "EQUAL";
|
|
875
|
-
})(ContainsResult
|
|
914
|
+
})(ContainsResult || (exports.ContainsResult = ContainsResult = {}));
|
|
876
915
|
class SelectionSet {
|
|
877
916
|
constructor(parentType, keyedSelections = new Map()) {
|
|
878
917
|
this.parentType = parentType;
|
|
@@ -893,6 +932,18 @@ class SelectionSet {
|
|
|
893
932
|
hasTopLevelTypenameField() {
|
|
894
933
|
return this._keyedSelections.has(definitions_1.typenameFieldName);
|
|
895
934
|
}
|
|
935
|
+
withoutTopLevelTypenameField() {
|
|
936
|
+
if (!this.hasTopLevelTypenameField) {
|
|
937
|
+
return this;
|
|
938
|
+
}
|
|
939
|
+
const newKeyedSelections = new Map();
|
|
940
|
+
for (const [key, selection] of this._keyedSelections) {
|
|
941
|
+
if (key !== definitions_1.typenameFieldName) {
|
|
942
|
+
newKeyedSelections.set(key, selection);
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
return new SelectionSet(this.parentType, newKeyedSelections);
|
|
946
|
+
}
|
|
896
947
|
fieldsInSet() {
|
|
897
948
|
const fields = new Array();
|
|
898
949
|
for (const selection of this.selections()) {
|
|
@@ -909,6 +960,21 @@ class SelectionSet {
|
|
|
909
960
|
}
|
|
910
961
|
return fields;
|
|
911
962
|
}
|
|
963
|
+
fieldsByResponseName() {
|
|
964
|
+
const byResponseName = new utils_1.MultiMap();
|
|
965
|
+
this.collectFieldsByResponseName(byResponseName);
|
|
966
|
+
return byResponseName;
|
|
967
|
+
}
|
|
968
|
+
collectFieldsByResponseName(collector) {
|
|
969
|
+
for (const selection of this.selections()) {
|
|
970
|
+
if (selection.kind === 'FieldSelection') {
|
|
971
|
+
collector.add(selection.element.responseName(), selection);
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
selection.selectionSet.collectFieldsByResponseName(collector);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
}
|
|
912
978
|
usedVariables() {
|
|
913
979
|
const collector = new definitions_1.VariableCollector();
|
|
914
980
|
this.collectVariables(collector);
|
|
@@ -929,19 +995,20 @@ class SelectionSet {
|
|
|
929
995
|
return this;
|
|
930
996
|
}
|
|
931
997
|
const wrapped = new InlineFragmentSelection(new FragmentElement(this.parentType, this.parentType), this);
|
|
932
|
-
const
|
|
998
|
+
const validator = FieldsConflictMultiBranchValidator.ofInitial(FieldsConflictValidator.build(this));
|
|
999
|
+
const optimized = wrapped.optimize(fragments, validator);
|
|
933
1000
|
return optimized instanceof FragmentSpreadSelection
|
|
934
1001
|
? selectionSetOf(this.parentType, optimized)
|
|
935
1002
|
: optimized.selectionSet;
|
|
936
1003
|
}
|
|
937
|
-
optimizeSelections(fragments) {
|
|
938
|
-
return this.lazyMap((selection) => selection.optimize(fragments));
|
|
1004
|
+
optimizeSelections(fragments, validator) {
|
|
1005
|
+
return this.lazyMap((selection) => selection.optimize(fragments, validator));
|
|
939
1006
|
}
|
|
940
1007
|
expandFragments(updatedFragments) {
|
|
941
1008
|
return this.lazyMap((selection) => selection.expandFragments(updatedFragments));
|
|
942
1009
|
}
|
|
943
|
-
|
|
944
|
-
return this.lazyMap((selection) => selection.
|
|
1010
|
+
normalize({ parentType, recursive }) {
|
|
1011
|
+
return this.lazyMap((selection) => selection.normalize({ parentType, recursive }), { parentType });
|
|
945
1012
|
}
|
|
946
1013
|
lazyMap(mapper, options) {
|
|
947
1014
|
var _a;
|
|
@@ -975,19 +1042,25 @@ class SelectionSet {
|
|
|
975
1042
|
return this.selections().some((s) => s.hasDefer());
|
|
976
1043
|
}
|
|
977
1044
|
filter(predicate) {
|
|
978
|
-
return this.lazyMap((selection) => selection
|
|
1045
|
+
return this.lazyMap((selection) => predicate(selection) ? selection : undefined);
|
|
1046
|
+
}
|
|
1047
|
+
filterRecursiveDepthFirst(predicate) {
|
|
1048
|
+
return this.lazyMap((selection) => selection.filterRecursiveDepthFirst(predicate));
|
|
979
1049
|
}
|
|
980
1050
|
withoutEmptyBranches() {
|
|
981
|
-
const updated = this.
|
|
1051
|
+
const updated = this.filterRecursiveDepthFirst((selection) => { var _a; return ((_a = selection.selectionSet) === null || _a === void 0 ? void 0 : _a.isEmpty()) !== true; });
|
|
982
1052
|
return updated.isEmpty() ? undefined : updated;
|
|
983
1053
|
}
|
|
984
|
-
rebaseOn(parentType, fragments) {
|
|
1054
|
+
rebaseOn({ parentType, fragments, errorIfCannotRebase, }) {
|
|
985
1055
|
if (this.parentType === parentType) {
|
|
986
1056
|
return this;
|
|
987
1057
|
}
|
|
988
1058
|
const newSelections = new Map();
|
|
989
1059
|
for (const selection of this.selections()) {
|
|
990
|
-
|
|
1060
|
+
const rebasedSelection = selection.rebaseOn({ parentType, fragments, errorIfCannotRebase });
|
|
1061
|
+
if (rebasedSelection) {
|
|
1062
|
+
newSelections.set(selection.key(), rebasedSelection);
|
|
1063
|
+
}
|
|
991
1064
|
}
|
|
992
1065
|
return new SelectionSet(parentType, newSelections);
|
|
993
1066
|
}
|
|
@@ -1006,14 +1079,21 @@ class SelectionSet {
|
|
|
1006
1079
|
}
|
|
1007
1080
|
return true;
|
|
1008
1081
|
}
|
|
1009
|
-
contains(that) {
|
|
1082
|
+
contains(that, options) {
|
|
1083
|
+
var _a;
|
|
1084
|
+
const ignoreMissingTypename = (_a = options === null || options === void 0 ? void 0 : options.ignoreMissingTypename) !== null && _a !== void 0 ? _a : false;
|
|
1010
1085
|
if (that._selections.length > this._selections.length) {
|
|
1011
|
-
|
|
1086
|
+
if (!ignoreMissingTypename || that._selections.length > this._selections.length + 1 || this.hasTopLevelTypenameField() || !that.hasTopLevelTypenameField()) {
|
|
1087
|
+
return ContainsResult.NOT_CONTAINED;
|
|
1088
|
+
}
|
|
1012
1089
|
}
|
|
1013
1090
|
let isEqual = true;
|
|
1014
1091
|
for (const [key, thatSelection] of that._keyedSelections) {
|
|
1092
|
+
if (key === definitions_1.typenameFieldName && ignoreMissingTypename) {
|
|
1093
|
+
continue;
|
|
1094
|
+
}
|
|
1015
1095
|
const thisSelection = this._keyedSelections.get(key);
|
|
1016
|
-
const selectionResult = thisSelection === null || thisSelection === void 0 ? void 0 : thisSelection.contains(thatSelection);
|
|
1096
|
+
const selectionResult = thisSelection === null || thisSelection === void 0 ? void 0 : thisSelection.contains(thatSelection, options);
|
|
1017
1097
|
if (selectionResult === undefined || selectionResult === ContainsResult.NOT_CONTAINED) {
|
|
1018
1098
|
return ContainsResult.NOT_CONTAINED;
|
|
1019
1099
|
}
|
|
@@ -1023,20 +1103,9 @@ class SelectionSet {
|
|
|
1023
1103
|
? ContainsResult.EQUAL
|
|
1024
1104
|
: ContainsResult.STRICTLY_CONTAINED;
|
|
1025
1105
|
}
|
|
1026
|
-
|
|
1027
|
-
const
|
|
1028
|
-
|
|
1029
|
-
return { contains: false };
|
|
1030
|
-
}
|
|
1031
|
-
if (this.contains(that)) {
|
|
1032
|
-
let updatedThis = this.expandFragments(fragments.filter((f) => f.name !== candidate.name));
|
|
1033
|
-
if (updatedThis !== this) {
|
|
1034
|
-
updatedThis = updatedThis.trimUnsatisfiableBranches(parentType);
|
|
1035
|
-
}
|
|
1036
|
-
const diff = updatedThis.minus(that);
|
|
1037
|
-
return { contains: true, diff: diff.isEmpty() ? undefined : diff };
|
|
1038
|
-
}
|
|
1039
|
-
return { contains: false };
|
|
1106
|
+
containsTopLevelField(field) {
|
|
1107
|
+
const selection = this._keyedSelections.get(field.key());
|
|
1108
|
+
return !!selection && selection.element.equals(field);
|
|
1040
1109
|
}
|
|
1041
1110
|
minus(that) {
|
|
1042
1111
|
const updated = new SelectionSetUpdates();
|
|
@@ -1054,6 +1123,25 @@ class SelectionSet {
|
|
|
1054
1123
|
}
|
|
1055
1124
|
return updated.toSelectionSet(this.parentType);
|
|
1056
1125
|
}
|
|
1126
|
+
intersectionWith(that) {
|
|
1127
|
+
if (this.isEmpty()) {
|
|
1128
|
+
return this;
|
|
1129
|
+
}
|
|
1130
|
+
if (that.isEmpty()) {
|
|
1131
|
+
return that;
|
|
1132
|
+
}
|
|
1133
|
+
const intersection = new SelectionSetUpdates();
|
|
1134
|
+
for (const [key, thisSelection] of this._keyedSelections) {
|
|
1135
|
+
const thatSelection = that._keyedSelections.get(key);
|
|
1136
|
+
if (thatSelection) {
|
|
1137
|
+
const selection = thisSelection.intersectionWith(thatSelection);
|
|
1138
|
+
if (selection) {
|
|
1139
|
+
intersection.add(selection);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
return intersection.toSelectionSet(this.parentType);
|
|
1144
|
+
}
|
|
1057
1145
|
canRebaseOn(parentTypeToTest) {
|
|
1058
1146
|
return this.selections().every((selection) => selection.canAddTo(parentTypeToTest));
|
|
1059
1147
|
}
|
|
@@ -1196,6 +1284,16 @@ class SelectionSetUpdates {
|
|
|
1196
1284
|
toSelectionSet(parentType, fragments) {
|
|
1197
1285
|
return makeSelectionSet(parentType, this.keyedUpdates, fragments);
|
|
1198
1286
|
}
|
|
1287
|
+
toString() {
|
|
1288
|
+
return '{\n'
|
|
1289
|
+
+ [...this.keyedUpdates.entries()].map(([k, updates]) => {
|
|
1290
|
+
const updStr = updates.map((upd) => upd instanceof AbstractSelection
|
|
1291
|
+
? upd.toString()
|
|
1292
|
+
: `${upd.path} -> ${upd.selections}`);
|
|
1293
|
+
return ` - ${k}: ${updStr}`;
|
|
1294
|
+
}).join('\n')
|
|
1295
|
+
+ '\n\}';
|
|
1296
|
+
}
|
|
1199
1297
|
}
|
|
1200
1298
|
exports.SelectionSetUpdates = SelectionSetUpdates;
|
|
1201
1299
|
function addToKeyedUpdates(keyedUpdates, selections) {
|
|
@@ -1260,9 +1358,9 @@ function makeSelection(parentType, updates, fragments) {
|
|
|
1260
1358
|
(0, utils_1.assert)(updates.length > 0, 'Should not be called without any updates');
|
|
1261
1359
|
const first = updates[0];
|
|
1262
1360
|
if (updates.length === 1 && first instanceof AbstractSelection) {
|
|
1263
|
-
return first.
|
|
1361
|
+
return first.rebaseOnOrError({ parentType, fragments });
|
|
1264
1362
|
}
|
|
1265
|
-
const element = updateElement(first).
|
|
1363
|
+
const element = updateElement(first).rebaseOnOrError(parentType);
|
|
1266
1364
|
const subSelectionParentType = element.kind === 'Field' ? element.baseType() : element.castedType();
|
|
1267
1365
|
if (!(0, definitions_1.isCompositeType)(subSelectionParentType)) {
|
|
1268
1366
|
return selectionOfElement(element);
|
|
@@ -1393,6 +1491,9 @@ class AbstractSelection {
|
|
|
1393
1491
|
constructor(element) {
|
|
1394
1492
|
this.element = element;
|
|
1395
1493
|
}
|
|
1494
|
+
rebaseOnOrError({ parentType, fragments }) {
|
|
1495
|
+
return this.rebaseOn({ parentType, fragments, errorIfCannotRebase: true });
|
|
1496
|
+
}
|
|
1396
1497
|
get parentType() {
|
|
1397
1498
|
return this.element.parentType;
|
|
1398
1499
|
}
|
|
@@ -1435,40 +1536,200 @@ class AbstractSelection {
|
|
|
1435
1536
|
}
|
|
1436
1537
|
return undefined;
|
|
1437
1538
|
}
|
|
1438
|
-
|
|
1439
|
-
|
|
1539
|
+
intersectionWith(that) {
|
|
1540
|
+
if (this.selectionSet && that.selectionSet) {
|
|
1541
|
+
const subSelectionSetIntersection = this.selectionSet.intersectionWith(that.selectionSet);
|
|
1542
|
+
if (subSelectionSetIntersection.isEmpty()) {
|
|
1543
|
+
return undefined;
|
|
1544
|
+
}
|
|
1545
|
+
else {
|
|
1546
|
+
return this.withUpdatedSelectionSet(subSelectionSetIntersection);
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
else {
|
|
1550
|
+
return this.us();
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
tryOptimizeSubselectionWithFragments({ parentType, subSelection, fragments, validator, canUseFullMatchingFragment, }) {
|
|
1554
|
+
let candidates = fragments.maybeApplyingDirectlyAtType(parentType);
|
|
1555
|
+
if (candidates.length === 0) {
|
|
1556
|
+
return subSelection;
|
|
1557
|
+
}
|
|
1440
1558
|
const applyingFragments = [];
|
|
1441
1559
|
for (const candidate of candidates) {
|
|
1442
|
-
|
|
1443
|
-
if (
|
|
1560
|
+
let atType = candidate.expandedSelectionSetAtType(parentType);
|
|
1561
|
+
if (atType.selectionSet.isEmpty() || (atType.selectionSet.selections().length === 1 && atType.selectionSet.selections()[0].isTypenameField())) {
|
|
1444
1562
|
continue;
|
|
1445
1563
|
}
|
|
1446
|
-
const res = subSelection.contains(
|
|
1564
|
+
const res = subSelection.contains(atType.selectionSet, { ignoreMissingTypename: true });
|
|
1447
1565
|
if (res === ContainsResult.EQUAL) {
|
|
1448
1566
|
if (canUseFullMatchingFragment(candidate)) {
|
|
1567
|
+
if (!validator.checkCanReuseFragmentAndTrackIt(atType)) {
|
|
1568
|
+
continue;
|
|
1569
|
+
}
|
|
1449
1570
|
return candidate;
|
|
1450
1571
|
}
|
|
1451
1572
|
if (candidate.appliedDirectives.length === 0) {
|
|
1452
|
-
applyingFragments.push(candidate);
|
|
1573
|
+
applyingFragments.push({ fragment: candidate, atType });
|
|
1453
1574
|
}
|
|
1454
1575
|
}
|
|
1455
1576
|
else if (res === ContainsResult.STRICTLY_CONTAINED && candidate.appliedDirectives.length === 0) {
|
|
1456
|
-
applyingFragments.push(candidate);
|
|
1577
|
+
applyingFragments.push({ fragment: candidate, atType });
|
|
1457
1578
|
}
|
|
1458
1579
|
}
|
|
1459
1580
|
if (applyingFragments.length === 0) {
|
|
1460
1581
|
return subSelection;
|
|
1461
1582
|
}
|
|
1462
|
-
const filteredApplyingFragments = applyingFragments.filter((
|
|
1583
|
+
const filteredApplyingFragments = applyingFragments.filter(({ fragment }) => !applyingFragments.some((o) => o.fragment.includes(fragment.name)));
|
|
1463
1584
|
let notCoveredByFragments = subSelection;
|
|
1464
1585
|
const optimized = new SelectionSetUpdates();
|
|
1465
|
-
for (const fragment of filteredApplyingFragments) {
|
|
1466
|
-
|
|
1586
|
+
for (const { fragment, atType } of filteredApplyingFragments) {
|
|
1587
|
+
if (!validator.checkCanReuseFragmentAndTrackIt(atType)) {
|
|
1588
|
+
continue;
|
|
1589
|
+
}
|
|
1590
|
+
const notCovered = subSelection.minus(atType.selectionSet);
|
|
1591
|
+
notCoveredByFragments = notCoveredByFragments.intersectionWith(notCovered);
|
|
1467
1592
|
optimized.add(new FragmentSpreadSelection(parentType, fragments, fragment, []));
|
|
1468
1593
|
}
|
|
1469
1594
|
return optimized.add(notCoveredByFragments).toSelectionSet(parentType, fragments);
|
|
1470
1595
|
}
|
|
1471
1596
|
}
|
|
1597
|
+
class FieldsConflictMultiBranchValidator {
|
|
1598
|
+
constructor(validators) {
|
|
1599
|
+
this.validators = validators;
|
|
1600
|
+
}
|
|
1601
|
+
static ofInitial(validator) {
|
|
1602
|
+
return new FieldsConflictMultiBranchValidator([validator]);
|
|
1603
|
+
}
|
|
1604
|
+
forField(field) {
|
|
1605
|
+
const forAllBranches = this.validators.flatMap((vs) => vs.forField(field));
|
|
1606
|
+
(0, utils_1.assert)(forAllBranches.length > 0, `Shoud have found at least one validator for ${field}`);
|
|
1607
|
+
return new FieldsConflictMultiBranchValidator(forAllBranches);
|
|
1608
|
+
}
|
|
1609
|
+
checkCanReuseFragmentAndTrackIt(fragment) {
|
|
1610
|
+
const validator = fragment.validator;
|
|
1611
|
+
if (!validator) {
|
|
1612
|
+
return true;
|
|
1613
|
+
}
|
|
1614
|
+
if (!this.validators.every((v) => v.doMergeWith(validator))) {
|
|
1615
|
+
return false;
|
|
1616
|
+
}
|
|
1617
|
+
if (this.usedSpreadTrimmedPartAtLevel) {
|
|
1618
|
+
if (!this.usedSpreadTrimmedPartAtLevel.every((t) => validator.doMergeWith(t))) {
|
|
1619
|
+
return false;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
else {
|
|
1623
|
+
this.usedSpreadTrimmedPartAtLevel = [];
|
|
1624
|
+
}
|
|
1625
|
+
this.usedSpreadTrimmedPartAtLevel.push(validator);
|
|
1626
|
+
return true;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
class FieldsConflictValidator {
|
|
1630
|
+
constructor(byResponseName) {
|
|
1631
|
+
this.byResponseName = byResponseName;
|
|
1632
|
+
}
|
|
1633
|
+
static build(s) {
|
|
1634
|
+
return FieldsConflictValidator.forLevel(s.fieldsInSet());
|
|
1635
|
+
}
|
|
1636
|
+
static forLevel(level) {
|
|
1637
|
+
var _a;
|
|
1638
|
+
const atLevel = new Map();
|
|
1639
|
+
for (const { field } of level) {
|
|
1640
|
+
const responseName = field.element.responseName();
|
|
1641
|
+
let atResponseName = atLevel.get(responseName);
|
|
1642
|
+
if (!atResponseName) {
|
|
1643
|
+
atResponseName = new Map();
|
|
1644
|
+
atLevel.set(responseName, atResponseName);
|
|
1645
|
+
}
|
|
1646
|
+
if (field.selectionSet) {
|
|
1647
|
+
let forField = (_a = atResponseName.get(field.element)) !== null && _a !== void 0 ? _a : [];
|
|
1648
|
+
atResponseName.set(field.element, forField.concat(field.selectionSet.fieldsInSet()));
|
|
1649
|
+
}
|
|
1650
|
+
else {
|
|
1651
|
+
atResponseName.set(field.element, null);
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
const byResponseName = new Map();
|
|
1655
|
+
for (const [name, level] of atLevel.entries()) {
|
|
1656
|
+
const atResponseName = new Map();
|
|
1657
|
+
for (const [field, collectedFields] of level) {
|
|
1658
|
+
const validator = collectedFields ? FieldsConflictValidator.forLevel(collectedFields) : null;
|
|
1659
|
+
atResponseName.set(field, validator);
|
|
1660
|
+
}
|
|
1661
|
+
byResponseName.set(name, atResponseName);
|
|
1662
|
+
}
|
|
1663
|
+
return new FieldsConflictValidator(byResponseName);
|
|
1664
|
+
}
|
|
1665
|
+
forField(field) {
|
|
1666
|
+
const byResponseName = this.byResponseName.get(field.responseName());
|
|
1667
|
+
if (!byResponseName) {
|
|
1668
|
+
return [];
|
|
1669
|
+
}
|
|
1670
|
+
return (0, utils_1.mapValues)(byResponseName).filter((v) => !!v);
|
|
1671
|
+
}
|
|
1672
|
+
doMergeWith(that) {
|
|
1673
|
+
var _a, _b;
|
|
1674
|
+
for (const [responseName, thisFields] of this.byResponseName.entries()) {
|
|
1675
|
+
const thatFields = that.byResponseName.get(responseName);
|
|
1676
|
+
if (!thatFields) {
|
|
1677
|
+
continue;
|
|
1678
|
+
}
|
|
1679
|
+
for (const [thisField, thisValidator] of thisFields.entries()) {
|
|
1680
|
+
for (const [thatField, thatValidator] of thatFields.entries()) {
|
|
1681
|
+
if (!(0, types_1.typesCanBeMerged)(thisField.definition.type, thatField.definition.type)) {
|
|
1682
|
+
return false;
|
|
1683
|
+
}
|
|
1684
|
+
const p1 = thisField.parentType;
|
|
1685
|
+
const p2 = thatField.parentType;
|
|
1686
|
+
if ((0, types_1.sameType)(p1, p2) || !(0, definitions_1.isObjectType)(p1) || !(0, definitions_1.isObjectType)(p2)) {
|
|
1687
|
+
if (thisField.name !== thatField.name
|
|
1688
|
+
|| !(0, values_1.argumentsEquals)((_a = thisField.args) !== null && _a !== void 0 ? _a : {}, (_b = thatField.args) !== null && _b !== void 0 ? _b : {})
|
|
1689
|
+
|| (thisValidator && thatValidator && !thisValidator.doMergeWith(thatValidator))) {
|
|
1690
|
+
return false;
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
else {
|
|
1694
|
+
if (thisValidator && thatValidator && !thisValidator.hasSameResponseShapeThan(thatValidator)) {
|
|
1695
|
+
return false;
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
return true;
|
|
1702
|
+
}
|
|
1703
|
+
hasSameResponseShapeThan(that) {
|
|
1704
|
+
for (const [responseName, thisFields] of this.byResponseName.entries()) {
|
|
1705
|
+
const thatFields = that.byResponseName.get(responseName);
|
|
1706
|
+
if (!thatFields) {
|
|
1707
|
+
continue;
|
|
1708
|
+
}
|
|
1709
|
+
for (const [thisField, thisValidator] of thisFields.entries()) {
|
|
1710
|
+
for (const [thatField, thatValidator] of thatFields.entries()) {
|
|
1711
|
+
if (!(0, types_1.typesCanBeMerged)(thisField.definition.type, thatField.definition.type)
|
|
1712
|
+
|| (thisValidator && thatValidator && !thisValidator.hasSameResponseShapeThan(thatValidator))) {
|
|
1713
|
+
return false;
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
return true;
|
|
1719
|
+
}
|
|
1720
|
+
toString(indent = '') {
|
|
1721
|
+
return '{\n'
|
|
1722
|
+
+ [...this.byResponseName.entries()].map(([name, byFields]) => {
|
|
1723
|
+
const innerIndent = indent + ' ';
|
|
1724
|
+
return `${innerIndent}${name}: [\n`
|
|
1725
|
+
+ [...byFields.entries()]
|
|
1726
|
+
.map(([field, next]) => `${innerIndent} ${field.parentType}.${field}${next ? next.toString(innerIndent + ' ') : ''}`)
|
|
1727
|
+
.join('\n')
|
|
1728
|
+
+ `\n${innerIndent}]`;
|
|
1729
|
+
}).join('\n')
|
|
1730
|
+
+ `\n${indent}}`;
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1472
1733
|
class FieldSelection extends AbstractSelection {
|
|
1473
1734
|
constructor(field, _selectionSet) {
|
|
1474
1735
|
super(field);
|
|
@@ -1485,41 +1746,44 @@ class FieldSelection extends AbstractSelection {
|
|
|
1485
1746
|
return this.element.definition.name === definitions_1.typenameFieldName;
|
|
1486
1747
|
}
|
|
1487
1748
|
withUpdatedComponents(field, selectionSet) {
|
|
1749
|
+
if (this.element === field && this.selectionSet === selectionSet) {
|
|
1750
|
+
return this;
|
|
1751
|
+
}
|
|
1488
1752
|
return new FieldSelection(field, selectionSet);
|
|
1489
1753
|
}
|
|
1490
1754
|
key() {
|
|
1491
1755
|
return this.element.key();
|
|
1492
1756
|
}
|
|
1493
|
-
optimize(fragments) {
|
|
1757
|
+
optimize(fragments, validator) {
|
|
1494
1758
|
const fieldBaseType = (0, definitions_1.baseType)(this.element.definition.type);
|
|
1495
1759
|
if (!(0, definitions_1.isCompositeType)(fieldBaseType) || !this.selectionSet) {
|
|
1496
1760
|
return this;
|
|
1497
1761
|
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1762
|
+
const fieldValidator = validator.forField(this.element);
|
|
1763
|
+
const optimized = this.tryOptimizeSubselectionWithFragments({
|
|
1764
|
+
parentType: fieldBaseType,
|
|
1765
|
+
subSelection: this.selectionSet,
|
|
1766
|
+
fragments,
|
|
1767
|
+
validator: fieldValidator,
|
|
1768
|
+
canUseFullMatchingFragment: (fragment) => fragment.appliedDirectives.length === 0,
|
|
1769
|
+
});
|
|
1770
|
+
let optimizedSelection;
|
|
1771
|
+
if (optimized instanceof NamedFragmentDefinition) {
|
|
1772
|
+
optimizedSelection = selectionSetOf(fieldBaseType, new FragmentSpreadSelection(fieldBaseType, fragments, optimized, []));
|
|
1773
|
+
}
|
|
1774
|
+
else {
|
|
1775
|
+
optimizedSelection = optimized;
|
|
1512
1776
|
}
|
|
1513
|
-
optimizedSelection = optimizedSelection.
|
|
1777
|
+
optimizedSelection = optimizedSelection.optimizeSelections(fragments, fieldValidator);
|
|
1514
1778
|
return this.selectionSet === optimizedSelection
|
|
1515
1779
|
? this
|
|
1516
1780
|
: this.withUpdatedSelectionSet(optimizedSelection);
|
|
1517
1781
|
}
|
|
1518
|
-
|
|
1782
|
+
filterRecursiveDepthFirst(predicate) {
|
|
1519
1783
|
if (!this.selectionSet) {
|
|
1520
1784
|
return predicate(this) ? this : undefined;
|
|
1521
1785
|
}
|
|
1522
|
-
const updatedSelectionSet = this.selectionSet.
|
|
1786
|
+
const updatedSelectionSet = this.selectionSet.filterRecursiveDepthFirst(predicate);
|
|
1523
1787
|
const thisWithFilteredSelectionSet = this.selectionSet === updatedSelectionSet
|
|
1524
1788
|
? this
|
|
1525
1789
|
: new FieldSelection(this.element, updatedSelectionSet);
|
|
@@ -1531,11 +1795,14 @@ class FieldSelection extends AbstractSelection {
|
|
|
1531
1795
|
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);
|
|
1532
1796
|
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.validate(variableDefinitions);
|
|
1533
1797
|
}
|
|
1534
|
-
rebaseOn(parentType, fragments) {
|
|
1798
|
+
rebaseOn({ parentType, fragments, errorIfCannotRebase, }) {
|
|
1535
1799
|
if (this.element.parentType === parentType) {
|
|
1536
1800
|
return this;
|
|
1537
1801
|
}
|
|
1538
|
-
const rebasedElement = this.element.rebaseOn(parentType);
|
|
1802
|
+
const rebasedElement = this.element.rebaseOn({ parentType, errorIfCannotRebase });
|
|
1803
|
+
if (!rebasedElement) {
|
|
1804
|
+
return undefined;
|
|
1805
|
+
}
|
|
1539
1806
|
if (!this.selectionSet) {
|
|
1540
1807
|
return this.withUpdatedElement(rebasedElement);
|
|
1541
1808
|
}
|
|
@@ -1544,7 +1811,8 @@ class FieldSelection extends AbstractSelection {
|
|
|
1544
1811
|
return this.withUpdatedElement(rebasedElement);
|
|
1545
1812
|
}
|
|
1546
1813
|
validate((0, definitions_1.isCompositeType)(rebasedBase), () => `Cannot rebase field selection ${this} on ${parentType}: rebased field base return type ${rebasedBase} is not composite`);
|
|
1547
|
-
|
|
1814
|
+
const rebasedSelectionSet = this.selectionSet.rebaseOn({ parentType: rebasedBase, fragments, errorIfCannotRebase });
|
|
1815
|
+
return rebasedSelectionSet.isEmpty() ? undefined : this.withUpdatedComponents(rebasedElement, rebasedSelectionSet);
|
|
1548
1816
|
}
|
|
1549
1817
|
canAddTo(parentType) {
|
|
1550
1818
|
if (this.element.parentType === parentType) {
|
|
@@ -1586,19 +1854,23 @@ class FieldSelection extends AbstractSelection {
|
|
|
1586
1854
|
var _a;
|
|
1587
1855
|
return !!((_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.hasDefer());
|
|
1588
1856
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1857
|
+
normalize({ parentType, recursive }) {
|
|
1858
|
+
const definition = parentType === this.parentType
|
|
1859
|
+
? this.element.definition
|
|
1860
|
+
: parentType.field(this.element.name);
|
|
1861
|
+
(0, utils_1.assert)(definition, `Cannot normalize ${this.element} at ${parentType} which does not have that field`);
|
|
1862
|
+
const element = this.element.definition === definition ? this.element : this.element.withUpdatedDefinition(definition);
|
|
1591
1863
|
if (!this.selectionSet) {
|
|
1592
|
-
return this;
|
|
1864
|
+
return this.withUpdatedElement(element);
|
|
1593
1865
|
}
|
|
1594
|
-
const base =
|
|
1595
|
-
(0, utils_1.assert)((0, definitions_1.isCompositeType)(base), () => `Field ${
|
|
1596
|
-
const
|
|
1597
|
-
if (
|
|
1598
|
-
return
|
|
1866
|
+
const base = element.baseType();
|
|
1867
|
+
(0, utils_1.assert)((0, definitions_1.isCompositeType)(base), () => `Field ${element} should not have a sub-selection`);
|
|
1868
|
+
const normalizedSubSelection = (recursive !== null && recursive !== void 0 ? recursive : true) ? this.selectionSet.normalize({ parentType: base }) : this.selectionSet;
|
|
1869
|
+
if (normalizedSubSelection === null || normalizedSubSelection === void 0 ? void 0 : normalizedSubSelection.isEmpty()) {
|
|
1870
|
+
return this.withUpdatedComponents(element, selectionSetOfElement(new Field(base.typenameField(), undefined, [new definitions_1.Directive('include', { 'if': false })])));
|
|
1599
1871
|
}
|
|
1600
1872
|
else {
|
|
1601
|
-
return
|
|
1873
|
+
return this.withUpdatedComponents(element, normalizedSubSelection);
|
|
1602
1874
|
}
|
|
1603
1875
|
}
|
|
1604
1876
|
expandFragments(updatedFragments) {
|
|
@@ -1616,7 +1888,7 @@ class FieldSelection extends AbstractSelection {
|
|
|
1616
1888
|
}
|
|
1617
1889
|
return !!that.selectionSet && this.selectionSet.equals(that.selectionSet);
|
|
1618
1890
|
}
|
|
1619
|
-
contains(that) {
|
|
1891
|
+
contains(that, options) {
|
|
1620
1892
|
if (!(that instanceof FieldSelection) || !this.element.equals(that.element)) {
|
|
1621
1893
|
return ContainsResult.NOT_CONTAINED;
|
|
1622
1894
|
}
|
|
@@ -1625,7 +1897,7 @@ class FieldSelection extends AbstractSelection {
|
|
|
1625
1897
|
return ContainsResult.EQUAL;
|
|
1626
1898
|
}
|
|
1627
1899
|
(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);
|
|
1900
|
+
return this.selectionSet.contains(that.selectionSet, options);
|
|
1629
1901
|
}
|
|
1630
1902
|
toString(expandFragments = true, indent) {
|
|
1631
1903
|
return (indent !== null && indent !== void 0 ? indent : '') + this.element + (this.selectionSet ? ' ' + this.selectionSet.toString(expandFragments, true, indent) : '');
|
|
@@ -1647,10 +1919,9 @@ class FragmentSelection extends AbstractSelection {
|
|
|
1647
1919
|
validate(schemaDef.rootType('mutation') !== parentType && schemaDef.rootType('subscription') !== parentType, () => { var _a; return `The @defer and @stream directives cannot be used on ${(_a = schemaDef.roots().filter((t) => t.type === parentType).pop()) === null || _a === void 0 ? void 0 : _a.rootKind} root type "${parentType}"`; });
|
|
1648
1920
|
}
|
|
1649
1921
|
}
|
|
1650
|
-
|
|
1651
|
-
const
|
|
1652
|
-
const
|
|
1653
|
-
const thisWithFilteredSelectionSet = updatedSelectionSet === selectionSet
|
|
1922
|
+
filterRecursiveDepthFirst(predicate) {
|
|
1923
|
+
const updatedSelectionSet = this.selectionSet.filterRecursiveDepthFirst(predicate);
|
|
1924
|
+
const thisWithFilteredSelectionSet = updatedSelectionSet === this.selectionSet
|
|
1654
1925
|
? this
|
|
1655
1926
|
: new InlineFragmentSelection(this.element, updatedSelectionSet);
|
|
1656
1927
|
return predicate(thisWithFilteredSelectionSet) ? thisWithFilteredSelectionSet : undefined;
|
|
@@ -1658,6 +1929,17 @@ class FragmentSelection extends AbstractSelection {
|
|
|
1658
1929
|
hasDefer() {
|
|
1659
1930
|
return this.element.hasDefer() || this.selectionSet.hasDefer();
|
|
1660
1931
|
}
|
|
1932
|
+
normalize({ parentType, recursive }) {
|
|
1933
|
+
const thisCondition = this.element.typeCondition;
|
|
1934
|
+
if (thisCondition && parentType !== this.parentType) {
|
|
1935
|
+
const conditionRuntimes = (0, definitions_1.possibleRuntimeTypes)(thisCondition);
|
|
1936
|
+
const typeRuntimes = (0, definitions_1.possibleRuntimeTypes)(parentType);
|
|
1937
|
+
if (!conditionRuntimes.some((t) => typeRuntimes.includes(t))) {
|
|
1938
|
+
return undefined;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
return this.normalizeKnowingItIntersects({ parentType, recursive });
|
|
1942
|
+
}
|
|
1661
1943
|
}
|
|
1662
1944
|
exports.FragmentSelection = FragmentSelection;
|
|
1663
1945
|
class InlineFragmentSelection extends FragmentSelection {
|
|
@@ -1672,6 +1954,9 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1672
1954
|
return this.element.key();
|
|
1673
1955
|
}
|
|
1674
1956
|
withUpdatedComponents(fragment, selectionSet) {
|
|
1957
|
+
if (fragment === this.element && selectionSet === this.selectionSet) {
|
|
1958
|
+
return this;
|
|
1959
|
+
}
|
|
1675
1960
|
return new InlineFragmentSelection(fragment, selectionSet);
|
|
1676
1961
|
}
|
|
1677
1962
|
validate(variableDefinitions) {
|
|
@@ -1679,16 +1964,20 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1679
1964
|
validate(!this.selectionSet.isEmpty(), () => `Invalid empty selection set for fragment "${this.element}"`);
|
|
1680
1965
|
this.selectionSet.validate(variableDefinitions);
|
|
1681
1966
|
}
|
|
1682
|
-
rebaseOn(parentType, fragments) {
|
|
1967
|
+
rebaseOn({ parentType, fragments, errorIfCannotRebase, }) {
|
|
1683
1968
|
if (this.parentType === parentType) {
|
|
1684
1969
|
return this;
|
|
1685
1970
|
}
|
|
1686
|
-
const rebasedFragment = this.element.rebaseOn(parentType);
|
|
1971
|
+
const rebasedFragment = this.element.rebaseOn({ parentType, errorIfCannotRebase });
|
|
1972
|
+
if (!rebasedFragment) {
|
|
1973
|
+
return undefined;
|
|
1974
|
+
}
|
|
1687
1975
|
const rebasedCastedType = rebasedFragment.castedType();
|
|
1688
1976
|
if (rebasedCastedType === this.selectionSet.parentType) {
|
|
1689
1977
|
return this.withUpdatedElement(rebasedFragment);
|
|
1690
1978
|
}
|
|
1691
|
-
|
|
1979
|
+
const rebasedSelectionSet = this.selectionSet.rebaseOn({ parentType: rebasedCastedType, fragments, errorIfCannotRebase });
|
|
1980
|
+
return rebasedSelectionSet.isEmpty() ? undefined : this.withUpdatedComponents(rebasedFragment, rebasedSelectionSet);
|
|
1692
1981
|
}
|
|
1693
1982
|
canAddTo(parentType) {
|
|
1694
1983
|
if (this.element.parentType === parentType) {
|
|
@@ -1720,7 +2009,7 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1720
2009
|
selectionSet: this.selectionSet.toSelectionSetNode()
|
|
1721
2010
|
};
|
|
1722
2011
|
}
|
|
1723
|
-
optimize(fragments) {
|
|
2012
|
+
optimize(fragments, validator) {
|
|
1724
2013
|
let optimizedSelection = this.selectionSet;
|
|
1725
2014
|
const typeCondition = this.element.typeCondition;
|
|
1726
2015
|
if (typeCondition) {
|
|
@@ -1728,6 +2017,7 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1728
2017
|
parentType: typeCondition,
|
|
1729
2018
|
subSelection: optimizedSelection,
|
|
1730
2019
|
fragments,
|
|
2020
|
+
validator,
|
|
1731
2021
|
canUseFullMatchingFragment: (fragment) => {
|
|
1732
2022
|
return fragment.appliedDirectives.length === 0
|
|
1733
2023
|
|| ((0, types_1.sameType)(typeCondition, fragment.typeCondition)
|
|
@@ -1750,7 +2040,7 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1750
2040
|
optimizedSelection = optimized;
|
|
1751
2041
|
}
|
|
1752
2042
|
}
|
|
1753
|
-
optimizedSelection = optimizedSelection.optimizeSelections(fragments);
|
|
2043
|
+
optimizedSelection = optimizedSelection.optimizeSelections(fragments, validator);
|
|
1754
2044
|
return this.selectionSet === optimizedSelection
|
|
1755
2045
|
? this
|
|
1756
2046
|
: new InlineFragmentSelection(this.element, optimizedSelection);
|
|
@@ -1778,42 +2068,35 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1778
2068
|
? this
|
|
1779
2069
|
: this.withUpdatedComponents(newElement, newSelection);
|
|
1780
2070
|
}
|
|
1781
|
-
|
|
1782
|
-
var _a
|
|
1783
|
-
const recursive = (_a = options === null || options === void 0 ? void 0 : options.recursive) !== null && _a !== void 0 ? _a : true;
|
|
2071
|
+
normalizeKnowingItIntersects({ parentType, recursive }) {
|
|
2072
|
+
var _a;
|
|
1784
2073
|
const thisCondition = this.element.typeCondition;
|
|
1785
2074
|
if (this.element.appliedDirectives.length === 0) {
|
|
1786
|
-
if (!thisCondition ||
|
|
1787
|
-
const
|
|
1788
|
-
return
|
|
2075
|
+
if (!thisCondition || parentType === this.element.typeCondition || (0, definitions_1.isObjectType)(parentType)) {
|
|
2076
|
+
const normalized = this.selectionSet.normalize({ parentType, recursive });
|
|
2077
|
+
return normalized.isEmpty() ? undefined : normalized;
|
|
1789
2078
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
2079
|
+
}
|
|
2080
|
+
let normalizedSelectionSet;
|
|
2081
|
+
if (recursive !== null && recursive !== void 0 ? recursive : true) {
|
|
2082
|
+
normalizedSelectionSet = this.selectionSet.normalize({ parentType: thisCondition !== null && thisCondition !== void 0 ? thisCondition : parentType });
|
|
2083
|
+
if (normalizedSelectionSet.isEmpty()) {
|
|
2084
|
+
if (this.element.appliedDirectives.length === 0) {
|
|
1792
2085
|
return undefined;
|
|
1793
2086
|
}
|
|
1794
2087
|
else {
|
|
1795
|
-
|
|
1796
|
-
return trimmed.isEmpty() ? undefined : trimmed;
|
|
2088
|
+
return this.withUpdatedComponents(this.element.rebaseOnOrError(parentType), selectionSetOfElement(new Field(((_a = this.element.typeCondition) !== null && _a !== void 0 ? _a : parentType).typenameField(), undefined, [new definitions_1.Directive('include', { 'if': false })])));
|
|
1797
2089
|
}
|
|
1798
2090
|
}
|
|
1799
2091
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
}
|
|
1803
|
-
const trimmedSelectionSet = this.selectionSet.trimUnsatisfiableBranches((_b = this.element.typeCondition) !== null && _b !== void 0 ? _b : this.parentType);
|
|
1804
|
-
if (trimmedSelectionSet.isEmpty()) {
|
|
1805
|
-
if (this.element.appliedDirectives.length === 0) {
|
|
1806
|
-
return undefined;
|
|
1807
|
-
}
|
|
1808
|
-
else {
|
|
1809
|
-
return this.withUpdatedSelectionSet(selectionSetOfElement(new Field(((_c = this.element.typeCondition) !== null && _c !== void 0 ? _c : this.parentType).typenameField(), undefined, [new definitions_1.Directive('include', { 'if': false })])));
|
|
1810
|
-
}
|
|
2092
|
+
else {
|
|
2093
|
+
normalizedSelectionSet = this.selectionSet;
|
|
1811
2094
|
}
|
|
1812
2095
|
if (this.element.appliedDirectives.length === 0 && (0, definitions_1.isAbstractType)(thisCondition)) {
|
|
1813
|
-
(0, utils_1.assert)(!(0, definitions_1.isObjectType)(
|
|
1814
|
-
const currentRuntimes = (0, definitions_1.possibleRuntimeTypes)(
|
|
2096
|
+
(0, utils_1.assert)(!(0, definitions_1.isObjectType)(parentType), () => `Should not have got here if ${parentType} is an object type`);
|
|
2097
|
+
const currentRuntimes = (0, definitions_1.possibleRuntimeTypes)(parentType);
|
|
1815
2098
|
const liftableSelections = [];
|
|
1816
|
-
for (const selection of
|
|
2099
|
+
for (const selection of normalizedSelectionSet.selections()) {
|
|
1817
2100
|
if (selection.kind === 'FragmentSelection'
|
|
1818
2101
|
&& selection.element.typeCondition
|
|
1819
2102
|
&& (0, definitions_1.isObjectType)(selection.element.typeCondition)
|
|
@@ -1821,17 +2104,19 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1821
2104
|
liftableSelections.push(selection);
|
|
1822
2105
|
}
|
|
1823
2106
|
}
|
|
1824
|
-
if (liftableSelections.length ===
|
|
1825
|
-
return
|
|
2107
|
+
if (liftableSelections.length === normalizedSelectionSet.selections().length) {
|
|
2108
|
+
return normalizedSelectionSet;
|
|
1826
2109
|
}
|
|
1827
2110
|
if (liftableSelections.length > 0) {
|
|
1828
2111
|
const newSet = new SelectionSetUpdates();
|
|
1829
2112
|
newSet.add(liftableSelections);
|
|
1830
|
-
newSet.add(this.withUpdatedSelectionSet(
|
|
1831
|
-
return newSet.toSelectionSet(
|
|
2113
|
+
newSet.add(this.withUpdatedSelectionSet(normalizedSelectionSet.filter((s) => !liftableSelections.includes(s))));
|
|
2114
|
+
return newSet.toSelectionSet(parentType);
|
|
1832
2115
|
}
|
|
1833
2116
|
}
|
|
1834
|
-
return this.
|
|
2117
|
+
return this.parentType === parentType && this.selectionSet === normalizedSelectionSet
|
|
2118
|
+
? this
|
|
2119
|
+
: this.withUpdatedComponents(this.element.rebaseOnOrError(parentType), normalizedSelectionSet);
|
|
1835
2120
|
}
|
|
1836
2121
|
expandFragments(updatedFragments) {
|
|
1837
2122
|
return this.mapToSelectionSet((s) => s.expandFragments(updatedFragments));
|
|
@@ -1844,11 +2129,11 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1844
2129
|
&& this.element.equals(that.element)
|
|
1845
2130
|
&& this.selectionSet.equals(that.selectionSet);
|
|
1846
2131
|
}
|
|
1847
|
-
contains(that) {
|
|
2132
|
+
contains(that, options) {
|
|
1848
2133
|
if (!(that instanceof FragmentSelection) || !this.element.equals(that.element)) {
|
|
1849
2134
|
return ContainsResult.NOT_CONTAINED;
|
|
1850
2135
|
}
|
|
1851
|
-
return this.selectionSet.contains(that.selectionSet);
|
|
2136
|
+
return this.selectionSet.contains(that.selectionSet, options);
|
|
1852
2137
|
}
|
|
1853
2138
|
toString(expandFragments = true, indent) {
|
|
1854
2139
|
return (indent !== null && indent !== void 0 ? indent : '') + this.element + ' ' + this.selectionSet.toString(expandFragments, true, indent);
|
|
@@ -1876,12 +2161,13 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1876
2161
|
withUpdatedComponents(_fragment, _selectionSet) {
|
|
1877
2162
|
(0, utils_1.assert)(false, `Unsupported`);
|
|
1878
2163
|
}
|
|
1879
|
-
|
|
1880
|
-
(0, utils_1.assert)(parentType.schema() === this.parentType.schema(), 'Should not try to
|
|
1881
|
-
return this.
|
|
2164
|
+
normalizeKnowingItIntersects({ parentType }) {
|
|
2165
|
+
(0, utils_1.assert)(parentType.schema() === this.parentType.schema(), 'Should not try to normalize using a type from another schema');
|
|
2166
|
+
return this.rebaseOnOrError({ parentType, fragments: this.fragments });
|
|
1882
2167
|
}
|
|
1883
2168
|
validate() {
|
|
1884
2169
|
this.validateDeferAndStream();
|
|
2170
|
+
validate((0, definitions_1.runtimeTypesIntersects)(this.parentType, this.namedFragment.typeCondition), () => `Fragment "${this.namedFragment.name}" cannot be spread inside type ${this.parentType} as the runtime types do not intersect ${this.namedFragment.typeCondition}`);
|
|
1885
2171
|
}
|
|
1886
2172
|
toSelectionNode() {
|
|
1887
2173
|
const directiveNodes = this.spreadDirectives.length === 0
|
|
@@ -1902,17 +2188,20 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1902
2188
|
directives: directiveNodes,
|
|
1903
2189
|
};
|
|
1904
2190
|
}
|
|
1905
|
-
optimize(
|
|
2191
|
+
optimize(_1, _2) {
|
|
1906
2192
|
return this;
|
|
1907
2193
|
}
|
|
1908
|
-
rebaseOn(parentType, fragments) {
|
|
2194
|
+
rebaseOn({ parentType, fragments, errorIfCannotRebase, }) {
|
|
1909
2195
|
if (this.parentType === parentType) {
|
|
1910
2196
|
return this;
|
|
1911
2197
|
}
|
|
1912
2198
|
(0, utils_1.assert)(fragments || this.parentType.schema() === parentType.schema(), `Must provide fragments is rebasing on other schema`);
|
|
1913
2199
|
const newFragments = fragments !== null && fragments !== void 0 ? fragments : this.fragments;
|
|
1914
2200
|
const namedFragment = newFragments.get(this.namedFragment.name);
|
|
1915
|
-
|
|
2201
|
+
if (!namedFragment) {
|
|
2202
|
+
validate(!errorIfCannotRebase, () => `Cannot rebase ${this.toString(false)} if it isn't part of the provided fragments`);
|
|
2203
|
+
return undefined;
|
|
2204
|
+
}
|
|
1916
2205
|
return new FragmentSpreadSelection(parentType, newFragments, namedFragment, this.spreadDirectives);
|
|
1917
2206
|
}
|
|
1918
2207
|
canAddTo(_) {
|
|
@@ -1949,14 +2238,14 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1949
2238
|
&& this.namedFragment.name === that.namedFragment.name
|
|
1950
2239
|
&& (0, definitions_1.sameDirectiveApplications)(this.spreadDirectives, that.spreadDirectives);
|
|
1951
2240
|
}
|
|
1952
|
-
contains(that) {
|
|
2241
|
+
contains(that, options) {
|
|
1953
2242
|
if (this.equals(that)) {
|
|
1954
2243
|
return ContainsResult.EQUAL;
|
|
1955
2244
|
}
|
|
1956
2245
|
if (!(that instanceof FragmentSelection) || !this.element.equals(that.element)) {
|
|
1957
2246
|
return ContainsResult.NOT_CONTAINED;
|
|
1958
2247
|
}
|
|
1959
|
-
return this.selectionSet.contains(that.selectionSet);
|
|
2248
|
+
return this.selectionSet.contains(that.selectionSet, options);
|
|
1960
2249
|
}
|
|
1961
2250
|
toString(expandFragments = true, indent) {
|
|
1962
2251
|
if (expandFragments) {
|