graphql 1.11.5 → 1.12.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +5 -5
  3. data/lib/generators/graphql/object_generator.rb +2 -0
  4. data/lib/generators/graphql/relay_generator.rb +63 -0
  5. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  6. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  7. data/lib/generators/graphql/templates/node_type.erb +9 -0
  8. data/lib/generators/graphql/templates/object.erb +1 -1
  9. data/lib/generators/graphql/templates/query_type.erb +1 -3
  10. data/lib/generators/graphql/templates/schema.erb +8 -35
  11. data/lib/graphql.rb +39 -4
  12. data/lib/graphql/analysis/analyze_query.rb +7 -0
  13. data/lib/graphql/analysis/ast.rb +11 -2
  14. data/lib/graphql/analysis/ast/visitor.rb +9 -1
  15. data/lib/graphql/backtrace.rb +28 -19
  16. data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
  17. data/lib/graphql/backtrace/table.rb +22 -2
  18. data/lib/graphql/backtrace/tracer.rb +40 -9
  19. data/lib/graphql/backwards_compatibility.rb +2 -1
  20. data/lib/graphql/base_type.rb +1 -1
  21. data/lib/graphql/compatibility/execution_specification.rb +1 -0
  22. data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
  23. data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
  24. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
  25. data/lib/graphql/dataloader.rb +198 -0
  26. data/lib/graphql/dataloader/null_dataloader.rb +21 -0
  27. data/lib/graphql/dataloader/request.rb +24 -0
  28. data/lib/graphql/dataloader/request_all.rb +22 -0
  29. data/lib/graphql/dataloader/source.rb +93 -0
  30. data/lib/graphql/define/assign_global_id_field.rb +2 -2
  31. data/lib/graphql/define/instance_definable.rb +32 -2
  32. data/lib/graphql/define/type_definer.rb +5 -5
  33. data/lib/graphql/deprecated_dsl.rb +7 -2
  34. data/lib/graphql/deprecation.rb +13 -0
  35. data/lib/graphql/enum_type.rb +2 -0
  36. data/lib/graphql/execution/errors.rb +4 -0
  37. data/lib/graphql/execution/execute.rb +7 -0
  38. data/lib/graphql/execution/interpreter.rb +10 -6
  39. data/lib/graphql/execution/interpreter/arguments.rb +57 -5
  40. data/lib/graphql/execution/interpreter/arguments_cache.rb +8 -0
  41. data/lib/graphql/execution/interpreter/handles_raw_value.rb +0 -7
  42. data/lib/graphql/execution/interpreter/runtime.rb +219 -117
  43. data/lib/graphql/execution/multiplex.rb +20 -6
  44. data/lib/graphql/function.rb +4 -0
  45. data/lib/graphql/input_object_type.rb +2 -0
  46. data/lib/graphql/integer_decoding_error.rb +17 -0
  47. data/lib/graphql/interface_type.rb +3 -1
  48. data/lib/graphql/internal_representation/document.rb +2 -2
  49. data/lib/graphql/internal_representation/rewrite.rb +1 -1
  50. data/lib/graphql/invalid_null_error.rb +1 -1
  51. data/lib/graphql/language/document_from_schema_definition.rb +50 -23
  52. data/lib/graphql/object_type.rb +2 -0
  53. data/lib/graphql/pagination/connection.rb +5 -1
  54. data/lib/graphql/pagination/connections.rb +15 -19
  55. data/lib/graphql/query.rb +6 -1
  56. data/lib/graphql/query/arguments.rb +1 -1
  57. data/lib/graphql/query/context.rb +8 -1
  58. data/lib/graphql/query/serial_execution.rb +1 -0
  59. data/lib/graphql/query/validation_pipeline.rb +1 -1
  60. data/lib/graphql/relay/array_connection.rb +2 -2
  61. data/lib/graphql/relay/base_connection.rb +7 -0
  62. data/lib/graphql/relay/connection_instrumentation.rb +4 -4
  63. data/lib/graphql/relay/connection_type.rb +1 -1
  64. data/lib/graphql/relay/mutation.rb +1 -0
  65. data/lib/graphql/relay/node.rb +3 -0
  66. data/lib/graphql/relay/range_add.rb +14 -5
  67. data/lib/graphql/relay/type_extensions.rb +2 -0
  68. data/lib/graphql/scalar_type.rb +2 -0
  69. data/lib/graphql/schema.rb +80 -29
  70. data/lib/graphql/schema/argument.rb +25 -7
  71. data/lib/graphql/schema/build_from_definition.rb +150 -58
  72. data/lib/graphql/schema/default_type_error.rb +2 -0
  73. data/lib/graphql/schema/directive.rb +76 -0
  74. data/lib/graphql/schema/directive/flagged.rb +57 -0
  75. data/lib/graphql/schema/enum.rb +3 -0
  76. data/lib/graphql/schema/enum_value.rb +12 -6
  77. data/lib/graphql/schema/field.rb +52 -23
  78. data/lib/graphql/schema/field/connection_extension.rb +10 -8
  79. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  80. data/lib/graphql/schema/input_object.rb +33 -22
  81. data/lib/graphql/schema/interface.rb +1 -0
  82. data/lib/graphql/schema/member.rb +4 -0
  83. data/lib/graphql/schema/member/base_dsl_methods.rb +1 -0
  84. data/lib/graphql/schema/member/build_type.rb +3 -3
  85. data/lib/graphql/schema/member/has_arguments.rb +67 -50
  86. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  87. data/lib/graphql/schema/member/has_directives.rb +98 -0
  88. data/lib/graphql/schema/member/has_fields.rb +2 -2
  89. data/lib/graphql/schema/member/has_validators.rb +31 -0
  90. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  91. data/lib/graphql/schema/middleware_chain.rb +1 -1
  92. data/lib/graphql/schema/object.rb +11 -0
  93. data/lib/graphql/schema/printer.rb +5 -4
  94. data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
  95. data/lib/graphql/schema/resolver.rb +7 -0
  96. data/lib/graphql/schema/resolver/has_payload_type.rb +2 -0
  97. data/lib/graphql/schema/subscription.rb +19 -1
  98. data/lib/graphql/schema/timeout_middleware.rb +3 -1
  99. data/lib/graphql/schema/unique_within_type.rb +1 -2
  100. data/lib/graphql/schema/validation.rb +4 -2
  101. data/lib/graphql/schema/validator.rb +163 -0
  102. data/lib/graphql/schema/validator/exclusion_validator.rb +31 -0
  103. data/lib/graphql/schema/validator/format_validator.rb +49 -0
  104. data/lib/graphql/schema/validator/inclusion_validator.rb +33 -0
  105. data/lib/graphql/schema/validator/length_validator.rb +57 -0
  106. data/lib/graphql/schema/validator/numericality_validator.rb +71 -0
  107. data/lib/graphql/schema/validator/required_validator.rb +68 -0
  108. data/lib/graphql/static_validation.rb +1 -0
  109. data/lib/graphql/static_validation/all_rules.rb +1 -0
  110. data/lib/graphql/static_validation/rules/fields_will_merge.rb +25 -17
  111. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  112. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  113. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  114. data/lib/graphql/static_validation/validator.rb +32 -9
  115. data/lib/graphql/subscriptions.rb +17 -20
  116. data/lib/graphql/subscriptions/subscription_root.rb +1 -1
  117. data/lib/graphql/tracing.rb +2 -2
  118. data/lib/graphql/tracing/appoptics_tracing.rb +3 -1
  119. data/lib/graphql/tracing/platform_tracing.rb +4 -2
  120. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  121. data/lib/graphql/tracing/skylight_tracing.rb +1 -1
  122. data/lib/graphql/types/int.rb +9 -2
  123. data/lib/graphql/types/relay.rb +11 -3
  124. data/lib/graphql/types/relay/base_connection.rb +2 -91
  125. data/lib/graphql/types/relay/base_edge.rb +2 -34
  126. data/lib/graphql/types/relay/connection_behaviors.rb +123 -0
  127. data/lib/graphql/types/relay/default_relay.rb +27 -0
  128. data/lib/graphql/types/relay/edge_behaviors.rb +42 -0
  129. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  130. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  131. data/lib/graphql/types/relay/node.rb +2 -4
  132. data/lib/graphql/types/relay/node_behaviors.rb +15 -0
  133. data/lib/graphql/types/relay/node_field.rb +1 -19
  134. data/lib/graphql/types/relay/nodes_field.rb +1 -19
  135. data/lib/graphql/types/relay/page_info.rb +2 -14
  136. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  137. data/lib/graphql/types/string.rb +7 -1
  138. data/lib/graphql/unauthorized_error.rb +1 -1
  139. data/lib/graphql/union_type.rb +2 -0
  140. data/lib/graphql/upgrader/member.rb +1 -0
  141. data/lib/graphql/upgrader/schema.rb +1 -0
  142. data/lib/graphql/version.rb +1 -1
  143. data/readme.md +1 -1
  144. metadata +50 -6
  145. data/lib/graphql/types/relay/base_field.rb +0 -22
  146. data/lib/graphql/types/relay/base_interface.rb +0 -29
  147. data/lib/graphql/types/relay/base_object.rb +0 -26
