graphql 1.11.6 → 1.13.19

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 (293) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +3 -8
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/install_generator.rb +17 -7
  8. data/lib/generators/graphql/interface_generator.rb +7 -7
  9. data/lib/generators/graphql/loader_generator.rb +1 -0
  10. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  11. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  12. data/lib/generators/graphql/mutation_generator.rb +6 -30
  13. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  14. data/lib/generators/graphql/object_generator.rb +12 -38
  15. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  16. data/lib/generators/graphql/relay.rb +63 -0
  17. data/lib/generators/graphql/relay_generator.rb +21 -0
  18. data/lib/generators/graphql/scalar_generator.rb +4 -2
  19. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  20. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  21. data/lib/generators/graphql/templates/enum.erb +5 -1
  22. data/lib/generators/graphql/templates/graphql_controller.erb +2 -2
  23. data/lib/generators/graphql/templates/input.erb +9 -0
  24. data/lib/generators/graphql/templates/interface.erb +4 -2
  25. data/lib/generators/graphql/templates/mutation.erb +1 -1
  26. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  27. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  28. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  29. data/lib/generators/graphql/templates/node_type.erb +9 -0
  30. data/lib/generators/graphql/templates/object.erb +5 -3
  31. data/lib/generators/graphql/templates/query_type.erb +1 -3
  32. data/lib/generators/graphql/templates/scalar.erb +3 -1
  33. data/lib/generators/graphql/templates/schema.erb +19 -34
  34. data/lib/generators/graphql/templates/union.erb +4 -2
  35. data/lib/generators/graphql/type_generator.rb +47 -10
  36. data/lib/generators/graphql/union_generator.rb +5 -5
  37. data/lib/graphql/analysis/analyze_query.rb +7 -0
  38. data/lib/graphql/analysis/ast/field_usage.rb +28 -1
  39. data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
  40. data/lib/graphql/analysis/ast/visitor.rb +14 -5
  41. data/lib/graphql/analysis/ast.rb +11 -2
  42. data/lib/graphql/argument.rb +1 -1
  43. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  44. data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
  45. data/lib/graphql/backtrace/table.rb +34 -3
  46. data/lib/graphql/backtrace/traced_error.rb +0 -1
  47. data/lib/graphql/backtrace/tracer.rb +40 -10
  48. data/lib/graphql/backtrace.rb +28 -19
  49. data/lib/graphql/backwards_compatibility.rb +2 -1
  50. data/lib/graphql/base_type.rb +6 -4
  51. data/lib/graphql/boolean_type.rb +1 -1
  52. data/lib/graphql/compatibility/execution_specification.rb +1 -0
  53. data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
  54. data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
  55. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
  56. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  57. data/lib/graphql/dataloader/request.rb +19 -0
  58. data/lib/graphql/dataloader/request_all.rb +19 -0
  59. data/lib/graphql/dataloader/source.rb +155 -0
  60. data/lib/graphql/dataloader.rb +308 -0
  61. data/lib/graphql/date_encoding_error.rb +16 -0
  62. data/lib/graphql/define/assign_global_id_field.rb +1 -1
  63. data/lib/graphql/define/instance_definable.rb +48 -3
  64. data/lib/graphql/define/type_definer.rb +5 -5
  65. data/lib/graphql/deprecated_dsl.rb +18 -5
  66. data/lib/graphql/deprecation.rb +9 -0
  67. data/lib/graphql/directive/deprecated_directive.rb +1 -1
  68. data/lib/graphql/directive/include_directive.rb +1 -1
  69. data/lib/graphql/directive/skip_directive.rb +1 -1
  70. data/lib/graphql/directive.rb +1 -5
  71. data/lib/graphql/enum_type.rb +9 -3
  72. data/lib/graphql/execution/errors.rb +110 -7
  73. data/lib/graphql/execution/execute.rb +8 -1
  74. data/lib/graphql/execution/interpreter/arguments.rb +57 -5
  75. data/lib/graphql/execution/interpreter/arguments_cache.rb +49 -15
  76. data/lib/graphql/execution/interpreter/handles_raw_value.rb +0 -7
  77. data/lib/graphql/execution/interpreter/resolve.rb +37 -25
  78. data/lib/graphql/execution/interpreter/runtime.rb +670 -294
  79. data/lib/graphql/execution/interpreter.rb +16 -16
  80. data/lib/graphql/execution/lazy.rb +5 -1
  81. data/lib/graphql/execution/lookahead.rb +2 -2
  82. data/lib/graphql/execution/multiplex.rb +39 -23
  83. data/lib/graphql/field.rb +1 -1
  84. data/lib/graphql/float_type.rb +1 -1
  85. data/lib/graphql/function.rb +4 -0
  86. data/lib/graphql/id_type.rb +1 -1
  87. data/lib/graphql/input_object_type.rb +3 -1
  88. data/lib/graphql/int_type.rb +1 -1
  89. data/lib/graphql/integer_decoding_error.rb +17 -0
  90. data/lib/graphql/integer_encoding_error.rb +18 -2
  91. data/lib/graphql/interface_type.rb +4 -2
  92. data/lib/graphql/internal_representation/document.rb +2 -2
  93. data/lib/graphql/internal_representation/rewrite.rb +1 -1
  94. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  95. data/lib/graphql/introspection/directive_type.rb +11 -5
  96. data/lib/graphql/introspection/entry_points.rb +2 -2
  97. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  98. data/lib/graphql/introspection/field_type.rb +3 -3
  99. data/lib/graphql/introspection/input_value_type.rb +10 -4
  100. data/lib/graphql/introspection/schema_type.rb +10 -5
  101. data/lib/graphql/introspection/type_type.rb +18 -12
  102. data/lib/graphql/introspection.rb +5 -2
  103. data/lib/graphql/invalid_null_error.rb +1 -1
  104. data/lib/graphql/language/block_string.rb +2 -6
  105. data/lib/graphql/language/cache.rb +37 -0
  106. data/lib/graphql/language/document_from_schema_definition.rb +60 -26
  107. data/lib/graphql/language/lexer.rb +50 -28
  108. data/lib/graphql/language/lexer.rl +2 -4
  109. data/lib/graphql/language/nodes.rb +14 -4
  110. data/lib/graphql/language/parser.rb +856 -825
  111. data/lib/graphql/language/parser.y +28 -11
  112. data/lib/graphql/language/printer.rb +10 -1
  113. data/lib/graphql/language/sanitized_printer.rb +5 -5
  114. data/lib/graphql/language/token.rb +0 -4
  115. data/lib/graphql/language.rb +1 -0
  116. data/lib/graphql/name_validator.rb +0 -4
  117. data/lib/graphql/object_type.rb +4 -4
  118. data/lib/graphql/pagination/active_record_relation_connection.rb +47 -3
  119. data/lib/graphql/pagination/connection.rb +19 -1
  120. data/lib/graphql/pagination/connections.rb +45 -30
  121. data/lib/graphql/pagination/relation_connection.rb +69 -28
  122. data/lib/graphql/parse_error.rb +0 -1
  123. data/lib/graphql/query/arguments.rb +2 -2
  124. data/lib/graphql/query/arguments_cache.rb +1 -2
  125. data/lib/graphql/query/context.rb +22 -4
  126. data/lib/graphql/query/executor.rb +0 -1
  127. data/lib/graphql/query/input_validation_result.rb +9 -0
  128. data/lib/graphql/query/literal_input.rb +1 -1
  129. data/lib/graphql/query/null_context.rb +21 -9
  130. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  131. data/lib/graphql/query/serial_execution.rb +1 -0
  132. data/lib/graphql/query/validation_pipeline.rb +3 -4
  133. data/lib/graphql/query/variable_validation_error.rb +3 -3
  134. data/lib/graphql/query/variables.rb +35 -4
  135. data/lib/graphql/query.rb +20 -8
  136. data/lib/graphql/railtie.rb +9 -1
  137. data/lib/graphql/rake_task.rb +3 -0
  138. data/lib/graphql/relay/array_connection.rb +2 -2
  139. data/lib/graphql/relay/base_connection.rb +7 -0
  140. data/lib/graphql/relay/connection_instrumentation.rb +4 -4
  141. data/lib/graphql/relay/connection_type.rb +16 -3
  142. data/lib/graphql/relay/edges_instrumentation.rb +0 -1
  143. data/lib/graphql/relay/global_id_resolve.rb +1 -2
  144. data/lib/graphql/relay/mutation.rb +2 -1
  145. data/lib/graphql/relay/node.rb +3 -0
  146. data/lib/graphql/relay/page_info.rb +1 -1
  147. data/lib/graphql/relay/range_add.rb +14 -5
  148. data/lib/graphql/relay/type_extensions.rb +2 -0
  149. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  150. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  151. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  152. data/lib/graphql/rubocop.rb +4 -0
  153. data/lib/graphql/scalar_type.rb +3 -1
  154. data/lib/graphql/schema/addition.rb +247 -0
  155. data/lib/graphql/schema/argument.rb +177 -21
  156. data/lib/graphql/schema/build_from_definition.rb +150 -55
  157. data/lib/graphql/schema/default_type_error.rb +2 -0
  158. data/lib/graphql/schema/directive/feature.rb +1 -1
  159. data/lib/graphql/schema/directive/flagged.rb +57 -0
  160. data/lib/graphql/schema/directive/include.rb +1 -1
  161. data/lib/graphql/schema/directive/skip.rb +1 -1
  162. data/lib/graphql/schema/directive/transform.rb +14 -2
  163. data/lib/graphql/schema/directive.rb +103 -4
  164. data/lib/graphql/schema/enum.rb +72 -11
  165. data/lib/graphql/schema/enum_value.rb +18 -6
  166. data/lib/graphql/schema/field/connection_extension.rb +4 -2
  167. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  168. data/lib/graphql/schema/field.rb +332 -111
  169. data/lib/graphql/schema/field_extension.rb +89 -2
  170. data/lib/graphql/schema/find_inherited_value.rb +4 -1
  171. data/lib/graphql/schema/finder.rb +5 -5
  172. data/lib/graphql/schema/input_object.rb +79 -55
  173. data/lib/graphql/schema/interface.rb +12 -20
  174. data/lib/graphql/schema/introspection_system.rb +1 -1
  175. data/lib/graphql/schema/list.rb +21 -4
  176. data/lib/graphql/schema/loader.rb +11 -0
  177. data/lib/graphql/schema/member/accepts_definition.rb +15 -3
  178. data/lib/graphql/schema/member/base_dsl_methods.rb +5 -16
  179. data/lib/graphql/schema/member/build_type.rb +4 -7
  180. data/lib/graphql/schema/member/cached_graphql_definition.rb +29 -2
  181. data/lib/graphql/schema/member/has_arguments.rb +166 -74
  182. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  183. data/lib/graphql/schema/member/has_directives.rb +98 -0
  184. data/lib/graphql/schema/member/has_fields.rb +77 -22
  185. data/lib/graphql/schema/member/has_interfaces.rb +100 -0
  186. data/lib/graphql/schema/member/has_validators.rb +31 -0
  187. data/lib/graphql/schema/member/instrumentation.rb +0 -1
  188. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  189. data/lib/graphql/schema/member/validates_input.rb +2 -2
  190. data/lib/graphql/schema/member.rb +5 -0
  191. data/lib/graphql/schema/middleware_chain.rb +1 -1
  192. data/lib/graphql/schema/non_null.rb +9 -3
  193. data/lib/graphql/schema/object.rb +40 -80
  194. data/lib/graphql/schema/printer.rb +16 -20
  195. data/lib/graphql/schema/relay_classic_mutation.rb +38 -4
  196. data/lib/graphql/schema/resolver/has_payload_type.rb +29 -2
  197. data/lib/graphql/schema/resolver.rb +110 -64
  198. data/lib/graphql/schema/scalar.rb +18 -2
  199. data/lib/graphql/schema/subscription.rb +55 -9
  200. data/lib/graphql/schema/timeout_middleware.rb +3 -1
  201. data/lib/graphql/schema/traversal.rb +1 -1
  202. data/lib/graphql/schema/type_expression.rb +1 -1
  203. data/lib/graphql/schema/type_membership.rb +18 -4
  204. data/lib/graphql/schema/union.rb +8 -1
  205. data/lib/graphql/schema/validation.rb +4 -2
  206. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  207. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  208. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  209. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  210. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  211. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  212. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  213. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  214. data/lib/graphql/schema/validator.rb +171 -0
  215. data/lib/graphql/schema/warden.rb +126 -53
  216. data/lib/graphql/schema.rb +262 -281
  217. data/lib/graphql/static_validation/all_rules.rb +2 -0
  218. data/lib/graphql/static_validation/base_visitor.rb +9 -6
  219. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  220. data/lib/graphql/static_validation/error.rb +3 -1
  221. data/lib/graphql/static_validation/literal_validator.rb +1 -1
  222. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +4 -2
  223. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +6 -2
  224. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  225. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  226. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  227. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  228. data/lib/graphql/static_validation/rules/fields_will_merge.rb +90 -47
  229. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  230. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  231. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  232. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  233. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  234. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  235. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  236. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  237. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  238. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
  239. data/lib/graphql/static_validation/validation_context.rb +12 -2
  240. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  241. data/lib/graphql/static_validation/validator.rb +41 -10
  242. data/lib/graphql/static_validation.rb +1 -0
  243. data/lib/graphql/string_encoding_error.rb +13 -3
  244. data/lib/graphql/string_type.rb +1 -1
  245. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +39 -8
  246. data/lib/graphql/subscriptions/broadcast_analyzer.rb +0 -3
  247. data/lib/graphql/subscriptions/event.rb +68 -32
  248. data/lib/graphql/subscriptions/instrumentation.rb +0 -1
  249. data/lib/graphql/subscriptions/serialize.rb +34 -5
  250. data/lib/graphql/subscriptions/subscription_root.rb +1 -1
  251. data/lib/graphql/subscriptions.rb +34 -39
  252. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
  253. data/lib/graphql/tracing/appoptics_tracing.rb +3 -1
  254. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  255. data/lib/graphql/tracing/data_dog_tracing.rb +24 -2
  256. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  257. data/lib/graphql/tracing/platform_tracing.rb +24 -12
  258. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  259. data/lib/graphql/tracing/skylight_tracing.rb +1 -1
  260. data/lib/graphql/tracing.rb +2 -2
  261. data/lib/graphql/types/big_int.rb +5 -1
  262. data/lib/graphql/types/int.rb +10 -3
  263. data/lib/graphql/types/iso_8601_date.rb +13 -5
  264. data/lib/graphql/types/iso_8601_date_time.rb +8 -1
  265. data/lib/graphql/types/relay/base_connection.rb +6 -91
  266. data/lib/graphql/types/relay/base_edge.rb +2 -34
  267. data/lib/graphql/types/relay/connection_behaviors.rb +174 -0
  268. data/lib/graphql/types/relay/default_relay.rb +31 -0
  269. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  270. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  271. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  272. data/lib/graphql/types/relay/node.rb +2 -4
  273. data/lib/graphql/types/relay/node_behaviors.rb +15 -0
  274. data/lib/graphql/types/relay/node_field.rb +3 -22
  275. data/lib/graphql/types/relay/nodes_field.rb +16 -18
  276. data/lib/graphql/types/relay/page_info.rb +2 -14
  277. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  278. data/lib/graphql/types/relay.rb +11 -3
  279. data/lib/graphql/types/string.rb +8 -2
  280. data/lib/graphql/unauthorized_error.rb +1 -1
  281. data/lib/graphql/union_type.rb +3 -1
  282. data/lib/graphql/upgrader/member.rb +1 -0
  283. data/lib/graphql/upgrader/schema.rb +1 -0
  284. data/lib/graphql/version.rb +1 -1
  285. data/lib/graphql.rb +68 -37
  286. data/readme.md +3 -6
  287. metadata +83 -113
  288. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  289. data/lib/graphql/types/relay/base_field.rb +0 -22
  290. data/lib/graphql/types/relay/base_interface.rb +0 -29
  291. data/lib/graphql/types/relay/base_object.rb +0 -26
  292. /data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +0 -0
  293. /data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +0 -0
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require "graphql/schema/addition"
2
3
  require "graphql/schema/base_64_encoder"
