graphql 1.11.6 → 1.13.19

Sign up to get free protection for your applications and to get access to all the features.
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?