@@ -158,6 +158,10 @@ module GraphQL
158
158
  @scoped_context = {}
159
159
  end
160
160
 
161
+ def dataloader
162
+ @dataloader ||= query.multiplex.dataloader
163
+ end
164
+
161
165
  # @api private
162
166
  attr_writer :interpreter
163
167
 
@@ -167,7 +171,10 @@ module GraphQL
167
171
  # @api private
168
172
  attr_accessor :scoped_context
169
173
 
170
- def_delegators :@provided_values, :[]=
174
+ def []=(key, value)
175
+ @provided_values[key] = value
176
+ end
177
+
171
178
  def_delegators :@query, :trace, :interpreter?
172
179
 
173
180
  # @!method []=(key, value)
@@ -16,6 +16,7 @@ module GraphQL
16
16
  # @param query_object [GraphQL::Query] the query object for this execution
17
17
  # @return [Hash] a spec-compliant GraphQL result, as a hash
18
18
  def execute(ast_operation, root_type, query_object)
19
+ GraphQL::Deprecation.warn "#{self.class} will be removed in GraphQL-Ruby 2.0, please upgrade to the Interpreter: https://graphql-ruby.org/queries/interpreter.html"
19
20
  operation_resolution.resolve(
20
21
  query_object.irep_selection,
21
22
  root_type,
@@ -72,7 +72,7 @@ module GraphQL
72
72
  elsif @operation_name_error
73
73
  @validation_errors << @operation_name_error
74
74
  else
75
- validation_result = @schema.static_validator.validate(@query, validate: @validate)
75
+ validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout)
76
76
  @validation_errors.concat(validation_result[:errors])
