/
resolvers.ts
112 lines (100 loc) · 3.01 KB
/
resolvers.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import {
GraphQLSchema,
GraphQLFieldResolver,
GraphQLObjectType,
} from 'graphql';
import {
Transform,
IResolvers,
Operation,
SubschemaConfig,
} from '../Interfaces';
import delegateToSchema from '../delegate/delegateToSchema';
import { handleResult } from '../delegate/checkResultAndHandleErrors';
import { makeMergedType } from '../stitch/makeMergedType';
import { getResponseKeyFromInfo } from '../stitch/getResponseKeyFromInfo';
import { getSubschema } from '../stitch/subSchema';
import { getErrors } from '../stitch/errors';
export function generateProxyingResolvers({
subschemaConfig,
transforms,
}: {
subschemaConfig: SubschemaConfig;
transforms?: Array<Transform>;
}): IResolvers {
const targetSchema = subschemaConfig.schema;
const operationTypes: Record<Operation, GraphQLObjectType> = {
query: targetSchema.getQueryType(),
mutation: targetSchema.getMutationType(),
subscription: targetSchema.getSubscriptionType(),
};
const createProxyingResolver =
subschemaConfig.createProxyingResolver != null
? subschemaConfig.createProxyingResolver
: defaultCreateProxyingResolver;
const resolvers = {};
Object.keys(operationTypes).forEach((operation: Operation) => {
const rootType = operationTypes[operation];
if (rootType != null) {
const typeName = rootType.name;
const fields = rootType.getFields();
resolvers[typeName] = {};
Object.keys(fields).forEach((fieldName) => {
const resolveField =
operation === 'subscription' ? 'subscribe' : 'resolve';
resolvers[typeName][fieldName] = {
[resolveField]: createProxyingResolver({
schema: subschemaConfig,
transforms,
operation,
}),
};
});
}
});
return resolvers;
}
function defaultCreateProxyingResolver({
schema,
transforms,
}: {
schema: SubschemaConfig;
transforms: Array<Transform>;
}): GraphQLFieldResolver<any, any> {
return (parent, _args, context, info) => {
if (parent != null) {
const responseKey = getResponseKeyFromInfo(info);
const errors = getErrors(parent, responseKey);
// Check to see if the parent contains a proxied result
if (errors != null) {
const subschema = getSubschema(parent, responseKey);
// If there is a proxied result from this subschema, return it
// This can happen even for a root field when the root type ia
// also nested as a field within a different type.
if (schema === subschema) {
return handleResult(
parent[responseKey],
errors,
subschema,
context,
info,
);
}
}
}
return delegateToSchema({
schema,
context,
info,
transforms,
});
};
}
export function stripResolvers(schema: GraphQLSchema): void {
const typeMap = schema.getTypeMap();
Object.keys(typeMap).forEach((typeName) => {
if (!typeName.startsWith('__')) {
makeMergedType(typeMap[typeName]);
}
});
}