graphql 1.10.2 → 2.0.21

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 (402) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +21 -10
  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 +45 -8
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/loader_generator.rb +1 -0
  12. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  14. data/lib/generators/graphql/mutation_generator.rb +6 -30
  15. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  16. data/lib/generators/graphql/object_generator.rb +28 -12
  17. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  18. data/lib/generators/graphql/relay.rb +49 -0
  19. data/lib/generators/graphql/relay_generator.rb +21 -0
  20. data/lib/generators/graphql/scalar_generator.rb +4 -2
  21. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  22. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  23. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  24. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  25. data/lib/generators/graphql/templates/base_field.erb +2 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  28. data/lib/generators/graphql/templates/base_object.erb +2 -0
  29. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  30. data/lib/generators/graphql/templates/base_union.erb +2 -0
  31. data/lib/generators/graphql/templates/enum.erb +7 -1
  32. data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
  33. data/lib/generators/graphql/templates/input.erb +9 -0
  34. data/lib/generators/graphql/templates/interface.erb +6 -2
  35. data/lib/generators/graphql/templates/loader.erb +2 -0
  36. data/lib/generators/graphql/templates/mutation.erb +3 -1
  37. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  40. data/lib/generators/graphql/templates/node_type.erb +9 -0
  41. data/lib/generators/graphql/templates/object.erb +7 -3
  42. data/lib/generators/graphql/templates/query_type.erb +3 -3
  43. data/lib/generators/graphql/templates/scalar.erb +5 -1
  44. data/lib/generators/graphql/templates/schema.erb +24 -33
  45. data/lib/generators/graphql/templates/union.erb +6 -2
  46. data/lib/generators/graphql/type_generator.rb +47 -10
  47. data/lib/generators/graphql/union_generator.rb +5 -5
  48. data/lib/graphql/analysis/ast/field_usage.rb +30 -1
  49. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  50. data/lib/graphql/analysis/ast/query_complexity.rb +125 -117
  51. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  52. data/lib/graphql/analysis/ast/visitor.rb +52 -36
  53. data/lib/graphql/analysis/ast.rb +7 -8
  54. data/lib/graphql/analysis.rb +0 -7
  55. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  56. data/lib/graphql/backtrace/table.rb +31 -18
  57. data/lib/graphql/backtrace/trace.rb +96 -0
  58. data/lib/graphql/backtrace/traced_error.rb +0 -1
  59. data/lib/graphql/backtrace/tracer.rb +39 -9
  60. data/lib/graphql/backtrace.rb +26 -18
  61. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  62. data/lib/graphql/dataloader/request.rb +19 -0
  63. data/lib/graphql/dataloader/request_all.rb +19 -0
  64. data/lib/graphql/dataloader/source.rb +164 -0
  65. data/lib/graphql/dataloader.rb +311 -0
  66. data/lib/graphql/date_encoding_error.rb +16 -0
  67. data/lib/graphql/deprecation.rb +9 -0
  68. data/lib/graphql/dig.rb +1 -1
  69. data/lib/graphql/execution/errors.rb +77 -44
  70. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  71. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  72. data/lib/graphql/execution/interpreter/arguments_cache.rb +104 -0
  73. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  74. data/lib/graphql/execution/interpreter/resolve.rb +62 -24
  75. data/lib/graphql/execution/interpreter/runtime.rb +826 -464
  76. data/lib/graphql/execution/interpreter.rb +206 -68
  77. data/lib/graphql/execution/lazy.rb +11 -21
  78. data/lib/graphql/execution/lookahead.rb +55 -136
  79. data/lib/graphql/execution/multiplex.rb +6 -162
  80. data/lib/graphql/execution.rb +11 -4
  81. data/lib/graphql/filter.rb +7 -2
  82. data/lib/graphql/integer_decoding_error.rb +17 -0
  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 +11 -5
  86. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  87. data/lib/graphql/introspection/entry_points.rb +4 -17
  88. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  89. data/lib/graphql/introspection/field_type.rb +9 -5
  90. data/lib/graphql/introspection/input_value_type.rb +15 -3
  91. data/lib/graphql/introspection/introspection_query.rb +6 -92
  92. data/lib/graphql/introspection/schema_type.rb +11 -6
  93. data/lib/graphql/introspection/type_type.rb +31 -14
  94. data/lib/graphql/introspection.rb +100 -0
  95. data/lib/graphql/invalid_null_error.rb +18 -0
  96. data/lib/graphql/language/block_string.rb +20 -5
  97. data/lib/graphql/language/cache.rb +37 -0
  98. data/lib/graphql/language/document_from_schema_definition.rb +96 -44
  99. data/lib/graphql/language/lexer.rb +216 -1462
  100. data/lib/graphql/language/nodes.rb +126 -129
  101. data/lib/graphql/language/parser.rb +997 -933
  102. data/lib/graphql/language/parser.y +148 -118
  103. data/lib/graphql/language/printer.rb +48 -23
  104. data/lib/graphql/language/sanitized_printer.rb +222 -0
  105. data/lib/graphql/language/token.rb +0 -4
  106. data/lib/graphql/language/visitor.rb +192 -84
  107. data/lib/graphql/language.rb +2 -0
  108. data/lib/graphql/name_validator.rb +2 -7
  109. data/lib/graphql/pagination/active_record_relation_connection.rb +45 -3
  110. data/lib/graphql/pagination/array_connection.rb +6 -4
  111. data/lib/graphql/pagination/connection.rb +105 -23
  112. data/lib/graphql/pagination/connections.rb +62 -35
  113. data/lib/graphql/pagination/relation_connection.rb +88 -36
  114. data/lib/graphql/parse_error.rb +0 -1
  115. data/lib/graphql/query/context.rb +203 -198
  116. data/lib/graphql/query/fingerprint.rb +26 -0
  117. data/lib/graphql/query/input_validation_result.rb +33 -7
  118. data/lib/graphql/query/null_context.rb +22 -9
  119. data/lib/graphql/query/validation_pipeline.rb +16 -38
  120. data/lib/graphql/query/variable_validation_error.rb +3 -3
  121. data/lib/graphql/query/variables.rb +36 -12
  122. data/lib/graphql/query.rb +92 -44
  123. data/lib/graphql/railtie.rb +6 -102
  124. data/lib/graphql/rake_task/validate.rb +1 -1
  125. data/lib/graphql/rake_task.rb +41 -10
  126. data/lib/graphql/relay/range_add.rb +17 -10
  127. data/lib/graphql/relay.rb +0 -15
  128. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  129. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  130. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  131. data/lib/graphql/rubocop.rb +4 -0
  132. data/lib/graphql/schema/addition.rb +245 -0
  133. data/lib/graphql/schema/argument.rb +250 -46
  134. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  135. data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
  136. data/lib/graphql/schema/build_from_definition.rb +243 -89
  137. data/lib/graphql/schema/directive/deprecated.rb +1 -1
  138. data/lib/graphql/schema/directive/feature.rb +1 -1
  139. data/lib/graphql/schema/directive/flagged.rb +57 -0
  140. data/lib/graphql/schema/directive/include.rb +1 -1
  141. data/lib/graphql/schema/directive/one_of.rb +12 -0
  142. data/lib/graphql/schema/directive/skip.rb +1 -1
  143. data/lib/graphql/schema/directive/transform.rb +14 -2
  144. data/lib/graphql/schema/directive.rb +108 -20
  145. data/lib/graphql/schema/enum.rb +105 -44
  146. data/lib/graphql/schema/enum_value.rb +15 -25
  147. data/lib/graphql/schema/field/connection_extension.rb +50 -30
  148. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  149. data/lib/graphql/schema/field.rb +476 -331
  150. data/lib/graphql/schema/field_extension.rb +86 -2
  151. data/lib/graphql/schema/find_inherited_value.rb +6 -8
  152. data/lib/graphql/schema/finder.rb +5 -5
  153. data/lib/graphql/schema/input_object.rb +133 -121
  154. data/lib/graphql/schema/interface.rb +17 -45
  155. data/lib/graphql/schema/introspection_system.rb +3 -8
  156. data/lib/graphql/schema/late_bound_type.rb +8 -2
  157. data/lib/graphql/schema/list.rb +25 -8
  158. data/lib/graphql/schema/loader.rb +139 -103
  159. data/lib/graphql/schema/member/base_dsl_methods.rb +29 -35
  160. data/lib/graphql/schema/member/build_type.rb +19 -14
  161. data/lib/graphql/schema/member/has_arguments.rb +310 -26
  162. data/lib/graphql/schema/member/has_ast_node.rb +16 -1
  163. data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
  164. data/lib/graphql/schema/member/has_directives.rb +118 -0
  165. data/lib/graphql/schema/member/has_fields.rb +164 -42
  166. data/lib/graphql/schema/member/has_interfaces.rb +129 -0
  167. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  168. data/lib/graphql/schema/member/has_validators.rb +57 -0
  169. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  170. data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
  171. data/lib/graphql/schema/member/validates_input.rb +3 -3
  172. data/lib/graphql/schema/member.rb +6 -6
  173. data/lib/graphql/schema/mutation.rb +4 -9
  174. data/lib/graphql/schema/non_null.rb +12 -7
  175. data/lib/graphql/schema/object.rb +35 -69
  176. data/lib/graphql/schema/printer.rb +16 -34
  177. data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
  178. data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
  179. data/lib/graphql/schema/resolver.rb +144 -79
  180. data/lib/graphql/schema/scalar.rb +27 -18
  181. data/lib/graphql/schema/subscription.rb +55 -26
  182. data/lib/graphql/schema/timeout.rb +45 -35
  183. data/lib/graphql/schema/type_expression.rb +1 -1
  184. data/lib/graphql/schema/type_membership.rb +21 -4
  185. data/lib/graphql/schema/union.rb +48 -13
  186. data/lib/graphql/schema/unique_within_type.rb +1 -2
  187. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  188. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  189. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  190. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  191. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  192. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  193. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  194. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  195. data/lib/graphql/schema/validator.rb +171 -0
  196. data/lib/graphql/schema/warden.rb +185 -32
  197. data/lib/graphql/schema/wrapper.rb +0 -5
  198. data/lib/graphql/schema.rb +471 -1116
  199. data/lib/graphql/static_validation/all_rules.rb +3 -0
  200. data/lib/graphql/static_validation/base_visitor.rb +13 -27
  201. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  202. data/lib/graphql/static_validation/error.rb +3 -1
  203. data/lib/graphql/static_validation/literal_validator.rb +69 -26
  204. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
  205. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  206. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
  207. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  208. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
  209. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
  210. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  211. data/lib/graphql/static_validation/rules/fields_will_merge.rb +92 -49
  212. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  213. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  214. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  215. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  216. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  217. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  218. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  219. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  220. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  221. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
  222. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  223. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
  224. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
  225. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
  226. data/lib/graphql/static_validation/validation_context.rb +13 -3
  227. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  228. data/lib/graphql/static_validation/validator.rb +32 -20
  229. data/lib/graphql/static_validation.rb +1 -2
  230. data/lib/graphql/string_encoding_error.rb +13 -3
  231. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +126 -19
  232. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  233. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  234. data/lib/graphql/subscriptions/event.rb +81 -35
  235. data/lib/graphql/subscriptions/instrumentation.rb +0 -52
  236. data/lib/graphql/subscriptions/serialize.rb +53 -6
  237. data/lib/graphql/subscriptions.rb +113 -58
  238. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  239. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
  240. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  241. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  242. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  243. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  244. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  245. data/lib/graphql/tracing/data_dog_tracing.rb +26 -2
  246. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  247. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  248. data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
  249. data/lib/graphql/tracing/notifications_trace.rb +42 -0
  250. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  251. data/lib/graphql/tracing/platform_trace.rb +109 -0
  252. data/lib/graphql/tracing/platform_tracing.rb +64 -43
  253. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  254. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
  255. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  256. data/lib/graphql/tracing/scout_trace.rb +72 -0
  257. data/lib/graphql/tracing/scout_tracing.rb +11 -0
  258. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  259. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  260. data/lib/graphql/tracing/trace.rb +75 -0
  261. data/lib/graphql/tracing.rb +23 -71
  262. data/lib/graphql/type_kinds.rb +6 -3
  263. data/lib/graphql/types/big_int.rb +5 -1
  264. data/lib/graphql/types/int.rb +10 -3
  265. data/lib/graphql/types/iso_8601_date.rb +20 -9
  266. data/lib/graphql/types/iso_8601_date_time.rb +36 -10
  267. data/lib/graphql/types/relay/base_connection.rb +18 -92
  268. data/lib/graphql/types/relay/base_edge.rb +2 -34
  269. data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
  270. data/lib/graphql/types/relay/edge_behaviors.rb +75 -0
  271. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  272. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  273. data/lib/graphql/types/relay/node.rb +2 -4
  274. data/lib/graphql/types/relay/node_behaviors.rb +25 -0
  275. data/lib/graphql/types/relay/page_info.rb +2 -14
  276. data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
  277. data/lib/graphql/types/relay.rb +10 -5
  278. data/lib/graphql/types/string.rb +8 -2
  279. data/lib/graphql/unauthorized_error.rb +2 -2
  280. data/lib/graphql/version.rb +1 -1
  281. data/lib/graphql.rb +54 -65
  282. data/readme.md +3 -6
  283. metadata +116 -236
  284. data/lib/graphql/analysis/analyze_query.rb +0 -91
  285. data/lib/graphql/analysis/field_usage.rb +0 -45
  286. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  287. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  288. data/lib/graphql/analysis/query_complexity.rb +0 -88
  289. data/lib/graphql/analysis/query_depth.rb +0 -43
  290. data/lib/graphql/analysis/reducer_state.rb +0 -48
  291. data/lib/graphql/argument.rb +0 -131
  292. data/lib/graphql/authorization.rb +0 -82
  293. data/lib/graphql/backwards_compatibility.rb +0 -60
  294. data/lib/graphql/base_type.rb +0 -230
  295. data/lib/graphql/boolean_type.rb +0 -2
  296. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  297. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  298. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  299. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  300. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  301. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  302. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  303. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  304. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  305. data/lib/graphql/compatibility.rb +0 -5
  306. data/lib/graphql/define/assign_argument.rb +0 -12
  307. data/lib/graphql/define/assign_connection.rb +0 -13
  308. data/lib/graphql/define/assign_enum_value.rb +0 -18
  309. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  310. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  311. data/lib/graphql/define/assign_object_field.rb +0 -42
  312. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  313. data/lib/graphql/define/instance_definable.rb +0 -210
  314. data/lib/graphql/define/no_definition_error.rb +0 -7
  315. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  316. data/lib/graphql/define/type_definer.rb +0 -31
  317. data/lib/graphql/define.rb +0 -31
  318. data/lib/graphql/deprecated_dsl.rb +0 -42
  319. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  320. data/lib/graphql/directive/include_directive.rb +0 -2
  321. data/lib/graphql/directive/skip_directive.rb +0 -2
  322. data/lib/graphql/directive.rb +0 -107
  323. data/lib/graphql/enum_type.rb +0 -127
  324. data/lib/graphql/execution/execute.rb +0 -326
  325. data/lib/graphql/execution/flatten.rb +0 -40
  326. data/lib/graphql/execution/instrumentation.rb +0 -92
  327. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  328. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  329. data/lib/graphql/execution/typecast.rb +0 -50
  330. data/lib/graphql/field/resolve.rb +0 -59
  331. data/lib/graphql/field.rb +0 -222
  332. data/lib/graphql/float_type.rb +0 -2
  333. data/lib/graphql/function.rb +0 -124
  334. data/lib/graphql/id_type.rb +0 -2
  335. data/lib/graphql/input_object_type.rb +0 -132
  336. data/lib/graphql/int_type.rb +0 -2
  337. data/lib/graphql/interface_type.rb +0 -65
  338. data/lib/graphql/internal_representation/document.rb +0 -27
  339. data/lib/graphql/internal_representation/node.rb +0 -206
  340. data/lib/graphql/internal_representation/print.rb +0 -51
  341. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  342. data/lib/graphql/internal_representation/scope.rb +0 -88
  343. data/lib/graphql/internal_representation/visit.rb +0 -36
  344. data/lib/graphql/internal_representation.rb +0 -7
  345. data/lib/graphql/language/lexer.rl +0 -258
  346. data/lib/graphql/list_type.rb +0 -80
  347. data/lib/graphql/literal_validation_error.rb +0 -6
  348. data/lib/graphql/non_null_type.rb +0 -71
  349. data/lib/graphql/object_type.rb +0 -121
  350. data/lib/graphql/query/arguments.rb +0 -188
  351. data/lib/graphql/query/arguments_cache.rb +0 -25
  352. data/lib/graphql/query/executor.rb +0 -53
  353. data/lib/graphql/query/literal_input.rb +0 -136
  354. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  355. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  356. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  357. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  358. data/lib/graphql/query/serial_execution.rb +0 -39
  359. data/lib/graphql/relay/array_connection.rb +0 -85
  360. data/lib/graphql/relay/base_connection.rb +0 -176
  361. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  362. data/lib/graphql/relay/connection_resolve.rb +0 -43
  363. data/lib/graphql/relay/connection_type.rb +0 -41
  364. data/lib/graphql/relay/edge.rb +0 -27
  365. data/lib/graphql/relay/edge_type.rb +0 -19
  366. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  367. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  368. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  369. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  370. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  371. data/lib/graphql/relay/mutation/result.rb +0 -38
  372. data/lib/graphql/relay/mutation.rb +0 -105
  373. data/lib/graphql/relay/node.rb +0 -36
  374. data/lib/graphql/relay/page_info.rb +0 -7
  375. data/lib/graphql/relay/relation_connection.rb +0 -190
  376. data/lib/graphql/relay/type_extensions.rb +0 -30
  377. data/lib/graphql/scalar_type.rb +0 -76
  378. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  379. data/lib/graphql/schema/default_parse_error.rb +0 -10
  380. data/lib/graphql/schema/default_type_error.rb +0 -15
  381. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  382. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  383. data/lib/graphql/schema/member/instrumentation.rb +0 -132
  384. data/lib/graphql/schema/middleware_chain.rb +0 -82
  385. data/lib/graphql/schema/possible_types.rb +0 -39
  386. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  387. data/lib/graphql/schema/timeout_middleware.rb +0 -86
  388. data/lib/graphql/schema/traversal.rb +0 -228
  389. data/lib/graphql/schema/validation.rb +0 -303
  390. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  391. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  392. data/lib/graphql/string_type.rb +0 -2
  393. data/lib/graphql/subscriptions/subscription_root.rb +0 -65
  394. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  395. data/lib/graphql/types/relay/base_field.rb +0 -22
  396. data/lib/graphql/types/relay/base_interface.rb +0 -29
  397. data/lib/graphql/types/relay/base_object.rb +0 -26
  398. data/lib/graphql/types/relay/node_field.rb +0 -43
  399. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  400. data/lib/graphql/union_type.rb +0 -113
  401. data/lib/graphql/upgrader/member.rb +0 -936
  402. data/lib/graphql/upgrader/schema.rb +0 -37
