graphql 1.13.24 → 2.0.0

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.

Files changed (195) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
  3. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  4. data/lib/graphql/analysis/ast/visitor.rb +1 -1
  5. data/lib/graphql/analysis/ast.rb +0 -10
  6. data/lib/graphql/analysis.rb +0 -7
  7. data/lib/graphql/backtrace/table.rb +0 -18
  8. data/lib/graphql/backtrace/tracer.rb +1 -2
  9. data/lib/graphql/backtrace.rb +2 -8
  10. data/lib/graphql/dig.rb +1 -1
  11. data/lib/graphql/execution/errors.rb +1 -9
  12. data/lib/graphql/execution/interpreter/runtime.rb +6 -13
  13. data/lib/graphql/execution/interpreter.rb +0 -22
  14. data/lib/graphql/execution/lazy.rb +1 -1
  15. data/lib/graphql/execution/lookahead.rb +6 -13
  16. data/lib/graphql/execution/multiplex.rb +50 -107
  17. data/lib/graphql/execution.rb +11 -3
  18. data/lib/graphql/introspection/directive_type.rb +2 -2
  19. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  20. data/lib/graphql/introspection/entry_points.rb +2 -15
  21. data/lib/graphql/introspection/field_type.rb +1 -1
  22. data/lib/graphql/introspection/schema_type.rb +2 -2
  23. data/lib/graphql/introspection/type_type.rb +5 -5
  24. data/lib/graphql/language/document_from_schema_definition.rb +0 -17
  25. data/lib/graphql/language/nodes.rb +0 -3
  26. data/lib/graphql/pagination/connections.rb +2 -28
  27. data/lib/graphql/query/context.rb +1 -185
  28. data/lib/graphql/query/input_validation_result.rb +0 -9
  29. data/lib/graphql/query/literal_input.rb +8 -13
  30. data/lib/graphql/query/validation_pipeline.rb +6 -34
  31. data/lib/graphql/query/variable_validation_error.rb +2 -2
  32. data/lib/graphql/query/variables.rb +8 -31
  33. data/lib/graphql/query.rb +5 -34
  34. data/lib/graphql/railtie.rb +0 -104
  35. data/lib/graphql/relay/range_add.rb +0 -4
  36. data/lib/graphql/relay.rb +0 -15
  37. data/lib/graphql/schema/addition.rb +1 -8
  38. data/lib/graphql/schema/argument.rb +6 -28
  39. data/lib/graphql/schema/build_from_definition.rb +7 -9
  40. data/lib/graphql/schema/directive.rb +1 -22
  41. data/lib/graphql/schema/enum.rb +3 -19
  42. data/lib/graphql/schema/enum_value.rb +1 -23
  43. data/lib/graphql/schema/field.rb +22 -221
  44. data/lib/graphql/schema/input_object.rb +17 -65
  45. data/lib/graphql/schema/interface.rb +1 -30
  46. data/lib/graphql/schema/introspection_system.rb +3 -8
  47. data/lib/graphql/schema/late_bound_type.rb +2 -2
  48. data/lib/graphql/schema/list.rb +3 -24
  49. data/lib/graphql/schema/loader.rb +0 -1
  50. data/lib/graphql/schema/member/base_dsl_methods.rb +1 -6
  51. data/lib/graphql/schema/member/build_type.rb +4 -6
  52. data/lib/graphql/schema/member/has_arguments.rb +16 -20
  53. data/lib/graphql/schema/member/has_fields.rb +3 -3
  54. data/lib/graphql/schema/member/has_interfaces.rb +1 -13
  55. data/lib/graphql/schema/member/validates_input.rb +2 -2
  56. data/lib/graphql/schema/member.rb +0 -6
  57. data/lib/graphql/schema/mutation.rb +0 -9
  58. data/lib/graphql/schema/non_null.rb +3 -9
  59. data/lib/graphql/schema/object.rb +0 -40
  60. data/lib/graphql/schema/relay_classic_mutation.rb +17 -28
  61. data/lib/graphql/schema/scalar.rb +1 -16
  62. data/lib/graphql/schema/union.rb +0 -16
  63. data/lib/graphql/schema/warden.rb +3 -12
  64. data/lib/graphql/schema/wrapper.rb +0 -5
  65. data/lib/graphql/schema.rb +106 -945
  66. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  67. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  68. data/lib/graphql/static_validation/validator.rb +2 -24
  69. data/lib/graphql/static_validation.rb +0 -2
  70. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  71. data/lib/graphql/subscriptions/event.rb +1 -1
  72. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  73. data/lib/graphql/subscriptions.rb +4 -13
  74. data/lib/graphql/tracing/data_dog_tracing.rb +16 -20
  75. data/lib/graphql/tracing/platform_tracing.rb +4 -32
  76. data/lib/graphql/tracing.rb +0 -1
  77. data/lib/graphql/types/relay/connection_behaviors.rb +2 -6
  78. data/lib/graphql/types/relay/default_relay.rb +0 -10
  79. data/lib/graphql/types/relay/node_behaviors.rb +5 -1
  80. data/lib/graphql/types/relay.rb +0 -2
  81. data/lib/graphql/types/string.rb +1 -1
  82. data/lib/graphql/version.rb +1 -1
  83. data/lib/graphql.rb +1 -66
  84. metadata +28 -164
  85. data/lib/graphql/analysis/analyze_query.rb +0 -98
  86. data/lib/graphql/analysis/field_usage.rb +0 -45
  87. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  88. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  89. data/lib/graphql/analysis/query_complexity.rb +0 -88
  90. data/lib/graphql/analysis/query_depth.rb +0 -43
  91. data/lib/graphql/analysis/reducer_state.rb +0 -48
  92. data/lib/graphql/argument.rb +0 -131
  93. data/lib/graphql/authorization.rb +0 -82
  94. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  95. data/lib/graphql/backwards_compatibility.rb +0 -61
  96. data/lib/graphql/base_type.rb +0 -232
  97. data/lib/graphql/boolean_type.rb +0 -2
  98. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  99. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  100. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  101. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  102. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  103. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  104. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  105. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  106. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  107. data/lib/graphql/compatibility.rb +0 -5
  108. data/lib/graphql/define/assign_argument.rb +0 -12
  109. data/lib/graphql/define/assign_connection.rb +0 -13
  110. data/lib/graphql/define/assign_enum_value.rb +0 -18
  111. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  112. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  113. data/lib/graphql/define/assign_object_field.rb +0 -42
  114. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  115. data/lib/graphql/define/instance_definable.rb +0 -255
  116. data/lib/graphql/define/no_definition_error.rb +0 -7
  117. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  118. data/lib/graphql/define/type_definer.rb +0 -31
  119. data/lib/graphql/define.rb +0 -31
  120. data/lib/graphql/deprecated_dsl.rb +0 -55
  121. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  122. data/lib/graphql/directive/include_directive.rb +0 -2
  123. data/lib/graphql/directive/skip_directive.rb +0 -2
  124. data/lib/graphql/directive.rb +0 -107
  125. data/lib/graphql/enum_type.rb +0 -133
  126. data/lib/graphql/execution/execute.rb +0 -333
  127. data/lib/graphql/execution/flatten.rb +0 -40
  128. data/lib/graphql/execution/typecast.rb +0 -50
  129. data/lib/graphql/field/resolve.rb +0 -59
  130. data/lib/graphql/field.rb +0 -226
  131. data/lib/graphql/float_type.rb +0 -2
  132. data/lib/graphql/function.rb +0 -128
  133. data/lib/graphql/id_type.rb +0 -2
  134. data/lib/graphql/input_object_type.rb +0 -138
  135. data/lib/graphql/int_type.rb +0 -2
  136. data/lib/graphql/interface_type.rb +0 -72
  137. data/lib/graphql/internal_representation/document.rb +0 -27
  138. data/lib/graphql/internal_representation/node.rb +0 -206
  139. data/lib/graphql/internal_representation/print.rb +0 -51
  140. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  141. data/lib/graphql/internal_representation/scope.rb +0 -88
  142. data/lib/graphql/internal_representation/visit.rb +0 -36
  143. data/lib/graphql/internal_representation.rb +0 -7
  144. data/lib/graphql/list_type.rb +0 -80
  145. data/lib/graphql/non_null_type.rb +0 -71
  146. data/lib/graphql/object_type.rb +0 -130
  147. data/lib/graphql/query/arguments.rb +0 -189
  148. data/lib/graphql/query/arguments_cache.rb +0 -24
  149. data/lib/graphql/query/executor.rb +0 -52
  150. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  151. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  152. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  153. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  154. data/lib/graphql/query/serial_execution.rb +0 -40
  155. data/lib/graphql/relay/array_connection.rb +0 -83
  156. data/lib/graphql/relay/base_connection.rb +0 -189
  157. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  158. data/lib/graphql/relay/connection_resolve.rb +0 -43
  159. data/lib/graphql/relay/connection_type.rb +0 -54
  160. data/lib/graphql/relay/edge.rb +0 -27
  161. data/lib/graphql/relay/edge_type.rb +0 -19
  162. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  163. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  164. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  165. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  166. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  167. data/lib/graphql/relay/mutation/result.rb +0 -38
  168. data/lib/graphql/relay/mutation.rb +0 -106
  169. data/lib/graphql/relay/node.rb +0 -39
  170. data/lib/graphql/relay/page_info.rb +0 -7
  171. data/lib/graphql/relay/relation_connection.rb +0 -188
  172. data/lib/graphql/relay/type_extensions.rb +0 -32
  173. data/lib/graphql/scalar_type.rb +0 -91
  174. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  175. data/lib/graphql/schema/default_parse_error.rb +0 -10
  176. data/lib/graphql/schema/default_type_error.rb +0 -17
  177. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  178. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  179. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  180. data/lib/graphql/schema/middleware_chain.rb +0 -82
  181. data/lib/graphql/schema/possible_types.rb +0 -44
  182. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  183. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  184. data/lib/graphql/schema/traversal.rb +0 -228
  185. data/lib/graphql/schema/validation.rb +0 -313
  186. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  187. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  188. data/lib/graphql/string_type.rb +0 -2
  189. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  190. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  191. data/lib/graphql/types/relay/node_field.rb +0 -24
  192. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  193. data/lib/graphql/union_type.rb +0 -115
  194. data/lib/graphql/upgrader/member.rb +0 -937
  195. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -1,24 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
  require "graphql/schema/addition"
