Spaces:
Paused
Paused
| import { inspect } from '../../jsutils/inspect.mjs'; | |
| import { GraphQLError } from '../../error/GraphQLError.mjs'; | |
| import { isCompositeType } from '../../type/definition.mjs'; | |
| import { doTypesOverlap } from '../../utilities/typeComparators.mjs'; | |
| import { typeFromAST } from '../../utilities/typeFromAST.mjs'; | |
| /** | |
| * 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) { | |
| 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}".`, | |
| { | |
| nodes: 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}".`, | |
| { | |
| nodes: node, | |
| }, | |
| ), | |
| ); | |
| } | |
| }, | |
| }; | |
| } | |
| function getFragmentType(context, name) { | |
| const frag = context.getFragment(name); | |
| if (frag) { | |
| const type = typeFromAST(context.getSchema(), frag.typeCondition); | |
| if (isCompositeType(type)) { | |
| return type; | |
| } | |
| } | |
| } | |