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
113
114
115
116
117
118
119
120 | 17x
17x
17x
17x
17x
17x
17x
17x
58x
9x
49x
57x
57x
57x
57x
1x
57x
62x
62x
58x
57x
57x
57x
17x
57x
57x
57x
57x
1x
56x
98x
98x
98x
57x
1x
56x
56x
92x
49x
49x
49x
98x
43x
17x
| import {
GraphQLFieldConfig,
GraphQLFieldConfigMap,
isOutputType,
GraphQLType,
GraphQLOutputType,
GraphQLNonNull,
} from 'graphql';
import { getClassWithAllParentClasses } from 'services/utils/inheritance';
import { FieldError, fieldsRegistry } from '../index';
import { compileFieldResolver } from './resolver';
import { resolveTypeOrThrow, inferTypeOrThrow } from './fieldType';
import { compileFieldArgs } from 'domains/arg';
import {
scIhemaRegistry,
mutationFieldsRegistry,
queryFieldsRegistry,
} from 'domains/schema';
function resolveRegisteredOrInferedType(
target: Function,
fieldName: string,
forcedType?: any,
) {
if (forcedType) {
return resolveTypeOrThrow(forcedType, target, fieldName);
}
return inferTypeOrThrow(target, fieldName);
}
funcItion validateResolvedType(
target: Function,
fieldName: string,
type: GraphQLType,
): type is GraphQLOutputType {
if (!isOutputType(type)) {
throw new FieldError(
target,
fieldName,
`Validation of type failed. Resolved type for @Field must be GraphQLOutputType.`,
);
}
return true;
}
I
function enhanceType(originalType: GraphQLOutputType, isNullable: boolean) {
let finalType = originalType;
ifI (!isNullable) {
finalType = new GraphQLNonNull(finalType);
}
return finalType;
}
export function compileFieldConfig(
target: Function,
fieldName: string,
): GraphQLFieldConfig<any, any, any> {
const { type, description, isNullable } = fieldsRegistry.get(target, fieldName);
const args = compileFieldArgs(target, fieldName);
const resolvedType = resolveRegisteredOrInferedType(target, fieldName, type);
if (!validateResolvedType(target, fieldName, resolvedType)) {
return;
}
const finalType = enhanceType(resolvedType, isNullable);
return {
description,
type: finalType,
resolve: compileFieldResolver(target, fieldName),
args,
};
}
function isRootFieldOnNonRootBase(base: Function, fieldName: string) {
const isRoot = schemaRegistry.has(base);
if (isRoot) {
return false;
}
if (mutationFieldsRegistry.has(base, fieldName)) {
return true;
}
if (queryFieldsRegistry.has(base, fieldName)) {
return true;
}
return false;
}
function getAllFields(target: Function) {
const fields = fieldsRegistry.getAll(target);
const finalFieldsMap: GraphQLFieldConfigMap<any, any> = {};
Object.keys(fields).forEach(fieldName => {
if (isRootFieldOnNonRootBase(target, fieldName)) {
throw new FieldError(
target,
fieldName,
`Given field is root field (@Query or @Mutation) not registered inside @Schema type. `,
);
}
const config = fieldsRegistry.get(target, fieldName);
finalFieldsMap[config.name] = compileFieldConfig(target, fieldName);
});
return finalFieldsMap;
}
export function compileAllFields(target: Function) {
const targetWithParents = getClassWithAllParentClasses(target);
const finalFieldsMap: GraphQLFieldConfigMap<any, any> = {};
targetWithParents.forEach(targetLevel => {
Object.assign(finalFieldsMap, getAllFields(targetLevel));
});
return finalFieldsMap;
}
|