graphql
Version:
A Query Language and Runtime which can target any service.
88 lines (74 loc) • 2.97 kB
JavaScript
/* @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.
*/
;
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'];