3
4
  require "graphql/schema/catchall_middleware"
4
5
  require "graphql/schema/default_parse_error"
@@ -21,6 +22,7 @@ require "graphql/schema/validation"
21
22
  require "graphql/schema/warden"
22
23
  require "graphql/schema/build_from_definition"
23
24
 
25
+ require "graphql/schema/validator"
24
26
  require "graphql/schema/member"
25
27
  require "graphql/schema/wrapper"
26
28
  require "graphql/schema/list"
@@ -40,6 +42,7 @@ require "graphql/schema/directive/deprecated"
40
42
  require "graphql/schema/directive/include"
41
43
  require "graphql/schema/directive/skip"
42
44
  require "graphql/schema/directive/feature"
45
+ require "graphql/schema/directive/flagged"
43
46
  require "graphql/schema/directive/transform"
44
47
  require "graphql/schema/type_membership"
45
48
 
@@ -80,6 +83,7 @@ module GraphQL
80
83
  extend GraphQL::Schema::Member::AcceptsDefinition
81
84
  extend GraphQL::Schema::Member::HasAstNode
82
85
  include GraphQL::Define::InstanceDefinable
86
+ extend GraphQL::Define::InstanceDefinable::DeprecatedDefine
83
87
  extend GraphQL::Schema::FindInheritedValue
