graphql 2.0.31 → 2.6.1

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.
Files changed (316) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/detailed_trace_generator.rb +77 -0
  3. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  4. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  5. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  6. data/lib/generators/graphql/install_generator.rb +49 -0
  7. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  8. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  9. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  10. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  11. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  12. data/lib/generators/graphql/templates/base_field.erb +2 -0
  13. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  14. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  15. data/lib/generators/graphql/templates/base_object.erb +2 -0
  16. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  17. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  18. data/lib/generators/graphql/templates/base_union.erb +2 -0
  19. data/lib/generators/graphql/templates/create_graphql_detailed_traces.erb +10 -0
  20. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  21. data/lib/generators/graphql/templates/loader.erb +2 -0
  22. data/lib/generators/graphql/templates/mutation.erb +2 -0
  23. data/lib/generators/graphql/templates/node_type.erb +2 -0
  24. data/lib/generators/graphql/templates/query_type.erb +2 -0
  25. data/lib/generators/graphql/templates/schema.erb +5 -0
  26. data/lib/generators/graphql/type_generator.rb +1 -1
  27. data/lib/graphql/analysis/analyzer.rb +90 -0
  28. data/lib/graphql/analysis/field_usage.rb +82 -0
  29. data/lib/graphql/analysis/max_query_complexity.rb +20 -0
  30. data/lib/graphql/analysis/max_query_depth.rb +20 -0
  31. data/lib/graphql/analysis/query_complexity.rb +263 -0
  32. data/lib/graphql/analysis/query_depth.rb +58 -0
  33. data/lib/graphql/analysis/visitor.rb +280 -0
  34. data/lib/graphql/analysis.rb +102 -1
  35. data/lib/graphql/autoload.rb +38 -0
  36. data/lib/graphql/backtrace/table.rb +118 -55
  37. data/lib/graphql/backtrace.rb +1 -19
  38. data/lib/graphql/coercion_error.rb +1 -9
  39. data/lib/graphql/current.rb +57 -0
  40. data/lib/graphql/dashboard/application_controller.rb +41 -0
  41. data/lib/graphql/dashboard/detailed_traces.rb +47 -0
  42. data/lib/graphql/dashboard/installable.rb +22 -0
  43. data/lib/graphql/dashboard/landings_controller.rb +9 -0
  44. data/lib/graphql/dashboard/limiters.rb +93 -0
  45. data/lib/graphql/dashboard/operation_store.rb +199 -0
  46. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
  47. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
  48. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  49. data/lib/graphql/dashboard/statics/dashboard.css +30 -0
  50. data/lib/graphql/dashboard/statics/dashboard.js +143 -0
  51. data/lib/graphql/dashboard/statics/header-icon.png +0 -0
  52. data/lib/graphql/dashboard/statics/icon.png +0 -0
  53. data/lib/graphql/dashboard/statics_controller.rb +31 -0
  54. data/lib/graphql/dashboard/subscriptions.rb +97 -0
  55. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  56. data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
  57. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  58. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  59. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +24 -0
  60. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  61. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  62. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  63. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  64. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  65. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  66. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  67. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  68. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  69. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  70. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
  71. data/lib/graphql/dashboard.rb +96 -0
  72. data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
  73. data/lib/graphql/dataloader/active_record_source.rb +47 -0
  74. data/lib/graphql/dataloader/async_dataloader.rb +112 -0
  75. data/lib/graphql/dataloader/null_dataloader.rb +55 -10
  76. data/lib/graphql/dataloader/request.rb +5 -0
  77. data/lib/graphql/dataloader/source.rb +35 -12
  78. data/lib/graphql/dataloader.rb +224 -149
  79. data/lib/graphql/date_encoding_error.rb +1 -1
  80. data/lib/graphql/dig.rb +2 -1
  81. data/lib/graphql/duration_encoding_error.rb +16 -0
  82. data/lib/graphql/execution/field_resolve_step.rb +631 -0
  83. data/lib/graphql/execution/finalize.rb +217 -0
  84. data/lib/graphql/execution/input_values.rb +261 -0
  85. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  86. data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
  87. data/lib/graphql/execution/interpreter/handles_raw_value.rb +6 -0
  88. data/lib/graphql/execution/interpreter/resolve.rb +23 -25
  89. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +228 -0
  90. data/lib/graphql/execution/interpreter/runtime.rb +365 -435
  91. data/lib/graphql/execution/interpreter.rb +87 -163
  92. data/lib/graphql/execution/lazy.rb +1 -1
  93. data/lib/graphql/execution/load_argument_step.rb +64 -0
  94. data/lib/graphql/execution/lookahead.rb +105 -31
  95. data/lib/graphql/execution/multiplex.rb +7 -6
  96. data/lib/graphql/execution/next.rb +90 -0
  97. data/lib/graphql/execution/prepare_object_step.rb +128 -0
  98. data/lib/graphql/execution/runner.rb +410 -0
  99. data/lib/graphql/execution/selections_step.rb +91 -0
  100. data/lib/graphql/execution.rb +8 -4
  101. data/lib/graphql/execution_error.rb +17 -10
  102. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  103. data/lib/graphql/introspection/directive_type.rb +7 -3
  104. data/lib/graphql/introspection/dynamic_fields.rb +5 -1
  105. data/lib/graphql/introspection/entry_points.rb +20 -6
  106. data/lib/graphql/introspection/enum_value_type.rb +5 -5
  107. data/lib/graphql/introspection/field_type.rb +13 -5
  108. data/lib/graphql/introspection/input_value_type.rb +21 -13
  109. data/lib/graphql/introspection/schema_type.rb +8 -11
  110. data/lib/graphql/introspection/type_type.rb +64 -28
  111. data/lib/graphql/invalid_name_error.rb +1 -1
  112. data/lib/graphql/invalid_null_error.rb +26 -17
  113. data/lib/graphql/language/block_string.rb +34 -18
  114. data/lib/graphql/language/cache.rb +13 -0
  115. data/lib/graphql/language/comment.rb +18 -0
  116. data/lib/graphql/language/definition_slice.rb +1 -1
  117. data/lib/graphql/language/document_from_schema_definition.rb +90 -61
  118. data/lib/graphql/language/lexer.rb +323 -193
  119. data/lib/graphql/language/nodes.rb +139 -77
  120. data/lib/graphql/language/parser.rb +807 -1985
  121. data/lib/graphql/language/printer.rb +324 -151
  122. data/lib/graphql/language/sanitized_printer.rb +21 -23
  123. data/lib/graphql/language/static_visitor.rb +171 -0
  124. data/lib/graphql/language/visitor.rb +62 -119
  125. data/lib/graphql/language.rb +71 -1
  126. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  127. data/lib/graphql/pagination/array_connection.rb +6 -6
  128. data/lib/graphql/pagination/connection.rb +30 -1
  129. data/lib/graphql/pagination/connections.rb +32 -0
  130. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  131. data/lib/graphql/query/context/scoped_context.rb +101 -0
  132. data/lib/graphql/query/context.rb +88 -144
  133. data/lib/graphql/query/null_context.rb +15 -18
  134. data/lib/graphql/query/partial.rb +194 -0
  135. data/lib/graphql/query/validation_pipeline.rb +4 -4
  136. data/lib/graphql/query/variable_validation_error.rb +1 -1
  137. data/lib/graphql/query/variables.rb +3 -3
  138. data/lib/graphql/query.rb +135 -81
  139. data/lib/graphql/railtie.rb +16 -6
  140. data/lib/graphql/rake_task.rb +3 -12
  141. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  142. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  143. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  144. data/lib/graphql/rubocop.rb +2 -0
  145. data/lib/graphql/runtime_error.rb +6 -0
  146. data/lib/graphql/schema/addition.rb +26 -13
  147. data/lib/graphql/schema/always_visible.rb +7 -2
  148. data/lib/graphql/schema/argument.rb +78 -14
  149. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  150. data/lib/graphql/schema/build_from_definition.rb +140 -66
  151. data/lib/graphql/schema/directive/flagged.rb +4 -2
  152. data/lib/graphql/schema/directive/one_of.rb +12 -0
  153. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  154. data/lib/graphql/schema/directive.rb +78 -12
  155. data/lib/graphql/schema/enum.rb +110 -27
  156. data/lib/graphql/schema/enum_value.rb +11 -3
  157. data/lib/graphql/schema/field/connection_extension.rb +4 -51
  158. data/lib/graphql/schema/field/scope_extension.rb +19 -7
  159. data/lib/graphql/schema/field.rb +245 -119
  160. data/lib/graphql/schema/field_extension.rb +12 -9
  161. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  162. data/lib/graphql/schema/input_object.rb +123 -65
  163. data/lib/graphql/schema/interface.rb +60 -16
  164. data/lib/graphql/schema/introspection_system.rb +8 -17
  165. data/lib/graphql/schema/late_bound_type.rb +4 -0
  166. data/lib/graphql/schema/list.rb +8 -4
  167. data/lib/graphql/schema/loader.rb +3 -4
  168. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -12
  169. data/lib/graphql/schema/member/has_arguments.rb +132 -100
  170. data/lib/graphql/schema/member/has_authorization.rb +35 -0
  171. data/lib/graphql/schema/member/has_dataloader.rb +99 -0
  172. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
  173. data/lib/graphql/schema/member/has_directives.rb +5 -5
  174. data/lib/graphql/schema/member/has_fields.rb +121 -17
  175. data/lib/graphql/schema/member/has_interfaces.rb +27 -13
  176. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  177. data/lib/graphql/schema/member/has_validators.rb +1 -1
  178. data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
  179. data/lib/graphql/schema/member/scoped.rb +19 -0
  180. data/lib/graphql/schema/member/type_system_helpers.rb +18 -5
  181. data/lib/graphql/schema/member/validates_input.rb +3 -3
  182. data/lib/graphql/schema/member.rb +6 -0
  183. data/lib/graphql/schema/mutation.rb +7 -0
  184. data/lib/graphql/schema/non_null.rb +1 -1
  185. data/lib/graphql/schema/object.rb +34 -8
  186. data/lib/graphql/schema/printer.rb +9 -7
  187. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  188. data/lib/graphql/schema/relay_classic_mutation.rb +6 -129
  189. data/lib/graphql/schema/resolver.rb +128 -32
  190. data/lib/graphql/schema/scalar.rb +4 -9
  191. data/lib/graphql/schema/subscription.rb +63 -12
  192. data/lib/graphql/schema/timeout.rb +19 -2
  193. data/lib/graphql/schema/type_expression.rb +2 -2
  194. data/lib/graphql/schema/union.rb +2 -2
  195. data/lib/graphql/schema/unique_within_type.rb +1 -1
  196. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  197. data/lib/graphql/schema/validator/required_validator.rb +92 -11
  198. data/lib/graphql/schema/validator.rb +3 -1
  199. data/lib/graphql/schema/visibility/migration.rb +188 -0
  200. data/lib/graphql/schema/visibility/profile.rb +464 -0
  201. data/lib/graphql/schema/visibility/visit.rb +190 -0
  202. data/lib/graphql/schema/visibility.rb +311 -0
  203. data/lib/graphql/schema/warden.rb +275 -103
  204. data/lib/graphql/schema/wrapper.rb +7 -1
  205. data/lib/graphql/schema.rb +954 -212
  206. data/lib/graphql/static_validation/all_rules.rb +3 -3
  207. data/lib/graphql/static_validation/base_visitor.rb +96 -71
  208. data/lib/graphql/static_validation/literal_validator.rb +6 -7
  209. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +2 -2
  210. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +18 -6
  211. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +6 -2
  212. data/lib/graphql/static_validation/rules/directives_are_defined.rb +6 -3
  213. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
  214. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +14 -3
  215. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +59 -15
  216. data/lib/graphql/static_validation/rules/fields_will_merge.rb +391 -262
  217. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  218. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +6 -6
  219. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +15 -2
  220. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  221. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  222. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  223. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  224. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  225. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +28 -8
  226. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  227. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  228. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +7 -3
  229. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  230. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  231. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  232. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +14 -2
  233. data/lib/graphql/static_validation/validation_context.rb +22 -6
  234. data/lib/graphql/static_validation/validator.rb +9 -1
  235. data/lib/graphql/static_validation.rb +0 -1
  236. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +8 -5
  237. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  238. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +45 -19
  239. data/lib/graphql/subscriptions/event.rb +22 -4
  240. data/lib/graphql/subscriptions/serialize.rb +3 -1
  241. data/lib/graphql/subscriptions.rb +56 -17
  242. data/lib/graphql/testing/helpers.rb +161 -0
  243. data/lib/graphql/testing/mock_action_cable.rb +111 -0
  244. data/lib/graphql/testing.rb +3 -0
  245. data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
  246. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  247. data/lib/graphql/tracing/appoptics_trace.rb +11 -3
  248. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  249. data/lib/graphql/tracing/appsignal_trace.rb +32 -55
  250. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  251. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  252. data/lib/graphql/tracing/data_dog_trace.rb +46 -158
  253. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  254. data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +74 -0
  255. data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
  256. data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
  257. data/lib/graphql/tracing/detailed_trace.rb +156 -0
  258. data/lib/graphql/tracing/legacy_hooks_trace.rb +75 -0
  259. data/lib/graphql/tracing/legacy_trace.rb +4 -61
  260. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  261. data/lib/graphql/tracing/new_relic_trace.rb +47 -54
  262. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  263. data/lib/graphql/tracing/notifications_trace.rb +184 -34
  264. data/lib/graphql/tracing/notifications_tracing.rb +2 -0
  265. data/lib/graphql/tracing/null_trace.rb +9 -0
  266. data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
  267. data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
  268. data/lib/graphql/tracing/perfetto_trace.rb +864 -0
  269. data/lib/graphql/tracing/platform_trace.rb +5 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +3 -1
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +5 -1
  272. data/lib/graphql/tracing/prometheus_trace.rb +72 -68
  273. data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
  274. data/lib/graphql/tracing/scout_trace.rb +32 -55
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +82 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +33 -41
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +118 -1
  280. data/lib/graphql/tracing.rb +31 -28
  281. data/lib/graphql/type_kinds.rb +2 -1
  282. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  283. data/lib/graphql/types/relay/connection_behaviors.rb +45 -3
  284. data/lib/graphql/types/relay/edge_behaviors.rb +19 -1
  285. data/lib/graphql/types/relay/has_node_field.rb +13 -8
  286. data/lib/graphql/types/relay/has_nodes_field.rb +13 -8
  287. data/lib/graphql/types/relay/node_behaviors.rb +13 -2
  288. data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
  289. data/lib/graphql/types.rb +18 -10
  290. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  291. data/lib/graphql/unauthorized_error.rb +9 -1
  292. data/lib/graphql/version.rb +1 -1
  293. data/lib/graphql.rb +69 -54
  294. data/readme.md +12 -2
  295. metadata +236 -40
  296. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  297. data/lib/graphql/analysis/ast/field_usage.rb +0 -57
  298. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -22
  299. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  300. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  301. data/lib/graphql/analysis/ast/query_depth.rb +0 -55
  302. data/lib/graphql/analysis/ast/visitor.rb +0 -276
  303. data/lib/graphql/analysis/ast.rb +0 -81
  304. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  305. data/lib/graphql/backtrace/trace.rb +0 -96
  306. data/lib/graphql/backtrace/tracer.rb +0 -80
  307. data/lib/graphql/deprecation.rb +0 -9
  308. data/lib/graphql/filter.rb +0 -59
  309. data/lib/graphql/language/parser.y +0 -560
  310. data/lib/graphql/language/token.rb +0 -34
  311. data/lib/graphql/schema/base_64_bp.rb +0 -26
  312. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  313. data/lib/graphql/schema/null_mask.rb +0 -11
  314. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  315. data/lib/graphql/static_validation/type_stack.rb +0 -216
  316. data/lib/graphql/subscriptions/instrumentation.rb +0 -28
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Schema
5
+ module HasSingleInputArgument
6
+ def resolve_with_support(**inputs)
7
+ if inputs[:input].is_a?(InputObject)
8
+ input = inputs[:input].to_kwargs
9
+ else
10
+ input = inputs[:input]
11
+ end
12
+
13
+ new_extras = field ? field.extras : []
14
+ all_extras = self.class.extras + new_extras
15
+
16
+ # Transfer these from the top-level hash to the
17
+ # shortcutted `input:` object
18
+ all_extras.each do |ext|
19
+ # It's possible that the `extra` was not passed along by this point,
20
+ # don't re-add it if it wasn't given here.
21
+ if inputs.key?(ext)
22
+ input[ext] = inputs[ext]
23
+ end
24
+ end
25
+
26
+ if input
27
+ # This is handled by Relay::Mutation::Resolve, a bit hacky, but here we are.
28
+ input_kwargs = input.to_h
29
+ else
30
+ # Relay Classic Mutations with no `argument`s
31
+ # don't require `input:`
32
+ input_kwargs = {}
33
+ end
34
+
35
+ if !input_kwargs.empty?
36
+ super(**input_kwargs)
37
+ else
38
+ super()
39
+ end
40
+ end
41
+
42
+ def self.included(base)
43
+ base.extend(ClassMethods)
44
+ end
45
+
46
+ module ClassMethods
47
+ def dummy
48
+ @dummy ||= begin
49
+ d = Class.new(GraphQL::Schema::Resolver)
50
+ d.graphql_name "#{self.graphql_name}DummyResolver"
51
+ d.argument_class(self.argument_class)
52
+ # TODO make this lazier?
53
+ d.argument(:input, input_type, description: "Parameters for #{self.graphql_name}")
54
+ d
55
+ end
56
+ end
57
+
58
+ def field_arguments(context = GraphQL::Query::NullContext.instance)
59
+ dummy.arguments(context)
60
+ end
61
+
62
+ def get_field_argument(name, context = GraphQL::Query::NullContext.instance)
63
+ dummy.get_argument(name, context)
64
+ end
65
+
66
+ def own_field_arguments
67
+ dummy.own_arguments
68
+ end
69
+
70
+ def any_field_arguments?
71
+ dummy.any_arguments?
72
+ end
73
+
74
+ def all_field_argument_definitions
75
+ dummy.all_argument_definitions
76
+ end
77
+
78
+ # Also apply this argument to the input type:
79
+ def argument(*args, own_argument: false, **kwargs, &block)
80
+ it = input_type # make sure any inherited arguments are already added to it
81
+ arg = super(*args, **kwargs, &block)
82
+
83
+ # This definition might be overriding something inherited;
84
+ # if it is, remove the inherited definition so it's not confused at runtime as having multiple definitions
85
+ prev_args = it.own_arguments[arg.graphql_name]
86
+ case prev_args
87
+ when GraphQL::Schema::Argument
88
+ if prev_args.owner != self
89
+ it.own_arguments.delete(arg.graphql_name)
90
+ end
91
+ when Array
92
+ prev_args.reject! { |a| a.owner != self }
93
+ if prev_args.empty?
94
+ it.own_arguments.delete(arg.graphql_name)
95
+ end
96
+ end
97
+
98
+ it.add_argument(arg)
99
+ arg
100
+ end
101
+
102
+ # The base class for generated input object types
103
+ # @param new_class [Class] The base class to use for generating input object definitions
104
+ # @return [Class] The base class for this mutation's generated input object (default is {GraphQL::Schema::InputObject})
105
+ def input_object_class(new_class = nil)
106
+ if new_class
107
+ @input_object_class = new_class
108
+ end
109
+ @input_object_class || (superclass.respond_to?(:input_object_class) ? superclass.input_object_class : GraphQL::Schema::InputObject)
110
+ end
111
+
112
+ # @param new_input_type [Class, nil] If provided, it configures this mutation to accept `new_input_type` instead of generating an input type
113
+ # @return [Class] The generated {Schema::InputObject} class for this mutation's `input`
114
+ def input_type(new_input_type = nil)
115
+ if new_input_type
116
+ @input_type = new_input_type
117
+ end
118
+ @input_type ||= generate_input_type
119
+ end
120
+
121
+ private
122
+
123
+ # Generate the input type for the `input:` argument
124
+ # To customize how input objects are generated, override this method
125
+ # @return [Class] a subclass of {.input_object_class}
126
+ def generate_input_type
127
+ mutation_args = all_argument_definitions
128
+ mutation_class = self
129
+ Class.new(input_object_class) do
130
+ class << self
131
+ def default_graphql_name
132
+ "#{self.mutation.graphql_name}Input"
133
+ end
134
+
135
+ def description(new_desc = nil)
136
+ super || "Autogenerated input type of #{self.mutation.graphql_name}"
137
+ end
138
+ end
139
+ # For compatibility, in case no arguments are defined:
140
+ has_no_arguments(true)
141
+ mutation(mutation_class)
142
+ # these might be inherited:
143
+ mutation_args.each do |arg|
144
+ add_argument(arg)
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ private
151
+
152
+ def authorize_arguments(args, values)
153
+ # remove the `input` wrapper to match values
154
+ input_type = args.find { |a| a.graphql_name == "input" }.type.unwrap
155
+ input_args = context.types.arguments(input_type)
156
+ super(input_args, values)
157
+ end
158
+ end
159
+ end
160
+ end
@@ -10,6 +10,14 @@ module GraphQL
10
10
 
