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
@@ -11,98 +11,144 @@ require "graphql/execution/interpreter/handles_raw_value"
11
11
  module GraphQL
12
12
  module Execution
13
13
  class Interpreter
14
- def initialize
15
- end
14
+ class << self
15
+ # Used internally to signal that the query shouldn't be executed
16
+ # @api private
17
+ NO_OPERATION = GraphQL::EmptyObjects::EMPTY_HASH
16
18
 
17
- # Support `Executor` :S
18
- def execute(_operation, _root_type, query)
19
- runtime = evaluate(query)
20
- sync_lazies(query: query)
21
- runtime.response
22
- end
19
+ # @param schema [GraphQL::Schema]
20
+ # @param queries [Array<GraphQL::Query, Hash>]
21
+ # @param context [Hash]
22
+ # @param max_complexity [Integer, nil]
23
+ # @return [Array<GraphQL::Query::Result>] One result per query
24
+ def run_all(schema, query_options, context: {}, max_complexity: schema.max_complexity)
25
+ queries = query_options.map do |opts|
26
+ case opts
27
+ when Hash
28
+ schema.query_class.new(schema, nil, **opts)
29
+ when GraphQL::Query
30
+ opts
31
+ else
32
+ raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
33
+ end
34
+ end
23
35
 
24
- def self.use(schema_class)
25
- if schema_class.interpreter?
26
- definition_line = caller(2, 1).first
27
- GraphQL::Deprecation.warn("GraphQL::Execution::Interpreter is now the default; remove `use GraphQL::Execution::Interpreter` from the schema definition (#{definition_line})")
28
- else
29
- schema_class.query_execution_strategy(self)
30
- schema_class.mutation_execution_strategy(self)
31
- schema_class.subscription_execution_strategy(self)
32
- schema_class.add_subscription_extension_if_necessary
33
- end
34
- end
36
+ multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
37
+ Fiber[:__graphql_current_multiplex] = multiplex
38
+ multiplex.current_trace.execute_multiplex(multiplex: multiplex) do
39
+ schema = multiplex.schema
40
+ queries = multiplex.queries
41
+ lazies_at_depth = Hash.new { |h, k| h[k] = [] }
42
+ multiplex_analyzers = schema.multiplex_analyzers
43
+ if multiplex.max_complexity
44
+ multiplex_analyzers += [GraphQL::Analysis::MaxQueryComplexity]
45
+ end
35
46
 
36
- def self.begin_multiplex(multiplex)
37
- # Since this is basically the batching context,
38
- # share it for a whole multiplex
39
- multiplex.context[:interpreter_instance] ||= self.new
40
- end
47
+ schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
48
+ begin
49
+ # Since this is basically the batching context,
50
+ # share it for a whole multiplex
51
+ multiplex.context[:interpreter_instance] ||= multiplex.schema.query_execution_strategy(deprecation_warning: false).new
52
+ # Do as much eager evaluation of the query as possible
53
+ results = []
54
+ queries.each_with_index do |query, idx|
55
+ if query.subscription? && !query.subscription_update?
56
+ subs_namespace = query.context.namespace(:subscriptions)
57
+ subs_namespace[:events] = []
58
+ subs_namespace[:subscriptions] = {}
59
+ end
60
+ multiplex.dataloader.append_job {
61
+ operation = query.selected_operation
62
+ result = if operation.nil? || !query.valid? || !query.context.errors.empty?
63
+ NO_OPERATION
64
+ else
65
+ begin
66
+ # Although queries in a multiplex _share_ an Interpreter instance,
67
+ # they also have another item of state, which is private to that query
68
+ # in particular, assign it here:
69
+ runtime = Runtime.new(query: query, lazies_at_depth: lazies_at_depth)
70
+ query.context.namespace(:interpreter_runtime)[:runtime] = runtime
41
71
 
42
- def self.begin_query(query, multiplex)
43
- # The batching context is shared by the multiplex,
44
- # so fetch it out and use that instance.
45
- interpreter =
46
- query.context.namespace(:interpreter)[:interpreter_instance] =
47
- multiplex.context[:interpreter_instance]
48
- interpreter.evaluate(query)
49
- query
50
- end
72
+ query.current_trace.execute_query(query: query) do
73
+ runtime.run_eager
74
+ end
75
+ rescue GraphQL::ExecutionError => err
76
+ query.context.errors << err
77
+ NO_OPERATION
78
+ end
79
+ end
80
+ results[idx] = result
81
+ }
82
+ end
51
83
 
