graphql 1.13.24 → 2.5.11

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 (427) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  3. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  4. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  5. data/lib/generators/graphql/install_generator.rb +50 -1
  6. data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
  7. data/lib/generators/graphql/mutation_update_generator.rb +1 -1
  8. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  9. data/lib/generators/graphql/relay.rb +21 -18
  10. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  11. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  12. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  13. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  14. data/lib/generators/graphql/templates/base_field.erb +2 -0
  15. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  16. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  17. data/lib/generators/graphql/templates/base_object.erb +2 -0
  18. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  19. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  20. data/lib/generators/graphql/templates/base_union.erb +2 -0
  21. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  22. data/lib/generators/graphql/templates/loader.erb +2 -0
  23. data/lib/generators/graphql/templates/mutation.erb +2 -0
  24. data/lib/generators/graphql/templates/node_type.erb +2 -0
  25. data/lib/generators/graphql/templates/query_type.erb +2 -0
  26. data/lib/generators/graphql/templates/schema.erb +8 -0
  27. data/lib/generators/graphql/type_generator.rb +1 -1
  28. data/lib/graphql/analysis/analyzer.rb +90 -0
  29. data/lib/graphql/analysis/field_usage.rb +65 -28
  30. data/lib/graphql/analysis/max_query_complexity.rb +11 -17
  31. data/lib/graphql/analysis/max_query_depth.rb +13 -19
  32. data/lib/graphql/analysis/query_complexity.rb +236 -61
  33. data/lib/graphql/analysis/query_depth.rb +38 -23
  34. data/lib/graphql/analysis/visitor.rb +280 -0
  35. data/lib/graphql/analysis.rb +93 -6
  36. data/lib/graphql/autoload.rb +38 -0
  37. data/lib/graphql/backtrace/table.rb +118 -73
  38. data/lib/graphql/backtrace.rb +2 -25
  39. data/lib/graphql/coercion_error.rb +1 -9
  40. data/lib/graphql/current.rb +57 -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/limiters.rb +93 -0
  44. data/lib/graphql/dashboard/operation_store.rb +199 -0
  45. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
  46. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
  47. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  48. data/lib/graphql/dashboard/statics/dashboard.css +30 -0
  49. data/lib/graphql/dashboard/statics/dashboard.js +143 -0
  50. data/lib/graphql/dashboard/statics/header-icon.png +0 -0
  51. data/lib/graphql/dashboard/statics/icon.png +0 -0
  52. data/lib/graphql/dashboard/subscriptions.rb +96 -0
  53. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  54. data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
  55. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  56. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  57. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
  58. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  59. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  60. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  61. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  62. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  63. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  64. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  65. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  66. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  67. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  68. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
  69. data/lib/graphql/dashboard.rb +158 -0
  70. data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
  71. data/lib/graphql/dataloader/active_record_source.rb +47 -0
  72. data/lib/graphql/dataloader/async_dataloader.rb +101 -0
  73. data/lib/graphql/dataloader/null_dataloader.rb +11 -2
  74. data/lib/graphql/dataloader/request.rb +5 -0
  75. data/lib/graphql/dataloader/source.rb +103 -47
  76. data/lib/graphql/dataloader.rb +174 -148
  77. data/lib/graphql/dig.rb +3 -2
  78. data/lib/graphql/duration_encoding_error.rb +16 -0
  79. data/lib/graphql/execution/errors.rb +12 -82
  80. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  81. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  82. data/lib/graphql/execution/interpreter/arguments_cache.rb +30 -35
  83. data/lib/graphql/execution/interpreter/resolve.rb +32 -2
  84. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +215 -0
  85. data/lib/graphql/execution/interpreter/runtime.rb +525 -502
  86. data/lib/graphql/execution/interpreter.rb +127 -81
  87. data/lib/graphql/execution/lazy.rb +7 -21
  88. data/lib/graphql/execution/lookahead.rb +133 -55
  89. data/lib/graphql/execution/multiplex.rb +6 -176
  90. data/lib/graphql/execution.rb +11 -4
  91. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  92. data/lib/graphql/introspection/directive_type.rb +1 -1
  93. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  94. data/lib/graphql/introspection/entry_points.rb +10 -17
  95. data/lib/graphql/introspection/field_type.rb +1 -1
  96. data/lib/graphql/introspection/schema_type.rb +8 -11
  97. data/lib/graphql/introspection/type_type.rb +13 -6
  98. data/lib/graphql/introspection.rb +4 -3
  99. data/lib/graphql/invalid_name_error.rb +1 -1
  100. data/lib/graphql/invalid_null_error.rb +20 -17
  101. data/lib/graphql/language/block_string.rb +34 -18
  102. data/lib/graphql/language/cache.rb +13 -0
  103. data/lib/graphql/language/comment.rb +18 -0
  104. data/lib/graphql/language/definition_slice.rb +1 -1
  105. data/lib/graphql/language/document_from_schema_definition.rb +114 -80
  106. data/lib/graphql/language/lexer.rb +375 -1489
  107. data/lib/graphql/language/nodes.rb +189 -104
  108. data/lib/graphql/language/parser.rb +807 -1941
  109. data/lib/graphql/language/printer.rb +366 -163
  110. data/lib/graphql/language/sanitized_printer.rb +21 -23
  111. data/lib/graphql/language/static_visitor.rb +171 -0
  112. data/lib/graphql/language/visitor.rb +189 -138
  113. data/lib/graphql/language.rb +62 -1
  114. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  115. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  116. data/lib/graphql/pagination/array_connection.rb +8 -6
  117. data/lib/graphql/pagination/connection.rb +61 -7
  118. data/lib/graphql/pagination/connections.rb +3 -28
  119. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  120. data/lib/graphql/pagination/relation_connection.rb +2 -0
  121. data/lib/graphql/query/context/scoped_context.rb +101 -0
  122. data/lib/graphql/query/context.rb +131 -225
  123. data/lib/graphql/query/input_validation_result.rb +1 -1
  124. data/lib/graphql/query/null_context.rb +11 -33
  125. data/lib/graphql/query/partial.rb +179 -0
  126. data/lib/graphql/query/validation_pipeline.rb +14 -37
  127. data/lib/graphql/query/variable_validation_error.rb +1 -1
  128. data/lib/graphql/query/variables.rb +6 -19
  129. data/lib/graphql/query.rb +162 -98
  130. data/lib/graphql/railtie.rb +15 -109
  131. data/lib/graphql/rake_task/validate.rb +1 -1
  132. data/lib/graphql/rake_task.rb +30 -11
  133. data/lib/graphql/relay/range_add.rb +9 -20
  134. data/lib/graphql/relay.rb +0 -15
  135. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  136. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  137. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  138. data/lib/graphql/rubocop.rb +2 -0
  139. data/lib/graphql/schema/addition.rb +70 -33
  140. data/lib/graphql/schema/always_visible.rb +15 -0
  141. data/lib/graphql/schema/argument.rb +104 -59
  142. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  143. data/lib/graphql/schema/build_from_definition.rb +154 -74
  144. data/lib/graphql/schema/directive/flagged.rb +4 -2
  145. data/lib/graphql/schema/directive/one_of.rb +24 -0
  146. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  147. data/lib/graphql/schema/directive/transform.rb +1 -1
  148. data/lib/graphql/schema/directive.rb +47 -24
  149. data/lib/graphql/schema/enum.rb +137 -65
  150. data/lib/graphql/schema/enum_value.rb +11 -26
  151. data/lib/graphql/schema/field/connection_extension.rb +6 -16
  152. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  153. data/lib/graphql/schema/field.rb +399 -404
  154. data/lib/graphql/schema/field_extension.rb +2 -5
  155. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +144 -99
  158. data/lib/graphql/schema/interface.rb +34 -51
  159. data/lib/graphql/schema/introspection_system.rb +12 -26
  160. data/lib/graphql/schema/late_bound_type.rb +12 -2
  161. data/lib/graphql/schema/list.rb +3 -9
  162. data/lib/graphql/schema/loader.rb +4 -6
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
  164. data/lib/graphql/schema/member/build_type.rb +15 -9
  165. data/lib/graphql/schema/member/has_arguments.rb +192 -96
  166. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  167. data/lib/graphql/schema/member/has_dataloader.rb +62 -0
  168. data/lib/graphql/schema/member/has_deprecation_reason.rb +18 -4
  169. data/lib/graphql/schema/member/has_directives.rb +81 -61
  170. data/lib/graphql/schema/member/has_fields.rb +119 -39
  171. data/lib/graphql/schema/member/has_interfaces.rb +66 -23
  172. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  173. data/lib/graphql/schema/member/has_validators.rb +32 -6
  174. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  175. data/lib/graphql/schema/member/scoped.rb +19 -0
  176. data/lib/graphql/schema/member/type_system_helpers.rb +32 -2
  177. data/lib/graphql/schema/member/validates_input.rb +4 -4
  178. data/lib/graphql/schema/member.rb +1 -6
  179. data/lib/graphql/schema/mutation.rb +7 -9
  180. data/lib/graphql/schema/non_null.rb +1 -7
  181. data/lib/graphql/schema/object.rb +42 -49
  182. data/lib/graphql/schema/printer.rb +12 -8
  183. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  184. data/lib/graphql/schema/relay_classic_mutation.rb +12 -124
  185. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  186. data/lib/graphql/schema/resolver.rb +96 -81
  187. data/lib/graphql/schema/scalar.rb +10 -30
  188. data/lib/graphql/schema/subscription.rb +60 -14
  189. data/lib/graphql/schema/timeout.rb +44 -31
  190. data/lib/graphql/schema/type_expression.rb +2 -2
  191. data/lib/graphql/schema/type_membership.rb +3 -0
  192. data/lib/graphql/schema/union.rb +12 -19
  193. data/lib/graphql/schema/unique_within_type.rb +1 -1
  194. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  195. data/lib/graphql/schema/validator/required_validator.rb +60 -10
  196. data/lib/graphql/schema/validator.rb +5 -3
  197. data/lib/graphql/schema/visibility/migration.rb +188 -0
  198. data/lib/graphql/schema/visibility/profile.rb +445 -0
  199. data/lib/graphql/schema/visibility/visit.rb +190 -0
  200. data/lib/graphql/schema/visibility.rb +311 -0
  201. data/lib/graphql/schema/warden.rb +318 -94
  202. data/lib/graphql/schema/wrapper.rb +0 -5
  203. data/lib/graphql/schema.rb +1148 -1085
  204. data/lib/graphql/static_validation/all_rules.rb +4 -3
  205. data/lib/graphql/static_validation/base_visitor.rb +11 -27
  206. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  207. data/lib/graphql/static_validation/error.rb +2 -2
  208. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  209. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  210. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  211. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  212. data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
  213. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -12
  214. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  215. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +48 -6
  216. data/lib/graphql/static_validation/rules/fields_will_merge.rb +90 -27
  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 +3 -3
  219. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -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/one_of_input_objects_are_valid.rb +66 -0
  225. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  226. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  227. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -5
  228. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  229. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  230. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +19 -9
  231. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  232. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  233. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  234. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  235. data/lib/graphql/static_validation/validation_context.rb +21 -5
  236. data/lib/graphql/static_validation/validator.rb +12 -26
  237. data/lib/graphql/static_validation.rb +0 -3
  238. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +14 -6
  239. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  240. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
  241. data/lib/graphql/subscriptions/event.rb +24 -12
  242. data/lib/graphql/subscriptions/serialize.rb +3 -1
  243. data/lib/graphql/subscriptions.rb +48 -32
  244. data/lib/graphql/testing/helpers.rb +158 -0
  245. data/lib/graphql/testing.rb +2 -0
  246. data/lib/graphql/tracing/active_support_notifications_trace.rb +27 -0
  247. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  248. data/lib/graphql/tracing/appoptics_trace.rb +259 -0
  249. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  250. data/lib/graphql/tracing/appsignal_trace.rb +54 -0
  251. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  252. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  253. data/lib/graphql/tracing/data_dog_trace.rb +71 -0
  254. data/lib/graphql/tracing/data_dog_tracing.rb +3 -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 +93 -0
  258. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
  259. data/lib/graphql/tracing/legacy_trace.rb +12 -0
  260. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  261. data/lib/graphql/tracing/new_relic_trace.rb +68 -0
  262. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  263. data/lib/graphql/tracing/notifications_trace.rb +195 -0
  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 +734 -0
  269. data/lib/graphql/tracing/platform_trace.rb +123 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +28 -41
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
  272. data/lib/graphql/tracing/prometheus_trace.rb +93 -0
  273. data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
  274. data/lib/graphql/tracing/scout_trace.rb +49 -0
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +80 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +48 -0
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +186 -0
  280. data/lib/graphql/tracing.rb +32 -52
  281. data/lib/graphql/type_kinds.rb +8 -4
  282. data/lib/graphql/types/iso_8601_date.rb +4 -1
  283. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  284. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  285. data/lib/graphql/types/relay/base_connection.rb +16 -6
  286. data/lib/graphql/types/relay/connection_behaviors.rb +65 -23
  287. data/lib/graphql/types/relay/edge_behaviors.rb +33 -5
  288. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  289. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  290. data/lib/graphql/types/relay.rb +0 -3
  291. data/lib/graphql/types/string.rb +1 -1
  292. data/lib/graphql/types.rb +18 -10
  293. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  294. data/lib/graphql/version.rb +1 -1
  295. data/lib/graphql.rb +76 -123
  296. data/readme.md +13 -3
  297. metadata +225 -142
  298. data/lib/graphql/analysis/analyze_query.rb +0 -98
  299. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  300. data/lib/graphql/analysis/ast/field_usage.rb +0 -55
  301. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
  302. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  303. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  304. data/lib/graphql/analysis/ast/query_depth.rb +0 -56
  305. data/lib/graphql/analysis/ast/visitor.rb +0 -269
  306. data/lib/graphql/analysis/ast.rb +0 -91
  307. data/lib/graphql/analysis/reducer_state.rb +0 -48
  308. data/lib/graphql/argument.rb +0 -131
  309. data/lib/graphql/authorization.rb +0 -82
  310. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  311. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  312. data/lib/graphql/backtrace/tracer.rb +0 -81
  313. data/lib/graphql/backwards_compatibility.rb +0 -61
  314. data/lib/graphql/base_type.rb +0 -232
  315. data/lib/graphql/boolean_type.rb +0 -2
  316. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  317. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  318. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  319. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  320. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  321. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  322. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  323. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  324. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  325. data/lib/graphql/compatibility.rb +0 -5
  326. data/lib/graphql/define/assign_argument.rb +0 -12
  327. data/lib/graphql/define/assign_connection.rb +0 -13
  328. data/lib/graphql/define/assign_enum_value.rb +0 -18
  329. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  330. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  331. data/lib/graphql/define/assign_object_field.rb +0 -42
  332. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  333. data/lib/graphql/define/instance_definable.rb +0 -255
  334. data/lib/graphql/define/no_definition_error.rb +0 -7
  335. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  336. data/lib/graphql/define/type_definer.rb +0 -31
  337. data/lib/graphql/define.rb +0 -31
  338. data/lib/graphql/deprecated_dsl.rb +0 -55
  339. data/lib/graphql/deprecation.rb +0 -9
  340. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  341. data/lib/graphql/directive/include_directive.rb +0 -2
  342. data/lib/graphql/directive/skip_directive.rb +0 -2
  343. data/lib/graphql/directive.rb +0 -107
  344. data/lib/graphql/enum_type.rb +0 -133
  345. data/lib/graphql/execution/execute.rb +0 -333
  346. data/lib/graphql/execution/flatten.rb +0 -40
  347. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  348. data/lib/graphql/execution/typecast.rb +0 -50
  349. data/lib/graphql/field/resolve.rb +0 -59
  350. data/lib/graphql/field.rb +0 -226
  351. data/lib/graphql/filter.rb +0 -53
  352. data/lib/graphql/float_type.rb +0 -2
  353. data/lib/graphql/function.rb +0 -128
  354. data/lib/graphql/id_type.rb +0 -2
  355. data/lib/graphql/input_object_type.rb +0 -138
  356. data/lib/graphql/int_type.rb +0 -2
  357. data/lib/graphql/interface_type.rb +0 -72
  358. data/lib/graphql/internal_representation/document.rb +0 -27
  359. data/lib/graphql/internal_representation/node.rb +0 -206
  360. data/lib/graphql/internal_representation/print.rb +0 -51
  361. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  362. data/lib/graphql/internal_representation/scope.rb +0 -88
  363. data/lib/graphql/internal_representation/visit.rb +0 -36
  364. data/lib/graphql/internal_representation.rb +0 -7
  365. data/lib/graphql/language/lexer.rl +0 -260
  366. data/lib/graphql/language/parser.y +0 -550
  367. data/lib/graphql/language/token.rb +0 -34
  368. data/lib/graphql/list_type.rb +0 -80
  369. data/lib/graphql/non_null_type.rb +0 -71
  370. data/lib/graphql/object_type.rb +0 -130
  371. data/lib/graphql/query/arguments.rb +0 -189
  372. data/lib/graphql/query/arguments_cache.rb +0 -24
  373. data/lib/graphql/query/executor.rb +0 -52
  374. data/lib/graphql/query/literal_input.rb +0 -136
  375. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  376. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  377. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  378. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  379. data/lib/graphql/query/serial_execution.rb +0 -40
  380. data/lib/graphql/relay/array_connection.rb +0 -83
  381. data/lib/graphql/relay/base_connection.rb +0 -189
  382. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  383. data/lib/graphql/relay/connection_resolve.rb +0 -43
  384. data/lib/graphql/relay/connection_type.rb +0 -54
  385. data/lib/graphql/relay/edge.rb +0 -27
  386. data/lib/graphql/relay/edge_type.rb +0 -19
  387. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  388. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  389. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  390. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  391. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  392. data/lib/graphql/relay/mutation/result.rb +0 -38
  393. data/lib/graphql/relay/mutation.rb +0 -106
  394. data/lib/graphql/relay/node.rb +0 -39
  395. data/lib/graphql/relay/page_info.rb +0 -7
  396. data/lib/graphql/relay/relation_connection.rb +0 -188
  397. data/lib/graphql/relay/type_extensions.rb +0 -32
  398. data/lib/graphql/scalar_type.rb +0 -91
  399. data/lib/graphql/schema/base_64_bp.rb +0 -26
  400. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  401. data/lib/graphql/schema/default_parse_error.rb +0 -10
  402. data/lib/graphql/schema/default_type_error.rb +0 -17
  403. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  404. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  405. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  406. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  407. data/lib/graphql/schema/middleware_chain.rb +0 -82
  408. data/lib/graphql/schema/null_mask.rb +0 -11
  409. data/lib/graphql/schema/possible_types.rb +0 -44
  410. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  411. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  412. data/lib/graphql/schema/traversal.rb +0 -228
  413. data/lib/graphql/schema/validation.rb +0 -313
  414. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  415. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  416. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  417. data/lib/graphql/static_validation/type_stack.rb +0 -216
  418. data/lib/graphql/string_type.rb +0 -2
  419. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  420. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  421. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  422. data/lib/graphql/types/relay/default_relay.rb +0 -31
  423. data/lib/graphql/types/relay/node_field.rb +0 -24
  424. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  425. data/lib/graphql/union_type.rb +0 -115
  426. data/lib/graphql/upgrader/member.rb +0 -937
  427. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -2,59 +2,15 @@