@@ -1,91 +1,229 @@
1
1
  # frozen_string_literal: true
2
+ require "fiber"
3
+ require "graphql/execution/interpreter/argument_value"
4
+ require "graphql/execution/interpreter/arguments"
5
+ require "graphql/execution/interpreter/arguments_cache"
2
6
  require "graphql/execution/interpreter/execution_errors"
3
- require "graphql/execution/interpreter/hash_response"
4
7
  require "graphql/execution/interpreter/runtime"
5
8
  require "graphql/execution/interpreter/resolve"
9
+ require "graphql/execution/interpreter/handles_raw_value"
6
10
 
7
11
  module GraphQL
8
12
  module Execution
9
13
  class Interpreter
10
- def initialize
11
- 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
12
18
 
13
- # Support `Executor` :S
14
- def execute(_operation, _root_type, query)
15
- runtime = evaluate(query)
16
- sync_lazies(query: query)
17
- runtime.final_value
18
- 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<Hash>] 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
+ GraphQL::Query.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
19
35
 
20
- def self.use(schema_class)
21
- schema_class.interpreter = true
22
- schema_class.query_execution_strategy(GraphQL::Execution::Interpreter)
23
- schema_class.mutation_execution_strategy(GraphQL::Execution::Interpreter)
24
- schema_class.subscription_execution_strategy(GraphQL::Execution::Interpreter)
25
- end
36
+ multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
37
+ multiplex.current_trace.execute_multiplex(multiplex: multiplex) do
38
+ schema = multiplex.schema
39
+ queries = multiplex.queries
40
+ query_instrumenters = schema.instrumenters[:query]
41
+ multiplex_instrumenters = schema.instrumenters[:multiplex]
42
+ lazies_at_depth = Hash.new { |h, k| h[k] = [] }
26
43
 
