UNPKG

7.15 kBPlain TextView Raw
1import {
2 Kind,
3 print,
4 ObjectTypeDefinitionNode,
5 NonNullTypeNode,
6 DirectiveNode,
7 NameNode,
8 OperationTypeNode,
9 FieldDefinitionNode,
10 NamedTypeNode,
11 InputValueDefinitionNode,
12 ValueNode,
13 OperationTypeDefinitionNode,
14 SchemaDefinitionNode,
15 ArgumentNode,
16 ListValueNode,
17 StringValueNode,
18 InputObjectTypeDefinitionNode,
19 DocumentNode,
20} from 'graphql';
21
22const intTypes = [`INTEGER`, `INT`, `SMALLINT`, `TINYINT`, `MEDIUMINT`, `BIGINT`, `BIT`];
23const floatTypes = [`FLOAT`, `DOUBLE`, `REAL`, `REAL_AS_FLOAT`, `DOUBLE PRECISION`, `DEC`, `DECIMAL`, `FIXED`, `NUMERIC`];
24
25/**
26 * Creates a non-null type, which is a node wrapped around another type that simply defines it is non-nullable.
27 *
28 * @param typeNode the type to be marked as non-nullable.
29 * @returns a non-null wrapper around the provided type.
30 */
31export function getNonNullType(typeNode: NamedTypeNode): NonNullTypeNode {
32 return {
33 kind: Kind.NON_NULL_TYPE,
34 type: typeNode,
35 };
36}
37
38/**
39 * Creates a named type for the schema.
40 *
41 * @param name the name of the type.
42 * @returns a named type with the provided name.
43 */
44export function getNamedType(name: string): NamedTypeNode {
45 return {
46 kind: Kind.NAMED_TYPE,
47 name: {
48 kind: Kind.NAME,
49 value: name,
50 },
51 };
52}
53
54/**
55 * Creates an input value definition for the schema.
56 *
57 * @param typeNode the type of the input node.
58 * @param name the name of the input.
59 * @returns an input value definition node with the provided type and name.
60 */
61export function getInputValueDefinition(typeNode: NamedTypeNode | NonNullTypeNode, name: string): InputValueDefinitionNode {
62 return {
63 kind: Kind.INPUT_VALUE_DEFINITION,
64 name: {
65 kind: Kind.NAME,
66 value: name,
67 },
68 type: typeNode,
69 };
70}
71
72/**
73 * Creates an operation field definition for the schema.
74 *
75 * @param name the name of the operation.
76 * @param args the arguments for the operation.
77 * @param type the type of the operation.
78 * @param directives the directives (if any) applied to this field. In this context, only subscriptions will have this.
79 * @returns an operation field definition with the provided name, args, type, and optionally directives.
80 */
81export function getOperationFieldDefinition(
82 name: string,
83 args: InputValueDefinitionNode[],
84 type: NamedTypeNode,
85 directives: ReadonlyArray<DirectiveNode>
86): FieldDefinitionNode {
87 return {
88 kind: Kind.FIELD_DEFINITION,
89 name: {
90 kind: Kind.NAME,
91 value: name,
92 },
93 arguments: args,
94 type: type,
95 directives: directives,
96 };
97}
98
99/**
100 * Creates a field definition node for the schema.
101 *
102 * @param fieldName the name of the field to be created.
103 * @param type the type of the field to be created.
104 * @returns a field definition node with the provided name and type.
105 */
106export function getFieldDefinition(fieldName: string, type: NonNullTypeNode | NamedTypeNode): FieldDefinitionNode {
107 return {
108 kind: Kind.FIELD_DEFINITION,
109 name: {
110 kind: Kind.NAME,
111 value: fieldName,
112 },
113 type,
114 };
115}
116
117/**
118 * Creates a type definition node for the schema.
119 *
120 * @param fields the field set to be included in the type.
121 * @param typeName the name of the type.
122 * @returns a type definition node defined by the provided fields and name.
123 */
124export function getTypeDefinition(fields: ReadonlyArray<FieldDefinitionNode>, typeName: string): ObjectTypeDefinitionNode {
125 return {
126 kind: Kind.OBJECT_TYPE_DEFINITION,
127 name: {
128 kind: Kind.NAME,
129 value: typeName,
130 },
131 fields: fields,
132 };
133}
134
135/**
136 * Creates an input type definition node for the schema.
137 *
138 * @param fields the fields in the input type.
139 * @param typeName the name of the input type
140 * @returns an input type definition node defined by the provided fields and
141 */
142export function getInputTypeDefinition(fields: ReadonlyArray<InputValueDefinitionNode>, typeName: string): InputObjectTypeDefinitionNode {
143 return {
144 kind: Kind.INPUT_OBJECT_TYPE_DEFINITION,
145 name: {
146 kind: Kind.NAME,
147 value: typeName,
148 },
149 fields: fields,
150 };
151}
152
153/**
154 * Creates a name node for the schema.
155 *
156 * @param name the name of the name node.
157 * @returns the name node defined by the provided name.
158 */
159export function getNameNode(name: string): NameNode {
160 return {
161 kind: Kind.NAME,
162 value: name,
163 };
164}
165
166/**
167 * Creates a list value node for the schema.
168 *
169 * @param values the list of values to be in the list node.
170 * @returns a list value node containing the provided values.
171 */
172export function getListValueNode(values: ReadonlyArray<ValueNode>): ListValueNode {
173 return {
174 kind: Kind.LIST,
175 values: values,
176 };
177}
178
179/**
180 * Creates a simple string value node for the schema.
181 *
182 * @param value the value to be set in the string value node.
183 * @returns a fleshed-out string value node.
184 */
185export function getStringValueNode(value: string): StringValueNode {
186 return {
187 kind: Kind.STRING,
188 value: value,
189 };
190}
191
192/**
193 * Creates a directive node for a subscription in the schema.
194 *
195 * @param mutationName the name of the mutation the subscription directive is for.
196 * @returns a directive node defining the subscription.
197 */
198export function getDirectiveNode(mutationName: string): DirectiveNode {
199 return {
200 kind: Kind.DIRECTIVE,
201 name: this.getNameNode('aws_subscribe'),
202 arguments: [this.getArgumentNode(mutationName)],
203 };
204}
205
206/**
207 * Creates an operation type definition (subscription, query, mutation) for the schema.
208 *
209 * @param operationType the type node defining the operation type.
210 * @param operation the named type node defining the operation type.
211 */
212export function getOperationTypeDefinition(operationType: OperationTypeNode, operation: NamedTypeNode): OperationTypeDefinitionNode {
213 return {
214 kind: Kind.OPERATION_TYPE_DEFINITION,
215 operation: operationType,
216 type: operation,
217 };
218}
219
220/**
221 * Creates an argument node for a subscription directive within the schema.
222 *
223 * @param argument the argument string.
224 * @returns the argument node.
225 */
226export function getArgumentNode(argument: string): ArgumentNode {
227 return {
228 kind: Kind.ARGUMENT,
229 name: this.getNameNode('mutations'),
230 value: this.getListValueNode([this.getStringValueNode(argument)]),
231 };
232}
233
234/**
235 * Given the DB type for a column, make a best effort to select the appropriate GraphQL type for
236 * the corresponding field.
237 *
238 * @param dbType the SQL column type.
239 * @returns the GraphQL field type.
240 */
241export function getGraphQLTypeFromMySQLType(dbType: string): string {
242 const normalizedType = dbType.toUpperCase().split('(')[0];
243 if (`BOOL` == normalizedType) {
244 return `Boolean`;
245 } else if (`JSON` == normalizedType) {
246 return `AWSJSON`;
247 } else if (`TIME` == normalizedType) {
248 return `AWSTime`;
249 } else if (`DATE` == normalizedType) {
250 return `AWSDate`;
251 } else if (`DATETIME` == normalizedType) {
252 return `AWSDateTime`;
253 } else if (`TIMESTAMP` == normalizedType) {
254 return `AWSTimestamp`;
255 } else if (intTypes.indexOf(normalizedType) > -1) {
256 return `Int`;
257 } else if (floatTypes.indexOf(normalizedType) > -1) {
258 return `Float`;
259 }
260 return `String`;
261}