UNPKG

13.6 kBJavaScriptView Raw
1function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
2
3function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
4
5import find from "../polyfills/find.mjs";
6import arrayFrom from "../polyfills/arrayFrom.mjs";
7import objectValues from "../polyfills/objectValues.mjs";
8import { SYMBOL_TO_STRING_TAG } from "../polyfills/symbols.mjs";
9import inspect from "../jsutils/inspect.mjs";
10import toObjMap from "../jsutils/toObjMap.mjs";
11import devAssert from "../jsutils/devAssert.mjs";
12import instanceOf from "../jsutils/instanceOf.mjs";
13import isObjectLike from "../jsutils/isObjectLike.mjs";
14import { __Schema } from "./introspection.mjs";
15import { GraphQLDirective, isDirective, specifiedDirectives } from "./directives.mjs";
16import { isObjectType, isInterfaceType, isUnionType, isInputObjectType, getNamedType } from "./definition.mjs";
17/**
18 * Test if the given value is a GraphQL schema.
19 */
20
21// eslint-disable-next-line no-redeclare
22export function isSchema(schema) {
23 return instanceOf(schema, GraphQLSchema);
24}
25export function assertSchema(schema) {
26 if (!isSchema(schema)) {
27 throw new Error("Expected ".concat(inspect(schema), " to be a GraphQL schema."));
28 }
29
30 return schema;
31}
32/**
33 * Schema Definition
34 *
35 * A Schema is created by supplying the root types of each type of operation,
36 * query and mutation (optional). A schema definition is then supplied to the
37 * validator and executor.
38 *
39 * Example:
40 *
41 * const MyAppSchema = new GraphQLSchema({
42 * query: MyAppQueryRootType,
43 * mutation: MyAppMutationRootType,
44 * })
45 *
46 * Note: When the schema is constructed, by default only the types that are
47 * reachable by traversing the root types are included, other types must be
48 * explicitly referenced.
49 *
50 * Example:
51 *
52 * const characterInterface = new GraphQLInterfaceType({
53 * name: 'Character',
54 * ...
55 * });
56 *
57 * const humanType = new GraphQLObjectType({
58 * name: 'Human',
59 * interfaces: [characterInterface],
60 * ...
61 * });
62 *
63 * const droidType = new GraphQLObjectType({
64 * name: 'Droid',
65 * interfaces: [characterInterface],
66 * ...
67 * });
68 *
69 * const schema = new GraphQLSchema({
70 * query: new GraphQLObjectType({
71 * name: 'Query',
72 * fields: {
73 * hero: { type: characterInterface, ... },
74 * }
75 * }),
76 * ...
77 * // Since this schema references only the `Character` interface it's
78 * // necessary to explicitly list the types that implement it if
79 * // you want them to be included in the final schema.
80 * types: [humanType, droidType],
81 * })
82 *
83 * Note: If an array of `directives` are provided to GraphQLSchema, that will be
84 * the exact list of directives represented and allowed. If `directives` is not
85 * provided then a default set of the specified directives (e.g. @include and
86 * @skip) will be used. If you wish to provide *additional* directives to these
87 * specified directives, you must explicitly declare them. Example:
88 *
89 * const MyAppSchema = new GraphQLSchema({
90 * ...
91 * directives: specifiedDirectives.concat([ myCustomDirective ]),
92 * })
93 *
94 */
95
96export var GraphQLSchema = /*#__PURE__*/function () {
97 // Used as a cache for validateSchema().
98 function GraphQLSchema(config) {
99 var _config$directives;
100
101 // If this schema was built from a source known to be valid, then it may be
102 // marked with assumeValid to avoid an additional type system validation.
103 this.__validationErrors = config.assumeValid === true ? [] : undefined; // Check for common mistakes during construction to produce early errors.
104
105 isObjectLike(config) || devAssert(0, 'Must provide configuration object.');
106 !config.types || Array.isArray(config.types) || devAssert(0, "\"types\" must be Array if provided but got: ".concat(inspect(config.types), "."));
107 !config.directives || Array.isArray(config.directives) || devAssert(0, '"directives" must be Array if provided but got: ' + "".concat(inspect(config.directives), "."));
108 this.description = config.description;
109 this.extensions = config.extensions && toObjMap(config.extensions);
110 this.astNode = config.astNode;
111 this.extensionASTNodes = config.extensionASTNodes;
112 this._queryType = config.query;
113 this._mutationType = config.mutation;
114 this._subscriptionType = config.subscription; // Provide specified directives (e.g. @include and @skip) by default.
115
116 this._directives = (_config$directives = config.directives) !== null && _config$directives !== void 0 ? _config$directives : specifiedDirectives; // To preserve order of user-provided types, we add first to add them to
117 // the set of "collected" types, so `collectReferencedTypes` ignore them.
118
119 var allReferencedTypes = new Set(config.types);
120
121 if (config.types != null) {
122 for (var _i2 = 0, _config$types2 = config.types; _i2 < _config$types2.length; _i2++) {
123 var type = _config$types2[_i2];
124 // When we ready to process this type, we remove it from "collected" types
125 // and then add it together with all dependent types in the correct position.
126 allReferencedTypes.delete(type);
127 collectReferencedTypes(type, allReferencedTypes);
128 }
129 }
130
131 if (this._queryType != null) {
132 collectReferencedTypes(this._queryType, allReferencedTypes);
133 }
134
135 if (this._mutationType != null) {
136 collectReferencedTypes(this._mutationType, allReferencedTypes);
137 }
138
139 if (this._subscriptionType != null) {
140 collectReferencedTypes(this._subscriptionType, allReferencedTypes);
141 }
142
143 for (var _i4 = 0, _this$_directives2 = this._directives; _i4 < _this$_directives2.length; _i4++) {
144 var directive = _this$_directives2[_i4];
145
146 // Directives are not validated until validateSchema() is called.
147 if (isDirective(directive)) {
148 for (var _i6 = 0, _directive$args2 = directive.args; _i6 < _directive$args2.length; _i6++) {
149 var arg = _directive$args2[_i6];
150 collectReferencedTypes(arg.type, allReferencedTypes);
151 }
152 }
153 }
154
155 collectReferencedTypes(__Schema, allReferencedTypes); // Storing the resulting map for reference by the schema.
156
157 this._typeMap = Object.create(null);
158 this._subTypeMap = Object.create(null); // Keep track of all implementations by interface name.
159
160 this._implementationsMap = Object.create(null);
161
162 for (var _i8 = 0, _arrayFrom2 = arrayFrom(allReferencedTypes); _i8 < _arrayFrom2.length; _i8++) {
163 var namedType = _arrayFrom2[_i8];
164
165 if (namedType == null) {
166 continue;
167 }
168
169 var typeName = namedType.name;
170 typeName || devAssert(0, 'One of the provided types for building the Schema is missing a name.');
171
172 if (this._typeMap[typeName] !== undefined) {
173 throw new Error("Schema must contain uniquely named types but contains multiple types named \"".concat(typeName, "\"."));
174 }
175
176 this._typeMap[typeName] = namedType;
177
178 if (isInterfaceType(namedType)) {
179 // Store implementations by interface.
180 for (var _i10 = 0, _namedType$getInterfa2 = namedType.getInterfaces(); _i10 < _namedType$getInterfa2.length; _i10++) {
181 var iface = _namedType$getInterfa2[_i10];
182
183 if (isInterfaceType(iface)) {
184 var implementations = this._implementationsMap[iface.name];
185
186 if (implementations === undefined) {
187 implementations = this._implementationsMap[iface.name] = {
188 objects: [],
189 interfaces: []
190 };
191 }
192
193 implementations.interfaces.push(namedType);
194 }
195 }
196 } else if (isObjectType(namedType)) {
197 // Store implementations by objects.
198 for (var _i12 = 0, _namedType$getInterfa4 = namedType.getInterfaces(); _i12 < _namedType$getInterfa4.length; _i12++) {
199 var _iface = _namedType$getInterfa4[_i12];
200
201 if (isInterfaceType(_iface)) {
202 var _implementations = this._implementationsMap[_iface.name];
203
204 if (_implementations === undefined) {
205 _implementations = this._implementationsMap[_iface.name] = {
206 objects: [],
207 interfaces: []
208 };
209 }
210
211 _implementations.objects.push(namedType);
212 }
213 }
214 }
215 }
216 }
217
218 var _proto = GraphQLSchema.prototype;
219
220 _proto.getQueryType = function getQueryType() {
221 return this._queryType;
222 };
223
224 _proto.getMutationType = function getMutationType() {
225 return this._mutationType;
226 };
227
228 _proto.getSubscriptionType = function getSubscriptionType() {
229 return this._subscriptionType;
230 };
231
232 _proto.getTypeMap = function getTypeMap() {
233 return this._typeMap;
234 };
235
236 _proto.getType = function getType(name) {
237 return this.getTypeMap()[name];
238 };
239
240 _proto.getPossibleTypes = function getPossibleTypes(abstractType) {
241 return isUnionType(abstractType) ? abstractType.getTypes() : this.getImplementations(abstractType).objects;
242 };
243
244 _proto.getImplementations = function getImplementations(interfaceType) {
245 var implementations = this._implementationsMap[interfaceType.name];
246 return implementations !== null && implementations !== void 0 ? implementations : {
247 objects: [],
248 interfaces: []
249 };
250 } // @deprecated: use isSubType instead - will be removed in v16.
251 ;
252
253 _proto.isPossibleType = function isPossibleType(abstractType, possibleType) {
254 return this.isSubType(abstractType, possibleType);
255 };
256
257 _proto.isSubType = function isSubType(abstractType, maybeSubType) {
258 var map = this._subTypeMap[abstractType.name];
259
260 if (map === undefined) {
261 map = Object.create(null);
262
263 if (isUnionType(abstractType)) {
264 for (var _i14 = 0, _abstractType$getType2 = abstractType.getTypes(); _i14 < _abstractType$getType2.length; _i14++) {
265 var type = _abstractType$getType2[_i14];
266 map[type.name] = true;
267 }
268 } else {
269 var implementations = this.getImplementations(abstractType);
270
271 for (var _i16 = 0, _implementations$obje2 = implementations.objects; _i16 < _implementations$obje2.length; _i16++) {
272 var _type = _implementations$obje2[_i16];
273 map[_type.name] = true;
274 }
275
276 for (var _i18 = 0, _implementations$inte2 = implementations.interfaces; _i18 < _implementations$inte2.length; _i18++) {
277 var _type2 = _implementations$inte2[_i18];
278 map[_type2.name] = true;
279 }
280 }
281
282 this._subTypeMap[abstractType.name] = map;
283 }
284
285 return map[maybeSubType.name] !== undefined;
286 };
287
288 _proto.getDirectives = function getDirectives() {
289 return this._directives;
290 };
291
292 _proto.getDirective = function getDirective(name) {
293 return find(this.getDirectives(), function (directive) {
294 return directive.name === name;
295 });
296 };
297
298 _proto.toConfig = function toConfig() {
299 var _this$extensionASTNod;
300
301 return {
302 description: this.description,
303 query: this.getQueryType(),
304 mutation: this.getMutationType(),
305 subscription: this.getSubscriptionType(),
306 types: objectValues(this.getTypeMap()),
307 directives: this.getDirectives().slice(),
308 extensions: this.extensions,
309 astNode: this.astNode,
310 extensionASTNodes: (_this$extensionASTNod = this.extensionASTNodes) !== null && _this$extensionASTNod !== void 0 ? _this$extensionASTNod : [],
311 assumeValid: this.__validationErrors !== undefined
312 };
313 } // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet
314 ;
315
316 _createClass(GraphQLSchema, [{
317 key: SYMBOL_TO_STRING_TAG,
318 get: function get() {
319 return 'GraphQLSchema';
320 }
321 }]);
322
323 return GraphQLSchema;
324}();
325
326function collectReferencedTypes(type, typeSet) {
327 var namedType = getNamedType(type);
328
329 if (!typeSet.has(namedType)) {
330 typeSet.add(namedType);
331
332 if (isUnionType(namedType)) {
333 for (var _i20 = 0, _namedType$getTypes2 = namedType.getTypes(); _i20 < _namedType$getTypes2.length; _i20++) {
334 var memberType = _namedType$getTypes2[_i20];
335 collectReferencedTypes(memberType, typeSet);
336 }
337 } else if (isObjectType(namedType) || isInterfaceType(namedType)) {
338 for (var _i22 = 0, _namedType$getInterfa6 = namedType.getInterfaces(); _i22 < _namedType$getInterfa6.length; _i22++) {
339 var interfaceType = _namedType$getInterfa6[_i22];
340 collectReferencedTypes(interfaceType, typeSet);
341 }
342
343 for (var _i24 = 0, _objectValues2 = objectValues(namedType.getFields()); _i24 < _objectValues2.length; _i24++) {
344 var field = _objectValues2[_i24];
345 collectReferencedTypes(field.type, typeSet);
346
347 for (var _i26 = 0, _field$args2 = field.args; _i26 < _field$args2.length; _i26++) {
348 var arg = _field$args2[_i26];
349 collectReferencedTypes(arg.type, typeSet);
350 }
351 }
352 } else if (isInputObjectType(namedType)) {
353 for (var _i28 = 0, _objectValues4 = objectValues(namedType.getFields()); _i28 < _objectValues4.length; _i28++) {
354 var _field = _objectValues4[_i28];
355 collectReferencedTypes(_field.type, typeSet);
356 }
357 }
358 }
359
360 return typeSet;
361}