27
- def self.begin_multiplex(multiplex)
28
- # Since this is basically the batching context,
29
- # share it for a whole multiplex
30
- multiplex.context[:interpreter_instance] ||= self.new
31
- end
44
+ # First, run multiplex instrumentation, then query instrumentation for each query
45
+ call_hooks(multiplex_instrumenters, multiplex, :before_multiplex, :after_multiplex) do
46
+ each_query_call_hooks(query_instrumenters, queries) do
47
+ schema = multiplex.schema
48
+ multiplex_analyzers = schema.multiplex_analyzers
49
+ queries = multiplex.queries
50
+ if multiplex.max_complexity
51
+ multiplex_analyzers += [GraphQL::Analysis::AST::MaxQueryComplexity]
52
+ end
32
53
 
33
- def self.begin_query(query, multiplex)
34
- # The batching context is shared by the multiplex,
35
- # so fetch it out and use that instance.
36
- interpreter =
37
- query.context.namespace(:interpreter)[:interpreter_instance] =
38
- multiplex.context[:interpreter_instance]
39
- interpreter.evaluate(query)
40
- query
41
- end
54
+ schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
55
+ begin
56
+ # Since this is basically the batching context,
57
+ # share it for a whole multiplex
58
+ multiplex.context[:interpreter_instance] ||= multiplex.schema.query_execution_strategy.new
59
+ # Do as much eager evaluation of the query as possible
60
+ results = []
61
+ queries.each_with_index do |query, idx|
62
+ multiplex.dataloader.append_job {
63
+ operation = query.selected_operation
64
+ result = if operation.nil? || !query.valid? || query.context.errors.any?
65
+ NO_OPERATION
66
+ else
67
+ begin
68
+ # Although queries in a multiplex _share_ an Interpreter instance,
69
+ # they also have another item of state, which is private to that query
70
+ # in particular, assign it here:
71
+ runtime = Runtime.new(query: query, lazies_at_depth: lazies_at_depth)
72
+ query.context.namespace(:interpreter_runtime)[:runtime] = runtime
42
73
 
43
- def self.finish_multiplex(_results, multiplex)
44
- interpreter = multiplex.context[:interpreter_instance]
45
- interpreter.sync_lazies(multiplex: multiplex)
46
- end
74
+ query.current_trace.execute_query(query: query) do
75
+ runtime.run_eager
76
+ end
77
+ rescue GraphQL::ExecutionError => err
78
+ query.context.errors << err
79
+ NO_OPERATION
80
+ end
81
+ end
82
+ results[idx] = result
83
+ }
84
+ end
47
85
 
