UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

325 lines (264 loc) 11.1 kB
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** * Copyright (c) 2015-present, Facebook, Inc. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * strict */ import { isAbstractType, isObjectType, isInterfaceType, isUnionType, isInputObjectType, isWrappingType } from './definition'; import { GraphQLDirective, isDirective, specifiedDirectives } from './directives'; import inspect from '../jsutils/inspect'; import { __Schema } from './introspection'; import defineToStringTag from '../jsutils/defineToStringTag'; import find from '../jsutils/find'; import instanceOf from '../jsutils/instanceOf'; import invariant from '../jsutils/invariant'; import objectValues from '../jsutils/objectValues'; // eslint-disable-next-line no-redeclare export function isSchema(schema) { return instanceOf(schema, GraphQLSchema); } /** * Schema Definition * * A Schema is created by supplying the root types of each type of operation, * query and mutation (optional). A schema definition is then supplied to the * validator and executor. * * Example: * * const MyAppSchema = new GraphQLSchema({ * query: MyAppQueryRootType, * mutation: MyAppMutationRootType, * }) * * Note: If an array of `directives` are provided to GraphQLSchema, that will be * the exact list of directives represented and allowed. If `directives` is not * provided then a default set of the specified directives (e.g. @include and * @skip) will be used. If you wish to provide *additional* directives to these * specified directives, you must explicitly declare them. Example: * * const MyAppSchema = new GraphQLSchema({ * ... * directives: specifiedDirectives.concat([ myCustomDirective ]), * }) * */ export var GraphQLSchema = /*#__PURE__*/ function () { // Used as a cache for validateSchema(). // Referenced by validateSchema(). function GraphQLSchema(config) { _defineProperty(this, "astNode", void 0); _defineProperty(this, "extensionASTNodes", void 0); _defineProperty(this, "_queryType", void 0); _defineProperty(this, "_mutationType", void 0); _defineProperty(this, "_subscriptionType", void 0); _defineProperty(this, "_directives", void 0); _defineProperty(this, "_typeMap", void 0); _defineProperty(this, "_implementations", void 0); _defineProperty(this, "_possibleTypeMap", void 0); _defineProperty(this, "__validationErrors", void 0); _defineProperty(this, "__allowedLegacyNames", void 0); // If this schema was built from a source known to be valid, then it may be // marked with assumeValid to avoid an additional type system validation. if (config && config.assumeValid) { this.__validationErrors = []; } else { // Otherwise check for common mistakes during construction to produce // clear and early error messages. !(_typeof(config) === 'object') ? invariant(0, 'Must provide configuration object.') : void 0; !(!config.types || Array.isArray(config.types)) ? invariant(0, "\"types\" must be Array if provided but got: ".concat(inspect(config.types), ".")) : void 0; !(!config.directives || Array.isArray(config.directives)) ? invariant(0, '"directives" must be Array if provided but got: ' + "".concat(inspect(config.directives), ".")) : void 0; !(!config.allowedLegacyNames || Array.isArray(config.allowedLegacyNames)) ? invariant(0, '"allowedLegacyNames" must be Array if provided but got: ' + "".concat(inspect(config.allowedLegacyNames), ".")) : void 0; } this.__allowedLegacyNames = config.allowedLegacyNames || []; this._queryType = config.query; this._mutationType = config.mutation; this._subscriptionType = config.subscription; // Provide specified directives (e.g. @include and @skip) by default. this._directives = config.directives || specifiedDirectives; this.astNode = config.astNode; this.extensionASTNodes = config.extensionASTNodes; // Build type map now to detect any errors within this schema. var initialTypes = [this.getQueryType(), this.getMutationType(), this.getSubscriptionType(), __Schema]; var types = config.types; if (types) { initialTypes = initialTypes.concat(types); } // Keep track of all types referenced within the schema. var typeMap = Object.create(null); // First by deeply visiting all initial types. typeMap = initialTypes.reduce(typeMapReducer, typeMap); // Then by deeply visiting all directive types. typeMap = this._directives.reduce(typeMapDirectiveReducer, typeMap); // Storing the resulting map for reference by the schema. this._typeMap = typeMap; // Keep track of all implementations by interface name. this._implementations = Object.create(null); var _arr = Object.keys(this._typeMap); for (var _i = 0; _i < _arr.length; _i++) { var typeName = _arr[_i]; var type = this._typeMap[typeName]; if (isObjectType(type)) { var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = type.getInterfaces()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var iface = _step.value; if (isInterfaceType(iface)) { var impls = this._implementations[iface.name]; if (impls) { impls.push(type); } else { this._implementations[iface.name] = [type]; } } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } } else if (isAbstractType(type) && !this._implementations[type.name]) { this._implementations[type.name] = []; } } } var _proto = GraphQLSchema.prototype; _proto.getQueryType = function getQueryType() { return this._queryType; }; _proto.getMutationType = function getMutationType() { return this._mutationType; }; _proto.getSubscriptionType = function getSubscriptionType() { return this._subscriptionType; }; _proto.getTypeMap = function getTypeMap() { return this._typeMap; }; _proto.getType = function getType(name) { return this.getTypeMap()[name]; }; _proto.getPossibleTypes = function getPossibleTypes(abstractType) { if (isUnionType(abstractType)) { return abstractType.getTypes(); } return this._implementations[abstractType.name]; }; _proto.isPossibleType = function isPossibleType(abstractType, possibleType) { var possibleTypeMap = this._possibleTypeMap; if (!possibleTypeMap) { this._possibleTypeMap = possibleTypeMap = Object.create(null); } if (!possibleTypeMap[abstractType.name]) { var possibleTypes = this.getPossibleTypes(abstractType); possibleTypeMap[abstractType.name] = possibleTypes.reduce(function (map, type) { return map[type.name] = true, map; }, Object.create(null)); } return Boolean(possibleTypeMap[abstractType.name][possibleType.name]); }; _proto.getDirectives = function getDirectives() { return this._directives; }; _proto.getDirective = function getDirective(name) { return find(this.getDirectives(), function (directive) { return directive.name === name; }); }; return GraphQLSchema; }(); // Conditionally apply `[Symbol.toStringTag]` if `Symbol`s are supported defineToStringTag(GraphQLSchema); function typeMapReducer(map, type) { if (!type) { return map; } if (isWrappingType(type)) { return typeMapReducer(map, type.ofType); } if (map[type.name]) { !(map[type.name] === type) ? invariant(0, 'Schema must contain unique named types but contains multiple ' + "types named \"".concat(type.name, "\".")) : void 0; return map; } map[type.name] = type; var reducedMap = map; if (isUnionType(type)) { reducedMap = type.getTypes().reduce(typeMapReducer, reducedMap); } if (isObjectType(type)) { reducedMap = type.getInterfaces().reduce(typeMapReducer, reducedMap); } if (isObjectType(type) || isInterfaceType(type)) { var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = objectValues(type.getFields())[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var field = _step2.value; if (field.args) { var fieldArgTypes = field.args.map(function (arg) { return arg.type; }); reducedMap = fieldArgTypes.reduce(typeMapReducer, reducedMap); } reducedMap = typeMapReducer(reducedMap, field.type); } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } } if (isInputObjectType(type)) { var _iteratorNormalCompletion3 = true; var _didIteratorError3 = false; var _iteratorError3 = undefined; try { for (var _iterator3 = objectValues(type.getFields())[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { var _field = _step3.value; reducedMap = typeMapReducer(reducedMap, _field.type); } } catch (err) { _didIteratorError3 = true; _iteratorError3 = err; } finally { try { if (!_iteratorNormalCompletion3 && _iterator3.return != null) { _iterator3.return(); } } finally { if (_didIteratorError3) { throw _iteratorError3; } } } } return reducedMap; } function typeMapDirectiveReducer(map, directive) { // Directives are not validated until validateSchema() is called. if (!isDirective(directive)) { return map; } return directive.args.reduce(function (_map, arg) { return typeMapReducer(_map, arg.type); }, map); }