11
11
  include GraphQL::Dig
12
12
 
13
+ # Raised when an InputObject doesn't have any arguments defined and hasn't explicitly opted out of this requirement
14
+ class ArgumentsAreRequiredError < GraphQL::Error
15
+ def initialize(input_object_type)
16
+ message = "Input Object types must have arguments, but #{input_object_type.graphql_name} doesn't have any. Define an argument for this type, remove it from your schema, or add `has_no_arguments(true)` to its definition."
17
+ super(message)
18
+ end
19
+ end
20
+
13
21
  # @return [GraphQL::Query::Context] The context for this query
14
22
  attr_reader :context
15
23
  # @return [GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
@@ -23,13 +31,14 @@ module GraphQL
23
31
  @ruby_style_hash = ruby_kwargs
24
32
  @arguments = arguments
25
33
  # Apply prepares, not great to have it duplicated here.
26
- self.class.arguments(context).each_value do |arg_defn|
34
+ arg_defns = context ? context.types.arguments(self.class) : self.class.arguments(context).each_value
35
+ arg_defns.each do |arg_defn|
27
36
  ruby_kwargs_key = arg_defn.keyword
28
37
  if @ruby_style_hash.key?(ruby_kwargs_key)
29
38
  # Weirdly, procs are applied during coercion, but not methods.