48
- def self.finish_query(query, _multiplex)
49
- {
50
- "data" => query.context.namespace(:interpreter)[:runtime].final_value
51
- }
52
- end
86
+ multiplex.dataloader.run
87
+
88
+ # Then, work through lazy results in a breadth-first way
89
+ multiplex.dataloader.append_job {
90
+ tracer = multiplex
91
+ query = multiplex.queries.length == 1 ? multiplex.queries[0] : nil
92
+ queries = multiplex ? multiplex.queries : [query]
93
+ final_values = queries.map do |query|
94
+ runtime = query.context.namespace(:interpreter_runtime)[:runtime]
95
+ # it might not be present if the query has an error
96
+ runtime ? runtime.final_result : nil
97
+ end
98
+ final_values.compact!
99
+ tracer.current_trace.execute_query_lazy(multiplex: multiplex, query: query) do
100
+ Interpreter::Resolve.resolve_each_depth(lazies_at_depth, multiplex.dataloader)
101
+ end
102
+ queries.each do |query|
103
+ runtime = query.context.namespace(:interpreter_runtime)[:runtime]
104
+ if runtime
105
+ runtime.delete_all_interpreter_context
106
+ end
107
+ end
108
+ }
109
+ multiplex.dataloader.run
110
+
111
+ # Then, find all errors and assign the result to the query object
112
+ results.each_with_index do |data_result, idx|
113
+ query = queries[idx]
114
+ # Assign the result so that it can be accessed in instrumentation
115
+ query.result_values = if data_result.equal?(NO_OPERATION)
116
+ if !query.valid? || query.context.errors.any?
117
+ # A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
118
+ { "errors" => query.static_errors.map(&:to_h) }
119
+ else
120
+ data_result
121
+ end
122
+ else
123
+ result = {
124
+ "data" => query.context.namespace(:interpreter_runtime)[:runtime].final_result
125
+ }
126
+
127
+ if query.context.errors.any?
128
+ error_result = query.context.errors.map(&:to_h)
129
+ result["errors"] = error_result
130
+ end
131
+
132
+ result
133
+ end
134
+ if query.context.namespace?(:__query_result_extensions__)
135
+ query.result_values["extensions"] = query.context.namespace(:__query_result_extensions__)
136
+ end
137
+ # Get the Query::Result, not the Hash
138
+ results[idx] = query.result
139
+ end
53
140
 
