362 lines
13 KiB
JavaScript
362 lines
13 KiB
JavaScript
function _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); } }
|
|
|
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
|
|
import find from "../polyfills/find.mjs";
|
|
import arrayFrom from "../polyfills/arrayFrom.mjs";
|
|
import objectValues from "../polyfills/objectValues.mjs";
|
|
import { SYMBOL_TO_STRING_TAG } from "../polyfills/symbols.mjs";
|
|
import inspect from "../jsutils/inspect.mjs";
|
|
import toObjMap from "../jsutils/toObjMap.mjs";
|
|
import devAssert from "../jsutils/devAssert.mjs";
|
|
import instanceOf from "../jsutils/instanceOf.mjs";
|
|
import isObjectLike from "../jsutils/isObjectLike.mjs";
|
|
import { __Schema } from "./introspection.mjs";
|
|
import { GraphQLDirective, isDirective, specifiedDirectives } from "./directives.mjs";
|
|
import { isObjectType, isInterfaceType, isUnionType, isInputObjectType, getNamedType } from "./definition.mjs";
|
|
/**
|
|
* Test if the given value is a GraphQL schema.
|
|
*/
|
|
|
|
// eslint-disable-next-line no-redeclare
|
|
export function isSchema(schema) {
|
|
return instanceOf(schema, GraphQLSchema);
|
|
}
|
|
export function assertSchema(schema) {
|
|
if (!isSchema(schema)) {
|
|
throw new Error("Expected ".concat(inspect(schema), " to be a GraphQL schema."));
|
|
}
|
|
|
|
return schema;
|
|
}
|
|
/**
|
|
* 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: When the schema is constructed, by default only the types that are
|
|
* reachable by traversing the root types are included, other types must be
|
|
* explicitly referenced.
|
|
*
|
|
* Example:
|
|
*
|
|
* const characterInterface = new GraphQLInterfaceType({
|
|
* name: 'Character',
|
|
* ...
|
|
* });
|
|
*
|
|
* const humanType = new GraphQLObjectType({
|
|
* name: 'Human',
|
|
* interfaces: [characterInterface],
|
|
* ...
|
|
* });
|
|
*
|
|
* const droidType = new GraphQLObjectType({
|
|
* name: 'Droid',
|
|
* interfaces: [characterInterface],
|
|
* ...
|
|
* });
|
|
*
|
|
* const schema = new GraphQLSchema({
|
|
* query: new GraphQLObjectType({
|
|
* name: 'Query',
|
|
* fields: {
|
|
* hero: { type: characterInterface, ... },
|
|
* }
|
|
* }),
|
|
* ...
|
|
* // Since this schema references only the `Character` interface it's
|
|
* // necessary to explicitly list the types that implement it if
|
|
* // you want them to be included in the final schema.
|
|
* types: [humanType, droidType],
|
|
* })
|
|
*
|
|
* 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().
|
|
function GraphQLSchema(config) {
|
|
var _config$directives;
|
|
|
|
// 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.
|
|
this.__validationErrors = config.assumeValid === true ? [] : undefined; // Check for common mistakes during construction to produce early errors.
|
|
|
|
isObjectLike(config) || devAssert(0, 'Must provide configuration object.');
|
|
!config.types || Array.isArray(config.types) || devAssert(0, "\"types\" must be Array if provided but got: ".concat(inspect(config.types), "."));
|
|
!config.directives || Array.isArray(config.directives) || devAssert(0, '"directives" must be Array if provided but got: ' + "".concat(inspect(config.directives), "."));
|
|
this.description = config.description;
|
|
this.extensions = config.extensions && toObjMap(config.extensions);
|
|
this.astNode = config.astNode;
|
|
this.extensionASTNodes = config.extensionASTNodes;
|
|
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 = config.directives) !== null && _config$directives !== void 0 ? _config$directives : specifiedDirectives; // To preserve order of user-provided types, we add first to add them to
|
|
// the set of "collected" types, so `collectReferencedTypes` ignore them.
|
|
|
|
var allReferencedTypes = new Set(config.types);
|
|
|
|
if (config.types != null) {
|
|
for (var _i2 = 0, _config$types2 = config.types; _i2 < _config$types2.length; _i2++) {
|
|
var type = _config$types2[_i2];
|
|
// When we ready to process this type, we remove it from "collected" types
|
|
// and then add it together with all dependent types in the correct position.
|
|
allReferencedTypes.delete(type);
|
|
collectReferencedTypes(type, allReferencedTypes);
|
|
}
|
|
}
|
|
|
|
if (this._queryType != null) {
|
|
collectReferencedTypes(this._queryType, allReferencedTypes);
|
|
}
|
|
|
|
if (this._mutationType != null) {
|
|
collectReferencedTypes(this._mutationType, allReferencedTypes);
|
|
}
|
|
|
|
if (this._subscriptionType != null) {
|
|
collectReferencedTypes(this._subscriptionType, allReferencedTypes);
|
|
}
|
|
|
|
for (var _i4 = 0, _this$_directives2 = this._directives; _i4 < _this$_directives2.length; _i4++) {
|
|
var directive = _this$_directives2[_i4];
|
|
|
|
// Directives are not validated until validateSchema() is called.
|
|
if (isDirective(directive)) {
|
|
for (var _i6 = 0, _directive$args2 = directive.args; _i6 < _directive$args2.length; _i6++) {
|
|
var arg = _directive$args2[_i6];
|
|
collectReferencedTypes(arg.type, allReferencedTypes);
|
|
}
|
|
}
|
|
}
|
|
|
|
collectReferencedTypes(__Schema, allReferencedTypes); // Storing the resulting map for reference by the schema.
|
|
|
|
this._typeMap = Object.create(null);
|
|
this._subTypeMap = Object.create(null); // Keep track of all implementations by interface name.
|
|
|
|
this._implementationsMap = Object.create(null);
|
|
|
|
for (var _i8 = 0, _arrayFrom2 = arrayFrom(allReferencedTypes); _i8 < _arrayFrom2.length; _i8++) {
|
|
var namedType = _arrayFrom2[_i8];
|
|
|
|
if (namedType == null) {
|
|
continue;
|
|
}
|
|
|
|
var typeName = namedType.name;
|
|
typeName || devAssert(0, 'One of the provided types for building the Schema is missing a name.');
|
|
|
|
if (this._typeMap[typeName] !== undefined) {
|
|
throw new Error("Schema must contain uniquely named types but contains multiple types named \"".concat(typeName, "\"."));
|
|
}
|
|
|
|
this._typeMap[typeName] = namedType;
|
|
|
|
if (isInterfaceType(namedType)) {
|
|
// Store implementations by interface.
|
|
for (var _i10 = 0, _namedType$getInterfa2 = namedType.getInterfaces(); _i10 < _namedType$getInterfa2.length; _i10++) {
|
|
var iface = _namedType$getInterfa2[_i10];
|
|
|
|
if (isInterfaceType(iface)) {
|
|
var implementations = this._implementationsMap[iface.name];
|
|
|
|
if (implementations === undefined) {
|
|
implementations = this._implementationsMap[iface.name] = {
|
|
objects: [],
|
|
interfaces: []
|
|
};
|
|
}
|
|
|
|
implementations.interfaces.push(namedType);
|
|
}
|
|
}
|
|
} else if (isObjectType(namedType)) {
|
|
// Store implementations by objects.
|
|
for (var _i12 = 0, _namedType$getInterfa4 = namedType.getInterfaces(); _i12 < _namedType$getInterfa4.length; _i12++) {
|
|
var _iface = _namedType$getInterfa4[_i12];
|
|
|
|
if (isInterfaceType(_iface)) {
|
|
var _implementations = this._implementationsMap[_iface.name];
|
|
|
|
if (_implementations === undefined) {
|
|
_implementations = this._implementationsMap[_iface.name] = {
|
|
objects: [],
|
|
interfaces: []
|
|
};
|
|
}
|
|
|
|
_implementations.objects.push(namedType);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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) {
|
|
return isUnionType(abstractType) ? abstractType.getTypes() : this.getImplementations(abstractType).objects;
|
|
};
|
|
|
|
_proto.getImplementations = function getImplementations(interfaceType) {
|
|
var implementations = this._implementationsMap[interfaceType.name];
|
|
return implementations !== null && implementations !== void 0 ? implementations : {
|
|
objects: [],
|
|
interfaces: []
|
|
};
|
|
} // @deprecated: use isSubType instead - will be removed in v16.
|
|
;
|
|
|
|
_proto.isPossibleType = function isPossibleType(abstractType, possibleType) {
|
|
return this.isSubType(abstractType, possibleType);
|
|
};
|
|
|
|
_proto.isSubType = function isSubType(abstractType, maybeSubType) {
|
|
var map = this._subTypeMap[abstractType.name];
|
|
|
|
if (map === undefined) {
|
|
map = Object.create(null);
|
|
|
|
if (isUnionType(abstractType)) {
|
|
for (var _i14 = 0, _abstractType$getType2 = abstractType.getTypes(); _i14 < _abstractType$getType2.length; _i14++) {
|
|
var type = _abstractType$getType2[_i14];
|
|
map[type.name] = true;
|
|
}
|
|
} else {
|
|
var implementations = this.getImplementations(abstractType);
|
|
|
|
for (var _i16 = 0, _implementations$obje2 = implementations.objects; _i16 < _implementations$obje2.length; _i16++) {
|
|
var _type = _implementations$obje2[_i16];
|
|
map[_type.name] = true;
|
|
}
|
|
|
|
for (var _i18 = 0, _implementations$inte2 = implementations.interfaces; _i18 < _implementations$inte2.length; _i18++) {
|
|
var _type2 = _implementations$inte2[_i18];
|
|
map[_type2.name] = true;
|
|
}
|
|
}
|
|
|
|
this._subTypeMap[abstractType.name] = map;
|
|
}
|
|
|
|
return map[maybeSubType.name] !== undefined;
|
|
};
|
|
|
|
_proto.getDirectives = function getDirectives() {
|
|
return this._directives;
|
|
};
|
|
|
|
_proto.getDirective = function getDirective(name) {
|
|
return find(this.getDirectives(), function (directive) {
|
|
return directive.name === name;
|
|
});
|
|
};
|
|
|
|
_proto.toConfig = function toConfig() {
|
|
var _this$extensionASTNod;
|
|
|
|
return {
|
|
description: this.description,
|
|
query: this.getQueryType(),
|
|
mutation: this.getMutationType(),
|
|
subscription: this.getSubscriptionType(),
|
|
types: objectValues(this.getTypeMap()),
|
|
directives: this.getDirectives().slice(),
|
|
extensions: this.extensions,
|
|
astNode: this.astNode,
|
|
extensionASTNodes: (_this$extensionASTNod = this.extensionASTNodes) !== null && _this$extensionASTNod !== void 0 ? _this$extensionASTNod : [],
|
|
assumeValid: this.__validationErrors !== undefined
|
|
};
|
|
} // $FlowFixMe[unsupported-syntax] Flow doesn't support computed properties yet
|
|
;
|
|
|
|
_createClass(GraphQLSchema, [{
|
|
key: SYMBOL_TO_STRING_TAG,
|
|
get: function get() {
|
|
return 'GraphQLSchema';
|
|
}
|
|
}]);
|
|
|
|
return GraphQLSchema;
|
|
}();
|
|
|
|
function collectReferencedTypes(type, typeSet) {
|
|
var namedType = getNamedType(type);
|
|
|
|
if (!typeSet.has(namedType)) {
|
|
typeSet.add(namedType);
|
|
|
|
if (isUnionType(namedType)) {
|
|
for (var _i20 = 0, _namedType$getTypes2 = namedType.getTypes(); _i20 < _namedType$getTypes2.length; _i20++) {
|
|
var memberType = _namedType$getTypes2[_i20];
|
|
collectReferencedTypes(memberType, typeSet);
|
|
}
|
|
} else if (isObjectType(namedType) || isInterfaceType(namedType)) {
|
|
for (var _i22 = 0, _namedType$getInterfa6 = namedType.getInterfaces(); _i22 < _namedType$getInterfa6.length; _i22++) {
|
|
var interfaceType = _namedType$getInterfa6[_i22];
|
|
collectReferencedTypes(interfaceType, typeSet);
|
|
}
|
|
|
|
for (var _i24 = 0, _objectValues2 = objectValues(namedType.getFields()); _i24 < _objectValues2.length; _i24++) {
|
|
var field = _objectValues2[_i24];
|
|
collectReferencedTypes(field.type, typeSet);
|
|
|
|
for (var _i26 = 0, _field$args2 = field.args; _i26 < _field$args2.length; _i26++) {
|
|
var arg = _field$args2[_i26];
|
|
collectReferencedTypes(arg.type, typeSet);
|
|
}
|
|
}
|
|
} else if (isInputObjectType(namedType)) {
|
|
for (var _i28 = 0, _objectValues4 = objectValues(namedType.getFields()); _i28 < _objectValues4.length; _i28++) {
|
|
var _field = _objectValues4[_i28];
|
|
collectReferencedTypes(_field.type, typeSet);
|
|
}
|
|
}
|
|
}
|
|
|
|
return typeSet;
|
|
}
|