graphql 1.2.6 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql.rb +3 -1
- data/lib/graphql/analysis.rb +1 -0
- data/lib/graphql/analysis/analyze_query.rb +1 -0
- data/lib/graphql/analysis/field_usage.rb +1 -0
- data/lib/graphql/analysis/max_query_complexity.rb +1 -0
- data/lib/graphql/analysis/max_query_depth.rb +1 -0
- data/lib/graphql/analysis/query_complexity.rb +1 -0
- data/lib/graphql/analysis/query_depth.rb +1 -0
- data/lib/graphql/analysis/reducer_state.rb +1 -0
- data/lib/graphql/analysis_error.rb +1 -0
- data/lib/graphql/argument.rb +1 -0
- data/lib/graphql/base_type.rb +16 -7
- data/lib/graphql/boolean_type.rb +1 -0
- data/lib/graphql/compatibility.rb +2 -0
- data/lib/graphql/compatibility/execution_specification.rb +113 -192
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +53 -0
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +195 -0
- data/lib/graphql/compatibility/lazy_execution_specification.rb +186 -0
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +97 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +1 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +1 -0
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +1 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +1 -0
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/assign_argument.rb +1 -0
- data/lib/graphql/define/assign_connection.rb +1 -0
- data/lib/graphql/define/assign_enum_value.rb +1 -0
- data/lib/graphql/define/assign_global_id_field.rb +1 -0
- data/lib/graphql/define/assign_object_field.rb +1 -0
- data/lib/graphql/define/defined_object_proxy.rb +1 -0
- data/lib/graphql/define/instance_definable.rb +11 -12
- data/lib/graphql/define/non_null_with_bang.rb +1 -0
- data/lib/graphql/define/type_definer.rb +1 -0
- data/lib/graphql/directive.rb +1 -0
- data/lib/graphql/directive/deprecated_directive.rb +1 -0
- data/lib/graphql/directive/include_directive.rb +1 -0
- data/lib/graphql/directive/skip_directive.rb +1 -0
- data/lib/graphql/enum_type.rb +8 -1
- data/lib/graphql/execution.rb +5 -0
- data/lib/graphql/execution/directive_checks.rb +1 -0
- data/lib/graphql/execution/execute.rb +222 -0
- data/lib/graphql/execution/field_result.rb +52 -0
- data/lib/graphql/execution/lazy.rb +59 -0
- data/lib/graphql/execution/lazy/lazy_method_map.rb +38 -0
- data/lib/graphql/execution/lazy/resolve.rb +68 -0
- data/lib/graphql/execution/selection_result.rb +84 -0
- data/lib/graphql/execution/typecast.rb +4 -4
- data/lib/graphql/execution_error.rb +1 -0
- data/lib/graphql/field.rb +68 -18
- data/lib/graphql/field/resolve.rb +1 -0
- data/lib/graphql/float_type.rb +1 -0
- data/lib/graphql/id_type.rb +1 -0
- data/lib/graphql/input_object_type.rb +6 -0
- data/lib/graphql/int_type.rb +1 -0
- data/lib/graphql/interface_type.rb +6 -0
- data/lib/graphql/internal_representation.rb +2 -1
- data/lib/graphql/internal_representation/node.rb +2 -1
- data/lib/graphql/internal_representation/rewrite.rb +1 -0
- data/lib/graphql/internal_representation/selection.rb +85 -0
- data/lib/graphql/introspection.rb +1 -0
- data/lib/graphql/introspection/arguments_field.rb +1 -0
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/enum_values_field.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/fields_field.rb +1 -0
- data/lib/graphql/introspection/input_fields_field.rb +1 -0
- data/lib/graphql/introspection/input_value_type.rb +2 -1
- data/lib/graphql/introspection/interfaces_field.rb +1 -0
- data/lib/graphql/introspection/introspection_query.rb +1 -0
- data/lib/graphql/introspection/of_type_field.rb +1 -0
- data/lib/graphql/introspection/possible_types_field.rb +1 -0
- data/lib/graphql/introspection/schema_field.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +1 -0
- data/lib/graphql/introspection/type_by_name_field.rb +1 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/introspection/typename_field.rb +1 -0
- data/lib/graphql/invalid_null_error.rb +17 -7
- data/lib/graphql/language.rb +10 -0
- data/lib/graphql/language/comments.rb +2 -1
- data/lib/graphql/language/definition_slice.rb +1 -0
- data/lib/graphql/language/generation.rb +25 -24
- data/lib/graphql/language/nodes.rb +1 -0
- data/lib/graphql/language/token.rb +1 -0
- data/lib/graphql/language/visitor.rb +1 -0
- data/lib/graphql/list_type.rb +1 -0
- data/lib/graphql/non_null_type.rb +2 -1
- data/lib/graphql/object_type.rb +12 -0
- data/lib/graphql/query.rb +40 -43
- data/lib/graphql/query/arguments.rb +1 -0
- data/lib/graphql/query/context.rb +31 -7
- data/lib/graphql/query/executor.rb +8 -1
- data/lib/graphql/query/input_validation_result.rb +1 -0
- data/lib/graphql/query/literal_input.rb +1 -0
- data/lib/graphql/query/serial_execution.rb +3 -4
- data/lib/graphql/query/serial_execution/field_resolution.rb +15 -10
- data/lib/graphql/query/serial_execution/operation_resolution.rb +3 -5
- data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -5
- data/lib/graphql/query/serial_execution/value_resolution.rb +26 -11
- data/lib/graphql/query/variable_validation_error.rb +1 -0
- data/lib/graphql/query/variables.rb +1 -0
- data/lib/graphql/relay.rb +1 -0
- data/lib/graphql/relay/array_connection.rb +3 -2
- data/lib/graphql/relay/base_connection.rb +20 -8
- data/lib/graphql/relay/connection_field.rb +1 -0
- data/lib/graphql/relay/connection_resolve.rb +14 -1
- data/lib/graphql/relay/connection_type.rb +1 -0
- data/lib/graphql/relay/edge.rb +1 -0
- data/lib/graphql/relay/edge_type.rb +1 -0
- data/lib/graphql/relay/global_id_resolve.rb +1 -0
- data/lib/graphql/relay/mutation.rb +13 -0
- data/lib/graphql/relay/node.rb +1 -0
- data/lib/graphql/relay/page_info.rb +1 -0
- data/lib/graphql/relay/relation_connection.rb +3 -2
- data/lib/graphql/runtime_type_error.rb +4 -0
- data/lib/graphql/scalar_type.rb +2 -1
- data/lib/graphql/schema.rb +116 -26
- data/lib/graphql/schema/base_64_encoder.rb +14 -0
- data/lib/graphql/schema/build_from_definition.rb +4 -0
- data/lib/graphql/schema/catchall_middleware.rb +1 -0
- data/lib/graphql/schema/default_type_error.rb +15 -0
- data/lib/graphql/schema/instrumented_field_map.rb +1 -0
- data/lib/graphql/schema/invalid_type_error.rb +1 -0
- data/lib/graphql/schema/loader.rb +5 -1
- data/lib/graphql/schema/middleware_chain.rb +1 -0
- data/lib/graphql/schema/possible_types.rb +1 -0
- data/lib/graphql/schema/printer.rb +3 -2
- data/lib/graphql/schema/reduce_types.rb +1 -0
- data/lib/graphql/schema/rescue_middleware.rb +3 -2
- data/lib/graphql/schema/timeout_middleware.rb +1 -0
- data/lib/graphql/schema/type_expression.rb +1 -0
- data/lib/graphql/schema/type_map.rb +1 -0
- data/lib/graphql/schema/unique_within_type.rb +1 -0
- data/lib/graphql/schema/validation.rb +57 -1
- data/lib/graphql/schema/warden.rb +1 -0
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/arguments_validator.rb +1 -0
- data/lib/graphql/static_validation/literal_validator.rb +1 -0
- data/lib/graphql/static_validation/message.rb +1 -0
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -0
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -0
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +6 -3
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +1 -0
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -0
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +1 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -0
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -0
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -0
- data/lib/graphql/static_validation/type_stack.rb +1 -0
- data/lib/graphql/static_validation/validation_context.rb +2 -1
- data/lib/graphql/static_validation/validator.rb +2 -1
- data/lib/graphql/string_type.rb +1 -0
- data/lib/graphql/type_kinds.rb +1 -0
- data/lib/graphql/union_type.rb +13 -0
- data/lib/graphql/unresolved_type_error.rb +26 -5
- data/lib/graphql/version.rb +2 -1
- data/readme.md +1 -5
- data/spec/graphql/analysis/analyze_query_spec.rb +1 -0
- data/spec/graphql/analysis/field_usage_spec.rb +1 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +1 -0
- data/spec/graphql/analysis/max_query_depth_spec.rb +1 -0
- data/spec/graphql/analysis/query_complexity_spec.rb +1 -0
- data/spec/graphql/analysis/query_depth_spec.rb +1 -0
- data/spec/graphql/argument_spec.rb +1 -0
- data/spec/graphql/base_type_spec.rb +13 -0
- data/spec/graphql/boolean_type_spec.rb +1 -0
- data/spec/graphql/compatibility/execution_specification_spec.rb +1 -0
- data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +4 -0
- data/spec/graphql/compatibility/query_parser_specification_spec.rb +1 -0
- data/spec/graphql/compatibility/schema_parser_specification_spec.rb +1 -0
- data/spec/graphql/define/assign_argument_spec.rb +1 -0
- data/spec/graphql/define/instance_definable_spec.rb +1 -0
- data/spec/graphql/directive_spec.rb +1 -0
- data/spec/graphql/enum_type_spec.rb +10 -0
- data/spec/graphql/execution/execute_spec.rb +5 -0
- data/spec/graphql/execution/lazy_spec.rb +252 -0
- data/spec/graphql/execution/typecast_spec.rb +1 -0
- data/spec/graphql/execution_error_spec.rb +1 -0
- data/spec/graphql/field_spec.rb +17 -0
- data/spec/graphql/float_type_spec.rb +1 -0
- data/spec/graphql/id_type_spec.rb +1 -0
- data/spec/graphql/input_object_type_spec.rb +10 -0
- data/spec/graphql/int_type_spec.rb +1 -0
- data/spec/graphql/interface_type_spec.rb +10 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +1 -0
- data/spec/graphql/introspection/directive_type_spec.rb +1 -0
- data/spec/graphql/introspection/input_value_type_spec.rb +1 -0
- data/spec/graphql/introspection/introspection_query_spec.rb +1 -0
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/introspection/type_type_spec.rb +1 -0
- data/spec/graphql/language/definition_slice_spec.rb +1 -0
- data/spec/graphql/language/equality_spec.rb +1 -0
- data/spec/graphql/language/generation_spec.rb +1 -0
- data/spec/graphql/language/lexer_spec.rb +1 -0
- data/spec/graphql/language/nodes_spec.rb +1 -0
- data/spec/graphql/language/parser_spec.rb +1 -0
- data/spec/graphql/language/visitor_spec.rb +1 -0
- data/spec/graphql/list_type_spec.rb +1 -0
- data/spec/graphql/non_null_type_spec.rb +17 -0
- data/spec/graphql/object_type_spec.rb +19 -0
- data/spec/graphql/query/arguments_spec.rb +1 -0
- data/spec/graphql/query/context_spec.rb +1 -0
- data/spec/graphql/query/executor_spec.rb +1 -0
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -0
- data/spec/graphql/query/variables_spec.rb +1 -0
- data/spec/graphql/query_spec.rb +25 -0
- data/spec/graphql/relay/array_connection_spec.rb +1 -0
- data/spec/graphql/relay/base_connection_spec.rb +33 -4
- data/spec/graphql/relay/connection_field_spec.rb +1 -0
- data/spec/graphql/relay/connection_type_spec.rb +1 -0
- data/spec/graphql/relay/mutation_spec.rb +6 -0
- data/spec/graphql/relay/node_spec.rb +1 -0
- data/spec/graphql/relay/page_info_spec.rb +1 -0
- data/spec/graphql/relay/relation_connection_spec.rb +1 -0
- data/spec/graphql/scalar_type_spec.rb +1 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +9 -1
- data/spec/graphql/schema/catchall_middleware_spec.rb +1 -0
- data/spec/graphql/schema/loader_spec.rb +7 -0
- data/spec/graphql/schema/middleware_chain_spec.rb +1 -0
- data/spec/graphql/schema/printer_spec.rb +1 -0
- data/spec/graphql/schema/reduce_types_spec.rb +1 -0
- data/spec/graphql/schema/rescue_middleware_spec.rb +1 -0
- data/spec/graphql/schema/timeout_middleware_spec.rb +1 -0
- data/spec/graphql/schema/type_expression_spec.rb +1 -0
- data/spec/graphql/schema/unique_within_type_spec.rb +1 -0
- data/spec/graphql/schema/validation_spec.rb +55 -0
- data/spec/graphql/schema/warden_spec.rb +1 -0
- data/spec/graphql/schema_spec.rb +39 -0
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +515 -31
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +1 -0
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +1 -0
- data/spec/graphql/static_validation/type_stack_spec.rb +1 -0
- data/spec/graphql/static_validation/validator_spec.rb +1 -0
- data/spec/graphql/string_type_spec.rb +1 -0
- data/spec/graphql/union_type_spec.rb +11 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/dairy_app.rb +1 -0
- data/spec/support/dairy_data.rb +1 -0
- data/spec/support/minimum_input_object.rb +1 -0
- data/spec/support/star_wars_data.rb +1 -0
- data/spec/support/star_wars_schema.rb +30 -7
- data/spec/support/static_validation_helpers.rb +1 -0
- metadata +24 -5
- data/lib/graphql/internal_representation/selections.rb +0 -41
data/lib/graphql/define.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
module Define
|
3
4
|
# This module provides the `.define { ... }` API for
|
@@ -94,15 +95,19 @@ module GraphQL
|
|
94
95
|
nil
|
95
96
|
end
|
96
97
|
|
97
|
-
#
|
98
|
-
#
|
98
|
+
# Shallow-copy this object, then apply new definitions to the copy.
|
99
|
+
# @see {#define} for arguments
|
99
100
|
# @return [InstanceDefinable] A new instance, with any extended definitions
|
100
101
|
def redefine(**kwargs, &block)
|
101
102
|
ensure_defined
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
103
|
+
new_inst = self.dup
|
104
|
+
new_inst.define(**kwargs, &block)
|
105
|
+
new_inst
|
106
|
+
end
|
107
|
+
|
108
|
+
def initialize_copy(other)
|
109
|
+
super
|
110
|
+
@metadata = other.metadata.dup
|
106
111
|
end
|
107
112
|
|
108
113
|
private
|
@@ -125,16 +130,10 @@ module GraphQL
|
|
125
130
|
if defn.define_proc
|
126
131
|
defn_proxy.instance_eval(&defn.define_proc)
|
127
132
|
end
|
128
|
-
|
129
|
-
applied_definitions << defn
|
130
133
|
end
|
131
134
|
nil
|
132
135
|
end
|
133
136
|
|
134
|
-
def applied_definitions
|
135
|
-
@applied_definitions ||= []
|
136
|
-
end
|
137
|
-
|
138
137
|
class Definition
|
139
138
|
attr_reader :define_keywords, :define_proc
|
140
139
|
def initialize(define_keywords, define_proc)
|
data/lib/graphql/directive.rb
CHANGED
data/lib/graphql/enum_type.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module GraphQL
|
2
3
|
# Represents a collection of related values.
|
3
4
|
# By convention, enum names are `SCREAMING_CASE_NAMES`,
|
@@ -78,6 +79,12 @@ module GraphQL
|
|
78
79
|
@values_by_name = {}
|
79
80
|
end
|
80
81
|
|
82
|
+
def initialize_copy(other)
|
83
|
+
super
|
84
|
+
self.values = other.values.values
|
85
|
+
end
|
86
|
+
|
87
|
+
|
81
88
|
# @param new_values [Array<EnumValue>] The set of values contained in this type
|
82
89
|
def values=(new_values)
|
83
90
|
@values_by_name = {}
|
@@ -104,7 +111,7 @@ module GraphQL
|
|
104
111
|
matching_value = allowed_values.find { |v| v.name == value_name }
|
105
112
|
|
106
113
|
if matching_value.nil?
|
107
|
-
result.add_problem("Expected #{
|
114
|
+
result.add_problem("Expected #{GraphQL::Language.serialize(value_name)} to be one of: #{allowed_values.map(&:name).join(', ')}")
|
108
115
|
end
|
109
116
|
|
110
117
|
result
|
data/lib/graphql/execution.rb
CHANGED
@@ -1,2 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "graphql/execution/directive_checks"
|
3
|
+
require "graphql/execution/execute"
|
4
|
+
require "graphql/execution/field_result"
|
5
|
+
require "graphql/execution/lazy"
|
6
|
+
require "graphql/execution/selection_result"
|
2
7
|
require "graphql/execution/typecast"
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Execution
|
4
|
+
# A valid execution strategy
|
5
|
+
class Execute
|
6
|
+
PROPAGATE_NULL = :__graphql_propagate_null__
|
7
|
+
|
8
|
+
def execute(ast_operation, root_type, query)
|
9
|
+
result = resolve_selection(
|
10
|
+
query.root_value,
|
11
|
+
root_type,
|
12
|
+
query.irep_selection,
|
13
|
+
query.context,
|
14
|
+
mutation: query.mutation?
|
15
|
+
)
|
16
|
+
|
17
|
+
GraphQL::Execution::Lazy.resolve(result)
|
18
|
+
|
19
|
+
result.to_h
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def resolve_selection(object, current_type, selection, query_ctx, mutation: false )
|
25
|
+
query = query_ctx.query
|
26
|
+
|
27
|
+
selection_result = SelectionResult.new
|
28
|
+
|
29
|
+
selection.each_selection(type: current_type) do |name, subselection|
|
30
|
+
field = query.get_field(current_type, subselection.definition_name)
|
31
|
+
field_result = resolve_field(
|
32
|
+
selection_result,
|
33
|
+
subselection,
|
34
|
+
current_type,
|
35
|
+
field,
|
36
|
+
object,
|
37
|
+
query_ctx
|
38
|
+
)
|
39
|
+
|
40
|
+
if mutation
|
41
|
+
GraphQL::Execution::Lazy.resolve(field_result)
|
42
|
+
end
|
43
|
+
|
44
|
+
selection_result.set(name, field_result)
|
45
|
+
end
|
46
|
+
|
47
|
+
selection_result
|
48
|
+
end
|
49
|
+
|
50
|
+
def resolve_field(owner, selection, parent_type, field, object, query_ctx)
|
51
|
+
query = query_ctx.query
|
52
|
+
field_ctx = query_ctx.spawn(
|
53
|
+
parent_type: parent_type,
|
54
|
+
field: field,
|
55
|
+
key: selection.name,
|
56
|
+
selection: selection,
|
57
|
+
)
|
58
|
+
|
59
|
+
arguments = query.arguments_for(selection.irep_node, field)
|
60
|
+
middlewares = query.schema.middleware
|
61
|
+
resolve_arguments = [parent_type, object, field, arguments, field_ctx]
|
62
|
+
|
63
|
+
raw_value = begin
|
64
|
+
# only run a middleware chain if there are any middleware
|
65
|
+
if middlewares.any?
|
66
|
+
chain = GraphQL::Schema::MiddlewareChain.new(
|
67
|
+
steps: middlewares + [FieldResolveStep],
|
68
|
+
arguments: resolve_arguments
|
69
|
+
)
|
70
|
+
chain.call
|
71
|
+
else
|
72
|
+
FieldResolveStep.call(*resolve_arguments)
|
73
|
+
end
|
74
|
+
rescue GraphQL::ExecutionError => err
|
75
|
+
err
|
76
|
+
end
|
77
|
+
|
78
|
+
result = if query.schema.lazy?(raw_value)
|
79
|
+
field.prepare_lazy(raw_value, arguments, field_ctx).then { |inner_value|
|
80
|
+
continue_resolve_field(selection, parent_type, field, inner_value, field_ctx)
|
81
|
+
}
|
82
|
+
elsif raw_value.is_a?(GraphQL::Execution::Lazy)
|
83
|
+
# It came from a connection resolve, assume it was already instrumented
|
84
|
+
raw_value.then { |inner_value|
|
85
|
+
continue_resolve_field(selection, parent_type, field, inner_value, field_ctx)
|
86
|
+
}
|
87
|
+
else
|
88
|
+
continue_resolve_field(selection, parent_type, field, raw_value, field_ctx)
|
89
|
+
end
|
90
|
+
|
91
|
+
FieldResult.new(
|
92
|
+
owner: owner,
|
93
|
+
field: field,
|
94
|
+
value: result,
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def continue_resolve_field(selection, parent_type, field, raw_value, field_ctx)
|
99
|
+
query = field_ctx.query
|
100
|
+
|
101
|
+
case raw_value
|
102
|
+
when GraphQL::ExecutionError
|
103
|
+
raw_value.ast_node = field_ctx.ast_node
|
104
|
+
raw_value.path = field_ctx.path
|
105
|
+
query.context.errors.push(raw_value)
|
106
|
+
when Array
|
107
|
+
list_errors = raw_value.each_with_index.select { |value, _| value.is_a?(GraphQL::ExecutionError) }
|
108
|
+
if list_errors.any?
|
109
|
+
list_errors.each do |error, index|
|
110
|
+
error.ast_node = field_ctx.ast_node
|
111
|
+
error.path = field_ctx.path + [index]
|
112
|
+
query.context.errors.push(error)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
resolve_value(
|
118
|
+
parent_type,
|
119
|
+
field,
|
120
|
+
field.type,
|
121
|
+
raw_value,
|
122
|
+
selection,
|
123
|
+
field_ctx,
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
127
|
+
def resolve_value(parent_type, field_defn, field_type, value, selection, field_ctx)
|
128
|
+
if value.nil?
|
129
|
+
if field_type.kind.non_null?
|
130
|
+
type_error = GraphQL::InvalidNullError.new(parent_type, field_defn, value)
|
131
|
+
field_ctx.schema.type_error(type_error, field_ctx)
|
132
|
+
PROPAGATE_NULL
|
133
|
+
else
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
elsif value.is_a?(GraphQL::ExecutionError)
|
137
|
+
if field_type.kind.non_null?
|
138
|
+
PROPAGATE_NULL
|
139
|
+
else
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
else
|
143
|
+
case field_type.kind
|
144
|
+
when GraphQL::TypeKinds::SCALAR
|
145
|
+
field_type.coerce_result(value)
|
146
|
+
when GraphQL::TypeKinds::ENUM
|
147
|
+
field_type.coerce_result(value, field_ctx.query.warden)
|
148
|
+
when GraphQL::TypeKinds::LIST
|
149
|
+
wrapped_type = field_type.of_type
|
150
|
+
i = 0
|
151
|
+
result = []
|
152
|
+
value.each do |inner_value|
|
153
|
+
inner_ctx = field_ctx.spawn(
|
154
|
+
key: i,
|
155
|
+
selection: selection,
|
156
|
+
parent_type: parent_type,
|
157
|
+
field: field_defn,
|
158
|
+
)
|
159
|
+
|
160
|
+
result << resolve_value(
|
161
|
+
parent_type,
|
162
|
+
field_defn,
|
163
|
+
wrapped_type,
|
164
|
+
inner_value,
|
165
|
+
selection,
|
166
|
+
inner_ctx,
|
167
|
+
)
|
168
|
+
i += 1
|
169
|
+
end
|
170
|
+
result
|
171
|
+
when GraphQL::TypeKinds::NON_NULL
|
172
|
+
wrapped_type = field_type.of_type
|
173
|
+
inner_value = resolve_value(
|
174
|
+
parent_type,
|
175
|
+
field_defn,
|
176
|
+
wrapped_type,
|
177
|
+
value,
|
178
|
+
selection,
|
179
|
+
field_ctx,
|
180
|
+
)
|
181
|
+
when GraphQL::TypeKinds::OBJECT
|
182
|
+
resolve_selection(
|
183
|
+
value,
|
184
|
+
field_type,
|
185
|
+
selection,
|
186
|
+
field_ctx
|
187
|
+
)
|
188
|
+
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
189
|
+
query = field_ctx.query
|
190
|
+
resolved_type = query.resolve_type(value)
|
191
|
+
possible_types = query.possible_types(field_type)
|
192
|
+
|
193
|
+
if !possible_types.include?(resolved_type)
|
194
|
+
type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
|
195
|
+
field_ctx.schema.type_error(type_error, field_ctx)
|
196
|
+
PROPAGATE_NULL
|
197
|
+
else
|
198
|
+
resolve_value(
|
199
|
+
parent_type,
|
200
|
+
field_defn,
|
201
|
+
resolved_type,
|
202
|
+
value,
|
203
|
+
selection,
|
204
|
+
field_ctx,
|
205
|
+
)
|
206
|
+
end
|
207
|
+
else
|
208
|
+
raise("Unknown type kind: #{field_type.kind}")
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# A `.call`-able suitable to be the last step in a middleware chain
|
214
|
+
module FieldResolveStep
|
215
|
+
# Execute the field's resolve method
|
216
|
+
def self.call(_parent_type, parent_object, field_definition, field_args, context, _next = nil)
|
217
|
+
field_definition.resolve(parent_object, field_args, context)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Execution
|
4
|
+
# This is one key-value pair in a GraphQL response.
|
5
|
+
class FieldResult
|
6
|
+
# @return [Any, Lazy] the GraphQL-ready response value, or a {Lazy} instance
|
7
|
+
attr_reader :value
|
8
|
+
|
9
|
+
# @return [GraphQL::Field] The field which resolved this value
|
10
|
+
attr_reader :field
|
11
|
+
|
12
|
+
# @return [SelectionResult] The result object that this field belongs to
|
13
|
+
attr_reader :owner
|
14
|
+
|
15
|
+
def initialize(field:, value:, owner:)
|
16
|
+
@field = field
|
17
|
+
@owner = owner
|
18
|
+
self.value = value
|
19
|
+
end
|
20
|
+
|
21
|
+
# Set a new value for this field in the response.
|
22
|
+
# It may be updated after resolving a {Lazy}.
|
23
|
+
# If it is {Execute::PROPAGATE_NULL}, tell the owner to propagate null.
|
24
|
+
# If the value is a {SelectionResult}, make a link with it, and if it's already null,
|
25
|
+
# propagate the null as needed.
|
26
|
+
# @param new_value [Any] The GraphQL-ready value
|
27
|
+
def value=(new_value)
|
28
|
+
if new_value.is_a?(SelectionResult)
|
29
|
+
if new_value.invalid_null?
|
30
|
+
new_value = GraphQL::Execution::Execute::PROPAGATE_NULL
|
31
|
+
else
|
32
|
+
new_value.owner = self
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if new_value == GraphQL::Execution::Execute::PROPAGATE_NULL
|
37
|
+
if field.type.kind.non_null?
|
38
|
+
@owner.propagate_null
|
39
|
+
else
|
40
|
+
@value = nil
|
41
|
+
end
|
42
|
+
else
|
43
|
+
@value = new_value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
"#<FieldResult #{value.inspect} (#{field.type})>"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|