-
-
Notifications
You must be signed in to change notification settings - Fork 677
/
types.ts
127 lines (114 loc) · 3.52 KB
/
types.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import {
GraphQLScalarType,
GraphQLString,
GraphQLFloat,
GraphQLType,
GraphQLNonNull,
GraphQLList,
GraphQLBoolean,
} from "graphql";
import { TypeOptions } from "../decorators/types";
import { GraphQLTimestamp } from "../scalars/timestamp";
import { GraphQLISODateTime } from "../scalars/isodate";
import { BuildContext } from "../schema/build-context";
import { WrongNullableListOptionError, ConflictingDefaultWithNullableError } from "../errors";
export function convertTypeIfScalar(type: any): GraphQLScalarType | undefined {
if (type instanceof GraphQLScalarType) {
return type;
}
const scalarMap = BuildContext.scalarsMaps.find(it => it.type === type);
if (scalarMap) {
return scalarMap.scalar;
}
switch (type) {
case String:
return GraphQLString;
case Boolean:
return GraphQLBoolean;
case Number:
return GraphQLFloat;
case Date:
return BuildContext.dateScalarMode === "isoDate" ? GraphQLISODateTime : GraphQLTimestamp;
default:
return undefined;
}
}
export function wrapWithTypeOptions<T extends GraphQLType>(
typeOwnerName: string,
type: T,
typeOptions: TypeOptions,
nullableByDefault: boolean,
): T {
if (
!typeOptions.array &&
(typeOptions.nullable === "items" || typeOptions.nullable === "itemsAndList")
) {
throw new WrongNullableListOptionError(typeOwnerName, typeOptions.nullable);
}
if (
typeOptions.defaultValue !== undefined &&
(typeOptions.nullable === false || typeOptions.nullable === "items")
) {
throw new ConflictingDefaultWithNullableError(
typeOwnerName,
typeOptions.defaultValue,
typeOptions.nullable,
);
}
let gqlType: GraphQLType = type;
if (typeOptions.array) {
const isNullableArray =
typeOptions.nullable === "items" ||
typeOptions.nullable === "itemsAndList" ||
(typeOptions.nullable === undefined && nullableByDefault === true);
gqlType = wrapTypeInNestedList(gqlType, typeOptions.arrayDepth!, isNullableArray);
}
if (
typeOptions.defaultValue === undefined &&
(typeOptions.nullable === false ||
(typeOptions.nullable === undefined && nullableByDefault === false) ||
typeOptions.nullable === "items")
) {
gqlType = new GraphQLNonNull(gqlType);
}
return gqlType as T;
}
const simpleTypes: Function[] = [String, Boolean, Number, Date, Array, Promise];
export function convertToType(Target: any, data?: object): object | undefined {
// skip converting undefined and null
if (data == null) {
return;
}
// skip converting scalars (object scalar mostly)
if (Target instanceof GraphQLScalarType) {
return data;
}
// skip converting simple types
if (simpleTypes.includes(data.constructor)) {
return data;
}
// skip converting already converted types
if (data instanceof Target) {
return data;
}
return Object.assign(new Target(), data);
}
export function getEnumValuesMap<T extends object>(enumObject: T) {
const enumKeys = Object.keys(enumObject).filter(key => isNaN(parseInt(key, 10)));
const enumMap = enumKeys.reduce<any>((map, key) => {
map[key] = enumObject[key as keyof T];
return map;
}, {});
return enumMap;
}
function wrapTypeInNestedList(
targetType: GraphQLType,
depth: number,
nullable: boolean,
): GraphQLList<GraphQLType> {
const targetTypeNonNull = nullable ? targetType : new GraphQLNonNull(targetType);
if (depth === 0) {
return targetType as GraphQLList<GraphQLType>;
}
return wrapTypeInNestedList(new GraphQLList(targetTypeNonNull), depth - 1, nullable);
}