2
2
 
3
3
  module GraphQL
4
4
  module Execution
5
- # A plugin that wraps query execution with error handling.
6
- # Supports class-based schemas and the new {Interpreter} runtime only.
7
- #
8
- # @example Handling ActiveRecord::NotFound
9
- #
10
- # class MySchema < GraphQL::Schema
11
- # use GraphQL::Execution::Errors
12
- #
13
- # rescue_from(ActiveRecord::NotFound) do |err, obj, args, ctx, field|
14
- # ErrorTracker.log("Not Found: #{err.message}")
15
- # nil
16
- # end
17
- # end
18
- #
19
5
  class Errors
20
- def self.use(schema)
21
- definition_line = caller(2, 1).first
22
- GraphQL::Deprecation.warn("GraphQL::Execution::Errors is now installed by default, remove `use GraphQL::Execution::Errors` from #{definition_line}")
23
- end
24
-
25
- NEW_HANDLER_HASH = ->(h, k) {
26
- h[k] = {
27
- class: k,
28
- handler: nil,
29
- subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
30
- }
31
- }
32
-
33
- def initialize(schema)
34
- @schema = schema
35
- @handlers = {
36
- class: nil,
37
- handler: nil,
38
- subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
39
- }
40
- end
41
-
42
- # @api private
43
- def each_rescue
44
- handlers = @handlers.values
45
- while (handler = handlers.shift) do
46
- yield(handler[:class], handler[:handler])
47
- handlers.concat(handler[:subclass_handlers].values)
48
- end
49
- end
50
-
51
6
  # Register this handler, updating the