84
88
 
85
89
  class DuplicateTypeNamesError < GraphQL::Error
@@ -88,6 +92,8 @@ module GraphQL
88
92
  end
89
93
  end
90
94
 
95
+ class DuplicateNamesError < GraphQL::Error; end
96
+
91
97
  class UnresolvedLateBoundTypeError < GraphQL::Error
92
98
  attr_reader :type
93
99
  def initialize(type:)
@@ -155,9 +161,9 @@ module GraphQL
155
161
  include LazyHandlingMethods
156
162
  extend LazyHandlingMethods
157
163
 
158
- accepts_definitions \
164
+ deprecated_accepts_definitions \
159
165
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
160
- :max_depth, :max_complexity, :default_max_page_size,
166
+ :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
161
167
  :orphan_types, :resolve_type, :type_error, :parse_error,
162
168
  :error_bubbling,
163
169
  :raise_definition_error,
@@ -181,7 +187,7 @@ module GraphQL
181
187
  },
182
188
  query_analyzer: ->(schema, analyzer) {
183
189
  if analyzer == GraphQL::Authorization::Analyzer
184
- warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
190
+ GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
185
191
  end
186
192
  schema.query_analyzers << analyzer
187
193
  },
@@ -196,7 +202,7 @@ module GraphQL
196
202
  attr_accessor \
197
203
  :query, :mutation, :subscription,
198
204
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
199
- :max_depth, :max_complexity, :default_max_page_size,
205
+ :validate_timeout, :validate_max_errors, :max_depth, :max_complexity, :default_max_page_size,
200
206
  :orphan_types, :directives,
201
207
  :query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
202
208
  :cursor_encoder,
@@ -281,11 +287,11 @@ module GraphQL
281
287
  @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
282
288
  @lazy_methods.set(GraphQL::Execution::Lazy, :value)
283
289
  @cursor_encoder = Base64Encoder
284
- # Default to the built-in execution strategy:
290
+ # For schema instances, default to legacy runtime modules
285
291
  @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
292
+ @query_execution_strategy = GraphQL::Execution::Execute
293
+ @mutation_execution_strategy = GraphQL::Execution::Execute
294
+ @subscription_execution_strategy = GraphQL::Execution::Execute
289
295
  @default_mask = GraphQL::Schema::NullMask
290
296
  @rebuilding_artifacts = false
291
297
  @context_class = GraphQL::Query::Context
@@ -300,12 +306,11 @@ module GraphQL
300
306
 
