graphql
Version:
A Query Language and Runtime which can target any service.
308 lines (259 loc) • 9.38 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.
*/
'use strict';
var _Object$defineProperty = require('babel-runtime/core-js/object/define-property')['default'];
var _Object$keys = require('babel-runtime/core-js/object/keys')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
_Object$defineProperty(exports, '__esModule', {
value: true
});
exports.getVariableValues = getVariableValues;
exports.getArgumentValues = getArgumentValues;
exports.getDirectiveValue = getDirectiveValue;
var _error = require('../error');
var _utilsKeyMap = require('../utils/keyMap');
var _utilsKeyMap2 = _interopRequireDefault(_utilsKeyMap);
var _utilsTypeFromAST = require('../utils/typeFromAST');
var _utilsTypeFromAST2 = _interopRequireDefault(_utilsTypeFromAST);
var _utilsIsNullish = require('../utils/isNullish');
var _utilsIsNullish2 = _interopRequireDefault(_utilsIsNullish);
var _utilsFind = require('../utils/find');
var _utilsFind2 = _interopRequireDefault(_utilsFind);
var _language = require('../language');
var _languagePrinter = require('../language/printer');
var _typeDefinition = require('../type/definition');
/**
* Prepares an object map of variables of the correct type based on the provided
* variable definitions and arbitrary input. If the input cannot be coerced
* to match the variable definitions, a GraphQLError will be thrown.
*/
function getVariableValues(schema, definitionASTs, inputs) {
return definitionASTs.reduce(function (values, defAST) {
var varName = defAST.variable.name.value;
values[varName] = getVariableValue(schema, defAST, inputs[varName]);
return values;
}, {});
}
/**
* Prepares an object map of argument values given a list of argument
* definitions and list of argument AST nodes.
*/
function getArgumentValues(argDefs, argASTs, variables) {
if (!argDefs || argDefs.length === 0) {
return null;
}
var argASTMap = argASTs ? (0, _utilsKeyMap2['default'])(argASTs, function (arg) {
return arg.name.value;
}) : {};
return argDefs.reduce(function (result, argDef) {
var name = argDef.name;
var valueAST = argASTMap[name] && argASTMap[name].value;
result[name] = coerceValueAST(argDef.type, valueAST, variables);
return result;
}, {});
}
function getDirectiveValue(directiveDef, directives, variables) {
var directiveAST = directives && (0, _utilsFind2['default'])(directives, function (directive) {
return directive.name.value === directiveDef.name;
});
if (directiveAST) {
if (!directiveDef.type) {
return null;
}
return coerceValueAST(directiveDef.type, directiveAST.value, variables);
}
}
/**
* Given a variable definition, and any value of input, return a value which
* adheres to the variable definition, or throw an error.
*/
function getVariableValue(schema, definitionAST, input) {
var type = (0, _utilsTypeFromAST2['default'])(schema, definitionAST.type);
if (!type) {
return null;
}
if (isValidValue(type, input)) {
if ((0, _utilsIsNullish2['default'])(input)) {
var defaultValue = definitionAST.defaultValue;
if (defaultValue) {
return coerceValueAST(type, defaultValue);
}
}
return coerceValue(type, input);
}
throw new _error.GraphQLError('Variable $' + definitionAST.variable.name.value + ' expected value of type ' + ('' + (0, _languagePrinter.print)(definitionAST.type) + ' but got: ' + JSON.stringify(input) + '.'), [definitionAST]);
}
/**
* Given a type and any value, return true if that value is valid.
*/
function isValidValue(_x, _x2) {
var _again = true;
_function: while (_again) {
var type = _x,
value = _x2;
itemType = fields = undefined;
_again = false;
if (type instanceof _typeDefinition.GraphQLNonNull) {
if ((0, _utilsIsNullish2['default'])(value)) {
return false;
}
_x = type.ofType;
_x2 = value;
_again = true;
continue _function;
}
if ((0, _utilsIsNullish2['default'])(value)) {
return true;
}
if (type instanceof _typeDefinition.GraphQLList) {
var itemType = type.ofType;
if (Array.isArray(value)) {
return value.every(function (item) {
return isValidValue(itemType, item);
});
} else {
_x = itemType;
_x2 = value;
_again = true;
continue _function;
}
}
if (type instanceof _typeDefinition.GraphQLInputObjectType) {
var fields = type.getFields();
return _Object$keys(fields).every(function (fieldName) {
return isValidValue(fields[fieldName].type, value[fieldName]);
});
}
if (type instanceof _typeDefinition.GraphQLScalarType || type instanceof _typeDefinition.GraphQLEnumType) {
return !(0, _utilsIsNullish2['default'])(type.coerce(value));
}
return false;
}
}
/**
* Given a type and any value, return a runtime value coerced to match the type.
*/
function coerceValue(_x3, _x4) {
var _again2 = true;
_function2: while (_again2) {
var type = _x3,
value = _x4;
itemType = fields = coerced = undefined;
_again2 = false;
if (type instanceof _typeDefinition.GraphQLNonNull) {
// Note: we're not checking that the result of coerceValue is non-null.
// We only call this function after calling isValidValue.
_x3 = type.ofType;
_x4 = value;
_again2 = true;
continue _function2;
}
if ((0, _utilsIsNullish2['default'])(value)) {
return null;
}
if (type instanceof _typeDefinition.GraphQLList) {
var itemType = type.ofType;
// TODO: support iterable input
if (Array.isArray(value)) {
return value.map(function (item) {
return coerceValue(itemType, item);
});
} else {
return [coerceValue(itemType, value)];
}
}
if (type instanceof _typeDefinition.GraphQLInputObjectType) {
var fields = type.getFields();
return _Object$keys(fields).reduce(function (obj, fieldName) {
var field = fields[fieldName];
var fieldValue = coerceValue(field.type, value[fieldName]);
obj[fieldName] = fieldValue === null ? field.defaultValue : fieldValue;
return obj;
}, {});
}
if (type instanceof _typeDefinition.GraphQLScalarType || type instanceof _typeDefinition.GraphQLEnumType) {
var coerced = type.coerce(value);
if (!(0, _utilsIsNullish2['default'])(coerced)) {
return coerced;
}
}
return null;
}
}
/**
* Given a type and a value AST node known to match this type, build a
* runtime value.
*/
function coerceValueAST(_x5, _x6, _x7) {
var _again3 = true;
_function3: while (_again3) {
var type = _x5,
valueAST = _x6,
variables = _x7;
variableName = itemType = fields = fieldASTs = coerced = undefined;
_again3 = false;
if (type instanceof _typeDefinition.GraphQLNonNull) {
// Note: we're not checking that the result of coerceValueAST is non-null.
// We're assuming that this query has been validated and the value used
// here is of the correct type.
_x5 = type.ofType;
_x6 = valueAST;
_x7 = variables;
_again3 = true;
continue _function3;
}
if (!valueAST) {
return null;
}
if (valueAST.kind === _language.Kind.VARIABLE) {
var variableName = valueAST.name.value;
if (!variables || !variables.hasOwnProperty(variableName)) {
return null;
}
// Note: we're not doing any checking that this variable is correct. We're
// assuming that this query has been validated and the variable usage here
// is of the correct type.
return variables[variableName];
}
if (type instanceof _typeDefinition.GraphQLList) {
var itemType = type.ofType;
if (valueAST.kind === _language.Kind.ARRAY) {
return valueAST.values.map(function (itemAST) {
return coerceValueAST(itemType, itemAST, variables);
});
} else {
return [coerceValueAST(itemType, valueAST, variables)];
}
}
if (type instanceof _typeDefinition.GraphQLInputObjectType) {
var fields = type.getFields();
if (valueAST.kind !== _language.Kind.OBJECT) {
return null;
}
var fieldASTs = (0, _utilsKeyMap2['default'])(valueAST.fields, function (field) {
return field.name.value;
});
return _Object$keys(fields).reduce(function (obj, fieldName) {
var field = fields[fieldName];
var fieldAST = fieldASTs[fieldName];
var fieldValue = coerceValueAST(field.type, fieldAST && fieldAST.value, variables);
obj[fieldName] = fieldValue === null ? field.defaultValue : fieldValue;
return obj;
}, {});
}
if (type instanceof _typeDefinition.GraphQLScalarType || type instanceof _typeDefinition.GraphQLEnumType) {
var coerced = type.coerceLiteral(valueAST);
if (!(0, _utilsIsNullish2['default'])(coerced)) {
return coerced;
}
}
return null;
}
}