UNPKG

graphql

Version:

A Query Language and Runtime which can target any service.

112 lines (94 loc) 3.68 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'] = VariablesInAllowedPosition; var _utilsTypeFromAST = require('../../utils/typeFromAST'); var _utilsTypeFromAST2 = _interopRequireDefault(_utilsTypeFromAST); var _error = require('../../error'); var _typeDefinition = require('../../type/definition'); var _errors = require('../errors'); /** * Variables passed to field arguments conform to type */ function VariablesInAllowedPosition(context) { var varDefMap = {}; var visitedFragmentNames = {}; return { // Visit FragmentDefinition after visiting FragmentSpread visitSpreadFragments: true, OperationDefinition: function OperationDefinition() { varDefMap = {}; visitedFragmentNames = {}; }, VariableDefinition: function VariableDefinition(varDefAST) { varDefMap[varDefAST.variable.name.value] = varDefAST; }, FragmentSpread: function FragmentSpread(spreadAST) { // Only visit fragments of a particular name once per operation if (visitedFragmentNames[spreadAST.name.value]) { return false; } visitedFragmentNames[spreadAST.name.value] = true; }, Variable: function Variable(variableAST) { var varName = variableAST.name.value; var varDef = varDefMap[varName]; var varType = varDef && (0, _utilsTypeFromAST2['default'])(context.getSchema(), varDef.type); var inputType = context.getInputType(); if (varType && inputType && !varTypeAllowedForType(effectiveType(varType, varDef), inputType)) { return new _error.GraphQLError((0, _errors.badVarPosMessage)(varName, varType, inputType), [variableAST]); } } }; } // If a variable definition has a default value, it's effectively non-null. function effectiveType(varType, varDef) { return !varDef.defaultValue || varType instanceof _typeDefinition.GraphQLNonNull ? varType : new _typeDefinition.GraphQLNonNull(varType); } // A var type is allowed if it is the same or more strict than the expected // type. It can be more strict if the variable type is non-null when the // expected type is nullable. If both are list types, the variable item type can // be more strict than the expected item type. function varTypeAllowedForType(_x, _x2) { var _again = true; _function: while (_again) { var varType = _x, expectedType = _x2; _again = false; if (expectedType instanceof _typeDefinition.GraphQLNonNull) { if (varType instanceof _typeDefinition.GraphQLNonNull) { _x = varType.ofType; _x2 = expectedType.ofType; _again = true; continue _function; } return false; } if (varType instanceof _typeDefinition.GraphQLNonNull) { _x = varType.ofType; _x2 = expectedType; _again = true; continue _function; } if (varType instanceof _typeDefinition.GraphQLList && expectedType instanceof _typeDefinition.GraphQLList) { _x = varType.ofType; _x2 = expectedType.ofType; _again = true; continue _function; } return varType === expectedType; } } module.exports = exports['default'];