30
39
  # Probably because these methods require a `self`.
31
40
  if arg_defn.prepare.is_a?(Symbol) || context.nil?
32
- prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
41
+ prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key], context: context)
33
42
  overwrite_argument(ruby_kwargs_key, prepared_value)
34
43
  end
35
44
  end
@@ -44,42 +53,18 @@ module GraphQL
44
53
  to_h
45
54
  end
46
55
 
47
- def prepare
48
- if @context
49
- object = @context[:current_object]
50
- # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
51
- Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
52
- self
56
+ def deconstruct_keys(keys = nil)
57
+ if keys.nil?
58
+ @ruby_style_hash
53
59
  else
54
- self
60
+ new_h = {}
61
+ keys.each { |k| @ruby_style_hash.key?(k) && new_h[k] = @ruby_style_hash[k] }
62
+ new_h
55
63
  end
56
64
  end
57
65
 
58
- def self.authorized?(obj, value, ctx)
59
- # Authorize each argument (but this doesn't apply if `prepare` is implemented):
60
- if value.respond_to?(:key?)
61
- arguments(ctx).each do |_name, input_obj_arg|
62
- if value.key?(input_obj_arg.keyword) &&
63
- !input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
64
- return false
65
- end
66
- end
67
- end
68
- # It didn't early-return false:
69
- true
70
- end
71
-
72
- def self.one_of
73
- if !one_of?
74
- if all_argument_definitions.any? { |arg| arg.type.non_null? }
75
- raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
76
- end
77
- directive(GraphQL::Schema::Directive::OneOf)
78
- end
79
- end
80
-
81
- def self.one_of?
82
- directives.any? { |d| d.is_a?(GraphQL::Schema::Directive::OneOf) }
66
+ def prepare
67
+ self
83
68
  end