3
3
  require "graphql/schema/base_64_encoder"
4
- require "graphql/schema/catchall_middleware"
5
- require "graphql/schema/default_parse_error"
6
- require "graphql/schema/default_type_error"
7
4
  require "graphql/schema/find_inherited_value"
8
5
  require "graphql/schema/finder"
9
6
  require "graphql/schema/invalid_type_error"
10
7
  require "graphql/schema/introspection_system"
11
8
  require "graphql/schema/late_bound_type"
12
- require "graphql/schema/middleware_chain"
13
9
  require "graphql/schema/null_mask"
14
- require "graphql/schema/possible_types"
15
- require "graphql/schema/rescue_middleware"
16
10
  require "graphql/schema/timeout"
17
- require "graphql/schema/timeout_middleware"
18
- require "graphql/schema/traversal"
19
11
  require "graphql/schema/type_expression"
20
12
  require "graphql/schema/unique_within_type"
21
- require "graphql/schema/validation"
22
13
  require "graphql/schema/warden"
23
14
  require "graphql/schema/build_from_definition"
24
15
 
@@ -79,11 +70,7 @@ module GraphQL
79
70
  # end
80
71
  #
81
72
  class Schema
82
- extend Forwardable
83
- extend GraphQL::Schema::Member::AcceptsDefinition
84
73
  extend GraphQL::Schema::Member::HasAstNode
85
- include GraphQL::Define::InstanceDefinable
86
- extend GraphQL::Define::InstanceDefinable::DeprecatedDefine
87
74
  extend GraphQL::Schema::FindInheritedValue
88
75
 
89
76
  class DuplicateTypeNamesError < GraphQL::Error
@@ -102,757 +89,41 @@ module GraphQL
102
89
  end
103
90
  end
104
91
 
