'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); exports.PossibleTypeExtensionsRule = PossibleTypeExtensionsRule; var _didYouMean = require('../../jsutils/didYouMean.js'); var _inspect = require('../../jsutils/inspect.js'); var _invariant = require('../../jsutils/invariant.js'); var _suggestionList = require('../../jsutils/suggestionList.js'); var _GraphQLError = require('../../error/GraphQLError.js'); var _kinds = require('../../language/kinds.js'); var _predicates = require('../../language/predicates.js'); var _definition = require('../../type/definition.js'); /** * Possible type extension * * A type extension is only valid if the type is defined and has the same kind. */ function PossibleTypeExtensionsRule(context) { const schema = context.getSchema(); const definedTypes = Object.create(null); for (const def of context.getDocument().definitions) { if ((0, _predicates.isTypeDefinitionNode)(def)) { definedTypes[def.name.value] = def; } } return { ScalarTypeExtension: checkExtension, ObjectTypeExtension: checkExtension, InterfaceTypeExtension: checkExtension, UnionTypeExtension: checkExtension, EnumTypeExtension: checkExtension, InputObjectTypeExtension: checkExtension, }; function checkExtension(node) { const typeName = node.name.value; const defNode = definedTypes[typeName]; const existingType = schema === null || schema === void 0 ? void 0 : schema.getType(typeName); let expectedKind; if (defNode) { expectedKind = defKindToExtKind[defNode.kind]; } else if (existingType) { expectedKind = typeToExtKind(existingType); } if (expectedKind) { if (expectedKind !== node.kind) { const kindStr = extensionKindToTypeName(node.kind); context.reportError( new _GraphQLError.GraphQLError( `Cannot extend non-${kindStr} type "${typeName}".`, { nodes: defNode ? [defNode, node] : node, }, ), ); } } else { const allTypeNames = Object.keys({ ...definedTypes, ...(schema === null || schema === void 0 ? void 0 : schema.getTypeMap()), }); const suggestedTypes = (0, _suggestionList.suggestionList)( typeName, allTypeNames, ); context.reportError( new _GraphQLError.GraphQLError( `Cannot extend type "${typeName}" because it is not defined.` + (0, _didYouMean.didYouMean)(suggestedTypes), { nodes: node.name, }, ), ); } } } const defKindToExtKind = { [_kinds.Kind.SCALAR_TYPE_DEFINITION]: _kinds.Kind.SCALAR_TYPE_EXTENSION, [_kinds.Kind.OBJECT_TYPE_DEFINITION]: _kinds.Kind.OBJECT_TYPE_EXTENSION, [_kinds.Kind.INTERFACE_TYPE_DEFINITION]: _kinds.Kind.INTERFACE_TYPE_EXTENSION, [_kinds.Kind.UNION_TYPE_DEFINITION]: _kinds.Kind.UNION_TYPE_EXTENSION, [_kinds.Kind.ENUM_TYPE_DEFINITION]: _kinds.Kind.ENUM_TYPE_EXTENSION, [_kinds.Kind.INPUT_OBJECT_TYPE_DEFINITION]: _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION, }; function typeToExtKind(type) { if ((0, _definition.isScalarType)(type)) { return _kinds.Kind.SCALAR_TYPE_EXTENSION; } if ((0, _definition.isObjectType)(type)) { return _kinds.Kind.OBJECT_TYPE_EXTENSION; } if ((0, _definition.isInterfaceType)(type)) { return _kinds.Kind.INTERFACE_TYPE_EXTENSION; } if ((0, _definition.isUnionType)(type)) { return _kinds.Kind.UNION_TYPE_EXTENSION; } if ((0, _definition.isEnumType)(type)) { return _kinds.Kind.ENUM_TYPE_EXTENSION; } if ((0, _definition.isInputObjectType)(type)) { return _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION; } /* c8 ignore next 3 */ // Not reachable. All possible types have been considered false || (0, _invariant.invariant)( false, 'Unexpected type: ' + (0, _inspect.inspect)(type), ); } function extensionKindToTypeName(kind) { switch (kind) { case _kinds.Kind.SCALAR_TYPE_EXTENSION: return 'scalar'; case _kinds.Kind.OBJECT_TYPE_EXTENSION: return 'object'; case _kinds.Kind.INTERFACE_TYPE_EXTENSION: return 'interface'; case _kinds.Kind.UNION_TYPE_EXTENSION: return 'union'; case _kinds.Kind.ENUM_TYPE_EXTENSION: return 'enum'; case _kinds.Kind.INPUT_OBJECT_TYPE_EXTENSION: return 'input object'; // Not reachable. All possible types have been considered /* c8 ignore next */ default: false || (0, _invariant.invariant)( false, 'Unexpected kind: ' + (0, _inspect.inspect)(kind), ); } }