/** * Copyright (c) 2018-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. * * @flow strict */ import type { SDLValidationContext } from '../ValidationContext'; import { GraphQLError } from '../../error/GraphQLError'; import type { ASTVisitor } from '../../language/visitor'; import type { TypeDefinitionNode } from '../../language/ast'; export function duplicateTypeNameMessage(typeName: string): string { return `There can be only one type named "${typeName}".`; } export function existedTypeNameMessage(typeName: string): string { return ( `Type "${typeName}" already exists in the schema. ` + 'It cannot also be defined in this type definition.' ); } /** * Unique type names * * A GraphQL document is only valid if all defined types have unique names. */ export function UniqueTypeNames(context: SDLValidationContext): ASTVisitor { const knownTypeNames = Object.create(null); const schema = context.getSchema(); return { ScalarTypeDefinition: checkTypeName, ObjectTypeDefinition: checkTypeName, InterfaceTypeDefinition: checkTypeName, UnionTypeDefinition: checkTypeName, EnumTypeDefinition: checkTypeName, InputObjectTypeDefinition: checkTypeName, }; function checkTypeName(node: TypeDefinitionNode) { const typeName = node.name.value; if (schema && schema.getType(typeName)) { context.reportError( new GraphQLError(existedTypeNameMessage(typeName), node.name), ); return; } if (knownTypeNames[typeName]) { context.reportError( new GraphQLError(duplicateTypeNameMessage(typeName), [ knownTypeNames[typeName], node.name, ]), ); } else { knownTypeNames[typeName] = node.name; } return false; } }