77
77
  @internal_representation = validation_result[:irep]
78
78
 
@@ -31,8 +31,6 @@ module GraphQL
31
31
  end
32
32
  end
33
33
 
34
- private
35
-
36
34
  def first
37
35
  @first ||= begin
38
36
  capped = limit_pagination_argument(arguments[:first], max_page_size)
@@ -47,6 +45,8 @@ module GraphQL
47
45
  @last ||= limit_pagination_argument(arguments[:last], max_page_size)
48
46
  end
49
47
 
48
+ private
49
+
50
50
  # apply first / last limit results
51
51
  def paged_nodes
52
52
  @paged_nodes ||= begin
@@ -59,6 +59,13 @@ module GraphQL
59
59
  # @param parent [Object] The object which this collection belongs to
60
60
  # @param context [GraphQL::Query::Context] The context from the field being resolved
61
61
  def initialize(nodes, arguments, field: nil, max_page_size: nil, parent: nil, context: nil)
62
+ GraphQL::Deprecation.warn "GraphQL::Relay::BaseConnection (used for #{self.class}) will be removed from GraphQL-Ruby 2.0, use GraphQL::Pagination::Connections instead: https://graphql-ruby.org/pagination/overview.html"
63
+
64
+ deprecated_caller = caller(0, 10).find { |c| !c.include?("lib/graphql") }
65
+ if deprecated_caller
66
+ GraphQL::Deprecation.warn " -> called from #{deprecated_caller}"
67
+ end
68
+
62
69
  @context = context
63
70
  @nodes = nodes
64
71
  @arguments = arguments
@@ -10,10 +10,10 @@ module GraphQL
10
10
  def self.default_arguments
11
11
  @default_arguments ||= begin
