-
-
Notifications
You must be signed in to change notification settings - Fork 796
/
mergeProxiedResults.ts
75 lines (65 loc) · 2.22 KB
/
mergeProxiedResults.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { GraphQLError, GraphQLResolveInfo, responsePathAsArray, SelectionSetNode, GraphQLObjectType } from 'graphql';
import {
mergeDeep,
ERROR_SYMBOL,
extendedError,
collectFields,
GraphQLExecutionContext,
relocatedError,
} from '@graphql-tools/utils';
import { SubschemaConfig } from '../types';
import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL } from '../symbols';
export function mergeProxiedResults(
info: GraphQLResolveInfo,
target: any,
sources: Array<any>,
selectionSets: Array<SelectionSetNode>
): any {
const results: Array<any> = [];
let errors: Array<GraphQLError> = [];
const path = responsePathAsArray(info.path);
sources.forEach((source, index) => {
if (source instanceof GraphQLError) {
const selectionSet = selectionSets[index];
const fieldNodes = collectFields(
{
schema: info.schema,
variableValues: {},
fragments: {},
} as GraphQLExecutionContext,
info.schema.getType(target.__typename) as GraphQLObjectType,
selectionSet,
Object.create(null),
Object.create(null)
);
const nullResult = {};
Object.keys(fieldNodes).forEach(responseKey => {
errors.push(relocatedError(source, [responseKey]));
nullResult[responseKey] = null;
});
results.push(nullResult);
} else {
errors = errors.concat(source[ERROR_SYMBOL]);
results.push(source);
}
});
const fieldSubschemaMap = results.reduce((acc: Record<any, SubschemaConfig>, source: any) => {
const subschema = source[OBJECT_SUBSCHEMA_SYMBOL];
Object.keys(source).forEach(key => {
acc[key] = subschema;
});
return acc;
}, {});
const result = results.reduce(mergeDeep, target);
result[FIELD_SUBSCHEMA_MAP_SYMBOL] = target[FIELD_SUBSCHEMA_MAP_SYMBOL]
? Object.assign({}, target[FIELD_SUBSCHEMA_MAP_SYMBOL], fieldSubschemaMap)
: fieldSubschemaMap;
const annotatedErrors = errors.map(error => {
return extendedError(error, {
...error.extensions,
graphQLToolsMergedPath: error.path != null ? [...path, ...error.path] : responsePathAsArray(info.path),
});
});
result[ERROR_SYMBOL] = target[ERROR_SYMBOL].concat(annotatedErrors);
return result;
}