52
- def self.finish_multiplex(_results, multiplex)
53
- interpreter = multiplex.context[:interpreter_instance]
54
- interpreter.sync_lazies(multiplex: multiplex)
55
- end
84
+ multiplex.dataloader.run
56
85
 
57
- def self.finish_query(query, _multiplex)
58
- {
59
- "data" => query.context.namespace(:interpreter)[:runtime].response
60
- }
61
- end
86
+ # Then, work through lazy results in a breadth-first way
87
+ multiplex.dataloader.append_job {
88
+ query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
89
+ queries = multiplex ? multiplex.queries : [query]
90
+ final_values = queries.map do |query|
91
+ runtime = query.context.namespace(:interpreter_runtime)[:runtime]
92
+ # it might not be present if the query has an error
93
+ runtime ? runtime.final_result : nil
94
+ end
95
+ final_values.compact!
96
+ multiplex.current_trace.execute_query_lazy(multiplex: multiplex, query: query) do
97
+ Interpreter::Resolve.resolve_each_depth(lazies_at_depth, multiplex.dataloader)
98
+ end
99
+ }
100
+ multiplex.dataloader.run
62
101
 
63
- # Run the eager part of `query`
64
- # @return {Interpreter::Runtime}
65
- def evaluate(query)
66
- # Although queries in a multiplex _share_ an Interpreter instance,
67
- # they also have another item of state, which is private to that query
68
- # in particular, assign it here:
69
- runtime = Runtime.new(query: query)
70
- query.context.namespace(:interpreter)[:runtime] = runtime
102
+ # Then, find all errors and assign the result to the query object
103
+ results.each_with_index do |data_result, idx|
104
+ query = queries[idx]
105
+ if (events = query.context.namespace(:subscriptions)[:events]) && !events.empty?
106
+ schema.subscriptions.write_subscription(query, events)
107
+ end
108
+ # Assign the result so that it can be accessed in instrumentation
109
+ query.result_values = if data_result.equal?(NO_OPERATION)
110
+ if !query.valid? || !query.context.errors.empty?
111
+ # A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
112
+ { "errors" => query.static_errors.map(&:to_h) }
113
+ else
114
+ data_result
115
+ end
116
+ else
117
+ result = {}
71
118
 
72
- query.trace("execute_query", {query: query}) do
73
- runtime.run_eager
74
- end
119
+ if !query.context.errors.empty?
120
+ error_result = query.context.errors.map(&:to_h)
121
+ result["errors"] = error_result
122
+ end
75
123
 
76
- runtime
77
- end
124
+ result["data"] = query.context.namespace(:interpreter_runtime)[:runtime].final_result
78
125
 
79
- # Run the lazy part of `query` or `multiplex`.
80
- # @return [void]
81
- def sync_lazies(query: nil, multiplex: nil)
82
- tracer = query || multiplex
83
- if query.nil? && multiplex.queries.length == 1
84
- query = multiplex.queries[0]
85
- end
86
- queries = multiplex ? multiplex.queries : [query]
87
- final_values = queries.map do |query|
88
- runtime = query.context.namespace(:interpreter)[:runtime]
89
- # it might not be present if the query has an error
90
- runtime ? runtime.response : nil
91
- end
92
- final_values.compact!
93
- tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
94
- Interpreter::Resolve.resolve_all(final_values, multiplex.dataloader)
95
- end
96
- queries.each do |query|
97
- runtime = query.context.namespace(:interpreter)[:runtime]
98
- if runtime
99
- runtime.delete_interpreter_context(:current_path)
100
- runtime.delete_interpreter_context(:current_field)
101
- runtime.delete_interpreter_context(:current_object)
102
- runtime.delete_interpreter_context(:current_arguments)
126
+ result
127
+ end
128
+ if query.context.namespace?(:__query_result_extensions__)
129
+ query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
130
+ end
131
+ # Get the Query::Result, not the Hash
132
+ results[idx] = query.result
133
+ end
134
+
135
+ results
136
+ rescue Exception
137
+ # TODO rescue at a higher level so it will catch errors in analysis, too
138
+ # Assign values here so that the query's `@executed` becomes true
139
+ queries.map { |q| q.result_values ||= {} }
140
+ raise
141
+ ensure
142
+ Fiber[:__graphql_current_multiplex] = nil
143
+ queries.map { |query|
144
+ runtime = query.context.namespace(:interpreter_runtime)[:runtime]
145
+ if runtime
146
+ runtime.delete_all_interpreter_context
147
+ end
148
+ }
149
+ end
103
150
  end