12
12
  argument_definitions = [
13
- ["first", GraphQL::INT_TYPE, "Returns the first _n_ elements from the list."],
14
- ["after", GraphQL::STRING_TYPE, "Returns the elements in the list that come after the specified cursor."],
15
- ["last", GraphQL::INT_TYPE, "Returns the last _n_ elements from the list."],
16
- ["before", GraphQL::STRING_TYPE, "Returns the elements in the list that come before the specified cursor."],
13
+ ["first", GraphQL::Deprecation_INT_TYPE, "Returns the first _n_ elements from the list."],
14
+ ["after", GraphQL::Deprecation_STRING_TYPE, "Returns the elements in the list that come after the specified cursor."],
15
+ ["last", GraphQL::Deprecation_INT_TYPE, "Returns the last _n_ elements from the list."],
16
+ ["before", GraphQL::Deprecation_STRING_TYPE, "Returns the elements in the list that come before the specified cursor."],
17
17
  ]
18
18
 
19
19
  argument_definitions.reduce({}) do |memo, arg_defn|
@@ -20,7 +20,7 @@ module GraphQL
20
20
  # Any call that would trigger `wrapped_type.ensure_defined`
21
21
  # must be inside this lazy block, otherwise we get weird
22
22
  # cyclical dependency errors :S
23
- ObjectType.define do
23
+ ObjectType.deprecated_define do
24
24
  type_name = wrapped_type.is_a?(GraphQL::BaseType) ? wrapped_type.name : wrapped_type.graphql_name
25
25
  edge_type ||= wrapped_type.edge_type
26
26
  name("#{type_name}Connection")
@@ -30,6 +30,7 @@ module GraphQL
30
30
  alias :input_fields :arguments
31
31
 
32
32
  def initialize
33
+ GraphQL::Deprecation.warn "GraphQL::Relay::Mutation will be removed from GraphQL-Ruby 2.0, use GraphQL::Schema::RelayClassicMutation instead: https://graphql-ruby.org/mutations/mutation_classes"
33
34
  @fields = {}
34
35
  @arguments = {}
35
36
  @has_generated_return_type = false
@@ -5,6 +5,7 @@ module GraphQL
5
5
  module Node
6
6
  # @return [GraphQL::Field] a field for finding objects by their global ID.
7
7
  def self.field(**kwargs, &block)
8
+ GraphQL::Deprecation.warn "GraphQL::Relay::Node.field will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::NodeField instead"
8
9
  # We have to define it fresh each time because
9
10
  # its name will be modified and its description
10
11
  # _may_ be modified.
@@ -18,6 +19,7 @@ module GraphQL
18
19
  end
19
20
 
20
21
  def self.plural_field(**kwargs, &block)
22
+ GraphQL::Deprecation.warn "GraphQL::Relay::Nodes.field will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::NodesField instead"
21
23
  field = GraphQL::Types::Relay::NodesField.graphql_definition
22
24
 
23
25
  if kwargs.any? || block
@@ -29,6 +31,7 @@ module GraphQL
29
31
 
30
32
  # @return [GraphQL::InterfaceType] The interface which all Relay types must implement
31
33
  def self.interface
34
+ GraphQL::Deprecation.warn "GraphQL::Relay::Node.interface will be removed from GraphQL-Ruby 2.0, use GraphQL::Types::Relay::Node instead"
32
35
  @interface ||= GraphQL::Types::Relay::Node.graphql_definition
33
36
  end
34
37
  end
@@ -33,12 +33,21 @@ module GraphQL
33
33
  # @param item [Object] The newly-added item (will be wrapped in `edge_class`)
34
34
  # @param parent [Object] The owner of `collection`, will be passed to the connection if provided
35
35
  # @param context [GraphQL::Query::Context] The surrounding `ctx`, will be passed to the connection if provided (this is required for cursor encoders)
36
- # @param edge_class [Class] The class to wrap `item` with
37
- def initialize(collection:, item:, parent: nil, context: nil, edge_class: Relay::Edge)
38
- connection_class = BaseConnection.connection_for_nodes(collection)
36
+ # @param edge_class [Class] The class to wrap `item` with (defaults to the connection's edge class)
37
+ def initialize(collection:, item:, parent: nil, context: nil, edge_class: nil)
38
+ if context && context.schema.new_connections?
39
+ conn_class = context.schema.connections.wrapper_for(collection)
40
+ # The rest will be added by ConnectionExtension
41
+ @connection = conn_class.new(collection, parent: parent, context: context, edge_class: edge_class)
42
+ @edge = @connection.edge_class.new(item, @connection)
43
+ else
44
+ connection_class = BaseConnection.connection_for_nodes(collection)
45
+ @connection = connection_class.new(collection, {}, parent: parent, context: context)
46
+ edge_class ||= Relay::Edge
47
+ @edge = edge_class.new(item, @connection)
48
+ end
49
+
39
50
  @parent = parent