105
- module LazyHandlingMethods
106
- # Call the given block at the right time, either:
107
- # - Right away, if `value` is not registered with `lazy_resolve`
108
- # - After resolving `value`, if it's registered with `lazy_resolve` (eg, `Promise`)
109
- # @api private
110
- def after_lazy(value, &block)
111
- if lazy?(value)
112
- GraphQL::Execution::Lazy.new do
113
- result = sync_lazy(value)
114
- # The returned result might also be lazy, so check it, too
115
- after_lazy(result, &block)
116
- end
117
- else
118
- yield(value) if block_given?
119
- end
120
- end
121
-
122
- # Override this method to handle lazy objects in a custom way.
123
- # @param value [Object] an instance of a class registered with {.lazy_resolve}
124
- # @return [Object] A GraphQL-ready (non-lazy) object
125
- # @api private
126
- def sync_lazy(value)
127
- lazy_method = lazy_method_name(value)
128
- if lazy_method
129
- synced_value = value.public_send(lazy_method)
130
- sync_lazy(synced_value)
131
- else
132
- value
133
- end
134
- end
135
-
136
- # @return [Symbol, nil] The method name to lazily resolve `obj`, or nil if `obj`'s class wasn't registered with {#lazy_resolve}.
137
- def lazy_method_name(obj)
138
- lazy_methods.get(obj)
139
- end
140
-
141
- # @return [Boolean] True if this object should be lazily resolved
142
- def lazy?(obj)
143
- !!lazy_method_name(obj)
144
- end
145
-
146
- # Return a lazy if any of `maybe_lazies` are lazy,
147
- # otherwise, call the block eagerly and return the result.
148
- # @param maybe_lazies [Array]
149
- # @api private
150
- def after_any_lazies(maybe_lazies)
151
- if maybe_lazies.any? { |l| lazy?(l) }
152
- GraphQL::Execution::Lazy.all(maybe_lazies).then do |result|
153
- yield result
154
- end
155
- else
156
- yield maybe_lazies
157
- end
158
- end
159
- end
160
-
161
- include LazyHandlingMethods
162
- extend LazyHandlingMethods
163
-
164
- deprecated_accepts_definitions \
165
- :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
166
- :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
167
- :orphan_types, :resolve_type, :type_error, :parse_error,
168
- :error_bubbling,
169
- :raise_definition_error,
170
- :object_from_id, :id_from_object,
171
- :default_mask,
172
- :cursor_encoder,
173
- # If these are given as classes, normalize them. Accept `nil` when building from string.
174
- query: ->(schema, t) { schema.query = t.respond_to?(:graphql_definition) ? t.graphql_definition : t },
175
- mutation: ->(schema, t) { schema.mutation = t.respond_to?(:graphql_definition) ? t.graphql_definition : t },
176
- subscription: ->(schema, t) { schema.subscription = t.respond_to?(:graphql_definition) ? t.graphql_definition : t },
177
- disable_introspection_entry_points: ->(schema) { schema.disable_introspection_entry_points = true },
178
- disable_schema_introspection_entry_point: ->(schema) { schema.disable_schema_introspection_entry_point = true },
179
- disable_type_introspection_entry_point: ->(schema) { schema.disable_type_introspection_entry_point = true },
180
- directives: ->(schema, directives) { schema.directives = directives.reduce({}) { |m, d| m[d.graphql_name] = d; m } },
181
- directive: ->(schema, directive) { schema.directives[directive.graphql_name] = directive },
182
- instrument: ->(schema, type, instrumenter, after_built_ins: false) {
183
- if type == :field && after_built_ins
184
- type = :field_after_built_ins
185
- end
186
- schema.instrumenters[type] << instrumenter
187
- },
188
- query_analyzer: ->(schema, analyzer) {
189
- if analyzer == GraphQL::Authorization::Analyzer
190
- GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
191
- end
192
- schema.query_analyzers << analyzer
193
- },
194
- multiplex_analyzer: ->(schema, analyzer) { schema.multiplex_analyzers << analyzer },
195
- middleware: ->(schema, middleware) { schema.middleware << middleware },
196
- lazy_resolve: ->(schema, lazy_class, lazy_value_method) { schema.lazy_methods.set(lazy_class, lazy_value_method) },
197
- rescue_from: ->(schema, err_class, &block) { schema.rescue_from(err_class, &block) },
198
- tracer: ->(schema, tracer) { schema.tracers.push(tracer) }
199
-
200
- ensure_defined :introspection_system
201
-
202
- attr_accessor \
203
- :query, :mutation, :subscription,
204
- :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
205
- :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
206
- :orphan_types, :directives,
207
- :query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
208
- :cursor_encoder,
209
- :ast_node,
210
- :raise_definition_error,
211
- :introspection_namespace,
212
- :analysis_engine
213
-
214
- # [Boolean] True if this object bubbles validation errors up from a field into its parent InputObject, if there is one.
215
- attr_accessor :error_bubbling
216
-
217
- # Single, long-lived instance of the provided subscriptions class, if there is one.
218
- # @return [GraphQL::Subscriptions]
219
- attr_accessor :subscriptions
220
-
221
- # @return [MiddlewareChain] MiddlewareChain which is applied to fields during execution
222
- attr_accessor :middleware
223
-
224
- # @return [<#call(member, ctx)>] A callable for filtering members of the schema
225
- # @see {Query.new} for query-specific filters with `except:`
226
- attr_accessor :default_mask
227
-
228
- # @see {GraphQL::Query::Context} The parent class of these classes
229
- # @return [Class] Instantiated for each query
230
- attr_accessor :context_class
231
-
232
- # [Boolean] True if this object disables the introspection entry point fields
233
- attr_accessor :disable_introspection_entry_points
234
-
235
- def disable_introspection_entry_points?
236
- !!@disable_introspection_entry_points
237
- end
238
-
239
- # [Boolean] True if this object disables the __schema introspection entry point field
240
- attr_accessor :disable_schema_introspection_entry_point
241
-
242
- def disable_schema_introspection_entry_point?
243
- !!@disable_schema_introspection_entry_point
244
- end
245
-
246
- # [Boolean] True if this object disables the __type introspection entry point field
247
- attr_accessor :disable_type_introspection_entry_point
248
-
249
- def disable_type_introspection_entry_point?
250
- !!@disable_type_introspection_entry_point
251
- end
92
+ # Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
93
+ class InvalidDocumentError < Error; end;
252
94
 
253
95
  class << self
