"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) }); } }