NoUndefinedVariablesRule.mjs 1.2 KB

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