@apollo/federation-internals 2.4.0-alpha.1 → 2.4.1
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/CHANGELOG.md +41 -0
- package/dist/coreSpec.js +1 -1
- package/dist/coreSpec.js.map +1 -1
- package/dist/definitions.d.ts +15 -15
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +35 -55
- package/dist/definitions.js.map +1 -1
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +19 -18
- package/dist/federation.js.map +1 -1
- package/dist/operations.d.ts +222 -88
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +934 -605
- package/dist/operations.js.map +1 -1
- package/dist/precompute.d.ts.map +1 -1
- package/dist/precompute.js +13 -10
- package/dist/precompute.js.map +1 -1
- package/dist/values.d.ts +3 -3
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +22 -28
- package/dist/values.js.map +1 -1
- package/package.json +4 -2
- package/src/__tests__/operations.test.ts +727 -145
- package/src/__tests__/schemaUpgrader.test.ts +1 -1
- package/src/definitions.ts +53 -57
- package/src/federation.ts +27 -23
- package/src/operations.ts +1370 -855
- package/src/precompute.ts +18 -12
- package/src/values.ts +24 -30
- package/tsconfig.tsbuildinfo +1 -1
package/dist/operations.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
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.allFieldDefinitionsInSelectionSet = exports.
|
|
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;
|
|
4
4
|
const graphql_1 = require("graphql");
|
|
5
5
|
const definitions_1 = require("./definitions");
|
|
6
|
+
const federation_1 = require("./federation");
|
|
6
7
|
const error_1 = require("./error");
|
|
7
8
|
const types_1 = require("./types");
|
|
8
9
|
const utils_1 = require("./utils");
|
|
9
10
|
const values_1 = require("./values");
|
|
11
|
+
const uuid_1 = require("uuid");
|
|
10
12
|
function validate(condition, message, sourceAST) {
|
|
11
13
|
if (!condition) {
|
|
12
14
|
throw error_1.ERRORS.INVALID_GRAPHQL.err(message(), { nodes: sourceAST });
|
|
@@ -16,12 +18,12 @@ function haveSameDirectives(op1, op2) {
|
|
|
16
18
|
return (0, definitions_1.sameDirectiveApplications)(op1.appliedDirectives, op2.appliedDirectives);
|
|
17
19
|
}
|
|
18
20
|
class AbstractOperationElement extends definitions_1.DirectiveTargetElement {
|
|
19
|
-
constructor(schema,
|
|
20
|
-
super(schema);
|
|
21
|
-
this.variablesInElement = variablesInElement;
|
|
21
|
+
constructor(schema, directives) {
|
|
22
|
+
super(schema, directives);
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
-
|
|
24
|
+
collectVariables(collector) {
|
|
25
|
+
this.collectVariablesInElement(collector);
|
|
26
|
+
this.collectVariablesInAppliedDirectives(collector);
|
|
25
27
|
}
|
|
26
28
|
addAttachement(key, value) {
|
|
27
29
|
if (!this.attachements) {
|
|
@@ -42,44 +44,76 @@ class AbstractOperationElement extends definitions_1.DirectiveTargetElement {
|
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
class Field extends AbstractOperationElement {
|
|
45
|
-
constructor(definition, args
|
|
46
|
-
super(definition.schema(),
|
|
47
|
+
constructor(definition, args, directives, alias) {
|
|
48
|
+
super(definition.schema(), directives);
|
|
47
49
|
this.definition = definition;
|
|
48
50
|
this.args = args;
|
|
49
|
-
this.variableDefinitions = variableDefinitions;
|
|
50
51
|
this.alias = alias;
|
|
51
52
|
this.kind = 'Field';
|
|
52
53
|
}
|
|
54
|
+
collectVariablesInElement(collector) {
|
|
55
|
+
if (this.args) {
|
|
56
|
+
collector.collectInArguments(this.args);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
53
59
|
get name() {
|
|
54
60
|
return this.definition.name;
|
|
55
61
|
}
|
|
62
|
+
argumentValue(name) {
|
|
63
|
+
return this.args ? this.args[name] : undefined;
|
|
64
|
+
}
|
|
56
65
|
responseName() {
|
|
57
66
|
return this.alias ? this.alias : this.name;
|
|
58
67
|
}
|
|
68
|
+
key() {
|
|
69
|
+
return this.responseName();
|
|
70
|
+
}
|
|
71
|
+
asPathElement() {
|
|
72
|
+
return this.responseName();
|
|
73
|
+
}
|
|
59
74
|
get parentType() {
|
|
60
75
|
return this.definition.parent;
|
|
61
76
|
}
|
|
77
|
+
isLeafField() {
|
|
78
|
+
return (0, definitions_1.isLeafType)((0, definitions_1.baseType)(this.definition.type));
|
|
79
|
+
}
|
|
62
80
|
withUpdatedDefinition(newDefinition) {
|
|
63
|
-
const newField = new Field(newDefinition, this.args, this.
|
|
64
|
-
for (const directive of this.appliedDirectives) {
|
|
65
|
-
newField.applyDirective(directive.definition, directive.arguments());
|
|
66
|
-
}
|
|
81
|
+
const newField = new Field(newDefinition, this.args, this.appliedDirectives, this.alias);
|
|
67
82
|
this.copyAttachementsTo(newField);
|
|
68
83
|
return newField;
|
|
69
84
|
}
|
|
70
85
|
withUpdatedAlias(newAlias) {
|
|
71
|
-
const newField = new Field(this.definition, this.args, this.
|
|
72
|
-
for (const directive of this.appliedDirectives) {
|
|
73
|
-
newField.applyDirective(directive.definition, directive.arguments());
|
|
74
|
-
}
|
|
86
|
+
const newField = new Field(this.definition, this.args, this.appliedDirectives, newAlias);
|
|
75
87
|
this.copyAttachementsTo(newField);
|
|
76
88
|
return newField;
|
|
77
89
|
}
|
|
90
|
+
withUpdatedDirectives(newDirectives) {
|
|
91
|
+
const newField = new Field(this.definition, this.args, newDirectives, this.alias);
|
|
92
|
+
this.copyAttachementsTo(newField);
|
|
93
|
+
return newField;
|
|
94
|
+
}
|
|
95
|
+
argumentsToNodes() {
|
|
96
|
+
if (!this.args) {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const entries = Object.entries(this.args);
|
|
100
|
+
if (entries.length === 0) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
return entries.map(([n, v]) => {
|
|
104
|
+
return {
|
|
105
|
+
kind: graphql_1.Kind.ARGUMENT,
|
|
106
|
+
name: { kind: graphql_1.Kind.NAME, value: n },
|
|
107
|
+
value: (0, values_1.valueToAST)(v, this.definition.argument(n).type),
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
}
|
|
78
111
|
appliesTo(type) {
|
|
79
112
|
const definition = type.field(this.name);
|
|
80
113
|
return !!definition && this.selects(definition);
|
|
81
114
|
}
|
|
82
|
-
selects(definition, assumeValid = false) {
|
|
115
|
+
selects(definition, assumeValid = false, variableDefinitions) {
|
|
116
|
+
(0, utils_1.assert)(assumeValid || variableDefinitions, 'Must provide variable definitions if validation is needed');
|
|
83
117
|
if (definition === this.definition) {
|
|
84
118
|
return true;
|
|
85
119
|
}
|
|
@@ -87,19 +121,19 @@ class Field extends AbstractOperationElement {
|
|
|
87
121
|
return false;
|
|
88
122
|
}
|
|
89
123
|
for (const argDef of definition.arguments()) {
|
|
90
|
-
const appliedValue = this.
|
|
124
|
+
const appliedValue = this.argumentValue(argDef.name);
|
|
91
125
|
if (appliedValue === undefined) {
|
|
92
126
|
if (argDef.defaultValue === undefined && !(0, definitions_1.isNullableType)(argDef.type)) {
|
|
93
127
|
return false;
|
|
94
128
|
}
|
|
95
129
|
}
|
|
96
130
|
else {
|
|
97
|
-
if (!assumeValid && !(0, values_1.isValidValue)(appliedValue, argDef,
|
|
131
|
+
if (!assumeValid && !(0, values_1.isValidValue)(appliedValue, argDef, variableDefinitions)) {
|
|
98
132
|
return false;
|
|
99
133
|
}
|
|
100
134
|
}
|
|
101
135
|
}
|
|
102
|
-
if (!assumeValid) {
|
|
136
|
+
if (!assumeValid && this.args) {
|
|
103
137
|
for (const [name, value] of Object.entries(this.args)) {
|
|
104
138
|
if (value !== null && definition.argument(name) === undefined) {
|
|
105
139
|
return false;
|
|
@@ -108,39 +142,41 @@ class Field extends AbstractOperationElement {
|
|
|
108
142
|
}
|
|
109
143
|
return true;
|
|
110
144
|
}
|
|
111
|
-
validate() {
|
|
145
|
+
validate(variableDefinitions) {
|
|
112
146
|
validate(this.name === this.definition.name, () => `Field name "${this.name}" cannot select field "${this.definition.coordinate}: name mismatch"`);
|
|
113
147
|
for (const argDef of this.definition.arguments()) {
|
|
114
|
-
const appliedValue = this.
|
|
148
|
+
const appliedValue = this.argumentValue(argDef.name);
|
|
115
149
|
if (appliedValue === undefined) {
|
|
116
150
|
validate(argDef.defaultValue !== undefined || (0, definitions_1.isNullableType)(argDef.type), () => `Missing mandatory value for argument "${argDef.name}" of field "${this.definition.coordinate}" in selection "${this}"`);
|
|
117
151
|
}
|
|
118
152
|
else {
|
|
119
|
-
validate((0, values_1.isValidValue)(appliedValue, argDef,
|
|
153
|
+
validate((0, values_1.isValidValue)(appliedValue, argDef, variableDefinitions), () => `Invalid value ${(0, values_1.valueToString)(appliedValue)} for argument "${argDef.coordinate}" of type ${argDef.type}`);
|
|
120
154
|
}
|
|
121
155
|
}
|
|
122
|
-
|
|
123
|
-
|
|
156
|
+
if (this.args) {
|
|
157
|
+
for (const [name, value] of Object.entries(this.args)) {
|
|
158
|
+
validate(value === null || this.definition.argument(name) !== undefined, () => `Unknown argument "${name}" in field application of "${this.name}"`);
|
|
159
|
+
}
|
|
124
160
|
}
|
|
125
161
|
}
|
|
126
|
-
|
|
127
|
-
const selectionParent = selectionSet.parentType;
|
|
162
|
+
rebaseOn(parentType) {
|
|
128
163
|
const fieldParent = this.definition.parent;
|
|
129
|
-
if (
|
|
164
|
+
if (parentType === fieldParent) {
|
|
130
165
|
return this;
|
|
131
166
|
}
|
|
132
167
|
if (this.name === definitions_1.typenameFieldName) {
|
|
133
|
-
return this.withUpdatedDefinition(
|
|
168
|
+
return this.withUpdatedDefinition(parentType.typenameField());
|
|
134
169
|
}
|
|
135
|
-
validate(this.canRebaseOn(
|
|
136
|
-
const fieldDef =
|
|
137
|
-
validate(fieldDef, () => `Cannot add selection of field "${this.definition.coordinate}" to selection set of parent type "${
|
|
170
|
+
validate(this.canRebaseOn(parentType), () => `Cannot add selection of field "${this.definition.coordinate}" to selection set of parent type "${parentType}"`);
|
|
171
|
+
const fieldDef = parentType.field(this.name);
|
|
172
|
+
validate(fieldDef, () => `Cannot add selection of field "${this.definition.coordinate}" to selection set of parent type "${parentType}" (that does not declare that field)`);
|
|
138
173
|
return this.withUpdatedDefinition(fieldDef);
|
|
139
174
|
}
|
|
140
175
|
canRebaseOn(parentType) {
|
|
141
176
|
const fieldParentType = this.definition.parent;
|
|
142
177
|
return parentType.name === fieldParentType.name
|
|
143
|
-
|| (
|
|
178
|
+
|| (0, definitions_1.isInterfaceType)(fieldParentType)
|
|
179
|
+
|| (0, federation_1.isInterfaceObjectType)(fieldParentType);
|
|
144
180
|
}
|
|
145
181
|
typeIfAddedTo(parentType) {
|
|
146
182
|
var _a, _b;
|
|
@@ -171,34 +207,56 @@ class Field extends AbstractOperationElement {
|
|
|
171
207
|
return that.kind === 'Field'
|
|
172
208
|
&& this.name === that.name
|
|
173
209
|
&& this.alias === that.alias
|
|
174
|
-
&& (0, values_1.argumentsEquals)(this.args, that.args)
|
|
210
|
+
&& (this.args ? that.args && (0, values_1.argumentsEquals)(this.args, that.args) : !that.args)
|
|
175
211
|
&& haveSameDirectives(this, that);
|
|
176
212
|
}
|
|
177
213
|
toString() {
|
|
178
214
|
const alias = this.alias ? this.alias + ': ' : '';
|
|
179
|
-
const entries = Object.entries(this.args);
|
|
180
|
-
const args = entries.length
|
|
215
|
+
const entries = this.args ? Object.entries(this.args) : [];
|
|
216
|
+
const args = entries.length === 0
|
|
181
217
|
? ''
|
|
182
218
|
: '(' + entries.map(([n, v]) => { var _a; return `${n}: ${(0, values_1.valueToString)(v, (_a = this.definition.argument(n)) === null || _a === void 0 ? void 0 : _a.type)}`; }).join(', ') + ')';
|
|
183
219
|
return alias + this.name + args + this.appliedDirectivesToString();
|
|
184
220
|
}
|
|
185
221
|
}
|
|
186
222
|
exports.Field = Field;
|
|
223
|
+
function keyForDirective(directive, directivesNeverEqualToThemselves = ['defer']) {
|
|
224
|
+
if (directivesNeverEqualToThemselves.includes(directive.name)) {
|
|
225
|
+
return (0, uuid_1.v1)();
|
|
226
|
+
}
|
|
227
|
+
const entries = Object.entries(directive.arguments()).filter(([_, v]) => v !== undefined);
|
|
228
|
+
entries.sort(([n1], [n2]) => n1.localeCompare(n2));
|
|
229
|
+
const args = entries.length == 0 ? '' : '(' + entries.map(([n, v]) => `${n}: ${(0, values_1.valueToString)(v, directive.argumentType(n))}`).join(', ') + ')';
|
|
230
|
+
return `@${directive.name}${args}`;
|
|
231
|
+
}
|
|
187
232
|
class FragmentElement extends AbstractOperationElement {
|
|
188
|
-
constructor(sourceType, typeCondition) {
|
|
189
|
-
super(sourceType.schema(),
|
|
233
|
+
constructor(sourceType, typeCondition, directives) {
|
|
234
|
+
super(sourceType.schema(), directives);
|
|
190
235
|
this.sourceType = sourceType;
|
|
191
236
|
this.kind = 'FragmentElement';
|
|
192
237
|
this.typeCondition = typeCondition !== undefined && typeof typeCondition === 'string'
|
|
193
238
|
? this.schema().type(typeCondition)
|
|
194
239
|
: typeCondition;
|
|
195
240
|
}
|
|
241
|
+
collectVariablesInElement(_) {
|
|
242
|
+
}
|
|
196
243
|
get parentType() {
|
|
197
244
|
return this.sourceType;
|
|
198
245
|
}
|
|
246
|
+
key() {
|
|
247
|
+
if (!this.computedKey) {
|
|
248
|
+
const keyForDirectives = this.appliedDirectives.map((d) => keyForDirective(d)).join(' ');
|
|
249
|
+
this.computedKey = '...' + (this.typeCondition ? ' on ' + this.typeCondition.name : '') + keyForDirectives;
|
|
250
|
+
}
|
|
251
|
+
return this.computedKey;
|
|
252
|
+
}
|
|
199
253
|
castedType() {
|
|
200
254
|
return this.typeCondition ? this.typeCondition : this.sourceType;
|
|
201
255
|
}
|
|
256
|
+
asPathElement() {
|
|
257
|
+
const condition = this.typeCondition;
|
|
258
|
+
return condition ? `... on ${condition}` : undefined;
|
|
259
|
+
}
|
|
202
260
|
withUpdatedSourceType(newSourceType) {
|
|
203
261
|
return this.withUpdatedTypes(newSourceType, this.typeCondition);
|
|
204
262
|
}
|
|
@@ -206,23 +264,24 @@ class FragmentElement extends AbstractOperationElement {
|
|
|
206
264
|
return this.withUpdatedTypes(this.sourceType, newCondition);
|
|
207
265
|
}
|
|
208
266
|
withUpdatedTypes(newSourceType, newCondition) {
|
|
209
|
-
const newFragment = new FragmentElement(newSourceType, newCondition === null || newCondition === void 0 ? void 0 : newCondition.name);
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
267
|
+
const newFragment = new FragmentElement(newSourceType, newCondition === null || newCondition === void 0 ? void 0 : newCondition.name, this.appliedDirectives);
|
|
268
|
+
this.copyAttachementsTo(newFragment);
|
|
269
|
+
return newFragment;
|
|
270
|
+
}
|
|
271
|
+
withUpdatedDirectives(newDirectives) {
|
|
272
|
+
const newFragment = new FragmentElement(this.sourceType, this.typeCondition, newDirectives);
|
|
213
273
|
this.copyAttachementsTo(newFragment);
|
|
214
274
|
return newFragment;
|
|
215
275
|
}
|
|
216
|
-
|
|
217
|
-
const selectionParent = selectionSet.parentType;
|
|
276
|
+
rebaseOn(parentType) {
|
|
218
277
|
const fragmentParent = this.parentType;
|
|
219
278
|
const typeCondition = this.typeCondition;
|
|
220
|
-
if (
|
|
279
|
+
if (parentType === fragmentParent) {
|
|
221
280
|
return this;
|
|
222
281
|
}
|
|
223
|
-
const { canRebase, rebasedCondition } = this.canRebaseOn(
|
|
224
|
-
validate(canRebase, () => `Cannot add fragment of condition "${typeCondition}" (runtimes: [${(0, definitions_1.possibleRuntimeTypes)(typeCondition)}]) to
|
|
225
|
-
return this.withUpdatedTypes(
|
|
282
|
+
const { canRebase, rebasedCondition } = this.canRebaseOn(parentType);
|
|
283
|
+
validate(canRebase, () => `Cannot add fragment of condition "${typeCondition}" (runtimes: [${(0, definitions_1.possibleRuntimeTypes)(typeCondition)}]) to parent type "${parentType}" (runtimes: ${(0, definitions_1.possibleRuntimeTypes)(parentType)})`);
|
|
284
|
+
return this.withUpdatedTypes(parentType, rebasedCondition);
|
|
226
285
|
}
|
|
227
286
|
canRebaseOn(parentType) {
|
|
228
287
|
if (!this.typeCondition) {
|
|
@@ -260,9 +319,8 @@ class FragmentElement extends AbstractOperationElement {
|
|
|
260
319
|
if (updatedDirectives.length === this.appliedDirectives.length) {
|
|
261
320
|
return this;
|
|
262
321
|
}
|
|
263
|
-
const updated = new FragmentElement(this.sourceType, this.typeCondition);
|
|
322
|
+
const updated = new FragmentElement(this.sourceType, this.typeCondition, updatedDirectives);
|
|
264
323
|
this.copyAttachementsTo(updated);
|
|
265
|
-
updatedDirectives.forEach((d) => updated.applyDirective(d.definition, d.arguments()));
|
|
266
324
|
return updated;
|
|
267
325
|
}
|
|
268
326
|
withNormalizedDefer(normalizer) {
|
|
@@ -307,11 +365,12 @@ class FragmentElement extends AbstractOperationElement {
|
|
|
307
365
|
if (!newDeferArgs) {
|
|
308
366
|
return this;
|
|
309
367
|
}
|
|
310
|
-
const updated = new FragmentElement(this.sourceType, this.typeCondition);
|
|
311
|
-
this.copyAttachementsTo(updated);
|
|
312
368
|
const deferDirective = this.schema().deferDirective();
|
|
313
|
-
|
|
314
|
-
|
|
369
|
+
const updatedDirectives = this.appliedDirectives
|
|
370
|
+
.filter((d) => d.name !== deferDirective.name)
|
|
371
|
+
.concat(new definitions_1.Directive(deferDirective.name, newDeferArgs));
|
|
372
|
+
const updated = new FragmentElement(this.sourceType, this.typeCondition, updatedDirectives);
|
|
373
|
+
this.copyAttachementsTo(updated);
|
|
315
374
|
return updated;
|
|
316
375
|
}
|
|
317
376
|
equals(that) {
|
|
@@ -389,6 +448,7 @@ class Operation {
|
|
|
389
448
|
this.name = name;
|
|
390
449
|
}
|
|
391
450
|
optimize(fragments, minUsagesToOptimize = 2) {
|
|
451
|
+
var _a;
|
|
392
452
|
(0, utils_1.assert)(minUsagesToOptimize >= 1, `Expected 'minUsagesToOptimize' to be at least 1, but got ${minUsagesToOptimize}`);
|
|
393
453
|
if (!fragments || fragments.isEmpty()) {
|
|
394
454
|
return this;
|
|
@@ -405,16 +465,24 @@ class Operation {
|
|
|
405
465
|
}
|
|
406
466
|
}
|
|
407
467
|
const toDeoptimize = (0, utils_1.mapEntries)(usages).filter(([_, count]) => count < minUsagesToOptimize).map(([name]) => name);
|
|
408
|
-
|
|
468
|
+
const newFragments = (_a = optimizedSelection.fragments) === null || _a === void 0 ? void 0 : _a.without(toDeoptimize);
|
|
469
|
+
optimizedSelection = optimizedSelection.expandFragments(toDeoptimize, newFragments);
|
|
409
470
|
return new Operation(this.schema, this.rootKind, optimizedSelection, this.variableDefinitions, this.name);
|
|
410
471
|
}
|
|
411
472
|
expandAllFragments() {
|
|
412
|
-
const expandedSelections = this.selectionSet.
|
|
473
|
+
const expandedSelections = this.selectionSet.expandAllFragments();
|
|
413
474
|
if (expandedSelections === this.selectionSet) {
|
|
414
475
|
return this;
|
|
415
476
|
}
|
|
416
477
|
return new Operation(this.schema, this.rootKind, expandedSelections, this.variableDefinitions, this.name);
|
|
417
478
|
}
|
|
479
|
+
trimUnsatisfiableBranches() {
|
|
480
|
+
const trimmedSelections = this.selectionSet.trimUnsatisfiableBranches(this.selectionSet.parentType);
|
|
481
|
+
if (trimmedSelections === this.selectionSet) {
|
|
482
|
+
return this;
|
|
483
|
+
}
|
|
484
|
+
return new Operation(this.schema, this.rootKind, trimmedSelections, this.variableDefinitions, this.name);
|
|
485
|
+
}
|
|
418
486
|
withoutDefer(labelsToRemove) {
|
|
419
487
|
(0, utils_1.assert)(!this.selectionSet.fragments || this.selectionSet.fragments.isEmpty(), 'Removing @defer currently only work on "expanded" selections (no named fragments)');
|
|
420
488
|
const updated = this.selectionSet.withoutDefer(labelsToRemove);
|
|
@@ -452,35 +520,23 @@ class Operation {
|
|
|
452
520
|
}
|
|
453
521
|
}
|
|
454
522
|
exports.Operation = Operation;
|
|
455
|
-
function addDirectiveNodesToElement(directiveNodes, element) {
|
|
456
|
-
if (!directiveNodes) {
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
const schema = element.schema();
|
|
460
|
-
for (const node of directiveNodes) {
|
|
461
|
-
const directiveDef = schema.directive(node.name.value);
|
|
462
|
-
validate(directiveDef, () => `Unknown directive "@${node.name.value}" in selection`);
|
|
463
|
-
element.applyDirective(directiveDef, (0, values_1.argumentsFromAST)(directiveDef.coordinate, node.arguments, directiveDef));
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
function selectionSetOf(parentType, selection) {
|
|
467
|
-
const selectionSet = new SelectionSet(parentType);
|
|
468
|
-
selectionSet.add(selection);
|
|
469
|
-
return selectionSet;
|
|
470
|
-
}
|
|
471
|
-
exports.selectionSetOf = selectionSetOf;
|
|
472
523
|
class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
473
|
-
constructor(schema, name, typeCondition,
|
|
474
|
-
super(schema);
|
|
524
|
+
constructor(schema, name, typeCondition, directives) {
|
|
525
|
+
super(schema, directives);
|
|
475
526
|
this.name = name;
|
|
476
527
|
this.typeCondition = typeCondition;
|
|
477
|
-
this.selectionSet = selectionSet;
|
|
478
528
|
}
|
|
479
|
-
|
|
480
|
-
|
|
529
|
+
setSelectionSet(selectionSet) {
|
|
530
|
+
(0, utils_1.assert)(!this._selectionSet, 'Attempting to set the selection set of a fragment definition already built');
|
|
531
|
+
this._selectionSet = selectionSet;
|
|
532
|
+
return this;
|
|
481
533
|
}
|
|
482
|
-
|
|
483
|
-
|
|
534
|
+
get selectionSet() {
|
|
535
|
+
(0, utils_1.assert)(this._selectionSet, () => `Trying to access fragment definition ${this.name} before it is fully built`);
|
|
536
|
+
return this._selectionSet;
|
|
537
|
+
}
|
|
538
|
+
withUpdatedSelectionSet(newSelectionSet) {
|
|
539
|
+
return new NamedFragmentDefinition(this.schema(), this.name, this.typeCondition).setSelectionSet(newSelectionSet);
|
|
484
540
|
}
|
|
485
541
|
collectUsedFragmentNames(collector) {
|
|
486
542
|
this.selectionSet.collectUsedFragmentNames(collector);
|
|
@@ -503,8 +559,7 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
503
559
|
};
|
|
504
560
|
}
|
|
505
561
|
canApplyAtType(type) {
|
|
506
|
-
const applyAtType = (0, types_1.sameType)(this.typeCondition, type)
|
|
507
|
-
|| ((0, definitions_1.isAbstractType)(this.typeCondition) && !(0, definitions_1.isUnionType)(type) && (0, types_1.isDirectSubtype)(this.typeCondition, type));
|
|
562
|
+
const applyAtType = (0, types_1.sameType)(type, this.typeCondition) || (0, definitions_1.runtimeTypesIntersects)(type, this.typeCondition);
|
|
508
563
|
return applyAtType
|
|
509
564
|
&& this.validForSchema(type.schema());
|
|
510
565
|
}
|
|
@@ -517,8 +572,7 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
517
572
|
return false;
|
|
518
573
|
}
|
|
519
574
|
try {
|
|
520
|
-
|
|
521
|
-
rebasedSelection.mergeIn(this.selectionSet);
|
|
575
|
+
this.selectionSet.rebaseOn(typeInSchema);
|
|
522
576
|
return true;
|
|
523
577
|
}
|
|
524
578
|
catch (e) {
|
|
@@ -537,13 +591,6 @@ class NamedFragments {
|
|
|
537
591
|
isEmpty() {
|
|
538
592
|
return this.fragments.size === 0;
|
|
539
593
|
}
|
|
540
|
-
variables() {
|
|
541
|
-
let variables = [];
|
|
542
|
-
for (const fragment of this.fragments.values()) {
|
|
543
|
-
variables = (0, definitions_1.mergeVariables)(variables, fragment.variables());
|
|
544
|
-
}
|
|
545
|
-
return variables;
|
|
546
|
-
}
|
|
547
594
|
names() {
|
|
548
595
|
return this.fragments.keys();
|
|
549
596
|
}
|
|
@@ -568,14 +615,14 @@ class NamedFragments {
|
|
|
568
615
|
const newFragments = new NamedFragments();
|
|
569
616
|
for (const fragment of this.fragments.values()) {
|
|
570
617
|
if (!names.includes(fragment.name)) {
|
|
571
|
-
const
|
|
572
|
-
const newFragment =
|
|
618
|
+
const updatedSelectionSet = fragment.selectionSet.expandFragments(names, newFragments);
|
|
619
|
+
const newFragment = updatedSelectionSet === fragment.selectionSet
|
|
573
620
|
? fragment
|
|
574
|
-
:
|
|
621
|
+
: fragment.withUpdatedSelectionSet(updatedSelectionSet);
|
|
575
622
|
newFragments.add(newFragment);
|
|
576
623
|
}
|
|
577
624
|
}
|
|
578
|
-
return newFragments;
|
|
625
|
+
return newFragments.isEmpty() ? undefined : newFragments;
|
|
579
626
|
}
|
|
580
627
|
get(name) {
|
|
581
628
|
return this.fragments.get(name);
|
|
@@ -586,9 +633,16 @@ class NamedFragments {
|
|
|
586
633
|
definitions() {
|
|
587
634
|
return this.fragments.values();
|
|
588
635
|
}
|
|
589
|
-
|
|
636
|
+
map(mapper) {
|
|
637
|
+
const mapped = new NamedFragments();
|
|
638
|
+
for (const def of this.fragments.values()) {
|
|
639
|
+
mapped.fragments.set(def.name, mapper(def));
|
|
640
|
+
}
|
|
641
|
+
return mapped;
|
|
642
|
+
}
|
|
643
|
+
validate(variableDefinitions) {
|
|
590
644
|
for (const fragment of this.fragments.values()) {
|
|
591
|
-
fragment.selectionSet.validate();
|
|
645
|
+
fragment.selectionSet.validate(variableDefinitions);
|
|
592
646
|
}
|
|
593
647
|
}
|
|
594
648
|
toFragmentDefinitionNodes() {
|
|
@@ -599,24 +653,6 @@ class NamedFragments {
|
|
|
599
653
|
}
|
|
600
654
|
}
|
|
601
655
|
exports.NamedFragments = NamedFragments;
|
|
602
|
-
class Freezable {
|
|
603
|
-
constructor() {
|
|
604
|
-
this._isFrozen = false;
|
|
605
|
-
}
|
|
606
|
-
freeze() {
|
|
607
|
-
if (!this.isFrozen()) {
|
|
608
|
-
this.freezeInternals();
|
|
609
|
-
this._isFrozen = true;
|
|
610
|
-
}
|
|
611
|
-
return this.us();
|
|
612
|
-
}
|
|
613
|
-
isFrozen() {
|
|
614
|
-
return this._isFrozen;
|
|
615
|
-
}
|
|
616
|
-
cloneIfFrozen() {
|
|
617
|
-
return this.isFrozen() ? this.clone() : this.us();
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
656
|
class DeferNormalizer {
|
|
621
657
|
constructor() {
|
|
622
658
|
this.index = 0;
|
|
@@ -631,7 +667,7 @@ class DeferNormalizer {
|
|
|
631
667
|
while (stack.length > 0) {
|
|
632
668
|
const selection = stack.pop();
|
|
633
669
|
if (selection.kind === 'FragmentSelection') {
|
|
634
|
-
const deferArgs = selection.element
|
|
670
|
+
const deferArgs = selection.element.deferDirectiveArgs();
|
|
635
671
|
if (deferArgs) {
|
|
636
672
|
hasDefers = true;
|
|
637
673
|
if (!deferArgs.label || deferArgs.if !== undefined) {
|
|
@@ -663,132 +699,103 @@ class DeferNormalizer {
|
|
|
663
699
|
this.deferConditions.add(condition.name, label);
|
|
664
700
|
}
|
|
665
701
|
}
|
|
666
|
-
class SelectionSet
|
|
667
|
-
constructor(parentType, fragments) {
|
|
668
|
-
super();
|
|
702
|
+
class SelectionSet {
|
|
703
|
+
constructor(parentType, keyedSelections = new Map(), fragments) {
|
|
669
704
|
this.parentType = parentType;
|
|
670
705
|
this.fragments = fragments;
|
|
671
|
-
this.
|
|
672
|
-
this.
|
|
673
|
-
validate(!(0, definitions_1.isLeafType)(parentType), () => `Cannot have selection on non-leaf type ${parentType}`);
|
|
706
|
+
this._keyedSelections = keyedSelections;
|
|
707
|
+
this._selections = (0, utils_1.mapValues)(keyedSelections);
|
|
674
708
|
}
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const selections = new Array(this._selectionCount);
|
|
681
|
-
let idx = 0;
|
|
682
|
-
for (const byResponseName of this._selections.values()) {
|
|
683
|
-
for (const selection of byResponseName) {
|
|
684
|
-
selections[idx++] = selection;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
this._cachedSelections = selections;
|
|
709
|
+
selectionsInReverseOrder() {
|
|
710
|
+
const length = this._selections.length;
|
|
711
|
+
const reversed = new Array(length);
|
|
712
|
+
for (let i = 0; i < length; i++) {
|
|
713
|
+
reversed[i] = this._selections[length - i - 1];
|
|
688
714
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
}
|
|
697
|
-
return this._cachedSelections;
|
|
715
|
+
return reversed;
|
|
716
|
+
}
|
|
717
|
+
selections() {
|
|
718
|
+
return this._selections;
|
|
719
|
+
}
|
|
720
|
+
hasTopLevelTypenameField() {
|
|
721
|
+
return this._keyedSelections.has(definitions_1.typenameFieldName);
|
|
698
722
|
}
|
|
699
723
|
fieldsInSet() {
|
|
700
724
|
const fields = new Array();
|
|
701
725
|
for (const selection of this.selections()) {
|
|
702
726
|
if (selection.kind === 'FieldSelection') {
|
|
703
|
-
fields.push({ path: [], field: selection
|
|
727
|
+
fields.push({ path: [], field: selection });
|
|
704
728
|
}
|
|
705
729
|
else {
|
|
706
|
-
const condition = selection.element
|
|
730
|
+
const condition = selection.element.typeCondition;
|
|
707
731
|
const header = condition ? [`... on ${condition}`] : [];
|
|
708
|
-
for (const { path, field
|
|
709
|
-
fields.push({ path: header.concat(path), field
|
|
732
|
+
for (const { path, field } of selection.selectionSet.fieldsInSet()) {
|
|
733
|
+
fields.push({ path: header.concat(path), field });
|
|
710
734
|
}
|
|
711
735
|
}
|
|
712
736
|
}
|
|
713
737
|
return fields;
|
|
714
738
|
}
|
|
715
739
|
usedVariables() {
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
variables = (0, definitions_1.mergeVariables)(variables, this.fragments.variables());
|
|
740
|
+
const collector = new definitions_1.VariableCollector();
|
|
741
|
+
this.collectVariables(collector);
|
|
742
|
+
return collector.variables();
|
|
743
|
+
}
|
|
744
|
+
collectVariables(collector) {
|
|
745
|
+
for (const selection of this.selections()) {
|
|
746
|
+
selection.collectVariables(collector);
|
|
724
747
|
}
|
|
725
|
-
return variables;
|
|
726
748
|
}
|
|
727
749
|
collectUsedFragmentNames(collector) {
|
|
728
|
-
for (const
|
|
729
|
-
|
|
730
|
-
selection.collectUsedFragmentNames(collector);
|
|
731
|
-
}
|
|
750
|
+
for (const selection of this.selections()) {
|
|
751
|
+
selection.collectUsedFragmentNames(collector);
|
|
732
752
|
}
|
|
733
753
|
}
|
|
734
754
|
optimize(fragments) {
|
|
735
755
|
if (!fragments || fragments.isEmpty()) {
|
|
736
756
|
return this;
|
|
737
757
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
}
|
|
741
|
-
const optimized = new SelectionSet(this.parentType, fragments);
|
|
742
|
-
for (const selection of this.selections()) {
|
|
743
|
-
optimized.add(selection.optimize(fragments));
|
|
744
|
-
}
|
|
745
|
-
return optimized;
|
|
758
|
+
(0, utils_1.assert)(!this.fragments || this.fragments.isEmpty(), `Should not be called on selection that already has named fragments, but got ${this.fragments}`);
|
|
759
|
+
return this.lazyMap((selection) => selection.optimize(fragments), { fragments });
|
|
746
760
|
}
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
761
|
+
expandAllFragments() {
|
|
762
|
+
return this.lazyMap((selection) => selection.expandAllFragments(), { fragments: null });
|
|
763
|
+
}
|
|
764
|
+
expandFragments(names, updatedFragments) {
|
|
765
|
+
if (names.length === 0) {
|
|
750
766
|
return this;
|
|
751
767
|
}
|
|
752
|
-
|
|
753
|
-
? (names ? (_a = this.fragments) === null || _a === void 0 ? void 0 : _a.without(names) : undefined)
|
|
754
|
-
: this.fragments;
|
|
755
|
-
const withExpanded = new SelectionSet(this.parentType, newFragments);
|
|
756
|
-
for (const selection of this.selections()) {
|
|
757
|
-
const expanded = selection.expandFragments(names, updateSelectionSetFragments);
|
|
758
|
-
if (Array.isArray(expanded)) {
|
|
759
|
-
withExpanded.addAll(expanded);
|
|
760
|
-
}
|
|
761
|
-
else {
|
|
762
|
-
withExpanded.add(expanded);
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
return withExpanded;
|
|
768
|
+
return this.lazyMap((selection) => selection.expandFragments(names, updatedFragments), { fragments: updatedFragments !== null && updatedFragments !== void 0 ? updatedFragments : null });
|
|
766
769
|
}
|
|
767
|
-
|
|
768
|
-
|
|
770
|
+
trimUnsatisfiableBranches(parentType) {
|
|
771
|
+
return this.lazyMap((selection) => selection.trimUnsatisfiableBranches(parentType), { parentType });
|
|
772
|
+
}
|
|
773
|
+
lazyMap(mapper, options) {
|
|
774
|
+
var _a;
|
|
769
775
|
const selections = this.selections();
|
|
776
|
+
const updatedFragments = options === null || options === void 0 ? void 0 : options.fragments;
|
|
777
|
+
const newFragments = updatedFragments === undefined ? this.fragments : (updatedFragments !== null && updatedFragments !== void 0 ? updatedFragments : undefined);
|
|
778
|
+
let updatedSelections = undefined;
|
|
770
779
|
for (let i = 0; i < selections.length; i++) {
|
|
771
780
|
const selection = selections[i];
|
|
772
781
|
const updated = mapper(selection);
|
|
773
782
|
if (updated !== selection && !updatedSelections) {
|
|
774
|
-
updatedSelections =
|
|
783
|
+
updatedSelections = new SelectionSetUpdates();
|
|
775
784
|
for (let j = 0; j < i; j++) {
|
|
776
|
-
updatedSelections.
|
|
785
|
+
updatedSelections.add(selections[j]);
|
|
777
786
|
}
|
|
778
787
|
}
|
|
779
788
|
if (!!updated && updatedSelections) {
|
|
780
|
-
|
|
781
|
-
updated.selections().forEach((s) => updatedSelections.push(s));
|
|
782
|
-
}
|
|
783
|
-
else {
|
|
784
|
-
updatedSelections.push(updated);
|
|
785
|
-
}
|
|
789
|
+
updatedSelections.add(updated);
|
|
786
790
|
}
|
|
787
791
|
}
|
|
788
792
|
if (!updatedSelections) {
|
|
789
|
-
return this;
|
|
793
|
+
return this.withUpdatedFragments(newFragments);
|
|
790
794
|
}
|
|
791
|
-
return
|
|
795
|
+
return updatedSelections.toSelectionSet((_a = options === null || options === void 0 ? void 0 : options.parentType) !== null && _a !== void 0 ? _a : this.parentType, newFragments);
|
|
796
|
+
}
|
|
797
|
+
withUpdatedFragments(newFragments) {
|
|
798
|
+
return this.fragments === newFragments ? this : new SelectionSet(this.parentType, this._keyedSelections, newFragments);
|
|
792
799
|
}
|
|
793
800
|
withoutDefer(labelsToRemove) {
|
|
794
801
|
(0, utils_1.assert)(!this.fragments, 'Not yet supported');
|
|
@@ -798,6 +805,9 @@ class SelectionSet extends Freezable {
|
|
|
798
805
|
(0, utils_1.assert)(!this.fragments, 'Not yet supported');
|
|
799
806
|
return this.lazyMap((selection) => selection.withNormalizedDefer(normalizer));
|
|
800
807
|
}
|
|
808
|
+
hasDefer() {
|
|
809
|
+
return this.selections().some((s) => s.hasDefer());
|
|
810
|
+
}
|
|
801
811
|
filter(predicate) {
|
|
802
812
|
return this.lazyMap((selection) => selection.filter(predicate));
|
|
803
813
|
}
|
|
@@ -805,169 +815,108 @@ class SelectionSet extends Freezable {
|
|
|
805
815
|
const updated = this.filter((selection) => { var _a; return ((_a = selection.selectionSet) === null || _a === void 0 ? void 0 : _a.isEmpty()) !== true; });
|
|
806
816
|
return updated.isEmpty() ? undefined : updated;
|
|
807
817
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
mergeIn(selectionSet) {
|
|
814
|
-
for (const selection of selectionSet.selections()) {
|
|
815
|
-
this.add(selection);
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
addAll(selections) {
|
|
819
|
-
selections.forEach(s => this.add(s));
|
|
820
|
-
return this;
|
|
821
|
-
}
|
|
822
|
-
add(selection) {
|
|
823
|
-
(0, utils_1.assert)(!this.isFrozen(), () => `Cannot add to frozen selection: ${this}`);
|
|
824
|
-
const toAdd = selection.updateForAddingTo(this);
|
|
825
|
-
const key = toAdd.key();
|
|
826
|
-
const existing = this._selections.get(key);
|
|
827
|
-
if (existing) {
|
|
828
|
-
for (const existingSelection of existing) {
|
|
829
|
-
if (existingSelection.kind === toAdd.kind && haveSameDirectives(existingSelection.element(), toAdd.element())) {
|
|
830
|
-
if (toAdd.selectionSet) {
|
|
831
|
-
existingSelection.selectionSet.mergeIn(toAdd.selectionSet);
|
|
832
|
-
}
|
|
833
|
-
return existingSelection;
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
this._selections.add(key, toAdd);
|
|
838
|
-
++this._selectionCount;
|
|
839
|
-
this._cachedSelections = undefined;
|
|
840
|
-
return toAdd;
|
|
841
|
-
}
|
|
842
|
-
removeTopLevelField(responseName) {
|
|
843
|
-
(0, utils_1.assert)(!this.isFrozen(), () => `Cannot remove from frozen selection: ${this}`);
|
|
844
|
-
const wasRemoved = this._selections.delete(responseName);
|
|
845
|
-
if (wasRemoved) {
|
|
846
|
-
--this._selectionCount;
|
|
847
|
-
this._cachedSelections = undefined;
|
|
848
|
-
}
|
|
849
|
-
return wasRemoved;
|
|
850
|
-
}
|
|
851
|
-
addPath(path, onPathEnd) {
|
|
852
|
-
let previousSelections = this;
|
|
853
|
-
let currentSelections = this;
|
|
854
|
-
for (const element of path) {
|
|
855
|
-
validate(currentSelections, () => `Cannot apply selection ${element} to non-selectable parent type "${previousSelections.parentType}"`);
|
|
856
|
-
const mergedSelection = currentSelections.add(selectionOfElement(element));
|
|
857
|
-
previousSelections = currentSelections;
|
|
858
|
-
currentSelections = mergedSelection.selectionSet;
|
|
859
|
-
}
|
|
860
|
-
if (onPathEnd) {
|
|
861
|
-
onPathEnd(currentSelections);
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
addSelectionSetNode(node, variableDefinitions, fieldAccessor = (type, name) => type.field(name)) {
|
|
865
|
-
if (!node) {
|
|
866
|
-
return;
|
|
867
|
-
}
|
|
868
|
-
for (const selectionNode of node.selections) {
|
|
869
|
-
this.addSelectionNode(selectionNode, variableDefinitions, fieldAccessor);
|
|
818
|
+
rebaseOn(parentType) {
|
|
819
|
+
if (this.parentType === parentType) {
|
|
820
|
+
return this;
|
|
870
821
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
}
|
|
875
|
-
nodeToSelection(node, variableDefinitions, fieldAccessor) {
|
|
876
|
-
var _a, _b;
|
|
877
|
-
let selection;
|
|
878
|
-
switch (node.kind) {
|
|
879
|
-
case graphql_1.Kind.FIELD:
|
|
880
|
-
const definition = fieldAccessor(this.parentType, node.name.value);
|
|
881
|
-
validate(definition, () => `Cannot query field "${node.name.value}" on type "${this.parentType}".`, this.parentType.sourceAST);
|
|
882
|
-
const type = (0, definitions_1.baseType)(definition.type);
|
|
883
|
-
selection = new FieldSelection(new Field(definition, (0, values_1.argumentsFromAST)(definition.coordinate, node.arguments, definition), variableDefinitions, (_a = node.alias) === null || _a === void 0 ? void 0 : _a.value), (0, definitions_1.isLeafType)(type) ? undefined : new SelectionSet(type, this.fragments));
|
|
884
|
-
if (node.selectionSet) {
|
|
885
|
-
validate(selection.selectionSet, () => `Unexpected selection set on leaf field "${selection.element()}"`, selection.element().definition.sourceAST);
|
|
886
|
-
selection.selectionSet.addSelectionSetNode(node.selectionSet, variableDefinitions, fieldAccessor);
|
|
887
|
-
}
|
|
888
|
-
break;
|
|
889
|
-
case graphql_1.Kind.INLINE_FRAGMENT:
|
|
890
|
-
const element = new FragmentElement(this.parentType, (_b = node.typeCondition) === null || _b === void 0 ? void 0 : _b.name.value);
|
|
891
|
-
selection = new InlineFragmentSelection(element, new SelectionSet(element.typeCondition ? element.typeCondition : element.parentType, this.fragments));
|
|
892
|
-
selection.selectionSet.addSelectionSetNode(node.selectionSet, variableDefinitions, fieldAccessor);
|
|
893
|
-
break;
|
|
894
|
-
case graphql_1.Kind.FRAGMENT_SPREAD:
|
|
895
|
-
const fragmentName = node.name.value;
|
|
896
|
-
validate(this.fragments, () => `Cannot find fragment name "${fragmentName}" (no fragments were provided)`);
|
|
897
|
-
selection = new FragmentSpreadSelection(this.parentType, this.fragments, fragmentName);
|
|
898
|
-
break;
|
|
822
|
+
const newSelections = new Map();
|
|
823
|
+
for (const selection of this.selections()) {
|
|
824
|
+
newSelections.set(selection.key(), selection.rebaseOn(parentType));
|
|
899
825
|
}
|
|
900
|
-
|
|
901
|
-
return selection;
|
|
826
|
+
return new SelectionSet(parentType, newSelections, this.fragments);
|
|
902
827
|
}
|
|
903
828
|
equals(that) {
|
|
904
829
|
if (this === that) {
|
|
905
830
|
return true;
|
|
906
831
|
}
|
|
907
|
-
if (this._selections.
|
|
832
|
+
if (this._selections.length !== that._selections.length) {
|
|
908
833
|
return false;
|
|
909
834
|
}
|
|
910
|
-
for (const [key,
|
|
911
|
-
const
|
|
912
|
-
if (!
|
|
913
|
-
|| thisSelections.length !== thatSelections.length
|
|
914
|
-
|| !thisSelections.every(thisSelection => thatSelections.some(thatSelection => thisSelection.equals(thatSelection)))) {
|
|
835
|
+
for (const [key, thisSelection] of this._keyedSelections) {
|
|
836
|
+
const thatSelection = that._keyedSelections.get(key);
|
|
837
|
+
if (!thatSelection || !thisSelection.equals(thatSelection)) {
|
|
915
838
|
return false;
|
|
916
839
|
}
|
|
917
840
|
}
|
|
918
841
|
return true;
|
|
919
842
|
}
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
843
|
+
triviallyNestedSelectionsForKey(parentType, key) {
|
|
844
|
+
const found = [];
|
|
845
|
+
for (const selection of this.selections()) {
|
|
846
|
+
if (selection.isUnecessaryInlineFragment(parentType)) {
|
|
847
|
+
const selectionForKey = selection.selectionSet._keyedSelections.get(key);
|
|
848
|
+
if (selectionForKey) {
|
|
849
|
+
found.push(selectionForKey);
|
|
850
|
+
}
|
|
851
|
+
for (const nestedSelection of selection.selectionSet.triviallyNestedSelectionsForKey(parentType, key)) {
|
|
852
|
+
found.push(nestedSelection);
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
return found;
|
|
857
|
+
}
|
|
858
|
+
mergeSameKeySelections(selections) {
|
|
859
|
+
if (selections.length === 0) {
|
|
860
|
+
return undefined;
|
|
923
861
|
}
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
862
|
+
const first = selections[0];
|
|
863
|
+
if (!first.selectionSet || (first instanceof FragmentSpreadSelection) || selections.length === 1) {
|
|
864
|
+
return first;
|
|
865
|
+
}
|
|
866
|
+
const mergedSubselections = new SelectionSetUpdates();
|
|
867
|
+
for (const selection of selections) {
|
|
868
|
+
mergedSubselections.add(selection.selectionSet);
|
|
869
|
+
}
|
|
870
|
+
return first.withUpdatedSelectionSet(mergedSubselections.toSelectionSet(first.selectionSet.parentType));
|
|
871
|
+
}
|
|
872
|
+
contains(that) {
|
|
873
|
+
for (const [key, thatSelection] of that._keyedSelections) {
|
|
874
|
+
const thisSelection = this._keyedSelections.get(key);
|
|
875
|
+
const otherSelections = this.triviallyNestedSelectionsForKey(this.parentType, key);
|
|
876
|
+
const mergedSelection = this.mergeSameKeySelections([thisSelection].concat(otherSelections).filter(utils_1.isDefined));
|
|
877
|
+
if (!(mergedSelection && mergedSelection.contains(thatSelection))
|
|
878
|
+
&& !(thatSelection.isUnecessaryInlineFragment(this.parentType) && this.contains(thatSelection.selectionSet))) {
|
|
929
879
|
return false;
|
|
930
880
|
}
|
|
931
881
|
}
|
|
932
882
|
return true;
|
|
933
883
|
}
|
|
884
|
+
diffIfContains(that) {
|
|
885
|
+
if (this.contains(that)) {
|
|
886
|
+
const diff = this.minus(that);
|
|
887
|
+
return { contains: true, diff: diff.isEmpty() ? undefined : diff };
|
|
888
|
+
}
|
|
889
|
+
return { contains: false };
|
|
890
|
+
}
|
|
934
891
|
minus(that) {
|
|
935
|
-
const updated = new
|
|
936
|
-
for (const [key,
|
|
937
|
-
const
|
|
938
|
-
|
|
939
|
-
|
|
892
|
+
const updated = new SelectionSetUpdates();
|
|
893
|
+
for (const [key, thisSelection] of this._keyedSelections) {
|
|
894
|
+
const thatSelection = that._keyedSelections.get(key);
|
|
895
|
+
const otherSelections = that.triviallyNestedSelectionsForKey(this.parentType, key);
|
|
896
|
+
const allSelections = thatSelection ? [thatSelection].concat(otherSelections) : otherSelections;
|
|
897
|
+
if (allSelections.length === 0) {
|
|
898
|
+
updated.add(thisSelection);
|
|
940
899
|
}
|
|
941
900
|
else {
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
if (thisSelection.selectionSet && thatSelection.selectionSet) {
|
|
946
|
-
const updatedSubSelectionSet = thisSelection.selectionSet.minus(thatSelection.selectionSet);
|
|
947
|
-
if (!updatedSubSelectionSet.isEmpty()) {
|
|
948
|
-
updated._selections.add(key, thisSelection.withUpdatedSubSelection(updatedSubSelectionSet));
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
else {
|
|
953
|
-
updated._selections.add(key, thisSelection);
|
|
954
|
-
}
|
|
901
|
+
const selectionDiff = allSelections.reduce((prev, val) => prev === null || prev === void 0 ? void 0 : prev.minus(val), thisSelection);
|
|
902
|
+
if (selectionDiff) {
|
|
903
|
+
updated.add(selectionDiff);
|
|
955
904
|
}
|
|
956
905
|
}
|
|
957
906
|
}
|
|
958
|
-
return updated;
|
|
907
|
+
return updated.toSelectionSet(this.parentType, this.fragments);
|
|
959
908
|
}
|
|
960
909
|
canRebaseOn(parentTypeToTest) {
|
|
961
910
|
return this.selections().every((selection) => selection.canAddTo(parentTypeToTest));
|
|
962
911
|
}
|
|
963
|
-
validate() {
|
|
912
|
+
validate(variableDefinitions) {
|
|
964
913
|
validate(!this.isEmpty(), () => `Invalid empty selection set`);
|
|
965
914
|
for (const selection of this.selections()) {
|
|
966
|
-
selection.validate();
|
|
915
|
+
selection.validate(variableDefinitions);
|
|
967
916
|
}
|
|
968
917
|
}
|
|
969
918
|
isEmpty() {
|
|
970
|
-
return this._selections.
|
|
919
|
+
return this._selections.length === 0;
|
|
971
920
|
}
|
|
972
921
|
toSelectionSetNode() {
|
|
973
922
|
if (this.isEmpty()) {
|
|
@@ -988,13 +937,13 @@ class SelectionSet extends Freezable {
|
|
|
988
937
|
};
|
|
989
938
|
}
|
|
990
939
|
selectionsInPrintOrder() {
|
|
991
|
-
const
|
|
992
|
-
const
|
|
940
|
+
const isNonAliasedTypenameSelection = (s) => s.kind === 'FieldSelection' && !s.element.alias && s.element.name === definitions_1.typenameFieldName;
|
|
941
|
+
const typenameSelection = this._selections.find((s) => isNonAliasedTypenameSelection(s));
|
|
993
942
|
if (typenameSelection) {
|
|
994
|
-
return typenameSelection.concat(this.selections().filter(s => !isNonAliasedTypenameSelection(s)));
|
|
943
|
+
return [typenameSelection].concat(this.selections().filter(s => !isNonAliasedTypenameSelection(s)));
|
|
995
944
|
}
|
|
996
945
|
else {
|
|
997
|
-
return this.
|
|
946
|
+
return this._selections;
|
|
998
947
|
}
|
|
999
948
|
}
|
|
1000
949
|
toOperationPaths() {
|
|
@@ -1002,7 +951,7 @@ class SelectionSet extends Freezable {
|
|
|
1002
951
|
}
|
|
1003
952
|
toOperationPathsInternal(parentPaths) {
|
|
1004
953
|
return this.selections().flatMap((selection) => {
|
|
1005
|
-
const updatedPaths = parentPaths.map(path => path.concat(selection.element
|
|
954
|
+
const updatedPaths = parentPaths.map(path => path.concat(selection.element));
|
|
1006
955
|
return selection.selectionSet
|
|
1007
956
|
? selection.selectionSet.toOperationPathsInternal(updatedPaths)
|
|
1008
957
|
: updatedPaths;
|
|
@@ -1010,21 +959,20 @@ class SelectionSet extends Freezable {
|
|
|
1010
959
|
}
|
|
1011
960
|
forEachElement(callback) {
|
|
1012
961
|
var _a;
|
|
1013
|
-
const stack = this.
|
|
962
|
+
const stack = this.selectionsInReverseOrder().concat();
|
|
1014
963
|
while (stack.length > 0) {
|
|
1015
964
|
const selection = stack.pop();
|
|
1016
|
-
callback(selection.element
|
|
1017
|
-
(_a = selection.selectionSet) === null || _a === void 0 ? void 0 : _a.
|
|
965
|
+
callback(selection.element);
|
|
966
|
+
(_a = selection.selectionSet) === null || _a === void 0 ? void 0 : _a.selectionsInReverseOrder().forEach((s) => stack.push(s));
|
|
1018
967
|
}
|
|
1019
968
|
}
|
|
1020
|
-
|
|
1021
|
-
const cloned = new SelectionSet(this.parentType);
|
|
969
|
+
some(predicate) {
|
|
1022
970
|
for (const selection of this.selections()) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
971
|
+
if (predicate(selection.element) || (selection.selectionSet && selection.selectionSet.some(predicate))) {
|
|
972
|
+
return true;
|
|
973
|
+
}
|
|
1026
974
|
}
|
|
1027
|
-
return
|
|
975
|
+
return false;
|
|
1028
976
|
}
|
|
1029
977
|
toOperationString(rootKind, variableDefinitions, operationName, expandFragments = false, prettyPrint = true) {
|
|
1030
978
|
const indent = prettyPrint ? '' : undefined;
|
|
@@ -1040,6 +988,9 @@ class SelectionSet extends Freezable {
|
|
|
1040
988
|
return fragmentsDefinitions + rootKind + nameAndVariables + " " + this.toString(expandFragments, true, indent);
|
|
1041
989
|
}
|
|
1042
990
|
toString(expandFragments = true, includeExternalBrackets = true, indent) {
|
|
991
|
+
if (this.isEmpty()) {
|
|
992
|
+
return '{}';
|
|
993
|
+
}
|
|
1043
994
|
if (indent === undefined) {
|
|
1044
995
|
const selectionsToString = this.selections().map(s => s.toString(expandFragments)).join(' ');
|
|
1045
996
|
return includeExternalBrackets ? '{ ' + selectionsToString + ' }' : selectionsToString;
|
|
@@ -1054,13 +1005,212 @@ class SelectionSet extends Freezable {
|
|
|
1054
1005
|
}
|
|
1055
1006
|
}
|
|
1056
1007
|
exports.SelectionSet = SelectionSet;
|
|
1008
|
+
class SelectionSetUpdates {
|
|
1009
|
+
constructor() {
|
|
1010
|
+
this.keyedUpdates = new utils_1.MultiMap;
|
|
1011
|
+
}
|
|
1012
|
+
isEmpty() {
|
|
1013
|
+
return this.keyedUpdates.size === 0;
|
|
1014
|
+
}
|
|
1015
|
+
add(selections) {
|
|
1016
|
+
addToKeyedUpdates(this.keyedUpdates, selections);
|
|
1017
|
+
return this;
|
|
1018
|
+
}
|
|
1019
|
+
addAtPath(path, selections) {
|
|
1020
|
+
if (path.length === 0) {
|
|
1021
|
+
if (selections) {
|
|
1022
|
+
addToKeyedUpdates(this.keyedUpdates, selections);
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
else {
|
|
1026
|
+
if (path.length === 1 && !selections) {
|
|
1027
|
+
const element = path[0];
|
|
1028
|
+
if (element.kind === 'Field' && element.isLeafField()) {
|
|
1029
|
+
const selection = selectionOfElement(element);
|
|
1030
|
+
this.keyedUpdates.add(selection.key(), selection);
|
|
1031
|
+
return this;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
this.keyedUpdates.add(path[0].key(), { path, selections });
|
|
1035
|
+
}
|
|
1036
|
+
return this;
|
|
1037
|
+
}
|
|
1038
|
+
clone() {
|
|
1039
|
+
const cloned = new SelectionSetUpdates();
|
|
1040
|
+
for (const [key, values] of this.keyedUpdates.entries()) {
|
|
1041
|
+
cloned.keyedUpdates.set(key, Array.from(values));
|
|
1042
|
+
}
|
|
1043
|
+
return cloned;
|
|
1044
|
+
}
|
|
1045
|
+
clear() {
|
|
1046
|
+
this.keyedUpdates.clear();
|
|
1047
|
+
}
|
|
1048
|
+
toSelectionSet(parentType, fragments) {
|
|
1049
|
+
return makeSelectionSet(parentType, this.keyedUpdates, fragments);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
exports.SelectionSetUpdates = SelectionSetUpdates;
|
|
1053
|
+
function addToKeyedUpdates(keyedUpdates, selections) {
|
|
1054
|
+
if (selections instanceof AbstractSelection) {
|
|
1055
|
+
addOneToKeyedUpdates(keyedUpdates, selections);
|
|
1056
|
+
}
|
|
1057
|
+
else {
|
|
1058
|
+
const toAdd = selections instanceof SelectionSet ? selections.selections() : selections;
|
|
1059
|
+
for (const selection of toAdd) {
|
|
1060
|
+
addOneToKeyedUpdates(keyedUpdates, selection);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
function addOneToKeyedUpdates(keyedUpdates, selection) {
|
|
1065
|
+
if (selection instanceof FragmentSpreadSelection) {
|
|
1066
|
+
keyedUpdates.set(selection.key(), [selection]);
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
keyedUpdates.add(selection.key(), selection);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
function isUnecessaryFragment(parentType, fragment) {
|
|
1073
|
+
return fragment.element.appliedDirectives.length === 0
|
|
1074
|
+
&& (!fragment.element.typeCondition || (0, types_1.sameType)(parentType, fragment.element.typeCondition));
|
|
1075
|
+
}
|
|
1076
|
+
function withUnecessaryFragmentsRemoved(parentType, selections) {
|
|
1077
|
+
if (selections instanceof AbstractSelection) {
|
|
1078
|
+
if (selections.kind !== 'FragmentSelection' || !isUnecessaryFragment(parentType, selections)) {
|
|
1079
|
+
return selections;
|
|
1080
|
+
}
|
|
1081
|
+
return withUnecessaryFragmentsRemoved(parentType, selections.selectionSet);
|
|
1082
|
+
}
|
|
1083
|
+
const toCheck = selections instanceof SelectionSet ? selections.selections() : selections;
|
|
1084
|
+
const filtered = [];
|
|
1085
|
+
for (const selection of toCheck) {
|
|
1086
|
+
if (selection.kind === 'FragmentSelection' && isUnecessaryFragment(parentType, selection)) {
|
|
1087
|
+
const subSelections = withUnecessaryFragmentsRemoved(parentType, selection.selectionSet);
|
|
1088
|
+
if (subSelections instanceof AbstractSelection) {
|
|
1089
|
+
filtered.push(subSelections);
|
|
1090
|
+
}
|
|
1091
|
+
else {
|
|
1092
|
+
for (const subSelection of subSelections) {
|
|
1093
|
+
filtered.push(subSelection);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
else {
|
|
1098
|
+
filtered.push(selection);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
return filtered;
|
|
1102
|
+
}
|
|
1103
|
+
function makeSelection(parentType, updates, fragments) {
|
|
1104
|
+
(0, utils_1.assert)(updates.length > 0, 'Should not be called without any updates');
|
|
1105
|
+
const first = updates[0];
|
|
1106
|
+
if (updates.length === 1 && first instanceof AbstractSelection) {
|
|
1107
|
+
return first.rebaseOn(parentType);
|
|
1108
|
+
}
|
|
1109
|
+
const element = updateElement(first).rebaseOn(parentType);
|
|
1110
|
+
const subSelectionParentType = element.kind === 'Field' ? (0, definitions_1.baseType)(element.definition.type) : element.castedType();
|
|
1111
|
+
if (!(0, definitions_1.isCompositeType)(subSelectionParentType)) {
|
|
1112
|
+
return selectionOfElement(element);
|
|
1113
|
+
}
|
|
1114
|
+
const subSelectionKeyedUpdates = new utils_1.MultiMap();
|
|
1115
|
+
for (const update of updates) {
|
|
1116
|
+
if (update instanceof AbstractSelection) {
|
|
1117
|
+
if (update.selectionSet) {
|
|
1118
|
+
addToKeyedUpdates(subSelectionKeyedUpdates, update.selectionSet);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
else {
|
|
1122
|
+
addSubpathToKeyUpdates(subSelectionKeyedUpdates, subSelectionParentType, update);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
return selectionOfElement(element, makeSelectionSet(subSelectionParentType, subSelectionKeyedUpdates, fragments));
|
|
1126
|
+
}
|
|
1127
|
+
function updateElement(update) {
|
|
1128
|
+
return update instanceof AbstractSelection ? update.element : update.path[0];
|
|
1129
|
+
}
|
|
1130
|
+
function addSubpathToKeyUpdates(keyedUpdates, subSelectionParentType, pathUpdate) {
|
|
1131
|
+
if (pathUpdate.path.length === 1) {
|
|
1132
|
+
if (!pathUpdate.selections) {
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
addToKeyedUpdates(keyedUpdates, withUnecessaryFragmentsRemoved(subSelectionParentType, pathUpdate.selections));
|
|
1136
|
+
}
|
|
1137
|
+
else {
|
|
1138
|
+
keyedUpdates.add(pathUpdate.path[1].key(), { path: pathUpdate.path.slice(1), selections: pathUpdate.selections });
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
function makeSelectionSet(parentType, keyedUpdates, fragments) {
|
|
1142
|
+
const selections = new Map();
|
|
1143
|
+
for (const [key, updates] of keyedUpdates.entries()) {
|
|
1144
|
+
selections.set(key, makeSelection(parentType, updates, fragments));
|
|
1145
|
+
}
|
|
1146
|
+
return new SelectionSet(parentType, selections, fragments);
|
|
1147
|
+
}
|
|
1148
|
+
class MutableSelectionSet {
|
|
1149
|
+
constructor(parentType, _updates, memoizer) {
|
|
1150
|
+
this.parentType = parentType;
|
|
1151
|
+
this._updates = _updates;
|
|
1152
|
+
this.memoizer = memoizer;
|
|
1153
|
+
}
|
|
1154
|
+
static empty(parentType) {
|
|
1155
|
+
return this.emptyWithMemoized(parentType, () => ({}));
|
|
1156
|
+
}
|
|
1157
|
+
static emptyWithMemoized(parentType, memoizer) {
|
|
1158
|
+
return new MutableSelectionSet(parentType, new SelectionSetUpdates(), memoizer);
|
|
1159
|
+
}
|
|
1160
|
+
static of(selectionSet) {
|
|
1161
|
+
return this.ofWithMemoized(selectionSet, () => ({}));
|
|
1162
|
+
}
|
|
1163
|
+
static ofWithMemoized(selectionSet, memoizer) {
|
|
1164
|
+
const s = new MutableSelectionSet(selectionSet.parentType, new SelectionSetUpdates(), memoizer);
|
|
1165
|
+
s._updates.add(selectionSet);
|
|
1166
|
+
s.computed = selectionSet;
|
|
1167
|
+
return s;
|
|
1168
|
+
}
|
|
1169
|
+
isEmpty() {
|
|
1170
|
+
return this._updates.isEmpty();
|
|
1171
|
+
}
|
|
1172
|
+
get() {
|
|
1173
|
+
if (!this.computed) {
|
|
1174
|
+
this.computed = this._updates.toSelectionSet(this.parentType);
|
|
1175
|
+
this._updates.clear();
|
|
1176
|
+
this._updates.add(this.computed);
|
|
1177
|
+
}
|
|
1178
|
+
return this.computed;
|
|
1179
|
+
}
|
|
1180
|
+
updates() {
|
|
1181
|
+
this.computed = undefined;
|
|
1182
|
+
this._memoized = undefined;
|
|
1183
|
+
return this._updates;
|
|
1184
|
+
}
|
|
1185
|
+
clone() {
|
|
1186
|
+
const cloned = new MutableSelectionSet(this.parentType, this._updates.clone(), this.memoizer);
|
|
1187
|
+
cloned.computed = this.computed;
|
|
1188
|
+
cloned._memoized = this._memoized;
|
|
1189
|
+
return cloned;
|
|
1190
|
+
}
|
|
1191
|
+
rebaseOn(parentType) {
|
|
1192
|
+
const rebased = new MutableSelectionSet(parentType, new SelectionSetUpdates(), this.memoizer);
|
|
1193
|
+
rebased._updates.add(this.get());
|
|
1194
|
+
return rebased;
|
|
1195
|
+
}
|
|
1196
|
+
memoized() {
|
|
1197
|
+
if (!this._memoized) {
|
|
1198
|
+
this._memoized = this.memoizer(this.get());
|
|
1199
|
+
}
|
|
1200
|
+
return this._memoized;
|
|
1201
|
+
}
|
|
1202
|
+
toString() {
|
|
1203
|
+
return this.get().toString();
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
exports.MutableSelectionSet = MutableSelectionSet;
|
|
1057
1207
|
function allFieldDefinitionsInSelectionSet(selection) {
|
|
1058
1208
|
const stack = Array.from(selection.selections());
|
|
1059
1209
|
const allFields = [];
|
|
1060
1210
|
while (stack.length > 0) {
|
|
1061
1211
|
const selection = stack.pop();
|
|
1062
1212
|
if (selection.kind === 'FieldSelection') {
|
|
1063
|
-
allFields.push(selection.
|
|
1213
|
+
allFields.push(selection.element.definition);
|
|
1064
1214
|
}
|
|
1065
1215
|
if (selection.selectionSet) {
|
|
1066
1216
|
stack.push(...selection.selectionSet.selections());
|
|
@@ -1069,59 +1219,137 @@ function allFieldDefinitionsInSelectionSet(selection) {
|
|
|
1069
1219
|
return allFields;
|
|
1070
1220
|
}
|
|
1071
1221
|
exports.allFieldDefinitionsInSelectionSet = allFieldDefinitionsInSelectionSet;
|
|
1072
|
-
function
|
|
1073
|
-
const
|
|
1074
|
-
|
|
1075
|
-
return
|
|
1222
|
+
function selectionSetOf(parentType, selection, fragments) {
|
|
1223
|
+
const map = new Map();
|
|
1224
|
+
map.set(selection.key(), selection);
|
|
1225
|
+
return new SelectionSet(parentType, map, fragments);
|
|
1226
|
+
}
|
|
1227
|
+
exports.selectionSetOf = selectionSetOf;
|
|
1228
|
+
function selectionSetOfElement(element, subSelection, fragments) {
|
|
1229
|
+
return selectionSetOf(element.parentType, selectionOfElement(element, subSelection), fragments);
|
|
1076
1230
|
}
|
|
1077
1231
|
exports.selectionSetOfElement = selectionSetOfElement;
|
|
1078
1232
|
function selectionOfElement(element, subSelection) {
|
|
1079
1233
|
return element.kind === 'Field' ? new FieldSelection(element, subSelection) : new InlineFragmentSelection(element, subSelection);
|
|
1080
1234
|
}
|
|
1081
1235
|
exports.selectionOfElement = selectionOfElement;
|
|
1082
|
-
class
|
|
1083
|
-
constructor(
|
|
1084
|
-
|
|
1085
|
-
this.field = field;
|
|
1086
|
-
this.kind = 'FieldSelection';
|
|
1087
|
-
const type = (0, definitions_1.baseType)(field.definition.type);
|
|
1088
|
-
this.selectionSet = (0, definitions_1.isLeafType)(type) ? undefined : (initialSelectionSet ? initialSelectionSet.cloneIfFrozen() : new SelectionSet(type));
|
|
1236
|
+
class AbstractSelection {
|
|
1237
|
+
constructor(element) {
|
|
1238
|
+
this.element = element;
|
|
1089
1239
|
}
|
|
1090
1240
|
get parentType() {
|
|
1091
|
-
return this.
|
|
1241
|
+
return this.element.parentType;
|
|
1092
1242
|
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1243
|
+
collectVariables(collector) {
|
|
1244
|
+
var _a;
|
|
1245
|
+
this.element.collectVariables(collector);
|
|
1246
|
+
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.collectVariables(collector);
|
|
1095
1247
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1248
|
+
collectUsedFragmentNames(collector) {
|
|
1249
|
+
var _a;
|
|
1250
|
+
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.collectUsedFragmentNames(collector);
|
|
1098
1251
|
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1252
|
+
namedFragments() {
|
|
1253
|
+
var _a;
|
|
1254
|
+
return (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.fragments;
|
|
1101
1255
|
}
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
return (0, definitions_1.mergeVariables)(this.element().variables(), (_b = (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.usedVariables()) !== null && _b !== void 0 ? _b : []);
|
|
1256
|
+
withUpdatedSelectionSet(selectionSet) {
|
|
1257
|
+
return this.withUpdatedComponents(this.element, selectionSet);
|
|
1105
1258
|
}
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1259
|
+
withUpdatedElement(element) {
|
|
1260
|
+
return this.withUpdatedComponents(element, this.selectionSet);
|
|
1261
|
+
}
|
|
1262
|
+
mapToSelectionSet(mapper) {
|
|
1263
|
+
if (!this.selectionSet) {
|
|
1264
|
+
return this.us();
|
|
1265
|
+
}
|
|
1266
|
+
const updatedSelectionSet = mapper(this.selectionSet);
|
|
1267
|
+
return updatedSelectionSet === this.selectionSet
|
|
1268
|
+
? this.us()
|
|
1269
|
+
: this.withUpdatedSelectionSet(updatedSelectionSet);
|
|
1270
|
+
}
|
|
1271
|
+
minus(that) {
|
|
1272
|
+
if (this.selectionSet && that.selectionSet) {
|
|
1273
|
+
const updatedSubSelectionSet = this.selectionSet.minus(that.selectionSet);
|
|
1274
|
+
if (!updatedSubSelectionSet.isEmpty()) {
|
|
1275
|
+
return this.withUpdatedSelectionSet(updatedSubSelectionSet);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
return undefined;
|
|
1279
|
+
}
|
|
1280
|
+
tryOptimizeSubselectionOnce(_) {
|
|
1281
|
+
(0, utils_1.assert)(false, `UNSUPPORTED`);
|
|
1282
|
+
}
|
|
1283
|
+
tryOptimizeSubselectionWithFragments({ parentType, subSelection, fragments, fragmentFilter, }) {
|
|
1284
|
+
let candidates = fragments.maybeApplyingAtType(parentType);
|
|
1285
|
+
if (fragmentFilter) {
|
|
1286
|
+
candidates = candidates.filter(fragmentFilter);
|
|
1109
1287
|
}
|
|
1288
|
+
let shouldTryAgain;
|
|
1289
|
+
do {
|
|
1290
|
+
const { spread, optimizedSelection, hasDiff } = this.tryOptimizeSubselectionOnce({ parentType, subSelection, candidates, fragments });
|
|
1291
|
+
if (optimizedSelection) {
|
|
1292
|
+
subSelection = optimizedSelection;
|
|
1293
|
+
}
|
|
1294
|
+
else if (spread) {
|
|
1295
|
+
return spread;
|
|
1296
|
+
}
|
|
1297
|
+
shouldTryAgain = !!spread && !!hasDiff;
|
|
1298
|
+
if (shouldTryAgain) {
|
|
1299
|
+
candidates = candidates.filter((c) => c !== (spread === null || spread === void 0 ? void 0 : spread.namedFragment));
|
|
1300
|
+
}
|
|
1301
|
+
} while (shouldTryAgain);
|
|
1302
|
+
return subSelection;
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
class FieldSelection extends AbstractSelection {
|
|
1306
|
+
constructor(field, _selectionSet) {
|
|
1307
|
+
super(field);
|
|
1308
|
+
this._selectionSet = _selectionSet;
|
|
1309
|
+
this.kind = 'FieldSelection';
|
|
1310
|
+
}
|
|
1311
|
+
get selectionSet() {
|
|
1312
|
+
return this._selectionSet;
|
|
1313
|
+
}
|
|
1314
|
+
us() {
|
|
1315
|
+
return this;
|
|
1316
|
+
}
|
|
1317
|
+
withUpdatedComponents(field, selectionSet) {
|
|
1318
|
+
return new FieldSelection(field, selectionSet);
|
|
1319
|
+
}
|
|
1320
|
+
key() {
|
|
1321
|
+
return this.element.key();
|
|
1110
1322
|
}
|
|
1111
1323
|
optimize(fragments) {
|
|
1112
|
-
|
|
1113
|
-
const fieldBaseType = (0, definitions_1.baseType)(this.
|
|
1324
|
+
let optimizedSelection = this.selectionSet ? this.selectionSet.optimize(fragments) : undefined;
|
|
1325
|
+
const fieldBaseType = (0, definitions_1.baseType)(this.element.definition.type);
|
|
1114
1326
|
if ((0, definitions_1.isCompositeType)(fieldBaseType) && optimizedSelection) {
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
}
|
|
1327
|
+
const optimized = this.tryOptimizeSubselectionWithFragments({
|
|
1328
|
+
parentType: fieldBaseType,
|
|
1329
|
+
subSelection: optimizedSelection,
|
|
1330
|
+
fragments,
|
|
1331
|
+
fragmentFilter: (f) => f.appliedDirectives.length === 0,
|
|
1332
|
+
});
|
|
1333
|
+
(0, utils_1.assert)(!(optimized instanceof FragmentSpreadSelection), 'tryOptimizeSubselectionOnce should never return only a spread');
|
|
1334
|
+
optimizedSelection = optimized;
|
|
1121
1335
|
}
|
|
1122
1336
|
return this.selectionSet === optimizedSelection
|
|
1123
1337
|
? this
|
|
1124
|
-
: new FieldSelection(this.
|
|
1338
|
+
: new FieldSelection(this.element, optimizedSelection);
|
|
1339
|
+
}
|
|
1340
|
+
tryOptimizeSubselectionOnce({ parentType, subSelection, candidates, fragments, }) {
|
|
1341
|
+
let optimizedSelection = subSelection;
|
|
1342
|
+
for (const candidate of candidates) {
|
|
1343
|
+
const { contains, diff } = optimizedSelection.diffIfContains(candidate.selectionSet);
|
|
1344
|
+
if (contains) {
|
|
1345
|
+
const spread = new FragmentSpreadSelection(parentType, fragments, candidate, []);
|
|
1346
|
+
optimizedSelection = diff
|
|
1347
|
+
? new SelectionSetUpdates().add(spread).add(diff).toSelectionSet(parentType, fragments)
|
|
1348
|
+
: selectionSetOf(parentType, spread);
|
|
1349
|
+
return { spread, optimizedSelection, hasDiff: !!diff };
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
return {};
|
|
1125
1353
|
}
|
|
1126
1354
|
filter(predicate) {
|
|
1127
1355
|
if (!this.selectionSet) {
|
|
@@ -1130,99 +1358,96 @@ class FieldSelection extends Freezable {
|
|
|
1130
1358
|
const updatedSelectionSet = this.selectionSet.filter(predicate);
|
|
1131
1359
|
const thisWithFilteredSelectionSet = this.selectionSet === updatedSelectionSet
|
|
1132
1360
|
? this
|
|
1133
|
-
: new FieldSelection(this.
|
|
1361
|
+
: new FieldSelection(this.element, updatedSelectionSet);
|
|
1134
1362
|
return predicate(thisWithFilteredSelectionSet) ? thisWithFilteredSelectionSet : undefined;
|
|
1135
1363
|
}
|
|
1136
|
-
|
|
1364
|
+
validate(variableDefinitions) {
|
|
1137
1365
|
var _a;
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
const expandedSelection = this.selectionSet ? this.selectionSet.expandFragments(names, updateSelectionSetFragments) : undefined;
|
|
1142
|
-
return this.selectionSet === expandedSelection
|
|
1143
|
-
? this
|
|
1144
|
-
: new FieldSelection(this.field, expandedSelection);
|
|
1366
|
+
this.element.validate(variableDefinitions);
|
|
1367
|
+
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);
|
|
1368
|
+
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.validate(variableDefinitions);
|
|
1145
1369
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
return undefined;
|
|
1370
|
+
rebaseOn(parentType) {
|
|
1371
|
+
if (this.element.parentType === parentType) {
|
|
1372
|
+
return this;
|
|
1150
1373
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
name: { kind: graphql_1.Kind.NAME, value: n },
|
|
1155
|
-
value: (0, values_1.valueToAST)(v, this.field.definition.argument(n).type),
|
|
1156
|
-
};
|
|
1157
|
-
});
|
|
1158
|
-
}
|
|
1159
|
-
validate() {
|
|
1160
|
-
var _a;
|
|
1161
|
-
this.field.validate();
|
|
1162
|
-
validate(!(this.selectionSet && this.selectionSet.isEmpty()), () => `Invalid empty selection set for field "${this.field.definition.coordinate}" of non-leaf type ${this.field.definition.type}`, this.field.definition.sourceAST);
|
|
1163
|
-
(_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.validate();
|
|
1164
|
-
}
|
|
1165
|
-
updateForAddingTo(selectionSet) {
|
|
1166
|
-
var _a;
|
|
1167
|
-
const updatedField = this.field.updateForAddingTo(selectionSet);
|
|
1168
|
-
if (this.field === updatedField) {
|
|
1169
|
-
return this.cloneIfFrozen();
|
|
1170
|
-
}
|
|
1171
|
-
const updatedBaseType = (0, definitions_1.baseType)(updatedField.definition.type);
|
|
1172
|
-
let updatedSelectionSet;
|
|
1173
|
-
if (this.selectionSet && this.selectionSet.parentType !== updatedBaseType) {
|
|
1174
|
-
(0, utils_1.assert)((0, definitions_1.isCompositeType)(updatedBaseType), `Expected ${updatedBaseType.coordinate} to be composite but ${updatedBaseType.kind}`);
|
|
1175
|
-
updatedSelectionSet = new SelectionSet(updatedBaseType);
|
|
1176
|
-
for (const selection of this.selectionSet.selections()) {
|
|
1177
|
-
updatedSelectionSet.add(selection);
|
|
1178
|
-
}
|
|
1374
|
+
const rebasedElement = this.element.rebaseOn(parentType);
|
|
1375
|
+
if (!this.selectionSet) {
|
|
1376
|
+
return this.withUpdatedElement(rebasedElement);
|
|
1179
1377
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1378
|
+
const rebasedBase = (0, definitions_1.baseType)(rebasedElement.definition.type);
|
|
1379
|
+
if (rebasedBase === this.selectionSet.parentType) {
|
|
1380
|
+
return this.withUpdatedElement(rebasedElement);
|
|
1182
1381
|
}
|
|
1183
|
-
|
|
1382
|
+
validate((0, definitions_1.isCompositeType)(rebasedBase), () => `Cannot rebase field selection ${this} on ${parentType}: rebased field base return type ${rebasedBase} is not composite`);
|
|
1383
|
+
return this.withUpdatedComponents(rebasedElement, this.selectionSet.rebaseOn(rebasedBase));
|
|
1184
1384
|
}
|
|
1185
1385
|
canAddTo(parentType) {
|
|
1186
|
-
if (this.
|
|
1386
|
+
if (this.element.parentType === parentType) {
|
|
1187
1387
|
return true;
|
|
1188
1388
|
}
|
|
1189
|
-
const type = this.
|
|
1389
|
+
const type = this.element.typeIfAddedTo(parentType);
|
|
1190
1390
|
if (!type) {
|
|
1191
1391
|
return false;
|
|
1192
1392
|
}
|
|
1193
1393
|
const base = (0, definitions_1.baseType)(type);
|
|
1194
1394
|
if (this.selectionSet && this.selectionSet.parentType !== base) {
|
|
1195
|
-
(0, utils_1.assert)((0, definitions_1.isCompositeType)(base), () => `${this.
|
|
1395
|
+
(0, utils_1.assert)((0, definitions_1.isCompositeType)(base), () => `${this.element} should have a selection set as it's type is not a composite`);
|
|
1196
1396
|
return this.selectionSet.selections().every((s) => s.canAddTo(base));
|
|
1197
1397
|
}
|
|
1198
1398
|
return true;
|
|
1199
1399
|
}
|
|
1200
1400
|
toSelectionNode() {
|
|
1201
1401
|
var _a;
|
|
1202
|
-
const alias = this.
|
|
1402
|
+
const alias = this.element.alias ? { kind: graphql_1.Kind.NAME, value: this.element.alias, } : undefined;
|
|
1203
1403
|
return {
|
|
1204
1404
|
kind: graphql_1.Kind.FIELD,
|
|
1205
1405
|
name: {
|
|
1206
1406
|
kind: graphql_1.Kind.NAME,
|
|
1207
|
-
value: this.
|
|
1407
|
+
value: this.element.name,
|
|
1208
1408
|
},
|
|
1209
1409
|
alias,
|
|
1210
|
-
arguments: this.
|
|
1211
|
-
directives: this.element
|
|
1410
|
+
arguments: this.element.argumentsToNodes(),
|
|
1411
|
+
directives: this.element.appliedDirectivesToDirectiveNodes(),
|
|
1212
1412
|
selectionSet: (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.toSelectionSetNode()
|
|
1213
1413
|
};
|
|
1214
1414
|
}
|
|
1215
|
-
|
|
1216
|
-
return
|
|
1415
|
+
withoutDefer(labelsToRemove) {
|
|
1416
|
+
return this.mapToSelectionSet((s) => s.withoutDefer(labelsToRemove));
|
|
1417
|
+
}
|
|
1418
|
+
withNormalizedDefer(normalizer) {
|
|
1419
|
+
return this.mapToSelectionSet((s) => s.withNormalizedDefer(normalizer));
|
|
1420
|
+
}
|
|
1421
|
+
hasDefer() {
|
|
1422
|
+
var _a;
|
|
1423
|
+
return !!((_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.hasDefer());
|
|
1424
|
+
}
|
|
1425
|
+
expandAllFragments() {
|
|
1426
|
+
return this.mapToSelectionSet((s) => s.expandAllFragments());
|
|
1427
|
+
}
|
|
1428
|
+
trimUnsatisfiableBranches(_) {
|
|
1429
|
+
var _a;
|
|
1430
|
+
if (!this.selectionSet) {
|
|
1431
|
+
return this;
|
|
1432
|
+
}
|
|
1433
|
+
const base = (0, definitions_1.baseType)(this.element.definition.type);
|
|
1434
|
+
(0, utils_1.assert)((0, definitions_1.isCompositeType)(base), () => `Field ${this.element} should not have a sub-selection`);
|
|
1435
|
+
const trimmed = this.mapToSelectionSet((s) => s.trimUnsatisfiableBranches(base));
|
|
1436
|
+
if ((_a = trimmed.selectionSet) === null || _a === void 0 ? void 0 : _a.isEmpty()) {
|
|
1437
|
+
return trimmed.withUpdatedSelectionSet(selectionSetOfElement(new Field(base.typenameField(), undefined, [new definitions_1.Directive('include', { 'if': false })])));
|
|
1438
|
+
}
|
|
1439
|
+
else {
|
|
1440
|
+
return trimmed;
|
|
1441
|
+
}
|
|
1217
1442
|
}
|
|
1218
|
-
|
|
1219
|
-
return
|
|
1443
|
+
expandFragments(names, updatedFragments) {
|
|
1444
|
+
return this.mapToSelectionSet((s) => s.expandFragments(names, updatedFragments));
|
|
1220
1445
|
}
|
|
1221
1446
|
equals(that) {
|
|
1222
1447
|
if (this === that) {
|
|
1223
1448
|
return true;
|
|
1224
1449
|
}
|
|
1225
|
-
if (!(that instanceof FieldSelection) || !this.
|
|
1450
|
+
if (!(that instanceof FieldSelection) || !this.element.equals(that.element)) {
|
|
1226
1451
|
return false;
|
|
1227
1452
|
}
|
|
1228
1453
|
if (!this.selectionSet) {
|
|
@@ -1231,7 +1456,7 @@ class FieldSelection extends Freezable {
|
|
|
1231
1456
|
return !!that.selectionSet && this.selectionSet.equals(that.selectionSet);
|
|
1232
1457
|
}
|
|
1233
1458
|
contains(that) {
|
|
1234
|
-
if (!(that instanceof FieldSelection) || !this.
|
|
1459
|
+
if (!(that instanceof FieldSelection) || !this.element.equals(that.element)) {
|
|
1235
1460
|
return false;
|
|
1236
1461
|
}
|
|
1237
1462
|
if (!that.selectionSet) {
|
|
@@ -1239,126 +1464,83 @@ class FieldSelection extends Freezable {
|
|
|
1239
1464
|
}
|
|
1240
1465
|
return !!this.selectionSet && this.selectionSet.contains(that.selectionSet);
|
|
1241
1466
|
}
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
return (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.fragments;
|
|
1245
|
-
}
|
|
1246
|
-
withoutDefer(labelsToRemove) {
|
|
1247
|
-
var _a;
|
|
1248
|
-
const updatedSubSelections = (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.withoutDefer(labelsToRemove);
|
|
1249
|
-
return updatedSubSelections === this.selectionSet
|
|
1250
|
-
? this
|
|
1251
|
-
: new FieldSelection(this.field, updatedSubSelections);
|
|
1252
|
-
}
|
|
1253
|
-
withNormalizedDefer(normalizer) {
|
|
1254
|
-
var _a;
|
|
1255
|
-
const updatedSubSelections = (_a = this.selectionSet) === null || _a === void 0 ? void 0 : _a.withNormalizedDefer(normalizer);
|
|
1256
|
-
return updatedSubSelections === this.selectionSet
|
|
1257
|
-
? this
|
|
1258
|
-
: new FieldSelection(this.field, updatedSubSelections);
|
|
1259
|
-
}
|
|
1260
|
-
clone() {
|
|
1261
|
-
if (!this.selectionSet) {
|
|
1262
|
-
return this;
|
|
1263
|
-
}
|
|
1264
|
-
return new FieldSelection(this.field, this.selectionSet.clone());
|
|
1467
|
+
isUnecessaryInlineFragment(_) {
|
|
1468
|
+
return false;
|
|
1265
1469
|
}
|
|
1266
1470
|
toString(expandFragments = true, indent) {
|
|
1267
|
-
return (indent !== null && indent !== void 0 ? indent : '') + this.
|
|
1471
|
+
return (indent !== null && indent !== void 0 ? indent : '') + this.element + (this.selectionSet ? ' ' + this.selectionSet.toString(expandFragments, true, indent) : '');
|
|
1268
1472
|
}
|
|
1269
1473
|
}
|
|
1270
1474
|
exports.FieldSelection = FieldSelection;
|
|
1271
|
-
class FragmentSelection extends
|
|
1475
|
+
class FragmentSelection extends AbstractSelection {
|
|
1272
1476
|
constructor() {
|
|
1273
1477
|
super(...arguments);
|
|
1274
1478
|
this.kind = 'FragmentSelection';
|
|
1275
1479
|
}
|
|
1276
|
-
get parentType() {
|
|
1277
|
-
return this.element().parentType;
|
|
1278
|
-
}
|
|
1279
1480
|
us() {
|
|
1280
1481
|
return this;
|
|
1281
1482
|
}
|
|
1282
1483
|
validateDeferAndStream() {
|
|
1283
|
-
if (this.element
|
|
1284
|
-
const schemaDef = this.element
|
|
1285
|
-
const parentType = this.
|
|
1484
|
+
if (this.element.hasDefer() || this.element.hasStream()) {
|
|
1485
|
+
const schemaDef = this.element.schema().schemaDefinition;
|
|
1486
|
+
const parentType = this.parentType;
|
|
1286
1487
|
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}"`; });
|
|
1287
1488
|
}
|
|
1288
1489
|
}
|
|
1289
|
-
usedVariables() {
|
|
1290
|
-
return (0, definitions_1.mergeVariables)(this.element().variables(), this.selectionSet.usedVariables());
|
|
1291
|
-
}
|
|
1292
1490
|
filter(predicate) {
|
|
1293
1491
|
const selectionSet = this.selectionSet;
|
|
1294
1492
|
const updatedSelectionSet = selectionSet.filter(predicate);
|
|
1295
1493
|
const thisWithFilteredSelectionSet = updatedSelectionSet === selectionSet
|
|
1296
1494
|
? this
|
|
1297
|
-
: new InlineFragmentSelection(this.element
|
|
1495
|
+
: new InlineFragmentSelection(this.element, updatedSelectionSet);
|
|
1298
1496
|
return predicate(thisWithFilteredSelectionSet) ? thisWithFilteredSelectionSet : undefined;
|
|
1299
1497
|
}
|
|
1300
|
-
|
|
1301
|
-
this.selectionSet.
|
|
1302
|
-
}
|
|
1303
|
-
equals(that) {
|
|
1304
|
-
if (this === that) {
|
|
1305
|
-
return true;
|
|
1306
|
-
}
|
|
1307
|
-
return (that instanceof FragmentSelection)
|
|
1308
|
-
&& this.element().equals(that.element())
|
|
1309
|
-
&& this.selectionSet.equals(that.selectionSet);
|
|
1310
|
-
}
|
|
1311
|
-
contains(that) {
|
|
1312
|
-
return (that instanceof FragmentSelection)
|
|
1313
|
-
&& this.element().equals(that.element())
|
|
1314
|
-
&& this.selectionSet.contains(that.selectionSet);
|
|
1498
|
+
hasDefer() {
|
|
1499
|
+
return this.element.hasDefer() || this.selectionSet.hasDefer();
|
|
1315
1500
|
}
|
|
1316
|
-
|
|
1317
|
-
return
|
|
1501
|
+
isUnecessaryInlineFragment(parentType) {
|
|
1502
|
+
return this.element.appliedDirectives.length === 0
|
|
1503
|
+
&& !!this.element.typeCondition
|
|
1504
|
+
&& (this.element.typeCondition.name === parentType.name
|
|
1505
|
+
|| ((0, definitions_1.isObjectType)(parentType) && (0, definitions_1.possibleRuntimeTypes)(this.element.typeCondition).some((t) => t.name === parentType.name)));
|
|
1318
1506
|
}
|
|
1319
1507
|
}
|
|
1320
1508
|
exports.FragmentSelection = FragmentSelection;
|
|
1321
1509
|
class InlineFragmentSelection extends FragmentSelection {
|
|
1322
|
-
constructor(
|
|
1323
|
-
super();
|
|
1324
|
-
this.
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1510
|
+
constructor(fragment, _selectionSet) {
|
|
1511
|
+
super(fragment);
|
|
1512
|
+
this._selectionSet = _selectionSet;
|
|
1513
|
+
}
|
|
1514
|
+
get selectionSet() {
|
|
1515
|
+
return this._selectionSet;
|
|
1328
1516
|
}
|
|
1329
1517
|
key() {
|
|
1330
|
-
|
|
1331
|
-
return (_b = (_a = this.element().typeCondition) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '';
|
|
1518
|
+
return this.element.key();
|
|
1332
1519
|
}
|
|
1333
|
-
|
|
1520
|
+
withUpdatedComponents(fragment, selectionSet) {
|
|
1521
|
+
return new InlineFragmentSelection(fragment, selectionSet);
|
|
1522
|
+
}
|
|
1523
|
+
validate(variableDefinitions) {
|
|
1334
1524
|
this.validateDeferAndStream();
|
|
1335
|
-
validate(!this.selectionSet.isEmpty(), () => `Invalid empty selection set for fragment "${this.element
|
|
1336
|
-
this.selectionSet.validate();
|
|
1525
|
+
validate(!this.selectionSet.isEmpty(), () => `Invalid empty selection set for fragment "${this.element}"`);
|
|
1526
|
+
this.selectionSet.validate(variableDefinitions);
|
|
1337
1527
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
if (this.element() === updatedFragment) {
|
|
1342
|
-
return this.cloneIfFrozen();
|
|
1343
|
-
}
|
|
1344
|
-
const updatedCastedType = updatedFragment.castedType();
|
|
1345
|
-
let updatedSelectionSet;
|
|
1346
|
-
if (this.selectionSet.parentType !== updatedCastedType) {
|
|
1347
|
-
updatedSelectionSet = new SelectionSet(updatedCastedType);
|
|
1348
|
-
for (const selection of this.selectionSet.selections()) {
|
|
1349
|
-
updatedSelectionSet.add(selection);
|
|
1350
|
-
}
|
|
1528
|
+
rebaseOn(parentType) {
|
|
1529
|
+
if (this.parentType === parentType) {
|
|
1530
|
+
return this;
|
|
1351
1531
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1532
|
+
const rebasedFragment = this.element.rebaseOn(parentType);
|
|
1533
|
+
const rebasedCastedType = rebasedFragment.castedType();
|
|
1534
|
+
if (rebasedCastedType === this.selectionSet.parentType) {
|
|
1535
|
+
return this.withUpdatedElement(rebasedFragment);
|
|
1354
1536
|
}
|
|
1355
|
-
return
|
|
1537
|
+
return this.withUpdatedComponents(rebasedFragment, this.selectionSet.rebaseOn(rebasedCastedType));
|
|
1356
1538
|
}
|
|
1357
1539
|
canAddTo(parentType) {
|
|
1358
|
-
if (this.element
|
|
1540
|
+
if (this.element.parentType === parentType) {
|
|
1359
1541
|
return true;
|
|
1360
1542
|
}
|
|
1361
|
-
const type = this.element
|
|
1543
|
+
const type = this.element.castedTypeIfAddedTo(parentType);
|
|
1362
1544
|
if (!type) {
|
|
1363
1545
|
return false;
|
|
1364
1546
|
}
|
|
@@ -1367,17 +1549,8 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1367
1549
|
}
|
|
1368
1550
|
return true;
|
|
1369
1551
|
}
|
|
1370
|
-
get selectionSet() {
|
|
1371
|
-
return this._selectionSet;
|
|
1372
|
-
}
|
|
1373
|
-
namedFragments() {
|
|
1374
|
-
return this.selectionSet.fragments;
|
|
1375
|
-
}
|
|
1376
|
-
element() {
|
|
1377
|
-
return this.fragmentElement;
|
|
1378
|
-
}
|
|
1379
1552
|
toSelectionNode() {
|
|
1380
|
-
const typeCondition = this.element
|
|
1553
|
+
const typeCondition = this.element.typeCondition;
|
|
1381
1554
|
return {
|
|
1382
1555
|
kind: graphql_1.Kind.INLINE_FRAGMENT,
|
|
1383
1556
|
typeCondition: typeCondition
|
|
@@ -1389,103 +1562,195 @@ class InlineFragmentSelection extends FragmentSelection {
|
|
|
1389
1562
|
},
|
|
1390
1563
|
}
|
|
1391
1564
|
: undefined,
|
|
1392
|
-
directives: this.element
|
|
1565
|
+
directives: this.element.appliedDirectivesToDirectiveNodes(),
|
|
1393
1566
|
selectionSet: this.selectionSet.toSelectionSetNode()
|
|
1394
1567
|
};
|
|
1395
1568
|
}
|
|
1396
1569
|
optimize(fragments) {
|
|
1397
1570
|
let optimizedSelection = this.selectionSet.optimize(fragments);
|
|
1398
|
-
const typeCondition = this.element
|
|
1571
|
+
const typeCondition = this.element.typeCondition;
|
|
1399
1572
|
if (typeCondition) {
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
return spread;
|
|
1408
|
-
}
|
|
1409
|
-
optimizedSelection = selectionSetOf(spread.element().parentType, spread);
|
|
1410
|
-
break;
|
|
1411
|
-
}
|
|
1573
|
+
const optimized = this.tryOptimizeSubselectionWithFragments({
|
|
1574
|
+
parentType: typeCondition,
|
|
1575
|
+
subSelection: optimizedSelection,
|
|
1576
|
+
fragments,
|
|
1577
|
+
});
|
|
1578
|
+
if (optimized instanceof FragmentSpreadSelection) {
|
|
1579
|
+
return optimized;
|
|
1412
1580
|
}
|
|
1581
|
+
optimizedSelection = optimized;
|
|
1413
1582
|
}
|
|
1414
1583
|
return this.selectionSet === optimizedSelection
|
|
1415
1584
|
? this
|
|
1416
|
-
: new InlineFragmentSelection(this.
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1585
|
+
: new InlineFragmentSelection(this.element, optimizedSelection);
|
|
1586
|
+
}
|
|
1587
|
+
tryOptimizeSubselectionOnce({ parentType, subSelection, candidates, fragments, }) {
|
|
1588
|
+
let optimizedSelection = subSelection;
|
|
1589
|
+
for (const candidate of candidates) {
|
|
1590
|
+
const { contains, diff } = optimizedSelection.diffIfContains(candidate.selectionSet);
|
|
1591
|
+
if (contains) {
|
|
1592
|
+
if (!diff && (0, types_1.sameType)(this.element.typeCondition, candidate.typeCondition)) {
|
|
1593
|
+
let spreadDirectives = this.element.appliedDirectives;
|
|
1594
|
+
if (candidate.appliedDirectives.length > 0) {
|
|
1595
|
+
const { isSubset, difference } = diffDirectives(this.element.appliedDirectives, candidate.appliedDirectives);
|
|
1596
|
+
if (!isSubset) {
|
|
1597
|
+
continue;
|
|
1598
|
+
}
|
|
1599
|
+
spreadDirectives = difference;
|
|
1600
|
+
}
|
|
1601
|
+
return {
|
|
1602
|
+
spread: new FragmentSpreadSelection(this.parentType, fragments, candidate, spreadDirectives),
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
if (candidate.appliedDirectives.length > 0) {
|
|
1606
|
+
continue;
|
|
1607
|
+
}
|
|
1608
|
+
const spread = new FragmentSpreadSelection(parentType, fragments, candidate, []);
|
|
1609
|
+
optimizedSelection = diff
|
|
1610
|
+
? new SelectionSetUpdates().add(spread).add(diff).toSelectionSet(parentType, fragments)
|
|
1611
|
+
: selectionSetOf(parentType, spread);
|
|
1612
|
+
return { spread, optimizedSelection, hasDiff: !!diff };
|
|
1613
|
+
}
|
|
1614
|
+
}
|
|
1615
|
+
return {};
|
|
1426
1616
|
}
|
|
1427
1617
|
withoutDefer(labelsToRemove) {
|
|
1428
|
-
const
|
|
1429
|
-
const deferArgs = this.
|
|
1618
|
+
const newSelection = this.selectionSet.withoutDefer(labelsToRemove);
|
|
1619
|
+
const deferArgs = this.element.deferDirectiveArgs();
|
|
1430
1620
|
const hasDeferToRemove = deferArgs && (!labelsToRemove || (deferArgs.label && labelsToRemove.has(deferArgs.label)));
|
|
1431
|
-
if (
|
|
1621
|
+
if (newSelection === this.selectionSet && !hasDeferToRemove) {
|
|
1432
1622
|
return this;
|
|
1433
1623
|
}
|
|
1434
|
-
const
|
|
1435
|
-
if (!
|
|
1436
|
-
return
|
|
1624
|
+
const newElement = hasDeferToRemove ? this.element.withoutDefer() : this.element;
|
|
1625
|
+
if (!newElement) {
|
|
1626
|
+
return newSelection;
|
|
1437
1627
|
}
|
|
1438
|
-
return
|
|
1628
|
+
return this.withUpdatedComponents(newElement, newSelection);
|
|
1439
1629
|
}
|
|
1440
1630
|
withNormalizedDefer(normalizer) {
|
|
1441
|
-
const
|
|
1442
|
-
const
|
|
1443
|
-
if (!
|
|
1444
|
-
return
|
|
1631
|
+
const newElement = this.element.withNormalizedDefer(normalizer);
|
|
1632
|
+
const newSelection = this.selectionSet.withNormalizedDefer(normalizer);
|
|
1633
|
+
if (!newElement) {
|
|
1634
|
+
return newSelection;
|
|
1445
1635
|
}
|
|
1446
|
-
return
|
|
1636
|
+
return newElement === this.element && newSelection === this.selectionSet
|
|
1447
1637
|
? this
|
|
1448
|
-
:
|
|
1638
|
+
: this.withUpdatedComponents(newElement, newSelection);
|
|
1639
|
+
}
|
|
1640
|
+
trimUnsatisfiableBranches(currentType) {
|
|
1641
|
+
var _a, _b;
|
|
1642
|
+
const thisCondition = this.element.typeCondition;
|
|
1643
|
+
if (this.element.appliedDirectives.length === 0) {
|
|
1644
|
+
if (!thisCondition || currentType === this.element.typeCondition) {
|
|
1645
|
+
const trimmed = this.selectionSet.trimUnsatisfiableBranches(currentType);
|
|
1646
|
+
return trimmed.isEmpty() ? undefined : trimmed;
|
|
1647
|
+
}
|
|
1648
|
+
if ((0, definitions_1.isObjectType)(currentType)) {
|
|
1649
|
+
if ((0, definitions_1.isObjectType)(thisCondition) || !(0, definitions_1.possibleRuntimeTypes)(thisCondition).includes(currentType)) {
|
|
1650
|
+
return undefined;
|
|
1651
|
+
}
|
|
1652
|
+
else {
|
|
1653
|
+
const trimmed = this.selectionSet.trimUnsatisfiableBranches(currentType);
|
|
1654
|
+
return trimmed.isEmpty() ? undefined : trimmed;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
const trimmedSelectionSet = this.selectionSet.trimUnsatisfiableBranches((_a = this.element.typeCondition) !== null && _a !== void 0 ? _a : this.parentType);
|
|
1659
|
+
if (trimmedSelectionSet.isEmpty()) {
|
|
1660
|
+
if (this.element.appliedDirectives.length === 0) {
|
|
1661
|
+
return undefined;
|
|
1662
|
+
}
|
|
1663
|
+
else {
|
|
1664
|
+
return this.withUpdatedSelectionSet(selectionSetOfElement(new Field(((_b = this.element.typeCondition) !== null && _b !== void 0 ? _b : this.parentType).typenameField(), undefined, [new definitions_1.Directive('include', { 'if': false })])));
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
if (this.element.appliedDirectives.length === 0 && (0, definitions_1.isAbstractType)(thisCondition)) {
|
|
1668
|
+
(0, utils_1.assert)(!(0, definitions_1.isObjectType)(currentType), () => `Should not have got here if ${currentType} is an object type`);
|
|
1669
|
+
const currentRuntimes = (0, definitions_1.possibleRuntimeTypes)(currentType);
|
|
1670
|
+
const liftableSelections = [];
|
|
1671
|
+
for (const selection of trimmedSelectionSet.selections()) {
|
|
1672
|
+
if (selection.kind === 'FragmentSelection'
|
|
1673
|
+
&& selection.element.typeCondition
|
|
1674
|
+
&& (0, definitions_1.isObjectType)(selection.element.typeCondition)
|
|
1675
|
+
&& currentRuntimes.includes(selection.element.typeCondition)) {
|
|
1676
|
+
liftableSelections.push(selection);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
if (liftableSelections.length === trimmedSelectionSet.selections().length) {
|
|
1680
|
+
return trimmedSelectionSet;
|
|
1681
|
+
}
|
|
1682
|
+
if (liftableSelections.length > 0) {
|
|
1683
|
+
const newSet = new SelectionSetUpdates();
|
|
1684
|
+
newSet.add(liftableSelections);
|
|
1685
|
+
newSet.add(this.withUpdatedSelectionSet(trimmedSelectionSet.filter((s) => !liftableSelections.includes(s))));
|
|
1686
|
+
return newSet.toSelectionSet(this.parentType);
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
return this.selectionSet === trimmedSelectionSet ? this : this.withUpdatedSelectionSet(trimmedSelectionSet);
|
|
1690
|
+
}
|
|
1691
|
+
expandAllFragments() {
|
|
1692
|
+
return this.mapToSelectionSet((s) => s.expandAllFragments());
|
|
1693
|
+
}
|
|
1694
|
+
expandFragments(names, updatedFragments) {
|
|
1695
|
+
return this.mapToSelectionSet((s) => s.expandFragments(names, updatedFragments));
|
|
1696
|
+
}
|
|
1697
|
+
equals(that) {
|
|
1698
|
+
if (this === that) {
|
|
1699
|
+
return true;
|
|
1700
|
+
}
|
|
1701
|
+
return (that instanceof FragmentSelection)
|
|
1702
|
+
&& this.element.equals(that.element)
|
|
1703
|
+
&& this.selectionSet.equals(that.selectionSet);
|
|
1449
1704
|
}
|
|
1450
|
-
|
|
1451
|
-
return
|
|
1705
|
+
contains(that) {
|
|
1706
|
+
return (that instanceof FragmentSelection)
|
|
1707
|
+
&& this.element.equals(that.element)
|
|
1708
|
+
&& this.selectionSet.contains(that.selectionSet);
|
|
1452
1709
|
}
|
|
1453
1710
|
toString(expandFragments = true, indent) {
|
|
1454
|
-
return (indent !== null && indent !== void 0 ? indent : '') + this.
|
|
1711
|
+
return (indent !== null && indent !== void 0 ? indent : '') + this.element + ' ' + this.selectionSet.toString(expandFragments, true, indent);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
function diffDirectives(superset, maybeSubset) {
|
|
1715
|
+
if (maybeSubset.every((d) => superset.some((s) => (0, definitions_1.sameDirectiveApplication)(d, s)))) {
|
|
1716
|
+
return { isSubset: true, difference: superset.filter((s) => !maybeSubset.some((d) => (0, definitions_1.sameDirectiveApplication)(d, s))) };
|
|
1717
|
+
}
|
|
1718
|
+
else {
|
|
1719
|
+
return { isSubset: false, difference: [] };
|
|
1455
1720
|
}
|
|
1456
1721
|
}
|
|
1457
1722
|
class FragmentSpreadSelection extends FragmentSelection {
|
|
1458
|
-
constructor(sourceType, fragments,
|
|
1459
|
-
super();
|
|
1723
|
+
constructor(sourceType, fragments, namedFragment, spreadDirectives) {
|
|
1724
|
+
super(new FragmentElement(sourceType, namedFragment.typeCondition, namedFragment.appliedDirectives.concat(spreadDirectives)));
|
|
1460
1725
|
this.fragments = fragments;
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
this._element.applyDirective(directive.definition, directive.arguments());
|
|
1467
|
-
}
|
|
1726
|
+
this.namedFragment = namedFragment;
|
|
1727
|
+
this.spreadDirectives = spreadDirectives;
|
|
1728
|
+
}
|
|
1729
|
+
get selectionSet() {
|
|
1730
|
+
return this.namedFragment.selectionSet;
|
|
1468
1731
|
}
|
|
1469
1732
|
key() {
|
|
1470
|
-
|
|
1733
|
+
if (!this.computedKey) {
|
|
1734
|
+
this.computedKey = '...' + this.namedFragment.name + (this.spreadDirectives.length === 0 ? '' : ' ' + this.spreadDirectives.join(' '));
|
|
1735
|
+
}
|
|
1736
|
+
return this.computedKey;
|
|
1471
1737
|
}
|
|
1472
|
-
|
|
1473
|
-
|
|
1738
|
+
withUpdatedComponents(_fragment, _selectionSet) {
|
|
1739
|
+
(0, utils_1.assert)(false, `Unsupported`);
|
|
1740
|
+
}
|
|
1741
|
+
trimUnsatisfiableBranches(_) {
|
|
1742
|
+
return this;
|
|
1474
1743
|
}
|
|
1475
1744
|
namedFragments() {
|
|
1476
1745
|
return this.fragments;
|
|
1477
1746
|
}
|
|
1478
|
-
get selectionSet() {
|
|
1479
|
-
return this.namedFragment.selectionSet;
|
|
1480
|
-
}
|
|
1481
1747
|
validate() {
|
|
1482
1748
|
this.validateDeferAndStream();
|
|
1483
1749
|
}
|
|
1484
1750
|
toSelectionNode() {
|
|
1485
|
-
const
|
|
1486
|
-
const directiveNodes = spreadDirectives.length === 0
|
|
1751
|
+
const directiveNodes = this.spreadDirectives.length === 0
|
|
1487
1752
|
? undefined
|
|
1488
|
-
: spreadDirectives.map(directive => {
|
|
1753
|
+
: this.spreadDirectives.map(directive => {
|
|
1489
1754
|
return {
|
|
1490
1755
|
kind: graphql_1.Kind.DIRECTIVE,
|
|
1491
1756
|
name: {
|
|
@@ -1504,20 +1769,26 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1504
1769
|
optimize(_) {
|
|
1505
1770
|
return this;
|
|
1506
1771
|
}
|
|
1507
|
-
|
|
1772
|
+
rebaseOn(_parentType) {
|
|
1508
1773
|
return this;
|
|
1509
1774
|
}
|
|
1510
1775
|
canAddTo(_) {
|
|
1511
1776
|
return true;
|
|
1512
1777
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1778
|
+
expandAllFragments() {
|
|
1779
|
+
const expandedSubSelections = this.selectionSet.expandAllFragments();
|
|
1780
|
+
return (0, types_1.sameType)(this.parentType, this.namedFragment.typeCondition) && this.element.appliedDirectives.length === 0
|
|
1781
|
+
? expandedSubSelections.selections()
|
|
1782
|
+
: new InlineFragmentSelection(this.element, expandedSubSelections);
|
|
1783
|
+
}
|
|
1784
|
+
expandFragments(names, updatedFragments) {
|
|
1785
|
+
if (!names.includes(this.namedFragment.name)) {
|
|
1515
1786
|
return this;
|
|
1516
1787
|
}
|
|
1517
|
-
const expandedSubSelections = this.selectionSet.expandFragments(names,
|
|
1518
|
-
return (0, types_1.sameType)(this.
|
|
1788
|
+
const expandedSubSelections = this.selectionSet.expandFragments(names, updatedFragments);
|
|
1789
|
+
return (0, types_1.sameType)(this.parentType, this.namedFragment.typeCondition) && this.element.appliedDirectives.length === 0
|
|
1519
1790
|
? expandedSubSelections.selections()
|
|
1520
|
-
: new InlineFragmentSelection(this.
|
|
1791
|
+
: new InlineFragmentSelection(this.element, expandedSubSelections);
|
|
1521
1792
|
}
|
|
1522
1793
|
collectUsedFragmentNames(collector) {
|
|
1523
1794
|
this.selectionSet.collectUsedFragmentNames(collector);
|
|
@@ -1525,28 +1796,89 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
1525
1796
|
collector.set(this.namedFragment.name, usageCount === undefined ? 1 : usageCount + 1);
|
|
1526
1797
|
}
|
|
1527
1798
|
withoutDefer(_labelsToRemove) {
|
|
1528
|
-
(0, utils_1.assert)(false, 'Unsupported, see `Operation.
|
|
1799
|
+
(0, utils_1.assert)(false, 'Unsupported, see `Operation.withAllDeferLabelled`');
|
|
1529
1800
|
}
|
|
1530
|
-
withNormalizedDefer(
|
|
1801
|
+
withNormalizedDefer(_normalizer) {
|
|
1531
1802
|
(0, utils_1.assert)(false, 'Unsupported, see `Operation.withAllDeferLabelled`');
|
|
1532
1803
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1804
|
+
minus(that) {
|
|
1805
|
+
(0, utils_1.assert)(this.equals(that), () => `Invalid operation for ${this.toString(false)} and ${that.toString(false)}`);
|
|
1806
|
+
return undefined;
|
|
1807
|
+
}
|
|
1808
|
+
equals(that) {
|
|
1809
|
+
if (this === that) {
|
|
1810
|
+
return true;
|
|
1811
|
+
}
|
|
1812
|
+
return (that instanceof FragmentSpreadSelection)
|
|
1813
|
+
&& this.namedFragment.name === that.namedFragment.name
|
|
1814
|
+
&& (0, definitions_1.sameDirectiveApplications)(this.spreadDirectives, that.spreadDirectives);
|
|
1535
1815
|
}
|
|
1536
|
-
|
|
1537
|
-
(
|
|
1816
|
+
contains(that) {
|
|
1817
|
+
if (this.equals(that)) {
|
|
1818
|
+
return true;
|
|
1819
|
+
}
|
|
1820
|
+
return (that instanceof FragmentSelection)
|
|
1821
|
+
&& this.element.equals(that.element)
|
|
1822
|
+
&& this.selectionSet.contains(that.selectionSet);
|
|
1538
1823
|
}
|
|
1539
1824
|
toString(expandFragments = true, indent) {
|
|
1540
1825
|
if (expandFragments) {
|
|
1541
|
-
return (indent !== null && indent !== void 0 ? indent : '') + this.
|
|
1826
|
+
return (indent !== null && indent !== void 0 ? indent : '') + this.element + ' ' + this.selectionSet.toString(true, true, indent);
|
|
1542
1827
|
}
|
|
1543
1828
|
else {
|
|
1544
|
-
const directives = this.spreadDirectives
|
|
1829
|
+
const directives = this.spreadDirectives;
|
|
1545
1830
|
const directiveString = directives.length == 0 ? '' : ' ' + directives.join(' ');
|
|
1546
1831
|
return (indent !== null && indent !== void 0 ? indent : '') + '...' + this.namedFragment.name + directiveString;
|
|
1547
1832
|
}
|
|
1548
1833
|
}
|
|
1549
1834
|
}
|
|
1835
|
+
function selectionSetOfNode(parentType, node, variableDefinitions, fragments, fieldAccessor = (type, name) => type.field(name)) {
|
|
1836
|
+
if (node.selections.length === 1) {
|
|
1837
|
+
return selectionSetOf(parentType, selectionOfNode(parentType, node.selections[0], variableDefinitions, fragments, fieldAccessor), fragments);
|
|
1838
|
+
}
|
|
1839
|
+
const selections = new SelectionSetUpdates();
|
|
1840
|
+
for (const selectionNode of node.selections) {
|
|
1841
|
+
selections.add(selectionOfNode(parentType, selectionNode, variableDefinitions, fragments, fieldAccessor));
|
|
1842
|
+
}
|
|
1843
|
+
return selections.toSelectionSet(parentType, fragments);
|
|
1844
|
+
}
|
|
1845
|
+
function directiveOfNode(schema, node) {
|
|
1846
|
+
const directiveDef = schema.directive(node.name.value);
|
|
1847
|
+
validate(directiveDef, () => `Unknown directive "@${node.name.value}"`);
|
|
1848
|
+
return new definitions_1.Directive(directiveDef.name, (0, values_1.argumentsFromAST)(directiveDef.coordinate, node.arguments, directiveDef));
|
|
1849
|
+
}
|
|
1850
|
+
function directivesOfNodes(schema, nodes) {
|
|
1851
|
+
var _a;
|
|
1852
|
+
return (_a = nodes === null || nodes === void 0 ? void 0 : nodes.map((n) => directiveOfNode(schema, n))) !== null && _a !== void 0 ? _a : [];
|
|
1853
|
+
}
|
|
1854
|
+
function selectionOfNode(parentType, node, variableDefinitions, fragments, fieldAccessor = (type, name) => type.field(name)) {
|
|
1855
|
+
var _a, _b;
|
|
1856
|
+
let selection;
|
|
1857
|
+
const directives = directivesOfNodes(parentType.schema(), node.directives);
|
|
1858
|
+
switch (node.kind) {
|
|
1859
|
+
case graphql_1.Kind.FIELD:
|
|
1860
|
+
const definition = fieldAccessor(parentType, node.name.value);
|
|
1861
|
+
validate(definition, () => `Cannot query field "${node.name.value}" on type "${parentType}".`, parentType.sourceAST);
|
|
1862
|
+
const type = (0, definitions_1.baseType)(definition.type);
|
|
1863
|
+
const selectionSet = node.selectionSet
|
|
1864
|
+
? selectionSetOfNode(type, node.selectionSet, variableDefinitions, fragments, fieldAccessor)
|
|
1865
|
+
: undefined;
|
|
1866
|
+
selection = new FieldSelection(new Field(definition, (0, values_1.argumentsFromAST)(definition.coordinate, node.arguments, definition), directives, (_a = node.alias) === null || _a === void 0 ? void 0 : _a.value), selectionSet);
|
|
1867
|
+
break;
|
|
1868
|
+
case graphql_1.Kind.INLINE_FRAGMENT:
|
|
1869
|
+
const element = new FragmentElement(parentType, (_b = node.typeCondition) === null || _b === void 0 ? void 0 : _b.name.value, directives);
|
|
1870
|
+
selection = new InlineFragmentSelection(element, selectionSetOfNode(element.typeCondition ? element.typeCondition : element.parentType, node.selectionSet, variableDefinitions, fragments, fieldAccessor));
|
|
1871
|
+
break;
|
|
1872
|
+
case graphql_1.Kind.FRAGMENT_SPREAD:
|
|
1873
|
+
const fragmentName = node.name.value;
|
|
1874
|
+
validate(fragments, () => `Cannot find fragment name "${fragmentName}" (no fragments were provided)`);
|
|
1875
|
+
const fragment = fragments.get(fragmentName);
|
|
1876
|
+
validate(fragment, () => `Cannot find fragment name "${fragmentName}" (provided fragments are: [${fragments.names().join(', ')}])`);
|
|
1877
|
+
selection = new FragmentSpreadSelection(parentType, fragments, fragment, directives);
|
|
1878
|
+
break;
|
|
1879
|
+
}
|
|
1880
|
+
return selection;
|
|
1881
|
+
}
|
|
1550
1882
|
function operationFromDocument(schema, document, options) {
|
|
1551
1883
|
let operation;
|
|
1552
1884
|
const operationName = options === null || options === void 0 ? void 0 : options.operationName;
|
|
@@ -1569,9 +1901,7 @@ function operationFromDocument(schema, document, options) {
|
|
|
1569
1901
|
if (!(0, definitions_1.isCompositeType)(typeCondition)) {
|
|
1570
1902
|
throw error_1.ERRORS.INVALID_GRAPHQL.err(`Invalid fragment "${name}" on non-composite type "${typeName}"`, { nodes: definition });
|
|
1571
1903
|
}
|
|
1572
|
-
|
|
1573
|
-
addDirectiveNodesToElement(definition.directives, fragment);
|
|
1574
|
-
fragments.add(fragment);
|
|
1904
|
+
fragments.add(new NamedFragmentDefinition(schema, name, typeCondition, directivesOfNodes(schema, definition.directives)));
|
|
1575
1905
|
break;
|
|
1576
1906
|
}
|
|
1577
1907
|
});
|
|
@@ -1583,11 +1913,11 @@ function operationFromDocument(schema, document, options) {
|
|
|
1583
1913
|
switch (definition.kind) {
|
|
1584
1914
|
case graphql_1.Kind.FRAGMENT_DEFINITION:
|
|
1585
1915
|
const fragment = fragments.get(definition.name.value);
|
|
1586
|
-
fragment.
|
|
1916
|
+
fragment.setSelectionSet(selectionSetOfNode(fragment.typeCondition, definition.selectionSet, variableDefinitions, fragments));
|
|
1587
1917
|
break;
|
|
1588
1918
|
}
|
|
1589
1919
|
});
|
|
1590
|
-
fragments.validate();
|
|
1920
|
+
fragments.validate(variableDefinitions);
|
|
1591
1921
|
return operationFromAST({ schema, operation, variableDefinitions, fragments, validateInput: options === null || options === void 0 ? void 0 : options.validate });
|
|
1592
1922
|
}
|
|
1593
1923
|
exports.operationFromDocument = operationFromDocument;
|
|
@@ -1599,7 +1929,7 @@ function operationFromAST({ schema, operation, variableDefinitions, fragments, v
|
|
|
1599
1929
|
parentType: rootType.type,
|
|
1600
1930
|
source: operation.selectionSet,
|
|
1601
1931
|
variableDefinitions,
|
|
1602
|
-
fragments,
|
|
1932
|
+
fragments: fragments.isEmpty() ? undefined : fragments,
|
|
1603
1933
|
validate: validateInput,
|
|
1604
1934
|
}), variableDefinitions, (_a = operation.name) === null || _a === void 0 ? void 0 : _a.value);
|
|
1605
1935
|
}
|
|
@@ -1607,14 +1937,13 @@ function parseOperation(schema, operation, options) {
|
|
|
1607
1937
|
return operationFromDocument(schema, (0, graphql_1.parse)(operation), options);
|
|
1608
1938
|
}
|
|
1609
1939
|
exports.parseOperation = parseOperation;
|
|
1610
|
-
function parseSelectionSet({ parentType, source, variableDefinitions, fragments, fieldAccessor, validate = true, }) {
|
|
1940
|
+
function parseSelectionSet({ parentType, source, variableDefinitions = new definitions_1.VariableDefinitions(), fragments, fieldAccessor, validate = true, }) {
|
|
1611
1941
|
const node = typeof source === 'string'
|
|
1612
1942
|
? parseOperationAST(source.trim().startsWith('{') ? source : `{${source}}`).selectionSet
|
|
1613
1943
|
: source;
|
|
1614
|
-
const selectionSet = new
|
|
1615
|
-
selectionSet.addSelectionSetNode(node, variableDefinitions !== null && variableDefinitions !== void 0 ? variableDefinitions : new definitions_1.VariableDefinitions(), fieldAccessor);
|
|
1944
|
+
const selectionSet = selectionSetOfNode(parentType, node, variableDefinitions !== null && variableDefinitions !== void 0 ? variableDefinitions : new definitions_1.VariableDefinitions(), fragments, fieldAccessor);
|
|
1616
1945
|
if (validate)
|
|
1617
|
-
selectionSet.validate();
|
|
1946
|
+
selectionSet.validate(variableDefinitions);
|
|
1618
1947
|
return selectionSet;
|
|
1619
1948
|
}
|
|
1620
1949
|
exports.parseSelectionSet = parseSelectionSet;
|