graphql
Version:
A Query Language and Runtime which can target any service.
121 lines (98 loc) • 3.79 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 _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['default'] = isValidLiteralValue;
var _languageKinds = require('../language/kinds');
var _typeDefinition = require('../type/definition');
var _keyMap = require('./keyMap');
var _keyMap2 = _interopRequireDefault(_keyMap);
var _isNullish = require('./isNullish');
var _isNullish2 = _interopRequireDefault(_isNullish);
/**
* Utility for validators which determines if a value literal AST is valid given
* an input type.
*
* Note that this only validates literal values, variables are assumed to
* provide values of the correct type.
*/
function isValidLiteralValue(_x, _x2) {
var _again = true;
_function: while (_again) {
var valueAST = _x,
type = _x2;
itemType = fields = fieldASTs = fieldASTMap = isMissingFields = undefined;
_again = false;
// A value can only be not provided if the type is nullable.
if (!valueAST) {
return !(type instanceof _typeDefinition.GraphQLNonNull);
}
// Unwrap non-null.
if (type instanceof _typeDefinition.GraphQLNonNull) {
_x = valueAST;
_x2 = type.ofType;
_again = true;
continue _function;
}
// This function only tests literals, and assumes variables will provide
// values of the correct type.
if (valueAST.kind === _languageKinds.VARIABLE) {
return true;
}
// Lists accept a non-list value as a list of one.
if (type instanceof _typeDefinition.GraphQLList) {
var itemType = type.ofType;
if (valueAST.kind === _languageKinds.ARRAY) {
return valueAST.values.every(function (itemAST) {
return isValidLiteralValue(itemAST, itemType);
});
} else {
_x = valueAST;
_x2 = itemType;
_again = true;
continue _function;
}
}
// Scalar/Enum input checks to ensure the type can coerce the value to
// a non-null value.
if (type instanceof _typeDefinition.GraphQLScalarType || type instanceof _typeDefinition.GraphQLEnumType) {
return !(0, _isNullish2['default'])(type.coerceLiteral(valueAST));
}
// Input objects check each defined field, ensuring it is of the correct
// type and provided if non-nullable.
if (type instanceof _typeDefinition.GraphQLInputObjectType) {
var fields = type.getFields();
if (valueAST.kind !== _languageKinds.OBJECT) {
return false;
}
var fieldASTs = valueAST.fields;
var fieldASTMap = (0, _keyMap2['default'])(fieldASTs, function (field) {
return field.name.value;
});
var isMissingFields = _Object$keys(fields).some(function (fieldName) {
return !fieldASTMap[fieldName] && fields[fieldName].type instanceof _typeDefinition.GraphQLNonNull;
});
if (isMissingFields) {
return false;
}
return fieldASTs.every(function (fieldAST) {
return fields[fieldAST.name.value] && isValidLiteralValue(fieldAST.value, fields[fieldAST.name.value].type);
});
}
// Any other kind of type is not an input type, and a literal cannot be used.
return false;
}
}
module.exports = exports['default'];