54
- # Run the eager part of `query`
55
- # @return {Interpreter::Runtime}
56
- def evaluate(query)
57
- # Although queries in a multiplex _share_ an Interpreter instance,
58
- # they also have another item of state, which is private to that query
59
- # in particular, assign it here:
60
- runtime = Runtime.new(
61
- query: query,
62
- response: HashResponse.new,
63
- )
64
- query.context.namespace(:interpreter)[:runtime] = runtime
65
-
66
- query.trace("execute_query", {query: query}) do
67
- runtime.run_eager
141
+ results
142
+ rescue Exception
143
+ # TODO rescue at a higher level so it will catch errors in analysis, too
144
+ # Assign values here so that the query's `@executed` becomes true
145
+ queries.map { |q| q.result_values ||= {} }
146
+ raise
147
+ ensure
148
+ queries.map { |query|
149
+ runtime = query.context.namespace(:interpreter_runtime)[:runtime]
150
+ if runtime
151
+ runtime.delete_all_interpreter_context
152
+ end
153
+ }
154
+ end
155
+ end
156
+ end
157
+ end
68
158
  end
69
159
 
70
- runtime
71
- end
160
+ private
161
+
162
+ # Call the before_ hooks of each query,
163
+ # Then yield if no errors.
164
+ # `call_hooks` takes care of appropriate cleanup.
165
+ def each_query_call_hooks(instrumenters, queries, i = 0)
166
+ if i >= queries.length
167
+ yield
168
+ else
169
+ query = queries[i]
170
+ call_hooks(instrumenters, query, :before_query, :after_query) {
171
+ each_query_call_hooks(instrumenters, queries, i + 1) {
172
+ yield
173
+ }
174
+ }
175
+ end
176
+ end
177
+
178
+ # Call each before hook, and if they all succeed, yield.
179
+ # If they don't all succeed, call after_ for each one that succeeded.
180
+ def call_hooks(instrumenters, object, before_hook_name, after_hook_name)
181
+ begin
182
+ successful = []
183
+ instrumenters.each do |instrumenter|
184
+ instrumenter.public_send(before_hook_name, object)
185
+ successful << instrumenter
186
+ end
187
+
188
+ # if any before hooks raise an exception, quit calling before hooks,
189
+ # but call the after hooks on anything that succeeded but also
190
+ # raise the exception that came from the before hook.
191
+ rescue GraphQL::ExecutionError => err
192
+ object.context.errors << err
193
+ rescue => e
194
+ raise call_after_hooks(successful, object, after_hook_name, e)
195
+ end
72
196
 