301
307
  # @return [Boolean] True if using the new {GraphQL::Execution::Interpreter}
302
308
  def interpreter?
303
- @interpreter
309
+ query_execution_strategy == GraphQL::Execution::Interpreter &&
310
+ mutation_execution_strategy == GraphQL::Execution::Interpreter &&
311
+ subscription_execution_strategy == GraphQL::Execution::Interpreter
304
312
  end
305
313
 
306
- # @api private
307
- attr_writer :interpreter
308
-
309
314
  def inspect
310
315
  "#<#{self.class.name} ...>"
311
316
  end
@@ -353,24 +358,7 @@ module GraphQL
353
358
  # For forwards-compatibility with Schema classes
354
359
  alias :graphql_definition :itself
355
360
 
356
- # Validate a query string according to this schema.
357
- # @param string_or_document [String, GraphQL::Language::Nodes::Document]
358
- # @return [Array<GraphQL::StaticValidation::Error >]
359
- def validate(string_or_document, rules: nil, context: nil)
360
- doc = if string_or_document.is_a?(String)
361
- GraphQL.parse(string_or_document)
362
- else
363
- string_or_document
364
- end
365
- query = GraphQL::Query.new(self, document: doc, context: context)
366
- validator_opts = { schema: self }
367
- rules && (validator_opts[:rules] = rules)
368
- validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
369
- res = validator.validate(query)
370
- res[:errors]
371
- end
372
-
373
- def define(**kwargs, &block)
361
+ def deprecated_define(**kwargs, &block)
374
362
  super
375
363
  ensure_defined
376
364
  # Assert that all necessary configs are present:
@@ -566,7 +554,7 @@ module GraphQL
566
554
  end
567
555
  end
568
556
 
569
- # @see [GraphQL::Schema::Warden] Resticted access to root types
557
+ # @see [GraphQL::Schema::Warden] Restricted access to root types
570
558
  # @return [GraphQL::ObjectType, nil]
571
559
  def root_type_for_operation(operation)
572
560
  case operation
@@ -710,6 +698,7 @@ module GraphQL
710
698
  def_delegators :_schema_class, :unauthorized_object, :unauthorized_field, :inaccessible_fields
711
699
  def_delegators :_schema_class, :directive
712
700
  def_delegators :_schema_class, :error_handler
701
+ def_delegators :_schema_class, :validate
713
702
 
714
703
 
715
704
  # Given this schema member, find the class-based definition object
@@ -787,9 +776,8 @@ module GraphQL
787
776
  # @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
788
777
  # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
789
778
  # @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
779
  # @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: {})
780
+ def self.from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {})
793
781
  # If the file ends in `.graphql`, treat it like a filepath
794
782
  if definition_or_path.end_with?(".graphql")
795
783
  GraphQL::Schema::BuildFromDefinition.from_definition_path(
@@ -797,7 +785,6 @@ module GraphQL
797
785
  default_resolve: default_resolve,
798
786
  parser: parser,
799
787
  using: using,
800
- interpreter: interpreter,
801
788
  )
802
789
  else
803
790
  GraphQL::Schema::BuildFromDefinition.from_definition(
@@ -805,7 +792,6 @@ module GraphQL
805
792
  default_resolve: default_resolve,
806
793
  parser: parser,
807
794
  using: using,
808
- interpreter: interpreter,
809
795
  )
810
796
  end
811
797
  end
@@ -859,16 +845,19 @@ module GraphQL
859
845
  # - Cause the Schema instance to be created, if it hasn't been created yet
860
846
  # - Delegate to that instance
861
847
  # Eventually, the methods will be moved into this class, removing the need for the singleton.
862
- def_delegators :graphql_definition,
848
+ def_delegators :deprecated_graphql_definition,
863
849
  # Execution
864
850
  :execution_strategy_for_operation,
865
- :validate,
866
851
  # Configuration
867
852
  :metadata, :redefine,
868
853
  :id_from_object_proc, :object_from_id_proc,
869
854
  :id_from_object=, :object_from_id=,
870
855
  :remove_handler
871
856
 
857
+ def deprecated_graphql_definition
858
+ graphql_definition(silence_deprecation_warning: true)
859
+ end
860
+
872
861
  # @return [GraphQL::Subscriptions]
873
862
  attr_accessor :subscriptions
874
863
 
@@ -903,6 +892,17 @@ module GraphQL
903
892
  GraphQL::Language::DocumentFromSchemaDefinition.new(self).document
904
893
  end
905
894
 
895
+ # @return [String, nil]
896
+ def description(new_description = nil)
897
+ if new_description
898
+ @description = new_description
899
+ elsif defined?(@description)
900
+ @description
901
+ else
902
+ find_inherited_value(:description, nil)
903
+ end
904
+ end
905
+
906
906
  def find(path)
907
907
  if !@finder
908
908
  @find_cache = {}
@@ -911,8 +911,15 @@ module GraphQL
911
911
  @find_cache[path] ||= @finder.find(path)
912
912
  end
913
913
 
914
- def graphql_definition
915
- @graphql_definition ||= to_graphql
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
916
923
  end
917
924
 
918
925
  def default_filter
@@ -944,17 +951,20 @@ module GraphQL
944
951
  find_inherited_value(:plugins, EMPTY_ARRAY) + own_plugins
945
952
  end
946
953
 
954
+ prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
947
955
  def to_graphql
948
956
  schema_defn = self.new
949
957
  schema_defn.raise_definition_error = true
950
- schema_defn.query = query && query.graphql_definition
951
- schema_defn.mutation = mutation && mutation.graphql_definition
952
- schema_defn.subscription = subscription && subscription.graphql_definition
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
953
963
  schema_defn.max_complexity = max_complexity
954
964
  schema_defn.error_bubbling = error_bubbling
955
965
  schema_defn.max_depth = max_depth
956
966
  schema_defn.default_max_page_size = default_max_page_size
957
- schema_defn.orphan_types = orphan_types.map(&:graphql_definition)
967
+ schema_defn.orphan_types = orphan_types.map { |t| t.graphql_definition(silence_deprecation_warning: true) }
958
968
  schema_defn.disable_introspection_entry_points = disable_introspection_entry_points?
959
969
  schema_defn.disable_schema_introspection_entry_point = disable_schema_introspection_entry_point?
960
970
  schema_defn.disable_type_introspection_entry_point = disable_type_introspection_entry_point?
@@ -989,7 +999,7 @@ module GraphQL
989
999
  schema_defn.lazy_methods.set(lazy_class, value_method)
990
1000
  end
991
1001
 
992
- rescues.each do |err_class, handler|
1002
+ error_handler.each_rescue do |err_class, handler|
993
1003
  schema_defn.rescue_from(err_class, &handler)
994
1004
  end
995
1005
 