104
151
  end
105
- nil
106
152
  end
107
153
 
108
154
  class ListResultFailedError < GraphQL::Error
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  require "graphql/execution/lazy/lazy_method_map"
3
- require "graphql/execution/lazy/resolve"
4
3
 
5
4
  module GraphQL
6
5
  module Execution
@@ -13,23 +12,14 @@ module GraphQL
13
12
  # - It has no error-catching functionality
14
13
  # @api private
15
14
  class Lazy
16
- # Traverse `val`, lazily resolving any values along the way
17
- # @param val [Object] A data structure containing mixed plain values and `Lazy` instances
18
- # @return void
19
- def self.resolve(val)
20
- Resolve.resolve(val)
21
- end
22
-
23
- attr_reader :path, :field
15
+ attr_reader :field
24
16
 
25
17
  # Create a {Lazy} which will get its inner value by calling the block
26
- # @param path [Array<String, Integer>]
27
18
  # @param field [GraphQL::Schema::Field]
28
19
  # @param get_value_func [Proc] a block to get the inner value (later)
29
- def initialize(path: nil, field: nil, &get_value_func)
20
+ def initialize(field: nil, &get_value_func)
30
21
  @get_value_func = get_value_func
31
22
  @resolved = false
32
- @path = path
33
23
  @field = field
34
24
  end
35
25
 
@@ -37,18 +27,18 @@ module GraphQL
37
27
  def value
38
28
  if !@resolved
39
29
  @resolved = true
40
- @value = begin
41
- v = @get_value_func.call
42
- if v.is_a?(Lazy)
43
- v = v.value
44
- end
45
- v
46
- rescue GraphQL::ExecutionError => err
47
- err
30
+ v = @get_value_func.call
31
+ if v.is_a?(Lazy)
32
+ v = v.value
48
33
  end
34
+ @value = v
49
35
  end
50
36
 
51
- if @value.is_a?(StandardError)
37
+ # `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
38
+ # (fewer clauses in a hot `case` block), but now it requires special handling here.
39
+ # I think it's still worth it for the performance win, but if the number of special
40
+ # cases grows, then maybe it's worth rethinking somehow.
41
+ if @value.is_a?(StandardError) && @value != GraphQL::Execution::SKIP
52
42
  raise @value
53
43
  else
54
44
  @value
@@ -55,8 +55,15 @@ module GraphQL
55
55
  @arguments
56
56
  else
57
57
  @arguments = if @field
58
- @query.schema.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
59
- args.is_a?(Execution::Interpreter::Arguments) ? args.keyword_arguments : args
58
+ @query.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
59
+ case args
60
+ when Execution::Interpreter::Arguments
61
+ args.keyword_arguments
62
+ when GraphQL::ExecutionError
63
+ EmptyObjects::EMPTY_HASH
64
+ else
65
+ args
66
+ end
60
67
  end
61
68
  else
62
69
  nil
@@ -76,8 +83,24 @@ module GraphQL
76
83
  # @param field_name [String, Symbol]
77
84
  # @param arguments [Hash] Arguments which must match in the selection
78
85
  # @return [Boolean]
