ScalarLeafsRule.js.flow 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // @flow strict
  2. import inspect from '../../jsutils/inspect';
  3. import { GraphQLError } from '../../error/GraphQLError';
  4. import type { FieldNode } from '../../language/ast';
  5. import type { ASTVisitor } from '../../language/visitor';
  6. import { getNamedType, isLeafType } from '../../type/definition';
  7. import type { ValidationContext } from '../ValidationContext';
  8. /**
  9. * Scalar leafs
  10. *
  11. * A GraphQL document is valid only if all leaf fields (fields without
  12. * sub selections) are of scalar or enum types.
  13. */
  14. export function ScalarLeafsRule(context: ValidationContext): ASTVisitor {
  15. return {
  16. Field(node: FieldNode) {
  17. const type = context.getType();
  18. const selectionSet = node.selectionSet;
  19. if (type) {
  20. if (isLeafType(getNamedType(type))) {
  21. if (selectionSet) {
  22. const fieldName = node.name.value;
  23. const typeStr = inspect(type);
  24. context.reportError(
  25. new GraphQLError(
  26. `Field "${fieldName}" must not have a selection since type "${typeStr}" has no subfields.`,
  27. selectionSet,
  28. ),
  29. );
  30. }
  31. } else if (!selectionSet) {
  32. const fieldName = node.name.value;
  33. const typeStr = inspect(type);
  34. context.reportError(
  35. new GraphQLError(
  36. `Field "${fieldName}" of type "${typeStr}" must have a selection of subfields. Did you mean "${fieldName} { ... }"?`,
  37. node,
  38. ),
  39. );
  40. }
  41. }
  42. },
  43. };
  44. }