NoUnusedVariablesRule.js.flow 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  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 unused variables
  7. *
  8. * A GraphQL operation is only valid if all variables defined by an operation
  9. * are used, either directly or within a spread fragment.
  10. */
  11. export function NoUnusedVariablesRule(context: ValidationContext): ASTVisitor {
  12. let variableDefs = [];
  13. return {
  14. OperationDefinition: {
  15. enter() {
  16. variableDefs = [];
  17. },
  18. leave(operation) {
  19. const variableNameUsed = Object.create(null);
  20. const usages = context.getRecursiveVariableUsages(operation);
  21. for (const { node } of usages) {
  22. variableNameUsed[node.name.value] = true;
  23. }
  24. for (const variableDef of variableDefs) {
  25. const variableName = variableDef.variable.name.value;
  26. if (variableNameUsed[variableName] !== true) {
  27. context.reportError(
  28. new GraphQLError(
  29. operation.name
  30. ? `Variable "$${variableName}" is never used in operation "${operation.name.value}".`
  31. : `Variable "$${variableName}" is never used.`,
  32. variableDef,
  33. ),
  34. );
  35. }
  36. }
  37. },
  38. },
  39. VariableDefinition(def) {
  40. variableDefs.push(def);
  41. },
  42. };
  43. }