graphql 1.12.12 → 2.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (428) 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/{templates → install/templates}/base_mutation.erb +2 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +60 -4
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  12. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_generator.rb +5 -30
  14. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  15. data/lib/generators/graphql/object_generator.rb +10 -38
  16. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  17. data/lib/generators/graphql/relay.rb +23 -12
  18. data/lib/generators/graphql/scalar_generator.rb +4 -2
  19. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  20. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  21. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  22. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  23. data/lib/generators/graphql/templates/base_field.erb +2 -0
  24. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  25. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  26. data/lib/generators/graphql/templates/base_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  28. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  29. data/lib/generators/graphql/templates/base_union.erb +2 -0
  30. data/lib/generators/graphql/templates/enum.erb +5 -1
  31. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  32. data/lib/generators/graphql/templates/input.erb +9 -0
  33. data/lib/generators/graphql/templates/interface.erb +4 -2
  34. data/lib/generators/graphql/templates/loader.erb +2 -0
  35. data/lib/generators/graphql/templates/mutation.erb +3 -1
  36. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  37. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  39. data/lib/generators/graphql/templates/node_type.erb +2 -0
  40. data/lib/generators/graphql/templates/object.erb +4 -2
  41. data/lib/generators/graphql/templates/query_type.erb +2 -0
  42. data/lib/generators/graphql/templates/scalar.erb +3 -1
  43. data/lib/generators/graphql/templates/schema.erb +22 -2
  44. data/lib/generators/graphql/templates/union.erb +4 -2
  45. data/lib/generators/graphql/type_generator.rb +46 -10
  46. data/lib/generators/graphql/union_generator.rb +5 -5
  47. data/lib/graphql/analysis/analyzer.rb +89 -0
  48. data/lib/graphql/analysis/field_usage.rb +65 -28
  49. data/lib/graphql/analysis/max_query_complexity.rb +11 -17
  50. data/lib/graphql/analysis/max_query_depth.rb +13 -19
  51. data/lib/graphql/analysis/query_complexity.rb +156 -61
  52. data/lib/graphql/analysis/query_depth.rb +38 -23
  53. data/lib/graphql/analysis/visitor.rb +283 -0
  54. data/lib/graphql/analysis.rb +90 -6
  55. data/lib/graphql/autoload.rb +38 -0
  56. data/lib/graphql/backtrace/inspect_result.rb +0 -12
  57. data/lib/graphql/backtrace/table.rb +4 -22
  58. data/lib/graphql/backtrace/trace.rb +93 -0
  59. data/lib/graphql/backtrace/tracer.rb +8 -6
  60. data/lib/graphql/backtrace.rb +3 -8
  61. data/lib/graphql/coercion_error.rb +1 -9
  62. data/lib/graphql/current.rb +52 -0
  63. data/lib/graphql/dataloader/async_dataloader.rb +89 -0
  64. data/lib/graphql/dataloader/null_dataloader.rb +4 -2
  65. data/lib/graphql/dataloader/request.rb +5 -0
  66. data/lib/graphql/dataloader/source.rb +125 -33
  67. data/lib/graphql/dataloader.rb +193 -143
  68. data/lib/graphql/date_encoding_error.rb +16 -0
  69. data/lib/graphql/dig.rb +1 -1
  70. data/lib/graphql/duration_encoding_error.rb +16 -0
  71. data/lib/graphql/execution/errors.rb +12 -81
  72. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  73. data/lib/graphql/execution/interpreter/arguments.rb +2 -2
  74. data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -36
  75. data/lib/graphql/execution/interpreter/resolve.rb +38 -4
  76. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +175 -0
  77. data/lib/graphql/execution/interpreter/runtime.rb +447 -403
  78. data/lib/graphql/execution/interpreter.rb +126 -80
  79. data/lib/graphql/execution/lazy.rb +11 -21
  80. data/lib/graphql/execution/lookahead.rb +133 -55
  81. data/lib/graphql/execution/multiplex.rb +4 -172
  82. data/lib/graphql/execution.rb +11 -4
  83. data/lib/graphql/integer_encoding_error.rb +18 -2
  84. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  85. data/lib/graphql/introspection/directive_type.rb +6 -4
  86. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  87. data/lib/graphql/introspection/entry_points.rb +11 -18
  88. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  89. data/lib/graphql/introspection/field_type.rb +4 -4
  90. data/lib/graphql/introspection/input_value_type.rb +10 -4
  91. data/lib/graphql/introspection/schema_type.rb +17 -15
  92. data/lib/graphql/introspection/type_type.rb +29 -16
  93. data/lib/graphql/introspection.rb +6 -2
  94. data/lib/graphql/invalid_null_error.rb +1 -1
  95. data/lib/graphql/language/block_string.rb +37 -25
  96. data/lib/graphql/language/cache.rb +13 -0
  97. data/lib/graphql/language/comment.rb +18 -0
  98. data/lib/graphql/language/definition_slice.rb +1 -1
  99. data/lib/graphql/language/document_from_schema_definition.rb +122 -81
  100. data/lib/graphql/language/lexer.rb +364 -1467
  101. data/lib/graphql/language/nodes.rb +197 -106
  102. data/lib/graphql/language/parser.rb +799 -1920
  103. data/lib/graphql/language/printer.rb +372 -160
  104. data/lib/graphql/language/sanitized_printer.rb +25 -27
  105. data/lib/graphql/language/static_visitor.rb +167 -0
  106. data/lib/graphql/language/visitor.rb +188 -141
  107. data/lib/graphql/language.rb +62 -1
  108. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  109. data/lib/graphql/name_validator.rb +0 -4
  110. data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
  111. data/lib/graphql/pagination/array_connection.rb +8 -6
  112. data/lib/graphql/pagination/connection.rb +61 -7
  113. data/lib/graphql/pagination/connections.rb +22 -23
  114. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  115. data/lib/graphql/pagination/relation_connection.rb +60 -28
  116. data/lib/graphql/query/context/scoped_context.rb +101 -0
  117. data/lib/graphql/query/context.rb +146 -222
  118. data/lib/graphql/query/input_validation_result.rb +10 -1
  119. data/lib/graphql/query/null_context.rb +15 -32
  120. data/lib/graphql/query/validation_pipeline.rb +15 -39
  121. data/lib/graphql/query/variable_validation_error.rb +3 -3
  122. data/lib/graphql/query/variables.rb +35 -17
  123. data/lib/graphql/query.rb +149 -82
  124. data/lib/graphql/railtie.rb +15 -109
  125. data/lib/graphql/rake_task/validate.rb +1 -1
  126. data/lib/graphql/rake_task.rb +30 -11
  127. data/lib/graphql/relay/range_add.rb +9 -16
  128. data/lib/graphql/relay.rb +0 -15
  129. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  130. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  131. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  132. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  133. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  134. data/lib/graphql/rubocop.rb +6 -0
  135. data/lib/graphql/schema/addition.rb +98 -54
  136. data/lib/graphql/schema/always_visible.rb +14 -0
  137. data/lib/graphql/schema/argument.rb +179 -82
  138. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  139. data/lib/graphql/schema/build_from_definition.rb +77 -39
  140. data/lib/graphql/schema/directive/feature.rb +1 -1
  141. data/lib/graphql/schema/directive/flagged.rb +4 -4
  142. data/lib/graphql/schema/directive/include.rb +1 -1
  143. data/lib/graphql/schema/directive/one_of.rb +24 -0
  144. data/lib/graphql/schema/directive/skip.rb +1 -1
  145. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  146. data/lib/graphql/schema/directive/transform.rb +2 -2
  147. data/lib/graphql/schema/directive.rb +36 -22
  148. data/lib/graphql/schema/enum.rb +158 -63
  149. data/lib/graphql/schema/enum_value.rb +12 -21
  150. data/lib/graphql/schema/field/connection_extension.rb +7 -17
  151. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  152. data/lib/graphql/schema/field.rb +521 -359
  153. data/lib/graphql/schema/field_extension.rb +86 -2
  154. data/lib/graphql/schema/find_inherited_value.rb +3 -7
  155. data/lib/graphql/schema/finder.rb +5 -5
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +148 -99
  158. data/lib/graphql/schema/interface.rb +41 -64
  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 +18 -7
  162. data/lib/graphql/schema/loader.rb +6 -5
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
  164. data/lib/graphql/schema/member/build_type.rb +16 -13
  165. data/lib/graphql/schema/member/has_arguments.rb +270 -86
  166. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  167. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  168. data/lib/graphql/schema/member/has_directives.rb +81 -61
  169. data/lib/graphql/schema/member/has_fields.rb +169 -31
  170. data/lib/graphql/schema/member/has_interfaces.rb +143 -0
  171. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  172. data/lib/graphql/schema/member/has_validators.rb +32 -6
  173. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  174. data/lib/graphql/schema/member/scoped.rb +19 -0
  175. data/lib/graphql/schema/member/type_system_helpers.rb +16 -0
  176. data/lib/graphql/schema/member/validates_input.rb +6 -6
  177. data/lib/graphql/schema/member.rb +1 -6
  178. data/lib/graphql/schema/mutation.rb +7 -9
  179. data/lib/graphql/schema/non_null.rb +7 -7
  180. data/lib/graphql/schema/object.rb +38 -119
  181. data/lib/graphql/schema/printer.rb +24 -25
  182. data/lib/graphql/schema/relay_classic_mutation.rb +13 -91
  183. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
  184. data/lib/graphql/schema/resolver.rb +118 -115
  185. data/lib/graphql/schema/scalar.rb +20 -21
  186. data/lib/graphql/schema/subscription.rb +95 -21
  187. data/lib/graphql/schema/timeout.rb +25 -29
  188. data/lib/graphql/schema/type_expression.rb +2 -2
  189. data/lib/graphql/schema/type_membership.rb +21 -4
  190. data/lib/graphql/schema/union.rb +16 -16
  191. data/lib/graphql/schema/unique_within_type.rb +1 -1
  192. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  193. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  194. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  195. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  196. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  197. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  198. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  199. data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
  200. data/lib/graphql/schema/validator/required_validator.rb +56 -18
  201. data/lib/graphql/schema/validator.rb +38 -28
  202. data/lib/graphql/schema/visibility/migration.rb +188 -0
  203. data/lib/graphql/schema/visibility/profile.rb +359 -0
  204. data/lib/graphql/schema/visibility/visit.rb +190 -0
  205. data/lib/graphql/schema/visibility.rb +294 -0
  206. data/lib/graphql/schema/warden.rb +423 -134
  207. data/lib/graphql/schema/wrapper.rb +0 -5
  208. data/lib/graphql/schema.rb +1015 -1057
  209. data/lib/graphql/static_validation/all_rules.rb +3 -1
  210. data/lib/graphql/static_validation/base_visitor.rb +15 -28
  211. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  212. data/lib/graphql/static_validation/error.rb +3 -1
  213. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  214. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  215. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  216. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +4 -3
  217. data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
  218. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +15 -13
  219. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  220. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +13 -5
  221. data/lib/graphql/static_validation/rules/fields_will_merge.rb +62 -35
  222. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  223. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  224. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  225. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  226. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  227. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  228. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  229. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  230. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  231. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  232. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  233. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +7 -5
  234. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  235. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  236. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +14 -8
  237. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  238. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  239. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
  240. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  241. data/lib/graphql/static_validation/validation_context.rb +32 -6
  242. data/lib/graphql/static_validation/validator.rb +11 -27
  243. data/lib/graphql/static_validation.rb +0 -3
  244. data/lib/graphql/string_encoding_error.rb +13 -3
  245. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +49 -11
  246. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  247. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
  248. data/lib/graphql/subscriptions/event.rb +87 -38
  249. data/lib/graphql/subscriptions/serialize.rb +27 -3
  250. data/lib/graphql/subscriptions.rb +63 -49
  251. data/lib/graphql/testing/helpers.rb +155 -0
  252. data/lib/graphql/testing.rb +2 -0
  253. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  254. data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
  255. data/lib/graphql/tracing/appoptics_trace.rb +253 -0
  256. data/lib/graphql/tracing/appoptics_tracing.rb +4 -2
  257. data/lib/graphql/tracing/appsignal_trace.rb +79 -0
  258. data/lib/graphql/tracing/appsignal_tracing.rb +17 -0
  259. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  260. data/lib/graphql/tracing/data_dog_trace.rb +185 -0
  261. data/lib/graphql/tracing/data_dog_tracing.rb +27 -15
  262. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
  263. data/lib/graphql/tracing/legacy_trace.rb +12 -0
  264. data/lib/graphql/tracing/new_relic_trace.rb +77 -0
  265. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  266. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  267. data/lib/graphql/tracing/notifications_tracing.rb +61 -0
  268. data/lib/graphql/tracing/null_trace.rb +9 -0
  269. data/lib/graphql/tracing/platform_trace.rb +118 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +46 -49
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
  272. data/lib/graphql/tracing/prometheus_trace.rb +94 -0
  273. data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
  274. data/lib/graphql/tracing/scout_trace.rb +74 -0
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +114 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +58 -0
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +79 -0
  280. data/lib/graphql/tracing.rb +29 -52
  281. data/lib/graphql/type_kinds.rb +7 -4
  282. data/lib/graphql/types/big_int.rb +5 -1
  283. data/lib/graphql/types/int.rb +1 -1
  284. data/lib/graphql/types/iso_8601_date.rb +17 -6
  285. data/lib/graphql/types/iso_8601_date_time.rb +12 -1
  286. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  287. data/lib/graphql/types/relay/base_connection.rb +16 -6
  288. data/lib/graphql/types/relay/connection_behaviors.rb +92 -32
  289. data/lib/graphql/types/relay/edge_behaviors.rb +46 -7
  290. data/lib/graphql/types/relay/has_node_field.rb +2 -2
  291. data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
  292. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  293. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  294. data/lib/graphql/types/relay.rb +0 -3
  295. data/lib/graphql/types/string.rb +2 -2
  296. data/lib/graphql/types.rb +18 -10
  297. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  298. data/lib/graphql/unauthorized_error.rb +1 -1
  299. data/lib/graphql/version.rb +1 -1
  300. data/lib/graphql.rb +82 -137
  301. data/readme.md +13 -6
  302. metadata +127 -186
  303. data/lib/graphql/analysis/analyze_query.rb +0 -98
  304. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  305. data/lib/graphql/analysis/ast/field_usage.rb +0 -28
  306. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
  307. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  308. data/lib/graphql/analysis/ast/query_complexity.rb +0 -234
  309. data/lib/graphql/analysis/ast/query_depth.rb +0 -56
  310. data/lib/graphql/analysis/ast/visitor.rb +0 -268
  311. data/lib/graphql/analysis/ast.rb +0 -91
  312. data/lib/graphql/analysis/reducer_state.rb +0 -48
  313. data/lib/graphql/argument.rb +0 -131
  314. data/lib/graphql/authorization.rb +0 -82
  315. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  316. data/lib/graphql/backwards_compatibility.rb +0 -61
  317. data/lib/graphql/base_type.rb +0 -230
  318. data/lib/graphql/boolean_type.rb +0 -2
  319. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  320. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  321. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  322. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  323. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  324. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  325. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  326. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  327. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  328. data/lib/graphql/compatibility.rb +0 -5
  329. data/lib/graphql/define/assign_argument.rb +0 -12
  330. data/lib/graphql/define/assign_connection.rb +0 -13
  331. data/lib/graphql/define/assign_enum_value.rb +0 -18
  332. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  333. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  334. data/lib/graphql/define/assign_object_field.rb +0 -42
  335. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  336. data/lib/graphql/define/instance_definable.rb +0 -240
  337. data/lib/graphql/define/no_definition_error.rb +0 -7
  338. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  339. data/lib/graphql/define/type_definer.rb +0 -31
  340. data/lib/graphql/define.rb +0 -31
  341. data/lib/graphql/deprecated_dsl.rb +0 -47
  342. data/lib/graphql/deprecation.rb +0 -13
  343. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  344. data/lib/graphql/directive/include_directive.rb +0 -2
  345. data/lib/graphql/directive/skip_directive.rb +0 -2
  346. data/lib/graphql/directive.rb +0 -111
  347. data/lib/graphql/enum_type.rb +0 -129
  348. data/lib/graphql/execution/execute.rb +0 -333
  349. data/lib/graphql/execution/flatten.rb +0 -40
  350. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  351. data/lib/graphql/execution/typecast.rb +0 -50
  352. data/lib/graphql/field/resolve.rb +0 -59
  353. data/lib/graphql/field.rb +0 -226
  354. data/lib/graphql/filter.rb +0 -53
  355. data/lib/graphql/float_type.rb +0 -2
  356. data/lib/graphql/function.rb +0 -128
  357. data/lib/graphql/id_type.rb +0 -2
  358. data/lib/graphql/input_object_type.rb +0 -138
  359. data/lib/graphql/int_type.rb +0 -2
  360. data/lib/graphql/interface_type.rb +0 -72
  361. data/lib/graphql/internal_representation/document.rb +0 -27
  362. data/lib/graphql/internal_representation/node.rb +0 -206
  363. data/lib/graphql/internal_representation/print.rb +0 -51
  364. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  365. data/lib/graphql/internal_representation/scope.rb +0 -88
  366. data/lib/graphql/internal_representation/visit.rb +0 -36
  367. data/lib/graphql/internal_representation.rb +0 -7
  368. data/lib/graphql/language/lexer.rl +0 -262
  369. data/lib/graphql/language/parser.y +0 -543
  370. data/lib/graphql/language/token.rb +0 -38
  371. data/lib/graphql/list_type.rb +0 -80
  372. data/lib/graphql/non_null_type.rb +0 -71
  373. data/lib/graphql/object_type.rb +0 -130
  374. data/lib/graphql/query/arguments.rb +0 -189
  375. data/lib/graphql/query/arguments_cache.rb +0 -24
  376. data/lib/graphql/query/executor.rb +0 -52
  377. data/lib/graphql/query/literal_input.rb +0 -136
  378. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  379. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  380. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  381. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  382. data/lib/graphql/query/serial_execution.rb +0 -40
  383. data/lib/graphql/relay/array_connection.rb +0 -83
  384. data/lib/graphql/relay/base_connection.rb +0 -189
  385. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  386. data/lib/graphql/relay/connection_resolve.rb +0 -43
  387. data/lib/graphql/relay/connection_type.rb +0 -41
  388. data/lib/graphql/relay/edge.rb +0 -27
  389. data/lib/graphql/relay/edge_type.rb +0 -19
  390. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  391. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  392. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  393. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  394. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  395. data/lib/graphql/relay/mutation/result.rb +0 -38
  396. data/lib/graphql/relay/mutation.rb +0 -106
  397. data/lib/graphql/relay/node.rb +0 -39
  398. data/lib/graphql/relay/page_info.rb +0 -7
  399. data/lib/graphql/relay/relation_connection.rb +0 -188
  400. data/lib/graphql/relay/type_extensions.rb +0 -32
  401. data/lib/graphql/scalar_type.rb +0 -91
  402. data/lib/graphql/schema/base_64_bp.rb +0 -26
  403. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  404. data/lib/graphql/schema/default_parse_error.rb +0 -10
  405. data/lib/graphql/schema/default_type_error.rb +0 -17
  406. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  407. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  408. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  409. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  410. data/lib/graphql/schema/middleware_chain.rb +0 -82
  411. data/lib/graphql/schema/possible_types.rb +0 -44
  412. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  413. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  414. data/lib/graphql/schema/traversal.rb +0 -228
  415. data/lib/graphql/schema/validation.rb +0 -313
  416. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  417. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  418. data/lib/graphql/static_validation/type_stack.rb +0 -216
  419. data/lib/graphql/string_type.rb +0 -2
  420. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  421. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  422. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  423. data/lib/graphql/types/relay/default_relay.rb +0 -27
  424. data/lib/graphql/types/relay/node_field.rb +0 -25
  425. data/lib/graphql/types/relay/nodes_field.rb +0 -27
  426. data/lib/graphql/union_type.rb +0 -115
  427. data/lib/graphql/upgrader/member.rb +0 -937
  428. 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,39 +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
