UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

88 lines (74 loc) 2.97 kB
/* @flow */ /** * Copyright (c) 2015, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. */ 'use strict'; var _Object$defineProperty = require('babel-runtime/core-js/object/define-property')['default']; var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default']; _Object$defineProperty(exports, '__esModule', { value: true }); exports['default'] = PossibleFragmentSpreads; var _error = require('../../error'); var _typeDefinition = require('../../type/definition'); var _utilsKeyMap = require('../../utils/keyMap'); var _utilsKeyMap2 = _interopRequireDefault(_utilsKeyMap); var _errors = require('../errors'); /** * 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. */ function PossibleFragmentSpreads(context) { return { InlineFragment: function InlineFragment(node) { var fragType = (0, _typeDefinition.getUnmodifiedType)(context.getType()); var parentType = context.getParentType(); if (fragType && parentType && !doTypesOverlap(fragType, parentType)) { return new _error.GraphQLError((0, _errors.typeIncompatibleAnonSpreadMessage)(parentType, fragType), [node]); } }, FragmentSpread: function FragmentSpread(node) { var fragName = node.name.value; var fragType = (0, _typeDefinition.getUnmodifiedType)(getFragmentType(context, fragName)); var parentType = context.getParentType(); if (fragType && parentType && !doTypesOverlap(fragType, parentType)) { return new _error.GraphQLError((0, _errors.typeIncompatibleSpreadMessage)(fragName, parentType, fragType), [node]); } } }; } function getFragmentType(context, name) { var frag = context.getFragment(name); return frag && context.getSchema().getType(frag.typeCondition.value); } function doTypesOverlap(t1, t2) { if (t1 === t2) { return true; } if (t1 instanceof _typeDefinition.GraphQLObjectType) { if (t2 instanceof _typeDefinition.GraphQLObjectType) { return false; } return t2.getPossibleTypes().indexOf(t1) !== -1; } if (t1 instanceof _typeDefinition.GraphQLInterfaceType || t1 instanceof _typeDefinition.GraphQLUnionType) { if (t2 instanceof _typeDefinition.GraphQLObjectType) { return t1.getPossibleTypes().indexOf(t2) !== -1; } var t1TypeNames = (0, _utilsKeyMap2['default'])(t1.getPossibleTypes(), function (type) { return type.name; }); return t2.getPossibleTypes().some(function (type) { return t1TypeNames[type.name]; }); } } module.exports = exports['default'];