254
- attr_writer :default_execution_strategy
255
- end
256
-
257
- def default_filter
258
- GraphQL::Filter.new(except: default_mask)
259
- end
260
-
261
- # @return [Array<#trace(key, data)>] Tracers applied to every query
262
- # @see {Query#tracers} for query-specific tracers
263
- attr_reader :tracers
264
-
265
- DYNAMIC_FIELDS = ["__type", "__typename", "__schema"].freeze
266
-
267
- attr_reader :static_validator, :object_from_id_proc, :id_from_object_proc, :resolve_type_proc
268
-
269
- def initialize
270
- @tracers = []
271
- @definition_error = nil
272
- @orphan_types = []
273
- @directives = {}
274
- self.class.default_directives.each do |name, dir|
275
- @directives[name] = dir.graphql_definition
276
- end
277
- @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
278
- @middleware = MiddlewareChain.new(final_step: GraphQL::Execution::Execute::FieldResolveStep)
279
- @query_analyzers = []
280
- @multiplex_analyzers = []
281
- @resolve_type_proc = nil
282
- @object_from_id_proc = nil
283
- @id_from_object_proc = nil
284
- @type_error_proc = DefaultTypeError
285
- @parse_error_proc = DefaultParseError
286
- @instrumenters = Hash.new { |h, k| h[k] = [] }
287
- @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
288
- @lazy_methods.set(GraphQL::Execution::Lazy, :value)
289
- @cursor_encoder = Base64Encoder
290
- # For schema instances, default to legacy runtime modules
291
- @analysis_engine = GraphQL::Analysis
292
- @query_execution_strategy = GraphQL::Execution::Execute
293
- @mutation_execution_strategy = GraphQL::Execution::Execute
294
- @subscription_execution_strategy = GraphQL::Execution::Execute
295
- @default_mask = GraphQL::Schema::NullMask
296
- @rebuilding_artifacts = false
297
- @context_class = GraphQL::Query::Context
298
- @introspection_namespace = nil
299
- @introspection_system = nil
300
- @interpreter = false
301
- @error_bubbling = false
302
- @disable_introspection_entry_points = false
303
- @disable_schema_introspection_entry_point = false
304
- @disable_type_introspection_entry_point = false
305
- end
306
-
307
- # @return [Boolean] True if using the new {GraphQL::Execution::Interpreter}
308
- def interpreter?
309
- query_execution_strategy == GraphQL::Execution::Interpreter &&
310
- mutation_execution_strategy == GraphQL::Execution::Interpreter &&
311
- subscription_execution_strategy == GraphQL::Execution::Interpreter
312
- end
313
-
314
- def inspect
315
- "#<#{self.class.name} ...>"
316
- end
317
-
318
- def initialize_copy(other)
319
- super
320
- @orphan_types = other.orphan_types.dup
321
- @directives = other.directives.dup
322
- @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
323
- @middleware = other.middleware.dup
324
- @query_analyzers = other.query_analyzers.dup
325
- @multiplex_analyzers = other.multiplex_analyzers.dup
326
- @tracers = other.tracers.dup
327
- @possible_types = GraphQL::Schema::PossibleTypes.new(self)
328
-
329
- @lazy_methods = other.lazy_methods.dup
330
-
331
- @instrumenters = Hash.new { |h, k| h[k] = [] }
332
- other.instrumenters.each do |key, insts|
333
- @instrumenters[key].concat(insts)
334
- end
335
-
336
- if other.rescues?
337
- @rescue_middleware = other.rescue_middleware
338
- end
339
-
340
- # This will be rebuilt when it's requested
341
- # or during a later `define` call
342
- @types = nil
343
- @introspection_system = nil
344
- end
345
-
346
- def rescue_from(*args, &block)
347
- rescue_middleware.rescue_from(*args, &block)
348
- end
349
-
350
- def remove_handler(*args, &block)
351
- rescue_middleware.remove_handler(*args, &block)
352
- end
353
-
354
- def using_ast_analysis?
355
- @analysis_engine == GraphQL::Analysis::AST
356
- end
357
-
358
- # For forwards-compatibility with Schema classes
359
- alias :graphql_definition :itself
360
-
361
- def deprecated_define(**kwargs, &block)
362
- super
363
- ensure_defined
364
- # Assert that all necessary configs are present:
365
- validation_error = Validation.validate(self)
366
- validation_error && raise(GraphQL::RequiredImplementationMissingError, validation_error)
367
- rebuild_artifacts
368
-
369
- @definition_error = nil
370
- nil
371
- rescue StandardError => err
372
- if @raise_definition_error || err.is_a?(CyclicalDefinitionError) || err.is_a?(GraphQL::RequiredImplementationMissingError)
373
- raise
374
- else
375
- # Raise this error _later_ to avoid messing with Rails constant loading
376
- @definition_error = err
377
- end
378
- nil
379
- end
380
-
381
- # Attach `instrumenter` to this schema for instrumenting events of `instrumentation_type`.
382
- # @param instrumentation_type [Symbol]
383
- # @param instrumenter
384
- # @return [void]
385
- def instrument(instrumentation_type, instrumenter)
386
- @instrumenters[instrumentation_type] << instrumenter
387
- if instrumentation_type == :field
388
- rebuild_artifacts
389
- end
390
- end
391
-
392
- # @return [Array<GraphQL::BaseType>] The root types of this schema
393
- def root_types
394
- @root_types ||= begin
395
- rebuild_artifacts
396
- @root_types
397
- end
398
- end
399
-
400
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
401
- # @return [GraphQL::Schema::TypeMap] `{ name => type }` pairs of types in this schema
402
- def types
403
- @types ||= begin
404
- rebuild_artifacts
405
- @types
406
- end
407
- end
408
-
409
- def get_type(type_name)
410
- @types[type_name]
411
- end
412
-
413
- # @api private
414
- def introspection_system
415
- @introspection_system ||= begin
416
- rebuild_artifacts
417
- @introspection_system
418
- end
419
- end
420
-
421
- # Returns a list of Arguments and Fields referencing a certain type
422
- # @param type_name [String]
423
- # @return [Hash]
424
- def references_to(type_name = nil)
425
- rebuild_artifacts unless defined?(@type_reference_map)
426
- if type_name
427
- @type_reference_map.fetch(type_name, [])
428
- else
429
- @type_reference_map
430
- end
431
- end
432
-
433
- # Returns a list of Union types in which a type is a member
434
- # @param type [GraphQL::ObjectType]
435
- # @return [Array<GraphQL::UnionType>] list of union types of which the type is a member
436
- def union_memberships(type)
437
- rebuild_artifacts unless defined?(@union_memberships)
438
- @union_memberships.fetch(type.name, [])
439
- end
440
-
441
- # Execute a query on itself. Raises an error if the schema definition is invalid.
442
- # @see {Query#initialize} for arguments.
443
- # @return [Hash] query result, ready to be serialized as JSON
444
- def execute(query_str = nil, **kwargs)
445
- if query_str
446
- kwargs[:query] = query_str
447
- end
448
- # Some of the query context _should_ be passed to the multiplex, too
449
- multiplex_context = if (ctx = kwargs[:context])
450
- {
451
- backtrace: ctx[:backtrace],
452
- tracers: ctx[:tracers],
453
- }
454
- else
455
- {}
456
- end
457
- # Since we're running one query, don't run a multiplex-level complexity analyzer
458
- all_results = multiplex([kwargs], max_complexity: nil, context: multiplex_context)
459
- all_results[0]
460
- end
461
-
462
- # Execute several queries on itself. Raises an error if the schema definition is invalid.
463
- # @example Run several queries at once
464
- # context = { ... }
465
- # queries = [
466
- # { query: params[:query_1], variables: params[:variables_1], context: context },
467
- # { query: params[:query_2], variables: params[:variables_2], context: context },
468
- # ]
469
- # results = MySchema.multiplex(queries)
470
- # render json: {
471
- # result_1: results[0],
472
- # result_2: results[1],
473
- # }
474
- #
475
- # @see {Query#initialize} for query keyword arguments
476
- # @see {Execution::Multiplex#run_queries} for multiplex keyword arguments
477
- # @param queries [Array<Hash>] Keyword arguments for each query
478
- # @param context [Hash] Multiplex-level context
479
- # @return [Array<Hash>] One result for each query in the input
480
- def multiplex(queries, **kwargs)
481
- with_definition_error_check {
482
- GraphQL::Execution::Multiplex.run_all(self, queries, **kwargs)
483
- }
484
- end
485
-
486
- # Search for a schema member using a string path
487
- # @example Finding a Field
488
- # Schema.find("Ensemble.musicians")
489
- #
490
- # @see {GraphQL::Schema::Finder} for more examples
491
- # @param path [String] A dot-separated path to the member
492
- # @raise [Schema::Finder::MemberNotFoundError] if path could not be found
493
- # @return [GraphQL::BaseType, GraphQL::Field, GraphQL::Argument, GraphQL::Directive] A GraphQL Schema Member
494
- def find(path)
495
- rebuild_artifacts unless defined?(@finder)
496
- @find_cache[path] ||= @finder.find(path)
497
- end
498
-
499
- # Resolve field named `field_name` for type `parent_type`.
500
- # Handles dynamic fields `__typename`, `__type` and `__schema`, too
501
- # @param parent_type [String, GraphQL::BaseType]
502
- # @param field_name [String]
503
- # @return [GraphQL::Field, nil] The field named `field_name` on `parent_type`
504
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
505
- def get_field(parent_type, field_name, _context = GraphQL::Query::NullContext)
506
- with_definition_error_check do
507
- parent_type_name = case parent_type
508
- when GraphQL::BaseType, Class, Module
509
- parent_type.graphql_name
510
- when String
511
- parent_type
96
+ # Create schema with the result of an introspection query.
97
+ # @param introspection_result [Hash] A response from {GraphQL::Introspection::INTROSPECTION_QUERY}
98
+ # @return [Class<GraphQL::Schema>] the schema described by `input`
99
+ def from_introspection(introspection_result)
100
+ GraphQL::Schema::Loader.load(introspection_result)
101
+ end
102
+
103
+ # Create schema from an IDL schema or file containing an IDL definition.
104
+ # @param definition_or_path [String] A schema definition string, or a path to a file containing the definition
105
+ # @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
106
+ # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
107
+ # @param using [Hash] Plugins to attach to the created schema with `use(key, value)`
108
+ # @return [Class] the schema described by `document`
109
+ def from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {})
110
+ # If the file ends in `.graphql`, treat it like a filepath
111
+ if definition_or_path.end_with?(".graphql")
112
+ GraphQL::Schema::BuildFromDefinition.from_definition_path(
113
+ definition_or_path,
114
+ default_resolve: default_resolve,
115
+ parser: parser,
116
+ using: using,
117
+ )
512
118
  else
513
- raise "Unexpected parent_type: #{parent_type}"
514
- end
515
-
516
- defined_field = @instrumented_field_map[parent_type_name][field_name]
517
- if defined_field
518
- defined_field
519
- elsif parent_type == query && (entry_point_field = introspection_system.entry_point(name: field_name))
520
- entry_point_field
521
- elsif (dynamic_field = introspection_system.dynamic_field(name: field_name))
522
- dynamic_field
523
- else
524
- nil
119
+ GraphQL::Schema::BuildFromDefinition.from_definition(
120
+ definition_or_path,
121
+ default_resolve: default_resolve,
122
+ parser: parser,
123
+ using: using,
124
+ )
525
125
  end
