graphql 2.0.13 → 2.3.10
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/mutation_root_generator.rb +2 -2
- data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
- data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
- data/lib/generators/graphql/install_generator.rb +3 -0
- data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
- data/lib/generators/graphql/mutation_update_generator.rb +1 -1
- data/lib/generators/graphql/relay.rb +18 -1
- data/lib/generators/graphql/templates/base_argument.erb +2 -0
- data/lib/generators/graphql/templates/base_connection.erb +2 -0
- data/lib/generators/graphql/templates/base_edge.erb +2 -0
- data/lib/generators/graphql/templates/base_enum.erb +2 -0
- data/lib/generators/graphql/templates/base_field.erb +2 -0
- data/lib/generators/graphql/templates/base_input_object.erb +2 -0
- data/lib/generators/graphql/templates/base_interface.erb +2 -0
- data/lib/generators/graphql/templates/base_object.erb +2 -0
- data/lib/generators/graphql/templates/base_resolver.erb +6 -0
- data/lib/generators/graphql/templates/base_scalar.erb +2 -0
- data/lib/generators/graphql/templates/base_union.erb +2 -0
- data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
- data/lib/generators/graphql/templates/loader.erb +2 -0
- data/lib/generators/graphql/templates/mutation.erb +2 -0
- data/lib/generators/graphql/templates/node_type.erb +2 -0
- data/lib/generators/graphql/templates/query_type.erb +2 -0
- data/lib/generators/graphql/templates/schema.erb +8 -0
- data/lib/graphql/analysis/analyzer.rb +89 -0
- data/lib/graphql/analysis/field_usage.rb +82 -0
- data/lib/graphql/analysis/max_query_complexity.rb +20 -0
- data/lib/graphql/analysis/max_query_depth.rb +20 -0
- data/lib/graphql/analysis/query_complexity.rb +183 -0
- data/lib/graphql/analysis/query_depth.rb +58 -0
- data/lib/graphql/analysis/visitor.rb +283 -0
- data/lib/graphql/analysis.rb +92 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -12
- data/lib/graphql/backtrace/table.rb +2 -2
- data/lib/graphql/backtrace/trace.rb +93 -0
- data/lib/graphql/backtrace/tracer.rb +1 -1
- data/lib/graphql/backtrace.rb +2 -1
- data/lib/graphql/coercion_error.rb +1 -9
- data/lib/graphql/dataloader/async_dataloader.rb +88 -0
- data/lib/graphql/dataloader/null_dataloader.rb +1 -1
- data/lib/graphql/dataloader/request.rb +5 -0
- data/lib/graphql/dataloader/source.rb +89 -45
- data/lib/graphql/dataloader.rb +115 -142
- data/lib/graphql/duration_encoding_error.rb +16 -0
- data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -33
- data/lib/graphql/execution/interpreter/resolve.rb +19 -0
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +175 -0
- data/lib/graphql/execution/interpreter/runtime.rb +331 -455
- data/lib/graphql/execution/interpreter.rb +125 -61
- data/lib/graphql/execution/lazy.rb +6 -12
- data/lib/graphql/execution/lookahead.rb +124 -46
- data/lib/graphql/execution/multiplex.rb +3 -117
- data/lib/graphql/execution.rb +0 -1
- data/lib/graphql/introspection/directive_type.rb +3 -3
- data/lib/graphql/introspection/dynamic_fields.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +11 -5
- data/lib/graphql/introspection/field_type.rb +2 -2
- data/lib/graphql/introspection/schema_type.rb +10 -13
- data/lib/graphql/introspection/type_type.rb +17 -10
- data/lib/graphql/introspection.rb +3 -2
- data/lib/graphql/language/block_string.rb +34 -18
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/document_from_schema_definition.rb +75 -59
- data/lib/graphql/language/lexer.rb +358 -1506
- data/lib/graphql/language/nodes.rb +166 -93
- data/lib/graphql/language/parser.rb +795 -1953
- data/lib/graphql/language/printer.rb +340 -160
- data/lib/graphql/language/sanitized_printer.rb +21 -23
- data/lib/graphql/language/static_visitor.rb +167 -0
- data/lib/graphql/language/visitor.rb +188 -141
- data/lib/graphql/language.rb +61 -1
- data/lib/graphql/load_application_object_failed_error.rb +5 -1
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/pagination/connection.rb +33 -6
- data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
- data/lib/graphql/query/context/scoped_context.rb +101 -0
- data/lib/graphql/query/context.rb +117 -112
- data/lib/graphql/query/null_context.rb +12 -25
- data/lib/graphql/query/validation_pipeline.rb +6 -5
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +86 -30
- data/lib/graphql/railtie.rb +9 -6
- data/lib/graphql/rake_task.rb +29 -11
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- data/lib/graphql/schema/addition.rb +59 -23
- data/lib/graphql/schema/always_visible.rb +11 -0
- data/lib/graphql/schema/argument.rb +55 -26
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +56 -32
- data/lib/graphql/schema/directive/one_of.rb +24 -0
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +15 -3
- data/lib/graphql/schema/enum.rb +35 -24
- data/lib/graphql/schema/enum_value.rb +2 -3
- data/lib/graphql/schema/field/connection_extension.rb +2 -16
- data/lib/graphql/schema/field/scope_extension.rb +8 -1
- data/lib/graphql/schema/field.rb +147 -107
- data/lib/graphql/schema/field_extension.rb +1 -4
- data/lib/graphql/schema/find_inherited_value.rb +2 -7
- data/lib/graphql/schema/has_single_input_argument.rb +158 -0
- data/lib/graphql/schema/input_object.rb +47 -11
- data/lib/graphql/schema/interface.rb +15 -21
- data/lib/graphql/schema/introspection_system.rb +7 -17
- data/lib/graphql/schema/late_bound_type.rb +10 -0
- data/lib/graphql/schema/list.rb +2 -2
- data/lib/graphql/schema/loader.rb +2 -3
- data/lib/graphql/schema/member/base_dsl_methods.rb +18 -14
- data/lib/graphql/schema/member/build_type.rb +11 -3
- data/lib/graphql/schema/member/has_arguments.rb +170 -130
- 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 -61
- data/lib/graphql/schema/member/has_fields.rb +100 -38
- data/lib/graphql/schema/member/has_interfaces.rb +65 -10
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +32 -6
- data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +16 -0
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/object.rb +16 -5
- data/lib/graphql/schema/printer.rb +11 -8
- data/lib/graphql/schema/relay_classic_mutation.rb +7 -129
- data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
- data/lib/graphql/schema/resolver.rb +47 -32
- data/lib/graphql/schema/scalar.rb +3 -3
- data/lib/graphql/schema/subscription.rb +11 -4
- data/lib/graphql/schema/subset.rb +397 -0
- data/lib/graphql/schema/timeout.rb +25 -29
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/type_membership.rb +3 -0
- data/lib/graphql/schema/union.rb +11 -2
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +60 -0
- data/lib/graphql/schema/validator.rb +4 -2
- data/lib/graphql/schema/warden.rb +238 -93
- data/lib/graphql/schema.rb +498 -103
- data/lib/graphql/static_validation/all_rules.rb +2 -1
- data/lib/graphql/static_validation/base_visitor.rb +7 -6
- data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
- data/lib/graphql/static_validation/literal_validator.rb +24 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -2
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +10 -10
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- 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/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/validation_context.rb +5 -5
- data/lib/graphql/static_validation/validator.rb +4 -1
- data/lib/graphql/static_validation.rb +0 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +11 -4
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
- data/lib/graphql/subscriptions/event.rb +11 -10
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +20 -13
- data/lib/graphql/testing/helpers.rb +151 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +251 -0
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/data_dog_trace.rb +183 -0
- data/lib/graphql/tracing/data_dog_tracing.rb +9 -21
- data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +10 -28
- data/lib/graphql/tracing/legacy_trace.rb +69 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +45 -0
- data/lib/graphql/tracing/platform_trace.rb +118 -0
- data/lib/graphql/tracing/platform_tracing.rb +17 -3
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +4 -2
- 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/sentry_trace.rb +112 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/trace.rb +76 -0
- data/lib/graphql/tracing.rb +20 -40
- data/lib/graphql/type_kinds.rb +7 -4
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/base_connection.rb +1 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +68 -6
- data/lib/graphql/types/relay/edge_behaviors.rb +33 -5
- data/lib/graphql/types/relay/node_behaviors.rb +8 -2
- data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
- data/lib/graphql/types/relay.rb +0 -1
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +27 -20
- data/readme.md +13 -3
- metadata +96 -47
- data/lib/graphql/analysis/ast/analyzer.rb +0 -84
- data/lib/graphql/analysis/ast/field_usage.rb +0 -57
- data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
- data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
- data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
- data/lib/graphql/analysis/ast/query_depth.rb +0 -55
- data/lib/graphql/analysis/ast/visitor.rb +0 -269
- data/lib/graphql/analysis/ast.rb +0 -81
- data/lib/graphql/deprecation.rb +0 -9
- data/lib/graphql/filter.rb +0 -53
- data/lib/graphql/language/lexer.rl +0 -280
- data/lib/graphql/language/parser.y +0 -554
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
- data/lib/graphql/types/relay/default_relay.rb +0 -21
@@ -26,7 +26,7 @@ module GraphQL
|
|
26
26
|
# rename some inputs to avoid conflicts inside the block
|
27
27
|
maybe_lazy = value
|
28
28
|
value = nil
|
29
|
-
context.
|
29
|
+
context.query.after_lazy(maybe_lazy) do |resolved_value|
|
30
30
|
value = resolved_value
|
31
31
|
if value.is_a? GraphQL::ExecutionError
|
32
32
|
# This isn't even going to work because context doesn't have ast_node anymore
|
@@ -54,23 +54,9 @@ module GraphQL
|
|
54
54
|
value.edge_class = custom_t
|
55
55
|
end
|
56
56
|
value
|
57
|
-
|
57
|
+
else
|
58
58
|
context.namespace(:connections)[:all_wrappers] ||= context.schema.connections.all_wrappers
|
59
59
|
context.schema.connections.wrap(field, object.object, value, original_arguments, context)
|
60
|
-
else
|
61
|
-
if object.is_a?(GraphQL::Schema::Object)
|
62
|
-
object = object.object
|
63
|
-
end
|
64
|
-
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(value)
|
65
|
-
connection_class.new(
|
66
|
-
value,
|
67
|
-
original_arguments,
|
68
|
-
field: field,
|
69
|
-
max_page_size: field.max_page_size,
|
70
|
-
default_page_size: field.default_page_size,
|
71
|
-
parent: object,
|
72
|
-
context: context,
|
73
|
-
)
|
74
60
|
end
|
75
61
|
end
|
76
62
|
end
|
@@ -10,7 +10,14 @@ module GraphQL
|
|
10
10
|
else
|
11
11
|
ret_type = @field.type.unwrap
|
12
12
|
if ret_type.respond_to?(:scope_items)
|
13
|
-
ret_type.scope_items(value, context)
|
13
|
+
scoped_items = ret_type.scope_items(value, context)
|
14
|
+
if !scoped_items.equal?(value) && !ret_type.reauthorize_scoped_objects
|
15
|
+
if (current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
|
16
|
+
(query_runtime_state = current_runtime_state[context.query])
|
17
|
+
query_runtime_state.was_authorized_by_scope_items = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
scoped_items
|
14
21
|
else
|
15
22
|
value
|
16
23
|
end
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -6,11 +6,12 @@ module GraphQL
|
|
6
6
|
class Schema
|
7
7
|
class Field
|
8
8
|
include GraphQL::Schema::Member::HasArguments
|
9
|
+
include GraphQL::Schema::Member::HasArguments::FieldConfigured
|
9
10
|
include GraphQL::Schema::Member::HasAstNode
|
10
11
|
include GraphQL::Schema::Member::HasPath
|
11
12
|
include GraphQL::Schema::Member::HasValidators
|
12
13
|
extend GraphQL::Schema::FindInheritedValue
|
13
|
-
include GraphQL::
|
14
|
+
include GraphQL::EmptyObjects
|
14
15
|
include GraphQL::Schema::Member::HasDirectives
|
15
16
|
include GraphQL::Schema::Member::HasDeprecationReason
|
16
17
|
|
@@ -40,6 +41,18 @@ module GraphQL
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
44
|
+
def directives
|
45
|
+
if @resolver_class && (r_dirs = @resolver_class.directives).any?
|
46
|
+
if (own_dirs = super).any?
|
47
|
+
own_dirs + r_dirs
|
48
|
+
else
|
49
|
+
r_dirs
|
50
|
+
end
|
51
|
+
else
|
52
|
+
super
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
43
56
|
# @return [Class] The thing this field was defined on (type, mutation, resolver)
|
44
57
|
attr_accessor :owner
|
45
58
|
|
@@ -91,7 +104,7 @@ module GraphQL
|
|
91
104
|
# @param resolver [Class] A {GraphQL::Schema::Resolver} class to use for field configuration
|
92
105
|
# @param mutation [Class] A {GraphQL::Schema::Mutation} class to use for field configuration
|
93
106
|
# @param subscription [Class] A {GraphQL::Schema::Subscription} class to use for field configuration
|
94
|
-
# @return [GraphQL::Schema:Field] an instance of `self
|
107
|
+
# @return [GraphQL::Schema:Field] an instance of `self`
|
95
108
|
# @see {.initialize} for other options
|
96
109
|
def self.from_options(name = nil, type = nil, desc = nil, resolver: nil, mutation: nil, subscription: nil,**kwargs, &block)
|
97
110
|
if (resolver_class = resolver || mutation || subscription)
|
@@ -129,15 +142,15 @@ module GraphQL
|
|
129
142
|
def connection?
|
130
143
|
if @connection.nil?
|
131
144
|
# Provide default based on type name
|
132
|
-
return_type_name = if @
|
133
|
-
Member::BuildType.to_type_name(@resolver_class.type)
|
134
|
-
elsif @return_type_expr
|
145
|
+
return_type_name = if @return_type_expr
|
135
146
|
Member::BuildType.to_type_name(@return_type_expr)
|
147
|
+
elsif @resolver_class && @resolver_class.type
|
148
|
+
Member::BuildType.to_type_name(@resolver_class.type)
|
136
149
|
else
|
137
150
|
# As a last ditch, try to force loading the return type:
|
138
151
|
type.unwrap.name
|
139
152
|
end
|
140
|
-
@connection = return_type_name.end_with?("Connection")
|
153
|
+
@connection = return_type_name.end_with?("Connection") && return_type_name != "Connection"
|
141
154
|
else
|
142
155
|
@connection
|
143
156
|
end
|
@@ -217,8 +230,8 @@ module GraphQL
|
|
217
230
|
# @param ast_node [Language::Nodes::FieldDefinition, nil] If this schema was parsed from definition, this AST node defined the field
|
218
231
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
219
232
|
# @param validates [Array<Hash>] Configurations for validating this field
|
220
|
-
# @fallback_value [Object] A fallback value if the method is not defined
|
221
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, description:
|
233
|
+
# @param fallback_value [Object] A fallback value if the method is not defined
|
234
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, dynamic_introspection: false, &definition_block)
|
222
235
|
if name.nil?
|
223
236
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
224
237
|
end
|
@@ -229,11 +242,13 @@ module GraphQL
|
|
229
242
|
end
|
230
243
|
@original_name = name
|
231
244
|
name_s = -name.to_s
|
245
|
+
|
232
246
|
@underscored_name = -Member::BuildType.underscore(name_s)
|
233
247
|
@name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
|
234
|
-
|
235
|
-
|
236
|
-
|
248
|
+
|
249
|
+
@description = description
|
250
|
+
@type = @owner_type = @own_validators = @own_directives = @own_arguments = @arguments_statically_coercible = nil # these will be prepared later if necessary
|
251
|
+
|
237
252
|
self.deprecation_reason = deprecation_reason
|
238
253
|
|
239
254
|
if method && hash_key && dig
|
@@ -255,12 +270,16 @@ module GraphQL
|
|
255
270
|
if hash_key
|
256
271
|
@hash_key = hash_key
|
257
272
|
@hash_key_str = hash_key.to_s
|
273
|
+
else
|
274
|
+
@hash_key = NOT_CONFIGURED
|
275
|
+
@hash_key_str = NOT_CONFIGURED
|
258
276
|
end
|
259
277
|
|
260
278
|
@method_str = -method_name.to_s
|
261
279
|
@method_sym = method_name.to_sym
|
262
280
|
@resolver_method = (resolver_method || name_s).to_sym
|
263
281
|
@complexity = complexity
|
282
|
+
@dynamic_introspection = dynamic_introspection
|
264
283
|
@return_type_expr = type
|
265
284
|
@return_type_null = if !null.nil?
|
266
285
|
null
|
@@ -270,15 +289,11 @@ module GraphQL
|
|
270
289
|
true
|
271
290
|
end
|
272
291
|
@connection = connection
|
273
|
-
@
|
274
|
-
@
|
275
|
-
@has_default_page_size = default_page_size != :not_given
|
276
|
-
@default_page_size = default_page_size == :not_given ? nil : default_page_size
|
292
|
+
@max_page_size = max_page_size
|
293
|
+
@default_page_size = default_page_size
|
277
294
|
@introspection = introspection
|
278
295
|
@extras = extras
|
279
|
-
|
280
|
-
@broadcastable = broadcastable
|
281
|
-
end
|
296
|
+
@broadcastable = broadcastable
|
282
297
|
@resolver_class = resolver_class
|
283
298
|
@scope = scope
|
284
299
|
@trace = trace
|
@@ -337,7 +352,7 @@ module GraphQL
|
|
337
352
|
self.validates(validates)
|
338
353
|
end
|
339
354
|
|
340
|
-
if
|
355
|
+
if block_given?
|
341
356
|
if definition_block.arity == 1
|
342
357
|
yield self
|
343
358
|
else
|
@@ -349,11 +364,13 @@ module GraphQL
|
|
349
364
|
@call_after_define = true
|
350
365
|
end
|
351
366
|
|
367
|
+
attr_accessor :dynamic_introspection
|
368
|
+
|
352
369
|
# If true, subscription updates with this field can be shared between viewers
|
353
370
|
# @return [Boolean, nil]
|
354
371
|
# @see GraphQL::Subscriptions::BroadcastAnalyzer
|
355
372
|
def broadcastable?
|
356
|
-
if
|
373
|
+
if !NOT_CONFIGURED.equal?(@broadcastable)
|
357
374
|
@broadcastable
|
358
375
|
elsif @resolver_class
|
359
376
|
@resolver_class.broadcastable?
|
@@ -367,10 +384,10 @@ module GraphQL
|
|
367
384
|
def description(text = nil)
|
368
385
|
if text
|
369
386
|
@description = text
|
370
|
-
elsif
|
387
|
+
elsif !NOT_CONFIGURED.equal?(@description)
|
371
388
|
@description
|
372
389
|
elsif @resolver_class
|
373
|
-
@
|
390
|
+
@resolver_class.description
|
374
391
|
else
|
375
392
|
nil
|
376
393
|
end
|
@@ -466,6 +483,8 @@ module GraphQL
|
|
466
483
|
if arguments[:last] && (max_possible_page_size.nil? || arguments[:last] > max_possible_page_size)
|
467
484
|
max_possible_page_size = arguments[:last]
|
468
485
|
end
|
486
|
+
elsif arguments.is_a?(GraphQL::UnauthorizedError)
|
487
|
+
raise arguments
|
469
488
|
end
|
470
489
|
|
471
490
|
if max_possible_page_size.nil?
|
@@ -478,41 +497,24 @@ module GraphQL
|
|
478
497
|
metadata_complexity = 0
|
479
498
|
lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)
|
480
499
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
500
|
+
lookahead.selections.each do |next_lookahead|
|
501
|
+
# this includes `pageInfo`, `nodes` and `edges` and any custom fields
|
502
|
+
# TODO this doesn't support procs yet -- unlikely to need it.
|
503
|
+
metadata_complexity += next_lookahead.field.complexity
|
504
|
+
if next_lookahead.name != :nodes && next_lookahead.name != :edges
|
505
|
+
# subfields, eg, for pageInfo -- assumes no subselections
|
506
|
+
metadata_complexity += next_lookahead.selections.size
|
507
|
+
end
|
488
508
|
end
|
489
509
|
|
490
|
-
nodes_edges_complexity = 0
|
491
|
-
nodes_edges_complexity += 1 if lookahead.selects?(:edges)
|
492
|
-
nodes_edges_complexity += 1 if lookahead.selects?(:nodes)
|
493
|
-
|
494
510
|
# Possible bug: selections on `edges` and `nodes` are _both_ multiplied here. Should they be?
|
495
|
-
items_complexity = child_complexity - metadata_complexity
|
496
|
-
|
497
|
-
|
511
|
+
items_complexity = child_complexity - metadata_complexity
|
512
|
+
subfields_complexity = (max_possible_page_size * items_complexity) + metadata_complexity
|
513
|
+
# Apply this field's own complexity
|
514
|
+
apply_own_complexity_to(subfields_complexity, query, nodes)
|
498
515
|
end
|
499
516
|
else
|
500
|
-
|
501
|
-
case defined_complexity
|
502
|
-
when Proc
|
503
|
-
arguments = query.arguments_for(nodes.first, self)
|
504
|
-
if arguments.is_a?(GraphQL::ExecutionError)
|
505
|
-
return child_complexity
|
506
|
-
elsif arguments.respond_to?(:keyword_arguments)
|
507
|
-
arguments = arguments.keyword_arguments
|
508
|
-
end
|
509
|
-
|
510
|
-
defined_complexity.call(query.context, arguments, child_complexity)
|
511
|
-
when Numeric
|
512
|
-
defined_complexity + child_complexity
|
513
|
-
else
|
514
|
-
raise("Invalid complexity: #{defined_complexity.inspect} on #{path} (#{inspect})")
|
515
|
-
end
|
517
|
+
apply_own_complexity_to(child_complexity, query, nodes)
|
516
518
|
end
|
517
519
|
end
|
518
520
|
|
@@ -542,22 +544,34 @@ module GraphQL
|
|
542
544
|
|
543
545
|
# @return [Boolean] True if this field's {#max_page_size} should override the schema default.
|
544
546
|
def has_max_page_size?
|
545
|
-
@
|
547
|
+
!NOT_CONFIGURED.equal?(@max_page_size) || (@resolver_class && @resolver_class.has_max_page_size?)
|
546
548
|
end
|
547
549
|
|
548
550
|
# @return [Integer, nil] Applied to connections if {#has_max_page_size?}
|
549
551
|
def max_page_size
|
550
|
-
|
552
|
+
if !NOT_CONFIGURED.equal?(@max_page_size)
|
553
|
+
@max_page_size
|
554
|
+
elsif @resolver_class && @resolver_class.has_max_page_size?
|
555
|
+
@resolver_class.max_page_size
|
556
|
+
else
|
557
|
+
nil
|
558
|
+
end
|
551
559
|
end
|
552
560
|
|
553
561
|
# @return [Boolean] True if this field's {#default_page_size} should override the schema default.
|
554
562
|
def has_default_page_size?
|
555
|
-
@
|
563
|
+
!NOT_CONFIGURED.equal?(@default_page_size) || (@resolver_class && @resolver_class.has_default_page_size?)
|
556
564
|
end
|
557
565
|
|
558
566
|
# @return [Integer, nil] Applied to connections if {#has_default_page_size?}
|
559
567
|
def default_page_size
|
560
|
-
|
568
|
+
if !NOT_CONFIGURED.equal?(@default_page_size)
|
569
|
+
@default_page_size
|
570
|
+
elsif @resolver_class && @resolver_class.has_default_page_size?
|
571
|
+
@resolver_class.default_page_size
|
572
|
+
else
|
573
|
+
nil
|
574
|
+
end
|
561
575
|
end
|
562
576
|
|
563
577
|
class MissingReturnTypeError < GraphQL::Error; end
|
@@ -589,48 +603,43 @@ module GraphQL
|
|
589
603
|
end
|
590
604
|
end
|
591
605
|
|
592
|
-
def accessible?(context)
|
593
|
-
if @resolver_class
|
594
|
-
@resolver_class.accessible?(context)
|
595
|
-
else
|
596
|
-
true
|
597
|
-
end
|
598
|
-
end
|
599
|
-
|
600
606
|
def authorized?(object, args, context)
|
601
607
|
if @resolver_class
|
602
608
|
# The resolver _instance_ will check itself during `resolve()`
|
603
609
|
@resolver_class.authorized?(object, context)
|
604
610
|
else
|
605
|
-
if
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
if
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
application_arg_value.
|
611
|
+
if args.size > 0
|
612
|
+
if (arg_values = context[:current_arguments])
|
613
|
+
# ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
|
614
|
+
using_arg_values = true
|
615
|
+
arg_values = arg_values.argument_values
|
616
|
+
else
|
617
|
+
arg_values = args
|
618
|
+
using_arg_values = false
|
619
|
+
end
|
620
|
+
|
621
|
+
args = context.types.arguments(self)
|
622
|
+
args.each do |arg|
|
623
|
+
arg_key = arg.keyword
|
624
|
+
if arg_values.key?(arg_key)
|
625
|
+
arg_value = arg_values[arg_key]
|
626
|
+
if using_arg_values
|
627
|
+
if arg_value.default_used?
|
628
|
+
# pass -- no auth required for default used
|
629
|
+
next
|
630
|
+
else
|
631
|
+
application_arg_value = arg_value.value
|
632
|
+
if application_arg_value.is_a?(GraphQL::Execution::Interpreter::Arguments)
|
633
|
+
application_arg_value.keyword_arguments
|
634
|
+
end
|
626
635
|
end
|
636
|
+
else
|
637
|
+
application_arg_value = arg_value
|
627
638
|
end
|
628
|
-
else
|
629
|
-
application_arg_value = arg_value
|
630
|
-
end
|
631
639
|
|
632
|
-
|
633
|
-
|
640
|
+
if !arg.authorized?(object, application_arg_value, context)
|
641
|
+
return false
|
642
|
+
end
|
634
643
|
end
|
635
644
|
end
|
636
645
|
end
|
@@ -650,9 +659,9 @@ module GraphQL
|
|
650
659
|
method_to_call = nil
|
651
660
|
method_args = nil
|
652
661
|
|
653
|
-
Schema::Validator.validate!(validators, application_object, query_ctx, args)
|
662
|
+
@own_validators && Schema::Validator.validate!(validators, application_object, query_ctx, args)
|
654
663
|
|
655
|
-
query_ctx.
|
664
|
+
query_ctx.query.after_lazy(self.authorized?(application_object, args, query_ctx)) do |is_authorized|
|
656
665
|
if is_authorized
|
657
666
|
with_extensions(object, args, query_ctx) do |obj, ruby_kwargs|
|
658
667
|
method_args = ruby_kwargs
|
@@ -665,7 +674,7 @@ module GraphQL
|
|
665
674
|
|
666
675
|
inner_object = obj.object
|
667
676
|
|
668
|
-
if
|
677
|
+
if !NOT_CONFIGURED.equal?(@hash_key)
|
669
678
|
hash_value = if inner_object.is_a?(Hash)
|
670
679
|
inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str]
|
671
680
|
elsif inner_object.respond_to?(:[])
|
@@ -676,7 +685,7 @@ module GraphQL
|
|
676
685
|
if hash_value == false
|
677
686
|
hash_value
|
678
687
|
else
|
679
|
-
hash_value || (@fallback_value !=
|
688
|
+
hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil)
|
680
689
|
end
|
681
690
|
elsif obj.respond_to?(resolver_method)
|
682
691
|
method_to_call = resolver_method
|
@@ -692,9 +701,9 @@ module GraphQL
|
|
692
701
|
inner_object.dig(*@dig_keys)
|
693
702
|
elsif inner_object.key?(@method_sym)
|
694
703
|
inner_object[@method_sym]
|
695
|
-
elsif inner_object.key?(@method_str)
|
704
|
+
elsif inner_object.key?(@method_str) || !inner_object.default_proc.nil?
|
696
705
|
inner_object[@method_str]
|
697
|
-
elsif @fallback_value !=
|
706
|
+
elsif @fallback_value != NOT_CONFIGURED
|
698
707
|
@fallback_value
|
699
708
|
else
|
700
709
|
nil
|
@@ -707,7 +716,7 @@ module GraphQL
|
|
707
716
|
else
|
708
717
|
inner_object.public_send(@method_sym)
|
709
718
|
end
|
710
|
-
elsif @fallback_value !=
|
719
|
+
elsif @fallback_value != NOT_CONFIGURED
|
711
720
|
@fallback_value
|
712
721
|
else
|
713
722
|
raise <<-ERR
|
@@ -744,6 +753,8 @@ module GraphQL
|
|
744
753
|
end
|
745
754
|
# if the line above doesn't raise, re-raise
|
746
755
|
raise
|
756
|
+
rescue GraphQL::ExecutionError => err
|
757
|
+
err
|
747
758
|
end
|
748
759
|
|
749
760
|
# @param ctx [GraphQL::Query::Context]
|
@@ -799,6 +810,17 @@ ERR
|
|
799
810
|
end
|
800
811
|
end
|
801
812
|
|
813
|
+
class ExtendedState
|
814
|
+
def initialize(args, object)
|
815
|
+
@arguments = args
|
816
|
+
@object = object
|
817
|
+
@memos = nil
|
818
|
+
@added_extras = nil
|
819
|
+
end
|
820
|
+
|
821
|
+
attr_accessor :arguments, :object, :memos, :added_extras
|
822
|
+
end
|
823
|
+
|
802
824
|
# Wrap execution with hooks.
|
803
825
|
# Written iteratively to avoid big stack traces.
|
804
826
|
# @return [Object] Whatever the
|
@@ -809,20 +831,20 @@ ERR
|
|
809
831
|
# This is a hack to get the _last_ value for extended obj and args,
|
810
832
|
# in case one of the extensions doesn't `yield`.
|
811
833
|
# (There's another implementation that uses multiple-return, but I'm wary of the perf cost of the extra arrays)
|
812
|
-
extended =
|
834
|
+
extended = ExtendedState.new(args, obj)
|
813
835
|
value = run_extensions_before_resolve(obj, args, ctx, extended) do |obj, args|
|
814
|
-
if (added_extras = extended
|
836
|
+
if (added_extras = extended.added_extras)
|
815
837
|
args = args.dup
|
816
838
|
added_extras.each { |e| args.delete(e) }
|
817
839
|
end
|
818
840
|
yield(obj, args)
|
819
841
|
end
|
820
842
|
|
821
|
-
extended_obj = extended
|
822
|
-
extended_args = extended
|
823
|
-
memos = extended
|
843
|
+
extended_obj = extended.object
|
844
|
+
extended_args = extended.arguments # rubocop:disable Development/ContextIsPassedCop
|
845
|
+
memos = extended.memos || EMPTY_HASH
|
824
846
|
|
825
|
-
ctx.
|
847
|
+
ctx.query.after_lazy(value) do |resolved_value|
|
826
848
|
idx = 0
|
827
849
|
@extensions.each do |ext|
|
828
850
|
memo = memos[idx]
|
@@ -840,23 +862,41 @@ ERR
|
|
840
862
|
if extension
|
841
863
|
extension.resolve(object: obj, arguments: args, context: ctx) do |extended_obj, extended_args, memo|
|
842
864
|
if memo
|
843
|
-
memos = extended
|
865
|
+
memos = extended.memos ||= {}
|
844
866
|
memos[idx] = memo
|
845
867
|
end
|
846
868
|
|
847
869
|
if (extras = extension.added_extras)
|
848
|
-
ae = extended
|
870
|
+
ae = extended.added_extras ||= []
|
849
871
|
ae.concat(extras)
|
850
872
|
end
|
851
873
|
|
852
|
-
extended
|
853
|
-
extended
|
874
|
+
extended.object = extended_obj
|
875
|
+
extended.arguments = extended_args
|
854
876
|
run_extensions_before_resolve(extended_obj, extended_args, ctx, extended, idx: idx + 1) { |o, a| yield(o, a) }
|
855
877
|
end
|
856
878
|
else
|
857
879
|
yield(obj, args)
|
858
880
|
end
|
859
881
|
end
|
882
|
+
|
883
|
+
def apply_own_complexity_to(child_complexity, query, nodes)
|
884
|
+
case (own_complexity = complexity)
|
885
|
+
when Numeric
|
886
|
+
own_complexity + child_complexity
|
887
|
+
when Proc
|
888
|
+
arguments = query.arguments_for(nodes.first, self)
|
889
|
+
if arguments.is_a?(GraphQL::ExecutionError)
|
890
|
+
return child_complexity
|
891
|
+
elsif arguments.respond_to?(:keyword_arguments)
|
892
|
+
arguments = arguments.keyword_arguments
|
893
|
+
end
|
894
|
+
|
895
|
+
own_complexity.call(query.context, arguments, child_complexity)
|
896
|
+
else
|
897
|
+
raise ArgumentError, "Invalid complexity for #{self.path}: #{own_complexity.inspect}"
|
898
|
+
end
|
899
|
+
end
|
860
900
|
end
|
861
901
|
end
|
862
902
|
end
|
@@ -71,14 +71,11 @@ module GraphQL
|
|
71
71
|
elsif inherited_extras
|
72
72
|
inherited_extras
|
73
73
|
else
|
74
|
-
|
74
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
NO_EXTRAS = [].freeze
|
80
|
-
private_constant :NO_EXTRAS
|
81
|
-
|
82
79
|
# Called when this extension is attached to a field.
|
83
80
|
# The field definition may be extended during this method.
|
84
81
|
# @return [void]
|
@@ -2,17 +2,12 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
module FindInheritedValue
|
5
|
-
module EmptyObjects
|
6
|
-
EMPTY_HASH = {}.freeze
|
7
|
-
EMPTY_ARRAY = [].freeze
|
8
|
-
end
|
9
|
-
|
10
5
|
def self.extended(child_cls)
|
11
|
-
child_cls.singleton_class.include(EmptyObjects)
|
6
|
+
child_cls.singleton_class.include(GraphQL::EmptyObjects)
|
12
7
|
end
|
13
8
|
|
14
9
|
def self.included(child_cls)
|
15
|
-
child_cls.include(EmptyObjects)
|
10
|
+
child_cls.include(GraphQL::EmptyObjects)
|
16
11
|
end
|
17
12
|
|
18
13
|
private
|