52
7
  # internal handler index to maintain least-to-most specific.
53
8
  #
54
9
  # @param error_class [Class<Exception>]
10
+ # @param error_handlers [Hash]
55
11
  # @param error_handler [Proc]
56
12
  # @return [void]
57
- def rescue_from(error_class, error_handler)
13
+ def self.register_rescue_from(error_class, error_handlers, error_handler)
58
14
  subclasses_handlers = {}
59
15
  this_level_subclasses = []
60
16
  # During this traversal, do two things:
@@ -62,13 +18,12 @@ module GraphQL
62
18
  # and gather them up to be inserted _under_ this class
63
19
  # - Find the point in the index where this handler should be inserted
64
20
  # (That is, _under_ any superclasses, or at top-level, if there are no superclasses registered)
65
- handlers = @handlers[:subclass_handlers]
66
- while (handlers) do
21
+ while (error_handlers) do
67
22
  this_level_subclasses.clear
68
23
  # First, identify already-loaded handlers that belong
69
24
  # _under_ this one. (That is, they're handlers
70
25
  # for subclasses of `error_class`.)
71
- handlers.each do |err_class, handler|
26
+ error_handlers.each do |err_class, handler|
72
27
  if err_class < error_class
73
28
  subclasses_handlers[err_class] = handler
