-
-
Notifications
You must be signed in to change notification settings - Fork 797
/
RenameInputObjectFields.ts
94 lines (84 loc) · 3.14 KB
/
RenameInputObjectFields.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
import { GraphQLInputFieldConfig, GraphQLSchema, ObjectFieldNode } from 'graphql';
import { DelegationContext, SubschemaConfig, Transform } from '@graphql-tools/delegate';
import { ExecutionRequest, MapperKind, mapSchema } from '@graphql-tools/utils';
import TransformInputObjectFields from './TransformInputObjectFields.js';
type RenamerFunction = (
typeName: string,
fieldName: string,
inputFieldConfig: GraphQLInputFieldConfig,
) => string | undefined;
interface RenameInputObjectFieldsTransformationContext extends Record<string, any> {}
export default class RenameInputObjectFields<TContext = Record<string, any>>
implements Transform<RenameInputObjectFieldsTransformationContext, TContext>
{
private readonly renamer: RenamerFunction;
private readonly transformer: TransformInputObjectFields<TContext>;
private reverseMap: Record<string, Record<string, string>>;
constructor(renamer: RenamerFunction) {
this.renamer = renamer;
this.transformer = new TransformInputObjectFields(
(typeName, inputFieldName, inputFieldConfig) => {
const newName = renamer(typeName, inputFieldName, inputFieldConfig);
if (newName !== undefined && newName !== inputFieldName) {
const value = renamer(typeName, inputFieldName, inputFieldConfig);
if (value != null) {
return [value, inputFieldConfig];
}
}
},
(typeName: string, inputFieldName: string, inputFieldNode: ObjectFieldNode) => {
if (!(typeName in this.reverseMap)) {
return inputFieldNode;
}
const inputFieldNameMap = this.reverseMap[typeName];
if (!(inputFieldName in inputFieldNameMap)) {
return inputFieldNode;
}
return {
...inputFieldNode,
name: {
...inputFieldNode.name,
value: inputFieldNameMap[inputFieldName],
},
};
},
);
this.reverseMap = Object.create(null);
}
public transformSchema(
originalWrappingSchema: GraphQLSchema,
subschemaConfig: SubschemaConfig<any, any, any, TContext>,
): GraphQLSchema {
mapSchema(originalWrappingSchema, {
[MapperKind.INPUT_OBJECT_FIELD]: (
inputFieldConfig: GraphQLInputFieldConfig,
fieldName: string,
typeName,
): undefined => {
const newName = this.renamer(typeName, fieldName, inputFieldConfig);
if (newName !== undefined && newName !== fieldName) {
if (this.reverseMap[typeName] == null) {
this.reverseMap[typeName] = Object.create(null);
}
this.reverseMap[typeName][newName] = fieldName;
}
return undefined;
},
[MapperKind.ROOT_OBJECT]() {
return undefined;
},
});
return this.transformer.transformSchema(originalWrappingSchema, subschemaConfig);
}
public transformRequest(
originalRequest: ExecutionRequest,
delegationContext: DelegationContext<TContext>,
transformationContext: RenameInputObjectFieldsTransformationContext,
): ExecutionRequest {
return this.transformer.transformRequest(
originalRequest,
delegationContext,
transformationContext,
);
}
}