graphql 2.0.30 → 2.3.6
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.
- 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/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 +5 -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 +282 -0
- data/lib/graphql/analysis.rb +92 -1
- data/lib/graphql/backtrace/inspect_result.rb +0 -12
- data/lib/graphql/backtrace/trace.rb +12 -15
- 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 +11 -3
- data/lib/graphql/dataloader.rb +112 -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/runtime/graphql_result.rb +175 -0
- data/lib/graphql/execution/interpreter/runtime.rb +163 -365
- data/lib/graphql/execution/interpreter.rb +92 -158
- data/lib/graphql/execution/lookahead.rb +88 -21
- data/lib/graphql/introspection/dynamic_fields.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +11 -5
- data/lib/graphql/introspection/schema_type.rb +3 -1
- 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 +38 -38
- data/lib/graphql/language/lexer.rb +305 -193
- data/lib/graphql/language/nodes.rb +113 -66
- data/lib/graphql/language/parser.rb +787 -1986
- data/lib/graphql/language/printer.rb +303 -146
- data/lib/graphql/language/sanitized_printer.rb +20 -22
- data/lib/graphql/language/static_visitor.rb +167 -0
- data/lib/graphql/language/visitor.rb +20 -81
- data/lib/graphql/language.rb +61 -0
- data/lib/graphql/load_application_object_failed_error.rb +5 -1
- data/lib/graphql/pagination/array_connection.rb +6 -6
- data/lib/graphql/pagination/connection.rb +28 -1
- 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 +66 -131
- data/lib/graphql/query/null_context.rb +4 -11
- data/lib/graphql/query/validation_pipeline.rb +4 -4
- data/lib/graphql/query/variables.rb +3 -3
- data/lib/graphql/query.rb +17 -26
- data/lib/graphql/railtie.rb +9 -6
- data/lib/graphql/rake_task.rb +3 -12
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- data/lib/graphql/schema/addition.rb +21 -11
- data/lib/graphql/schema/argument.rb +43 -8
- data/lib/graphql/schema/base_64_encoder.rb +3 -5
- data/lib/graphql/schema/build_from_definition.rb +9 -12
- data/lib/graphql/schema/directive/one_of.rb +12 -0
- data/lib/graphql/schema/directive/specified_by.rb +14 -0
- data/lib/graphql/schema/directive.rb +3 -1
- data/lib/graphql/schema/enum.rb +3 -3
- data/lib/graphql/schema/field/connection_extension.rb +1 -15
- data/lib/graphql/schema/field/scope_extension.rb +8 -1
- data/lib/graphql/schema/field.rb +49 -35
- data/lib/graphql/schema/has_single_input_argument.rb +157 -0
- data/lib/graphql/schema/input_object.rb +4 -4
- data/lib/graphql/schema/interface.rb +10 -10
- data/lib/graphql/schema/introspection_system.rb +4 -2
- data/lib/graphql/schema/late_bound_type.rb +4 -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 +2 -1
- data/lib/graphql/schema/member/has_arguments.rb +63 -73
- data/lib/graphql/schema/member/has_directives.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +8 -5
- data/lib/graphql/schema/member/has_interfaces.rb +23 -9
- data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -2
- data/lib/graphql/schema/member/validates_input.rb +3 -3
- data/lib/graphql/schema/mutation.rb +7 -0
- data/lib/graphql/schema/object.rb +8 -0
- data/lib/graphql/schema/printer.rb +8 -7
- data/lib/graphql/schema/relay_classic_mutation.rb +6 -128
- data/lib/graphql/schema/resolver.rb +27 -13
- data/lib/graphql/schema/scalar.rb +3 -3
- data/lib/graphql/schema/subscription.rb +11 -4
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/unique_within_type.rb +1 -1
- data/lib/graphql/schema/warden.rb +96 -95
- data/lib/graphql/schema.rb +323 -102
- data/lib/graphql/static_validation/all_rules.rb +1 -1
- data/lib/graphql/static_validation/base_visitor.rb +1 -1
- data/lib/graphql/static_validation/literal_validator.rb +2 -3
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +2 -2
- data/lib/graphql/static_validation/validation_context.rb +5 -5
- data/lib/graphql/static_validation/validator.rb +3 -0
- data/lib/graphql/static_validation.rb +0 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +4 -3
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +1 -1
- data/lib/graphql/subscriptions/event.rb +8 -2
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/subscriptions.rb +15 -13
- data/lib/graphql/testing/helpers.rb +151 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/appoptics_trace.rb +2 -2
- data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
- data/lib/graphql/tracing/legacy_hooks_trace.rb +74 -0
- data/lib/graphql/tracing/platform_tracing.rb +3 -1
- data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +3 -1
- data/lib/graphql/tracing/prometheus_trace.rb +9 -9
- data/lib/graphql/tracing/sentry_trace.rb +112 -0
- data/lib/graphql/tracing/trace.rb +1 -0
- data/lib/graphql/tracing.rb +3 -1
- data/lib/graphql/type_kinds.rb +1 -1
- data/lib/graphql/types/iso_8601_duration.rb +77 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +32 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +7 -0
- data/lib/graphql/types.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +13 -13
- data/readme.md +12 -2
- metadata +33 -26
- 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 -276
- data/lib/graphql/analysis/ast.rb +0 -81
- data/lib/graphql/deprecation.rb +0 -9
- data/lib/graphql/filter.rb +0 -59
- data/lib/graphql/language/parser.y +0 -560
- data/lib/graphql/schema/base_64_bp.rb +0 -26
- data/lib/graphql/static_validation/type_stack.rb +0 -216
- data/lib/graphql/subscriptions/instrumentation.rb +0 -28
data/lib/graphql/schema.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
require "logger"
|
|
2
3
|
require "graphql/schema/addition"
|
|
3
4
|
require "graphql/schema/always_visible"
|
|
4
5
|
require "graphql/schema/base_64_encoder"
|
|
@@ -37,10 +38,12 @@ require "graphql/schema/directive/skip"
|
|
|
37
38
|
require "graphql/schema/directive/feature"
|
|
38
39
|
require "graphql/schema/directive/flagged"
|
|
39
40
|
require "graphql/schema/directive/transform"
|
|
41
|
+
require "graphql/schema/directive/specified_by"
|
|
40
42
|
require "graphql/schema/type_membership"
|
|
41
43
|
|
|
42
44
|
require "graphql/schema/resolver"
|
|
43
45
|
require "graphql/schema/mutation"
|
|
46
|
+
require "graphql/schema/has_single_input_argument"
|
|
44
47
|
require "graphql/schema/relay_classic_mutation"
|
|
45
48
|
require "graphql/schema/subscription"
|
|
46
49
|
|
|
@@ -60,10 +63,6 @@ module GraphQL
|
|
|
60
63
|
# Schemas can restrict large incoming queries with `max_depth` and `max_complexity` configurations.
|
|
61
64
|
# (These configurations can be overridden by specific calls to {Schema#execute})
|
|
62
65
|
#
|
|
63
|
-
# Schemas can specify how queries should be executed against them.
|
|
64
|
-
# `query_execution_strategy`, `mutation_execution_strategy` and `subscription_execution_strategy`
|
|
65
|
-
# each apply to corresponding root types.
|
|
66
|
-
#
|
|
67
66
|
# @example defining a schema
|
|
68
67
|
# class MySchema < GraphQL::Schema
|
|
69
68
|
# query QueryType
|
|
@@ -144,53 +143,105 @@ module GraphQL
|
|
|
144
143
|
@subscriptions = new_implementation
|
|
145
144
|
end
|
|
146
145
|
|
|
146
|
+
# @param new_mode [Symbol] If configured, this will be used when `context: { trace_mode: ... }` isn't set.
|
|
147
|
+
def default_trace_mode(new_mode = nil)
|
|
148
|
+
if new_mode
|
|
149
|
+
@default_trace_mode = new_mode
|
|
150
|
+
elsif defined?(@default_trace_mode)
|
|
151
|
+
@default_trace_mode
|
|
152
|
+
elsif superclass.respond_to?(:default_trace_mode)
|
|
153
|
+
superclass.default_trace_mode
|
|
154
|
+
else
|
|
155
|
+
:default
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
147
159
|
def trace_class(new_class = nil)
|
|
148
160
|
if new_class
|
|
161
|
+
# If any modules were already added for `:default`,
|
|
162
|
+
# re-apply them here
|
|
163
|
+
mods = trace_modules_for(:default)
|
|
164
|
+
mods.each { |mod| new_class.include(mod) }
|
|
149
165
|
trace_mode(:default, new_class)
|
|
150
166
|
backtrace_class = Class.new(new_class)
|
|
151
167
|
backtrace_class.include(GraphQL::Backtrace::Trace)
|
|
152
168
|
trace_mode(:default_backtrace, backtrace_class)
|
|
153
169
|
end
|
|
154
|
-
trace_class_for(:default)
|
|
170
|
+
trace_class_for(:default, build: true)
|
|
155
171
|
end
|
|
156
172
|
|
|
157
173
|
# @return [Class] Return the trace class to use for this mode, looking one up on the superclass if this Schema doesn't have one defined.
|
|
158
|
-
def trace_class_for(mode)
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
end
|
|
168
|
-
Class.new(superclass_base_class)
|
|
169
|
-
when :default_backtrace
|
|
170
|
-
schema_base_class = trace_class_for(:default)
|
|
171
|
-
Class.new(schema_base_class) do
|
|
172
|
-
include(GraphQL::Backtrace::Trace)
|
|
173
|
-
end
|
|
174
|
-
else
|
|
175
|
-
mods = trace_modules_for(mode)
|
|
176
|
-
Class.new(trace_class_for(:default)) do
|
|
177
|
-
mods.any? && include(*mods)
|
|
178
|
-
end
|
|
179
|
-
end
|
|
174
|
+
def trace_class_for(mode, build: false)
|
|
175
|
+
if (trace_class = own_trace_modes[mode])
|
|
176
|
+
trace_class
|
|
177
|
+
elsif superclass.respond_to?(:trace_class_for) && (trace_class = superclass.trace_class_for(mode, build: false))
|
|
178
|
+
trace_class
|
|
179
|
+
elsif build
|
|
180
|
+
own_trace_modes[mode] = build_trace_mode(mode)
|
|
181
|
+
else
|
|
182
|
+
nil
|
|
180
183
|
end
|
|
181
184
|
end
|
|
182
185
|
|
|
183
186
|
# Configure `trace_class` to be used whenever `context: { trace_mode: mode_name }` is requested.
|
|
184
|
-
#
|
|
187
|
+
# {default_trace_mode} is used when no `trace_mode: ...` is requested.
|
|
188
|
+
#
|
|
189
|
+
# When a `trace_class` is added this way, it will _not_ receive other modules added with `trace_with(...)`
|
|
190
|
+
# unless `trace_mode` is explicitly given. (This class will not receive any default trace modules.)
|
|
191
|
+
#
|
|
192
|
+
# Subclasses of the schema will use `trace_class` as a base class for this mode and those
|
|
193
|
+
# subclass also will _not_ receive default tracing modules.
|
|
194
|
+
#
|
|
185
195
|
# @param mode_name [Symbol]
|
|
186
196
|
# @param trace_class [Class] subclass of GraphQL::Tracing::Trace
|
|
187
197
|
# @return void
|
|
188
198
|
def trace_mode(mode_name, trace_class)
|
|
189
|
-
|
|
190
|
-
@trace_modes[mode_name] = trace_class
|
|
199
|
+
own_trace_modes[mode_name] = trace_class
|
|
191
200
|
nil
|
|
192
201
|
end
|
|
193
202
|
|
|
203
|
+
def own_trace_modes
|
|
204
|
+
@own_trace_modes ||= {}
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
module DefaultTraceClass
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
private_constant :DefaultTraceClass
|
|
211
|
+
|
|
212
|
+
def build_trace_mode(mode)
|
|
213
|
+
case mode
|
|
214
|
+
when :default
|
|
215
|
+
# Use the superclass's default mode if it has one, or else start an inheritance chain at the built-in base class.
|
|
216
|
+
base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode)) || GraphQL::Tracing::Trace
|
|
217
|
+
Class.new(base_class) do
|
|
218
|
+
include DefaultTraceClass
|
|
219
|
+
end
|
|
220
|
+
when :default_backtrace
|
|
221
|
+
schema_base_class = trace_class_for(:default, build: true)
|
|
222
|
+
Class.new(schema_base_class) do
|
|
223
|
+
include(GraphQL::Backtrace::Trace)
|
|
224
|
+
end
|
|
225
|
+
else
|
|
226
|
+
# First, see if the superclass has a custom-defined class for this.
|
|
227
|
+
# Then, if it doesn't, use this class's default trace
|
|
228
|
+
base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode)) || trace_class_for(:default, build: true)
|
|
229
|
+
# Prepare the default trace class if it hasn't been initialized yet
|
|
230
|
+
base_class ||= (own_trace_modes[:default] = build_trace_mode(:default))
|
|
231
|
+
mods = trace_modules_for(mode)
|
|
232
|
+
if base_class < DefaultTraceClass
|
|
233
|
+
mods = trace_modules_for(:default) + mods
|
|
234
|
+
end
|
|
235
|
+
# Copy the existing default options into this mode's options
|
|
236
|
+
default_options = trace_options_for(:default)
|
|
237
|
+
add_trace_options_for(mode, default_options)
|
|
238
|
+
|
|
239
|
+
Class.new(base_class) do
|
|
240
|
+
mods.any? && include(*mods)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
194
245
|
def own_trace_modules
|
|
195
246
|
@own_trace_modules ||= Hash.new { |h, k| h[k] = [] }
|
|
196
247
|
end
|
|
@@ -222,7 +273,7 @@ module GraphQL
|
|
|
222
273
|
# @param include_specified_by_url [Boolean] If true, scalar types' `specifiedByUrl:` will be included in the response
|
|
223
274
|
# @param include_is_one_of [Boolean] If true, `isOneOf: true|false` will be included with input objects
|
|
224
275
|
# @return [Hash] GraphQL result
|
|
225
|
-
def as_json(
|
|
276
|
+
def as_json(context: {}, include_deprecated_args: true, include_schema_description: false, include_is_repeatable: false, include_specified_by_url: false, include_is_one_of: false)
|
|
226
277
|
introspection_query = Introspection.query(
|
|
227
278
|
include_deprecated_args: include_deprecated_args,
|
|
228
279
|
include_schema_description: include_schema_description,
|
|
@@ -231,16 +282,14 @@ module GraphQL
|
|
|
231
282
|
include_specified_by_url: include_specified_by_url,
|
|
232
283
|
)
|
|
233
284
|
|
|
234
|
-
execute(introspection_query,
|
|
285
|
+
execute(introspection_query, context: context).to_h
|
|
235
286
|
end
|
|
236
287
|
|
|
237
288
|
# Return the GraphQL IDL for the schema
|
|
238
289
|
# @param context [Hash]
|
|
239
|
-
# @param only [<#call(member, ctx)>]
|
|
240
|
-
# @param except [<#call(member, ctx)>]
|
|
241
290
|
# @return [String]
|
|
242
|
-
def to_definition(
|
|
243
|
-
GraphQL::Schema::Printer.print_schema(self,
|
|
291
|
+
def to_definition(context: {})
|
|
292
|
+
GraphQL::Schema::Printer.print_schema(self, context: context)
|
|
244
293
|
end
|
|
245
294
|
|
|
246
295
|
# Return the GraphQL::Language::Document IDL AST for the schema
|
|
@@ -268,20 +317,6 @@ module GraphQL
|
|
|
268
317
|
@find_cache[path] ||= @finder.find(path)
|
|
269
318
|
end
|
|
270
319
|
|
|
271
|
-
def default_filter
|
|
272
|
-
GraphQL::Filter.new(except: default_mask)
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
def default_mask(new_mask = nil)
|
|
276
|
-
if new_mask
|
|
277
|
-
line = caller(2, 10).find { |l| !l.include?("lib/graphql") }
|
|
278
|
-
GraphQL::Deprecation.warn("GraphQL::Filter and Schema.mask are deprecated and will be removed in v2.1.0. Implement `visible?` on your schema members instead (https://graphql-ruby.org/authorization/visibility.html).\n #{line}")
|
|
279
|
-
@own_default_mask = new_mask
|
|
280
|
-
else
|
|
281
|
-
@own_default_mask || find_inherited_value(:default_mask, Schema::NullMask)
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
|
|
285
320
|
def static_validator
|
|
286
321
|
GraphQL::StaticValidation::Validator.new(schema: self)
|
|
287
322
|
end
|
|
@@ -302,7 +337,7 @@ module GraphQL
|
|
|
302
337
|
# Build a map of `{ name => type }` and return it
|
|
303
338
|
# @return [Hash<String => Class>] A dictionary of type classes by their GraphQL name
|
|
304
339
|
# @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes.
|
|
305
|
-
def types(context = GraphQL::Query::NullContext)
|
|
340
|
+
def types(context = GraphQL::Query::NullContext.instance)
|
|
306
341
|
all_types = non_introspection_types.merge(introspection_system.types)
|
|
307
342
|
visible_types = {}
|
|
308
343
|
all_types.each do |k, v|
|
|
@@ -329,7 +364,7 @@ module GraphQL
|
|
|
329
364
|
|
|
330
365
|
# @param type_name [String]
|
|
331
366
|
# @return [Module, nil] A type, or nil if there's no type called `type_name`
|
|
332
|
-
def get_type(type_name, context = GraphQL::Query::NullContext)
|
|
367
|
+
def get_type(type_name, context = GraphQL::Query::NullContext.instance)
|
|
333
368
|
local_entry = own_types[type_name]
|
|
334
369
|
type_defn = case local_entry
|
|
335
370
|
when nil
|
|
@@ -360,6 +395,11 @@ module GraphQL
|
|
|
360
395
|
(superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
|
|
361
396
|
end
|
|
362
397
|
|
|
398
|
+
# @return [Boolean] Does this schema have _any_ definition for a type named `type_name`, regardless of visibility?
|
|
399
|
+
def has_defined_type?(type_name)
|
|
400
|
+
own_types.key?(type_name) || introspection_system.types.key?(type_name) || (superclass.respond_to?(:has_defined_type?) ? superclass.has_defined_type?(type_name) : false)
|
|
401
|
+
end
|
|
402
|
+
|
|
363
403
|
# @api private
|
|
364
404
|
attr_writer :connections
|
|
365
405
|
|
|
@@ -460,13 +500,13 @@ module GraphQL
|
|
|
460
500
|
# @param type [Module] The type definition whose possible types you want to see
|
|
461
501
|
# @return [Hash<String, Module>] All possible types, if no `type` is given.
|
|
462
502
|
# @return [Array<Module>] Possible types for `type`, if it's given.
|
|
463
|
-
def possible_types(type = nil, context = GraphQL::Query::NullContext)
|
|
503
|
+
def possible_types(type = nil, context = GraphQL::Query::NullContext.instance)
|
|
464
504
|
if type
|
|
465
505
|
# TODO duck-typing `.possible_types` would probably be nicer here
|
|
466
506
|
if type.kind.union?
|
|
467
507
|
type.possible_types(context: context)
|
|
468
508
|
else
|
|
469
|
-
stored_possible_types = own_possible_types[type
|
|
509
|
+
stored_possible_types = own_possible_types[type]
|
|
470
510
|
visible_possible_types = if stored_possible_types && type.kind.interface?
|
|
471
511
|
stored_possible_types.select do |possible_type|
|
|
472
512
|
possible_type.interfaces(context).include?(type)
|
|
@@ -475,7 +515,7 @@ module GraphQL
|
|
|
475
515
|
stored_possible_types
|
|
476
516
|
end
|
|
477
517
|
visible_possible_types ||
|
|
478
|
-
introspection_system.possible_types[type
|
|
518
|
+
introspection_system.possible_types[type] ||
|
|
479
519
|
(
|
|
480
520
|
superclass.respond_to?(:possible_types) ?
|
|
481
521
|
superclass.possible_types(type, context) :
|
|
@@ -513,18 +553,12 @@ module GraphQL
|
|
|
513
553
|
attr_writer :dataloader_class
|
|
514
554
|
|
|
515
555
|
def references_to(to_type = nil, from: nil)
|
|
516
|
-
@own_references_to ||= Hash.new { |h, k| h[k] = [] }
|
|
517
556
|
if to_type
|
|
518
|
-
if !to_type.is_a?(String)
|
|
519
|
-
to_type = to_type.graphql_name
|
|
520
|
-
end
|
|
521
|
-
|
|
522
557
|
if from
|
|
523
|
-
|
|
558
|
+
refs = own_references_to[to_type] ||= []
|
|
559
|
+
refs << from
|
|
524
560
|
else
|
|
525
|
-
|
|
526
|
-
inherited_refs = find_inherited_value(:references_to, EMPTY_HASH)[to_type] || EMPTY_ARRAY
|
|
527
|
-
own_refs + inherited_refs
|
|
561
|
+
get_references_to(to_type) || EMPTY_ARRAY
|
|
528
562
|
end
|
|
529
563
|
else
|
|
530
564
|
# `@own_references_to` can be quite large for big schemas,
|
|
@@ -532,9 +566,9 @@ module GraphQL
|
|
|
532
566
|
# So optimize the most common case -- don't create a duplicate Hash.
|
|
533
567
|
inherited_value = find_inherited_value(:references_to, EMPTY_HASH)
|
|
534
568
|
if inherited_value.any?
|
|
535
|
-
inherited_value.merge(
|
|
569
|
+
inherited_value.merge(own_references_to)
|
|
536
570
|
else
|
|
537
|
-
|
|
571
|
+
own_references_to
|
|
538
572
|
end
|
|
539
573
|
end
|
|
540
574
|
end
|
|
@@ -544,7 +578,7 @@ module GraphQL
|
|
|
544
578
|
GraphQL::Schema::TypeExpression.build_type(type_owner, ast_node)
|
|
545
579
|
end
|
|
546
580
|
|
|
547
|
-
def get_field(type_or_name, field_name, context = GraphQL::Query::NullContext)
|
|
581
|
+
def get_field(type_or_name, field_name, context = GraphQL::Query::NullContext.instance)
|
|
548
582
|
parent_type = case type_or_name
|
|
549
583
|
when LateBoundType
|
|
550
584
|
get_type(type_or_name.name, context)
|
|
@@ -567,7 +601,7 @@ module GraphQL
|
|
|
567
601
|
end
|
|
568
602
|
end
|
|
569
603
|
|
|
570
|
-
def get_fields(type, context = GraphQL::Query::NullContext)
|
|
604
|
+
def get_fields(type, context = GraphQL::Query::NullContext.instance)
|
|
571
605
|
type.fields(context)
|
|
572
606
|
end
|
|
573
607
|
|
|
@@ -604,6 +638,17 @@ module GraphQL
|
|
|
604
638
|
end
|
|
605
639
|
end
|
|
606
640
|
|
|
641
|
+
# A limit on the number of tokens to accept on incoming query strings.
|
|
642
|
+
# Use this to prevent parsing maliciously-large query strings.
|
|
643
|
+
# @return [nil, Integer]
|
|
644
|
+
def max_query_string_tokens(new_max_tokens = NOT_CONFIGURED)
|
|
645
|
+
if NOT_CONFIGURED.equal?(new_max_tokens)
|
|
646
|
+
defined?(@max_query_string_tokens) ? @max_query_string_tokens : find_inherited_value(:max_query_string_tokens)
|
|
647
|
+
else
|
|
648
|
+
@max_query_string_tokens = new_max_tokens
|
|
649
|
+
end
|
|
650
|
+
end
|
|
651
|
+
|
|
607
652
|
def default_page_size(new_default_page_size = nil)
|
|
608
653
|
if new_default_page_size
|
|
609
654
|
@default_page_size = new_default_page_size
|
|
@@ -612,27 +657,39 @@ module GraphQL
|
|
|
612
657
|
end
|
|
613
658
|
end
|
|
614
659
|
|
|
615
|
-
def query_execution_strategy(new_query_execution_strategy = nil)
|
|
660
|
+
def query_execution_strategy(new_query_execution_strategy = nil, deprecation_warning: true)
|
|
661
|
+
if deprecation_warning
|
|
662
|
+
warn "GraphQL::Schema.query_execution_strategy is deprecated without replacement. Use `GraphQL::Query.new` directly to create and execute a custom query instead."
|
|
663
|
+
warn " #{caller(1, 1).first}"
|
|
664
|
+
end
|
|
616
665
|
if new_query_execution_strategy
|
|
617
666
|
@query_execution_strategy = new_query_execution_strategy
|
|
618
667
|
else
|
|
619
|
-
@query_execution_strategy ||
|
|
668
|
+
@query_execution_strategy || (superclass.respond_to?(:query_execution_strategy) ? superclass.query_execution_strategy(deprecation_warning: false) : self.default_execution_strategy)
|
|
620
669
|
end
|
|
621
670
|
end
|
|
622
671
|
|
|
623
|
-
def mutation_execution_strategy(new_mutation_execution_strategy = nil)
|
|
672
|
+
def mutation_execution_strategy(new_mutation_execution_strategy = nil, deprecation_warning: true)
|
|
673
|
+
if deprecation_warning
|
|
674
|
+
warn "GraphQL::Schema.mutation_execution_strategy is deprecated without replacement. Use `GraphQL::Query.new` directly to create and execute a custom query instead."
|
|
675
|
+
warn " #{caller(1, 1).first}"
|
|
676
|
+
end
|
|
624
677
|
if new_mutation_execution_strategy
|
|
625
678
|
@mutation_execution_strategy = new_mutation_execution_strategy
|
|
626
679
|
else
|
|
627
|
-
@mutation_execution_strategy ||
|
|
680
|
+
@mutation_execution_strategy || (superclass.respond_to?(:mutation_execution_strategy) ? superclass.mutation_execution_strategy(deprecation_warning: false) : self.default_execution_strategy)
|
|
628
681
|
end
|
|
629
682
|
end
|
|
630
683
|
|
|
631
|
-
def subscription_execution_strategy(new_subscription_execution_strategy = nil)
|
|
684
|
+
def subscription_execution_strategy(new_subscription_execution_strategy = nil, deprecation_warning: true)
|
|
685
|
+
if deprecation_warning
|
|
686
|
+
warn "GraphQL::Schema.subscription_execution_strategy is deprecated without replacement. Use `GraphQL::Query.new` directly to create and execute a custom query instead."
|
|
687
|
+
warn " #{caller(1, 1).first}"
|
|
688
|
+
end
|
|
632
689
|
if new_subscription_execution_strategy
|
|
633
690
|
@subscription_execution_strategy = new_subscription_execution_strategy
|
|
634
691
|
else
|
|
635
|
-
@subscription_execution_strategy ||
|
|
692
|
+
@subscription_execution_strategy || (superclass.respond_to?(:subscription_execution_strategy) ? superclass.subscription_execution_strategy(deprecation_warning: false) : self.default_execution_strategy)
|
|
636
693
|
end
|
|
637
694
|
end
|
|
638
695
|
|
|
@@ -657,7 +714,7 @@ module GraphQL
|
|
|
657
714
|
else
|
|
658
715
|
string_or_document
|
|
659
716
|
end
|
|
660
|
-
query =
|
|
717
|
+
query = query_class.new(self, document: doc, context: context)
|
|
661
718
|
validator_opts = { schema: self }
|
|
662
719
|
rules && (validator_opts[:rules] = rules)
|
|
663
720
|
validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
|
|
@@ -665,6 +722,14 @@ module GraphQL
|
|
|
665
722
|
res[:errors]
|
|
666
723
|
end
|
|
667
724
|
|
|
725
|
+
def query_class(new_query_class = NOT_CONFIGURED)
|
|
726
|
+
if NOT_CONFIGURED.equal?(new_query_class)
|
|
727
|
+
@query_class || (superclass.respond_to?(:query_class) ? superclass.query_class : GraphQL::Query)
|
|
728
|
+
else
|
|
729
|
+
@query_class = new_query_class
|
|
730
|
+
end
|
|
731
|
+
end
|
|
732
|
+
|
|
668
733
|
attr_writer :validate_max_errors
|
|
669
734
|
|
|
670
735
|
def validate_max_errors(new_validate_max_errors = nil)
|
|
@@ -679,9 +744,10 @@ module GraphQL
|
|
|
679
744
|
|
|
680
745
|
attr_writer :max_complexity
|
|
681
746
|
|
|
682
|
-
def max_complexity(max_complexity = nil)
|
|
747
|
+
def max_complexity(max_complexity = nil, count_introspection_fields: true)
|
|
683
748
|
if max_complexity
|
|
684
749
|
@max_complexity = max_complexity
|
|
750
|
+
@max_complexity_count_introspection_fields = count_introspection_fields
|
|
685
751
|
elsif defined?(@max_complexity)
|
|
686
752
|
@max_complexity
|
|
687
753
|
else
|
|
@@ -689,6 +755,14 @@ module GraphQL
|
|
|
689
755
|
end
|
|
690
756
|
end
|
|
691
757
|
|
|
758
|
+
def max_complexity_count_introspection_fields
|
|
759
|
+
if defined?(@max_complexity_count_introspection_fields)
|
|
760
|
+
@max_complexity_count_introspection_fields
|
|
761
|
+
else
|
|
762
|
+
find_inherited_value(:max_complexity_count_introspection_fields, true)
|
|
763
|
+
end
|
|
764
|
+
end
|
|
765
|
+
|
|
692
766
|
attr_writer :analysis_engine
|
|
693
767
|
|
|
694
768
|
def analysis_engine
|
|
@@ -707,6 +781,7 @@ module GraphQL
|
|
|
707
781
|
|
|
708
782
|
def error_bubbling(new_error_bubbling = nil)
|
|
709
783
|
if !new_error_bubbling.nil?
|
|
784
|
+
warn("error_bubbling(#{new_error_bubbling.inspect}) is deprecated; the default value of `false` will be the only option in GraphQL-Ruby 3.0")
|
|
710
785
|
@error_bubbling = new_error_bubbling
|
|
711
786
|
else
|
|
712
787
|
@error_bubbling.nil? ? find_inherited_value(:error_bubbling) : @error_bubbling
|
|
@@ -717,9 +792,10 @@ module GraphQL
|
|
|
717
792
|
|
|
718
793
|
attr_writer :max_depth
|
|
719
794
|
|
|
720
|
-
def max_depth(new_max_depth = nil)
|
|
795
|
+
def max_depth(new_max_depth = nil, count_introspection_fields: true)
|
|
721
796
|
if new_max_depth
|
|
722
797
|
@max_depth = new_max_depth
|
|
798
|
+
@count_introspection_fields = count_introspection_fields
|
|
723
799
|
elsif defined?(@max_depth)
|
|
724
800
|
@max_depth
|
|
725
801
|
else
|
|
@@ -727,6 +803,14 @@ module GraphQL
|
|
|
727
803
|
end
|
|
728
804
|
end
|
|
729
805
|
|
|
806
|
+
def count_introspection_fields
|
|
807
|
+
if defined?(@count_introspection_fields)
|
|
808
|
+
@count_introspection_fields
|
|
809
|
+
else
|
|
810
|
+
find_inherited_value(:count_introspection_fields, true)
|
|
811
|
+
end
|
|
812
|
+
end
|
|
813
|
+
|
|
730
814
|
def disable_introspection_entry_points
|
|
731
815
|
@disable_introspection_entry_points = true
|
|
732
816
|
# TODO: this clears the cache made in `def types`. But this is not a great solution.
|
|
@@ -769,14 +853,54 @@ module GraphQL
|
|
|
769
853
|
end
|
|
770
854
|
end
|
|
771
855
|
|
|
856
|
+
# @param new_extra_types [Module] Type definitions to include in printing and introspection, even though they aren't referenced in the schema
|
|
857
|
+
# @return [Array<Module>] Type definitions added to this schema
|
|
858
|
+
def extra_types(*new_extra_types)
|
|
859
|
+
if new_extra_types.any?
|
|
860
|
+
new_extra_types = new_extra_types.flatten
|
|
861
|
+
@own_extra_types ||= []
|
|
862
|
+
@own_extra_types.concat(new_extra_types)
|
|
863
|
+
end
|
|
864
|
+
inherited_et = find_inherited_value(:extra_types, nil)
|
|
865
|
+
if inherited_et
|
|
866
|
+
if @own_extra_types
|
|
867
|
+
inherited_et + @own_extra_types
|
|
868
|
+
else
|
|
869
|
+
inherited_et
|
|
870
|
+
end
|
|
871
|
+
else
|
|
872
|
+
@own_extra_types || EMPTY_ARRAY
|
|
873
|
+
end
|
|
874
|
+
end
|
|
875
|
+
|
|
772
876
|
def orphan_types(*new_orphan_types)
|
|
773
877
|
if new_orphan_types.any?
|
|
774
878
|
new_orphan_types = new_orphan_types.flatten
|
|
879
|
+
non_object_types = new_orphan_types.reject { |ot| ot.is_a?(Class) && ot < GraphQL::Schema::Object }
|
|
880
|
+
if non_object_types.any?
|
|
881
|
+
raise ArgumentError, <<~ERR
|
|
882
|
+
Only object type classes should be added as `orphan_types(...)`.
|
|
883
|
+
|
|
884
|
+
- Remove these no-op types from `orphan_types`: #{non_object_types.map { |t| "#{t.inspect} (#{t.kind.name})"}.join(", ")}
|
|
885
|
+
- See https://graphql-ruby.org/type_definitions/interfaces.html#orphan-types
|
|
886
|
+
|
|
887
|
+
To add other types to your schema, you might want `extra_types`: https://graphql-ruby.org/schema/definition.html#extra-types
|
|
888
|
+
ERR
|
|
889
|
+
end
|
|
775
890
|
add_type_and_traverse(new_orphan_types, root: false)
|
|
776
891
|
own_orphan_types.concat(new_orphan_types.flatten)
|
|
777
892
|
end
|
|
778
893
|
|
|
779
|
-
find_inherited_value(:orphan_types,
|
|
894
|
+
inherited_ot = find_inherited_value(:orphan_types, nil)
|
|
895
|
+
if inherited_ot
|
|
896
|
+
if own_orphan_types.any?
|
|
897
|
+
inherited_ot + own_orphan_types
|
|
898
|
+
else
|
|
899
|
+
inherited_ot
|
|
900
|
+
end
|
|
901
|
+
else
|
|
902
|
+
own_orphan_types
|
|
903
|
+
end
|
|
780
904
|
end
|
|
781
905
|
|
|
782
906
|
def default_execution_strategy
|
|
@@ -795,6 +919,26 @@ module GraphQL
|
|
|
795
919
|
end
|
|
796
920
|
end
|
|
797
921
|
|
|
922
|
+
def default_logger(new_default_logger = NOT_CONFIGURED)
|
|
923
|
+
if NOT_CONFIGURED.equal?(new_default_logger)
|
|
924
|
+
if defined?(@default_logger)
|
|
925
|
+
@default_logger
|
|
926
|
+
elsif superclass.respond_to?(:default_logger)
|
|
927
|
+
superclass.default_logger
|
|
928
|
+
elsif defined?(Rails) && Rails.respond_to?(:logger) && (rails_logger = Rails.logger)
|
|
929
|
+
rails_logger
|
|
930
|
+
else
|
|
931
|
+
def_logger = Logger.new($stdout)
|
|
932
|
+
def_logger.info! # It doesn't output debug info by default
|
|
933
|
+
def_logger
|
|
934
|
+
end
|
|
935
|
+
elsif new_default_logger == nil
|
|
936
|
+
@default_logger = Logger.new(IO::NULL)
|
|
937
|
+
else
|
|
938
|
+
@default_logger = new_default_logger
|
|
939
|
+
end
|
|
940
|
+
end
|
|
941
|
+
|
|
798
942
|
def context_class(new_context_class = nil)
|
|
799
943
|
if new_context_class
|
|
800
944
|
@context_class = new_context_class
|
|
@@ -870,17 +1014,19 @@ module GraphQL
|
|
|
870
1014
|
end
|
|
871
1015
|
|
|
872
1016
|
def resolve_type(type, obj, ctx)
|
|
873
|
-
|
|
874
|
-
type
|
|
875
|
-
else
|
|
876
|
-
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
|
|
877
|
-
end
|
|
1017
|
+
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types, Interface types, or `loads:` (tried to resolve: #{type.name})"
|
|
878
1018
|
end
|
|
879
1019
|
# rubocop:enable Lint/DuplicateMethods
|
|
880
1020
|
|
|
881
1021
|
def inherited(child_class)
|
|
882
1022
|
if self == GraphQL::Schema
|
|
883
1023
|
child_class.directives(default_directives.values)
|
|
1024
|
+
child_class.extend(SubclassGetReferencesTo)
|
|
1025
|
+
end
|
|
1026
|
+
# Make sure the child class has these built out, so that
|
|
1027
|
+
# subclasses can be modified by later calls to `trace_with`
|
|
1028
|
+
own_trace_modes.each do |name, _class|
|
|
1029
|
+
child_class.own_trace_modes[name] = child_class.build_trace_mode(name)
|
|
884
1030
|
end
|
|
885
1031
|
child_class.singleton_class.prepend(ResolveTypeWithType)
|
|
886
1032
|
super
|
|
@@ -968,6 +1114,12 @@ module GraphQL
|
|
|
968
1114
|
end
|
|
969
1115
|
|
|
970
1116
|
def instrument(instrument_step, instrumenter, options = {})
|
|
1117
|
+
warn <<~WARN
|
|
1118
|
+
Schema.instrument is deprecated, use `trace_with` instead: https://graphql-ruby.org/queries/tracing.html"
|
|
1119
|
+
(From `#{self}.instrument(#{instrument_step}, #{instrumenter})` at #{caller(1, 1).first})
|
|
1120
|
+
|
|
1121
|
+
WARN
|
|
1122
|
+
trace_with(Tracing::LegacyHooksTrace)
|
|
971
1123
|
own_instrumenters[instrument_step] << instrumenter
|
|
972
1124
|
end
|
|
973
1125
|
|
|
@@ -978,7 +1130,12 @@ module GraphQL
|
|
|
978
1130
|
new_directives.flatten.each { |d| directive(d) }
|
|
979
1131
|
end
|
|
980
1132
|
|
|
981
|
-
find_inherited_value(:directives, default_directives)
|
|
1133
|
+
inherited_dirs = find_inherited_value(:directives, default_directives)
|
|
1134
|
+
if own_directives.any?
|
|
1135
|
+
inherited_dirs.merge(own_directives)
|
|
1136
|
+
else
|
|
1137
|
+
inherited_dirs
|
|
1138
|
+
end
|
|
982
1139
|
end
|
|
983
1140
|
|
|
984
1141
|
# Attach a single directive to this schema
|
|
@@ -994,11 +1151,17 @@ module GraphQL
|
|
|
994
1151
|
"skip" => GraphQL::Schema::Directive::Skip,
|
|
995
1152
|
"deprecated" => GraphQL::Schema::Directive::Deprecated,
|
|
996
1153
|
"oneOf" => GraphQL::Schema::Directive::OneOf,
|
|
1154
|
+
"specifiedBy" => GraphQL::Schema::Directive::SpecifiedBy,
|
|
997
1155
|
}.freeze
|
|
998
1156
|
end
|
|
999
1157
|
|
|
1000
|
-
def tracer(new_tracer)
|
|
1001
|
-
if !
|
|
1158
|
+
def tracer(new_tracer, silence_deprecation_warning: false)
|
|
1159
|
+
if !silence_deprecation_warning
|
|
1160
|
+
warn("`Schema.tracer(#{new_tracer.inspect})` is deprecated; use module-based `trace_with` instead. See: https://graphql-ruby.org/queries/tracing.html")
|
|
1161
|
+
warn " #{caller(1, 1).first}"
|
|
1162
|
+
end
|
|
1163
|
+
default_trace = trace_class_for(:default, build: true)
|
|
1164
|
+
if default_trace.nil? || !(default_trace < GraphQL::Tracing::CallLegacyTracers)
|
|
1002
1165
|
trace_with(GraphQL::Tracing::CallLegacyTracers)
|
|
1003
1166
|
end
|
|
1004
1167
|
|
|
@@ -1020,13 +1183,26 @@ module GraphQL
|
|
|
1020
1183
|
if mode.is_a?(Array)
|
|
1021
1184
|
mode.each { |m| trace_with(trace_mod, mode: m, **options) }
|
|
1022
1185
|
else
|
|
1023
|
-
tc =
|
|
1186
|
+
tc = own_trace_modes[mode] ||= build_trace_mode(mode)
|
|
1024
1187
|
tc.include(trace_mod)
|
|
1025
|
-
|
|
1026
|
-
|
|
1188
|
+
own_trace_modules[mode] << trace_mod
|
|
1189
|
+
add_trace_options_for(mode, options)
|
|
1190
|
+
if mode == :default
|
|
1191
|
+
# This module is being added as a default tracer. If any other mode classes
|
|
1192
|
+
# have already been created, but get their default behavior from a superclass,
|
|
1193
|
+
# Then mix this into this schema's subclass.
|
|
1194
|
+
# (But don't mix it into mode classes that aren't default-based.)
|
|
1195
|
+
own_trace_modes.each do |other_mode_name, other_mode_class|
|
|
1196
|
+
if other_mode_class < DefaultTraceClass
|
|
1197
|
+
# Don't add it back to the inheritance tree if it's already there
|
|
1198
|
+
if !(other_mode_class < trace_mod)
|
|
1199
|
+
other_mode_class.include(trace_mod)
|
|
1200
|
+
end
|
|
1201
|
+
# Add any options so they'll be available
|
|
1202
|
+
add_trace_options_for(other_mode_name, options)
|
|
1203
|
+
end
|
|
1204
|
+
end
|
|
1027
1205
|
end
|
|
1028
|
-
t_opts = trace_options_for(mode)
|
|
1029
|
-
t_opts.merge!(options)
|
|
1030
1206
|
end
|
|
1031
1207
|
nil
|
|
1032
1208
|
end
|
|
@@ -1036,16 +1212,22 @@ module GraphQL
|
|
|
1036
1212
|
def trace_options_for(mode)
|
|
1037
1213
|
@trace_options_for_mode ||= {}
|
|
1038
1214
|
@trace_options_for_mode[mode] ||= begin
|
|
1215
|
+
# It may be time to create an options hash for a mode that wasn't registered yet.
|
|
1216
|
+
# Mix in the default options in that case.
|
|
1217
|
+
default_options = mode == :default ? EMPTY_HASH : trace_options_for(:default)
|
|
1218
|
+
# Make sure this returns a new object so that other hashes aren't modified later
|
|
1039
1219
|
if superclass.respond_to?(:trace_options_for)
|
|
1040
|
-
superclass.trace_options_for(mode).
|
|
1220
|
+
superclass.trace_options_for(mode).merge(default_options)
|
|
1041
1221
|
else
|
|
1042
|
-
|
|
1222
|
+
default_options.dup
|
|
1043
1223
|
end
|
|
1044
1224
|
end
|
|
1045
1225
|
end
|
|
1046
1226
|
|
|
1047
1227
|
# Create a trace instance which will include the trace modules specified for the optional mode.
|
|
1048
1228
|
#
|
|
1229
|
+
# If no `mode:` is given, then {default_trace_mode} will be used.
|
|
1230
|
+
#
|
|
1049
1231
|
# @param mode [Symbol] Trace modules for this trade mode will be included
|
|
1050
1232
|
# @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
|
|
1051
1233
|
# @return [Tracing::Trace]
|
|
@@ -1056,14 +1238,21 @@ module GraphQL
|
|
|
1056
1238
|
trace_mode = if mode
|
|
1057
1239
|
mode
|
|
1058
1240
|
elsif target && target.context[:backtrace]
|
|
1059
|
-
:
|
|
1241
|
+
if default_trace_mode != :default
|
|
1242
|
+
raise ArgumentError, "Can't use `context[:backtrace]` with a custom default trace mode (`#{dm.inspect}`)"
|
|
1243
|
+
else
|
|
1244
|
+
own_trace_modes[:default_backtrace] ||= build_trace_mode(:default_backtrace)
|
|
1245
|
+
options_trace_mode = :default
|
|
1246
|
+
:default_backtrace
|
|
1247
|
+
end
|
|
1060
1248
|
else
|
|
1061
|
-
|
|
1249
|
+
default_trace_mode
|
|
1062
1250
|
end
|
|
1063
1251
|
|
|
1064
|
-
|
|
1252
|
+
options_trace_mode ||= trace_mode
|
|
1253
|
+
base_trace_options = trace_options_for(options_trace_mode)
|
|
1065
1254
|
trace_options = base_trace_options.merge(options)
|
|
1066
|
-
trace_class_for_mode = trace_class_for(trace_mode)
|
|
1255
|
+
trace_class_for_mode = trace_class_for(trace_mode, build: true)
|
|
1067
1256
|
trace_class_for_mode.new(**trace_options)
|
|
1068
1257
|
end
|
|
1069
1258
|
|
|
@@ -1093,7 +1282,7 @@ module GraphQL
|
|
|
1093
1282
|
|
|
1094
1283
|
# Execute a query on itself.
|
|
1095
1284
|
# @see {Query#initialize} for arguments.
|
|
1096
|
-
# @return [
|
|
1285
|
+
# @return [GraphQL::Query::Result] query result, ready to be serialized as JSON
|
|
1097
1286
|
def execute(query_str = nil, **kwargs)
|
|
1098
1287
|
if query_str
|
|
1099
1288
|
kwargs[:query] = query_str
|
|
@@ -1133,7 +1322,7 @@ module GraphQL
|
|
|
1133
1322
|
# @see {Execution::Multiplex#run_all} for multiplex keyword arguments
|
|
1134
1323
|
# @param queries [Array<Hash>] Keyword arguments for each query
|
|
1135
1324
|
# @param context [Hash] Multiplex-level context
|
|
1136
|
-
# @return [Array<
|
|
1325
|
+
# @return [Array<GraphQL::Query::Result>] One result for each query in the input
|
|
1137
1326
|
def multiplex(queries, **kwargs)
|
|
1138
1327
|
GraphQL::Execution::Interpreter.run_all(self, queries, **kwargs)
|
|
1139
1328
|
end
|
|
@@ -1217,6 +1406,12 @@ module GraphQL
|
|
|
1217
1406
|
|
|
1218
1407
|
private
|
|
1219
1408
|
|
|
1409
|
+
def add_trace_options_for(mode, new_options)
|
|
1410
|
+
t_opts = trace_options_for(mode)
|
|
1411
|
+
t_opts.merge!(new_options)
|
|
1412
|
+
nil
|
|
1413
|
+
end
|
|
1414
|
+
|
|
1220
1415
|
# @param t [Module, Array<Module>]
|
|
1221
1416
|
# @return [void]
|
|
1222
1417
|
def add_type_and_traverse(t, root:)
|
|
@@ -1260,7 +1455,8 @@ module GraphQL
|
|
|
1260
1455
|
own_union_memberships.merge!(addition.union_memberships)
|
|
1261
1456
|
|
|
1262
1457
|
addition.references.each { |thing, pointers|
|
|
1263
|
-
|
|
1458
|
+
prev_refs = own_references_to[thing] || []
|
|
1459
|
+
own_references_to[thing] = prev_refs | pointers.to_a
|
|
1264
1460
|
}
|
|
1265
1461
|
|
|
1266
1462
|
addition.directives.each { |dir_class| own_directives[dir_class.graphql_name] = dir_class }
|
|
@@ -1278,7 +1474,7 @@ module GraphQL
|
|
|
1278
1474
|
else
|
|
1279
1475
|
@lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
|
|
1280
1476
|
@lazy_methods.set(GraphQL::Execution::Lazy, :value)
|
|
1281
|
-
@lazy_methods.set(GraphQL::Dataloader::Request, :
|
|
1477
|
+
@lazy_methods.set(GraphQL::Dataloader::Request, :load_with_deprecation_warning)
|
|
1282
1478
|
end
|
|
1283
1479
|
end
|
|
1284
1480
|
@lazy_methods
|
|
@@ -1288,6 +1484,10 @@ module GraphQL
|
|
|
1288
1484
|
@own_types ||= {}
|
|
1289
1485
|
end
|
|
1290
1486
|
|
|
1487
|
+
def own_references_to
|
|
1488
|
+
@own_references_to ||= {}.tap(&:compare_by_identity)
|
|
1489
|
+
end
|
|
1490
|
+
|
|
1291
1491
|
def non_introspection_types
|
|
1292
1492
|
find_inherited_value(:non_introspection_types, EMPTY_HASH).merge(own_types)
|
|
1293
1493
|
end
|
|
@@ -1301,7 +1501,7 @@ module GraphQL
|
|
|
1301
1501
|
end
|
|
1302
1502
|
|
|
1303
1503
|
def own_possible_types
|
|
1304
|
-
@own_possible_types ||= {}
|
|
1504
|
+
@own_possible_types ||= {}.tap(&:compare_by_identity)
|
|
1305
1505
|
end
|
|
1306
1506
|
|
|
1307
1507
|
def own_union_memberships
|
|
@@ -1327,6 +1527,27 @@ module GraphQL
|
|
|
1327
1527
|
def own_multiplex_analyzers
|
|
1328
1528
|
@own_multiplex_analyzers ||= []
|
|
1329
1529
|
end
|
|
1530
|
+
|
|
1531
|
+
# This is overridden in subclasses to check the inheritance chain
|
|
1532
|
+
def get_references_to(type_defn)
|
|
1533
|
+
own_references_to[type_defn]
|
|
1534
|
+
end
|
|
1535
|
+
end
|
|
1536
|
+
|
|
1537
|
+
module SubclassGetReferencesTo
|
|
1538
|
+
def get_references_to(type_defn)
|
|
1539
|
+
own_refs = own_references_to[type_defn]
|
|
1540
|
+
inherited_refs = superclass.references_to(type_defn)
|
|
1541
|
+
if inherited_refs&.any?
|
|
1542
|
+
if own_refs&.any?
|
|
1543
|
+
own_refs + inherited_refs
|
|
1544
|
+
else
|
|
1545
|
+
inherited_refs
|
|
1546
|
+
end
|
|
1547
|
+
else
|
|
1548
|
+
own_refs
|
|
1549
|
+
end
|
|
1550
|
+
end
|
|
1330
1551
|
end
|
|
1331
1552
|
|
|
1332
1553
|
# Install these here so that subclasses will also install it.
|