| "use strict"; |
| |
| Object.defineProperty(exports, "__esModule", { |
| value: true |
| }); |
| exports.buildClientSchema = buildClientSchema; |
| |
| var _objectValues = _interopRequireDefault(require("../polyfills/objectValues")); |
| |
| var _inspect = _interopRequireDefault(require("../jsutils/inspect")); |
| |
| var _devAssert = _interopRequireDefault(require("../jsutils/devAssert")); |
| |
| var _keyValMap = _interopRequireDefault(require("../jsutils/keyValMap")); |
| |
| var _isObjectLike = _interopRequireDefault(require("../jsutils/isObjectLike")); |
| |
| var _parser = require("../language/parser"); |
| |
| var _directives = require("../type/directives"); |
| |
| var _scalars = require("../type/scalars"); |
| |
| var _introspection = require("../type/introspection"); |
| |
| var _schema = require("../type/schema"); |
| |
| var _definition = require("../type/definition"); |
| |
| var _valueFromAST = require("./valueFromAST"); |
| |
| function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
| |
| /** |
| * Build a GraphQLSchema for use by client tools. |
| * |
| * Given the result of a client running the introspection query, creates and |
| * returns a GraphQLSchema instance which can be then used with all graphql-js |
| * tools, but cannot be used to execute a query, as introspection does not |
| * represent the "resolver", "parse" or "serialize" functions or any other |
| * server-internal mechanisms. |
| * |
| * This function expects a complete introspection result. Don't forget to check |
| * the "errors" field of a server response before calling this function. |
| */ |
| function buildClientSchema(introspection, options) { |
| (0, _isObjectLike.default)(introspection) && (0, _isObjectLike.default)(introspection.__schema) || (0, _devAssert.default)(0, "Invalid or incomplete introspection result. Ensure that you are passing \"data\" property of introspection response and no \"errors\" was returned alongside: ".concat((0, _inspect.default)(introspection), ".")); // Get the schema from the introspection result. |
| |
| var schemaIntrospection = introspection.__schema; // Iterate through all types, getting the type definition for each. |
| |
| var typeMap = (0, _keyValMap.default)(schemaIntrospection.types, function (typeIntrospection) { |
| return typeIntrospection.name; |
| }, function (typeIntrospection) { |
| return buildType(typeIntrospection); |
| }); // Include standard types only if they are used. |
| |
| for (var _i2 = 0, _ref2 = [].concat(_scalars.specifiedScalarTypes, _introspection.introspectionTypes); _i2 < _ref2.length; _i2++) { |
| var stdType = _ref2[_i2]; |
| |
| if (typeMap[stdType.name]) { |
| typeMap[stdType.name] = stdType; |
| } |
| } // Get the root Query, Mutation, and Subscription types. |
| |
| |
| var queryType = schemaIntrospection.queryType ? getObjectType(schemaIntrospection.queryType) : null; |
| var mutationType = schemaIntrospection.mutationType ? getObjectType(schemaIntrospection.mutationType) : null; |
| var subscriptionType = schemaIntrospection.subscriptionType ? getObjectType(schemaIntrospection.subscriptionType) : null; // Get the directives supported by Introspection, assuming empty-set if |
| // directives were not queried for. |
| |
| var directives = schemaIntrospection.directives ? schemaIntrospection.directives.map(buildDirective) : []; // Then produce and return a Schema with these types. |
| |
| return new _schema.GraphQLSchema({ |
| description: schemaIntrospection.description, |
| query: queryType, |
| mutation: mutationType, |
| subscription: subscriptionType, |
| types: (0, _objectValues.default)(typeMap), |
| directives: directives, |
| assumeValid: options === null || options === void 0 ? void 0 : options.assumeValid |
| }); // Given a type reference in introspection, return the GraphQLType instance. |
| // preferring cached instances before building new instances. |
| |
| function getType(typeRef) { |
| if (typeRef.kind === _introspection.TypeKind.LIST) { |
| var itemRef = typeRef.ofType; |
| |
| if (!itemRef) { |
| throw new Error('Decorated type deeper than introspection query.'); |
| } |
| |
| return (0, _definition.GraphQLList)(getType(itemRef)); |
| } |
| |
| if (typeRef.kind === _introspection.TypeKind.NON_NULL) { |
| var nullableRef = typeRef.ofType; |
| |
| if (!nullableRef) { |
| throw new Error('Decorated type deeper than introspection query.'); |
| } |
| |
| var nullableType = getType(nullableRef); |
| return (0, _definition.GraphQLNonNull)((0, _definition.assertNullableType)(nullableType)); |
| } |
| |
| return getNamedType(typeRef); |
| } |
| |
| function getNamedType(typeRef) { |
| var typeName = typeRef.name; |
| |
| if (!typeName) { |
| throw new Error("Unknown type reference: ".concat((0, _inspect.default)(typeRef), ".")); |
| } |
| |
| var type = typeMap[typeName]; |
| |
| if (!type) { |
| throw new Error("Invalid or incomplete schema, unknown type: ".concat(typeName, ". Ensure that a full introspection query is used in order to build a client schema.")); |
| } |
| |
| return type; |
| } |
| |
| function getObjectType(typeRef) { |
| return (0, _definition.assertObjectType)(getNamedType(typeRef)); |
| } |
| |
| function getInterfaceType(typeRef) { |
| return (0, _definition.assertInterfaceType)(getNamedType(typeRef)); |
| } // Given a type's introspection result, construct the correct |
| // GraphQLType instance. |
| |
| |
| function buildType(type) { |
| if (type != null && type.name != null && type.kind != null) { |
| switch (type.kind) { |
| case _introspection.TypeKind.SCALAR: |
| return buildScalarDef(type); |
| |
| case _introspection.TypeKind.OBJECT: |
| return buildObjectDef(type); |
| |
| case _introspection.TypeKind.INTERFACE: |
| return buildInterfaceDef(type); |
| |
| case _introspection.TypeKind.UNION: |
| return buildUnionDef(type); |
| |
| case _introspection.TypeKind.ENUM: |
| return buildEnumDef(type); |
| |
| case _introspection.TypeKind.INPUT_OBJECT: |
| return buildInputObjectDef(type); |
| } |
| } |
| |
| var typeStr = (0, _inspect.default)(type); |
| throw new Error("Invalid or incomplete introspection result. Ensure that a full introspection query is used in order to build a client schema: ".concat(typeStr, ".")); |
| } |
| |
| function buildScalarDef(scalarIntrospection) { |
| return new _definition.GraphQLScalarType({ |
| name: scalarIntrospection.name, |
| description: scalarIntrospection.description |
| }); |
| } |
| |
| function buildImplementationsList(implementingIntrospection) { |
| // TODO: Temporary workaround until GraphQL ecosystem will fully support |
| // 'interfaces' on interface types. |
| if (implementingIntrospection.interfaces === null && implementingIntrospection.kind === _introspection.TypeKind.INTERFACE) { |
| return []; |
| } |
| |
| if (!implementingIntrospection.interfaces) { |
| var implementingIntrospectionStr = (0, _inspect.default)(implementingIntrospection); |
| throw new Error("Introspection result missing interfaces: ".concat(implementingIntrospectionStr, ".")); |
| } |
| |
| return implementingIntrospection.interfaces.map(getInterfaceType); |
| } |
| |
| function buildObjectDef(objectIntrospection) { |
| return new _definition.GraphQLObjectType({ |
| name: objectIntrospection.name, |
| description: objectIntrospection.description, |
| interfaces: function interfaces() { |
| return buildImplementationsList(objectIntrospection); |
| }, |
| fields: function fields() { |
| return buildFieldDefMap(objectIntrospection); |
| } |
| }); |
| } |
| |
| function buildInterfaceDef(interfaceIntrospection) { |
| return new _definition.GraphQLInterfaceType({ |
| name: interfaceIntrospection.name, |
| description: interfaceIntrospection.description, |
| interfaces: function interfaces() { |
| return buildImplementationsList(interfaceIntrospection); |
| }, |
| fields: function fields() { |
| return buildFieldDefMap(interfaceIntrospection); |
| } |
| }); |
| } |
| |
| function buildUnionDef(unionIntrospection) { |
| if (!unionIntrospection.possibleTypes) { |
| var unionIntrospectionStr = (0, _inspect.default)(unionIntrospection); |
| throw new Error("Introspection result missing possibleTypes: ".concat(unionIntrospectionStr, ".")); |
| } |
| |
| return new _definition.GraphQLUnionType({ |
| name: unionIntrospection.name, |
| description: unionIntrospection.description, |
| types: function types() { |
| return unionIntrospection.possibleTypes.map(getObjectType); |
| } |
| }); |
| } |
| |
| function buildEnumDef(enumIntrospection) { |
| if (!enumIntrospection.enumValues) { |
| var enumIntrospectionStr = (0, _inspect.default)(enumIntrospection); |
| throw new Error("Introspection result missing enumValues: ".concat(enumIntrospectionStr, ".")); |
| } |
| |
| return new _definition.GraphQLEnumType({ |
| name: enumIntrospection.name, |
| description: enumIntrospection.description, |
| values: (0, _keyValMap.default)(enumIntrospection.enumValues, function (valueIntrospection) { |
| return valueIntrospection.name; |
| }, function (valueIntrospection) { |
| return { |
| description: valueIntrospection.description, |
| deprecationReason: valueIntrospection.deprecationReason |
| }; |
| }) |
| }); |
| } |
| |
| function buildInputObjectDef(inputObjectIntrospection) { |
| if (!inputObjectIntrospection.inputFields) { |
| var inputObjectIntrospectionStr = (0, _inspect.default)(inputObjectIntrospection); |
| throw new Error("Introspection result missing inputFields: ".concat(inputObjectIntrospectionStr, ".")); |
| } |
| |
| return new _definition.GraphQLInputObjectType({ |
| name: inputObjectIntrospection.name, |
| description: inputObjectIntrospection.description, |
| fields: function fields() { |
| return buildInputValueDefMap(inputObjectIntrospection.inputFields); |
| } |
| }); |
| } |
| |
| function buildFieldDefMap(typeIntrospection) { |
| if (!typeIntrospection.fields) { |
| throw new Error("Introspection result missing fields: ".concat((0, _inspect.default)(typeIntrospection), ".")); |
| } |
| |
| return (0, _keyValMap.default)(typeIntrospection.fields, function (fieldIntrospection) { |
| return fieldIntrospection.name; |
| }, buildField); |
| } |
| |
| function buildField(fieldIntrospection) { |
| var type = getType(fieldIntrospection.type); |
| |
| if (!(0, _definition.isOutputType)(type)) { |
| var typeStr = (0, _inspect.default)(type); |
| throw new Error("Introspection must provide output type for fields, but received: ".concat(typeStr, ".")); |
| } |
| |
| if (!fieldIntrospection.args) { |
| var fieldIntrospectionStr = (0, _inspect.default)(fieldIntrospection); |
| throw new Error("Introspection result missing field args: ".concat(fieldIntrospectionStr, ".")); |
| } |
| |
| return { |
| description: fieldIntrospection.description, |
| deprecationReason: fieldIntrospection.deprecationReason, |
| type: type, |
| args: buildInputValueDefMap(fieldIntrospection.args) |
| }; |
| } |
| |
| function buildInputValueDefMap(inputValueIntrospections) { |
| return (0, _keyValMap.default)(inputValueIntrospections, function (inputValue) { |
| return inputValue.name; |
| }, buildInputValue); |
| } |
| |
| function buildInputValue(inputValueIntrospection) { |
| var type = getType(inputValueIntrospection.type); |
| |
| if (!(0, _definition.isInputType)(type)) { |
| var typeStr = (0, _inspect.default)(type); |
| throw new Error("Introspection must provide input type for arguments, but received: ".concat(typeStr, ".")); |
| } |
| |
| var defaultValue = inputValueIntrospection.defaultValue != null ? (0, _valueFromAST.valueFromAST)((0, _parser.parseValue)(inputValueIntrospection.defaultValue), type) : undefined; |
| return { |
| description: inputValueIntrospection.description, |
| type: type, |
| defaultValue: defaultValue |
| }; |
| } |
| |
| function buildDirective(directiveIntrospection) { |
| if (!directiveIntrospection.args) { |
| var directiveIntrospectionStr = (0, _inspect.default)(directiveIntrospection); |
| throw new Error("Introspection result missing directive args: ".concat(directiveIntrospectionStr, ".")); |
| } |
| |
| if (!directiveIntrospection.locations) { |
| var _directiveIntrospectionStr = (0, _inspect.default)(directiveIntrospection); |
| |
| throw new Error("Introspection result missing directive locations: ".concat(_directiveIntrospectionStr, ".")); |
| } |
| |
| return new _directives.GraphQLDirective({ |
| name: directiveIntrospection.name, |
| description: directiveIntrospection.description, |
| isRepeatable: directiveIntrospection.isRepeatable, |
| locations: directiveIntrospection.locations.slice(), |
| args: buildInputValueDefMap(directiveIntrospection.args) |
| }); |
| } |
| } |