40
- @connection = connection_class.new(collection, {}, parent: parent, context: context)
41
- @edge = edge_class.new(item, @connection)
42
51
  end
43
52
  end
44
53
  end
@@ -12,6 +12,7 @@ module GraphQL
12
12
  # Define a custom connection type for this object type
13
13
  # @return [GraphQL::ObjectType]
14
14
  def define_connection(**kwargs, &block)
15
+ GraphQL::Deprecation.warn ".connection_type and .define_connection will be removed from GraphQL-Ruby 2.0, use class-based type definitions instead: https://graphql-ruby.org/schema/class_based_api.html"
15
16
  GraphQL::Relay::ConnectionType.create_type(self, **kwargs, &block)
16
17
  end
17
18
 
@@ -23,6 +24,7 @@ module GraphQL
23
24
  # Define a custom edge type for this object type
24
25
  # @return [GraphQL::ObjectType]
25
26
  def define_edge(**kwargs, &block)
27
+ GraphQL::Deprecation.warn ".edge_type and .define_edge will be removed from GraphQL-Ruby 2.0, use class-based type definitions instead: https://graphql-ruby.org/schema/class_based_api.html"
26
28
  GraphQL::Relay::EdgeType.create_type(self, **kwargs, &block)
27
29
  end
28
30
  end
@@ -2,6 +2,8 @@
2
2
  module GraphQL
3
3
  # @api deprecated
4
4
  class ScalarType < GraphQL::BaseType
5
+ extend Define::InstanceDefinable::DeprecatedDefine
6
+
5
7
  accepts_definitions :coerce, :coerce_input, :coerce_result
6
8
  ensure_defined :coerce_non_null_input, :coerce_result
7
9
 
@@ -21,6 +21,7 @@ require "graphql/schema/validation"
21
21
  require "graphql/schema/warden"
22
22
  require "graphql/schema/build_from_definition"
23
23
 
24
+ require "graphql/schema/validator"
24
25
  require "graphql/schema/member"
25
26
  require "graphql/schema/wrapper"
26
27
  require "graphql/schema/list"
@@ -40,6 +41,7 @@ require "graphql/schema/directive/deprecated"
40
41
  require "graphql/schema/directive/include"
41
42
  require "graphql/schema/directive/skip"
42
43
  require "graphql/schema/directive/feature"
44
+ require "graphql/schema/directive/flagged"
43
45
  require "graphql/schema/directive/transform"
44
46
  require "graphql/schema/type_membership"
45
47
 
@@ -80,6 +82,7 @@ module GraphQL
80
82
  extend GraphQL::Schema::Member::AcceptsDefinition
81
83
  extend GraphQL::Schema::Member::HasAstNode
82
84
  include GraphQL::Define::InstanceDefinable
85
+ extend GraphQL::Define::InstanceDefinable::DeprecatedDefine
83
86
  extend GraphQL::Schema::FindInheritedValue
84
87
 
85
88
  class DuplicateTypeNamesError < GraphQL::Error
@@ -157,7 +160,7 @@ module GraphQL
157
160
 
158
161
  accepts_definitions \
159
162
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
160
- :max_depth, :max_complexity, :default_max_page_size,
163
+ :validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
161
164
  :orphan_types, :resolve_type, :type_error, :parse_error,
162
165
  :error_bubbling,
163
166
  :raise_definition_error,
@@ -181,7 +184,7 @@ module GraphQL
181
184
  },
182
185
  query_analyzer: ->(schema, analyzer) {
183
186
  if analyzer == GraphQL::Authorization::Analyzer
184
- warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
187
+ GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
185
188
  end
186
189
  schema.query_analyzers << analyzer
187
190
  },
@@ -196,7 +199,7 @@ module GraphQL
196
199
  attr_accessor \
197
200
  :query, :mutation, :subscription,
198
201
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
199
- :max_depth, :max_complexity, :default_max_page_size,
202
+ :validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
200
203
  :orphan_types, :directives,