84
69
 
85
70
  def unwrap_value(value)
@@ -119,7 +104,42 @@ module GraphQL
119
104
  @ruby_style_hash.dup
120
105
  end
121
106
 
107
+ # @api private
108
+ def validate_for(context)
109
+ object = context[:current_object]
110
+ # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
111
+ Schema::Validator.validate!(self.class.validators, object, context, @ruby_style_hash, as: self.class)
112
+ nil
113
+ end
114
+
122
115
  class << self
116
+ def authorized?(obj, value, ctx)
117
+ # Authorize each argument (but this doesn't apply if `prepare` is implemented):
118
+ if value.respond_to?(:key?)
119
+ ctx.types.arguments(self).each do |input_obj_arg|
120
+ if value.key?(input_obj_arg.keyword) &&
121
+ !input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
122
+ return false
123
+ end
124
+ end
125
+ end
126
+ # It didn't early-return false:
127
+ true
128
+ end
129
+
130
+ def one_of
131
+ if !one_of?
132
+ if all_argument_definitions.any? { |arg| arg.type.non_null? }
133
+ raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
134
+ end
135
+ directive(GraphQL::Schema::Directive::OneOf)
136
+ end
137
+ end
138
+
139
+ def one_of?
140
+ false # Re-defined when `OneOf` is added
141
+ end
142
+
123
143
  def argument(*args, **kwargs, &block)