73
- # Run the lazy part of `query` or `multiplex`.
74
- # @return [void]
75
- def sync_lazies(query: nil, multiplex: nil)
76
- tracer = query || multiplex
77
- if query.nil? && multiplex.queries.length == 1
78
- query = multiplex.queries[0]
197
+ begin
198
+ yield # Call the user code
199
+ ensure
200
+ ex = call_after_hooks(successful, object, after_hook_name, nil)
201
+ raise ex if ex
202
+ end
79
203
  end
80
- queries = multiplex ? multiplex.queries : [query]
81
- final_values = queries.map do |query|
82
- runtime = query.context.namespace(:interpreter)[:runtime]
83
- # it might not be present if the query has an error
84
- runtime ? runtime.final_value : nil
204
+
205
+ def call_after_hooks(instrumenters, object, after_hook_name, ex)
206
+ instrumenters.reverse_each do |instrumenter|
207
+ begin
208
+ instrumenter.public_send(after_hook_name, object)
209
+ rescue => e
210
+ ex = e
211
+ end
212
+ end
213
+ ex
85
214
  end
86
- final_values.compact!
87
- tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
88
- Interpreter::Resolve.resolve_all(final_values)
215
+ end
216
+
217
+ class ListResultFailedError < GraphQL::Error
218
+ def initialize(value:, path:, field:)
219
+ message = "Failed to build a GraphQL list result for field `#{field.path}` at path `#{path.join(".")}`.\n".dup
220
+
221
+ message << "Expected `#{value.inspect}` (#{value.class}) to implement `.each` to satisfy the GraphQL return type `#{field.type.to_type_signature}`.\n"
222
+
223
+ if field.connection?
224
+ message << "\nThis field was treated as a Relay-style connection; add `connection: false` to the `field(...)` to disable this behavior."
225
+ end
226
+ super(message)
89
227
  end
90
228
  end
91
229
  end
@@ -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
@@ -51,7 +51,17 @@ module GraphQL
51
51
 
52
52
  # @return [Hash<Symbol, Object>]
53
53
  def arguments
54
- @arguments ||= @field && ArgumentHelpers.arguments(@query, @field, ast_nodes.first)
54
+ if defined?(@arguments)
55
+ @arguments
56
+ else
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
60
+ end
61
+ else
62
+ nil
63
+ end
64
+ end
55
65
  end
56
66
 
57
67
  # True if this node has a selection on `field_name`.
@@ -66,8 +76,8 @@ module GraphQL
66
76
  # @param field_name [String, Symbol]
67
77
  # @param arguments [Hash] Arguments which must match in the selection
68
78
  # @return [Boolean]
69
- def selects?(field_name, arguments: nil)
70
- selection(field_name, arguments: arguments).selected?
79
+ def selects?(field_name, selected_type: @selected_type, arguments: nil)
80
+ selection(field_name, selected_type: selected_type, arguments: arguments).selected?
71
81
  end
72
82
 
73
83
  # @return [Boolean] True if this lookahead represents a field that was requested
@@ -77,16 +87,39 @@ module GraphQL
77
87
 
78
88
  # Like {#selects?}, but can be used for chaining.
79
89
  # It returns a null object (check with {#selected?})
90
+ # @param field_name [String, Symbol]
80
91
  # @return [GraphQL::Execution::Lookahead]
81
92
  def selection(field_name, selected_type: @selected_type, arguments: nil)
82
- next_field_name = normalize_name(field_name)
93
+ next_field_defn = case field_name
94
+ when String
95
+ @query.get_field(selected_type, field_name)
96
+ when Symbol
97
+ # Try to avoid the `.to_s` below, if possible
98
+ all_fields = if selected_type.kind.fields?
99
+ @query.warden.fields(selected_type)
100
+ else
101
+ # Handle unions by checking possible
102
+ @query.warden
103
+ .possible_types(selected_type)
104
+ .map { |t| @query.warden.fields(t) }
105
+ .flatten
106
+ end
107
+
108
+ if (match_by_orig_name = all_fields.find { |f| f.original_name == field_name })
109
+ match_by_orig_name
110
+ else
111
+ # Symbol#name is only present on 3.0+
112
+ sym_s = field_name.respond_to?(:name) ? field_name.name : field_name.to_s
113
+ guessed_name = Schema::Member::BuildType.camelize(sym_s)
114
+ @query.get_field(selected_type, guessed_name)
115
+ end
116
+ end
83
117
 
