/
makeExecutableSchema.ts
110 lines (98 loc) · 3.19 KB
/
makeExecutableSchema.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
import { buildASTSchema, buildSchema, GraphQLSchema } from 'graphql';
import { asArray, pruneSchema } from '@graphql-tools/utils';
import { addResolversToSchema } from './addResolversToSchema';
import { assertResolversPresent } from './assertResolversPresent';
import { IExecutableSchemaDefinition } from './types';
import { applyExtensions, mergeExtensions, mergeResolvers, mergeTypeDefs } from '@graphql-tools/merge';
/**
* Builds a schema from the provided type definitions and resolvers.
*
* The type definitions are written using Schema Definition Language (SDL). They
* can be provided as a string, a `DocumentNode`, a function, or an array of any
* of these. If a function is provided, it will be passed no arguments and
* should return an array of strings or `DocumentNode`s.
*
* Note: You can use `graphql-tag` to not only parse a string into a
* `DocumentNode` but also to provide additional syntax highlighting in your
* editor (with the appropriate editor plugin).
*
* ```js
* const typeDefs = gql`
* type Query {
* posts: [Post]
* author(id: Int!): Author
* }
* `;
* ```
*
* The `resolvers` object should be a map of type names to nested object, which
* themselves map the type's fields to their appropriate resolvers.
* See the [Resolvers](/docs/resolvers) section of the documentation for more details.
*
* ```js
* const resolvers = {
* Query: {
* posts: (obj, args, ctx, info) => getAllPosts(),
* author: (obj, args, ctx, info) => getAuthorById(args.id)
* }
* };
* ```
*
* Once you've defined both the `typeDefs` and `resolvers`, you can create your
* schema:
*
* ```js
* const schema = makeExecutableSchema({
* typeDefs,
* resolvers,
* })
* ```
*/
export function makeExecutableSchema<TContext = any>({
typeDefs,
resolvers = {},
resolverValidationOptions = {},
parseOptions = {},
inheritResolversFromInterfaces = false,
pruningOptions,
updateResolversInPlace = false,
extensions,
}: IExecutableSchemaDefinition<TContext>) {
// Validate and clean up arguments
if (typeof resolverValidationOptions !== 'object') {
throw new Error('Expected `resolverValidationOptions` to be an object');
}
if (!typeDefs) {
throw new Error('Must provide typeDefs');
}
let schema: GraphQLSchema;
if (parseOptions?.commentDescriptions) {
const mergedTypeDefs = mergeTypeDefs(typeDefs, {
...parseOptions,
commentDescriptions: true,
});
schema = buildSchema(mergedTypeDefs, parseOptions);
} else {
const mergedTypeDefs = mergeTypeDefs(typeDefs, parseOptions);
schema = buildASTSchema(mergedTypeDefs, parseOptions);
}
if (pruningOptions) {
schema = pruneSchema(schema);
}
// We allow passing in an array of resolver maps, in which case we merge them
schema = addResolversToSchema({
schema,
resolvers: mergeResolvers(resolvers),
resolverValidationOptions,
inheritResolversFromInterfaces,
updateResolversInPlace,
});
if (Object.keys(resolverValidationOptions).length > 0) {
assertResolversPresent(schema, resolverValidationOptions);
}
if (extensions) {
extensions = mergeExtensions(asArray(extensions));
applyExtensions(schema, extensions);
}
return schema;
}