graphql
Version:
A Query Language and Runtime which can target any service.
1 lines • 4.5 kB
Source Map (JSON)
{"version":3,"file":"UniqueEnumValueNamesRule.js","sourceRoot":"","sources":["../../../src/validation/rules/UniqueEnumValueNamesRule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,qCAAoC;AAS3D,OAAO,EAAE,UAAU,EAAE,kCAAiC;AA6BtD,MAAM,UAAU,wBAAwB,CACtC,OAA6B;IAE7B,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,eAAe,GAAG,IAAI,GAAG,EAAiC,CAAC;IAEjE,OAAO;QACL,kBAAkB,EAAE,oBAAoB;QACxC,iBAAiB,EAAE,oBAAoB;KACxC,CAAC;IAEF,SAAS,oBAAoB,CAC3B,IAAoD;QAEpD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAEjC,IAAI,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;YACvB,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;QAErC,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YAEtC,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC/C,IAAI,UAAU,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACjE,OAAO,CAAC,WAAW,CACjB,IAAI,YAAY,CACd,eAAe,QAAQ,IAAI,SAAS,mFAAmF,EACvH,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,EAAE,CACzB,CACF,CAAC;gBACF,SAAS;YACX,CAAC;YAED,MAAM,cAAc,GAAG,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACjD,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;gBAC3B,OAAO,CAAC,WAAW,CACjB,IAAI,YAAY,CACd,eAAe,QAAQ,IAAI,SAAS,6BAA6B,EACjE,EAAE,KAAK,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAC3C,CACF,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC","sourcesContent":["/** @category Validation Rules */\n\nimport { GraphQLError } from '../../error/GraphQLError.ts';\n\nimport type {\n EnumTypeDefinitionNode,\n EnumTypeExtensionNode,\n NameNode,\n} from '../../language/ast.ts';\nimport type { ASTVisitor } from '../../language/visitor.ts';\n\nimport { isEnumType } from '../../type/definition.ts';\n\nimport type { SDLValidationContext } from '../ValidationContext.ts';\n\n/**\n * Unique enum value names\n *\n * A GraphQL enum type is only valid if all its values are uniquely named.\n * @param context - The validation context used while checking the document.\n * @returns A visitor that reports validation errors for this rule.\n * @example\n * ```ts\n * import { buildSchema } from 'graphql';\n * import { UniqueEnumValueNamesRule } from 'graphql/validation';\n *\n * const invalidSDL = `\n * enum Status { ACTIVE ACTIVE } type Query { status: Status }\n * `;\n *\n * UniqueEnumValueNamesRule.name; // => 'UniqueEnumValueNamesRule'\n * buildSchema(invalidSDL); // throws an error\n *\n * const validSDL = `\n * enum Status { ACTIVE INACTIVE } type Query { status: Status }\n * `;\n *\n * buildSchema(validSDL); // does not throw\n * ```\n */\nexport function UniqueEnumValueNamesRule(\n context: SDLValidationContext,\n): ASTVisitor {\n const schema = context.getSchema();\n const existingTypeMap = schema ? schema.getTypeMap() : Object.create(null);\n const knownValueNames = new Map<string, Map<string, NameNode>>();\n\n return {\n EnumTypeDefinition: checkValueUniqueness,\n EnumTypeExtension: checkValueUniqueness,\n };\n\n function checkValueUniqueness(\n node: EnumTypeDefinitionNode | EnumTypeExtensionNode,\n ) {\n const typeName = node.name.value;\n\n let valueNames = knownValueNames.get(typeName);\n if (valueNames == null) {\n valueNames = new Map();\n knownValueNames.set(typeName, valueNames);\n }\n\n const valueNodes = node.values ?? [];\n\n for (const valueDef of valueNodes) {\n const valueName = valueDef.name.value;\n\n const existingType = existingTypeMap[typeName];\n if (isEnumType(existingType) && existingType.getValue(valueName)) {\n context.reportError(\n new GraphQLError(\n `Enum value \"${typeName}.${valueName}\" already exists in the schema. It cannot also be defined in this type extension.`,\n { nodes: valueDef.name },\n ),\n );\n continue;\n }\n\n const knownValueName = valueNames.get(valueName);\n if (knownValueName != null) {\n context.reportError(\n new GraphQLError(\n `Enum value \"${typeName}.${valueName}\" can only be defined once.`,\n { nodes: [knownValueName, valueDef.name] },\n ),\n );\n } else {\n valueNames.set(valueName, valueDef.name);\n }\n }\n\n return false;\n }\n}\n"]}