74
29
  this_level_subclasses << err_class
@@ -76,13 +31,13 @@ module GraphQL
76
31
  end
77
32
  # Any handlers that we'll be moving, delete them from this point in the index
78
33
  this_level_subclasses.each do |err_class|
79
- handlers.delete(err_class)
34
+ error_handlers.delete(err_class)
80
35
  end
81
36
 
82
37
  # See if any keys in this hash are superclasses of this new class:
83
- next_index_point = handlers.find { |err_class, handler| error_class < err_class }
38
+ next_index_point = error_handlers.find { |err_class, handler| error_class < err_class }
84
39
  if next_index_point
85
- handlers = next_index_point[1][:subclass_handlers]
40
+ error_handlers = next_index_point[1][:subclass_handlers]
86
41
  else
87
42
  # this new handler doesn't belong to any sub-handlers,
88
43
  # so insert it in the current set of `handlers`
@@ -91,40 +46,15 @@ module GraphQL
91
46
  end
92
47
  # Having found the point at which to insert this handler,
93
48
  # register it and merge any subclass handlers back in at this point.
94
- this_class_handlers = handlers[error_class]
49
+ this_class_handlers = error_handlers[error_class]
95
50
  this_class_handlers[:handler] = error_handler
96
51
  this_class_handlers[:subclass_handlers].merge!(subclasses_handlers)