79
- def selects?(field_name, arguments: nil)
80
- selection(field_name, arguments: arguments).selected?
86
+ def selects?(field_name, selected_type: @selected_type, arguments: nil)
87
+ selection(field_name, selected_type: selected_type, arguments: arguments).selected?
88
+ end
89
+
90
+ # True if this node has a selection with alias matching `alias_name`.
91
+ # If `alias_name` is a String, it is treated as a GraphQL-style (camelized)
92
+ # field name and used verbatim. If `alias_name` is a Symbol, it is
93
+ # treated as a Ruby-style (underscored) name and camelized before comparing.
94
+ #
95
+ # If `arguments:` is provided, each provided key/value will be matched
96
+ # against the arguments in the next selection. This method will return false
97
+ # if any of the given `arguments:` are not present and matching in the next selection.
98
+ # (But, the next selection may contain _more_ than the given arguments.)
99
+ # @param alias_name [String, Symbol]
100
+ # @param arguments [Hash] Arguments which must match in the selection
101
+ # @return [Boolean]
102
+ def selects_alias?(alias_name, arguments: nil)
103
+ alias_selection(alias_name, arguments: arguments).selected?
81
104
  end
82
105
 
83
106
  # @return [Boolean] True if this lookahead represents a field that was requested
@@ -87,27 +110,57 @@ module GraphQL
87
110
 
88
111
  # Like {#selects?}, but can be used for chaining.
89
112
  # It returns a null object (check with {#selected?})
113
+ # @param field_name [String, Symbol]
90
114
  # @return [GraphQL::Execution::Lookahead]
91
115
  def selection(field_name, selected_type: @selected_type, arguments: nil)
92
- next_field_name = normalize_name(field_name)
93
-
94
- next_field_defn = get_class_based_field(selected_type, next_field_name)
95
- if next_field_defn
96
- next_nodes = []
97
- @ast_nodes.each do |ast_node|
98
- ast_node.selections.each do |selection|
99
- find_selected_nodes(selection, next_field_name, next_field_defn, arguments: arguments, matches: next_nodes)
100
- end
116
+ next_field_defn = case field_name
117
+ when String
118
+ @query.types.field(selected_type, field_name)
119
+ when Symbol
120
+ # Try to avoid the `.to_s` below, if possible
121
+ all_fields = if selected_type.kind.fields?
122
+ @query.types.fields(selected_type)
123
+ else
124
+ # Handle unions by checking possible
125
+ @query.types
126
+ .possible_types(selected_type)
127
+ .map { |t| @query.types.fields(t) }
128
+ .tap(&:flatten!)
101
129
  end
102
130
 
103
- if next_nodes.any?
104
- Lookahead.new(query: @query, ast_nodes: next_nodes, field: next_field_defn, owner_type: selected_type)
131
+
132
+ if (match_by_orig_name = all_fields.find { |f| f.original_name == field_name })
133
+ match_by_orig_name
105
134
  else
106
- NULL_LOOKAHEAD
135
+ # Symbol#name is only present on 3.0+
136
+ sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
137
+ guessed_name = Schema::Member::BuildType.camelize(sym_s)
138
+ @query.types.field(selected_type, guessed_name)
107
139
  end
108
- else
109
- NULL_LOOKAHEAD
110
140
  end
141
+ lookahead_for_selection(next_field_defn, selected_type, arguments)
142
+ end
143
+
144
+ # Like {#selection}, but for aliases.
145
+ # It returns a null object (check with {#selected?})
146
+ # @return [GraphQL::Execution::Lookahead]
147
+ def alias_selection(alias_name, selected_type: @selected_type, arguments: nil)
148
+ alias_cache_key = [alias_name, arguments]
149
+ return alias_selections[key] if alias_selections.key?(alias_name)
150
+
151
+ alias_node = lookup_alias_node(ast_nodes, alias_name)
152
+ return NULL_LOOKAHEAD unless alias_node
153
+
154
+ next_field_defn = @query.types.field(selected_type, alias_node.name)
155
+
156
+ alias_arguments = @query.arguments_for(alias_node, next_field_defn)
157
+ if alias_arguments.is_a?(::GraphQL::Execution::Interpreter::Arguments)
158
+ alias_arguments = alias_arguments.keyword_arguments
159
+ end
160
+
161
+ return NULL_LOOKAHEAD if arguments && arguments != alias_arguments
162
+
163
+ alias_selections[alias_cache_key] = lookahead_for_selection(next_field_defn, selected_type, alias_arguments, alias_name)
111
164
  end
