@graphql-hive/router-runtime 1.2.5 → 1.3.0-alpha-a990d4c23ad5a2cd3bc5526ee8a987fa39a5ca86
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 +8 -1
- package/dist/index.cjs +416 -144
- package/dist/index.js +419 -147
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# @graphql-hive/router-runtime
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.3.0-alpha-a990d4c23ad5a2cd3bc5526ee8a987fa39a5ca86
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- [#2203](https://github.com/graphql-hive/gateway/pull/2203) [`12dfc58`](https://github.com/graphql-hive/gateway/commit/12dfc58cf08fcfb7e47a0a000f36f846701a05e1) Thanks [@ardatan](https://github.com/ardatan)! - EDFS Support for Router Runtime
|
|
9
|
+
|
|
10
|
+
|
|
4
11
|
### Patch Changes
|
|
5
12
|
|
|
6
13
|
|
package/dist/index.cjs
CHANGED
|
@@ -10,6 +10,219 @@ var graphql = require('graphql');
|
|
|
10
10
|
var core = require('@envelop/core');
|
|
11
11
|
var executor = require('@graphql-tools/executor');
|
|
12
12
|
|
|
13
|
+
const getTypeInfo = utils.memoize1(function getTypeInfo2(schema) {
|
|
14
|
+
return new graphql.TypeInfo(schema);
|
|
15
|
+
});
|
|
16
|
+
utils.memoize2(function getTypeInfoWithType2(schema, type) {
|
|
17
|
+
return graphql.versionInfo.major < 16 ? new graphql.TypeInfo(schema, void 0, type) : new graphql.TypeInfo(schema, type);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const getPubsubOperationRootFields = utils.memoize1(function(schema) {
|
|
21
|
+
const pubsubOperationFields = /* @__PURE__ */ new Map();
|
|
22
|
+
const subscriptionType = schema.getSubscriptionType();
|
|
23
|
+
if (subscriptionType) {
|
|
24
|
+
const subscriptionFields = subscriptionType.getFields();
|
|
25
|
+
for (const fieldName in subscriptionFields) {
|
|
26
|
+
const fieldDef = subscriptionFields[fieldName];
|
|
27
|
+
if (fieldDef) {
|
|
28
|
+
const pubsubOperations = utils.getDirectiveInExtensions(
|
|
29
|
+
fieldDef,
|
|
30
|
+
"pubsubOperation"
|
|
31
|
+
);
|
|
32
|
+
if (pubsubOperations) {
|
|
33
|
+
for (const { pubsubTopic } of pubsubOperations) {
|
|
34
|
+
pubsubOperationFields.set(fieldDef.name, pubsubTopic);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return pubsubOperationFields;
|
|
41
|
+
});
|
|
42
|
+
function resolvePubsubOperationRootField(responseKey, topicName, pubsub) {
|
|
43
|
+
return utils.mapAsyncIterator(pubsub.subscribe(topicName), (payload) => ({
|
|
44
|
+
data: {
|
|
45
|
+
[responseKey]: payload
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
}
|
|
49
|
+
function handlePubsubOperationField(supergraphSchema, executionRequest) {
|
|
50
|
+
if (executionRequest.operationType === "subscription") {
|
|
51
|
+
const typeInfo = getTypeInfo(supergraphSchema);
|
|
52
|
+
let responseKey;
|
|
53
|
+
let fieldName;
|
|
54
|
+
let selectionSet;
|
|
55
|
+
let returnType;
|
|
56
|
+
graphql.visit(
|
|
57
|
+
executionRequest.document,
|
|
58
|
+
graphql.visitWithTypeInfo(typeInfo, {
|
|
59
|
+
Field(node) {
|
|
60
|
+
const parentType = typeInfo.getParentType();
|
|
61
|
+
if (parentType === supergraphSchema.getSubscriptionType()) {
|
|
62
|
+
responseKey = node.alias?.value || node.name.value;
|
|
63
|
+
fieldName = node.name.value;
|
|
64
|
+
selectionSet = node.selectionSet;
|
|
65
|
+
const fieldDef = typeInfo.getFieldDef();
|
|
66
|
+
if (fieldDef) {
|
|
67
|
+
returnType = graphql.getNamedType(fieldDef.type);
|
|
68
|
+
}
|
|
69
|
+
return graphql.BREAK;
|
|
70
|
+
}
|
|
71
|
+
return node;
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
);
|
|
75
|
+
if (responseKey && fieldName) {
|
|
76
|
+
const pubsubOperationFields = getPubsubOperationRootFields(supergraphSchema);
|
|
77
|
+
const pubsubTopic = pubsubOperationFields.get(fieldName);
|
|
78
|
+
if (pubsubTopic) {
|
|
79
|
+
const pubsub = executionRequest.context?.pubsub;
|
|
80
|
+
if (!pubsub) {
|
|
81
|
+
throw utils.createGraphQLError(
|
|
82
|
+
`You have to configure a PubSub instance in the context to execute subscription operations with @pubsubOperation directive.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
let newExecutionRequest;
|
|
86
|
+
if (selectionSet && returnType) {
|
|
87
|
+
const newDocument = graphql.parse(
|
|
88
|
+
/* GraphQL */
|
|
89
|
+
`
|
|
90
|
+
query ${executionRequest.operationName}($representations: [_Any!]!) {
|
|
91
|
+
_entities(representations: $representations) {
|
|
92
|
+
__typename
|
|
93
|
+
... on ${returnType.name} ${graphql.print(selectionSet)}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
`
|
|
97
|
+
);
|
|
98
|
+
newExecutionRequest = {
|
|
99
|
+
...executionRequest,
|
|
100
|
+
document: newDocument
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
executionResult: resolvePubsubOperationRootField(
|
|
105
|
+
responseKey,
|
|
106
|
+
pubsubTopic,
|
|
107
|
+
pubsub
|
|
108
|
+
),
|
|
109
|
+
responseKey,
|
|
110
|
+
returnTypeName: returnType?.name,
|
|
111
|
+
newExecutionRequest
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
const getPubsubPublishVisitor = utils.memoize2(function getPubsubPublishFields(schema, pubsub) {
|
|
119
|
+
const pubsubPublishVisitor = {};
|
|
120
|
+
for (const typeName in schema.getTypeMap()) {
|
|
121
|
+
const type = schema.getType(typeName);
|
|
122
|
+
if (type != null && "getFields" in type) {
|
|
123
|
+
const fields = type.getFields();
|
|
124
|
+
for (const fieldName in fields) {
|
|
125
|
+
const fieldDef = fields[fieldName];
|
|
126
|
+
if (fieldDef) {
|
|
127
|
+
const pubsubPublishes = utils.getDirectiveInExtensions(
|
|
128
|
+
fieldDef,
|
|
129
|
+
"pubsubPublish"
|
|
130
|
+
);
|
|
131
|
+
if (pubsubPublishes) {
|
|
132
|
+
for (const { pubsubTopic } of pubsubPublishes) {
|
|
133
|
+
const typeVisitor = pubsubPublishVisitor[typeName] ||= {};
|
|
134
|
+
typeVisitor[fieldName] = (value) => {
|
|
135
|
+
pubsub.publish(pubsubTopic, value);
|
|
136
|
+
return value;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!Object.keys(pubsubPublishVisitor).length) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return pubsubPublishVisitor;
|
|
148
|
+
});
|
|
149
|
+
function handleResultWithPubSubPublish(schema, request, result) {
|
|
150
|
+
if (result.data != null && request.context?.pubsub != null) {
|
|
151
|
+
const pubsubPublishVisitor = getPubsubPublishVisitor(
|
|
152
|
+
schema,
|
|
153
|
+
request.context.pubsub
|
|
154
|
+
);
|
|
155
|
+
if (pubsubPublishVisitor) {
|
|
156
|
+
return utils.visitResult(result, request, schema, pubsubPublishVisitor);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const queryPlanForExecutionRequestContext = /* @__PURE__ */ new WeakMap();
|
|
162
|
+
function getLazyValue(factory) {
|
|
163
|
+
let _value;
|
|
164
|
+
return function() {
|
|
165
|
+
if (_value == null) {
|
|
166
|
+
_value = factory();
|
|
167
|
+
}
|
|
168
|
+
return _value;
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function getLazyFactory(factory) {
|
|
172
|
+
let _value;
|
|
173
|
+
return function(...args) {
|
|
174
|
+
if (!_value) {
|
|
175
|
+
_value = factory();
|
|
176
|
+
}
|
|
177
|
+
return _value(...args);
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function onSubgraphExecuteWithTransforms(subgraphName, executionRequest, onSubgraphExecute, getSubschema) {
|
|
181
|
+
const subschema = getSubschema(subgraphName);
|
|
182
|
+
if (subschema.transforms?.length) {
|
|
183
|
+
const transforms = subschema.transforms;
|
|
184
|
+
const transformationContext = /* @__PURE__ */ Object.create(null);
|
|
185
|
+
const delegationContext = void 0;
|
|
186
|
+
for (const transform of transforms) {
|
|
187
|
+
if (transform.transformRequest) {
|
|
188
|
+
executionRequest = transform.transformRequest(
|
|
189
|
+
executionRequest,
|
|
190
|
+
delegationContext,
|
|
191
|
+
transformationContext
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
196
|
+
() => onSubgraphExecute(subgraphName, executionRequest),
|
|
197
|
+
(executionResult) => {
|
|
198
|
+
for (const transform of transforms.toReversed()) {
|
|
199
|
+
if (transform.transformResult) {
|
|
200
|
+
executionResult = transform.transformResult(
|
|
201
|
+
executionResult,
|
|
202
|
+
delegationContext,
|
|
203
|
+
transformationContext
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return executionResult;
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return onSubgraphExecute(subgraphName, executionRequest);
|
|
212
|
+
}
|
|
213
|
+
function handleMaybePromiseMaybeAsyncIterable(executor, mapper, errorMapper) {
|
|
214
|
+
return promiseHelpers.handleMaybePromise(
|
|
215
|
+
executor,
|
|
216
|
+
(result$) => {
|
|
217
|
+
if (utils.isAsyncIterable(result$)) {
|
|
218
|
+
return promiseHelpers.mapAsyncIterator(result$, mapper, errorMapper);
|
|
219
|
+
}
|
|
220
|
+
return mapper(result$);
|
|
221
|
+
},
|
|
222
|
+
errorMapper
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
13
226
|
function isEntityRepresentation(obj) {
|
|
14
227
|
return obj?.__typename != null;
|
|
15
228
|
}
|
|
@@ -28,23 +241,17 @@ function executeQueryPlan({
|
|
|
28
241
|
executionRequest,
|
|
29
242
|
onSubgraphExecute
|
|
30
243
|
});
|
|
31
|
-
|
|
32
|
-
const executionResult = {};
|
|
33
|
-
if (Object.keys(executionContext.data).length > 0) {
|
|
34
|
-
executionResult.data = projectDataByOperation(executionContext);
|
|
35
|
-
}
|
|
36
|
-
if (executionContext.errors.length > 0) {
|
|
37
|
-
executionResult.errors = executionContext.errors;
|
|
38
|
-
}
|
|
39
|
-
return executionResult;
|
|
40
|
-
}
|
|
41
|
-
return promiseHelpers.handleMaybePromise(
|
|
244
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
42
245
|
() => executePlanNode(node, executionContext),
|
|
43
|
-
(
|
|
44
|
-
|
|
45
|
-
|
|
246
|
+
() => {
|
|
247
|
+
const executionResult = {};
|
|
248
|
+
if (Object.keys(executionContext.data).length > 0) {
|
|
249
|
+
executionResult.data = projectDataByOperation(executionContext);
|
|
46
250
|
}
|
|
47
|
-
|
|
251
|
+
if (executionContext.errors.length > 0) {
|
|
252
|
+
executionResult.errors = executionContext.errors;
|
|
253
|
+
}
|
|
254
|
+
return executionResult;
|
|
48
255
|
}
|
|
49
256
|
);
|
|
50
257
|
}
|
|
@@ -465,41 +672,7 @@ function executeBatchFetchPlanNode(batchFetchNode, executionContext, batchContex
|
|
|
465
672
|
batchContext,
|
|
466
673
|
selectedVariables
|
|
467
674
|
);
|
|
468
|
-
|
|
469
|
-
if (utils.isAsyncIterable(fetchResult)) {
|
|
470
|
-
return promiseHelpers.mapAsyncIterator(fetchResult, handleBatchResult);
|
|
471
|
-
}
|
|
472
|
-
if (fetchResult.errors?.length) {
|
|
473
|
-
executionContext.errors.push(
|
|
474
|
-
...normalizeBatchFetchErrors(fetchResult.errors, batchContext)
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
const responseData = fetchResult.data;
|
|
478
|
-
if (!responseData || typeof responseData !== "object") {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
for (const [aliasName, aliasContext] of batchContext.byAlias.entries()) {
|
|
482
|
-
let aliasData = responseData[aliasName];
|
|
483
|
-
if (!aliasData) {
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
if (aliasContext.outputRewrites?.length) {
|
|
487
|
-
aliasData = applyOutputRewrites(
|
|
488
|
-
aliasData,
|
|
489
|
-
aliasContext.outputRewrites,
|
|
490
|
-
executionContext.supergraphSchema
|
|
491
|
-
);
|
|
492
|
-
}
|
|
493
|
-
if (Array.isArray(aliasData)) {
|
|
494
|
-
applyBatchAliasEntities(
|
|
495
|
-
aliasData,
|
|
496
|
-
aliasContext
|
|
497
|
-
);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
return;
|
|
501
|
-
};
|
|
502
|
-
return promiseHelpers.handleMaybePromise(
|
|
675
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
503
676
|
() => executionContext.onSubgraphExecute(batchFetchNode.serviceName, {
|
|
504
677
|
document: getDocumentNodeOfFetchingNode(batchFetchNode),
|
|
505
678
|
variables: variablesForFetch,
|
|
@@ -512,7 +685,42 @@ function executeBatchFetchPlanNode(batchFetchNode, executionContext, batchContex
|
|
|
512
685
|
info: executionContext.executionRequest.info,
|
|
513
686
|
signal: executionContext.executionRequest.signal
|
|
514
687
|
}),
|
|
515
|
-
|
|
688
|
+
(fetchResult) => {
|
|
689
|
+
if (fetchResult.errors?.length) {
|
|
690
|
+
executionContext.errors.push(
|
|
691
|
+
...normalizeBatchFetchErrors(fetchResult.errors, batchContext)
|
|
692
|
+
);
|
|
693
|
+
}
|
|
694
|
+
const responseData = fetchResult.data;
|
|
695
|
+
if (!responseData || typeof responseData !== "object") {
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
for (const [aliasName, aliasContext] of batchContext.byAlias.entries()) {
|
|
699
|
+
let aliasData = responseData[aliasName];
|
|
700
|
+
if (!aliasData) {
|
|
701
|
+
continue;
|
|
702
|
+
}
|
|
703
|
+
if (aliasContext.outputRewrites?.length) {
|
|
704
|
+
aliasData = applyOutputRewrites(
|
|
705
|
+
aliasData,
|
|
706
|
+
aliasContext.outputRewrites,
|
|
707
|
+
executionContext.supergraphSchema
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
if (Array.isArray(aliasData)) {
|
|
711
|
+
applyBatchAliasEntities(
|
|
712
|
+
aliasData,
|
|
713
|
+
aliasContext
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return;
|
|
718
|
+
},
|
|
719
|
+
(error) => handleSubgraphExecutionError(
|
|
720
|
+
error,
|
|
721
|
+
executionContext,
|
|
722
|
+
batchFetchNode.serviceName
|
|
723
|
+
)
|
|
516
724
|
);
|
|
517
725
|
}
|
|
518
726
|
function executeFetchPlanNode(fetchNode, executionContext, state) {
|
|
@@ -582,53 +790,7 @@ function executeFetchPlanNode(fetchNode, executionContext, state) {
|
|
|
582
790
|
variablesForFetch = variablesForFetch ? { ...selectedVariables, ...variablesForFetch } : { ...selectedVariables };
|
|
583
791
|
}
|
|
584
792
|
const defaultErrorPath = state?.errorPath ?? state?.flatten?.errorPath ?? getDefaultErrorPath(fetchNode);
|
|
585
|
-
|
|
586
|
-
if (utils.isAsyncIterable(fetchResult)) {
|
|
587
|
-
return promiseHelpers.mapAsyncIterator(fetchResult, handleFetchResult);
|
|
588
|
-
}
|
|
589
|
-
if (fetchResult.errors?.length) {
|
|
590
|
-
const normalizedErrors = normalizeFetchErrors(fetchResult.errors, {
|
|
591
|
-
fetchNode,
|
|
592
|
-
state,
|
|
593
|
-
defaultPath: defaultErrorPath
|
|
594
|
-
});
|
|
595
|
-
if (normalizedErrors.length) {
|
|
596
|
-
executionContext.errors.push(...normalizedErrors);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
const responseData = fetchNode.outputRewrites ? applyOutputRewrites(
|
|
600
|
-
fetchResult.data,
|
|
601
|
-
fetchNode.outputRewrites,
|
|
602
|
-
executionContext.supergraphSchema
|
|
603
|
-
) : fetchResult.data;
|
|
604
|
-
if (!responseData) {
|
|
605
|
-
return;
|
|
606
|
-
}
|
|
607
|
-
if (flattenState && flattenState.entityRefs.length) {
|
|
608
|
-
const returnedEntities = responseData._entities;
|
|
609
|
-
if (Array.isArray(returnedEntities)) {
|
|
610
|
-
mergeFlattenEntities(returnedEntities, flattenState);
|
|
611
|
-
}
|
|
612
|
-
return;
|
|
613
|
-
}
|
|
614
|
-
if (representationTargets?.length && responseData._entities) {
|
|
615
|
-
const returnedEntities = responseData._entities;
|
|
616
|
-
for (let index = 0; index < returnedEntities.length; index++) {
|
|
617
|
-
const entity = returnedEntities[index];
|
|
618
|
-
const target = representationTargets[index];
|
|
619
|
-
if (target && entity) {
|
|
620
|
-
Object.assign(target, utils.mergeDeep([target, entity], false, true, true));
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
return;
|
|
624
|
-
}
|
|
625
|
-
Object.assign(
|
|
626
|
-
executionContext.data,
|
|
627
|
-
utils.mergeDeep([executionContext.data, responseData], false, true, true)
|
|
628
|
-
);
|
|
629
|
-
return;
|
|
630
|
-
};
|
|
631
|
-
return promiseHelpers.handleMaybePromise(
|
|
793
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
632
794
|
() => executionContext.onSubgraphExecute(fetchNode.serviceName, {
|
|
633
795
|
document: getDocumentNodeOfFetchingNode(fetchNode),
|
|
634
796
|
variables: variablesForFetch,
|
|
@@ -641,9 +803,76 @@ function executeFetchPlanNode(fetchNode, executionContext, state) {
|
|
|
641
803
|
info: executionContext.executionRequest.info,
|
|
642
804
|
signal: executionContext.executionRequest.signal
|
|
643
805
|
}),
|
|
644
|
-
|
|
806
|
+
(fetchResult) => {
|
|
807
|
+
if (fetchResult.errors?.length) {
|
|
808
|
+
const normalizedErrors = normalizeFetchErrors(fetchResult.errors, {
|
|
809
|
+
fetchNode,
|
|
810
|
+
state,
|
|
811
|
+
defaultPath: defaultErrorPath
|
|
812
|
+
});
|
|
813
|
+
if (normalizedErrors.length) {
|
|
814
|
+
executionContext.errors.push(...normalizedErrors);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
const responseData = fetchNode.outputRewrites ? applyOutputRewrites(
|
|
818
|
+
fetchResult.data,
|
|
819
|
+
fetchNode.outputRewrites,
|
|
820
|
+
executionContext.supergraphSchema
|
|
821
|
+
) : fetchResult.data;
|
|
822
|
+
if (!responseData) {
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
if (flattenState && flattenState.entityRefs.length) {
|
|
826
|
+
const returnedEntities = responseData._entities;
|
|
827
|
+
if (Array.isArray(returnedEntities)) {
|
|
828
|
+
mergeFlattenEntities(returnedEntities, flattenState);
|
|
829
|
+
}
|
|
830
|
+
return;
|
|
831
|
+
}
|
|
832
|
+
if (representationTargets?.length && responseData._entities) {
|
|
833
|
+
const returnedEntities = responseData._entities;
|
|
834
|
+
for (let index = 0; index < returnedEntities.length; index++) {
|
|
835
|
+
const entity = returnedEntities[index];
|
|
836
|
+
const target = representationTargets[index];
|
|
837
|
+
if (target && entity) {
|
|
838
|
+
Object.assign(
|
|
839
|
+
target,
|
|
840
|
+
utils.mergeDeep([target, entity], false, true, true)
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
Object.assign(
|
|
847
|
+
executionContext.data,
|
|
848
|
+
utils.mergeDeep([executionContext.data, responseData], false, true, true)
|
|
849
|
+
);
|
|
850
|
+
return;
|
|
851
|
+
},
|
|
852
|
+
(error) => handleSubgraphExecutionError(
|
|
853
|
+
error,
|
|
854
|
+
executionContext,
|
|
855
|
+
fetchNode.serviceName,
|
|
856
|
+
defaultErrorPath
|
|
857
|
+
)
|
|
645
858
|
);
|
|
646
859
|
}
|
|
860
|
+
function handleSubgraphExecutionError(error, executionContext, serviceName, path) {
|
|
861
|
+
let graphQLError;
|
|
862
|
+
if (error instanceof graphql.GraphQLError) {
|
|
863
|
+
graphQLError = error;
|
|
864
|
+
} else {
|
|
865
|
+
graphQLError = utils.createGraphQLError(error.message, {
|
|
866
|
+
originalError: error,
|
|
867
|
+
extensions: {
|
|
868
|
+
code: "DOWNSTREAM_SERVICE_ERROR",
|
|
869
|
+
serviceName
|
|
870
|
+
},
|
|
871
|
+
path
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
executionContext.errors.push(graphQLError);
|
|
875
|
+
}
|
|
647
876
|
function selectFetchVariables(variableValues, variableUsages) {
|
|
648
877
|
if (!variableValues || !variableUsages || variableUsages.length === 0) {
|
|
649
878
|
return void 0;
|
|
@@ -1333,20 +1562,12 @@ function projectRequires(requiresSelections, entity, supergraphSchema) {
|
|
|
1333
1562
|
return result;
|
|
1334
1563
|
}
|
|
1335
1564
|
|
|
1336
|
-
const queryPlanForExecutionRequestContext = /* @__PURE__ */ new WeakMap();
|
|
1337
|
-
function getLazyFactory(factory) {
|
|
1338
|
-
let _value;
|
|
1339
|
-
return function(...args) {
|
|
1340
|
-
if (!_value) {
|
|
1341
|
-
_value = factory();
|
|
1342
|
-
}
|
|
1343
|
-
return _value(...args);
|
|
1344
|
-
};
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
1565
|
async function unifiedGraphHandler(opts) {
|
|
1348
1566
|
const getSubschema = getLazyFactory(
|
|
1349
|
-
() =>
|
|
1567
|
+
() => getHandledFederationSupergraph().getSubschema
|
|
1568
|
+
);
|
|
1569
|
+
const getHandledFederationSupergraph = getLazyValue(
|
|
1570
|
+
() => fusionRuntime.handleFederationSupergraph(opts)
|
|
1350
1571
|
);
|
|
1351
1572
|
const moduleName = "@graphql-hive/router-query-planner";
|
|
1352
1573
|
const { QueryPlanner } = await import(moduleName);
|
|
@@ -1440,45 +1661,96 @@ async function unifiedGraphHandler(opts) {
|
|
|
1440
1661
|
supergraphSchema,
|
|
1441
1662
|
executionRequest,
|
|
1442
1663
|
onSubgraphExecute(subgraphName, executionRequest2) {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
void 0,
|
|
1452
|
-
transformationContext
|
|
1453
|
-
);
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
return promiseHelpers.handleMaybePromise(
|
|
1457
|
-
() => opts.onSubgraphExecute(subgraphName, executionRequest2),
|
|
1664
|
+
function executeSubgraph(executionRequest3) {
|
|
1665
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
1666
|
+
() => onSubgraphExecuteWithTransforms(
|
|
1667
|
+
subgraphName,
|
|
1668
|
+
executionRequest3,
|
|
1669
|
+
opts.onSubgraphExecute,
|
|
1670
|
+
getSubschema
|
|
1671
|
+
),
|
|
1458
1672
|
(executionResult) => {
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
void 0,
|
|
1465
|
-
transformationContext
|
|
1466
|
-
);
|
|
1467
|
-
}
|
|
1468
|
-
}
|
|
1469
|
-
return executionResult2;
|
|
1470
|
-
}
|
|
1471
|
-
if (utils.isAsyncIterable(executionResult)) {
|
|
1472
|
-
return promiseHelpers.mapAsyncIterator(
|
|
1473
|
-
executionResult,
|
|
1474
|
-
(result) => handleResult(result)
|
|
1673
|
+
if (executionRequest3.operationType === "mutation") {
|
|
1674
|
+
handleResultWithPubSubPublish(
|
|
1675
|
+
supergraphSchema,
|
|
1676
|
+
executionRequest3,
|
|
1677
|
+
executionResult
|
|
1475
1678
|
);
|
|
1476
1679
|
}
|
|
1477
|
-
return
|
|
1680
|
+
return executionResult;
|
|
1478
1681
|
}
|
|
1479
1682
|
);
|
|
1480
1683
|
}
|
|
1481
|
-
|
|
1684
|
+
const maybeResult = handlePubsubOperationField(
|
|
1685
|
+
supergraphSchema,
|
|
1686
|
+
executionRequest2
|
|
1687
|
+
);
|
|
1688
|
+
if (maybeResult) {
|
|
1689
|
+
const {
|
|
1690
|
+
executionResult,
|
|
1691
|
+
newExecutionRequest,
|
|
1692
|
+
responseKey,
|
|
1693
|
+
returnTypeName
|
|
1694
|
+
} = maybeResult;
|
|
1695
|
+
if (newExecutionRequest) {
|
|
1696
|
+
return promiseHelpers.mapAsyncIterator(
|
|
1697
|
+
executionResult,
|
|
1698
|
+
(executionResult2) => {
|
|
1699
|
+
if (executionResult2.data?.[responseKey] != null) {
|
|
1700
|
+
const representations = utils.asArray(
|
|
1701
|
+
executionResult2.data[responseKey]
|
|
1702
|
+
);
|
|
1703
|
+
if (returnTypeName) {
|
|
1704
|
+
for (const representation of representations) {
|
|
1705
|
+
representation.__typename = returnTypeName;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
1709
|
+
() => executeSubgraph({
|
|
1710
|
+
...newExecutionRequest,
|
|
1711
|
+
variables: {
|
|
1712
|
+
representations
|
|
1713
|
+
}
|
|
1714
|
+
}),
|
|
1715
|
+
(entitiesResult) => {
|
|
1716
|
+
if (entitiesResult?.data?._entities?.length) {
|
|
1717
|
+
const entities = utils.asArray(
|
|
1718
|
+
entitiesResult.data._entities
|
|
1719
|
+
);
|
|
1720
|
+
for (let i = 0; i < entities.length; i++) {
|
|
1721
|
+
const entity = entities[i];
|
|
1722
|
+
const representation = representations[i];
|
|
1723
|
+
if (entity != null && representation != null) {
|
|
1724
|
+
Object.assign(
|
|
1725
|
+
representation,
|
|
1726
|
+
utils.mergeDeep(
|
|
1727
|
+
[entity, representation],
|
|
1728
|
+
false,
|
|
1729
|
+
true,
|
|
1730
|
+
true
|
|
1731
|
+
)
|
|
1732
|
+
);
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1735
|
+
return executionResult2;
|
|
1736
|
+
}
|
|
1737
|
+
if (entitiesResult?.errors?.length) {
|
|
1738
|
+
executionResult2.errors ||= [];
|
|
1739
|
+
executionResult2.errors.push(
|
|
1740
|
+
...entitiesResult.errors
|
|
1741
|
+
);
|
|
1742
|
+
}
|
|
1743
|
+
return executionResult2;
|
|
1744
|
+
}
|
|
1745
|
+
);
|
|
1746
|
+
}
|
|
1747
|
+
return executionResult2;
|
|
1748
|
+
}
|
|
1749
|
+
);
|
|
1750
|
+
}
|
|
1751
|
+
return executionResult;
|
|
1752
|
+
}
|
|
1753
|
+
return executeSubgraph(executionRequest2);
|
|
1482
1754
|
},
|
|
1483
1755
|
queryPlan
|
|
1484
1756
|
});
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,225 @@ import { handleFederationSupergraph } from '@graphql-mesh/fusion-runtime';
|
|
|
2
2
|
import { createDefaultExecutor } from '@graphql-mesh/transport-common';
|
|
3
3
|
import { defaultPrintFn } from '@graphql-tools/executor-common';
|
|
4
4
|
import { filterInternalFieldsAndTypes, getRngFromEnv } from '@graphql-tools/federation';
|
|
5
|
-
import {
|
|
6
|
-
import { handleMaybePromise, mapAsyncIterator, isPromise } from '@whatwg-node/promise-helpers';
|
|
7
|
-
import {
|
|
5
|
+
import { memoize1, memoize2, createGraphQLError, visitResult, getDirectiveInExtensions, mapAsyncIterator, isAsyncIterable, getOperationASTFromRequest, getOperationASTFromDocument, mergeDeep, relocatedError, getDirective, asArray } from '@graphql-tools/utils';
|
|
6
|
+
import { handleMaybePromise, mapAsyncIterator as mapAsyncIterator$1, isPromise } from '@whatwg-node/promise-helpers';
|
|
7
|
+
import { TypeInfo, versionInfo, visit, visitWithTypeInfo, getNamedType, BREAK, parse, print, Kind, isObjectType, isInterfaceType, TypeNameMetaFieldDef, isEnumType, isNonNullType, isOutputType, GraphQLError, isAbstractType } from 'graphql';
|
|
8
8
|
import { documentStringMap } from '@envelop/core';
|
|
9
9
|
import { getFragmentsFromDocument, getVariableValues } from '@graphql-tools/executor';
|
|
10
10
|
|
|
11
|
+
const getTypeInfo = memoize1(function getTypeInfo2(schema) {
|
|
12
|
+
return new TypeInfo(schema);
|
|
13
|
+
});
|
|
14
|
+
memoize2(function getTypeInfoWithType2(schema, type) {
|
|
15
|
+
return versionInfo.major < 16 ? new TypeInfo(schema, void 0, type) : new TypeInfo(schema, type);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const getPubsubOperationRootFields = memoize1(function(schema) {
|
|
19
|
+
const pubsubOperationFields = /* @__PURE__ */ new Map();
|
|
20
|
+
const subscriptionType = schema.getSubscriptionType();
|
|
21
|
+
if (subscriptionType) {
|
|
22
|
+
const subscriptionFields = subscriptionType.getFields();
|
|
23
|
+
for (const fieldName in subscriptionFields) {
|
|
24
|
+
const fieldDef = subscriptionFields[fieldName];
|
|
25
|
+
if (fieldDef) {
|
|
26
|
+
const pubsubOperations = getDirectiveInExtensions(
|
|
27
|
+
fieldDef,
|
|
28
|
+
"pubsubOperation"
|
|
29
|
+
);
|
|
30
|
+
if (pubsubOperations) {
|
|
31
|
+
for (const { pubsubTopic } of pubsubOperations) {
|
|
32
|
+
pubsubOperationFields.set(fieldDef.name, pubsubTopic);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return pubsubOperationFields;
|
|
39
|
+
});
|
|
40
|
+
function resolvePubsubOperationRootField(responseKey, topicName, pubsub) {
|
|
41
|
+
return mapAsyncIterator(pubsub.subscribe(topicName), (payload) => ({
|
|
42
|
+
data: {
|
|
43
|
+
[responseKey]: payload
|
|
44
|
+
}
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
function handlePubsubOperationField(supergraphSchema, executionRequest) {
|
|
48
|
+
if (executionRequest.operationType === "subscription") {
|
|
49
|
+
const typeInfo = getTypeInfo(supergraphSchema);
|
|
50
|
+
let responseKey;
|
|
51
|
+
let fieldName;
|
|
52
|
+
let selectionSet;
|
|
53
|
+
let returnType;
|
|
54
|
+
visit(
|
|
55
|
+
executionRequest.document,
|
|
56
|
+
visitWithTypeInfo(typeInfo, {
|
|
57
|
+
Field(node) {
|
|
58
|
+
const parentType = typeInfo.getParentType();
|
|
59
|
+
if (parentType === supergraphSchema.getSubscriptionType()) {
|
|
60
|
+
responseKey = node.alias?.value || node.name.value;
|
|
61
|
+
fieldName = node.name.value;
|
|
62
|
+
selectionSet = node.selectionSet;
|
|
63
|
+
const fieldDef = typeInfo.getFieldDef();
|
|
64
|
+
if (fieldDef) {
|
|
65
|
+
returnType = getNamedType(fieldDef.type);
|
|
66
|
+
}
|
|
67
|
+
return BREAK;
|
|
68
|
+
}
|
|
69
|
+
return node;
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
if (responseKey && fieldName) {
|
|
74
|
+
const pubsubOperationFields = getPubsubOperationRootFields(supergraphSchema);
|
|
75
|
+
const pubsubTopic = pubsubOperationFields.get(fieldName);
|
|
76
|
+
if (pubsubTopic) {
|
|
77
|
+
const pubsub = executionRequest.context?.pubsub;
|
|
78
|
+
if (!pubsub) {
|
|
79
|
+
throw createGraphQLError(
|
|
80
|
+
`You have to configure a PubSub instance in the context to execute subscription operations with @pubsubOperation directive.`
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
let newExecutionRequest;
|
|
84
|
+
if (selectionSet && returnType) {
|
|
85
|
+
const newDocument = parse(
|
|
86
|
+
/* GraphQL */
|
|
87
|
+
`
|
|
88
|
+
query ${executionRequest.operationName}($representations: [_Any!]!) {
|
|
89
|
+
_entities(representations: $representations) {
|
|
90
|
+
__typename
|
|
91
|
+
... on ${returnType.name} ${print(selectionSet)}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
`
|
|
95
|
+
);
|
|
96
|
+
newExecutionRequest = {
|
|
97
|
+
...executionRequest,
|
|
98
|
+
document: newDocument
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
executionResult: resolvePubsubOperationRootField(
|
|
103
|
+
responseKey,
|
|
104
|
+
pubsubTopic,
|
|
105
|
+
pubsub
|
|
106
|
+
),
|
|
107
|
+
responseKey,
|
|
108
|
+
returnTypeName: returnType?.name,
|
|
109
|
+
newExecutionRequest
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const getPubsubPublishVisitor = memoize2(function getPubsubPublishFields(schema, pubsub) {
|
|
117
|
+
const pubsubPublishVisitor = {};
|
|
118
|
+
for (const typeName in schema.getTypeMap()) {
|
|
119
|
+
const type = schema.getType(typeName);
|
|
120
|
+
if (type != null && "getFields" in type) {
|
|
121
|
+
const fields = type.getFields();
|
|
122
|
+
for (const fieldName in fields) {
|
|
123
|
+
const fieldDef = fields[fieldName];
|
|
124
|
+
if (fieldDef) {
|
|
125
|
+
const pubsubPublishes = getDirectiveInExtensions(
|
|
126
|
+
fieldDef,
|
|
127
|
+
"pubsubPublish"
|
|
128
|
+
);
|
|
129
|
+
if (pubsubPublishes) {
|
|
130
|
+
for (const { pubsubTopic } of pubsubPublishes) {
|
|
131
|
+
const typeVisitor = pubsubPublishVisitor[typeName] ||= {};
|
|
132
|
+
typeVisitor[fieldName] = (value) => {
|
|
133
|
+
pubsub.publish(pubsubTopic, value);
|
|
134
|
+
return value;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (!Object.keys(pubsubPublishVisitor).length) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return pubsubPublishVisitor;
|
|
146
|
+
});
|
|
147
|
+
function handleResultWithPubSubPublish(schema, request, result) {
|
|
148
|
+
if (result.data != null && request.context?.pubsub != null) {
|
|
149
|
+
const pubsubPublishVisitor = getPubsubPublishVisitor(
|
|
150
|
+
schema,
|
|
151
|
+
request.context.pubsub
|
|
152
|
+
);
|
|
153
|
+
if (pubsubPublishVisitor) {
|
|
154
|
+
return visitResult(result, request, schema, pubsubPublishVisitor);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const queryPlanForExecutionRequestContext = /* @__PURE__ */ new WeakMap();
|
|
160
|
+
function getLazyValue(factory) {
|
|
161
|
+
let _value;
|
|
162
|
+
return function() {
|
|
163
|
+
if (_value == null) {
|
|
164
|
+
_value = factory();
|
|
165
|
+
}
|
|
166
|
+
return _value;
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function getLazyFactory(factory) {
|
|
170
|
+
let _value;
|
|
171
|
+
return function(...args) {
|
|
172
|
+
if (!_value) {
|
|
173
|
+
_value = factory();
|
|
174
|
+
}
|
|
175
|
+
return _value(...args);
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function onSubgraphExecuteWithTransforms(subgraphName, executionRequest, onSubgraphExecute, getSubschema) {
|
|
179
|
+
const subschema = getSubschema(subgraphName);
|
|
180
|
+
if (subschema.transforms?.length) {
|
|
181
|
+
const transforms = subschema.transforms;
|
|
182
|
+
const transformationContext = /* @__PURE__ */ Object.create(null);
|
|
183
|
+
const delegationContext = void 0;
|
|
184
|
+
for (const transform of transforms) {
|
|
185
|
+
if (transform.transformRequest) {
|
|
186
|
+
executionRequest = transform.transformRequest(
|
|
187
|
+
executionRequest,
|
|
188
|
+
delegationContext,
|
|
189
|
+
transformationContext
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
194
|
+
() => onSubgraphExecute(subgraphName, executionRequest),
|
|
195
|
+
(executionResult) => {
|
|
196
|
+
for (const transform of transforms.toReversed()) {
|
|
197
|
+
if (transform.transformResult) {
|
|
198
|
+
executionResult = transform.transformResult(
|
|
199
|
+
executionResult,
|
|
200
|
+
delegationContext,
|
|
201
|
+
transformationContext
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return executionResult;
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return onSubgraphExecute(subgraphName, executionRequest);
|
|
210
|
+
}
|
|
211
|
+
function handleMaybePromiseMaybeAsyncIterable(executor, mapper, errorMapper) {
|
|
212
|
+
return handleMaybePromise(
|
|
213
|
+
executor,
|
|
214
|
+
(result$) => {
|
|
215
|
+
if (isAsyncIterable(result$)) {
|
|
216
|
+
return mapAsyncIterator$1(result$, mapper, errorMapper);
|
|
217
|
+
}
|
|
218
|
+
return mapper(result$);
|
|
219
|
+
},
|
|
220
|
+
errorMapper
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
11
224
|
function isEntityRepresentation(obj) {
|
|
12
225
|
return obj?.__typename != null;
|
|
13
226
|
}
|
|
@@ -26,23 +239,17 @@ function executeQueryPlan({
|
|
|
26
239
|
executionRequest,
|
|
27
240
|
onSubgraphExecute
|
|
28
241
|
});
|
|
29
|
-
|
|
30
|
-
const executionResult = {};
|
|
31
|
-
if (Object.keys(executionContext.data).length > 0) {
|
|
32
|
-
executionResult.data = projectDataByOperation(executionContext);
|
|
33
|
-
}
|
|
34
|
-
if (executionContext.errors.length > 0) {
|
|
35
|
-
executionResult.errors = executionContext.errors;
|
|
36
|
-
}
|
|
37
|
-
return executionResult;
|
|
38
|
-
}
|
|
39
|
-
return handleMaybePromise(
|
|
242
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
40
243
|
() => executePlanNode(node, executionContext),
|
|
41
|
-
(
|
|
42
|
-
|
|
43
|
-
|
|
244
|
+
() => {
|
|
245
|
+
const executionResult = {};
|
|
246
|
+
if (Object.keys(executionContext.data).length > 0) {
|
|
247
|
+
executionResult.data = projectDataByOperation(executionContext);
|
|
44
248
|
}
|
|
45
|
-
|
|
249
|
+
if (executionContext.errors.length > 0) {
|
|
250
|
+
executionResult.errors = executionContext.errors;
|
|
251
|
+
}
|
|
252
|
+
return executionResult;
|
|
46
253
|
}
|
|
47
254
|
);
|
|
48
255
|
}
|
|
@@ -463,41 +670,7 @@ function executeBatchFetchPlanNode(batchFetchNode, executionContext, batchContex
|
|
|
463
670
|
batchContext,
|
|
464
671
|
selectedVariables
|
|
465
672
|
);
|
|
466
|
-
|
|
467
|
-
if (isAsyncIterable(fetchResult)) {
|
|
468
|
-
return mapAsyncIterator(fetchResult, handleBatchResult);
|
|
469
|
-
}
|
|
470
|
-
if (fetchResult.errors?.length) {
|
|
471
|
-
executionContext.errors.push(
|
|
472
|
-
...normalizeBatchFetchErrors(fetchResult.errors, batchContext)
|
|
473
|
-
);
|
|
474
|
-
}
|
|
475
|
-
const responseData = fetchResult.data;
|
|
476
|
-
if (!responseData || typeof responseData !== "object") {
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
for (const [aliasName, aliasContext] of batchContext.byAlias.entries()) {
|
|
480
|
-
let aliasData = responseData[aliasName];
|
|
481
|
-
if (!aliasData) {
|
|
482
|
-
continue;
|
|
483
|
-
}
|
|
484
|
-
if (aliasContext.outputRewrites?.length) {
|
|
485
|
-
aliasData = applyOutputRewrites(
|
|
486
|
-
aliasData,
|
|
487
|
-
aliasContext.outputRewrites,
|
|
488
|
-
executionContext.supergraphSchema
|
|
489
|
-
);
|
|
490
|
-
}
|
|
491
|
-
if (Array.isArray(aliasData)) {
|
|
492
|
-
applyBatchAliasEntities(
|
|
493
|
-
aliasData,
|
|
494
|
-
aliasContext
|
|
495
|
-
);
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
return;
|
|
499
|
-
};
|
|
500
|
-
return handleMaybePromise(
|
|
673
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
501
674
|
() => executionContext.onSubgraphExecute(batchFetchNode.serviceName, {
|
|
502
675
|
document: getDocumentNodeOfFetchingNode(batchFetchNode),
|
|
503
676
|
variables: variablesForFetch,
|
|
@@ -510,7 +683,42 @@ function executeBatchFetchPlanNode(batchFetchNode, executionContext, batchContex
|
|
|
510
683
|
info: executionContext.executionRequest.info,
|
|
511
684
|
signal: executionContext.executionRequest.signal
|
|
512
685
|
}),
|
|
513
|
-
|
|
686
|
+
(fetchResult) => {
|
|
687
|
+
if (fetchResult.errors?.length) {
|
|
688
|
+
executionContext.errors.push(
|
|
689
|
+
...normalizeBatchFetchErrors(fetchResult.errors, batchContext)
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
const responseData = fetchResult.data;
|
|
693
|
+
if (!responseData || typeof responseData !== "object") {
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
for (const [aliasName, aliasContext] of batchContext.byAlias.entries()) {
|
|
697
|
+
let aliasData = responseData[aliasName];
|
|
698
|
+
if (!aliasData) {
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
if (aliasContext.outputRewrites?.length) {
|
|
702
|
+
aliasData = applyOutputRewrites(
|
|
703
|
+
aliasData,
|
|
704
|
+
aliasContext.outputRewrites,
|
|
705
|
+
executionContext.supergraphSchema
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
if (Array.isArray(aliasData)) {
|
|
709
|
+
applyBatchAliasEntities(
|
|
710
|
+
aliasData,
|
|
711
|
+
aliasContext
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
return;
|
|
716
|
+
},
|
|
717
|
+
(error) => handleSubgraphExecutionError(
|
|
718
|
+
error,
|
|
719
|
+
executionContext,
|
|
720
|
+
batchFetchNode.serviceName
|
|
721
|
+
)
|
|
514
722
|
);
|
|
515
723
|
}
|
|
516
724
|
function executeFetchPlanNode(fetchNode, executionContext, state) {
|
|
@@ -580,53 +788,7 @@ function executeFetchPlanNode(fetchNode, executionContext, state) {
|
|
|
580
788
|
variablesForFetch = variablesForFetch ? { ...selectedVariables, ...variablesForFetch } : { ...selectedVariables };
|
|
581
789
|
}
|
|
582
790
|
const defaultErrorPath = state?.errorPath ?? state?.flatten?.errorPath ?? getDefaultErrorPath(fetchNode);
|
|
583
|
-
|
|
584
|
-
if (isAsyncIterable(fetchResult)) {
|
|
585
|
-
return mapAsyncIterator(fetchResult, handleFetchResult);
|
|
586
|
-
}
|
|
587
|
-
if (fetchResult.errors?.length) {
|
|
588
|
-
const normalizedErrors = normalizeFetchErrors(fetchResult.errors, {
|
|
589
|
-
fetchNode,
|
|
590
|
-
state,
|
|
591
|
-
defaultPath: defaultErrorPath
|
|
592
|
-
});
|
|
593
|
-
if (normalizedErrors.length) {
|
|
594
|
-
executionContext.errors.push(...normalizedErrors);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
const responseData = fetchNode.outputRewrites ? applyOutputRewrites(
|
|
598
|
-
fetchResult.data,
|
|
599
|
-
fetchNode.outputRewrites,
|
|
600
|
-
executionContext.supergraphSchema
|
|
601
|
-
) : fetchResult.data;
|
|
602
|
-
if (!responseData) {
|
|
603
|
-
return;
|
|
604
|
-
}
|
|
605
|
-
if (flattenState && flattenState.entityRefs.length) {
|
|
606
|
-
const returnedEntities = responseData._entities;
|
|
607
|
-
if (Array.isArray(returnedEntities)) {
|
|
608
|
-
mergeFlattenEntities(returnedEntities, flattenState);
|
|
609
|
-
}
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
if (representationTargets?.length && responseData._entities) {
|
|
613
|
-
const returnedEntities = responseData._entities;
|
|
614
|
-
for (let index = 0; index < returnedEntities.length; index++) {
|
|
615
|
-
const entity = returnedEntities[index];
|
|
616
|
-
const target = representationTargets[index];
|
|
617
|
-
if (target && entity) {
|
|
618
|
-
Object.assign(target, mergeDeep([target, entity], false, true, true));
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
Object.assign(
|
|
624
|
-
executionContext.data,
|
|
625
|
-
mergeDeep([executionContext.data, responseData], false, true, true)
|
|
626
|
-
);
|
|
627
|
-
return;
|
|
628
|
-
};
|
|
629
|
-
return handleMaybePromise(
|
|
791
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
630
792
|
() => executionContext.onSubgraphExecute(fetchNode.serviceName, {
|
|
631
793
|
document: getDocumentNodeOfFetchingNode(fetchNode),
|
|
632
794
|
variables: variablesForFetch,
|
|
@@ -639,9 +801,76 @@ function executeFetchPlanNode(fetchNode, executionContext, state) {
|
|
|
639
801
|
info: executionContext.executionRequest.info,
|
|
640
802
|
signal: executionContext.executionRequest.signal
|
|
641
803
|
}),
|
|
642
|
-
|
|
804
|
+
(fetchResult) => {
|
|
805
|
+
if (fetchResult.errors?.length) {
|
|
806
|
+
const normalizedErrors = normalizeFetchErrors(fetchResult.errors, {
|
|
807
|
+
fetchNode,
|
|
808
|
+
state,
|
|
809
|
+
defaultPath: defaultErrorPath
|
|
810
|
+
});
|
|
811
|
+
if (normalizedErrors.length) {
|
|
812
|
+
executionContext.errors.push(...normalizedErrors);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const responseData = fetchNode.outputRewrites ? applyOutputRewrites(
|
|
816
|
+
fetchResult.data,
|
|
817
|
+
fetchNode.outputRewrites,
|
|
818
|
+
executionContext.supergraphSchema
|
|
819
|
+
) : fetchResult.data;
|
|
820
|
+
if (!responseData) {
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
if (flattenState && flattenState.entityRefs.length) {
|
|
824
|
+
const returnedEntities = responseData._entities;
|
|
825
|
+
if (Array.isArray(returnedEntities)) {
|
|
826
|
+
mergeFlattenEntities(returnedEntities, flattenState);
|
|
827
|
+
}
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (representationTargets?.length && responseData._entities) {
|
|
831
|
+
const returnedEntities = responseData._entities;
|
|
832
|
+
for (let index = 0; index < returnedEntities.length; index++) {
|
|
833
|
+
const entity = returnedEntities[index];
|
|
834
|
+
const target = representationTargets[index];
|
|
835
|
+
if (target && entity) {
|
|
836
|
+
Object.assign(
|
|
837
|
+
target,
|
|
838
|
+
mergeDeep([target, entity], false, true, true)
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
Object.assign(
|
|
845
|
+
executionContext.data,
|
|
846
|
+
mergeDeep([executionContext.data, responseData], false, true, true)
|
|
847
|
+
);
|
|
848
|
+
return;
|
|
849
|
+
},
|
|
850
|
+
(error) => handleSubgraphExecutionError(
|
|
851
|
+
error,
|
|
852
|
+
executionContext,
|
|
853
|
+
fetchNode.serviceName,
|
|
854
|
+
defaultErrorPath
|
|
855
|
+
)
|
|
643
856
|
);
|
|
644
857
|
}
|
|
858
|
+
function handleSubgraphExecutionError(error, executionContext, serviceName, path) {
|
|
859
|
+
let graphQLError;
|
|
860
|
+
if (error instanceof GraphQLError) {
|
|
861
|
+
graphQLError = error;
|
|
862
|
+
} else {
|
|
863
|
+
graphQLError = createGraphQLError(error.message, {
|
|
864
|
+
originalError: error,
|
|
865
|
+
extensions: {
|
|
866
|
+
code: "DOWNSTREAM_SERVICE_ERROR",
|
|
867
|
+
serviceName
|
|
868
|
+
},
|
|
869
|
+
path
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
executionContext.errors.push(graphQLError);
|
|
873
|
+
}
|
|
645
874
|
function selectFetchVariables(variableValues, variableUsages) {
|
|
646
875
|
if (!variableValues || !variableUsages || variableUsages.length === 0) {
|
|
647
876
|
return void 0;
|
|
@@ -1331,20 +1560,12 @@ function projectRequires(requiresSelections, entity, supergraphSchema) {
|
|
|
1331
1560
|
return result;
|
|
1332
1561
|
}
|
|
1333
1562
|
|
|
1334
|
-
const queryPlanForExecutionRequestContext = /* @__PURE__ */ new WeakMap();
|
|
1335
|
-
function getLazyFactory(factory) {
|
|
1336
|
-
let _value;
|
|
1337
|
-
return function(...args) {
|
|
1338
|
-
if (!_value) {
|
|
1339
|
-
_value = factory();
|
|
1340
|
-
}
|
|
1341
|
-
return _value(...args);
|
|
1342
|
-
};
|
|
1343
|
-
}
|
|
1344
|
-
|
|
1345
1563
|
async function unifiedGraphHandler(opts) {
|
|
1346
1564
|
const getSubschema = getLazyFactory(
|
|
1347
|
-
() =>
|
|
1565
|
+
() => getHandledFederationSupergraph().getSubschema
|
|
1566
|
+
);
|
|
1567
|
+
const getHandledFederationSupergraph = getLazyValue(
|
|
1568
|
+
() => handleFederationSupergraph(opts)
|
|
1348
1569
|
);
|
|
1349
1570
|
const moduleName = "@graphql-hive/router-query-planner";
|
|
1350
1571
|
const { QueryPlanner } = await import(moduleName);
|
|
@@ -1438,45 +1659,96 @@ async function unifiedGraphHandler(opts) {
|
|
|
1438
1659
|
supergraphSchema,
|
|
1439
1660
|
executionRequest,
|
|
1440
1661
|
onSubgraphExecute(subgraphName, executionRequest2) {
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
void 0,
|
|
1450
|
-
transformationContext
|
|
1451
|
-
);
|
|
1452
|
-
}
|
|
1453
|
-
}
|
|
1454
|
-
return handleMaybePromise(
|
|
1455
|
-
() => opts.onSubgraphExecute(subgraphName, executionRequest2),
|
|
1662
|
+
function executeSubgraph(executionRequest3) {
|
|
1663
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
1664
|
+
() => onSubgraphExecuteWithTransforms(
|
|
1665
|
+
subgraphName,
|
|
1666
|
+
executionRequest3,
|
|
1667
|
+
opts.onSubgraphExecute,
|
|
1668
|
+
getSubschema
|
|
1669
|
+
),
|
|
1456
1670
|
(executionResult) => {
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
void 0,
|
|
1463
|
-
transformationContext
|
|
1464
|
-
);
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
return executionResult2;
|
|
1468
|
-
}
|
|
1469
|
-
if (isAsyncIterable(executionResult)) {
|
|
1470
|
-
return mapAsyncIterator(
|
|
1471
|
-
executionResult,
|
|
1472
|
-
(result) => handleResult(result)
|
|
1671
|
+
if (executionRequest3.operationType === "mutation") {
|
|
1672
|
+
handleResultWithPubSubPublish(
|
|
1673
|
+
supergraphSchema,
|
|
1674
|
+
executionRequest3,
|
|
1675
|
+
executionResult
|
|
1473
1676
|
);
|
|
1474
1677
|
}
|
|
1475
|
-
return
|
|
1678
|
+
return executionResult;
|
|
1476
1679
|
}
|
|
1477
1680
|
);
|
|
1478
1681
|
}
|
|
1479
|
-
|
|
1682
|
+
const maybeResult = handlePubsubOperationField(
|
|
1683
|
+
supergraphSchema,
|
|
1684
|
+
executionRequest2
|
|
1685
|
+
);
|
|
1686
|
+
if (maybeResult) {
|
|
1687
|
+
const {
|
|
1688
|
+
executionResult,
|
|
1689
|
+
newExecutionRequest,
|
|
1690
|
+
responseKey,
|
|
1691
|
+
returnTypeName
|
|
1692
|
+
} = maybeResult;
|
|
1693
|
+
if (newExecutionRequest) {
|
|
1694
|
+
return mapAsyncIterator$1(
|
|
1695
|
+
executionResult,
|
|
1696
|
+
(executionResult2) => {
|
|
1697
|
+
if (executionResult2.data?.[responseKey] != null) {
|
|
1698
|
+
const representations = asArray(
|
|
1699
|
+
executionResult2.data[responseKey]
|
|
1700
|
+
);
|
|
1701
|
+
if (returnTypeName) {
|
|
1702
|
+
for (const representation of representations) {
|
|
1703
|
+
representation.__typename = returnTypeName;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return handleMaybePromiseMaybeAsyncIterable(
|
|
1707
|
+
() => executeSubgraph({
|
|
1708
|
+
...newExecutionRequest,
|
|
1709
|
+
variables: {
|
|
1710
|
+
representations
|
|
1711
|
+
}
|
|
1712
|
+
}),
|
|
1713
|
+
(entitiesResult) => {
|
|
1714
|
+
if (entitiesResult?.data?._entities?.length) {
|
|
1715
|
+
const entities = asArray(
|
|
1716
|
+
entitiesResult.data._entities
|
|
1717
|
+
);
|
|
1718
|
+
for (let i = 0; i < entities.length; i++) {
|
|
1719
|
+
const entity = entities[i];
|
|
1720
|
+
const representation = representations[i];
|
|
1721
|
+
if (entity != null && representation != null) {
|
|
1722
|
+
Object.assign(
|
|
1723
|
+
representation,
|
|
1724
|
+
mergeDeep(
|
|
1725
|
+
[entity, representation],
|
|
1726
|
+
false,
|
|
1727
|
+
true,
|
|
1728
|
+
true
|
|
1729
|
+
)
|
|
1730
|
+
);
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
return executionResult2;
|
|
1734
|
+
}
|
|
1735
|
+
if (entitiesResult?.errors?.length) {
|
|
1736
|
+
executionResult2.errors ||= [];
|
|
1737
|
+
executionResult2.errors.push(
|
|
1738
|
+
...entitiesResult.errors
|
|
1739
|
+
);
|
|
1740
|
+
}
|
|
1741
|
+
return executionResult2;
|
|
1742
|
+
}
|
|
1743
|
+
);
|
|
1744
|
+
}
|
|
1745
|
+
return executionResult2;
|
|
1746
|
+
}
|
|
1747
|
+
);
|
|
1748
|
+
}
|
|
1749
|
+
return executionResult;
|
|
1750
|
+
}
|
|
1751
|
+
return executeSubgraph(executionRequest2);
|
|
1480
1752
|
},
|
|
1481
1753
|
queryPlan
|
|
1482
1754
|
});
|