97
52
  nil
98
53
  end
99
54
 
100
- # Call the given block with the schema's configured error handlers.
101
- #
102
- # If the block returns a lazy value, it's not wrapped with error handling. That area will have to be wrapped itself.
103
- #
104
- # @param ctx [GraphQL::Query::Context]
105
- # @return [Object] Either the result of the given block, or some object to replace the result, in case of error handling.
106
- def with_error_handling(ctx)
107
- yield
108
- rescue StandardError => err
109
- handler = find_handler_for(err.class)
110
- if handler
111
- runtime_info = ctx.namespace(:interpreter) || {}
112
- obj = runtime_info[:current_object]
113
- args = runtime_info[:current_arguments]
114
- args = args && args.keyword_arguments
115
- field = runtime_info[:current_field]
116
- if obj.is_a?(GraphQL::Schema::Object)
117
- obj = obj.object
118
- end
119
- handler[:handler].call(err, obj, args, ctx, field)
120
- else
121
- raise err
122
- end
123
- end
124
-
125
55
  # @return [Proc, nil] The handler for `error_class`, if one was registered on this schema or inherited
126
- def find_handler_for(error_class)
127
- handlers = @handlers[:subclass_handlers]
56
+ def self.find_handler_for(schema, error_class)
57
+ handlers = schema.error_handlers[:subclass_handlers]
128
58
  handler = nil
129
59
  while (handlers) do
130
60
  _err_class, next_handler = handlers.find { |err_class, handler| error_class <= err_class }
@@ -139,8 +69,8 @@ module GraphQL
139
69
  end
140
70
 
141
71
  # check for a handler from a parent class:
142
- if @schema.superclass.respond_to?(:error_handler) && (parent_errors = @schema.superclass.error_handler)
143
- parent_handler = parent_errors.find_handler_for(error_class)
72
+ if schema.superclass.respond_to?(:error_handlers)
73
+ parent_handler = find_handler_for(schema.superclass, error_class)
144
74
  end
145
75
 
146
76
  # If the inherited handler is more specific than the one defined here,
@@ -6,15 +6,19 @@ module GraphQL
6
6
  # A container for metadata regarding arguments present in a GraphQL query.
7
7
  # @see Interpreter::Arguments#argument_values for a hash of these objects.
8
8
  class ArgumentValue
9
- def initialize(definition:, value:, default_used:)
9
+ def initialize(definition:, value:, original_value:, default_used:)
10
10
  @definition = definition
11
11
  @value = value
12
+ @original_value = original_value
12
13
  @default_used = default_used
13
14
  end
14
15
 
15
16
  # @return [Object] The Ruby-ready value for this Argument
16
17
  attr_reader :value
17
18
 
19
+ # @return [Object] The value of this argument _before_ `prepare` is applied.
20
+ attr_reader :original_value
21
+
18
22
  # @return [GraphQL::Schema::Argument] The definition instance for this argument
19
23
  attr_reader :definition
20
24
 
@@ -80,7 +80,7 @@ module GraphQL
80
80
  )
81
81
  end
82
82
 
83
- NO_ARGS = {}.freeze
83
+ NO_ARGS = GraphQL::EmptyObjects::EMPTY_HASH
84
84
  EMPTY = self.new(argument_values: nil, keyword_arguments: NO_ARGS).freeze
85
85
  end
86
86
  end
@@ -7,57 +7,52 @@ module GraphQL
7
7
  def initialize(query)
8
8
  @query = query
9
9
  @dataloader = query.context.dataloader
10
- @storage = Hash.new do |h, ast_node|
11
- h[ast_node] = Hash.new do |h2, arg_owner|
12
- h2[arg_owner] = Hash.new do |h3, parent_object|
13
- dataload_for(ast_node, arg_owner, parent_object) do |kwarg_arguments|
14
- h3[parent_object] = @query.schema.after_lazy(kwarg_arguments) do |resolved_args|
15
- h3[parent_object] = resolved_args
16
- end
17
- end
18
-
19
- if !h3.key?(parent_object)
20
- # TODO should i bother putting anything here?
21
- h3[parent_object] = NO_ARGUMENTS
22
- else
23
- h3[parent_object]
24
- end
25
- end
10
+ @storage = Hash.new do |h, argument_owner|
11
+ h[argument_owner] = if argument_owner.arguments_statically_coercible?
12
+ shared_values_cache = {}
13
+ Hash.new do |h2, ignored_parent_object|
14
+ h2[ignored_parent_object] = shared_values_cache
15
+ end.compare_by_identity
16
+ else
17
+ Hash.new do |h2, parent_object|
18
+ h2[parent_object] = {}.compare_by_identity
19
+ end.compare_by_identity
26
20
  end
27
- end
21
+ end.compare_by_identity
28
22
  end
29
23
 
30
24
  def fetch(ast_node, argument_owner, parent_object)
31
- # If any jobs were enqueued, run them now,
32
- # since this might have been called outside of execution.
33
- # (The jobs are responsible for updating `result` in-place.)
34
- if !@storage.key?(ast_node) || !@storage[ast_node].key?(argument_owner)
35
- @dataloader.run_isolated do
36
- @storage[ast_node][argument_owner][parent_object]
25
+ # This runs eagerly if no block is given
26
+ @storage[argument_owner][parent_object][ast_node] ||= begin
27
+ args_hash = self.class.prepare_args_hash(@query, ast_node)
28
+ kwarg_arguments = argument_owner.coerce_arguments(parent_object, args_hash, @query.context)
29
+ @query.after_lazy(kwarg_arguments) do |resolved_args|
30
+ @storage[argument_owner][parent_object][ast_node] = resolved_args
37
31
  end
38
32
  end
39
- # Ack, the _hash_ is updated, but the key is eventually
40
- # overridden with an immutable arguments instance.
41
- # The first call queues up the job,
42
- # then this call fetches the result.
43
- # TODO this should be better, find a solution
44
- # that works with merging the runtime.rb code
45
- @storage[ast_node][argument_owner][parent_object]
33
+
46
34
  end
47
35
 
48
36
  # @yield [Interpreter::Arguments, Lazy<Interpreter::Arguments>] The finally-loaded arguments
49
37
  def dataload_for(ast_node, argument_owner, parent_object, &block)
50
38
  # First, normalize all AST or Ruby values to a plain Ruby hash
51
- args_hash = self.class.prepare_args_hash(@query, ast_node)
52
- argument_owner.coerce_arguments(parent_object, args_hash, @query.context, &block)
39
+ arg_storage = @storage[argument_owner][parent_object]
40
+ if (args = arg_storage[ast_node])
41
+ yield(args)
42
+ else
43
+ args_hash = self.class.prepare_args_hash(@query, ast_node)
44
+ argument_owner.coerce_arguments(parent_object, args_hash, @query.context) do |resolved_args|
45
+ arg_storage[ast_node] = resolved_args
46
+ yield(resolved_args)
47
+ end
48
+ end
53
49
  nil
