123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- // @flow strict
- import inspect from '../../jsutils/inspect';
- import { GraphQLError } from '../../error/GraphQLError';
- import type { ASTVisitor } from '../../language/visitor';
- import type { GraphQLCompositeType } from '../../type/definition';
- import { isCompositeType } from '../../type/definition';
- import { typeFromAST } from '../../utilities/typeFromAST';
- import { doTypesOverlap } from '../../utilities/typeComparators';
- import type { ValidationContext } from '../ValidationContext';
- /**
- * Possible fragment spread
- *
- * A fragment spread is only valid if the type condition could ever possibly
- * be true: if there is a non-empty intersection of the possible parent types,
- * and possible types which pass the type condition.
- */
- export function PossibleFragmentSpreadsRule(
- context: ValidationContext,
- ): ASTVisitor {
- return {
- InlineFragment(node) {
- const fragType = context.getType();
- const parentType = context.getParentType();
- if (
- isCompositeType(fragType) &&
- isCompositeType(parentType) &&
- !doTypesOverlap(context.getSchema(), fragType, parentType)
- ) {
- const parentTypeStr = inspect(parentType);
- const fragTypeStr = inspect(fragType);
- context.reportError(
- new GraphQLError(
- `Fragment cannot be spread here as objects of type "${parentTypeStr}" can never be of type "${fragTypeStr}".`,
- node,
- ),
- );
- }
- },
- FragmentSpread(node) {
- const fragName = node.name.value;
- const fragType = getFragmentType(context, fragName);
- const parentType = context.getParentType();
- if (
- fragType &&
- parentType &&
- !doTypesOverlap(context.getSchema(), fragType, parentType)
- ) {
- const parentTypeStr = inspect(parentType);
- const fragTypeStr = inspect(fragType);
- context.reportError(
- new GraphQLError(
- `Fragment "${fragName}" cannot be spread here as objects of type "${parentTypeStr}" can never be of type "${fragTypeStr}".`,
- node,
- ),
- );
- }
- },
- };
- }
- function getFragmentType(
- context: ValidationContext,
- name: string,
- ): ?GraphQLCompositeType {
- const frag = context.getFragment(name);
- if (frag) {
- const type = typeFromAST(context.getSchema(), frag.typeCondition);
- if (isCompositeType(type)) {
- return type;
- }
- }
- }
|