526
126
  end
527
- end
528
-
529
- # Fields for this type, after instrumentation is applied
530
- # @return [Hash<String, GraphQL::Field>]
531
- def get_fields(type)
532
- @instrumented_field_map[type.graphql_name]
533
- end
534
-
535
- def type_from_ast(ast_node, context:)
536
- GraphQL::Schema::TypeExpression.build_type(self, ast_node)
537
- end
538
-
539
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
540
- # @param type_defn [GraphQL::InterfaceType, GraphQL::UnionType] the type whose members you want to retrieve
541
- # @param context [GraphQL::Query::Context] The context for the current query
542
- # @return [Array<GraphQL::ObjectType>] types which belong to `type_defn` in this schema
543
- def possible_types(type_defn, context = GraphQL::Query::NullContext)
544
- if context == GraphQL::Query::NullContext
545
- @possible_types ||= GraphQL::Schema::PossibleTypes.new(self)
546
- @possible_types.possible_types(type_defn, context)
547
- else
548
- # Use the incoming context to cache this instance --
549
- # if it were cached on the schema, we'd have a memory leak
550
- # https://github.com/rmosolgo/graphql-ruby/issues/2878
551
- ns = context.namespace(:possible_types)
552
- per_query_possible_types = ns[:possible_types] ||= GraphQL::Schema::PossibleTypes.new(self)
553
- per_query_possible_types.possible_types(type_defn, context)
554
- end
555
- end
556
-
557
- # @see [GraphQL::Schema::Warden] Restricted access to root types
558
- # @return [GraphQL::ObjectType, nil]
559
- def root_type_for_operation(operation)
560
- case operation
561
- when "query"
562
- query
563
- when "mutation"
564
- mutation
565
- when "subscription"
566
- subscription
567
- else
568
- raise ArgumentError, "unknown operation type: #{operation}"
569
- end
570
- end
571
-
572
- def execution_strategy_for_operation(operation)
573
- case operation
574
- when "query"
575
- query_execution_strategy
576
- when "mutation"
577
- mutation_execution_strategy
578
- when "subscription"
579
- subscription_execution_strategy
580
- else
581
- raise ArgumentError, "unknown operation type: #{operation}"
582
- end
583
- end
584
-
585
- # Determine the GraphQL type for a given object.
586
- # This is required for unions and interfaces (including Relay's `Node` interface)
587
- # @see [GraphQL::Schema::Warden] Restricted access to members of a schema
588
- # @param type [GraphQL::UnionType, GraphQL:InterfaceType] the abstract type which is being resolved
589
- # @param object [Any] An application object which GraphQL is currently resolving on
590
- # @param ctx [GraphQL::Query::Context] The context for the current query
591
- # @return [GraphQL::ObjectType] The type for exposing `object` in GraphQL
592
- def resolve_type(type, object, ctx = :__undefined__)
593
- check_resolved_type(type, object, ctx) do |ok_type, ok_object, ok_ctx|
594
- if @resolve_type_proc.nil?
595
- raise(GraphQL::RequiredImplementationMissingError, "Can't determine GraphQL type for: #{ok_object.inspect}, define `resolve_type (type, obj, ctx) -> { ... }` inside `Schema.define`.")
596
- end
597
- @resolve_type_proc.call(ok_type, ok_object, ok_ctx)
598
- end
599
- end
600
-
601
- # This is a compatibility hack so that instance-level and class-level
602
- # methods can get correctness checks without calling one another
603
- # @api private
604
- def check_resolved_type(type, object, ctx = :__undefined__)
605
- if ctx == :__undefined__
606
- # Old method signature
607
- ctx = object
608
- object = type
609
- type = nil
610
- end
611
-
612
- if object.is_a?(GraphQL::Schema::Object)
613
- object = object.object
614
- end
615
-
616
- if type.respond_to?(:graphql_definition)
617
- type = type.graphql_definition
618
- end
619
-
620
- # Prefer a type-local function; fall back to the schema-level function
621
- type_proc = type && type.resolve_type_proc
622
- type_result = if type_proc
623
- type_proc.call(object, ctx)
624
- else
625
- yield(type, object, ctx)
626
- end
627
-
628
- if type_result.nil?
629
- nil
630
- else
631
- after_lazy(type_result) do |resolved_type_result|
632
- if resolved_type_result.respond_to?(:graphql_definition)
633
- resolved_type_result = resolved_type_result.graphql_definition
634
- end
635
- if !resolved_type_result.is_a?(GraphQL::BaseType)
636
- type_str = "#{resolved_type_result} (#{resolved_type_result.class.name})"
637
- raise "resolve_type(#{object}) returned #{type_str}, but it should return a GraphQL type"
638
- else
639
- resolved_type_result
640
- end
641
- end
642
- end
643
- end
644
-
645
- def resolve_type=(new_resolve_type_proc)
646
- callable = GraphQL::BackwardsCompatibility.wrap_arity(new_resolve_type_proc, from: 2, to: 3, last: true, name: "Schema#resolve_type(type, obj, ctx)")
647
- @resolve_type_proc = callable
648
- end
649
-
650
- # Fetch an application object by its unique id
651
- # @param id [String] A unique identifier, provided previously by this GraphQL schema
652
- # @param ctx [GraphQL::Query::Context] The context for the current query
653
- # @return [Any] The application object identified by `id`
654
- def object_from_id(id, ctx)
655
- if @object_from_id_proc.nil?
656
- raise(GraphQL::RequiredImplementationMissingError, "Can't fetch an object for id \"#{id}\" because the schema's `object_from_id (id, ctx) -> { ... }` function is not defined")
657
- else
658
- @object_from_id_proc.call(id, ctx)
659
- end
660
- end
661
-
662
- # @param new_proc [#call] A new callable for fetching objects by ID
663
- def object_from_id=(new_proc)
664
- @object_from_id_proc = new_proc
665
- end
666
-
667
- # When we encounter a type error during query execution, we call this hook.
668
- #
669
- # You can use this hook to write a log entry,
670
- # add a {GraphQL::ExecutionError} to the response (with `ctx.add_error`)
671
- # or raise an exception and halt query execution.
672
- #
673
- # @example A `nil` is encountered by a non-null field
674
- # type_error ->(err, query_ctx) {
675
- # err.is_a?(GraphQL::InvalidNullError) # => true
676
- # }
677
- #
678
- # @example An object doesn't resolve to one of a {UnionType}'s members
679
- # type_error ->(err, query_ctx) {
680
- # err.is_a?(GraphQL::UnresolvedTypeError) # => true
681
- # }
682
- #
683
- # @see {DefaultTypeError} is the default behavior.
684
- # @param err [GraphQL::TypeError] The error encountered during execution
685
- # @param ctx [GraphQL::Query::Context] The context for the field where the error occurred
686
- # @return void
687
- def type_error(err, ctx)
688
- @type_error_proc.call(err, ctx)
689
- end
690
-
691
- # @param new_proc [#call] A new callable for handling type errors during execution
692
- def type_error=(new_proc)
693
- @type_error_proc = new_proc
694
- end
695
-
696
- # Can't delegate to `class`
697
- alias :_schema_class :class
698
- def_delegators :_schema_class, :unauthorized_object, :unauthorized_field, :inaccessible_fields
699
- def_delegators :_schema_class, :directive
700
- def_delegators :_schema_class, :error_handler
701
- def_delegators :_schema_class, :validate
702
-
703
-
704
- # Given this schema member, find the class-based definition object
705
- # whose `method_name` should be treated as an application hook
706
- # @see {.visible?}
707
- # @see {.accessible?}
708
- def call_on_type_class(member, method_name, context, default:)
709
- member = if member.respond_to?(:type_class)
710
- member.type_class
711
- else
712
- member
713
- end
714
-
715
- if member.respond_to?(:relay_node_type) && (t = member.relay_node_type)
716
- member = t
717
- end
718
-
719
- if member.respond_to?(method_name)
720
- member.public_send(method_name, context)
721
- else
722
- default
723
- end
724
- end
725
-
726
- def visible?(member, context)
727
- call_on_type_class(member, :visible?, context, default: true)
728
- end
729
-
730
- def accessible?(member, context)
731
- call_on_type_class(member, :accessible?, context, default: true)
732
- end
733
-
734
- # A function to call when {#execute} receives an invalid query string
735
- #
736
- # @see {DefaultParseError} is the default behavior.
737
- # @param err [GraphQL::ParseError] The error encountered during parsing
738
- # @param ctx [GraphQL::Query::Context] The context for the query where the error occurred
739
- # @return void
740
- def parse_error(err, ctx)
741
- @parse_error_proc.call(err, ctx)
742
- end
743
-
744
- # @param new_proc [#call] A new callable for handling parse errors during execution
745
- def parse_error=(new_proc)
746
- @parse_error_proc = new_proc
747
- end
748
-
749
- # Get a unique identifier from this object
750
- # @param object [Any] An application object
751
- # @param type [GraphQL::BaseType] The current type definition
752
- # @param ctx [GraphQL::Query::Context] the context for the current query
753
- # @return [String] a unique identifier for `object` which clients can use to refetch it
754
- def id_from_object(object, type, ctx)
755
- if @id_from_object_proc.nil?
756
- raise(GraphQL::RequiredImplementationMissingError, "Can't generate an ID for #{object.inspect} of type #{type}, schema's `id_from_object` must be defined")
757
- else
758
- @id_from_object_proc.call(object, type, ctx)
759
- end
760
- end
761
-
762
- # @param new_proc [#call] A new callable for generating unique IDs
763
- def id_from_object=(new_proc)
764
- @id_from_object_proc = new_proc
765
- end
766
-
767
- # Create schema with the result of an introspection query.
768
- # @param introspection_result [Hash] A response from {GraphQL::Introspection::INTROSPECTION_QUERY}
769
- # @return [GraphQL::Schema] the schema described by `input`
770
- def self.from_introspection(introspection_result)
771
- GraphQL::Schema::Loader.load(introspection_result)
772
- end
773
-
774
- # Create schema from an IDL schema or file containing an IDL definition.
775
- # @param definition_or_path [String] A schema definition string, or a path to a file containing the definition
776
- # @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
777
- # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
778
- # @param using [Hash] Plugins to attach to the created schema with `use(key, value)`
779
- # @return [Class] the schema described by `document`
780
- def self.from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {})
781
- # If the file ends in `.graphql`, treat it like a filepath
782
- if definition_or_path.end_with?(".graphql")
783
- GraphQL::Schema::BuildFromDefinition.from_definition_path(
784
- definition_or_path,
785
- default_resolve: default_resolve,
786
- parser: parser,
787
- using: using,
788
- )
789
- else
790
- GraphQL::Schema::BuildFromDefinition.from_definition(
791
- definition_or_path,
792
- default_resolve: default_resolve,
793
- parser: parser,
794
- using: using,
795
- )
796
- end
797
- end
798
-
799
- # Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
800
- class InvalidDocumentError < Error; end;
801
-
802
- # Return the GraphQL IDL for the schema
803
- # @param context [Hash]
804
- # @param only [<#call(member, ctx)>]
805
- # @param except [<#call(member, ctx)>]
806
- # @return [String]
807
- def to_definition(only: nil, except: nil, context: {})
808
- GraphQL::Schema::Printer.print_schema(self, only: only, except: except, context: context)
809
- end
810
-
811
- # Return the GraphQL::Language::Document IDL AST for the schema
812
- # @param context [Hash]
813
- # @param only [<#call(member, ctx)>]
814
- # @param except [<#call(member, ctx)>]
815
- # @return [GraphQL::Language::Document]
816
- def to_document(only: nil, except: nil, context: {})
817
- GraphQL::Language::DocumentFromSchemaDefinition.new(self, only: only, except: except, context: context).document
818
- end
819
-
820
- # Return the Hash response of {Introspection::INTROSPECTION_QUERY}.
821
- # @param context [Hash]
822
- # @param only [<#call(member, ctx)>]
823
- # @param except [<#call(member, ctx)>]
824
- # @return [Hash] GraphQL result
825
- def as_json(only: nil, except: nil, context: {})
826
- execute(Introspection.query(include_deprecated_args: true), only: only, except: except, context: context).to_h
827
- end
828
-
829
- # Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
830
- # @see {#as_json}
831
- # @return [String]
832
- def to_json(*args)
833
- JSON.pretty_generate(as_json(*args))
834
- end
835
-
836
- def new_connections?
837
- !!connections
838
- end
839
-
840
- attr_accessor :connections
841
-
842
- class << self
843
- extend Forwardable
844
- # For compatibility, these methods all:
845
- # - Cause the Schema instance to be created, if it hasn't been created yet
846
- # - Delegate to that instance
847
- # Eventually, the methods will be moved into this class, removing the need for the singleton.
848
- def_delegators :deprecated_graphql_definition,
849
- # Execution
850
- :execution_strategy_for_operation,
851
- # Configuration
852
- :metadata, :redefine,
853
- :id_from_object_proc, :object_from_id_proc,
854
- :id_from_object=, :object_from_id=,
855
- :remove_handler
856
127
 
