@apollo/federation-internals 2.7.1 → 2.7.3-testing.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/definitions.d.ts +4 -1
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +29 -17
- package/dist/definitions.js.map +1 -1
- package/dist/federation.d.ts +2 -1
- package/dist/federation.d.ts.map +1 -1
- package/dist/federation.js +21 -12
- package/dist/federation.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/operations.d.ts +10 -3
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +70 -37
- package/dist/operations.js.map +1 -1
- package/dist/specs/connectSpec.d.ts +12 -0
- package/dist/specs/connectSpec.d.ts.map +1 -0
- package/dist/specs/connectSpec.js +82 -0
- package/dist/specs/connectSpec.js.map +1 -0
- package/dist/specs/coreSpec.d.ts +1 -0
- package/dist/specs/coreSpec.d.ts.map +1 -1
- package/dist/specs/coreSpec.js +9 -0
- package/dist/specs/coreSpec.js.map +1 -1
- package/dist/specs/sourceSpec.d.ts.map +1 -1
- package/dist/specs/sourceSpec.js +2 -11
- package/dist/specs/sourceSpec.js.map +1 -1
- package/package.json +1 -1
- package/src/definitions.ts +39 -17
- package/src/federation.ts +31 -13
- package/src/index.ts +1 -0
- package/src/operations.ts +128 -48
- package/src/specs/connectSpec.ts +146 -0
- package/src/specs/coreSpec.ts +22 -0
- package/src/specs/sourceSpec.ts +2 -21
package/dist/operations.js
CHANGED
|
@@ -536,25 +536,26 @@ function computeFragmentsToKeep(selectionSet, fragments, minUsagesToOptimize) {
|
|
|
536
536
|
return toExpand.size === 0 ? fragments : fragments.filter((f) => !toExpand.has(f.name));
|
|
537
537
|
}
|
|
538
538
|
class Operation {
|
|
539
|
-
constructor(schema, rootKind, selectionSet, variableDefinitions, fragments, name) {
|
|
539
|
+
constructor(schema, rootKind, selectionSet, variableDefinitions, fragments, name, directives) {
|
|
540
540
|
this.schema = schema;
|
|
541
541
|
this.rootKind = rootKind;
|
|
542
542
|
this.selectionSet = selectionSet;
|
|
543
543
|
this.variableDefinitions = variableDefinitions;
|
|
544
544
|
this.fragments = fragments;
|
|
545
545
|
this.name = name;
|
|
546
|
+
this.directives = directives;
|
|
546
547
|
}
|
|
547
548
|
withUpdatedSelectionSet(newSelectionSet) {
|
|
548
549
|
if (this.selectionSet === newSelectionSet) {
|
|
549
550
|
return this;
|
|
550
551
|
}
|
|
551
|
-
return new Operation(this.schema, this.rootKind, newSelectionSet, this.variableDefinitions, this.fragments, this.name);
|
|
552
|
+
return new Operation(this.schema, this.rootKind, newSelectionSet, this.variableDefinitions, this.fragments, this.name, this.directives);
|
|
552
553
|
}
|
|
553
554
|
withUpdatedSelectionSetAndFragments(newSelectionSet, newFragments) {
|
|
554
555
|
if (this.selectionSet === newSelectionSet && newFragments === this.fragments) {
|
|
555
556
|
return this;
|
|
556
557
|
}
|
|
557
|
-
return new Operation(this.schema, this.rootKind, newSelectionSet, this.variableDefinitions, newFragments, this.name);
|
|
558
|
+
return new Operation(this.schema, this.rootKind, newSelectionSet, this.variableDefinitions, newFragments, this.name, this.directives);
|
|
558
559
|
}
|
|
559
560
|
optimize(fragments, minUsagesToOptimize = 2) {
|
|
560
561
|
(0, utils_1.assert)(minUsagesToOptimize >= 1, `Expected 'minUsagesToOptimize' to be at least 1, but got ${minUsagesToOptimize}`);
|
|
@@ -582,6 +583,10 @@ class Operation {
|
|
|
582
583
|
}
|
|
583
584
|
return this.withUpdatedSelectionSetAndFragments(optimizedSelection, finalFragments !== null && finalFragments !== void 0 ? finalFragments : undefined);
|
|
584
585
|
}
|
|
586
|
+
generateQueryFragments() {
|
|
587
|
+
const [minimizedSelectionSet, fragments] = this.selectionSet.minimizeSelectionSet();
|
|
588
|
+
return new Operation(this.schema, this.rootKind, minimizedSelectionSet, this.variableDefinitions, fragments, this.name, this.directives);
|
|
589
|
+
}
|
|
585
590
|
expandAllFragments() {
|
|
586
591
|
const expanded = this.selectionSet.expandFragments();
|
|
587
592
|
return this.withUpdatedSelectionSetAndFragments(expanded.normalize({ parentType: expanded.parentType }), undefined);
|
|
@@ -616,7 +621,7 @@ class Operation {
|
|
|
616
621
|
return defaultedVariableValues;
|
|
617
622
|
}
|
|
618
623
|
toString(expandFragments = false, prettyPrint = true) {
|
|
619
|
-
return this.selectionSet.toOperationString(this.rootKind, this.variableDefinitions, this.fragments, this.name, expandFragments, prettyPrint);
|
|
624
|
+
return this.selectionSet.toOperationString(this.rootKind, this.variableDefinitions, this.fragments, this.name, this.directives, expandFragments, prettyPrint);
|
|
620
625
|
}
|
|
621
626
|
}
|
|
622
627
|
exports.Operation = Operation;
|
|
@@ -703,6 +708,10 @@ class NamedFragmentDefinition extends definitions_1.DirectiveTargetElement {
|
|
|
703
708
|
computeExpandedSelectionSetAtType(type) {
|
|
704
709
|
const expandedSelectionSet = this.expandedSelectionSet();
|
|
705
710
|
const selectionSet = expandedSelectionSet.normalize({ parentType: type });
|
|
711
|
+
if (!(0, definitions_1.isObjectType)(this.typeCondition)) {
|
|
712
|
+
const validator = FieldsConflictValidator.build(expandedSelectionSet);
|
|
713
|
+
return { selectionSet, validator };
|
|
714
|
+
}
|
|
706
715
|
const trimmed = expandedSelectionSet.minus(selectionSet);
|
|
707
716
|
const validator = trimmed.isEmpty() ? undefined : FieldsConflictValidator.build(trimmed);
|
|
708
717
|
return { selectionSet, validator };
|
|
@@ -815,17 +824,6 @@ class NamedFragments {
|
|
|
815
824
|
return fragment.withUpdatedSelectionSet(reoptimizedSelectionSet);
|
|
816
825
|
});
|
|
817
826
|
}
|
|
818
|
-
selectionSetIsWorthUsing(selectionSet) {
|
|
819
|
-
const selections = selectionSet.selections();
|
|
820
|
-
if (selections.length === 0) {
|
|
821
|
-
return false;
|
|
822
|
-
}
|
|
823
|
-
if (selections.length === 1) {
|
|
824
|
-
const s = selections[0];
|
|
825
|
-
return !(s.kind === 'FieldSelection' && s.element.isLeafField());
|
|
826
|
-
}
|
|
827
|
-
return true;
|
|
828
|
-
}
|
|
829
827
|
rebaseOn(schema) {
|
|
830
828
|
return this.mapInDependencyOrder((fragment, newFragments) => {
|
|
831
829
|
const rebasedType = schema.type(fragment.selectionSet.parentType.name);
|
|
@@ -834,7 +832,7 @@ class NamedFragments {
|
|
|
834
832
|
}
|
|
835
833
|
let rebasedSelection = fragment.selectionSet.rebaseOn({ parentType: rebasedType, fragments: newFragments, errorIfCannotRebase: false });
|
|
836
834
|
rebasedSelection = rebasedSelection.normalize({ parentType: rebasedType });
|
|
837
|
-
return
|
|
835
|
+
return rebasedSelection.isWorthUsing()
|
|
838
836
|
? new NamedFragmentDefinition(schema, fragment.name, rebasedType).setSelectionSet(rebasedSelection)
|
|
839
837
|
: undefined;
|
|
840
838
|
});
|
|
@@ -923,6 +921,39 @@ class SelectionSet {
|
|
|
923
921
|
this._keyedSelections = keyedSelections;
|
|
924
922
|
this._selections = (0, utils_1.mapValues)(keyedSelections);
|
|
925
923
|
}
|
|
924
|
+
minimizeSelectionSet(namedFragments = new NamedFragments(), seenSelections = new Map()) {
|
|
925
|
+
const minimizedSelectionSet = this.lazyMap((selection) => {
|
|
926
|
+
var _a;
|
|
927
|
+
if (selection.kind === 'FragmentSelection' && selection.element.typeCondition && selection.element.appliedDirectives.length === 0
|
|
928
|
+
&& selection.selectionSet && selection.selectionSet.isWorthUsing()) {
|
|
929
|
+
const mockHashCode = `on${selection.element.typeCondition}` + selection.selectionSet.selections().length;
|
|
930
|
+
const equivalentSelectionSetCandidates = seenSelections.get(mockHashCode);
|
|
931
|
+
if (equivalentSelectionSetCandidates) {
|
|
932
|
+
const match = equivalentSelectionSetCandidates.find(([candidateSet]) => candidateSet.equals(selection.selectionSet));
|
|
933
|
+
if (match) {
|
|
934
|
+
return new FragmentSpreadSelection(this.parentType, namedFragments, match[1], []);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
const [minimizedSelectionSet] = selection.selectionSet.minimizeSelectionSet(namedFragments, seenSelections);
|
|
938
|
+
const fragmentDefinition = new NamedFragmentDefinition(this.parentType.schema(), `_generated_${mockHashCode}_${(_a = equivalentSelectionSetCandidates === null || equivalentSelectionSetCandidates === void 0 ? void 0 : equivalentSelectionSetCandidates.length) !== null && _a !== void 0 ? _a : 0}`, selection.element.typeCondition).setSelectionSet(minimizedSelectionSet);
|
|
939
|
+
if (!equivalentSelectionSetCandidates) {
|
|
940
|
+
seenSelections.set(mockHashCode, [[selection.selectionSet, fragmentDefinition]]);
|
|
941
|
+
namedFragments.add(fragmentDefinition);
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
equivalentSelectionSetCandidates.push([selection.selectionSet, fragmentDefinition]);
|
|
945
|
+
}
|
|
946
|
+
return new FragmentSpreadSelection(this.parentType, namedFragments, fragmentDefinition, []);
|
|
947
|
+
}
|
|
948
|
+
else if (selection.kind === 'FieldSelection') {
|
|
949
|
+
if (selection.selectionSet) {
|
|
950
|
+
selection = selection.withUpdatedSelectionSet(selection.selectionSet.minimizeSelectionSet(namedFragments, seenSelections)[0]);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
return selection;
|
|
954
|
+
});
|
|
955
|
+
return [minimizedSelectionSet, namedFragments];
|
|
956
|
+
}
|
|
926
957
|
selectionsInReverseOrder() {
|
|
927
958
|
const length = this._selections.length;
|
|
928
959
|
const reversed = new Array(length);
|
|
@@ -1219,7 +1250,7 @@ class SelectionSet {
|
|
|
1219
1250
|
}
|
|
1220
1251
|
return false;
|
|
1221
1252
|
}
|
|
1222
|
-
toOperationString(rootKind, variableDefinitions, fragments, operationName, expandFragments = false, prettyPrint = true) {
|
|
1253
|
+
toOperationString(rootKind, variableDefinitions, fragments, operationName, directives, expandFragments = false, prettyPrint = true) {
|
|
1223
1254
|
const indent = prettyPrint ? '' : undefined;
|
|
1224
1255
|
const fragmentsDefinitions = !expandFragments && fragments && !fragments.isEmpty()
|
|
1225
1256
|
? fragments.toString(indent) + "\n\n"
|
|
@@ -1230,7 +1261,8 @@ class SelectionSet {
|
|
|
1230
1261
|
const nameAndVariables = operationName
|
|
1231
1262
|
? " " + (operationName + (variableDefinitions.isEmpty() ? "" : variableDefinitions.toString()))
|
|
1232
1263
|
: (variableDefinitions.isEmpty() ? "" : " " + variableDefinitions.toString());
|
|
1233
|
-
|
|
1264
|
+
const directives_str = (0, definitions_1.directivesToString)(directives);
|
|
1265
|
+
return fragmentsDefinitions + rootKind + nameAndVariables + directives_str + " " + this.toString(expandFragments, true, indent);
|
|
1234
1266
|
}
|
|
1235
1267
|
toString(expandFragments = true, includeExternalBrackets = true, indent) {
|
|
1236
1268
|
if (this.isEmpty()) {
|
|
@@ -1248,6 +1280,17 @@ class SelectionSet {
|
|
|
1248
1280
|
: selectionsToString;
|
|
1249
1281
|
}
|
|
1250
1282
|
}
|
|
1283
|
+
isWorthUsing() {
|
|
1284
|
+
const selections = this.selections();
|
|
1285
|
+
if (selections.length === 0) {
|
|
1286
|
+
return false;
|
|
1287
|
+
}
|
|
1288
|
+
if (selections.length === 1) {
|
|
1289
|
+
const s = selections[0];
|
|
1290
|
+
return !(s.kind === 'FieldSelection' && s.element.isLeafField());
|
|
1291
|
+
}
|
|
1292
|
+
return true;
|
|
1293
|
+
}
|
|
1251
1294
|
}
|
|
1252
1295
|
exports.SelectionSet = SelectionSet;
|
|
1253
1296
|
class SelectionSetUpdates {
|
|
@@ -2163,7 +2206,7 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
2163
2206
|
}
|
|
2164
2207
|
key() {
|
|
2165
2208
|
if (!this.computedKey) {
|
|
2166
|
-
this.computedKey = '...' + this.namedFragment.name + (
|
|
2209
|
+
this.computedKey = '...' + this.namedFragment.name + (0, definitions_1.directivesToString)(this.spreadDirectives);
|
|
2167
2210
|
}
|
|
2168
2211
|
return this.computedKey;
|
|
2169
2212
|
}
|
|
@@ -2179,18 +2222,7 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
2179
2222
|
validate((0, definitions_1.runtimeTypesIntersects)(this.parentType, this.namedFragment.typeCondition), () => `Fragment "${this.namedFragment.name}" cannot be spread inside type ${this.parentType} as the runtime types do not intersect ${this.namedFragment.typeCondition}`);
|
|
2180
2223
|
}
|
|
2181
2224
|
toSelectionNode() {
|
|
2182
|
-
const directiveNodes = this.spreadDirectives
|
|
2183
|
-
? undefined
|
|
2184
|
-
: this.spreadDirectives.map(directive => {
|
|
2185
|
-
return {
|
|
2186
|
-
kind: graphql_1.Kind.DIRECTIVE,
|
|
2187
|
-
name: {
|
|
2188
|
-
kind: graphql_1.Kind.NAME,
|
|
2189
|
-
value: directive.name,
|
|
2190
|
-
},
|
|
2191
|
-
arguments: directive.argumentsToAST()
|
|
2192
|
-
};
|
|
2193
|
-
});
|
|
2225
|
+
const directiveNodes = (0, definitions_1.directivesToDirectiveNodes)(this.spreadDirectives);
|
|
2194
2226
|
return {
|
|
2195
2227
|
kind: graphql_1.Kind.FRAGMENT_SPREAD,
|
|
2196
2228
|
name: { kind: graphql_1.Kind.NAME, value: this.namedFragment.name },
|
|
@@ -2266,9 +2298,7 @@ class FragmentSpreadSelection extends FragmentSelection {
|
|
|
2266
2298
|
return (indent !== null && indent !== void 0 ? indent : '') + this.element + ' ' + this.selectionSet.toString(true, true, indent);
|
|
2267
2299
|
}
|
|
2268
2300
|
else {
|
|
2269
|
-
|
|
2270
|
-
const directiveString = directives.length == 0 ? '' : ' ' + directives.join(' ');
|
|
2271
|
-
return (indent !== null && indent !== void 0 ? indent : '') + '...' + this.namedFragment.name + directiveString;
|
|
2301
|
+
return (indent !== null && indent !== void 0 ? indent : '') + '...' + this.namedFragment.name + (0, definitions_1.directivesToString)(this.spreadDirectives);
|
|
2272
2302
|
}
|
|
2273
2303
|
}
|
|
2274
2304
|
}
|
|
@@ -2321,6 +2351,7 @@ function selectionOfNode(parentType, node, variableDefinitions, fragments, field
|
|
|
2321
2351
|
}
|
|
2322
2352
|
function operationFromDocument(schema, document, options) {
|
|
2323
2353
|
let operation;
|
|
2354
|
+
let operation_directives;
|
|
2324
2355
|
const operationName = options === null || options === void 0 ? void 0 : options.operationName;
|
|
2325
2356
|
const fragments = new NamedFragments();
|
|
2326
2357
|
document.definitions.forEach(definition => {
|
|
@@ -2329,6 +2360,7 @@ function operationFromDocument(schema, document, options) {
|
|
|
2329
2360
|
validate(!operation || operationName, () => 'Must provide operation name if query contains multiple operations.');
|
|
2330
2361
|
if (!operationName || (definition.name && definition.name.value === operationName)) {
|
|
2331
2362
|
operation = definition;
|
|
2363
|
+
operation_directives = directivesOfNodes(schema, definition.directives);
|
|
2332
2364
|
}
|
|
2333
2365
|
break;
|
|
2334
2366
|
case graphql_1.Kind.FRAGMENT_DEFINITION:
|
|
@@ -2358,10 +2390,10 @@ function operationFromDocument(schema, document, options) {
|
|
|
2358
2390
|
}
|
|
2359
2391
|
});
|
|
2360
2392
|
fragments.validate(variableDefinitions);
|
|
2361
|
-
return operationFromAST({ schema, operation, variableDefinitions, fragments, validateInput: options === null || options === void 0 ? void 0 : options.validate });
|
|
2393
|
+
return operationFromAST({ schema, operation, operation_directives, variableDefinitions, fragments, validateInput: options === null || options === void 0 ? void 0 : options.validate });
|
|
2362
2394
|
}
|
|
2363
2395
|
exports.operationFromDocument = operationFromDocument;
|
|
2364
|
-
function operationFromAST({ schema, operation, variableDefinitions, fragments, validateInput, }) {
|
|
2396
|
+
function operationFromAST({ schema, operation, operation_directives, variableDefinitions, fragments, validateInput, }) {
|
|
2365
2397
|
var _a;
|
|
2366
2398
|
const rootType = schema.schemaDefinition.root(operation.operation);
|
|
2367
2399
|
validate(rootType, () => `The schema has no "${operation.operation}" root type defined`);
|
|
@@ -2372,7 +2404,7 @@ function operationFromAST({ schema, operation, variableDefinitions, fragments, v
|
|
|
2372
2404
|
variableDefinitions,
|
|
2373
2405
|
fragments: fragmentsIfAny,
|
|
2374
2406
|
validate: validateInput,
|
|
2375
|
-
}), variableDefinitions, fragmentsIfAny, (_a = operation.name) === null || _a === void 0 ? void 0 : _a.value);
|
|
2407
|
+
}), variableDefinitions, fragmentsIfAny, (_a = operation.name) === null || _a === void 0 ? void 0 : _a.value, operation_directives);
|
|
2376
2408
|
}
|
|
2377
2409
|
function parseOperation(schema, operation, options) {
|
|
2378
2410
|
return operationFromDocument(schema, (0, graphql_1.parse)(operation), options);
|
|
@@ -2403,6 +2435,7 @@ function operationToDocument(operation) {
|
|
|
2403
2435
|
name: operation.name ? { kind: graphql_1.Kind.NAME, value: operation.name } : undefined,
|
|
2404
2436
|
selectionSet: operation.selectionSet.toSelectionSetNode(),
|
|
2405
2437
|
variableDefinitions: operation.variableDefinitions.toVariableDefinitionNodes(),
|
|
2438
|
+
directives: (0, definitions_1.directivesToDirectiveNodes)(operation.directives),
|
|
2406
2439
|
};
|
|
2407
2440
|
const fragmentASTs = operation.fragments
|
|
2408
2441
|
? (_a = operation.fragments) === null || _a === void 0 ? void 0 : _a.toFragmentDefinitionNodes()
|