NoUnusedFragmentsRule.mjs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { GraphQLError } from '../../error/GraphQLError.mjs';
  2. /**
  3. * No unused fragments
  4. *
  5. * A GraphQL document is only valid if all fragment definitions are spread
  6. * within operations, or spread within other fragments spread within operations.
  7. *
  8. * See https://spec.graphql.org/draft/#sec-Fragments-Must-Be-Used
  9. */
  10. export function NoUnusedFragmentsRule(context) {
  11. const operationDefs = [];
  12. const fragmentDefs = [];
  13. return {
  14. OperationDefinition(node) {
  15. operationDefs.push(node);
  16. return false;
  17. },
  18. FragmentDefinition(node) {
  19. fragmentDefs.push(node);
  20. return false;
  21. },
  22. Document: {
  23. leave() {
  24. const fragmentNameUsed = Object.create(null);
  25. for (const operation of operationDefs) {
  26. for (const fragment of context.getRecursivelyReferencedFragments(
  27. operation,
  28. )) {
  29. fragmentNameUsed[fragment.name.value] = true;
  30. }
  31. }
  32. for (const fragmentDef of fragmentDefs) {
  33. const fragName = fragmentDef.name.value;
  34. if (fragmentNameUsed[fragName] !== true) {
  35. context.reportError(
  36. new GraphQLError(`Fragment "${fragName}" is never used.`, {
  37. nodes: fragmentDef,
  38. }),
  39. );
  40. }
  41. }
  42. },
  43. },
  44. };
  45. }