857
128
  def deprecated_graphql_definition
858
129
  graphql_definition(silence_deprecation_warning: true)
@@ -911,17 +182,6 @@ module GraphQL
911
182
  @find_cache[path] ||= @finder.find(path)
912
183
  end
913
184
 
914
- def graphql_definition(silence_deprecation_warning: false)
915
- @graphql_definition ||= begin
916
- unless silence_deprecation_warning
917
- message = "Legacy `.graphql_definition` objects are deprecated and will be removed in GraphQL-Ruby 2.0. Use a class-based definition instead."
918
- caller_message = "\n\nCalled on #{self.inspect} from:\n #{caller(1, 25).map { |l| " #{l}" }.join("\n")}"
919
- GraphQL::Deprecation.warn(message + caller_message)
920
- end
921
- to_graphql(silence_deprecation_warning: silence_deprecation_warning)
922
- end
923
- end
924
-
925
185
  def default_filter
926
186
  GraphQL::Filter.new(except: default_mask)
927
187
  end
@@ -951,73 +211,6 @@ module GraphQL
951
211
  find_inherited_value(:plugins, EMPTY_ARRAY) + own_plugins
952
212
  end
953
213
 
954
- prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
955
- def to_graphql
956
- schema_defn = self.new
957
- schema_defn.raise_definition_error = true
958
- schema_defn.query = query && query.graphql_definition(silence_deprecation_warning: true)
959
- schema_defn.mutation = mutation && mutation.graphql_definition(silence_deprecation_warning: true)
960
- schema_defn.subscription = subscription && subscription.graphql_definition(silence_deprecation_warning: true)
961
- schema_defn.validate_timeout = validate_timeout
962
- schema_defn.validate_max_errors = validate_max_errors
963
- schema_defn.max_complexity = max_complexity
964
- schema_defn.error_bubbling = error_bubbling
965
- schema_defn.max_depth = max_depth
966
- schema_defn.default_max_page_size = default_max_page_size
967
- schema_defn.orphan_types = orphan_types.map { |t| t.graphql_definition(silence_deprecation_warning: true) }
968
- schema_defn.disable_introspection_entry_points = disable_introspection_entry_points?
969
- schema_defn.disable_schema_introspection_entry_point = disable_schema_introspection_entry_point?
970
- schema_defn.disable_type_introspection_entry_point = disable_type_introspection_entry_point?
971
-
972
- prepped_dirs = {}
973
- directives.each { |k, v| prepped_dirs[k] = v.graphql_definition}
974
- schema_defn.directives = prepped_dirs
975
- schema_defn.introspection_namespace = introspection
976
- schema_defn.resolve_type = method(:resolve_type)
977
- schema_defn.object_from_id = method(:object_from_id)
978
- schema_defn.id_from_object = method(:id_from_object)
979
- schema_defn.type_error = method(:type_error)
980
- schema_defn.context_class = context_class
981
- schema_defn.cursor_encoder = cursor_encoder
982
- schema_defn.tracers.concat(tracers)
983
- schema_defn.query_analyzers.concat(query_analyzers)
984
- schema_defn.analysis_engine = analysis_engine
985
-
986
- schema_defn.middleware.concat(all_middleware)
987
- schema_defn.multiplex_analyzers.concat(multiplex_analyzers)
988
- schema_defn.query_execution_strategy = query_execution_strategy
989
- schema_defn.mutation_execution_strategy = mutation_execution_strategy
990
- schema_defn.subscription_execution_strategy = subscription_execution_strategy
991
- schema_defn.default_mask = default_mask
992
- instrumenters.each do |step, insts|
993
- insts.each do |inst|
994
- schema_defn.instrumenters[step] << inst
995
- end
996
- end
997
-
998
- lazy_methods.each do |lazy_class, value_method|
999
- schema_defn.lazy_methods.set(lazy_class, value_method)
1000
- end
1001
-
1002
- error_handler.each_rescue do |err_class, handler|
1003
- schema_defn.rescue_from(err_class, &handler)
1004
- end
1005
-
1006
- schema_defn.subscriptions ||= self.subscriptions
1007
-
1008
- if !schema_defn.interpreter?
1009
- schema_defn.instrumenters[:query] << GraphQL::Schema::Member::Instrumentation
1010
- end
1011
-
1012
- if new_connections?
1013
- schema_defn.connections = self.connections
1014
- end
1015
-
1016
- schema_defn.send(:rebuild_artifacts)
1017
-
1018
- schema_defn
1019
- end
1020
-
1021
214
  # Build a map of `{ name => type }` and return it
