lib/graphql/query/literal_input.rb in graphql-1.4.1 vs lib/graphql/query/literal_input.rb in graphql-1.4.2

- old
+ new

@@ -1,102 +1,65 @@ # frozen_string_literal: true module GraphQL class Query # Turn query string values into something useful for query execution class LiteralInput - def self.coerce(type, value, variables) - if value.is_a?(Language::Nodes::VariableIdentifier) - variables[value.name] - elsif value.nil? + def self.coerce(type, ast_node, variables) + case ast_node + when nil nil + when Language::Nodes::VariableIdentifier + variables[ast_node.name] else - LiteralKindCoercers::STRATEGIES.fetch(type.kind).coerce(value, type, variables) + case type + when GraphQL::ScalarType + type.coerce_input(ast_node) + when GraphQL::EnumType + type.coerce_input(ast_node.name) + when GraphQL::NonNullType + LiteralInput.coerce(type.of_type, ast_node, variables) + when GraphQL::ListType + if ast_node.is_a?(Array) + ast_node.map { |element_ast| LiteralInput.coerce(type.of_type, element_ast, variables) } + else + [LiteralInput.coerce(type.of_type, ast_node, variables)] + end + when GraphQL::InputObjectType + from_arguments(ast_node.arguments, type.arguments, variables) + end end end def self.from_arguments(ast_arguments, argument_defns, variables) values_hash = {} - argument_defns.each do |arg_name, arg_defn| - ast_arg = ast_arguments.find { |ast_arg| ast_arg.name == arg_name } - arg_default_value = arg_defn.default_value - if ast_arg.nil? && arg_default_value.nil? - # If it wasn't in the document, - # and there's no provided default, - # then don't pass it to the resolve function - next - else - arg_value = nil + indexed_arguments = ast_arguments.each_with_object({}) { |a, memo| memo[a.name] = a } - if ast_arg - arg_value = coerce(arg_defn.type, ast_arg.value, variables) - end - - if arg_value.nil? - arg_value = arg_default_value - end - - values_hash[arg_name] = arg_value - end - end - GraphQL::Query::Arguments.new(values_hash, argument_definitions: argument_defns) - end - - module LiteralKindCoercers - module NonNullLiteral - def self.coerce(value, type, variables) - LiteralInput.coerce(type.of_type, value, variables) - end - end - - module ListLiteral - def self.coerce(value, type, variables) - if value.is_a?(Array) - value.map{ |element_ast| LiteralInput.coerce(type.of_type, element_ast, variables) } + argument_defns.each do |arg_name, arg_defn| + ast_arg = indexed_arguments[arg_name] + # First, check the argument in the AST. + # If the value is a variable, + # only add a value if the variable is actually present. + # Otherwise, coerce the value in the AST and add it. + if ast_arg + if ast_arg.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier) + if variables.key?(ast_arg.value.name) + values_hash[ast_arg.name] = coerce(arg_defn.type, ast_arg.value, variables) + end else - [LiteralInput.coerce(type.of_type, value, variables)] + values_hash[ast_arg.name] = coerce(arg_defn.type, ast_arg.value, variables) end end - end - module InputObjectLiteral - def self.coerce(value, type, variables) - hash = {} - value.arguments.each do |arg| - field_type = type.arguments[arg.name].type - hash[arg.name] = LiteralInput.coerce(field_type, arg.value, variables) - end - type.input_fields.each do |arg_name, arg_defn| - if hash[arg_name].nil? - value = LiteralInput.coerce(arg_defn.type, arg_defn.default_value, variables) - if !value.nil? - hash[arg_name] = value - end - end - end - Arguments.new(hash, argument_definitions: type.arguments) + # Then, the definition for a default value. + # If the definition has a default value and + # a value wasn't provided from the AST, + # then add the default value. + if arg_defn.default_value? && !values_hash.key?(arg_name) + values_hash[arg_name] = arg_defn.default_value end end - module EnumLiteral - def self.coerce(value, type, variables) - type.coerce_input(value.name) - end - end - - module ScalarLiteral - def self.coerce(value, type, variables) - type.coerce_input(value) - end - end - - STRATEGIES = { - TypeKinds::NON_NULL => NonNullLiteral, - TypeKinds::LIST => ListLiteral, - TypeKinds::INPUT_OBJECT => InputObjectLiteral, - TypeKinds::ENUM => EnumLiteral, - TypeKinds::SCALAR => ScalarLiteral, - } + GraphQL::Query::Arguments.new(values_hash, argument_definitions: argument_defns) end - private_constant :LiteralKindCoercers end end end