- field = runtime_info[:current_field]
115
- if obj.is_a?(GraphQL::Schema::Object)
116
- obj = obj.object
117
- end
118
- handler[:handler].call(err, obj, args, ctx, field)
119
- else
120
- raise err
121
- end
122
- end
123
-
124
55
  # @return [Proc, nil] The handler for `error_class`, if one was registered on this schema or inherited
125
- def find_handler_for(error_class)
126
- handlers = @handlers[:subclass_handlers]
56
+ def self.find_handler_for(schema, error_class)
57
+ handlers = schema.error_handlers[:subclass_handlers]
127
58
  handler = nil
128
59
  while (handlers) do
129
60
  _err_class, next_handler = handlers.find { |err_class, handler| error_class <= err_class }
@@ -138,8 +69,8 @@ module GraphQL
138
69
  end
139
70
 
140
71
  # check for a handler from a parent class:
141
- if @schema.superclass.respond_to?(:error_handler) && (parent_errors = @schema.superclass.error_handler)
142
- 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)
143
74
  end
144
75
 
145
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
 
@@ -59,7 +59,7 @@ module GraphQL
59
59
  @empty
60
60
  end
61
61
 
62
- def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values
62
+ def_delegators :keyword_arguments, :key?, :[], :fetch, :keys, :each, :values, :size, :to_h
63
63
  def_delegators :argument_values, :each_value
