UniqueDirectivesPerLocation.mjs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { GraphQLError } from '../../error/GraphQLError';
  2. import { Kind } from '../../language/kinds';
  3. import { specifiedDirectives } from '../../type/directives';
  4. export function duplicateDirectiveMessage(directiveName) {
  5. return "The directive \"".concat(directiveName, "\" can only be used once at this location.");
  6. }
  7. /**
  8. * Unique directive names per location
  9. *
  10. * A GraphQL document is only valid if all non-repeatable directives at
  11. * a given location are uniquely named.
  12. */
  13. export function UniqueDirectivesPerLocation(context) {
  14. var uniqueDirectiveMap = Object.create(null);
  15. var schema = context.getSchema();
  16. var definedDirectives = schema ? schema.getDirectives() : specifiedDirectives;
  17. for (var _i2 = 0; _i2 < definedDirectives.length; _i2++) {
  18. var directive = definedDirectives[_i2];
  19. uniqueDirectiveMap[directive.name] = !directive.isRepeatable;
  20. }
  21. var astDefinitions = context.getDocument().definitions;
  22. for (var _i4 = 0; _i4 < astDefinitions.length; _i4++) {
  23. var def = astDefinitions[_i4];
  24. if (def.kind === Kind.DIRECTIVE_DEFINITION) {
  25. uniqueDirectiveMap[def.name.value] = !def.repeatable;
  26. }
  27. }
  28. return {
  29. // Many different AST nodes may contain directives. Rather than listing
  30. // them all, just listen for entering any node, and check to see if it
  31. // defines any directives.
  32. enter: function enter(node) {
  33. // Flow can't refine that node.directives will only contain directives,
  34. // so we cast so the rest of the code is well typed.
  35. var directives = node.directives;
  36. if (directives) {
  37. var knownDirectives = Object.create(null);
  38. for (var _i6 = 0; _i6 < directives.length; _i6++) {
  39. var _directive = directives[_i6];
  40. var directiveName = _directive.name.value;
  41. if (uniqueDirectiveMap[directiveName]) {
  42. if (knownDirectives[directiveName]) {
  43. context.reportError(new GraphQLError(duplicateDirectiveMessage(directiveName), [knownDirectives[directiveName], _directive]));
  44. } else {
  45. knownDirectives[directiveName] = _directive;
  46. }
  47. }
  48. }
  49. }
  50. }
  51. };
  52. }