1022
215
  # @return [Hash<String => Class>] A dictionary of type classes by their GraphQL name
1023
216
  # @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes.
@@ -1172,9 +365,7 @@ module GraphQL
1172
365
  stored_possible_types = own_possible_types[type.graphql_name]
1173
366
  visible_possible_types = if stored_possible_types && type.kind.interface?
1174
367
  stored_possible_types.select do |possible_type|
1175
- # Use `.graphql_name` comparison to match legacy vs class-based types.
1176
- # When we don't need to support legacy `.define` types, use `.include?(type)` instead.
1177
- possible_type.interfaces(context).any? { |interface| interface.graphql_name == type.graphql_name }
368
+ possible_type.interfaces(context).include?(type)
1178
369
  end
1179
370
  else
1180
371
  stored_possible_types
@@ -1393,13 +584,11 @@ module GraphQL
1393
584
  end
1394
585
 
1395
586
  def using_ast_analysis?
1396
- analysis_engine == GraphQL::Analysis::AST
587
+ true
1397
588
  end
1398
589
 
1399
590
  def interpreter?
1400
- query_execution_strategy == GraphQL::Execution::Interpreter &&
1401
- mutation_execution_strategy == GraphQL::Execution::Interpreter &&
1402
- subscription_execution_strategy == GraphQL::Execution::Interpreter
591
+ true
1403
592
  end
1404
593
 
1405
594
  attr_writer :interpreter
@@ -1518,7 +707,7 @@ module GraphQL
1518
707
  end
1519
708
 
1520
709
  after_lazy(first_resolved_type) do |resolved_type|
1521
- if resolved_type.nil? || (resolved_type.is_a?(Module) && resolved_type.respond_to?(:kind)) || resolved_type.is_a?(GraphQL::BaseType)
710
+ if resolved_type.nil? || (resolved_type.is_a?(Module) && resolved_type.respond_to?(:kind))
1522
711
  if resolved_value
1523
712
  [resolved_type, resolved_value]
1524
713
  else
@@ -1557,11 +746,11 @@ module GraphQL
1557
746
  end
1558
747
 
1559
748
  def visible?(member, ctx)
1560
- member.type_class.visible?(ctx)
749
+ member.visible?(ctx)
1561
750
  end
1562
751
 
1563
752
  def accessible?(member, ctx)
1564
- member.type_class.accessible?(ctx)
753
+ member.accessible?(ctx)
1565
754
  end
1566
755
 
1567
756
  # This hook is called when a client tries to access one or more
@@ -1611,8 +800,15 @@ module GraphQL
1611
800
  unauthorized_object(unauthorized_error)
1612
801
  end
1613
802
 
1614
- def type_error(type_err, ctx)
1615
- DefaultTypeError.call(type_err, ctx)
803
+ def type_error(type_error, ctx)
804
+ case type_error
805
+ when GraphQL::InvalidNullError
806
+ ctx.errors << type_error
807
+ when GraphQL::UnresolvedTypeError, GraphQL::StringEncodingError, GraphQL::IntegerEncodingError
808
+ raise type_error
809
+ when GraphQL::IntegerDecodingError
810
+ nil
811
+ end
1616
812
  end
1617
813
 
1618
814
  # A function to call when {#execute} receives an invalid query string
@@ -1635,17 +831,7 @@ module GraphQL
1635
831
  end
1636
832
 
1637
833
  def instrument(instrument_step, instrumenter, options = {})
1638
- if instrument_step == :field
1639
- 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"
1640
- end
1641
-
1642
- step = if instrument_step == :field && options[:after_built_ins]
1643
- :field_after_built_ins
1644
- else
1645
- instrument_step
1646
- end
1647
-
1648
- own_instrumenters[step] << instrumenter
834
+ own_instrumenters[instrument_step] << instrumenter
1649
835
  end
1650
836
 
1651
837
  # Add several directives at once
@@ -1682,9 +868,6 @@ module GraphQL
1682
868
  end
1683
869
 
1684
870
  def query_analyzer(new_analyzer)
1685
- if new_analyzer == GraphQL::Authorization::Analyzer
1686
- GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
1687
- end
1688
871
  own_query_analyzers << new_analyzer
1689
872
  end
1690
873
 
@@ -1692,16 +875,6 @@ module GraphQL
1692
875
  find_inherited_value(:query_analyzers, EMPTY_ARRAY) + own_query_analyzers
1693
876
  end
1694
877
 
1695
- def middleware(new_middleware = nil)
1696
- if new_middleware
1697
- 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"
1698
- own_middleware << new_middleware
1699
- else
1700
- # TODO make sure this is cached when running a query
1701
- MiddlewareChain.new(steps: all_middleware, final_step: GraphQL::Execution::Execute::FieldResolveStep)
1702
- end
1703
- end
1704
-
1705
878
  def multiplex_analyzer(new_analyzer)