84
- next_field_defn = FieldHelpers.get_field(@query.schema, selected_type, next_field_name)
85
118
  if next_field_defn
86
119
  next_nodes = []
87
120
  @ast_nodes.each do |ast_node|
88
121
  ast_node.selections.each do |selection|
89
- find_selected_nodes(selection, next_field_name, next_field_defn, arguments: arguments, matches: next_nodes)
122
+ find_selected_nodes(selection, next_field_defn, arguments: arguments, matches: next_nodes)
90
123
  end
91
124
  end
92
125
 
@@ -127,7 +160,7 @@ module GraphQL
127
160
 
128
161
  subselections_by_type.each do |type, ast_nodes_by_response_key|
129
162
  ast_nodes_by_response_key.each do |response_key, ast_nodes|
130
- field_defn = FieldHelpers.get_field(@query.schema, type, ast_nodes.first.name)
163
+ field_defn = @query.get_field(type, ast_nodes.first.name)
131
164
  lookahead = Lookahead.new(query: @query, ast_nodes: ast_nodes, field: field_defn, owner_type: type)
132
165
  subselections.push(lookahead)
133
166
  end
@@ -186,29 +219,12 @@ module GraphQL
186
219
 
187
220
  private
188
221
 
189
- # If it's a symbol, stringify and camelize it
190
- def normalize_name(name)
191
- if name.is_a?(Symbol)
192
- Schema::Member::BuildType.camelize(name.to_s)
193
- else
194
- name
195
- end
196
- end
197
-
198
- def normalize_keyword(keyword)
199
- if keyword.is_a?(String)
200
- Schema::Member::BuildType.underscore(keyword).to_sym
201
- else
202
- keyword
203
- end
204
- end
205
-
206
222
  def skipped_by_directive?(ast_selection)
207
223
  ast_selection.directives.each do |directive|
208
224
  dir_defn = @query.schema.directives.fetch(directive.name)
209
- directive_class = dir_defn.type_class
225
+ directive_class = dir_defn
210
226
  if directive_class
211
- dir_args = GraphQL::Execution::Lookahead::ArgumentHelpers.arguments(@query, dir_defn, directive)
227
+ dir_args = @query.arguments_for(directive, dir_defn)
212
228
  return true unless directive_class.static_include?(dir_args, @query.context)
213
229
  end
214
230
  end
@@ -227,7 +243,7 @@ module GraphQL
227
243
  elsif arguments.nil? || arguments.empty?
228
244
  selections_on_type[response_key] = [ast_selection]
229
245
  else
230
- field_defn = FieldHelpers.get_field(@query.schema, selected_type, ast_selection.name)
246
+ field_defn = @query.get_field(selected_type, ast_selection.name)
231
247
  if arguments_match?(arguments, field_defn, ast_selection)
232
248
  selections_on_type[response_key] = [ast_selection]
233
249
  end
@@ -237,14 +253,14 @@ module GraphQL
237
253
  subselections_on_type = selections_on_type
238
254
  if (t = ast_selection.type)
239
255
  # Assuming this is valid, that `t` will be found.
240
- on_type = @query.schema.get_type(t.name).type_class
256
+ on_type = @query.get_type(t.name)
241
257
  subselections_on_type = subselections_by_type[on_type] ||= {}
242
258
  end
243
259
  find_selections(subselections_by_type, subselections_on_type, on_type, ast_selection.selections, arguments)
244
260
  when GraphQL::Language::Nodes::FragmentSpread