124
144
  argument_defn = super(*args, **kwargs, &block)
125
145
  if one_of?
@@ -131,12 +151,9 @@ module GraphQL
131
151
  end
132
152
  end
133
153
  # Add a method access
134
- method_name = argument_defn.keyword
135
- class_eval <<-RUBY, __FILE__, __LINE__
136
- def #{method_name}
137
- self[#{method_name.inspect}]
138
- end
139
- RUBY
154
+ suppress_redefinition_warning do
155
+ define_accessor_method(argument_defn.keyword)
156
+ end
140
157
  argument_defn
141
158
  end
142
159
 
@@ -145,10 +162,10 @@ module GraphQL
145
162
  end
146
163
 
147
164
  # @api private
148
- INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
165
+ INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object."
149
166
 
150
167
  def validate_non_null_input(input, ctx, max_errors: nil)
151
- warden = ctx.warden
168
+ types = ctx.types
152
169
 
153
170
  if input.is_a?(Array)
154
171
  return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
@@ -159,30 +176,37 @@ module GraphQL
159
176
  return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
160
177
  end
161
178
 
162
- # Inject missing required arguments
163
- missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
164
- if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
165
- m[argument_name] = nil
166
- end
167
-
168
- m
169
- end
170
179
 
171
180
  result = nil
172
- [input, missing_required_inputs].each do |args_to_validate|
173
- args_to_validate.each do |argument_name, value|
174
- argument = warden.get_argument(self, argument_name)
175
- # Items in the input that are unexpected
176
- if argument.nil?
177
- result ||= Query::InputValidationResult.new
178
- result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
179
- else
180
- # Items in the input that are expected, but have invalid values
181
- argument_result = argument.type.validate_input(value, ctx)
181
+
182
+
183
+ input.each do |argument_name, value|
184
+ argument = types.argument(self, argument_name)
185
+ if argument.nil? && ctx.is_a?(Query::NullContext) && argument_name.is_a?(Symbol)
186
+ # Validating definition directive arguments which come in as Symbols
187
+ argument = types.arguments(self).find { |arg| arg.keyword == argument_name }
188
+ end
189
+ # Items in the input that are unexpected
190
+ if argument.nil?
191
+ result ||= Query::InputValidationResult.new
192
+ result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
193
+ else
194
+ # Items in the input that are expected, but have invalid values
195
+ argument_result = argument.type.validate_input(value, ctx)
196
+ if !argument_result.valid?
182
197
  result ||= Query::InputValidationResult.new
183
- if !argument_result.valid?
184
- result.merge_result!(argument_name, argument_result)
185
- end
198
+ result.merge_result!(argument_name, argument_result)
199
+ end
200
+ end
201
+ end
202
+
203
+ # Check for missing non-null arguments
204
+ ctx.types.arguments(self).each do |argument|
205
+ if !input.key?(argument.graphql_name) && argument.type.non_null? && !argument.default_value?
206
+ result ||= Query::InputValidationResult.new
207
+ argument_result = argument.type.validate_input(nil, ctx)
208
+ if !argument_result.valid?
209
+ result.merge_result!(argument.graphql_name, argument_result)
186
210
  end
187
211
  end
188
212
  end
@@ -215,8 +239,7 @@ module GraphQL
215
239
  if resolved_arguments.is_a?(GraphQL::Error)
216
240
  raise resolved_arguments
217
241
  else
218
- input_obj_instance = self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
219
- input_obj_instance.prepare
242
+ self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
220
243
  end
221
244
  end
222
245
  end
@@ -242,6 +265,41 @@ module GraphQL
242
265
 
243
266
  result
244
267
  end
268
+
269
+ # @param new_has_no_arguments [Boolean] Call with `true` to make this InputObject type ignore the requirement to have any defined arguments.
270
+ # @return [void]
271
+ def has_no_arguments(new_has_no_arguments)
272
+ @has_no_arguments = new_has_no_arguments
273
+ nil
274
+ end
275
+
276
+ # @return [Boolean] `true` if `has_no_arguments(true)` was configued
277
+ def has_no_arguments?
278
+ @has_no_arguments
279
+ end
280
+
281
+ def arguments(context = GraphQL::Query::NullContext.instance, require_defined_arguments = true)
282
+ if require_defined_arguments && !has_no_arguments? && !any_arguments?
283
+ warn(GraphQL::Schema::InputObject::ArgumentsAreRequiredError.new(self).message + "\n\nThis will raise an error in a future GraphQL-Ruby version.")
284
+ end
285
+ super(context, false)
286
+ end
287
+
288
+ private
289
+
290
+ # Suppress redefinition warning for objectId arguments
291
+ def suppress_redefinition_warning
292
+ verbose = $VERBOSE
293
+ $VERBOSE = nil
294
+ yield
295
+ ensure
296
+ $VERBOSE = verbose
297
+ end
298
+
299
+ def define_accessor_method(method_name)
300
+ define_method(method_name) { self[method_name] }
301
+ alias_method(method_name, method_name)
302
+ end
245
303
  end
246
304
 
247
305
  private
@@ -13,6 +13,7 @@ module GraphQL
13
13
  include GraphQL::Schema::Member::Scoped
14
14
  include GraphQL::Schema::Member::HasAstNode
15
15
  include GraphQL::Schema::Member::HasUnresolvedTypeError
16
+ include GraphQL::Schema::Member::HasDataloader
16
17
  include GraphQL::Schema::Member::HasDirectives
17
18
  include GraphQL::Schema::Member::HasInterfaces
18
19
 
@@ -20,7 +21,36 @@ module GraphQL
20
21
  # - Added as class methods to this interface
21
22
  # - Added as class methods to all child interfaces
22
23
  def definition_methods(&block)
23
- self::DefinitionMethods.module_eval(&block)
24
+ # Use an instance variable to tell whether it's been included previously or not;
25
+ # You can't use constant detection because constants are brought into scope
26
+ # by `include`, which has already happened at this point.
27
+ if !defined?(@_definition_methods)
28
+ defn_methods_module = Module.new
29
+ @_definition_methods = defn_methods_module
30
+ const_set(:DefinitionMethods, defn_methods_module)
31
+ extend(self::DefinitionMethods)
32
+ end
33
+ self::DefinitionMethods.module_exec(&block)
34
+ end
35
+
36
+ # Instance methods defined in this block will become class methods on objects that implement this interface.
37
+ # Use it to implement `resolve_each:`, `resolve_batch:`, and `resolve_static:` fields.
38
+ # @example
39
+ # field :thing, String, resolve_static: true
40
+ #
41
+ # resolver_methods do
42
+ # def thing
43
+ # Somehow.get.thing
44
+ # end
45
+ # end
46
+ def resolver_methods(&block)
47
+ if !defined?(@_resolver_methods)
48
+ resolver_methods_module = Module.new
49
+ @_resolver_methods = resolver_methods_module
50
+ const_set(:ResolverMethods, resolver_methods_module)
51
+ extend(self::ResolverMethods)
52
+ end
53
+ self::ResolverMethods.module_exec(&block)
24
54
  end
25
55
 
26
56
  # @see {Schema::Warden} hides interfaces without visible implementations
@@ -47,22 +77,14 @@ module GraphQL
47
77
 
48
78
  child_class.type_membership_class(self.type_membership_class)
49
79
  child_class.ancestors.reverse_each do |ancestor|
50
- if ancestor.const_defined?(:DefinitionMethods)
80
+ if ancestor.const_defined?(:DefinitionMethods) && ancestor != child_class
51
81
  child_class.extend(ancestor::DefinitionMethods)
52
82
  end
53
83
  end
54
84
 
55
- # Use an instance variable to tell whether it's been included previously or not;
56
- # You can't use constant detection because constants are brought into scope
57
- # by `include`, which has already happened at this point.
58
- if !child_class.instance_variable_defined?(:@_definition_methods)
59
- defn_methods_module = Module.new
60
- child_class.instance_variable_set(:@_definition_methods, defn_methods_module)
61
- child_class.const_set(:DefinitionMethods, defn_methods_module)
62
- child_class.extend(child_class::DefinitionMethods)
63
- end
64
85
  child_class.introspection(introspection)
65
86
  child_class.description(description)
87
+ child_class.comment(nil)
66
88
  # If interfaces are mixed into each other, only define this class once
67
89
  if !child_class.const_defined?(:UnresolvedTypeError, false)
68
90
  add_unresolved_type_error(child_class)
@@ -77,18 +99,40 @@ module GraphQL
77
99
  if !backtrace_line
78
100
  raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
79
101
  end
102
+
103
+ child_class.ancestors.reverse_each do |ancestor|
104
+ if ancestor.const_defined?(:ResolverMethods)
105
+ child_class.extend(ancestor::ResolverMethods)
106
+ end
107
+ end
80
108
  end
81
109
 
82
110
  super
83
111
  end
84
112
 
113
+ # Register other Interface or Object types as implementers of this Interface.
114
+ #
115
+ # When those Interfaces or Objects aren't used as the return values of fields,
116
+ # they may have to be registered using this method so that GraphQL-Ruby can find them.
117
+ # @param types [Class, Module]
118
+ # @return [Array<Module, Class>] Implementers of this interface, if they're registered
85
119
  def orphan_types(*types)
86
- if types.any?
87
- @orphan_types = types
120
+ if !types.empty?
121
+ @orphan_types ||= []
122
+ @orphan_types.concat(types)
88
123
  else
89
- all_orphan_types = @orphan_types || []
90
- all_orphan_types += super if defined?(super)
91
- all_orphan_types.uniq
124
+ if defined?(@orphan_types)
125
+ all_orphan_types = @orphan_types.dup
126
+ if defined?(super)
127
+ all_orphan_types += super
128
+ all_orphan_types.uniq!
129
+ end
130
+ all_orphan_types
131
+ elsif defined?(super)
132
+ super
133
+ else
134
+ EmptyObjects::EMPTY_ARRAY
135
+ end
92
136
  end
93
137
  end
94
138
 
@@ -25,10 +25,10 @@ module GraphQL
25
25
  load_constant(:DirectiveLocationEnum)
26
26
  ]