@@ -1011,16 +1021,58 @@ module GraphQL
1011
1021
  # Build a map of `{ name => type }` and return it
1012
1022
  # @return [Hash<String => Class>] A dictionary of type classes by their GraphQL name
1013
1023
  # @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes.
1014
- def types
1015
- non_introspection_types.merge(introspection_system.types)
1024
+ def types(context = GraphQL::Query::NullContext)
1025
+ all_types = non_introspection_types.merge(introspection_system.types)
1026
+ visible_types = {}
1027
+ all_types.each do |k, v|
1028
+ visible_types[k] =if v.is_a?(Array)
1029
+ visible_t = nil
1030
+ v.each do |t|
1031
+ if t.visible?(context)
1032
+ if visible_t.nil?
1033
+ visible_t = t
1034
+ else
1035
+ raise DuplicateNamesError, "Found two visible type definitions for `#{k}`: #{visible_t.inspect}, #{t.inspect}"
1036
+ end
1037
+ end
1038
+ end
1039
+ visible_t
1040
+ else
1041
+ v
1042
+ end
1043
+ end
1044
+ visible_types
1016
1045
  end
1017
1046
 
1018
1047
  # @param type_name [String]
1019
1048
  # @return [Module, nil] A type, or nil if there's no type called `type_name`
1020
- def get_type(type_name)
1021
- own_types[type_name] ||
1022
- introspection_system.types[type_name] ||
1023
- find_inherited_value(:types, EMPTY_HASH)[type_name]
1049
+ def get_type(type_name, context = GraphQL::Query::NullContext)
1050
+ local_entry = own_types[type_name]
1051
+ type_defn = case local_entry
1052
+ when nil
1053
+ nil
1054
+ when Array
1055
+ visible_t = nil
1056
+ warden = Warden.from_context(context)
1057
+ local_entry.each do |t|
1058
+ if warden.visible_type?(t, context)
1059
+ if visible_t.nil?
1060
+ visible_t = t
1061
+ else
1062
+ raise DuplicateNamesError, "Found two visible type definitions for `#{type_name}`: #{visible_t.inspect}, #{t.inspect}"
1063
+ end
1064
+ end
1065
+ end
1066
+ visible_t
1067
+ when Module
1068
+ local_entry
1069
+ else
1070
+ raise "Invariant: unexpected own_types[#{type_name.inspect}]: #{local_entry.inspect}"
1071
+ end
1072
+
1073
+ type_defn ||
1074
+ introspection_system.types[type_name] || # todo context-specific introspection?
1075
+ (superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
1024
1076
  end
1025
1077
 
1026
1078
  # @api private
@@ -1089,7 +1141,7 @@ module GraphQL
1089
1141
  end
1090
1142
  end
1091
1143
 
1092
- # @see [GraphQL::Schema::Warden] Resticted access to root types
1144
+ # @see [GraphQL::Schema::Warden] Restricted access to root types
1093
1145
  # @return [GraphQL::ObjectType, nil]
1094
1146
  def root_type_for_operation(operation)
1095
1147
  case operation
@@ -1118,14 +1170,15 @@ module GraphQL
1118
1170
  type.possible_types(context: context)
1119
1171
  else
1120
1172
  stored_possible_types = own_possible_types[type.graphql_name]
1121
- visible_possible_types = stored_possible_types.select do |possible_type|
1122
- next true unless type.kind.interface?
1123
- next true unless possible_type.kind.object?
1124
-
1125
- # Use `.graphql_name` comparison to match legacy vs class-based types.
1126
- # When we don't need to support legacy `.define` types, use `.include?(type)` instead.
1127
- possible_type.interfaces(context).any? { |interface| interface.graphql_name == type.graphql_name }
1128
- end if stored_possible_types
1173
+ visible_possible_types = if stored_possible_types && type.kind.interface?
1174
+ 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 }
1178
+ end
1179
+ else
1180
+ stored_possible_types
1181
+ end
1129
1182
  visible_possible_types ||
1130
1183
  introspection_system.possible_types[type.graphql_name] ||