201
204
  :query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
202
205
  :cursor_encoder,
@@ -281,11 +284,11 @@ module GraphQL
281
284
  @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
282
285
  @lazy_methods.set(GraphQL::Execution::Lazy, :value)
283
286
  @cursor_encoder = Base64Encoder
284
- # Default to the built-in execution strategy:
287
+ # For schema instances, default to legacy runtime modules
285
288
  @analysis_engine = GraphQL::Analysis
286
- @query_execution_strategy = self.class.default_execution_strategy
287
- @mutation_execution_strategy = self.class.default_execution_strategy
288
- @subscription_execution_strategy = self.class.default_execution_strategy
289
+ @query_execution_strategy = GraphQL::Execution::Execute
290
+ @mutation_execution_strategy = GraphQL::Execution::Execute
291
+ @subscription_execution_strategy = GraphQL::Execution::Execute
289
292
  @default_mask = GraphQL::Schema::NullMask
290
293
  @rebuilding_artifacts = false
291
294
  @context_class = GraphQL::Query::Context
@@ -300,12 +303,11 @@ module GraphQL
300
303
 
301
304
  # @return [Boolean] True if using the new {GraphQL::Execution::Interpreter}
302
305
  def interpreter?
303
- @interpreter
306
+ query_execution_strategy == GraphQL::Execution::Interpreter &&
307
+ mutation_execution_strategy == GraphQL::Execution::Interpreter &&
308
+ subscription_execution_strategy == GraphQL::Execution::Interpreter
304
309
  end
305
310
 
306
- # @api private
307
- attr_writer :interpreter
308
-
309
311
  def inspect
310
312
  "#<#{self.class.name} ...>"
311
313
  end
@@ -366,11 +368,11 @@ module GraphQL
366
368
  validator_opts = { schema: self }
367
369
  rules && (validator_opts[:rules] = rules)
368
370
  validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
369
- res = validator.validate(query)
371
+ res = validator.validate(query, timeout: validate_timeout)
370
372
  res[:errors]
371
373
  end
372
374
 
373
- def define(**kwargs, &block)
375
+ def deprecated_define(**kwargs, &block)
374
376
  super
375
377
  ensure_defined
376
378
  # Assert that all necessary configs are present:
@@ -709,7 +711,7 @@ module GraphQL
709
711
  alias :_schema_class :class
710
712
  def_delegators :_schema_class, :unauthorized_object, :unauthorized_field, :inaccessible_fields
711
713
  def_delegators :_schema_class, :directive
712
- def_delegators :_schema_class, :error_handler
714
+ def_delegators :_schema_class, :error_handler, :rescues
713
715
 
714
716
 
715
717
  # Given this schema member, find the class-based definition object
@@ -787,9 +789,8 @@ module GraphQL
787
789
  # @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
788
790
  # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
789
791
  # @param using [Hash] Plugins to attach to the created schema with `use(key, value)`
790
- # @param interpreter [Boolean] If false, the legacy {Execution::Execute} runtime will be used
791
792
  # @return [Class] the schema described by `document`
792
- def self.from_definition(definition_or_path, default_resolve: nil, interpreter: true, parser: GraphQL.default_parser, using: {})
793
+ def self.from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {})
793
794
  # If the file ends in `.graphql`, treat it like a filepath
794
795
  if definition_or_path.end_with?(".graphql")
795
796
  GraphQL::Schema::BuildFromDefinition.from_definition_path(
@@ -797,7 +798,6 @@ module GraphQL
797
798
  default_resolve: default_resolve,
798
799
  parser: parser,
799
800
  using: using,
800
- interpreter: interpreter,
801
801
  )
802
802
  else
803
803
  GraphQL::Schema::BuildFromDefinition.from_definition(
@@ -805,7 +805,6 @@ module GraphQL
805
805
  default_resolve: default_resolve,
806
806
  parser: parser,
807
807
  using: using,
808
- interpreter: interpreter,
809
808
  )
810
809
  end
811
810
  end
@@ -950,6 +949,7 @@ module GraphQL
950
949
  schema_defn.query = query && query.graphql_definition
951
950
  schema_defn.mutation = mutation && mutation.graphql_definition
952
951
  schema_defn.subscription = subscription && subscription.graphql_definition
