diff options
Diffstat (limited to 'includes/external/school/node_modules/graphql/validation/rules/PossibleFragmentSpreadsRule.js.flow')
-rw-r--r-- | includes/external/school/node_modules/graphql/validation/rules/PossibleFragmentSpreadsRule.js.flow | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/includes/external/school/node_modules/graphql/validation/rules/PossibleFragmentSpreadsRule.js.flow b/includes/external/school/node_modules/graphql/validation/rules/PossibleFragmentSpreadsRule.js.flow new file mode 100644 index 0000000..9c275bb --- /dev/null +++ b/includes/external/school/node_modules/graphql/validation/rules/PossibleFragmentSpreadsRule.js.flow @@ -0,0 +1,78 @@ +// @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; + } + } +} |