1131
1184
  (
@@ -1156,6 +1209,14 @@ module GraphQL
1156
1209
  end
1157
1210
  end
1158
1211
 
1212
+ # @api private
1213
+ # @see GraphQL::Dataloader
1214
+ def dataloader_class
1215
+ @dataloader_class || GraphQL::Dataloader::NullDataloader
1216
+ end
1217
+
1218
+ attr_writer :dataloader_class
1219
+
1159
1220
  def references_to(to_type = nil, from: nil)
1160
1221
  @own_references_to ||= Hash.new { |h, k| h[k] = [] }
1161
1222
  if to_type
@@ -1188,19 +1249,19 @@ module GraphQL
1188
1249
  GraphQL::Schema::TypeExpression.build_type(type_owner, ast_node)
1189
1250
  end
1190
1251
 
1191
- def get_field(type_or_name, field_name)
1252
+ def get_field(type_or_name, field_name, context = GraphQL::Query::NullContext)
1192
1253
  parent_type = case type_or_name
1193
1254
  when LateBoundType
1194
- get_type(type_or_name.name)
1255
+ get_type(type_or_name.name, context)
1195
1256
  when String
1196
- get_type(type_or_name)
1257
+ get_type(type_or_name, context)
1197
1258
  when Module
1198
1259
  type_or_name
1199
1260
  else
1200
- raise ArgumentError, "unexpected field owner for #{field_name.inspect}: #{type_or_name.inspect} (#{type_or_name.class})"
1261
+ raise GraphQL::InvariantError, "Unexpected field owner for #{field_name.inspect}: #{type_or_name.inspect} (#{type_or_name.class})"
1201
1262
  end
1202
1263
 
1203
- if parent_type.kind.fields? && (field = parent_type.get_field(field_name))
1264
+ if parent_type.kind.fields? && (field = parent_type.get_field(field_name, context))
1204
1265
  field
1205
1266
  elsif parent_type == query && (entry_point_field = introspection_system.entry_point(name: field_name))
1206
1267
  entry_point_field
@@ -1211,8 +1272,8 @@ module GraphQL
1211
1272
  end
1212
1273
  end
1213
1274
 
1214
- def get_fields(type)
1215
- type.fields
1275
+ def get_fields(type, context = GraphQL::Query::NullContext)
1276
+ type.fields(context)
1216
1277
  end
1217
1278
 
1218
1279
  def introspection(new_introspection_namespace = nil)
@@ -1272,6 +1333,47 @@ module GraphQL
1272
1333
  end
1273
1334
  end
1274
1335
 
1336
+ attr_writer :validate_timeout
1337
+
1338
+ def validate_timeout(new_validate_timeout = nil)
1339
+ if new_validate_timeout
1340
+ @validate_timeout = new_validate_timeout
1341
+ elsif defined?(@validate_timeout)
1342
+ @validate_timeout
1343
+ else
1344
+ find_inherited_value(:validate_timeout)
1345
+ end
1346
+ end
1347
+
1348
+ # Validate a query string according to this schema.
1349
+ # @param string_or_document [String, GraphQL::Language::Nodes::Document]
1350
+ # @return [Array<GraphQL::StaticValidation::Error >]
1351
+ def validate(string_or_document, rules: nil, context: nil)
1352
+ doc = if string_or_document.is_a?(String)
1353
+ GraphQL.parse(string_or_document)
1354
+ else
1355
+ string_or_document
1356
+ end
1357
+ query = GraphQL::Query.new(self, document: doc, context: context)
1358
+ validator_opts = { schema: self }
1359
+ rules && (validator_opts[:rules] = rules)
1360
+ validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
1361
+ res = validator.validate(query, timeout: validate_timeout, max_errors: validate_max_errors)
1362
+ res[:errors]
1363
+ end
1364
+
1365
+ attr_writer :validate_max_errors
1366
+
1367
+ def validate_max_errors(new_validate_max_errors = nil)
1368
+ if new_validate_max_errors
1369
+ @validate_max_errors = new_validate_max_errors
1370
+ elsif defined?(@validate_max_errors)
1371
+ @validate_max_errors
1372
+ else
1373
+ find_inherited_value(:validate_max_errors)
1374
+ end
1375
+ end
1376
+
1275
1377
  attr_writer :max_complexity
1276
1378
 
1277
1379
  def max_complexity(max_complexity = nil)
@@ -1287,7 +1389,7 @@ module GraphQL
1287
1389
  attr_writer :analysis_engine
1288
1390
 
1289
1391
  def analysis_engine
1290
- @analysis_engine || find_inherited_value(:analysis_engine, GraphQL::Analysis)
1392
+ @analysis_engine || find_inherited_value(:analysis_engine, self.default_analysis_engine)
1291
1393
  end
1292
1394
 
1293
1395
  def using_ast_analysis?
@@ -1295,11 +1397,9 @@ module GraphQL
1295
1397
  end
1296
1398
 
1297
1399
  def interpreter?
1298
- if defined?(@interpreter)
1299
- @interpreter
1300
- else
1301
- find_inherited_value(:interpreter?, false)
1302
- end
1400
+ query_execution_strategy == GraphQL::Execution::Interpreter &&
1401
+ mutation_execution_strategy == GraphQL::Execution::Interpreter &&
1402
+ subscription_execution_strategy == GraphQL::Execution::Interpreter
1303
1403
  end
1304
1404
 
1305
1405
  attr_writer :interpreter
@@ -1372,7 +1472,6 @@ module GraphQL
1372
1472
  if new_orphan_types.any?
1373
1473
  new_orphan_types = new_orphan_types.flatten
1374
1474
  add_type_and_traverse(new_orphan_types, root: false)
1375
- @orphan_types = new_orphan_types
1376
1475
  own_orphan_types.concat(new_orphan_types.flatten)
1377
1476
  end
1378
1477
 
@@ -1383,7 +1482,15 @@ module GraphQL
1383
1482
  if superclass <= GraphQL::Schema
1384
1483
  superclass.default_execution_strategy
1385
1484
  else
1386
- @default_execution_strategy ||= GraphQL::Execution::Execute
1485
+ @default_execution_strategy ||= GraphQL::Execution::Interpreter
1486
+ end
1487
+ end
1488
+
1489
+ def default_analysis_engine
1490
+ if superclass <= GraphQL::Schema
1491
+ superclass.default_analysis_engine
1492
+ else
1493
+ @default_analysis_engine ||= GraphQL::Analysis::AST
1387
1494
  end
1388
1495
  end
1389
1496
 
@@ -1397,7 +1504,7 @@ module GraphQL
1397
1504
 
1398
1505
  def rescue_from(*err_classes, &handler_block)
1399
1506
  err_classes.each do |err_class|
1400
- own_rescues[err_class] = handler_block
1507
+ error_handler.rescue_from(err_class, handler_block)
1401
1508
  end
1402
1509
  end
1403
1510
 
@@ -1441,10 +1548,6 @@ module GraphQL
1441
1548
  super
1442
1549
  end
1443
1550
 
1444
- def rescues
1445
- find_inherited_value(:rescues, EMPTY_HASH).merge(own_rescues)
1446
- end
1447
-
1448
1551
  def object_from_id(node_id, ctx)
1449
1552
  raise GraphQL::RequiredImplementationMissingError, "#{self.name}.object_from_id(node_id, ctx) must be implemented to load by ID (tried to load from id `#{node_id}`)"
1450
1553
  end
@@ -1521,15 +1624,10 @@ module GraphQL
1521
1624
  def parse_error(parse_err, ctx)
1522
1625
  ctx.errors.push(parse_err)
1523
1626
  end
1524
- attr_writer :error_handler
1525
1627
 
1526
- # @return [GraphQL::Execution::Errors, Class<GraphQL::Execution::Errors::NullErrorHandler>]
1628
+ # @return [GraphQL::Execution::Errors]
1527
1629
  def error_handler
1528
- if defined?(@error_handler)
1529
- @error_handler
1530
- else
1531
- find_inherited_value(:error_handler, GraphQL::Execution::Errors::NullErrorHandler)
1532
- end
1630
+ @error_handler ||= GraphQL::Execution::Errors.new(self)
1533
1631
  end
1534
1632
 
1535
1633
  def lazy_resolve(lazy_class, value_method)
@@ -1537,6 +1635,10 @@ module GraphQL
1537
1635
  end
1538
1636
 
1539
1637
  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
+
1540
1642
  step = if instrument_step == :field && options[:after_built_ins]
1541
1643
  :field_after_built_ins
1542
1644
  else
@@ -1558,9 +1660,9 @@ module GraphQL
1558
1660
 
1559
1661
  # Attach a single directive to this schema
1560
1662
  # @param new_directive [Class]
1663
+ # @return void
1561
1664
  def directive(new_directive)
1562
1665
  add_type_and_traverse(new_directive, root: false)
1563
- own_directives[new_directive.graphql_name] = new_directive
1564
1666
  end
1565
1667
 
1566
1668
  def default_directives
@@ -1581,7 +1683,7 @@ module GraphQL
1581
1683
 
1582
1684
  def query_analyzer(new_analyzer)
1583
1685
  if new_analyzer == GraphQL::Authorization::Analyzer
1584
- warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
1686
+ GraphQL::Deprecation.warn("The Authorization query analyzer is deprecated. Authorizing at query runtime is generally a better idea.")
1585
1687
  end
1586
1688
  own_query_analyzers << new_analyzer
1587
1689
  end
@@ -1592,6 +1694,7 @@ module GraphQL
1592
1694
 
1593
1695
  def middleware(new_middleware = nil)
1594
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"
1595
1698
  own_middleware << new_middleware
1596
1699
  else
1597
1700
  # TODO make sure this is cached when running a query
@@ -1607,6 +1710,14 @@ module GraphQL
1607
1710
  find_inherited_value(:multiplex_analyzers, EMPTY_ARRAY) + own_multiplex_analyzers
1608
1711
  end
1609
1712
 
1713
+ def sanitized_printer(new_sanitized_printer = nil)
1714
+ if new_sanitized_printer
1715
+ @own_sanitized_printer = new_sanitized_printer
1716
+ else
1717
+ @own_sanitized_printer || GraphQL::Language::SanitizedPrinter
1718
+ end
1719
+ end
1720
+
1610
1721
  # Execute a query on itself.
1611
1722
  # @see {Query#initialize} for arguments.
1612
1723
  # @return [Hash] query result, ready to be serialized as JSON
@@ -1619,6 +1730,7 @@ module GraphQL
1619
1730
  {
1620
1731
  backtrace: ctx[:backtrace],
1621
1732
  tracers: ctx[:tracers],
1733
+ dataloader: ctx[:dataloader],
1622
1734
  }
1623
1735
  else
1624
1736
  {}
@@ -1668,9 +1780,9 @@ module GraphQL
1668
1780
  if interpreter? && !defined?(@subscription_extension_added) && subscription && self.subscriptions
1669
1781
  @subscription_extension_added = true
1670
1782
  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}).")