112
165
 
113
166
  # Like {#selection}, but for all nodes.
@@ -137,7 +190,7 @@ module GraphQL
137
190
 
138
191
  subselections_by_type.each do |type, ast_nodes_by_response_key|
139
192
  ast_nodes_by_response_key.each do |response_key, ast_nodes|
140
- field_defn = get_class_based_field(type, ast_nodes.first.name)
193
+ field_defn = @query.types.field(type, ast_nodes.first.name)
141
194
  lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
142
195
  subselections.push(lookahead)
143
196
  end
@@ -196,34 +249,10 @@ module GraphQL
196
249
 
197
250
  private
198
251
 
199
- # If it's a symbol, stringify and camelize it
200
- def normalize_name(name)
201
- if name.is_a?(Symbol)
202
- Schema::Member::BuildType.camelize(name.to_s)
203
- else
204
- name
205
- end
206
- end
207
-
208
- def normalize_keyword(keyword)
209
- if keyword.is_a?(String)
210
- Schema::Member::BuildType.underscore(keyword).to_sym
211
- else
212
- keyword
213
- end
214
- end
215
-
216
- # Wrap get_field and ensure that it returns a GraphQL::Schema::Field.
217
- # Remove this when legacy execution is removed.
218
- def get_class_based_field(type, name)
219
- f = @query.get_field(type, name)
220
- f && f.type_class
221
- end
222
-
223
252
  def skipped_by_directive?(ast_selection)
224
253
  ast_selection.directives.each do |directive|
225
254
  dir_defn = @query.schema.directives.fetch(directive.name)
226
- directive_class = dir_defn.type_class
255
+ directive_class = dir_defn
227
256
  if directive_class
228
257
  dir_args = @query.arguments_for(directive, dir_defn)
229
258
  return true unless directive_class.static_include?(dir_args, @query.context)
@@ -244,7 +273,7 @@ module GraphQL
244
273
  elsif arguments.nil? || arguments.empty?
245
274
  selections_on_type[response_key] = [ast_selection]
246
275
  else
247
- field_defn = get_class_based_field(selected_type, ast_selection.name)
276
+ field_defn = @query.types.field(selected_type, ast_selection.name)
248
277
  if arguments_match?(arguments, field_defn, ast_selection)
249
278
  selections_on_type[response_key] = [ast_selection]
250
279
  end
@@ -254,14 +283,14 @@ module GraphQL
254
283
  subselections_on_type = selections_on_type
255
284
  if (t = ast_selection.type)
256
285
  # Assuming this is valid, that `t` will be found.
257
- on_type = @query.schema.get_type(t.name).type_class
286
+ on_type = @query.types.type(t.name)
258
287
  subselections_on_type = subselections_by_type[on_type] ||= {}
259
288
  end
260
289
  find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
261
290
  when GraphQL::Language::Nodes::FragmentSpread
262
- frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
291
+ frag_defn = lookup_fragment(ast_selection)
263
292
  # Again, assuming a valid AST
264
- on_type = @query.schema.get_type(frag_defn.type.name).type_class
293
+ on_type = @query.types.type(frag_defn.type.name)
265
294
  subselections_on_type = subselections_by_type[on_type] ||= {}
266
295
  find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
267
296
  else
@@ -272,11 +301,11 @@ module GraphQL
272
301
 
273
302
  # If a selection on `node` matches `field_name` (which is backed by `field_defn`)
274
303
  # and matches the `arguments:` constraints, then add that node to `matches`
275
- def find_selected_nodes(node, field_name, field_defn, arguments:, matches:)
304
+ def find_selected_nodes(node, field_name, field_defn, arguments:, matches:, alias_name: NOT_CONFIGURED)
276
305
  return if skipped_by_directive?(node)
