UNPKG

12.2 kBJavaScriptView Raw
1import { GraphQLInt, GraphQLFloat, GraphQLBoolean, GraphQLID, GraphQLString, GraphQLSchema, GraphQLObjectType, GraphQLInputObjectType, GraphQLList, GraphQLNonNull, GraphQLInterfaceType, GraphQLUnionType, GraphQLEnumType, GraphQLScalarType } from 'graphql';
2
3function builtInScalar(builtInType) {
4 return {
5 kind: 'Scalar',
6 builtInType,
7 };
8}
9function createTypesFactory() {
10 return {
11 String: builtInScalar(GraphQLString),
12 Int: builtInScalar(GraphQLInt),
13 Float: builtInScalar(GraphQLFloat),
14 Boolean: builtInScalar(GraphQLBoolean),
15 ID: builtInScalar(GraphQLID),
16 scalarType({ name, description, serialize, parseValue, parseLiteral, }) {
17 return {
18 kind: 'Scalar',
19 graphqlTypeConfig: {
20 name,
21 description,
22 serialize,
23 parseLiteral,
24 parseValue,
25 },
26 };
27 },
28 enumType({ name, description, values, }) {
29 return {
30 kind: 'Enum',
31 name,
32 description,
33 values,
34 };
35 },
36 arg(type, description) {
37 return {
38 kind: 'Argument',
39 type,
40 description,
41 };
42 },
43 defaultArg(type, defaultArg, description) {
44 return {
45 kind: 'DefaultArgument',
46 type: type,
47 description,
48 default: defaultArg,
49 };
50 },
51 field(name, { type, args = {}, resolve, description, deprecationReason, extensions }) {
52 return {
53 kind: 'Field',
54 name,
55 type,
56 description,
57 deprecationReason,
58 args,
59 resolve,
60 extensions
61 };
62 },
63 defaultField(name, type, opts) {
64 return {
65 kind: 'Field',
66 name: String(name),
67 type,
68 description: opts && opts.description,
69 deprecationReason: opts && opts.deprecationReason,
70 args: {},
71 resolve: (src) => src[name],
72 };
73 },
74 abstractField(name, type, opts) {
75 return {
76 kind: 'AbstractField',
77 name,
78 description: opts && opts.description,
79 deprecationReason: opts && opts.deprecationReason,
80 type,
81 };
82 },
83 objectType({ name, description, interfaces = [], fields, isTypeOf, extensions, }) {
84 const obj = {
85 kind: 'ObjectType',
86 name,
87 description,
88 interfaces,
89 fieldsFn: undefined,
90 isTypeOf,
91 extensions,
92 };
93 obj.fieldsFn = () => fields(obj);
94 return obj;
95 },
96 inputObjectType({ name, description, fields, }) {
97 let inputObj = {
98 kind: 'InputObject',
99 name,
100 description,
101 fieldsFn: null,
102 };
103 inputObj.fieldsFn = () => fields(inputObj);
104 return inputObj;
105 },
106 unionType({ name, types, resolveType, }) {
107 return {
108 kind: 'Union',
109 name,
110 types,
111 resolveType,
112 };
113 },
114 interfaceType({ name, description, interfaces = [], fields, }) {
115 const obj = {
116 kind: 'Interface',
117 name,
118 description,
119 interfaces,
120 fieldsFn: undefined,
121 };
122 obj.fieldsFn = () => fields(obj);
123 return obj;
124 },
125 List(ofType) {
126 return {
127 kind: 'List',
128 ofType: ofType,
129 };
130 },
131 ListInput(ofType) {
132 return {
133 kind: 'ListInput',
134 ofType: ofType,
135 };
136 },
137 NonNull(ofType) {
138 return {
139 kind: 'NonNull',
140 ofType: ofType,
141 };
142 },
143 NonNullInput(ofType) {
144 return {
145 kind: 'NonNullInput',
146 ofType: ofType,
147 };
148 },
149 queryType({ name = 'Query', fields, }) {
150 return {
151 kind: 'ObjectType',
152 name,
153 interfaces: [],
154 fieldsFn: () => fields,
155 };
156 },
157 mutationType({ name = 'Mutation', fields, }) {
158 return {
159 kind: 'ObjectType',
160 name,
161 interfaces: [],
162 fieldsFn: fields,
163 };
164 },
165 subscriptionField(name, { type, args = {}, subscribe, resolve, description, deprecationReason, }) {
166 return {
167 kind: 'SubscriptionField',
168 name,
169 type,
170 args,
171 subscribe,
172 resolve,
173 description,
174 deprecationReason,
175 };
176 },
177 subscriptionType({ name = 'Subscription', fields, }) {
178 return {
179 kind: 'SubscriptionObject',
180 name,
181 fields,
182 };
183 },
184 };
185}
186
187function buildGraphQLSchema(schema) {
188 const typeMap = new Map();
189 return new GraphQLSchema({
190 query: toGraphQLOutputType(schema.query, typeMap),
191 mutation: schema.mutation &&
192 toGraphQLOutputType(schema.mutation, typeMap),
193 subscription: schema.subscription && toGraphQLSubscriptionObject(schema.subscription, typeMap),
194 types: schema.types && schema.types.map((type) => toGraphQLOutputType(type, typeMap)),
195 directives: schema.directives
196 });
197}
198function toGraphQLArgs(args, typeMap) {
199 const graphqlArgs = {};
200 Object.keys(args).forEach((k) => {
201 const arg = args[k];
202 graphqlArgs[k] = {
203 type: toGraphQLInputType(arg.type, typeMap),
204 description: arg.description,
205 defaultValue: arg.kind === 'DefaultArgument' ? arg.default : undefined,
206 };
207 });
208 return graphqlArgs;
209}
210function toGraphQLSubscriptionObject(subscriptionObj, typeMap) {
211 return new GraphQLObjectType({
212 name: subscriptionObj.name,
213 fields: () => {
214 const gqlFieldConfig = {};
215 subscriptionObj.fields.forEach((field) => {
216 gqlFieldConfig[field.name] = {
217 type: toGraphQLOutputType(field.type, typeMap),
218 description: field.description,
219 subscribe: field.subscribe,
220 resolve: field.resolve,
221 args: toGraphQLArgs(field.args, typeMap),
222 deprecationReason: field.deprecationReason,
223 };
224 });
225 return gqlFieldConfig;
226 },
227 });
228}
229function toGraphQLInputType(t, typeMap) {
230 const found = typeMap.get(t);
231 if (found) {
232 return typeMap.get(t);
233 }
234 switch (t.kind) {
235 case 'Scalar':
236 case 'Enum':
237 return toGraphQLOutputType(t, typeMap);
238 case 'NonNullInput':
239 return new GraphQLNonNull(toGraphQLInputType(t.ofType, typeMap));
240 case 'ListInput':
241 return new GraphQLList(toGraphQLInputType(t.ofType, typeMap));
242 case 'InputObject':
243 const fields = t.fieldsFn();
244 function graphqlFields() {
245 const gqlFieldConfig = {};
246 Object.keys(fields).forEach((k) => {
247 const field = fields[k];
248 gqlFieldConfig[k] = {
249 type: toGraphQLInputType(field.type, typeMap),
250 description: field.description,
251 deprecationReason: field.deprecationReason,
252 };
253 });
254 return gqlFieldConfig;
255 }
256 const obj = new GraphQLInputObjectType({
257 name: t.name,
258 fields: graphqlFields,
259 });
260 typeMap.set(t, obj);
261 return obj;
262 }
263}
264function toGraphQLOutputType(t, typeMap) {
265 const found = typeMap.get(t);
266 if (found) {
267 return found;
268 }
269 switch (t.kind) {
270 case 'Scalar':
271 let scalar;
272 if ('builtInType' in t) {
273 scalar = t.builtInType;
274 }
275 else {
276 scalar = new GraphQLScalarType({
277 ...t.graphqlTypeConfig,
278 });
279 }
280 typeMap.set(t, scalar);
281 return scalar;
282 case 'Enum':
283 const enumT = new GraphQLEnumType({
284 name: t.name,
285 description: t.description,
286 values: t.values.reduce((acc, val) => {
287 acc[val.name] = {
288 value: val.value,
289 deprecationReason: val.deprecationReason,
290 description: val.description,
291 };
292 return acc;
293 }, {}),
294 });
295 typeMap.set(t, enumT);
296 return enumT;
297 case 'NonNull':
298 return new GraphQLNonNull(toGraphQLOutputType(t.ofType, typeMap));
299 case 'List':
300 return new GraphQLList(toGraphQLOutputType(t.ofType, typeMap));
301 case 'ObjectType':
302 const obj = new GraphQLObjectType({
303 name: t.name,
304 interfaces: t.interfaces.map((intf) => toGraphQLOutputType(intf, typeMap)),
305 isTypeOf: t.isTypeOf,
306 fields: () => {
307 const fields = t.fieldsFn();
308 const gqlFieldConfig = {};
309 fields.forEach((field) => {
310 gqlFieldConfig[field.name] = {
311 type: toGraphQLOutputType(field.type, typeMap),
312 description: field.description,
313 resolve: field.resolve,
314 args: toGraphQLArgs(field.args, typeMap),
315 deprecationReason: field.deprecationReason,
316 extensions: field.extensions
317 };
318 });
319 return gqlFieldConfig;
320 },
321 extensions: t.extensions,
322 });
323 typeMap.set(t, obj);
324 return obj;
325 case 'Union':
326 const union = new GraphQLUnionType({
327 name: t.name,
328 types: t.types.map((t) => toGraphQLOutputType(t, typeMap)),
329 resolveType: async (src, ctx, info) => {
330 const resolved = await t.resolveType(src, ctx, info);
331 if (typeof resolved === 'string' || resolved == null)
332 return resolved;
333 return typeMap.get(resolved);
334 },
335 });
336 typeMap.set(t, union);
337 return union;
338 case 'Interface':
339 const intf = new GraphQLInterfaceType({
340 name: t.name,
341 fields: () => {
342 const fields = t.fieldsFn();
343 const result = {};
344 fields.forEach((field) => {
345 result[field.name] = {
346 type: toGraphQLOutputType(field.type, typeMap),
347 description: field.description,
348 deprecationReason: field.deprecationReason,
349 };
350 });
351 return result;
352 },
353 interfaces: t.interfaces.map((intf) => toGraphQLOutputType(intf, typeMap)),
354 });
355 typeMap.set(t, intf);
356 return intf;
357 }
358}
359
360export { buildGraphQLSchema, createTypesFactory, toGraphQLInputType, toGraphQLOutputType };