64
64
 
65
65
  def inspect
@@ -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,55 +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
- @dataloader.run_isolated do
35
- @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
31
+ end
36
32
  end
37
- # Ack, the _hash_ is updated, but the key is eventually
38
- # overridden with an immutable arguments instance.
39
- # The first call queues up the job,
40
- # then this call fetches the result.
41
- # TODO this should be better, find a solution
42
- # that works with merging the runtime.rb code
43
- @storage[ast_node][argument_owner][parent_object]
33
+
44
34
  end
45
35
 
46
36
  # @yield [Interpreter::Arguments, Lazy<Interpreter::Arguments>] The finally-loaded arguments
47
37
  def dataload_for(ast_node, argument_owner, parent_object, &block)
48
38
  # First, normalize all AST or Ruby values to a plain Ruby hash
49
- args_hash = self.class.prepare_args_hash(@query, ast_node)
50
- 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
51
49
  nil
52
50
  end
53
51
 
54
52
  private
55
53
 
56
- NO_ARGUMENTS = {}.freeze
57
-
58
- NO_VALUE_GIVEN = Object.new
54
+ NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
55
+ NO_VALUE_GIVEN = NOT_CONFIGURED
59
56
 
60
57
  def self.prepare_args_hash(query, ast_arg_or_hash_or_value)