27
27
  @types = {}
28
- @possible_types = {}
28
+ @possible_types = {}.compare_by_identity
29
29
  type_defns.each do |t|
30
30
  @types[t.graphql_name] = t
31
- @possible_types[t.graphql_name] = [t]
31
+ @possible_types[t] = [t]
32
32
  end
33
33
  @entry_point_fields =
34
34
  if schema.disable_introspection_entry_points?
@@ -39,7 +39,9 @@ module GraphQL
39
39
  entry_point_fields.delete('__type') if schema.disable_type_introspection_entry_point?
40
40
  entry_point_fields
41
41
  end
42
+ @entry_point_fields.each { |k, v| v.dynamic_introspection = true }
42
43
  @dynamic_fields = get_fields_from_class(class_sym: :DynamicFields)
44
+ @dynamic_fields.each { |k, v| v.dynamic_introspection = true }
43
45
  end
44
46
 
45
47
  def entry_points
@@ -67,7 +69,7 @@ module GraphQL
67
69
  def resolve_late_bindings
68
70
  @types.each do |name, t|
69
71
  if t.kind.fields?
70
- t.fields.each do |_name, field_defn|
72
+ t.all_field_definitions.each do |field_defn|
71
73
  field_defn.type = resolve_late_binding(field_defn.type)
