NoUndefinedVariablesRule.js.flow 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. // @flow strict
  2. import { GraphQLError } from '../../error/GraphQLError';
  3. import type { ASTVisitor } from '../../language/visitor';
  4. import type { ValidationContext } from '../ValidationContext';
  5. /**
  6. * No undefined variables
  7. *
  8. * A GraphQL operation is only valid if all variables encountered, both directly
  9. * and via fragment spreads, are defined by that operation.
  10. */
  11. export function NoUndefinedVariablesRule(
  12. context: ValidationContext,
  13. ): ASTVisitor {
  14. let variableNameDefined = Object.create(null);
  15. return {
  16. OperationDefinition: {
  17. enter() {
  18. variableNameDefined = Object.create(null);
  19. },
  20. leave(operation) {
  21. const usages = context.getRecursiveVariableUsages(operation);
  22. for (const { node } of usages) {
  23. const varName = node.name.value;
  24. if (variableNameDefined[varName] !== true) {
  25. context.reportError(
  26. new GraphQLError(
  27. operation.name
  28. ? `Variable "$${varName}" is not defined by operation "${operation.name.value}".`
  29. : `Variable "$${varName}" is not defined.`,
  30. [node, operation],
  31. ),
  32. );
  33. }
  34. }
  35. },
  36. },
  37. VariableDefinition(node) {
  38. variableNameDefined[node.variable.name.value] = true;
  39. },
  40. };
  41. }