UNPKG

10.7 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.isSchema = isSchema;
7exports.assertSchema = assertSchema;
8exports.GraphQLSchema = void 0;
9
10var _find = _interopRequireDefault(require("../polyfills/find"));
11
12var _objectValues7 = _interopRequireDefault(require("../polyfills/objectValues"));
13
14var _inspect = _interopRequireDefault(require("../jsutils/inspect"));
15
16var _toObjMap = _interopRequireDefault(require("../jsutils/toObjMap"));
17
18var _devAssert = _interopRequireDefault(require("../jsutils/devAssert"));
19
20var _instanceOf = _interopRequireDefault(require("../jsutils/instanceOf"));
21
22var _isObjectLike = _interopRequireDefault(require("../jsutils/isObjectLike"));
23
24var _defineToStringTag = _interopRequireDefault(require("../jsutils/defineToStringTag"));
25
26var _introspection = require("./introspection");
27
28var _directives = require("./directives");
29
30var _definition = require("./definition");
31
32function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33
34// eslint-disable-next-line no-redeclare
35function isSchema(schema) {
36 return (0, _instanceOf.default)(schema, GraphQLSchema);
37}
38
39function assertSchema(schema) {
40 if (!isSchema(schema)) {
41 throw new Error("Expected ".concat((0, _inspect.default)(schema), " to be a GraphQL schema."));
42 }
43
44 return schema;
45}
46/**
47 * Schema Definition
48 *
49 * A Schema is created by supplying the root types of each type of operation,
50 * query and mutation (optional). A schema definition is then supplied to the
51 * validator and executor.
52 *
53 * Example:
54 *
55 * const MyAppSchema = new GraphQLSchema({
56 * query: MyAppQueryRootType,
57 * mutation: MyAppMutationRootType,
58 * })
59 *
60 * Note: When the schema is constructed, by default only the types that are
61 * reachable by traversing the root types are included, other types must be
62 * explicitly referenced.
63 *
64 * Example:
65 *
66 * const characterInterface = new GraphQLInterfaceType({
67 * name: 'Character',
68 * ...
69 * });
70 *
71 * const humanType = new GraphQLObjectType({
72 * name: 'Human',
73 * interfaces: [characterInterface],
74 * ...
75 * });
76 *
77 * const droidType = new GraphQLObjectType({
78 * name: 'Droid',
79 * interfaces: [characterInterface],
80 * ...
81 * });
82 *
83 * const schema = new GraphQLSchema({
84 * query: new GraphQLObjectType({
85 * name: 'Query',
86 * fields: {
87 * hero: { type: characterInterface, ... },
88 * }
89 * }),
90 * ...
91 * // Since this schema references only the `Character` interface it's
92 * // necessary to explicitly list the types that implement it if
93 * // you want them to be included in the final schema.
94 * types: [humanType, droidType],
95 * })
96 *
97 * Note: If an array of `directives` are provided to GraphQLSchema, that will be
98 * the exact list of directives represented and allowed. If `directives` is not
99 * provided then a default set of the specified directives (e.g. @include and
100 * @skip) will be used. If you wish to provide *additional* directives to these
101 * specified directives, you must explicitly declare them. Example:
102 *
103 * const MyAppSchema = new GraphQLSchema({
104 * ...
105 * directives: specifiedDirectives.concat([ myCustomDirective ]),
106 * })
107 *
108 */
109
110
111var GraphQLSchema =
112/*#__PURE__*/
113function () {
114 // Used as a cache for validateSchema().
115 // Referenced by validateSchema().
116 function GraphQLSchema(config) {
117 // If this schema was built from a source known to be valid, then it may be
118 // marked with assumeValid to avoid an additional type system validation.
119 if (config && config.assumeValid) {
120 this.__validationErrors = [];
121 } else {
122 this.__validationErrors = undefined; // Otherwise check for common mistakes during construction to produce
123 // clear and early error messages.
124
125 (0, _isObjectLike.default)(config) || (0, _devAssert.default)(0, 'Must provide configuration object.');
126 !config.types || Array.isArray(config.types) || (0, _devAssert.default)(0, "\"types\" must be Array if provided but got: ".concat((0, _inspect.default)(config.types), "."));
127 !config.directives || Array.isArray(config.directives) || (0, _devAssert.default)(0, '"directives" must be Array if provided but got: ' + "".concat((0, _inspect.default)(config.directives), "."));
128 !config.allowedLegacyNames || Array.isArray(config.allowedLegacyNames) || (0, _devAssert.default)(0, '"allowedLegacyNames" must be Array if provided but got: ' + "".concat((0, _inspect.default)(config.allowedLegacyNames), "."));
129 }
130
131 this.extensions = config.extensions && (0, _toObjMap.default)(config.extensions);
132 this.astNode = config.astNode;
133 this.extensionASTNodes = config.extensionASTNodes;
134 this.__allowedLegacyNames = config.allowedLegacyNames || [];
135 this._queryType = config.query;
136 this._mutationType = config.mutation;
137 this._subscriptionType = config.subscription; // Provide specified directives (e.g. @include and @skip) by default.
138
139 this._directives = config.directives || _directives.specifiedDirectives; // Build type map now to detect any errors within this schema.
140
141 var initialTypes = [this._queryType, this._mutationType, this._subscriptionType, _introspection.__Schema].concat(config.types); // Keep track of all types referenced within the schema.
142
143 var typeMap = Object.create(null); // First by deeply visiting all initial types.
144
145 typeMap = initialTypes.reduce(typeMapReducer, typeMap); // Then by deeply visiting all directive types.
146
147 typeMap = this._directives.reduce(typeMapDirectiveReducer, typeMap); // Storing the resulting map for reference by the schema.
148
149 this._typeMap = typeMap;
150 this._possibleTypeMap = Object.create(null); // Keep track of all implementations by interface name.
151
152 this._implementations = Object.create(null);
153
154 for (var _i2 = 0, _objectValues2 = (0, _objectValues7.default)(this._typeMap); _i2 < _objectValues2.length; _i2++) {
155 var type = _objectValues2[_i2];
156
157 if ((0, _definition.isObjectType)(type)) {
158 for (var _i4 = 0, _type$getInterfaces2 = type.getInterfaces(); _i4 < _type$getInterfaces2.length; _i4++) {
159 var iface = _type$getInterfaces2[_i4];
160
161 if ((0, _definition.isInterfaceType)(iface)) {
162 var impls = this._implementations[iface.name];
163
164 if (impls) {
165 impls.push(type);
166 } else {
167 this._implementations[iface.name] = [type];
168 }
169 }
170 }
171 }
172 }
173 }
174
175 var _proto = GraphQLSchema.prototype;
176
177 _proto.getQueryType = function getQueryType() {
178 return this._queryType;
179 };
180
181 _proto.getMutationType = function getMutationType() {
182 return this._mutationType;
183 };
184
185 _proto.getSubscriptionType = function getSubscriptionType() {
186 return this._subscriptionType;
187 };
188
189 _proto.getTypeMap = function getTypeMap() {
190 return this._typeMap;
191 };
192
193 _proto.getType = function getType(name) {
194 return this.getTypeMap()[name];
195 };
196
197 _proto.getPossibleTypes = function getPossibleTypes(abstractType) {
198 if ((0, _definition.isUnionType)(abstractType)) {
199 return abstractType.getTypes();
200 }
201
202 return this._implementations[abstractType.name] || [];
203 };
204
205 _proto.isPossibleType = function isPossibleType(abstractType, possibleType) {
206 if (this._possibleTypeMap[abstractType.name] == null) {
207 var map = Object.create(null);
208
209 for (var _i6 = 0, _this$getPossibleType2 = this.getPossibleTypes(abstractType); _i6 < _this$getPossibleType2.length; _i6++) {
210 var type = _this$getPossibleType2[_i6];
211 map[type.name] = true;
212 }
213
214 this._possibleTypeMap[abstractType.name] = map;
215 }
216
217 return Boolean(this._possibleTypeMap[abstractType.name][possibleType.name]);
218 };
219
220 _proto.getDirectives = function getDirectives() {
221 return this._directives;
222 };
223
224 _proto.getDirective = function getDirective(name) {
225 return (0, _find.default)(this.getDirectives(), function (directive) {
226 return directive.name === name;
227 });
228 };
229
230 _proto.toConfig = function toConfig() {
231 return {
232 query: this.getQueryType(),
233 mutation: this.getMutationType(),
234 subscription: this.getSubscriptionType(),
235 types: (0, _objectValues7.default)(this.getTypeMap()),
236 directives: this.getDirectives().slice(),
237 extensions: this.extensions,
238 astNode: this.astNode,
239 extensionASTNodes: this.extensionASTNodes || [],
240 assumeValid: this.__validationErrors !== undefined,
241 allowedLegacyNames: this.__allowedLegacyNames
242 };
243 };
244
245 return GraphQLSchema;
246}(); // Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported
247
248
249exports.GraphQLSchema = GraphQLSchema;
250(0, _defineToStringTag.default)(GraphQLSchema);
251
252function typeMapReducer(map, type) {
253 if (!type) {
254 return map;
255 }
256
257 var namedType = (0, _definition.getNamedType)(type);
258 var seenType = map[namedType.name];
259
260 if (seenType) {
261 if (seenType !== namedType) {
262 throw new Error("Schema must contain uniquely named types but contains multiple types named \"".concat(namedType.name, "\"."));
263 }
264
265 return map;
266 }
267
268 map[namedType.name] = namedType;
269 var reducedMap = map;
270
271 if ((0, _definition.isUnionType)(namedType)) {
272 reducedMap = namedType.getTypes().reduce(typeMapReducer, reducedMap);
273 }
274
275 if ((0, _definition.isObjectType)(namedType)) {
276 reducedMap = namedType.getInterfaces().reduce(typeMapReducer, reducedMap);
277 }
278
279 if ((0, _definition.isObjectType)(namedType) || (0, _definition.isInterfaceType)(namedType)) {
280 for (var _i8 = 0, _objectValues4 = (0, _objectValues7.default)(namedType.getFields()); _i8 < _objectValues4.length; _i8++) {
281 var field = _objectValues4[_i8];
282 var fieldArgTypes = field.args.map(function (arg) {
283 return arg.type;
284 });
285 reducedMap = fieldArgTypes.reduce(typeMapReducer, reducedMap);
286 reducedMap = typeMapReducer(reducedMap, field.type);
287 }
288 }
289
290 if ((0, _definition.isInputObjectType)(namedType)) {
291 for (var _i10 = 0, _objectValues6 = (0, _objectValues7.default)(namedType.getFields()); _i10 < _objectValues6.length; _i10++) {
292 var _field = _objectValues6[_i10];
293 reducedMap = typeMapReducer(reducedMap, _field.type);
294 }
295 }
296
297 return reducedMap;
298}
299
300function typeMapDirectiveReducer(map, directive) {
301 // Directives are not validated until validateSchema() is called.
302 if (!(0, _directives.isDirective)(directive)) {
303 return map;
304 }
305
306 return directive.args.reduce(function (_map, arg) {
307 return typeMapReducer(_map, arg.type);
308 }, map);
309}