54
50
  end
55
51
 
56
52
  private
57
53
 
58
- NO_ARGUMENTS = {}.freeze
59
-
60
- NO_VALUE_GIVEN = Object.new
54
+ NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
55
+ NO_VALUE_GIVEN = NOT_CONFIGURED
61
56
 
62
57
  def self.prepare_args_hash(query, ast_arg_or_hash_or_value)
63
58
  case ast_arg_or_hash_or_value
@@ -11,6 +11,29 @@ module GraphQL
11
11
  nil
12
12
  end
13
13
 
14
+ def self.resolve_each_depth(lazies_at_depth, dataloader)
15
+ smallest_depth = nil
16
+ lazies_at_depth.each_key do |depth_key|
17
+ smallest_depth ||= depth_key
18
+ if depth_key < smallest_depth
19
+ smallest_depth = depth_key
20
+ end
21
+ end
22
+
23
+ if smallest_depth
24
+ lazies = lazies_at_depth.delete(smallest_depth)
25
+ if !lazies.empty?
26
+ lazies.each do |l|
27
+ dataloader.append_job { l.value }
28
+ end
29
+ # Run lazies _and_ dataloader, see if more are enqueued
30
+ dataloader.run
31
+ resolve_each_depth(lazies_at_depth, dataloader)
32
+ end
33
+ end
34
+ nil
35
+ end
36
+
14
37
  # After getting `results` back from an interpreter evaluation,
15
38
  # continue it until you get a response-ready Ruby value.
16
39
  #
@@ -32,7 +55,7 @@ module GraphQL
32
55
  # these approaches.
33
56
  dataloader.run
34
57
  next_results = []
35
- while results.any?
58
+ while !results.empty?
36
59
  result_value = results.shift
37
60
  if result_value.is_a?(Runtime::GraphQLResultHash) || result_value.is_a?(Hash)
38
61
  results.concat(result_value.values)
@@ -58,7 +81,14 @@ module GraphQL
58
81
  end
59
82
  end
60
83
 
61
- if next_results.any?
84
+ if !next_results.empty?
85
+ # Any pending data loader jobs may populate the
86
+ # resutl arrays or result hashes accumulated in
87
+ # `next_results``. Run those **to completion**
88
+ # before continuing to resolve `next_results`.
89
+ # (Just `.append_job` doesn't work if any pending
90
+ # jobs require multiple passes.)
91
+ dataloader.run
62
92
  dataloader.append_job { resolve(next_results, dataloader) }
63
93
  end
