graphql 1.13.17 → 2.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +1 -1
- data/lib/generators/graphql/relay.rb +3 -17
- data/lib/generators/graphql/templates/schema.erb +3 -0
- data/lib/graphql/analysis/ast/field_usage.rb +3 -1
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
- data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +43 -36
- data/lib/graphql/analysis/ast.rb +2 -12
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +2 -20
- data/lib/graphql/backtrace/tracer.rb +2 -3
- data/lib/graphql/backtrace.rb +2 -8
- data/lib/graphql/dataloader/null_dataloader.rb +3 -1
- data/lib/graphql/dataloader/source.rb +9 -0
- data/lib/graphql/dataloader.rb +4 -1
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +12 -82
- data/lib/graphql/execution/interpreter/resolve.rb +26 -0
- data/lib/graphql/execution/interpreter/runtime.rb +159 -120
- data/lib/graphql/execution/interpreter.rb +187 -78
- data/lib/graphql/execution/lazy.rb +7 -21
- data/lib/graphql/execution/lookahead.rb +44 -40
- data/lib/graphql/execution/multiplex.rb +3 -174
- data/lib/graphql/execution.rb +11 -4
- data/lib/graphql/introspection/directive_type.rb +2 -2
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +13 -6
- data/lib/graphql/introspection.rb +4 -3
- data/lib/graphql/language/document_from_schema_definition.rb +18 -35
- data/lib/graphql/language/lexer.rb +216 -1488
- data/lib/graphql/language/nodes.rb +65 -39
- data/lib/graphql/language/parser.rb +376 -364
- data/lib/graphql/language/parser.y +49 -44
- data/lib/graphql/language/printer.rb +37 -21
- data/lib/graphql/language/visitor.rb +191 -83
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/array_connection.rb +4 -2
- data/lib/graphql/pagination/connection.rb +31 -4
- data/lib/graphql/pagination/connections.rb +3 -28
- data/lib/graphql/pagination/relation_connection.rb +2 -0
- data/lib/graphql/query/context.rb +155 -196
- data/lib/graphql/query/input_validation_result.rb +1 -1
- data/lib/graphql/query/null_context.rb +0 -3
- data/lib/graphql/query/validation_pipeline.rb +10 -34
- data/lib/graphql/query/variables.rb +7 -20
- data/lib/graphql/query.rb +32 -42
- data/lib/graphql/railtie.rb +0 -104
- data/lib/graphql/rake_task/validate.rb +1 -1
- data/lib/graphql/rake_task.rb +29 -1
- data/lib/graphql/relay/range_add.rb +9 -20
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/schema/addition.rb +7 -9
- data/lib/graphql/schema/argument.rb +36 -43
- data/lib/graphql/schema/build_from_definition.rb +32 -18
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +12 -23
- data/lib/graphql/schema/enum.rb +28 -39
- data/lib/graphql/schema/enum_value.rb +5 -25
- data/lib/graphql/schema/field/connection_extension.rb +4 -0
- data/lib/graphql/schema/field.rb +237 -339
- data/lib/graphql/schema/input_object.rb +56 -67
- data/lib/graphql/schema/interface.rb +0 -35
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +8 -2
- data/lib/graphql/schema/list.rb +0 -6
- data/lib/graphql/schema/loader.rb +1 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
- data/lib/graphql/schema/member/build_type.rb +5 -7
- data/lib/graphql/schema/member/has_arguments.rb +146 -55
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +81 -59
- data/lib/graphql/schema/member/has_fields.rb +17 -4
- data/lib/graphql/schema/member/has_interfaces.rb +49 -10
- data/lib/graphql/schema/member/has_validators.rb +31 -5
- data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/member/validates_input.rb +1 -1
- data/lib/graphql/schema/member.rb +0 -6
- data/lib/graphql/schema/mutation.rb +0 -9
- data/lib/graphql/schema/non_null.rb +1 -7
- data/lib/graphql/schema/object.rb +15 -52
- data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
- data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
- data/lib/graphql/schema/resolver.rb +41 -42
- data/lib/graphql/schema/scalar.rb +7 -22
- data/lib/graphql/schema/subscription.rb +0 -7
- data/lib/graphql/schema/timeout.rb +24 -28
- data/lib/graphql/schema/type_membership.rb +3 -0
- data/lib/graphql/schema/union.rb +10 -17
- data/lib/graphql/schema/warden.rb +34 -8
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +241 -973
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/base_visitor.rb +4 -21
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
- data/lib/graphql/static_validation/error.rb +2 -2
- data/lib/graphql/static_validation/literal_validator.rb +19 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
- data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
- data/lib/graphql/static_validation/validator.rb +3 -25
- data/lib/graphql/static_validation.rb +0 -2
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +3 -8
- data/lib/graphql/subscriptions/instrumentation.rb +0 -51
- data/lib/graphql/subscriptions.rb +32 -20
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appsignal_trace.rb +71 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +41 -0
- data/lib/graphql/tracing/platform_trace.rb +107 -0
- data/lib/graphql/tracing/platform_tracing.rb +26 -40
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing.rb +136 -40
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/iso_8601_date.rb +4 -1
- data/lib/graphql/types/iso_8601_date_time.rb +4 -0
- data/lib/graphql/types/relay/base_connection.rb +16 -6
- data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
- data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
- data/lib/graphql/types/relay/node_behaviors.rb +12 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -3
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +13 -74
- metadata +30 -133
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- data/lib/graphql/base_type.rb +0 -232
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -255
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -55
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -133
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/instrumentation.rb +0 -92
- data/lib/graphql/execution/lazy/resolve.rb +0 -91
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -226
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/language/lexer.rl +0 -260
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- data/lib/graphql/query/literal_input.rb +0 -136
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -54
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -39
- data/lib/graphql/relay/global_id_resolve.rb +0 -17
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -17
- data/lib/graphql/schema/member/accepts_definition.rb +0 -164
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
- data/lib/graphql/schema/member/instrumentation.rb +0 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/default_relay.rb +0 -31
- data/lib/graphql/types/relay/node_field.rb +0 -24
- data/lib/graphql/types/relay/nodes_field.rb +0 -43
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- data/lib/graphql/upgrader/schema.rb +0 -38
@@ -7,14 +7,6 @@ module GraphQL
|
|
7
7
|
class ActiveRecordRelationConnection < Pagination::RelationConnection
|
8
8
|
private
|
9
9
|
|
10
|
-
def relation_larger_than(relation, initial_offset, size)
|
11
|
-
if already_loaded?(relation)
|
12
|
-
(relation.size + initial_offset) > size
|
13
|
-
else
|
14
|
-
set_offset(sliced_nodes, initial_offset + size).exists?
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
10
|
def relation_count(relation)
|
19
11
|
int_or_hash = if already_loaded?(relation)
|
20
12
|
relation.size
|
@@ -35,9 +35,11 @@ module GraphQL
|
|
35
35
|
def load_nodes
|
36
36
|
@nodes ||= begin
|
37
37
|
sliced_nodes = if before && after
|
38
|
-
|
38
|
+
end_idx = index_from_cursor(before)-1
|
39
|
+
end_idx < 0 ? [] : items[index_from_cursor(after)..end_idx] || []
|
39
40
|
elsif before
|
40
|
-
|
41
|
+
end_idx = index_from_cursor(before)-2
|
42
|
+
end_idx < 0 ? [] : items[0..end_idx] || []
|
41
43
|
elsif after
|
42
44
|
items[index_from_cursor(after)..-1] || []
|
43
45
|
else
|
@@ -56,8 +56,9 @@ module GraphQL
|
|
56
56
|
# @param last [Integer, nil] Limit parameter from the client, if provided
|
57
57
|
# @param before [String, nil] A cursor for pagination, if the client provided one.
|
58
58
|
# @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
|
59
|
-
# @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given.
|
60
|
-
|
59
|
+
# @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
|
60
|
+
# @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
|
61
|
+
def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: :not_given, default_page_size: :not_given, last: nil, before: nil, edge_class: nil, arguments: nil)
|
61
62
|
@items = items
|
62
63
|
@parent = parent
|
63
64
|
@context = context
|
@@ -76,6 +77,12 @@ module GraphQL
|
|
76
77
|
else
|
77
78
|
max_page_size
|
78
79
|
end
|
80
|
+
@has_default_page_size_override = default_page_size != :not_given
|
81
|
+
@default_page_size = if default_page_size == :not_given
|
82
|
+
nil
|
83
|
+
else
|
84
|
+
default_page_size
|
85
|
+
end
|
79
86
|
end
|
80
87
|
|
81
88
|
def max_page_size=(new_value)
|
@@ -95,16 +102,36 @@ module GraphQL
|
|
95
102
|
@has_max_page_size_override
|
96
103
|
end
|
97
104
|
|
105
|
+
def default_page_size=(new_value)
|
106
|
+
@has_default_page_size_override = true
|
107
|
+
@default_page_size = new_value
|
108
|
+
end
|
109
|
+
|
110
|
+
def default_page_size
|
111
|
+
if @has_default_page_size_override
|
112
|
+
@default_page_size
|
113
|
+
else
|
114
|
+
context.schema.default_page_size
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def has_default_page_size_override?
|
119
|
+
@has_default_page_size_override
|
120
|
+
end
|
121
|
+
|
98
122
|
attr_writer :first
|
99
123
|
# @return [Integer, nil]
|
100
124
|
# A clamped `first` value.
|
101
125
|
# (The underlying instance variable doesn't have limits on it.)
|
102
|
-
# If neither `first` nor `last` is given, but `
|
126
|
+
# If neither `first` nor `last` is given, but `default_page_size` is
|
127
|
+
# present, default_page_size is used for first. If `default_page_size`
|
128
|
+
# is greater than `max_page_size``, it'll be clamped down to
|
129
|
+
# `max_page_size`. If `default_page_size` is nil, use `max_page_size`.
|
103
130
|
def first
|
104
131
|
@first ||= begin
|
105
132
|
capped = limit_pagination_argument(@first_value, max_page_size)
|
106
133
|
if capped.nil? && last.nil?
|
107
|
-
capped = max_page_size
|
134
|
+
capped = limit_pagination_argument(default_page_size, max_page_size) || max_page_size
|
108
135
|
end
|
109
136
|
capped
|
110
137
|
end
|
@@ -21,13 +21,6 @@ module GraphQL
|
|
21
21
|
class ImplementationMissingError < GraphQL::Error
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.use(schema_defn)
|
25
|
-
if schema_defn.plugins.any? { |(plugin, args)| plugin == self }
|
26
|
-
GraphQL::Deprecation.warn("#{self} is now the default, remove `use #{self}` from #{caller(2,1).first}")
|
27
|
-
end
|
28
|
-
schema_defn.connections = self.new(schema: schema_defn)
|
29
|
-
end
|
30
|
-
|
31
24
|
def initialize(schema:)
|
32
25
|
@schema = schema
|
33
26
|
@wrappers = {}
|
@@ -77,6 +70,7 @@ module GraphQL
|
|
77
70
|
parent: parent,
|
78
71
|
field: field,
|
79
72
|
max_page_size: field.has_max_page_size? ? field.max_page_size : context.schema.default_max_page_size,
|
73
|
+
default_page_size: field.has_default_page_size? ? field.default_page_size : context.schema.default_page_size,
|
80
74
|
first: arguments[:first],
|
81
75
|
after: arguments[:after],
|
82
76
|
last: arguments[:last],
|
@@ -85,26 +79,7 @@ module GraphQL
|
|
85
79
|
edge_class: edge_class_for_field(field),
|
86
80
|
)
|
87
81
|
else
|
88
|
-
|
89
|
-
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(items)
|
90
|
-
if parent.is_a?(GraphQL::Schema::Object)
|
91
|
-
parent = parent.object
|
92
|
-
end
|
93
|
-
connection_class.new(
|
94
|
-
items,
|
95
|
-
arguments,
|
96
|
-
field: field,
|
97
|
-
max_page_size: field.max_page_size,
|
98
|
-
parent: parent,
|
99
|
-
context: context,
|
100
|
-
)
|
101
|
-
rescue RuntimeError => err
|
102
|
-
if err.message.include?("No connection implementation to wrap")
|
103
|
-
raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
|
104
|
-
else
|
105
|
-
raise err
|
106
|
-
end
|
107
|
-
end
|
82
|
+
raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
|
108
83
|
end
|
109
84
|
end
|
110
85
|
|
@@ -113,7 +88,7 @@ module GraphQL
|
|
113
88
|
def edge_class_for_field(field)
|
114
89
|
conn_type = field.type.unwrap
|
115
90
|
conn_type_edge_type = conn_type.respond_to?(:edge_class) && conn_type.edge_class
|
116
|
-
if conn_type_edge_type && conn_type_edge_type !=
|
91
|
+
if conn_type_edge_type && conn_type_edge_type != Pagination::Connection::Edge
|
117
92
|
conn_type_edge_type
|
118
93
|
else
|
119
94
|
nil
|
@@ -5,49 +5,10 @@ module GraphQL
|
|
5
5
|
# It delegates `[]` to the hash that's passed to `GraphQL::Query#initialize`.
|
6
6
|
class Context
|
7
7
|
module SharedMethods
|
8
|
-
# @return [Object] The target for field resolution
|
9
|
-
attr_accessor :object
|
10
|
-
|
11
|
-
# @return [Hash, Array, String, Integer, Float, Boolean, nil] The resolved value for this field
|
12
|
-
attr_reader :value
|
13
|
-
|
14
|
-
# @return [Boolean] were any fields of this selection skipped?
|
15
|
-
attr_reader :skipped
|
16
|
-
alias :skipped? :skipped
|
17
|
-
|
18
|
-
# @api private
|
19
|
-
attr_writer :skipped
|
20
|
-
|
21
8
|
# Return this value to tell the runtime
|
22
9
|
# to exclude this field from the response altogether
|
23
10
|
def skip
|
24
|
-
GraphQL::Execution::
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [Boolean] True if this selection has been nullified by a null child
|
28
|
-
def invalid_null?
|
29
|
-
@invalid_null
|
30
|
-
end
|
31
|
-
|
32
|
-
# Remove this child from the result value
|
33
|
-
# (used for null propagation and skip)
|
34
|
-
# @api private
|
35
|
-
def delete_child(child_ctx)
|
36
|
-
@value.delete(child_ctx.key)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Create a child context to use for `key`
|
40
|
-
# @param key [String, Integer] The key in the response (name or index)
|
41
|
-
# @param irep_node [InternalRepresentation::Node] The node being evaluated
|
42
|
-
# @api private
|
43
|
-
def spawn_child(key:, irep_node:, object:)
|
44
|
-
FieldResolutionContext.new(
|
45
|
-
@context,
|
46
|
-
key,
|
47
|
-
irep_node,
|
48
|
-
self,
|
49
|
-
object
|
50
|
-
)
|
11
|
+
GraphQL::Execution::SKIP
|
51
12
|
end
|
52
13
|
|
53
14
|
# Add error at query-level.
|
@@ -72,12 +33,6 @@ module GraphQL
|
|
72
33
|
def execution_errors
|
73
34
|
@execution_errors ||= ExecutionErrors.new(self)
|
74
35
|
end
|
75
|
-
|
76
|
-
def lookahead
|
77
|
-
ast_nodes = irep_node.ast_nodes
|
78
|
-
field = irep_node.definition.metadata[:type_class] || raise("Lookahead is only compatible with class-based schemas")
|
79
|
-
Execution::Lookahead.new(query: query, ast_nodes: ast_nodes, field: field)
|
80
|
-
end
|
81
36
|
end
|
82
37
|
|
83
38
|
class ExecutionErrors
|
@@ -105,27 +60,6 @@ module GraphQL
|
|
105
60
|
include SharedMethods
|
106
61
|
extend Forwardable
|
107
62
|
|
108
|
-
attr_reader :execution_strategy
|
109
|
-
# `strategy` is required by GraphQL::Batch
|
110
|
-
alias_method :strategy, :execution_strategy
|
111
|
-
|
112
|
-
def execution_strategy=(new_strategy)
|
113
|
-
# GraphQL::Batch re-assigns this value but it was previously not used
|
114
|
-
# (ExecutionContext#strategy was used instead)
|
115
|
-
# now it _is_ used, but it breaks GraphQL::Batch tests
|
116
|
-
@execution_strategy ||= new_strategy
|
117
|
-
end
|
118
|
-
|
119
|
-
# @return [GraphQL::InternalRepresentation::Node] The internal representation for this query node
|
120
|
-
def irep_node
|
121
|
-
@irep_node ||= query.irep_selection
|
122
|
-
end
|
123
|
-
|
124
|
-
# @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
|
125
|
-
def ast_node
|
126
|
-
@irep_node.ast_node
|
127
|
-
end
|
128
|
-
|
129
63
|
# @return [Array<GraphQL::ExecutionError>] errors returned during execution
|
130
64
|
attr_reader :errors
|
131
65
|
|
@@ -152,8 +86,106 @@ module GraphQL
|
|
152
86
|
@errors = []
|
153
87
|
@path = []
|
154
88
|
@value = nil
|
155
|
-
@context = self # for SharedMethods
|
156
|
-
@scoped_context =
|
89
|
+
@context = self # for SharedMethods TODO delete sharedmethods
|
90
|
+
@scoped_context = ScopedContext.new(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
class ScopedContext
|
94
|
+
NO_PATH = [].freeze
|
95
|
+
NO_CONTEXT = {}.freeze
|
96
|
+
|
97
|
+
def initialize(query_context)
|
98
|
+
@query_context = query_context
|
99
|
+
@scoped_contexts = nil
|
100
|
+
@all_keys = nil
|
101
|
+
end
|
102
|
+
|
103
|
+
def merged_context
|
104
|
+
if @scoped_contexts.nil?
|
105
|
+
NO_CONTEXT
|
106
|
+
else
|
107
|
+
merged_ctx = {}
|
108
|
+
each_present_path_ctx do |path_ctx|
|
109
|
+
merged_ctx = path_ctx.merge(merged_ctx)
|
110
|
+
end
|
111
|
+
merged_ctx
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def merge!(hash)
|
116
|
+
@all_keys ||= Set.new
|
117
|
+
@all_keys.merge(hash.keys)
|
118
|
+
ctx = @scoped_contexts ||= {}
|
119
|
+
current_path.each do |path_part|
|
120
|
+
ctx = ctx[path_part] ||= { parent: ctx }
|
121
|
+
end
|
122
|
+
this_scoped_ctx = ctx[:scoped_context] ||= {}
|
123
|
+
this_scoped_ctx.merge!(hash)
|
124
|
+
end
|
125
|
+
|
126
|
+
def key?(key)
|
127
|
+
if @all_keys && @all_keys.include?(key)
|
128
|
+
each_present_path_ctx do |path_ctx|
|
129
|
+
if path_ctx.key?(key)
|
130
|
+
return true
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
false
|
135
|
+
end
|
136
|
+
|
137
|
+
def [](key)
|
138
|
+
each_present_path_ctx do |path_ctx|
|
139
|
+
if path_ctx.key?(key)
|
140
|
+
return path_ctx[key]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
nil
|
144
|
+
end
|
145
|
+
|
146
|
+
def current_path
|
147
|
+
@query_context.current_path || NO_PATH
|
148
|
+
end
|
149
|
+
|
150
|
+
def dig(key, *other_keys)
|
151
|
+
each_present_path_ctx do |path_ctx|
|
152
|
+
if path_ctx.key?(key)
|
153
|
+
found_value = path_ctx[key]
|
154
|
+
if other_keys.any?
|
155
|
+
return found_value.dig(*other_keys)
|
156
|
+
else
|
157
|
+
return found_value
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
|
164
|
+
private
|
165
|
+
|
166
|
+
# Start at the current location,
|
167
|
+
# but look up the tree for previously-assigned scoped values
|
168
|
+
def each_present_path_ctx
|
169
|
+
ctx = @scoped_contexts
|
170
|
+
if ctx.nil?
|
171
|
+
# no-op
|
172
|
+
else
|
173
|
+
current_path.each do |path_part|
|
174
|
+
if ctx.key?(path_part)
|
175
|
+
ctx = ctx[path_part]
|
176
|
+
else
|
177
|
+
break
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
while ctx
|
182
|
+
if (scoped_ctx = ctx[:scoped_context])
|
183
|
+
yield(scoped_ctx)
|
184
|
+
end
|
185
|
+
ctx = ctx[:parent]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
157
189
|
end
|
158
190
|
|
159
191
|
# @return [Hash] A hash that will be added verbatim to the result hash, as `"extensions" => { ... }`
|
@@ -172,7 +204,7 @@ module GraphQL
|
|
172
204
|
attr_writer :value
|
173
205
|
|
174
206
|
# @api private
|
175
|
-
|
207
|
+
attr_reader :scoped_context
|
176
208
|
|
177
209
|
def []=(key, value)
|
178
210
|
@provided_values[key] = value
|
@@ -180,13 +212,39 @@ module GraphQL
|
|
180
212
|
|
181
213
|
def_delegators :@query, :trace, :interpreter?
|
182
214
|
|
215
|
+
RUNTIME_METADATA_KEYS = Set.new([:current_object, :current_arguments, :current_field, :current_path])
|
183
216
|
# @!method []=(key, value)
|
184
217
|
# Reassign `key` to the hash passed to {Schema#execute} as `context:`
|
185
218
|
|
186
219
|
# Lookup `key` from the hash passed to {Schema#execute} as `context:`
|
187
220
|
def [](key)
|
188
|
-
|
189
|
-
|
221
|
+
if @scoped_context.key?(key)
|
222
|
+
@scoped_context[key]
|
223
|
+
elsif @provided_values.key?(key)
|
224
|
+
@provided_values[key]
|
225
|
+
elsif RUNTIME_METADATA_KEYS.include?(key)
|
226
|
+
if key == :current_path
|
227
|
+
current_path
|
228
|
+
else
|
229
|
+
thread_info = Thread.current[:__graphql_runtime_info]
|
230
|
+
thread_info && thread_info[key]
|
231
|
+
end
|
232
|
+
else
|
233
|
+
# not found
|
234
|
+
nil
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def current_path
|
239
|
+
thread_info = Thread.current[:__graphql_runtime_info]
|
240
|
+
path = thread_info &&
|
241
|
+
(result = thread_info[:current_result]) &&
|
242
|
+
(result.path)
|
243
|
+
if path && (rn = thread_info[:current_result_name])
|
244
|
+
path = path.dup
|
245
|
+
path.push(rn)
|
246
|
+
end
|
247
|
+
path
|
190
248
|
end
|
191
249
|
|
192
250
|
def delete(key)
|
@@ -200,8 +258,11 @@ module GraphQL
|
|
200
258
|
UNSPECIFIED_FETCH_DEFAULT = Object.new
|
201
259
|
|
202
260
|
def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
|
203
|
-
if
|
204
|
-
|
261
|
+
if RUNTIME_METADATA_KEYS.include?(key)
|
262
|
+
(thread_info = Thread.current[:__graphql_runtime_info]) &&
|
263
|
+
thread_info[key]
|
264
|
+
elsif @scoped_context.key?(key)
|
265
|
+
scoped_context[key]
|
205
266
|
elsif @provided_values.key?(key)
|
206
267
|
@provided_values[key]
|
207
268
|
elsif default != UNSPECIFIED_FETCH_DEFAULT
|
@@ -214,12 +275,24 @@ module GraphQL
|
|
214
275
|
end
|
215
276
|
|
216
277
|
def dig(key, *other_keys)
|
217
|
-
|
278
|
+
if RUNTIME_METADATA_KEYS.include?(key)
|
279
|
+
(thread_info = Thread.current[:__graphql_runtime_info]).key?(key) &&
|
280
|
+
thread_info.dig(key, *other_keys)
|
281
|
+
elsif @scoped_context.key?(key)
|
282
|
+
@scoped_context.dig(key, *other_keys)
|
283
|
+
else
|
284
|
+
@provided_values.dig(key, *other_keys)
|
285
|
+
end
|
218
286
|
end
|
219
287
|
|
220
288
|
def to_h
|
221
|
-
|
289
|
+
if (current_scoped_context = @scoped_context.merged_context)
|
290
|
+
@provided_values.merge(current_scoped_context)
|
291
|
+
else
|
292
|
+
@provided_values
|
293
|
+
end
|
222
294
|
end
|
295
|
+
|
223
296
|
alias :to_hash :to_h
|
224
297
|
|
225
298
|
def key?(key)
|
@@ -238,7 +311,11 @@ module GraphQL
|
|
238
311
|
# @param ns [Object] a usage-specific namespace identifier
|
239
312
|
# @return [Hash] namespaced storage
|
240
313
|
def namespace(ns)
|
241
|
-
|
314
|
+
if ns == :interpreter
|
315
|
+
self
|
316
|
+
else
|
317
|
+
@storage[ns]
|
318
|
+
end
|
242
319
|
end
|
243
320
|
|
244
321
|
# @return [Boolean] true if this namespace was accessed before
|
@@ -250,132 +327,14 @@ module GraphQL
|
|
250
327
|
"#<Query::Context ...>"
|
251
328
|
end
|
252
329
|
|
253
|
-
# @api private
|
254
|
-
def received_null_child
|
255
|
-
@invalid_null = true
|
256
|
-
@value = nil
|
257
|
-
end
|
258
|
-
|
259
330
|
def scoped_merge!(hash)
|
260
|
-
@scoped_context
|
331
|
+
@scoped_context.merge!(hash)
|
261
332
|
end
|
262
333
|
|
263
334
|
def scoped_set!(key, value)
|
264
335
|
scoped_merge!(key => value)
|
265
336
|
nil
|
266
337
|
end
|
267
|
-
|
268
|
-
class FieldResolutionContext
|
269
|
-
include SharedMethods
|
270
|
-
include Tracing::Traceable
|
271
|
-
extend Forwardable
|
272
|
-
|
273
|
-
attr_reader :irep_node, :field, :parent_type, :query, :schema, :parent, :key, :type
|
274
|
-
alias :selection :irep_node
|
275
|
-
|
276
|
-
def initialize(context, key, irep_node, parent, object)
|
277
|
-
@context = context
|
278
|
-
@key = key
|
279
|
-
@parent = parent
|
280
|
-
@object = object
|
281
|
-
@irep_node = irep_node
|
282
|
-
@field = irep_node.definition
|
283
|
-
@parent_type = irep_node.owner_type
|
284
|
-
@type = field.type
|
285
|
-
# This is needed constantly, so set it ahead of time:
|
286
|
-
@query = context.query
|
287
|
-
@schema = context.schema
|
288
|
-
@tracers = @query.tracers
|
289
|
-
# This hack flag is required by ConnectionResolve
|
290
|
-
@wrapped_connection = false
|
291
|
-
@wrapped_object = false
|
292
|
-
end
|
293
|
-
|
294
|
-
# @api private
|
295
|
-
attr_accessor :wrapped_connection, :wrapped_object
|
296
|
-
|
297
|
-
def path
|
298
|
-
@path ||= @parent.path.dup << @key
|
299
|
-
end
|
300
|
-
|
301
|
-
def_delegators :@context,
|
302
|
-
:[], :[]=, :key?, :fetch, :to_h, :namespace, :dig,
|
303
|
-
:spawn, :warden, :errors,
|
304
|
-
:execution_strategy, :strategy, :interpreter?
|
305
|
-
|
306
|
-
# @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
|
307
|
-
def ast_node
|
308
|
-
@irep_node.ast_node
|
309
|
-
end
|
310
|
-
|
311
|
-
# Add error to current field resolution.
|
312
|
-
# @param error [GraphQL::ExecutionError] an execution error
|
313
|
-
# @return [void]
|
314
|
-
def add_error(error)
|
315
|
-
super
|
316
|
-
error.ast_node ||= irep_node.ast_node
|
317
|
-
error.path ||= path
|
318
|
-
nil
|
319
|
-
end
|
320
|
-
|
321
|
-
def inspect
|
322
|
-
"#<GraphQL Context @ #{irep_node.owner_type.name}.#{field.name}>"
|
323
|
-
end
|
324
|
-
|
325
|
-
# Set a new value for this field in the response.
|
326
|
-
# It may be updated after resolving a {Lazy}.
|
327
|
-
# If it is {Execute::PROPAGATE_NULL}, tell the owner to propagate null.
|
328
|
-
# If it's {Execute::Execution::SKIP}, remove this field result from its parent
|
329
|
-
# @param new_value [Any] The GraphQL-ready value
|
330
|
-
# @api private
|
331
|
-
def value=(new_value)
|
332
|
-
case new_value
|
333
|
-
when GraphQL::Execution::Execute::PROPAGATE_NULL, nil
|
334
|
-
@invalid_null = true
|
335
|
-
@value = nil
|
336
|
-
if @type.kind.non_null?
|
337
|
-
@parent.received_null_child
|
338
|
-
end
|
339
|
-
when GraphQL::Execution::Execute::SKIP
|
340
|
-
@parent.skipped = true
|
341
|
-
@parent.delete_child(self)
|
342
|
-
else
|
343
|
-
@value = new_value
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
protected
|
348
|
-
|
349
|
-
def received_null_child
|
350
|
-
case @value
|
351
|
-
when Hash
|
352
|
-
self.value = GraphQL::Execution::Execute::PROPAGATE_NULL
|
353
|
-
when Array
|
354
|
-
if list_of_non_null_items?(@type)
|
355
|
-
self.value = GraphQL::Execution::Execute::PROPAGATE_NULL
|
356
|
-
end
|
357
|
-
when nil
|
358
|
-
# TODO This is a hack
|
359
|
-
# It was already nulled out but it's getting reassigned
|
360
|
-
else
|
361
|
-
raise "Unexpected value for received_null_child (#{self.value.class}): #{value}"
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
private
|
366
|
-
|
367
|
-
def list_of_non_null_items?(type)
|
368
|
-
case type
|
369
|
-
when GraphQL::NonNullType
|
370
|
-
# Unwrap [T]!
|
371
|
-
list_of_non_null_items?(type.of_type)
|
372
|
-
when GraphQL::ListType
|
373
|
-
type.of_type.is_a?(GraphQL::NonNullType)
|
374
|
-
else
|
375
|
-
raise "Unexpected list_of_non_null_items check: #{type}"
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
379
338
|
end
|
380
339
|
end
|
381
340
|
end
|