72
74
  end
73
75
  end
@@ -88,7 +90,8 @@ module GraphQL
88
90
  def resolve_late_binding(late_bound_type)
89
91
  case late_bound_type
90
92
  when GraphQL::Schema::LateBoundType
91
- @schema.get_type(late_bound_type.name)
93
+ type_name = late_bound_type.name
94
+ @types[type_name] || @schema.get_type(type_name)
92
95
  when GraphQL::Schema::List
93
96
  resolve_late_binding(late_bound_type.of_type).to_list_type
94
97
  when GraphQL::Schema::NonNull
@@ -111,19 +114,7 @@ module GraphQL
111
114
 
112
115
  def get_fields_from_class(class_sym:)
113
116
  object_type_defn = load_constant(class_sym)
114
-
115
- if object_type_defn.is_a?(Module)
116
- object_type_defn.fields
117
- else
118
- extracted_field_defns = {}
119
- object_class = object_type_defn.metadata[:type_class]
120
- object_type_defn.all_fields.each do |field_defn|
121
- inner_resolve = field_defn.resolve_proc
122
- resolve_with_instantiate = PerFieldProxyResolve.new(object_class: object_class, inner_resolve: inner_resolve)
123
- extracted_field_defns[field_defn.name] = field_defn.redefine(resolve: resolve_with_instantiate)
124
- end
125
- extracted_field_defns
126
- end
117
+ object_type_defn.fields
127
118
  end