64
94
 
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ module Execution
5
+ class Interpreter
6
+ class Runtime
7
+ module GraphQLResult
8
+ def initialize(result_name, result_type, application_value, parent_result, is_non_null_in_parent, selections, is_eager, ast_node, graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
9
+ @ast_node = ast_node
10
+ @graphql_arguments = graphql_arguments
11
+ @graphql_field = graphql_field
12
+ @graphql_parent = parent_result
13
+ @graphql_application_value = application_value
14
+ @graphql_result_type = result_type
15
+ if parent_result && parent_result.graphql_dead
16
+ @graphql_dead = true
17
+ end
18
+ @graphql_result_name = result_name
19
+ @graphql_is_non_null_in_parent = is_non_null_in_parent
20
+ # Jump through some hoops to avoid creating this duplicate storage if at all possible.
21
+ @graphql_metadata = nil
22
+ @graphql_selections = selections
23
+ @graphql_is_eager = is_eager
24
+ @base_path = nil
25
+ end
26
+
27
+ # TODO test full path in Partial
28
+ attr_writer :base_path
29
+
30
+ def path
31
+ @path ||= build_path([])
32
+ end
33
+
34
+ def build_path(path_array)
35
+ graphql_result_name && path_array.unshift(graphql_result_name)
36
+ if @graphql_parent
37
+ @graphql_parent.build_path(path_array)
38
+ elsif @base_path
39
+ @base_path + path_array
40
+ else
41
+ path_array
42
+ end
43
+ end
44
+
45
+ attr_accessor :graphql_dead
46
+ attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent,
47
+ :graphql_application_value, :graphql_result_type, :graphql_selections, :graphql_is_eager, :ast_node, :graphql_arguments, :graphql_field
48
+
49
+ # @return [Hash] Plain-Ruby result data (`@graphql_metadata` contains Result wrapper objects)
50
+ attr_accessor :graphql_result_data
51
+ end
52
+
53
+ class GraphQLResultHash
54
+ def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager, _ast_node, _graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
55
+ super
56
+ @graphql_result_data = {}
57
+ @ordered_result_keys = nil
58
+ end
59
+
60
+ attr_accessor :ordered_result_keys
61
+
62
+ include GraphQLResult
63
+
64
+ attr_accessor :graphql_merged_into
65
+
66
+ def set_leaf(key, value)
67
+ # This is a hack.
68
+ # Basically, this object is merged into the root-level result at some point.
69
+ # But the problem is, some lazies are created whose closures retain reference to _this_
70
+ # object. When those lazies are resolved, they cause an update to this object.
71
+ #
72
+ # In order to return a proper top-level result, we have to update that top-level result object.
73
+ # In order to return a proper partial result (eg, for a directive), we have to update this object, too.
74
+ # Yowza.
75
+ if (t = @graphql_merged_into)
76
+ t.set_leaf(key, value)
77
+ end
78
+
79
+ before_size = @graphql_result_data.size
80
+ @graphql_result_data[key] = value
81
+ after_size = @graphql_result_data.size
82
+ if after_size > before_size && @ordered_result_keys[before_size] != key
83
+ fix_result_order
84
+ end
85
+
86
+ # keep this up-to-date if it's been initialized
87
+ @graphql_metadata && @graphql_metadata[key] = value
88
+
89
+ value
90
+ end
91
+
92
+ def set_child_result(key, value)
93
+ if (t = @graphql_merged_into)
94
+ t.set_child_result(key, value)
95
+ end
96
+ before_size = @graphql_result_data.size
97
+ @graphql_result_data[key] = value.graphql_result_data
98
+ after_size = @graphql_result_data.size
99
+ if after_size > before_size && @ordered_result_keys[before_size] != key
100
+ fix_result_order
101
+ end
102
+
103
+ # If we encounter some part of this response that requires metadata tracking,
104
+ # then create the metadata hash if necessary. It will be kept up-to-date after this.
105
+ (@graphql_metadata ||= @graphql_result_data.dup)[key] = value
106
+ value
107
+ end
108
+
109
+ def delete(key)
110
+ @graphql_metadata && @graphql_metadata.delete(key)
111
+ @graphql_result_data.delete(key)
112
+ end
113
+
114
+ def each
115
+ (@graphql_metadata || @graphql_result_data).each { |k, v| yield(k, v) }
116
+ end
117
+
118
+ def values
119
+ (@graphql_metadata || @graphql_result_data).values
120
+ end
121
+
122
+ def key?(k)
123
+ @graphql_result_data.key?(k)
124
+ end
125
+
126
+ def [](k)
127
+ (@graphql_metadata || @graphql_result_data)[k]
128
+ end
129
+
130
+ def merge_into(into_result)
131
+ self.each do |key, value|
132
+ case value
133
+ when GraphQLResultHash
134
+ next_into = into_result[key]
135
+ if next_into
136
+ value.merge_into(next_into)
137
+ else
138
+ into_result.set_child_result(key, value)
139
+ end
140
+ when GraphQLResultArray
141
+ # There's no special handling of arrays because currently, there's no way to split the execution
142
+ # of a list over several concurrent flows.
143
+ into_result.set_child_result(key, value)
144
+ else
145
+ # We have to assume that, since this passed the `fields_will_merge` selection,
146
+ # that the old and new values are the same.
147
+ into_result.set_leaf(key, value)
148
+ end
149
+ end
150
+ @graphql_merged_into = into_result
151
+ end
152
+
153
+ def fix_result_order
154
+ @ordered_result_keys.each do |k|
155
+ if @graphql_result_data.key?(k)
156
+ @graphql_result_data[k] = @graphql_result_data.delete(k)
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ class GraphQLResultArray
163
+ include GraphQLResult
164
+
165
+ def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager, _ast_node, _graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
166
+ super
167
+ @graphql_result_data = []
168
+ end
169
+
170
+ def graphql_skip_at(index)
171
+ # Mark this index as dead. It's tricky because some indices may already be storing
172
+ # `Lazy`s. So the runtime is still holding indexes _before_ skipping,
173
+ # this object has to coordinate incoming writes to account for any already-skipped indices.
174
+ @skip_indices ||= []
175
+ @skip_indices << index
176
+ offset_by = @skip_indices.count { |skipped_idx| skipped_idx < index}
177
+ delete_at_index = index - offset_by
178
+ @graphql_metadata && @graphql_metadata.delete_at(delete_at_index)
179
+ @graphql_result_data.delete_at(delete_at_index)
180
+ end
181
+
182
+ def set_leaf(idx, value)
183
+ if @skip_indices
184
+ offset_by = @skip_indices.count { |skipped_idx| skipped_idx < idx }
185
+ idx -= offset_by
186
+ end
187
+ @graphql_result_data[idx] = value
188
+ @graphql_metadata && @graphql_metadata[idx] = value
189
+ value
190
+ end
191
+
192
+ def set_child_result(idx, value)
193
+ if @skip_indices
194
+ offset_by = @skip_indices.count { |skipped_idx| skipped_idx < idx }
195
+ idx -= offset_by
196
+ end
197
+ @graphql_result_data[idx] = value.graphql_result_data
198
+ # If we encounter some part of this response that requires metadata tracking,
199
+ # then create the metadata hash if necessary. It will be kept up-to-date after this.
200
+ (@graphql_metadata ||= @graphql_result_data.dup)[idx] = value
201
+ value
202
+ end
203
+
204
+ def values
205
+ (@graphql_metadata || @graphql_result_data)
206
+ end
207
+
208
+ def [](idx)
209
+ (@graphql_metadata || @graphql_result_data)[idx]
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end