61
58
  case ast_arg_or_hash_or_value
@@ -71,11 +68,11 @@ module GraphQL
71
68
  when Array
72
69
  ast_arg_or_hash_or_value.map { |v| prepare_args_hash(query, v) }
73
70
  when GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::InputObject, GraphQL::Language::Nodes::Directive
74
- if ast_arg_or_hash_or_value.arguments.empty?
71
+ if ast_arg_or_hash_or_value.arguments.empty? # rubocop:disable Development/ContextIsPassedCop -- AST-related
75
72
  return NO_ARGUMENTS
76
73
  end
77
74
  args_hash = {}
78
- ast_arg_or_hash_or_value.arguments.each do |arg|
75
+ ast_arg_or_hash_or_value.arguments.each do |arg| # rubocop:disable Development/ContextIsPassedCop -- AST-related
79
76
  v = prepare_args_hash(query, arg.value)
80
77
  if v != NO_VALUE_GIVEN
81
78
  args_hash[arg.name] = v
@@ -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
+ dataloader.append_job {
27
+ lazies.each(&:value) # resolve these Lazy instances
28
+ }
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,9 +55,12 @@ 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
- if result_value.is_a?(Hash)
60
+ if result_value.is_a?(Runtime::GraphQLResultHash) || result_value.is_a?(Hash)
61
+ results.concat(result_value.values)
62
+ next
63
+ elsif result_value.is_a?(Runtime::GraphQLResultArray)
38
64
  results.concat(result_value.values)
