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