277
306
  case node
278
307
  when GraphQL::Language::Nodes::Field
279
- if node.name == field_name
308
+ if node.name == field_name && (NOT_CONFIGURED.equal?(alias_name) || node.alias == alias_name)
280
309
  if arguments.nil? || arguments.empty?
281
310
  # No constraint applied
282
311
  matches << node
@@ -285,10 +314,10 @@ module GraphQL
285
314
  end
286
315
  end
287
316
  when GraphQL::Language::Nodes::InlineFragment
288
- node.selections.each { |s| find_selected_nodes(s, field_name, field_defn, arguments: arguments, matches: matches) }
317
+ node.selections.each { |s| find_selected_nodes(s, field_name, field_defn, arguments: arguments, matches: matches, alias_name: alias_name) }
289
318
  when GraphQL::Language::Nodes::FragmentSpread
290
- frag_defn = @query.fragments[node.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{node.name} (found: #{@query.fragments.keys})")
291
- frag_defn.selections.each { |s| find_selected_nodes(s, field_name, field_defn, arguments: arguments, matches: matches) }
319
+ frag_defn = lookup_fragment(node)
320
+ frag_defn.selections.each { |s| find_selected_nodes(s, field_name, field_defn, arguments: arguments, matches: matches, alias_name: alias_name) }
292
321
  else
293
322
  raise "Unexpected selection comparison on #{node.class.name} (#{node})"
294
323
  end
@@ -297,11 +326,60 @@ module GraphQL
297
326
  def arguments_match?(arguments, field_defn, field_node)
298
327
  query_kwargs = @query.arguments_for(field_node, field_defn)
299
328
  arguments.all? do |arg_name, arg_value|
300
- arg_name = normalize_keyword(arg_name)
329
+ arg_name_sym = if arg_name.is_a?(String)
330
+ Schema::Member::BuildType.underscore(arg_name).to_sym
331
+ else
332
+ arg_name
333
+ end
334
+
301
335
  # Make sure the constraint is present with a matching value
302
- query_kwargs.key?(arg_name) && query_kwargs[arg_name] == arg_value
336
+ query_kwargs.key?(arg_name_sym) && query_kwargs[arg_name_sym] == arg_value
337
+ end
338
+ end
339
+
340
+ def lookahead_for_selection(field_defn, selected_type, arguments, alias_name = NOT_CONFIGURED)
341
+ return NULL_LOOKAHEAD unless field_defn
342
+
343
+ next_nodes = []
344
+ field_name = field_defn.name
345
+ @ast_nodes.each do |ast_node|
346
+ ast_node.selections.each do |selection|
347
+ find_selected_nodes(selection, field_name, field_defn, arguments: arguments, matches: next_nodes, alias_name: alias_name)
348
+ end
349
+ end
350
+
351
+ return NULL_LOOKAHEAD if next_nodes.empty?
352
+
353
+ Lookahead.new(query: @query, ast_nodes: next_nodes, field: field_defn, owner_type: selected_type)
354
+ end
355
+
356
+ def alias_selections
357
+ return @alias_selections if defined?(@alias_selections)
358
+ @alias_selections ||= {}
359
+ end
360
+
361
+ def lookup_alias_node(nodes, name)
362
+ return if nodes.empty?
363
+
364
+ nodes.flat_map(&:children)
365
+ .flat_map { |child| unwrap_fragments(child) }
366
+ .find { |child| child.is_a?(GraphQL::Language::Nodes::Field) && child.alias == name }
367
+ end
368
+
369
+ def unwrap_fragments(node)
370
+ case node
371
+ when GraphQL::Language::Nodes::InlineFragment
372
+ node.children
373
+ when GraphQL::Language::Nodes::FragmentSpread
374
+ lookup_fragment(node).children
375
+ else
376
+ [node]
303
377
  end
304
378
  end
379
+
380
+ def lookup_fragment(ast_selection)
381
+ @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
382
+ end
305
383
  end
306
384
  end
307
385
  end