1783
+ GraphQL::Deprecation.warn("`extend Subscriptions::SubscriptionRoot` is no longer required; you may remove it from #{self}'s `subscription` root type (#{subscription}).")
1672
1784
  else
1673
- subscription.fields.each do |name, field|
1785
+ subscription.all_field_definitions.each do |field|
1674
1786
  field.extension(Subscriptions::DefaultSubscriptionResolveExtension)
1675
1787
  end
1676
1788
  end
@@ -1683,6 +1795,59 @@ module GraphQL
1683
1795
 
1684
1796
  private
1685
1797
 
1798
+ # @param t [Module, Array<Module>]
1799
+ # @return [void]
1800
+ def add_type_and_traverse(t, root:)
1801
+ if root
1802
+ @root_types ||= []
1803
+ @root_types << t
1804
+ end
1805
+ new_types = Array(t)
1806
+ addition = Schema::Addition.new(schema: self, own_types: own_types, new_types: new_types)
1807
+ addition.types.each do |name, types_entry| # rubocop:disable Development/ContextIsPassedCop -- build-time, not query-time
1808
+ if (prev_entry = own_types[name])
1809
+ prev_entries = case prev_entry
1810
+ when Array
1811
+ prev_entry
1812
+ when Module
1813
+ own_types[name] = [prev_entry]
1814
+ else
1815
+ raise "Invariant: unexpected prev_entry at #{name.inspect} when adding #{t.inspect}"
1816
+ end
1817
+
1818
+ case types_entry
1819
+ when Array
1820
+ prev_entries.concat(types_entry)
1821
+ prev_entries.uniq! # in case any are being re-visited
1822
+ when Module
1823
+ if !prev_entries.include?(types_entry)
1824
+ prev_entries << types_entry
1825
+ end
1826
+ else
1827
+ raise "Invariant: unexpected types_entry at #{name} when adding #{t.inspect}"
1828
+ end
1829
+ else
1830
+ if types_entry.is_a?(Array)
1831
+ types_entry.uniq!
1832
+ end
1833
+ own_types[name] = types_entry
1834
+ end
1835
+ end
1836
+
1837
+ own_possible_types.merge!(addition.possible_types) { |key, old_val, new_val| old_val + new_val }
1838
+ own_union_memberships.merge!(addition.union_memberships)
1839
+
1840
+ addition.references.each { |thing, pointers|
1841
+ pointers.each { |pointer| references_to(thing, from: pointer) }
1842
+ }
1843
+
1844
+ addition.directives.each { |dir_class| own_directives[dir_class.graphql_name] = dir_class }
1845
+
1846
+ addition.arguments_with_default_values.each do |arg|
1847
+ arg.validate_default_value
1848
+ end
1849
+ end
1850
+
1686
1851
  def lazy_methods
1687
1852
  if !defined?(@lazy_methods)
1688
1853
  if inherited_map = find_inherited_value(:lazy_methods)
@@ -1691,6 +1856,7 @@ module GraphQL
1691
1856
  else
1692
1857
  @lazy_methods = GraphQL::Execution::Lazy::LazyMethodMap.new
1693
1858
  @lazy_methods.set(GraphQL::Execution::Lazy, :value)
1859
+ @lazy_methods.set(GraphQL::Dataloader::Request, :load)
1694
1860
  end
1695
1861
  end
1696
1862
  @lazy_methods
@@ -1708,10 +1874,6 @@ module GraphQL
1708
1874
  @own_plugins ||= []
1709
1875
  end
1710
1876
 
1711
- def own_rescues
1712
- @own_rescues ||= {}
1713
- end
1714
-
1715
1877
  def own_orphan_types
1716
1878
  @own_orphan_types ||= []
1717
1879
  end
@@ -1751,196 +1913,15 @@ module GraphQL
1751
1913
  def own_multiplex_analyzers
1752
1914
  @own_multiplex_analyzers ||= []
1753
1915
  end
1916
+ end
1754
1917
 