952
+ schema_defn.validate_timeout = validate_timeout
953
953
  schema_defn.max_complexity = max_complexity
954
954
  schema_defn.error_bubbling = error_bubbling
955
955
  schema_defn.max_depth = max_depth
@@ -1156,6 +1156,14 @@ module GraphQL
1156
1156
  end
1157
1157
  end
1158
1158
 
1159
+ # @api private
1160
+ # @see GraphQL::Dataloader
1161
+ def dataloader_class
1162
+ @dataloader_class || GraphQL::Dataloader::NullDataloader
1163
+ end
1164
+
1165
+ attr_writer :dataloader_class
1166
+
1159
1167
  def references_to(to_type = nil, from: nil)
1160
1168
  @own_references_to ||= Hash.new { |h, k| h[k] = [] }
1161
1169
  if to_type
@@ -1272,6 +1280,18 @@ module GraphQL
1272
1280
  end
1273
1281
  end
1274
1282
 
1283
+ attr_writer :validate_timeout
1284
+
1285
+ def validate_timeout(new_validate_timeout = nil)
1286
+ if new_validate_timeout
1287
+ @validate_timeout = new_validate_timeout
1288
+ elsif defined?(@validate_timeout)
1289
+ @validate_timeout
1290
+ else
1291
+ find_inherited_value(:validate_timeout)
1292
+ end
1293
+ end
1294
+
1275
1295
  attr_writer :max_complexity
1276
1296
 
1277
1297
  def max_complexity(max_complexity = nil)
@@ -1287,7 +1307,7 @@ module GraphQL
1287
1307
  attr_writer :analysis_engine
1288
1308
 
1289
1309
  def analysis_engine
1290
- @analysis_engine || find_inherited_value(:analysis_engine, GraphQL::Analysis)
1310
+ @analysis_engine || find_inherited_value(:analysis_engine, self.default_analysis_engine)
1291
1311
  end
1292
1312
 
1293
1313
  def using_ast_analysis?
@@ -1295,11 +1315,9 @@ module GraphQL
1295
1315
  end
1296
1316
 
1297
1317
  def interpreter?
1298
- if defined?(@interpreter)
1299
- @interpreter
1300
- else
1301
- find_inherited_value(:interpreter?, false)
1302
- end
1318
+ query_execution_strategy == GraphQL::Execution::Interpreter &&
1319
+ mutation_execution_strategy == GraphQL::Execution::Interpreter &&
1320
+ subscription_execution_strategy == GraphQL::Execution::Interpreter
1303
1321
  end
1304
1322
 
1305
1323
  attr_writer :interpreter
@@ -1383,7 +1401,15 @@ module GraphQL
1383
1401
  if superclass <= GraphQL::Schema
1384
1402
  superclass.default_execution_strategy
1385
1403
  else
1386
- @default_execution_strategy ||= GraphQL::Execution::Execute
1404
+ @default_execution_strategy ||= GraphQL::Execution::Interpreter
1405
+ end
1406
+ end
1407
+
1408
+ def default_analysis_engine
1409
+ if superclass <= GraphQL::Schema
1410
+ superclass.default_analysis_engine
1411
+ else
1412
+ @default_analysis_engine ||= GraphQL::Analysis::AST
1387
1413
  end
1388
1414
  end
1389
1415
 
@@ -1537,6 +1563,10 @@ module GraphQL
1537
1563
  end
1538
1564
 
1539
1565
  def instrument(instrument_step, instrumenter, options = {})
1566
+ if instrument_step == :field
1567
+ GraphQL::Deprecation.warn "Field instrumentation (#{instrumenter.inspect}) will be removed in GraphQL-Ruby 2.0, please upgrade to field extensions: https://graphql-ruby.org/type_definitions/field_extensions.html"
1568
+ end
1569
+
1540
1570
  step = if instrument_step == :field && options[:after_built_ins]
1541
1571
  :field_after_built_ins
1542
1572
  else
@@ -1558,9 +1588,12 @@ module GraphQL
1558
1588
 
1559
1589
  # Attach a single directive to this schema
1560
1590
  # @param new_directive [Class]
1591
+ # @return void
1561
1592
  def directive(new_directive)
1562
- add_type_and_traverse(new_directive, root: false)
1563
- own_directives[new_directive.graphql_name] = new_directive
1593
+ own_directives[new_directive.graphql_name] ||= begin
1594
+ add_type_and_traverse(new_directive, root: false)
1595
+ new_directive
1596
+ end
1564
1597
  end
