/
AddFragmentsByField.ts
76 lines (68 loc) · 2.11 KB
/
AddFragmentsByField.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
import {
DocumentNode,
GraphQLSchema,
GraphQLType,
Kind,
SelectionSetNode,
TypeInfo,
visit,
visitWithTypeInfo,
InlineFragmentNode,
} from 'graphql';
import { Request } from '@graphql-tools/utils';
import { Transform, DelegationContext } from '../types';
export default class AddFragmentsByField implements Transform {
private readonly targetSchema: GraphQLSchema;
private readonly mapping: Record<string, Record<string, InlineFragmentNode>>;
constructor(targetSchema: GraphQLSchema, mapping: Record<string, Record<string, InlineFragmentNode>>) {
this.targetSchema = targetSchema;
this.mapping = mapping;
}
public transformRequest(
originalRequest: Request,
_delegationContext: DelegationContext,
_transformationContext: Record<string, any>
): Request {
const document = addFragmentsByField(this.targetSchema, originalRequest.document, this.mapping);
return {
...originalRequest,
document,
};
}
}
function addFragmentsByField(
targetSchema: GraphQLSchema,
document: DocumentNode,
mapping: Record<string, Record<string, InlineFragmentNode>>
): DocumentNode {
const typeInfo = new TypeInfo(targetSchema);
return visit(
document,
visitWithTypeInfo(typeInfo, {
[Kind.SELECTION_SET](node: SelectionSetNode): SelectionSetNode | null | undefined {
const parentType: GraphQLType | null | undefined = typeInfo.getParentType();
if (parentType != null) {
const parentTypeName = parentType.name;
let selections = node.selections;
if (parentTypeName in mapping) {
node.selections.forEach(selection => {
if (selection.kind === Kind.FIELD) {
const name = selection.name.value;
const fragment = mapping[parentTypeName][name];
if (fragment != null) {
selections = selections.concat(fragment);
}
}
});
}
if (selections !== node.selections) {
return {
...node,
selections,
};
}
}
},
})
);
}