245
261
  frag_defn = @query.fragments[ast_selection.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{ast_selection.name} (found: #{@query.fragments.keys})")
246
262
  # Again, assuming a valid AST
247
- on_type = @query.schema.get_type(frag_defn.type.name).type_class
263
+ on_type = @query.get_type(frag_defn.type.name)
248
264
  subselections_on_type = subselections_by_type[on_type] ||= {}
249
265
  find_selections(subselections_by_type, subselections_on_type, on_type, frag_defn.selections, arguments)
250
266
  else
@@ -255,11 +271,11 @@ module GraphQL
255
271
 
256
272
  # If a selection on `node` matches `field_name` (which is backed by `field_defn`)
257
273
  # and matches the `arguments:` constraints, then add that node to `matches`
258
- def find_selected_nodes(node, field_name, field_defn, arguments:, matches:)
274
+ def find_selected_nodes(node, field_defn, arguments:, matches:)
259
275
  return if skipped_by_directive?(node)
260
276
  case node
261
277
  when GraphQL::Language::Nodes::Field
262
- if node.name == field_name
278
+ if node.name == field_defn.graphql_name
263
279
  if arguments.nil? || arguments.empty?
264
280
  # No constraint applied
265
281
  matches << node
@@ -268,123 +284,26 @@ module GraphQL
268
284
  end
269
285
  end
270
286
  when GraphQL::Language::Nodes::InlineFragment
271
- node.selections.each { |s| find_selected_nodes(s, field_name, field_defn, arguments: arguments, matches: matches) }
287
+ node.selections.each { |s| find_selected_nodes(s, field_defn, arguments: arguments, matches: matches) }
272
288
  when GraphQL::Language::Nodes::FragmentSpread
273
289
  frag_defn = @query.fragments[node.name] || raise("Invariant: Can't look ahead to nonexistent fragment #{node.name} (found: #{@query.fragments.keys})")
274
- frag_defn.selections.each { |s| find_selected_nodes(s, field_name, field_defn, arguments: arguments, matches: matches) }
290
+ frag_defn.selections.each { |s| find_selected_nodes(s, field_defn, arguments: arguments, matches: matches) }
275
291
  else
276
292
  raise "Unexpected selection comparison on #{node.class.name} (#{node})"
277
293
  end
278
294
  end
279
295
 
280
296
  def arguments_match?(arguments, field_defn, field_node)
281
- query_kwargs = ArgumentHelpers.arguments(@query, field_defn, field_node)
297
+ query_kwargs = @query.arguments_for(field_node, field_defn)
282
298
  arguments.all? do |arg_name, arg_value|
283
- arg_name = normalize_keyword(arg_name)
284
- # Make sure the constraint is present with a matching value
285
- query_kwargs.key?(arg_name) && query_kwargs[arg_name] == arg_value
286
- end
287
- end
288
-
289
- # TODO Dedup with interpreter
290
- module ArgumentHelpers
291
- module_function
292
-
293
- def arguments(query, arg_owner, ast_node)
294
- kwarg_arguments = {}
295
- arg_defns = arg_owner.arguments
296
- ast_node.arguments.each do |arg|
297
- arg_defn = arg_defns[arg.name] || raise("Invariant: missing argument definition for #{arg.name.inspect} in #{arg_defns.keys} from #{arg_owner}")
298
- # Need to distinguish between client-provided `nil`
299
- # and nothing-at-all
300
- is_present, value = arg_to_value(query, arg_defn.type, arg.value)
301
- if is_present
302
- kwarg_arguments[arg_defn.keyword] = value
303
- end
304
- end
305
- arg_defns.each do |name, arg_defn|
306
- if arg_defn.default_value? && !kwarg_arguments.key?(arg_defn.keyword)
307
- kwarg_arguments[arg_defn.keyword] = arg_defn.default_value
308
- end
309
- end
310
- kwarg_arguments
311
- end
312
-
313
- # Get a Ruby-ready value from a client query.
314
- # @param graphql_object [Object] The owner of the field whose argument this is
315
- # @param arg_type [Class, GraphQL::Schema::NonNull, GraphQL::Schema::List]
316
- # @param ast_value [GraphQL::Language::Nodes::VariableIdentifier, String, Integer, Float, Boolean]
317
- # @return [Array(is_present, value)]
318
- def arg_to_value(query, arg_type, ast_value)
319
- if ast_value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
320
- # If it's not here, it will get added later
321
- if query.variables.key?(ast_value.name)
322
- return true, query.variables[ast_value.name]
323
- else
324
- return false, nil
325
- end
326
- elsif ast_value.is_a?(GraphQL::Language::Nodes::NullValue)
327
- return true, nil
328
- elsif arg_type.is_a?(GraphQL::Schema::NonNull)
329
- arg_to_value(query, arg_type.of_type, ast_value)
330
- elsif arg_type.is_a?(GraphQL::Schema::List)
331
- # Treat a single value like a list
332
- arg_value = Array(ast_value)
333
- list = []
334
- arg_value.map do |inner_v|
335
- _present, value = arg_to_value(query, arg_type.of_type, inner_v)
336
- list << value
337
- end
338
- return true, list
339
- elsif arg_type.is_a?(Class) && arg_type < GraphQL::Schema::InputObject
340
- # For these, `prepare` is applied during `#initialize`.
341
- # Pass `nil` so it will be skipped in `#arguments`.
342
- # What a mess.
343
- args = arguments(query, nil, arg_type, ast_value)
344
- # We're not tracking defaults_used, but for our purposes
345
- # we compare the value to the default value.
346
- return true, arg_type.new(ruby_kwargs: args, context: query.context, defaults_used: nil)
347
- else
348
- flat_value = flatten_ast_value(query, ast_value)
349
- return true, arg_type.coerce_input(flat_value, query.context)
350
- end
351
- end
352
-
353
- def flatten_ast_value(query, v)
354
- case v
355
- when GraphQL::Language::Nodes::Enum
356
- v.name
357
- when GraphQL::Language::Nodes::InputObject
358
- h = {}
359
- v.arguments.each do |arg|
360
- h[arg.name] = flatten_ast_value(query, arg.value)
361
- end
362
- h
363
- when Array
364
- v.map { |v2| flatten_ast_value(query, v2) }
365
- when GraphQL::Language::Nodes::VariableIdentifier
366
- flatten_ast_value(query.variables[v.name])
367
- else
368
- v
369
- end
370
- end
371
- end
372
-
373
- # TODO dedup with interpreter
374
- module FieldHelpers
375
- module_function
376
-
377
- def get_field(schema, owner_type, field_name)
378
- field_defn = owner_type.get_field(field_name)
379
- field_defn ||= if owner_type == schema.query.type_class && (entry_point_field = schema.introspection_system.entry_point(name: field_name))
380
- entry_point_field.type_class
381
- elsif (dynamic_field = schema.introspection_system.dynamic_field(name: field_name))
382
- dynamic_field.type_class
299
+ arg_name_sym = if arg_name.is_a?(String)
300
+ Schema::Member::BuildType.underscore(arg_name).to_sym
383
301
  else
384
- nil
302
+ arg_name
385
303
  end
386
304
 
387
- field_defn
305
+ # Make sure the constraint is present with a matching value
306
+ query_kwargs.key?(arg_name_sym) && query_kwargs[arg_name_sym] == arg_value
388
307
  end
389
308
  end
390
309
  end