1706
879
  own_multiplex_analyzers << new_analyzer
1707
880
  end
@@ -1730,7 +903,6 @@ module GraphQL
1730
903
  {
1731
904
  backtrace: ctx[:backtrace],
1732
905
  tracers: ctx[:tracers],
1733
- dataloader: ctx[:dataloader],
1734
906
  }
1735
907
  else
1736
908
  {}
@@ -1755,17 +927,12 @@ module GraphQL
1755
927
  # }
1756
928
  #
1757
929
  # @see {Query#initialize} for query keyword arguments
1758
- # @see {Execution::Multiplex#run_queries} for multiplex keyword arguments
930
+ # @see {Execution::Multiplex#run_all} for multiplex keyword arguments
1759
931
  # @param queries [Array<Hash>] Keyword arguments for each query
1760
932
  # @param context [Hash] Multiplex-level context
1761
933
  # @return [Array<Hash>] One result for each query in the input
1762
934
  def multiplex(queries, **kwargs)
1763
- schema = if interpreter?
1764
- self
1765
- else
1766
- graphql_definition
1767
- end
1768
- GraphQL::Execution::Multiplex.run_all(schema, queries, **kwargs)
935
+ GraphQL::Execution::Multiplex.run_all(self, queries, **kwargs)
1769
936
  end
1770
937
 
1771
938
  def instrumenters
@@ -1777,14 +944,10 @@ module GraphQL
1777
944
 
1778
945
  # @api private
1779
946
  def add_subscription_extension_if_necessary
1780
- if interpreter? && !defined?(@subscription_extension_added) && subscription && self.subscriptions
947
+ if !defined?(@subscription_extension_added) && subscription && self.subscriptions
1781
948
  @subscription_extension_added = true
1782
- if subscription.singleton_class.ancestors.include?(Subscriptions::SubscriptionRoot)
1783
- GraphQL::Deprecation.warn("`extend Subscriptions::SubscriptionRoot` is no longer required; you may remove it from #{self}'s `subscription` root type (#{subscription}).")
1784
- else
1785
- subscription.all_field_definitions.each do |field|
1786
- field.extension(Subscriptions::DefaultSubscriptionResolveExtension)
1787
- end
949
+ subscription.all_field_definitions.each do |field|
950
+ field.extension(Subscriptions::DefaultSubscriptionResolveExtension)
1788
951
  end
1789
952
  end
1790
953
  end
@@ -1793,6 +956,60 @@ module GraphQL
1793
956
  query.context.errors.push(GraphQL::ExecutionError.new("This query is too large to execute."))
1794
957
  end
1795
958
 
959
+ # Call the given block at the right time, either:
960
+ # - Right away, if `value` is not registered with `lazy_resolve`
961
+ # - After resolving `value`, if it's registered with `lazy_resolve` (eg, `Promise`)
962
+ # @api private
963
+ def after_lazy(value, &block)
964
+ if lazy?(value)
965
+ GraphQL::Execution::Lazy.new do
966
+ result = sync_lazy(value)
967
+ # The returned result might also be lazy, so check it, too
968
+ after_lazy(result, &block)
969
+ end
970
+ else
971
+ yield(value) if block_given?
972
+ end
973
+ end
974
+
975
+ # Override this method to handle lazy objects in a custom way.
976
+ # @param value [Object] an instance of a class registered with {.lazy_resolve}
977
+ # @return [Object] A GraphQL-ready (non-lazy) object
978
+ # @api private
979
+ def sync_lazy(value)
980
+ lazy_method = lazy_method_name(value)
981
+ if lazy_method
982
+ synced_value = value.public_send(lazy_method)
983
+ sync_lazy(synced_value)
984
+ else
985
+ value
986
+ end
987
+ end
988
+
989
+ # @return [Symbol, nil] The method name to lazily resolve `obj`, or nil if `obj`'s class wasn't registered with {#lazy_resolve}.
990
+ def lazy_method_name(obj)
991
+ lazy_methods.get(obj)
992
+ end
993
+
994
+ # @return [Boolean] True if this object should be lazily resolved
995
+ def lazy?(obj)
996
+ !!lazy_method_name(obj)
997
+ end
998
+
999
+ # Return a lazy if any of `maybe_lazies` are lazy,
1000
+ # otherwise, call the block eagerly and return the result.
1001
+ # @param maybe_lazies [Array]
1002
+ # @api private
1003
+ def after_any_lazies(maybe_lazies)
1004
+ if maybe_lazies.any? { |l| lazy?(l) }
1005
+ GraphQL::Execution::Lazy.all(maybe_lazies).then do |result|
1006
+ yield result
1007
+ end
1008
+ else
1009
+ yield maybe_lazies
1010
+ end
1011
+ end
1012
+
1796
1013
  private
1797
1014
 
1798
1015
  # @param t [Module, Array<Module>]
@@ -1902,68 +1119,12 @@ module GraphQL
1902
1119
  @defined_query_analyzers ||= []
1903
1120
  end
1904
1121
 
1905
- def all_middleware
1906
- find_inherited_value(:all_middleware, EMPTY_ARRAY) + own_middleware
1907
- end
1908
-
1909
- def own_middleware
1910
- @own_middleware ||= []
1911
- end
1912
-
1913
1122
  def own_multiplex_analyzers
1914
1123
  @own_multiplex_analyzers ||= []
1915
1124
  end
1916
1125
  end
1917
1126
 
1918
- def dataloader_class
1919
- self.class.dataloader_class
1920
- end
1921
-
1922
1127
  # Install these here so that subclasses will also install it.
1923
- use(GraphQL::Pagination::Connections)
1924
-
1925
- protected
1926
-
1927
- def rescues?
1928
- !!@rescue_middleware
1929
- end
1930
-
1931
- # Lazily create a middleware and add it to the schema
1932
- # (Don't add it if it's not used)
1933
- def rescue_middleware
1934
- @rescue_middleware ||= GraphQL::Schema::RescueMiddleware.new.tap { |m| middleware.insert(0, m) }
1935
- end
1936
-
1937
- private
1938
-
1939
- def rebuild_artifacts
1940
- if @rebuilding_artifacts
1941
- raise CyclicalDefinitionError, "Part of the schema build process re-triggered the schema build process, causing an infinite loop. Avoid using Schema#types, Schema#possible_types, and Schema#get_field during schema build."
1942
- else
1943
- @rebuilding_artifacts = true
1944
- @introspection_system = Schema::IntrospectionSystem.new(self)
1945
- traversal = Traversal.new(self)
1946
- @types = traversal.type_map
1947
- @root_types = [query, mutation, subscription]
1948
- @instrumented_field_map = traversal.instrumented_field_map
1949
- @type_reference_map = traversal.type_reference_map
1950
- @union_memberships = traversal.union_memberships
1951
- @find_cache = {}
1952
- @finder = Finder.new(self)
1953
- end
1954
- ensure
1955
- @rebuilding_artifacts = false
1956
- end
1957
-
1958
- class CyclicalDefinitionError < GraphQL::Error
1959
- end
1960
-
1961
- def with_definition_error_check
1962
- if @definition_error
1963
- raise @definition_error
1964
- else
1965
- yield
1966
- end
1967
- end
1128
+ self.connections = GraphQL::Pagination::Connections.new(schema: self)
1968
1129
  end
1969
1130
  end