UniqueDirectiveNamesRule.js.flow 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // @flow strict
  2. import { GraphQLError } from '../../error/GraphQLError';
  3. import type { ASTVisitor } from '../../language/visitor';
  4. import type { SDLValidationContext } from '../ValidationContext';
  5. /**
  6. * Unique directive names
  7. *
  8. * A GraphQL document is only valid if all defined directives have unique names.
  9. */
  10. export function UniqueDirectiveNamesRule(
  11. context: SDLValidationContext,
  12. ): ASTVisitor {
  13. const knownDirectiveNames = Object.create(null);
  14. const schema = context.getSchema();
  15. return {
  16. DirectiveDefinition(node) {
  17. const directiveName = node.name.value;
  18. if (schema?.getDirective(directiveName)) {
  19. context.reportError(
  20. new GraphQLError(
  21. `Directive "@${directiveName}" already exists in the schema. It cannot be redefined.`,
  22. node.name,
  23. ),
  24. );
  25. return;
  26. }
  27. if (knownDirectiveNames[directiveName]) {
  28. context.reportError(
  29. new GraphQLError(
  30. `There can be only one directive named "@${directiveName}".`,
  31. [knownDirectiveNames[directiveName], node.name],
  32. ),
  33. );
  34. } else {
  35. knownDirectiveNames[directiveName] = node.name;
  36. }
  37. return false;
  38. },
  39. };
  40. }