1565
1598
 
1566
1599
  def default_directives
@@ -1581,7 +1614,7 @@ module GraphQL
1581
1614
 
1582
1615
  def query_analyzer(new_analyzer)
1583
1616
  if new_analyzer == GraphQL::Authorization::Analyzer
1584
- warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
1617
+ GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
1585
1618
  end
1586
1619
  own_query_analyzers << new_analyzer
1587
1620
  end
@@ -1592,6 +1625,7 @@ module GraphQL
1592
1625
 
1593
1626
  def middleware(new_middleware = nil)
1594
1627
  if new_middleware
1628
+ GraphQL::Deprecation.warn "Middleware will be removed in GraphQL-Ruby 2.0, please upgrade to Field Extensions: https://graphql-ruby.org/type_definitions/field_extensions.html"
1595
1629
  own_middleware << new_middleware
1596
1630
  else
1597
1631
  # TODO make sure this is cached when running a query
@@ -1668,7 +1702,7 @@ module GraphQL
1668
1702
  if interpreter? && !defined?(@subscription_extension_added) && subscription && self.subscriptions
1669
1703
  @subscription_extension_added = true
1670
1704
  if subscription.singleton_class.ancestors.include?(Subscriptions::SubscriptionRoot)
1671
- warn("`extend Subscriptions::SubscriptionRoot` is no longer required; you may remove it from #{self}'s `subscription` root type (#{subscription}).")
1705
+ GraphQL::Deprecation.warn("`extend Subscriptions::SubscriptionRoot` is no longer required; you may remove it from #{self}'s `subscription` root type (#{subscription}).")
1672
1706
  else
1673
1707
  subscription.fields.each do |name, field|
1674
1708
  field.extension(Subscriptions::DefaultSubscriptionResolveExtension)
@@ -1691,6 +1725,7 @@ module GraphQL
1691
1725
  else
1692
1726
  @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
1693
1727
  @lazy_methods.set(GraphQL::Execution::Lazy, :value)
1728
+ @lazy_methods.set(GraphQL::Dataloader::Request, :load)
1694
1729
  end
1695
1730
  end
1696
1731
  @lazy_methods
@@ -1887,13 +1922,16 @@ module GraphQL
1887
1922
  end
1888
1923
  else
1889
1924
  own_types[type.graphql_name] = type
1925
+ add_directives_from(type)
1890
1926
  if type.kind.fields?
1891
1927
  type.fields.each do |name, field|
1892
1928
  field_type = field.type.unwrap
1893
1929
  references_to(field_type, from: field)
1894
1930
  field_path = path + [name]
1895
1931
  add_type(field_type, owner: field, late_types: late_types, path: field_path)
1932
+ add_directives_from(field)
1896
1933
  field.arguments.each do |arg_name, arg|
1934
+ add_directives_from(arg)
1897
1935
  arg_type = arg.type.unwrap
1898
1936
  references_to(arg_type, from: arg)
1899
1937
  add_type(arg_type, owner: arg, late_types: late_types, path: field_path + [arg_name])
@@ -1902,6 +1940,7 @@ module GraphQL
1902
1940
  end
1903
1941
  if type.kind.input_object?
1904
1942
  type.arguments.each do |arg_name, arg|
1943
+ add_directives_from(arg)
1905
1944
  arg_type = arg.type.unwrap
1906
1945
  references_to(arg_type, from: arg)
1907
1946
  add_type(arg_type, owner: arg, late_types: late_types, path: path + [arg_name])
@@ -1939,8 +1978,20 @@ module GraphQL
1939
1978
  end
1940
1979
  end
1941
1980
  end
1981
+
1982
+ def add_directives_from(owner)
1983
+ owner.directives.each { |dir| directive(dir.class) }
1984
+ end
1942
1985
  end
1943
1986
 
1987
+ def dataloader_class
1988
+ self.class.dataloader_class
1989
+ end
1990
+
1991
+ # Install these here so that subclasses will also install it.
1992
+ use(GraphQL::Execution::Errors)
1993
+ use(GraphQL::Pagination::Connections)
1994
+
1944
1995
  protected
1945
1996
 
1946
1997
  def rescues?