39
65
  next
40
66
  elsif result_value.is_a?(Array)
@@ -46,7 +72,8 @@ module GraphQL
46
72
  # Since this field returned another lazy,
47
73
  # add it to the same queue
48
74
  results << loaded_value
49
- elsif loaded_value.is_a?(Hash) || loaded_value.is_a?(Array)
75
+ elsif loaded_value.is_a?(Runtime::GraphQLResultHash) || loaded_value.is_a?(Runtime::GraphQLResultArray) ||
76
+ loaded_value.is_a?(Hash) || loaded_value.is_a?(Array)
50
77
  # Add these values in wholesale --
51
78
  # they might be modified by later work in the dataloader.
52
79
  next_results << loaded_value
@@ -54,7 +81,14 @@ module GraphQL
54
81
  end
55
82
  end
56
83
 
57
- 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
58
92
  dataloader.append_job { resolve(next_results, dataloader) }
59
93
  end
60
94
 
@@ -0,0 +1,175 @@
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)
9
+ @graphql_parent = parent_result
10
+ @graphql_application_value = application_value
11
+ @graphql_result_type = result_type
12
+ if parent_result && parent_result.graphql_dead
13
+ @graphql_dead = true
14
+ end
15
+ @graphql_result_name = result_name
16
+ @graphql_is_non_null_in_parent = is_non_null_in_parent
17
+ # Jump through some hoops to avoid creating this duplicate storage if at all possible.
18
+ @graphql_metadata = nil
19
+ @graphql_selections = selections
20
+ @graphql_is_eager = is_eager
21
+ end
22
+
23
+ def path
24
+ @path ||= build_path([])
25
+ end
26
+
27
+ def build_path(path_array)
28
+ graphql_result_name && path_array.unshift(graphql_result_name)
29
+ @graphql_parent ? @graphql_parent.build_path(path_array) : path_array
30
+ end
31
+
32
+ attr_accessor :graphql_dead
33
+ attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent,
34
+ :graphql_application_value, :graphql_result_type, :graphql_selections, :graphql_is_eager
35
+
36
+ # @return [Hash] Plain-Ruby result data (`@graphql_metadata` contains Result wrapper objects)
37
+ attr_accessor :graphql_result_data
38
+ end
39
+
40
+ class GraphQLResultHash
41
+ def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager)
42
+ super
43
+ @graphql_result_data = {}
44
+ end
45
+
46
+ include GraphQLResult
47
+
48
+ attr_accessor :graphql_merged_into
49
+
50
+ def set_leaf(key, value)
51
+ # This is a hack.
52
+ # Basically, this object is merged into the root-level result at some point.
53
+ # But the problem is, some lazies are created whose closures retain reference to _this_
54
+ # object. When those lazies are resolved, they cause an update to this object.
55
+ #
56
+ # In order to return a proper top-level result, we have to update that top-level result object.
57
+ # In order to return a proper partial result (eg, for a directive), we have to update this object, too.
58
+ # Yowza.
59
+ if (t = @graphql_merged_into)
60
+ t.set_leaf(key, value)
61
+ end
62
+
63
+ @graphql_result_data[key] = value
64
+ # keep this up-to-date if it's been initialized
65
+ @graphql_metadata && @graphql_metadata[key] = value
66
+
67
+ value
68
+ end
69
+
70
+ def set_child_result(key, value)
71
+ if (t = @graphql_merged_into)
72
+ t.set_child_result(key, value)
73
+ end
74
+ @graphql_result_data[key] = value.graphql_result_data
75
+ # If we encounter some part of this response that requires metadata tracking,
76
+ # then create the metadata hash if necessary. It will be kept up-to-date after this.
77
+ (@graphql_metadata ||= @graphql_result_data.dup)[key] = value
78
+ value
79
+ end
80
+
81
+ def delete(key)
82
+ @graphql_metadata && @graphql_metadata.delete(key)
83
+ @graphql_result_data.delete(key)
84
+ end
85
+
86
+ def each
87
+ (@graphql_metadata || @graphql_result_data).each { |k, v| yield(k, v) }
88
+ end
89
+
90
+ def values
91
+ (@graphql_metadata || @graphql_result_data).values
92
+ end
93
+
94
+ def key?(k)
95
+ @graphql_result_data.key?(k)
96
+ end
97
+
98
+ def [](k)
99
+ (@graphql_metadata || @graphql_result_data)[k]
100
+ end
101
+
102
+ def merge_into(into_result)
103
+ self.each do |key, value|
104
+ case value
105
+ when GraphQLResultHash
106
+ next_into = into_result[key]
107
+ if next_into
108
+ value.merge_into(next_into)
109
+ else
110
+ into_result.set_child_result(key, value)
111
+ end
112
+ when GraphQLResultArray
113
+ # There's no special handling of arrays because currently, there's no way to split the execution
114
+ # of a list over several concurrent flows.
115
+ into_result.set_child_result(key, value)
116
+ else
117
+ # We have to assume that, since this passed the `fields_will_merge` selection,
118
+ # that the old and new values are the same.
119
+ into_result.set_leaf(key, value)
120
+ end
121
+ end
122
+ @graphql_merged_into = into_result
123
+ end
124
+ end
125
+
126
+ class GraphQLResultArray
127
+ include GraphQLResult
128
+
129
+ def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager)
130
+ super
131
+ @graphql_result_data = []
132
+ end
133
+
134
+ def graphql_skip_at(index)
135
+ # Mark this index as dead. It's tricky because some indices may already be storing
136
+ # `Lazy`s. So the runtime is still holding indexes _before_ skipping,
137
+ # this object has to coordinate incoming writes to account for any already-skipped indices.
138
+ @skip_indices ||= []
139
+ @skip_indices << index
140
+ offset_by = @skip_indices.count { |skipped_idx| skipped_idx < index}
141
+ delete_at_index = index - offset_by
142
+ @graphql_metadata && @graphql_metadata.delete_at(delete_at_index)
143
+ @graphql_result_data.delete_at(delete_at_index)
144
+ end
145
+
146
+ def set_leaf(idx, value)
147
+ if @skip_indices
148
+ offset_by = @skip_indices.count { |skipped_idx| skipped_idx < idx }
149
+ idx -= offset_by
150
+ end
151
+ @graphql_result_data[idx] = value
152
+ @graphql_metadata && @graphql_metadata[idx] = value
153
+ value
154
+ end
155
+
156
+ def set_child_result(idx, value)
157
+ if @skip_indices
158
+ offset_by = @skip_indices.count { |skipped_idx| skipped_idx < idx }
159
+ idx -= offset_by
160
+ end
161
+ @graphql_result_data[idx] = value.graphql_result_data
162
+ # If we encounter some part of this response that requires metadata tracking,
163
+ # then create the metadata hash if necessary. It will be kept up-to-date after this.
164
+ (@graphql_metadata ||= @graphql_result_data.dup)[idx] = value
165
+ value
166
+ end
167
+
168
+ def values
169
+ (@graphql_metadata || @graphql_result_data)
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end