128
119
 
129
120
  # This is probably not 100% robust -- but it has to be good enough to avoid modifying the built-in introspection types
@@ -25,6 +25,10 @@ module GraphQL
25
25
  @to_list_type ||= GraphQL::Schema::List.new(self)
26
26
  end
27
27
 
28
+ def to_type_signature
29
+ name
30
+ end
31
+
28
32
  def inspect
29
33
  "#<LateBoundType @name=#{name}>"
30
34
  end
@@ -4,7 +4,7 @@ module GraphQL
4
4
  class Schema
5
5
  # Represents a list type in the schema.
6
6
  # Wraps a {Schema::Member} as a list type.
7
- # @see {Schema::Member::TypeSystemHelpers#to_list_type}
7
+ # @see Schema::Member::TypeSystemHelpers#to_list_type Create a list type from another GraphQL type
8
8
  class List < GraphQL::Schema::Wrapper
9
9
  include Schema::Member::ValidatesInput
10
10
 
@@ -19,7 +19,11 @@ module GraphQL
19
19
  end
20
20
 
21
21
  def to_type_signature
22
- "[#{@of_type.to_type_signature}]"
22
+ @type_signature ||= -"[#{@of_type.to_type_signature}]"
23
+ end
24
+
25
+ def authorizes?(ctx)
26
+ of_type.authorizes?(ctx)
23
27
  end
24
28
 
25
29
  # This is for introspection, where it's expected the name will be `null`
@@ -52,7 +56,7 @@ module GraphQL
52
56
  unless item_result.valid?
53
57
  if max_errors
54
58
  if max_errors == 0
55
- add_max_errros_reached_message(result)
59
+ add_max_errors_reached_message(result)
56
60
  break
57
61
  end
58
62
 
@@ -76,7 +80,7 @@ module GraphQL
76
80
  end
77
81
  end
78
82
 
79
- def add_max_errros_reached_message(result)
83
+ def add_max_errors_reached_message(result)
80
84
  message = "Too many errors processing list variable, max validation error limit reached. Execution aborted"
81
85
  item_result = GraphQL::Query::InputValidationResult.from_problem(message)
82
86
  result.merge_result!(nil, item_result)
@@ -32,7 +32,8 @@ module GraphQL
32
32
  end
33
33
 
34
34
  Class.new(GraphQL::Schema) do
35
- orphan_types(types.values)
35
+ add_type_and_traverse(types.values, root: false)
36
+ orphan_types(types.values.select { |t| t.kind.object? })
36
37
  directives(directives)
37
38
  description(schema["description"])
38
39
 
@@ -176,7 +177,6 @@ module GraphQL
176
177
  while (of_type = unwrapped_field_hash["ofType"])
177
178
  unwrapped_field_hash = of_type
178
179
  end
179
- type_name = unwrapped_field_hash["name"]
180
180
 
181
181
  type_defn.field(
182
182
  field_hash["name"],
@@ -186,9 +186,8 @@ module GraphQL
186
186
  null: true,
187
187
  camelize: false,
188
188
  connection_extension: nil,
189
- connection: type_name.end_with?("Connection"),
190
189
  ) do
191
- if field_hash["args"].any?
190
+ if !field_hash["args"].empty?
192
191
  loader.build_arguments(self, field_hash["args"], type_resolver)
193
192
  end
194
193
  end