1755
- # @param t [Module, Array<Module>]
1756
- # @return [void]
1757
- def add_type_and_traverse(t, root:)
1758
- if root
1759
- @root_types ||= []
1760
- @root_types << t
1761
- end
1762
- late_types = []
1763
- new_types = Array(t)
1764
- new_types.each { |t| add_type(t, owner: nil, late_types: late_types, path: [t.graphql_name]) }
1765
- missed_late_types = 0
1766
- while (late_type_vals = late_types.shift)
1767
- type_owner, lt = late_type_vals
1768
- if lt.is_a?(String)
1769
- type = Member::BuildType.constantize(lt)
1770
- # Reset the counter, since we might succeed next go-round
1771
- missed_late_types = 0
1772
- update_type_owner(type_owner, type)
1773
- add_type(type, owner: type_owner, late_types: late_types, path: [type.graphql_name])
1774
- elsif lt.is_a?(LateBoundType)
1775
- if (type = get_type(lt.graphql_name))
1776
- # Reset the counter, since we might succeed next go-round
1777
- missed_late_types = 0
1778
- update_type_owner(type_owner, type)
1779
- add_type(type, owner: type_owner, late_types: late_types, path: [type.graphql_name])
1780
- else
1781
- missed_late_types += 1
1782
- # Add it back to the list, maybe we'll be able to resolve it later.
1783
- late_types << [type_owner, lt]
1784
- if missed_late_types == late_types.size
1785
- # We've looked at all of them and haven't resolved one.
1786
- raise UnresolvedLateBoundTypeError.new(type: lt)
1787
- else
1788
- # Try the next one
1789
- end
1790
- end
1791
- else
1792
- raise ArgumentError, "Unexpected late type: #{lt.inspect}"
1793
- end
1794
- end
1795
- nil
1796
- end
1797
-
1798
- def update_type_owner(owner, type)
1799
- case owner
1800
- when Class
1801
- if owner.kind.union?
1802
- # It's a union with possible_types
1803
- # Replace the item by class name
1804
- owner.assign_type_membership_object_type(type)
1805
- own_possible_types[owner.graphql_name] = owner.possible_types
1806
- elsif type.kind.interface? && owner.kind.object?
1807
- new_interfaces = []
1808
- owner.interfaces.each do |int_t|
1809
- if int_t.is_a?(String) && int_t == type.graphql_name
1810
- new_interfaces << type
1811
- elsif int_t.is_a?(LateBoundType) && int_t.graphql_name == type.graphql_name
1812
- new_interfaces << type
1813
- else
1814
- # Don't re-add proper interface definitions,
1815
- # they were probably already added, maybe with options.
1816
- end
1817
- end
1818
- owner.implements(*new_interfaces)
1819
- new_interfaces.each do |int|
1820
- pt = own_possible_types[int.graphql_name] ||= []
1821
- if !pt.include?(owner)
1822
- pt << owner
1823
- end
1824
- end
1825
- end
1826
-
1827
- when nil
1828
- # It's a root type
1829
- own_types[type.graphql_name] = type
1830
- when GraphQL::Schema::Field, GraphQL::Schema::Argument
1831
- orig_type = owner.type
1832
- # Apply list/non-null wrapper as needed
1833
- if orig_type.respond_to?(:of_type)
1834
- transforms = []
1835
- while (orig_type.respond_to?(:of_type))
1836
- if orig_type.kind.non_null?
1837
- transforms << :to_non_null_type
1838
- elsif orig_type.kind.list?
1839
- transforms << :to_list_type
1840
- else
1841
- raise "Invariant: :of_type isn't non-null or list"
1842
- end
1843
- orig_type = orig_type.of_type
1844
- end
1845
- transforms.reverse_each { |t| type = type.public_send(t) }
1846
- end
1847
- owner.type = type
1848
- else
1849
- raise "Unexpected update: #{owner.inspect} #{type.inspect}"
1850
- end
1851
- end
1852
-
1853
- def add_type(type, owner:, late_types:, path:)
1854
- if type.respond_to?(:metadata) && type.metadata.is_a?(Hash)
1855
- type_class = type.metadata[:type_class]
1856
- if type_class.nil?
1857
- raise ArgumentError, "Can't add legacy type: #{type} (#{type.class})"
1858
- else
1859
- type = type_class
1860
- end
1861
- elsif type.is_a?(String) || type.is_a?(GraphQL::Schema::LateBoundType)
1862
- late_types << [owner, type]
1863
- return
1864
- end
1865
-
1866
- if owner.is_a?(Class) && owner < GraphQL::Schema::Union
1867
- um = own_union_memberships[type.graphql_name] ||= []
1868
- um << owner
1869
- end
1870
-
1871
- if (prev_type = own_types[type.graphql_name])
1872
- if prev_type != type
1873
- raise DuplicateTypeNamesError.new(
1874
- type_name: type.graphql_name,
1875
- first_definition: prev_type,
1876
- second_definition: type,
1877
- path: path,
1878
- )
1879
- else
1880
- # This type was already added
1881
- end
1882
- elsif type.is_a?(Class) && type < GraphQL::Schema::Directive
1883
- type.arguments.each do |name, arg|
1884
- arg_type = arg.type.unwrap
1885
- references_to(arg_type, from: arg)
1886
- add_type(arg_type, owner: arg, late_types: late_types, path: path + [name])
1887
- end
1888
- else
1889
- own_types[type.graphql_name] = type
1890
- if type.kind.fields?
1891
- type.fields.each do |name, field|
1892
- field_type = field.type.unwrap
1893
- references_to(field_type, from: field)
1894
- field_path = path + [name]
1895
- add_type(field_type, owner: field, late_types: late_types, path: field_path)
1896
- field.arguments.each do |arg_name, arg|
1897
- arg_type = arg.type.unwrap
1898
- references_to(arg_type, from: arg)
1899
- add_type(arg_type, owner: arg, late_types: late_types, path: field_path + [arg_name])
1900
- end
1901
- end
1902
- end
1903
- if type.kind.input_object?
1904
- type.arguments.each do |arg_name, arg|
1905
- arg_type = arg.type.unwrap
1906
- references_to(arg_type, from: arg)
1907
- add_type(arg_type, owner: arg, late_types: late_types, path: path + [arg_name])
1908
- end
1909
- end
1910
- if type.kind.union?
1911
- own_possible_types[type.graphql_name] = type.possible_types
1912
- type.possible_types.each do |t|
1913
- add_type(t, owner: type, late_types: late_types, path: path + ["possible_types"])
1914
- end
1915
- end
1916
- if type.kind.interface?
1917
- type.orphan_types.each do |t|
1918
- add_type(t, owner: type, late_types: late_types, path: path + ["orphan_types"])
1919
- end
1920
- end
1921
- if type.kind.object?
1922
- own_possible_types[type.graphql_name] = [type]
1923
- type.interface_type_memberships.each do |interface_type_membership|
1924
- case interface_type_membership
1925
- when Schema::TypeMembership
1926
- interface_type = interface_type_membership.abstract_type
1927
- # We can get these now; we'll have to get late-bound types later
1928
- if interface_type.is_a?(Module)
1929
- implementers = own_possible_types[interface_type.graphql_name] ||= []
1930
- implementers << type
1931
- end
1932
- when String, Schema::LateBoundType
1933
- interface_type = interface_type_membership
1934
- else
1935
- raise ArgumentError, "Invariant: unexpected type membership for #{type.graphql_name}: #{interface_type_membership.class} (#{interface_type_membership.inspect})"
1936
- end
1937
- add_type(interface_type, owner: type, late_types: late_types, path: path + ["implements"])
1938
- end
1939
- end
1940
- end
1941
- end
1918
+ def dataloader_class
1919
+ self.class.dataloader_class
1942
1920
  end
1943
1921
 
1922
+ # Install these here so that subclasses will also install it.
1923
+ use(GraphQL::Pagination::Connections)
1924
+
1944
1925
  protected
1945
1926
 
1946
1927
  def rescues?