graphql 1.9.5 → 1.13.19

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 (659) hide show
  1. checksums.yaml +5 -5
  2. data/lib/generators/graphql/core.rb +21 -9
  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/install/templates/base_mutation.erb +10 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +48 -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 +63 -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 +6 -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 +7 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +3 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +4 -0
  28. data/lib/generators/graphql/templates/base_object.erb +3 -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 +21 -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 +23 -28
  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/analyze_query.rb +7 -0
  49. data/lib/graphql/analysis/ast/analyzer.rb +34 -12
  50. data/lib/graphql/analysis/ast/field_usage.rb +29 -2
  51. data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
  52. data/lib/graphql/analysis/ast/max_query_depth.rb +7 -3
  53. data/lib/graphql/analysis/ast/query_complexity.rb +179 -64
  54. data/lib/graphql/analysis/ast/query_depth.rb +16 -26
  55. data/lib/graphql/analysis/ast/visitor.rb +46 -32
  56. data/lib/graphql/analysis/ast.rb +23 -14
  57. data/lib/graphql/analysis/query_depth.rb +4 -17
  58. data/lib/graphql/argument.rb +16 -38
  59. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  60. data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
  61. data/lib/graphql/backtrace/table.rb +44 -5
  62. data/lib/graphql/backtrace/traced_error.rb +0 -1
  63. data/lib/graphql/backtrace/tracer.rb +40 -9
  64. data/lib/graphql/backtrace.rb +28 -19
  65. data/lib/graphql/backwards_compatibility.rb +2 -1
  66. data/lib/graphql/base_type.rb +11 -5
  67. data/lib/graphql/boolean_type.rb +1 -1
  68. data/lib/graphql/coercion_error.rb +8 -0
  69. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
  70. data/lib/graphql/compatibility/execution_specification.rb +1 -0
  71. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +1 -1
  72. data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
  73. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  74. data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
  75. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
  76. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  77. data/lib/graphql/dataloader/request.rb +19 -0
  78. data/lib/graphql/dataloader/request_all.rb +19 -0
  79. data/lib/graphql/dataloader/source.rb +155 -0
  80. data/lib/graphql/dataloader.rb +308 -0
  81. data/lib/graphql/date_encoding_error.rb +16 -0
  82. data/lib/graphql/define/assign_enum_value.rb +1 -1
  83. data/lib/graphql/define/assign_global_id_field.rb +2 -2
  84. data/lib/graphql/define/assign_object_field.rb +3 -3
  85. data/lib/graphql/define/defined_object_proxy.rb +3 -0
  86. data/lib/graphql/define/instance_definable.rb +65 -110
  87. data/lib/graphql/define/type_definer.rb +5 -5
  88. data/lib/graphql/deprecated_dsl.rb +18 -5
  89. data/lib/graphql/deprecation.rb +9 -0
  90. data/lib/graphql/directive/deprecated_directive.rb +1 -12
  91. data/lib/graphql/directive/include_directive.rb +1 -1
  92. data/lib/graphql/directive/skip_directive.rb +1 -1
  93. data/lib/graphql/directive.rb +9 -6
  94. data/lib/graphql/enum_type.rb +14 -74
  95. data/lib/graphql/execution/directive_checks.rb +2 -2
  96. data/lib/graphql/execution/errors.rb +163 -0
  97. data/lib/graphql/execution/execute.rb +10 -3
  98. data/lib/graphql/execution/instrumentation.rb +1 -1
  99. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  100. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  101. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  102. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  103. data/lib/graphql/execution/interpreter/resolve.rb +37 -25
  104. data/lib/graphql/execution/interpreter/runtime.rb +737 -376
  105. data/lib/graphql/execution/interpreter.rb +42 -19
  106. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  107. data/lib/graphql/execution/lazy.rb +5 -1
  108. data/lib/graphql/execution/lookahead.rb +39 -114
  109. data/lib/graphql/execution/multiplex.rb +58 -29
  110. data/lib/graphql/execution.rb +1 -0
  111. data/lib/graphql/execution_error.rb +3 -2
  112. data/lib/graphql/field.rb +15 -119
  113. data/lib/graphql/filter.rb +1 -1
  114. data/lib/graphql/float_type.rb +1 -1
  115. data/lib/graphql/function.rb +6 -31
  116. data/lib/graphql/id_type.rb +1 -1
  117. data/lib/graphql/input_object_type.rb +11 -26
  118. data/lib/graphql/int_type.rb +1 -1
  119. data/lib/graphql/integer_decoding_error.rb +17 -0
  120. data/lib/graphql/integer_encoding_error.rb +18 -2
  121. data/lib/graphql/interface_type.rb +10 -24
  122. data/lib/graphql/internal_representation/document.rb +2 -2
  123. data/lib/graphql/internal_representation/rewrite.rb +1 -1
  124. data/lib/graphql/internal_representation/scope.rb +2 -2
  125. data/lib/graphql/internal_representation/visit.rb +2 -2
  126. data/lib/graphql/introspection/base_object.rb +2 -5
  127. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  128. data/lib/graphql/introspection/directive_type.rb +12 -6
  129. data/lib/graphql/introspection/entry_points.rb +9 -8
  130. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  131. data/lib/graphql/introspection/field_type.rb +9 -5
  132. data/lib/graphql/introspection/input_value_type.rb +41 -11
  133. data/lib/graphql/introspection/introspection_query.rb +6 -92
  134. data/lib/graphql/introspection/schema_type.rb +13 -12
  135. data/lib/graphql/introspection/type_type.rb +27 -17
  136. data/lib/graphql/introspection.rb +99 -0
  137. data/lib/graphql/invalid_null_error.rb +18 -0
  138. data/lib/graphql/language/block_string.rb +22 -7
  139. data/lib/graphql/language/cache.rb +37 -0
  140. data/lib/graphql/language/definition_slice.rb +21 -10
  141. data/lib/graphql/language/document_from_schema_definition.rb +126 -67
  142. data/lib/graphql/language/lexer.rb +180 -141
  143. data/lib/graphql/language/lexer.rl +75 -51
  144. data/lib/graphql/language/nodes.rb +92 -108
  145. data/lib/graphql/language/parser.rb +933 -897
  146. data/lib/graphql/language/parser.y +129 -103
  147. data/lib/graphql/language/printer.rb +11 -2
  148. data/lib/graphql/language/sanitized_printer.rb +222 -0
  149. data/lib/graphql/language/token.rb +1 -1
  150. data/lib/graphql/language/visitor.rb +11 -8
  151. data/lib/graphql/language.rb +3 -1
  152. data/lib/graphql/name_validator.rb +2 -7
  153. data/lib/graphql/non_null_type.rb +0 -10
  154. data/lib/graphql/object_type.rb +47 -58
  155. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  156. data/lib/graphql/pagination/array_connection.rb +77 -0
  157. data/lib/graphql/pagination/connection.rb +226 -0
  158. data/lib/graphql/pagination/connections.rb +160 -0
  159. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  160. data/lib/graphql/pagination/relation_connection.rb +226 -0
  161. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  162. data/lib/graphql/pagination.rb +6 -0
  163. data/lib/graphql/parse_error.rb +0 -1
  164. data/lib/graphql/query/arguments.rb +29 -19
  165. data/lib/graphql/query/arguments_cache.rb +1 -2
  166. data/lib/graphql/query/context.rb +81 -14
  167. data/lib/graphql/query/executor.rb +0 -1
  168. data/lib/graphql/query/fingerprint.rb +26 -0
  169. data/lib/graphql/query/input_validation_result.rb +32 -6
  170. data/lib/graphql/query/literal_input.rb +31 -10
  171. data/lib/graphql/query/null_context.rb +28 -8
  172. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  173. data/lib/graphql/query/serial_execution.rb +1 -0
  174. data/lib/graphql/query/validation_pipeline.rb +6 -4
  175. data/lib/graphql/query/variable_validation_error.rb +3 -3
  176. data/lib/graphql/query/variables.rb +51 -9
  177. data/lib/graphql/query.rb +97 -23
  178. data/lib/graphql/railtie.rb +9 -1
  179. data/lib/graphql/rake_task/validate.rb +3 -0
  180. data/lib/graphql/rake_task.rb +12 -9
  181. data/lib/graphql/relay/array_connection.rb +11 -13
  182. data/lib/graphql/relay/base_connection.rb +33 -16
  183. data/lib/graphql/relay/connection_instrumentation.rb +4 -4
  184. data/lib/graphql/relay/connection_type.rb +18 -4
  185. data/lib/graphql/relay/edge_type.rb +1 -0
  186. data/lib/graphql/relay/edges_instrumentation.rb +1 -2
  187. data/lib/graphql/relay/global_id_resolve.rb +1 -2
  188. data/lib/graphql/relay/mutation.rb +3 -87
  189. data/lib/graphql/relay/node.rb +5 -2
  190. data/lib/graphql/relay/page_info.rb +1 -1
  191. data/lib/graphql/relay/range_add.rb +27 -9
  192. data/lib/graphql/relay/relation_connection.rb +17 -15
  193. data/lib/graphql/relay/type_extensions.rb +2 -0
  194. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  195. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  196. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  197. data/lib/graphql/rubocop.rb +4 -0
  198. data/lib/graphql/scalar_type.rb +18 -62
  199. data/lib/graphql/schema/addition.rb +247 -0
  200. data/lib/graphql/schema/argument.rb +289 -11
  201. data/lib/graphql/schema/base_64_bp.rb +3 -2
  202. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  203. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  204. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  205. data/lib/graphql/schema/build_from_definition.rb +323 -203
  206. data/lib/graphql/schema/built_in_types.rb +5 -5
  207. data/lib/graphql/schema/default_type_error.rb +2 -0
  208. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  209. data/lib/graphql/schema/directive/feature.rb +2 -2
  210. data/lib/graphql/schema/directive/flagged.rb +57 -0
  211. data/lib/graphql/schema/directive/include.rb +2 -2
  212. data/lib/graphql/schema/directive/skip.rb +2 -2
  213. data/lib/graphql/schema/directive/transform.rb +14 -2
  214. data/lib/graphql/schema/directive.rb +136 -6
  215. data/lib/graphql/schema/enum.rb +121 -12
  216. data/lib/graphql/schema/enum_value.rb +23 -6
  217. data/lib/graphql/schema/field/connection_extension.rb +46 -20
  218. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  219. data/lib/graphql/schema/field.rb +515 -191
  220. data/lib/graphql/schema/field_extension.rb +89 -2
  221. data/lib/graphql/schema/find_inherited_value.rb +36 -0
  222. data/lib/graphql/schema/finder.rb +16 -14
  223. data/lib/graphql/schema/input_object.rb +178 -34
  224. data/lib/graphql/schema/interface.rb +35 -25
  225. data/lib/graphql/schema/introspection_system.rb +111 -35
  226. data/lib/graphql/schema/late_bound_type.rb +3 -2
  227. data/lib/graphql/schema/list.rb +65 -1
  228. data/lib/graphql/schema/loader.rb +147 -97
  229. data/lib/graphql/schema/member/accepts_definition.rb +15 -3
  230. data/lib/graphql/schema/member/base_dsl_methods.rb +40 -45
  231. data/lib/graphql/schema/member/build_type.rb +19 -8
  232. data/lib/graphql/schema/member/cached_graphql_definition.rb +34 -2
  233. data/lib/graphql/schema/member/has_arguments.rb +212 -22
  234. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  235. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  236. data/lib/graphql/schema/member/has_directives.rb +98 -0
  237. data/lib/graphql/schema/member/has_fields.rb +113 -28
  238. data/lib/graphql/schema/member/has_interfaces.rb +100 -0
  239. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  240. data/lib/graphql/schema/member/has_validators.rb +31 -0
  241. data/lib/graphql/schema/member/instrumentation.rb +6 -2
  242. data/lib/graphql/schema/member/relay_shortcuts.rb +2 -2
  243. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  244. data/lib/graphql/schema/member/validates_input.rb +33 -0
  245. data/lib/graphql/schema/member.rb +11 -0
  246. data/lib/graphql/schema/middleware_chain.rb +1 -1
  247. data/lib/graphql/schema/mutation.rb +5 -1
  248. data/lib/graphql/schema/non_null.rb +37 -1
  249. data/lib/graphql/schema/object.rb +52 -37
  250. data/lib/graphql/schema/possible_types.rb +12 -7
  251. data/lib/graphql/schema/printer.rb +17 -34
  252. data/lib/graphql/schema/relay_classic_mutation.rb +51 -7
  253. data/lib/graphql/schema/resolver/has_payload_type.rb +36 -5
  254. data/lib/graphql/schema/resolver.rb +159 -59
  255. data/lib/graphql/schema/scalar.rb +43 -3
  256. data/lib/graphql/schema/subscription.rb +83 -25
  257. data/lib/graphql/schema/timeout.rb +123 -0
  258. data/lib/graphql/schema/timeout_middleware.rb +6 -3
  259. data/lib/graphql/schema/traversal.rb +2 -2
  260. data/lib/graphql/schema/type_expression.rb +21 -13
  261. data/lib/graphql/schema/type_membership.rb +48 -0
  262. data/lib/graphql/schema/union.rb +67 -6
  263. data/lib/graphql/schema/unique_within_type.rb +1 -2
  264. data/lib/graphql/schema/validation.rb +30 -8
  265. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  266. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  267. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  268. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  269. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  270. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  271. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  272. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  273. data/lib/graphql/schema/validator.rb +171 -0
  274. data/lib/graphql/schema/warden.rb +263 -30
  275. data/lib/graphql/schema/wrapper.rb +1 -1
  276. data/lib/graphql/schema.rb +1016 -256
  277. data/lib/graphql/static_validation/all_rules.rb +2 -0
  278. data/lib/graphql/static_validation/base_visitor.rb +17 -10
  279. data/lib/graphql/static_validation/definition_dependencies.rb +21 -13
  280. data/lib/graphql/static_validation/error.rb +3 -1
  281. data/lib/graphql/static_validation/literal_validator.rb +52 -27
  282. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +46 -79
  283. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +23 -6
  284. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  285. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  286. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  287. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -2
  288. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  289. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  290. data/lib/graphql/static_validation/rules/fields_will_merge.rb +105 -55
  291. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  292. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  293. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  294. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  295. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  296. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  297. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  298. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -3
  299. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  300. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  301. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  302. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  303. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  304. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  305. data/lib/graphql/static_validation/type_stack.rb +2 -2
  306. data/lib/graphql/static_validation/validation_context.rb +13 -3
  307. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  308. data/lib/graphql/static_validation/validator.rb +43 -9
  309. data/lib/graphql/static_validation.rb +1 -0
  310. data/lib/graphql/string_encoding_error.rb +13 -3
  311. data/lib/graphql/string_type.rb +1 -1
  312. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
  313. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  314. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
  315. data/lib/graphql/subscriptions/event.rb +94 -26
  316. data/lib/graphql/subscriptions/instrumentation.rb +10 -6
  317. data/lib/graphql/subscriptions/serialize.rb +53 -6
  318. data/lib/graphql/subscriptions/subscription_root.rb +15 -5
  319. data/lib/graphql/subscriptions.rb +122 -54
  320. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  321. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  322. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  323. data/lib/graphql/tracing/data_dog_tracing.rb +32 -2
  324. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  325. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  326. data/lib/graphql/tracing/platform_tracing.rb +66 -7
  327. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  328. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  329. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  330. data/lib/graphql/tracing/skylight_tracing.rb +9 -0
  331. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  332. data/lib/graphql/tracing.rb +15 -35
  333. data/lib/graphql/types/big_int.rb +5 -1
  334. data/lib/graphql/types/int.rb +10 -3
  335. data/lib/graphql/types/iso_8601_date.rb +42 -0
  336. data/lib/graphql/types/iso_8601_date_time.rb +32 -8
  337. data/lib/graphql/types/relay/base_connection.rb +6 -88
  338. data/lib/graphql/types/relay/base_edge.rb +2 -37
  339. data/lib/graphql/types/relay/connection_behaviors.rb +174 -0
  340. data/lib/graphql/types/relay/default_relay.rb +31 -0
  341. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  342. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  343. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  344. data/lib/graphql/types/relay/node.rb +2 -4
  345. data/lib/graphql/types/relay/node_behaviors.rb +15 -0
  346. data/lib/graphql/types/relay/node_field.rb +4 -23
  347. data/lib/graphql/types/relay/nodes_field.rb +16 -18
  348. data/lib/graphql/types/relay/page_info.rb +2 -14
  349. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  350. data/lib/graphql/types/relay.rb +11 -3
  351. data/lib/graphql/types/string.rb +8 -2
  352. data/lib/graphql/types.rb +1 -0
  353. data/lib/graphql/unauthorized_error.rb +2 -2
  354. data/lib/graphql/union_type.rb +61 -46
  355. data/lib/graphql/unresolved_type_error.rb +2 -2
  356. data/lib/graphql/upgrader/member.rb +150 -112
  357. data/lib/graphql/upgrader/schema.rb +1 -0
  358. data/lib/graphql/version.rb +1 -1
  359. data/lib/graphql.rb +89 -18
  360. data/readme.md +4 -7
  361. metadata +115 -703
  362. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  363. data/lib/graphql/literal_validation_error.rb +0 -6
  364. data/lib/graphql/types/relay/base_field.rb +0 -22
  365. data/lib/graphql/types/relay/base_interface.rb +0 -29
  366. data/lib/graphql/types/relay/base_object.rb +0 -26
  367. data/spec/dummy/Gemfile +0 -12
  368. data/spec/dummy/Gemfile.lock +0 -157
  369. data/spec/dummy/README.md +0 -24
  370. data/spec/dummy/Rakefile +0 -7
  371. data/spec/dummy/app/assets/config/manifest.js +0 -1
  372. data/spec/dummy/app/assets/javascripts/application.js +0 -66
  373. data/spec/dummy/app/channels/application_cable/channel.rb +0 -5
  374. data/spec/dummy/app/channels/application_cable/connection.rb +0 -5
  375. data/spec/dummy/app/channels/graphql_channel.rb +0 -116
  376. data/spec/dummy/app/controllers/application_controller.rb +0 -4
  377. data/spec/dummy/app/controllers/pages_controller.rb +0 -5
  378. data/spec/dummy/app/helpers/application_helper.rb +0 -3
  379. data/spec/dummy/app/jobs/application_job.rb +0 -3
  380. data/spec/dummy/app/views/layouts/application.html.erb +0 -12
  381. data/spec/dummy/app/views/pages/show.html +0 -16
  382. data/spec/dummy/bin/bundle +0 -4
  383. data/spec/dummy/bin/rails +0 -5
  384. data/spec/dummy/bin/rake +0 -5
  385. data/spec/dummy/bin/setup +0 -31
  386. data/spec/dummy/bin/update +0 -27
  387. data/spec/dummy/bin/yarn +0 -12
  388. data/spec/dummy/config/application.rb +0 -30
  389. data/spec/dummy/config/boot.rb +0 -4
  390. data/spec/dummy/config/cable.yml +0 -10
  391. data/spec/dummy/config/environment.rb +0 -6
  392. data/spec/dummy/config/environments/development.rb +0 -40
  393. data/spec/dummy/config/environments/production.rb +0 -76
  394. data/spec/dummy/config/environments/test.rb +0 -37
  395. data/spec/dummy/config/initializers/application_controller_renderer.rb +0 -9
  396. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
  397. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -6
  398. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -5
  399. data/spec/dummy/config/initializers/inflections.rb +0 -17
  400. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  401. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -10
  402. data/spec/dummy/config/locales/en.yml +0 -33
  403. data/spec/dummy/config/puma.rb +0 -57
  404. data/spec/dummy/config/routes.rb +0 -4
  405. data/spec/dummy/config/secrets.yml +0 -32
  406. data/spec/dummy/config.ru +0 -6
  407. data/spec/dummy/log/test.log +0 -199
  408. data/spec/dummy/package.json +0 -5
  409. data/spec/dummy/public/404.html +0 -67
  410. data/spec/dummy/public/422.html +0 -67
  411. data/spec/dummy/public/500.html +0 -66
  412. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  413. data/spec/dummy/public/apple-touch-icon.png +0 -0
  414. data/spec/dummy/public/favicon.ico +0 -0
  415. data/spec/dummy/public/robots.txt +0 -1
  416. data/spec/dummy/test/application_system_test_case.rb +0 -6
  417. data/spec/dummy/test/system/action_cable_subscription_test.rb +0 -45
  418. data/spec/dummy/test/test_helper.rb +0 -4
  419. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
  420. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +0 -1
  421. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +0 -1
  422. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +0 -1
  423. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +0 -3
  424. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
  425. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -2
  426. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -2
  427. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
  428. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
  429. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +0 -1
  430. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
  431. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +0 -1
  432. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +0 -3
  433. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +0 -1
  434. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +0 -1
  435. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
  436. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +0 -1
  437. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
  438. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  439. data/spec/fixtures/upgrader/account.original.rb +0 -19
  440. data/spec/fixtures/upgrader/account.transformed.rb +0 -20
  441. data/spec/fixtures/upgrader/blame_range.original.rb +0 -43
  442. data/spec/fixtures/upgrader/blame_range.transformed.rb +0 -30
  443. data/spec/fixtures/upgrader/date_time.original.rb +0 -24
  444. data/spec/fixtures/upgrader/date_time.transformed.rb +0 -23
  445. data/spec/fixtures/upgrader/delete_project.original.rb +0 -28
  446. data/spec/fixtures/upgrader/delete_project.transformed.rb +0 -27
  447. data/spec/fixtures/upgrader/gist_order_field.original.rb +0 -14
  448. data/spec/fixtures/upgrader/gist_order_field.transformed.rb +0 -13
  449. data/spec/fixtures/upgrader/increment_count.original.rb +0 -59
  450. data/spec/fixtures/upgrader/increment_count.transformed.rb +0 -50
  451. data/spec/fixtures/upgrader/photo.original.rb +0 -10
  452. data/spec/fixtures/upgrader/photo.transformed.rb +0 -12
  453. data/spec/fixtures/upgrader/release_order.original.rb +0 -15
  454. data/spec/fixtures/upgrader/release_order.transformed.rb +0 -14
  455. data/spec/fixtures/upgrader/starrable.original.rb +0 -49
  456. data/spec/fixtures/upgrader/starrable.transformed.rb +0 -46
  457. data/spec/fixtures/upgrader/subscribable.original.rb +0 -55
  458. data/spec/fixtures/upgrader/subscribable.transformed.rb +0 -51
  459. data/spec/fixtures/upgrader/type_x.original.rb +0 -65
  460. data/spec/fixtures/upgrader/type_x.transformed.rb +0 -56
  461. data/spec/graphql/analysis/analyze_query_spec.rb +0 -272
  462. data/spec/graphql/analysis/ast/field_usage_spec.rb +0 -51
  463. data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +0 -120
  464. data/spec/graphql/analysis/ast/max_query_depth_spec.rb +0 -114
  465. data/spec/graphql/analysis/ast/query_complexity_spec.rb +0 -299
  466. data/spec/graphql/analysis/ast/query_depth_spec.rb +0 -108
  467. data/spec/graphql/analysis/ast_spec.rb +0 -269
  468. data/spec/graphql/analysis/field_usage_spec.rb +0 -62
  469. data/spec/graphql/analysis/max_query_complexity_spec.rb +0 -102
  470. data/spec/graphql/analysis/max_query_depth_spec.rb +0 -101
  471. data/spec/graphql/analysis/query_complexity_spec.rb +0 -301
  472. data/spec/graphql/analysis/query_depth_spec.rb +0 -81
  473. data/spec/graphql/argument_spec.rb +0 -159
  474. data/spec/graphql/authorization_spec.rb +0 -974
  475. data/spec/graphql/backtrace_spec.rb +0 -206
  476. data/spec/graphql/base_type_spec.rb +0 -171
  477. data/spec/graphql/boolean_type_spec.rb +0 -21
  478. data/spec/graphql/compatibility/execution_specification_spec.rb +0 -4
  479. data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +0 -4
  480. data/spec/graphql/compatibility/query_parser_specification_spec.rb +0 -6
  481. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +0 -6
  482. data/spec/graphql/define/assign_argument_spec.rb +0 -61
  483. data/spec/graphql/define/instance_definable_spec.rb +0 -203
  484. data/spec/graphql/directive/skip_directive_spec.rb +0 -9
  485. data/spec/graphql/directive_spec.rb +0 -295
  486. data/spec/graphql/enum_type_spec.rb +0 -158
  487. data/spec/graphql/execution/execute_spec.rb +0 -303
  488. data/spec/graphql/execution/instrumentation_spec.rb +0 -184
  489. data/spec/graphql/execution/interpreter_spec.rb +0 -485
  490. data/spec/graphql/execution/lazy/lazy_method_map_spec.rb +0 -57
  491. data/spec/graphql/execution/lazy_spec.rb +0 -247
  492. data/spec/graphql/execution/lookahead_spec.rb +0 -390
  493. data/spec/graphql/execution/multiplex_spec.rb +0 -211
  494. data/spec/graphql/execution/typecast_spec.rb +0 -47
  495. data/spec/graphql/execution_error_spec.rb +0 -325
  496. data/spec/graphql/field_spec.rb +0 -246
  497. data/spec/graphql/float_type_spec.rb +0 -16
  498. data/spec/graphql/function_spec.rb +0 -152
  499. data/spec/graphql/id_type_spec.rb +0 -33
  500. data/spec/graphql/input_object_type_spec.rb +0 -25
  501. data/spec/graphql/int_type_spec.rb +0 -35
  502. data/spec/graphql/interface_type_spec.rb +0 -196
  503. data/spec/graphql/internal_representation/print_spec.rb +0 -41
  504. data/spec/graphql/internal_representation/rewrite_spec.rb +0 -376
  505. data/spec/graphql/introspection/directive_type_spec.rb +0 -61
  506. data/spec/graphql/introspection/input_value_type_spec.rb +0 -144
  507. data/spec/graphql/introspection/introspection_query_spec.rb +0 -59
  508. data/spec/graphql/introspection/schema_type_spec.rb +0 -56
  509. data/spec/graphql/introspection/type_type_spec.rb +0 -155
  510. data/spec/graphql/language/block_string_spec.rb +0 -70
  511. data/spec/graphql/language/definition_slice_spec.rb +0 -226
  512. data/spec/graphql/language/document_from_schema_definition_spec.rb +0 -770
  513. data/spec/graphql/language/equality_spec.rb +0 -84
  514. data/spec/graphql/language/generation_spec.rb +0 -38
  515. data/spec/graphql/language/lexer_spec.rb +0 -135
  516. data/spec/graphql/language/nodes_spec.rb +0 -67
  517. data/spec/graphql/language/parser_spec.rb +0 -183
  518. data/spec/graphql/language/printer_spec.rb +0 -215
  519. data/spec/graphql/language/visitor_spec.rb +0 -419
  520. data/spec/graphql/list_type_spec.rb +0 -57
  521. data/spec/graphql/non_null_type_spec.rb +0 -48
  522. data/spec/graphql/object_type_spec.rb +0 -197
  523. data/spec/graphql/query/arguments_spec.rb +0 -346
  524. data/spec/graphql/query/context_spec.rb +0 -292
  525. data/spec/graphql/query/executor_spec.rb +0 -341
  526. data/spec/graphql/query/literal_input_spec.rb +0 -91
  527. data/spec/graphql/query/result_spec.rb +0 -29
  528. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +0 -109
  529. data/spec/graphql/query_spec.rb +0 -800
  530. data/spec/graphql/rake_task_spec.rb +0 -59
  531. data/spec/graphql/scalar_type_spec.rb +0 -66
  532. data/spec/graphql/schema/argument_spec.rb +0 -152
  533. data/spec/graphql/schema/build_from_definition_spec.rb +0 -1187
  534. data/spec/graphql/schema/catchall_middleware_spec.rb +0 -35
  535. data/spec/graphql/schema/directive/feature_spec.rb +0 -81
  536. data/spec/graphql/schema/directive/transform_spec.rb +0 -39
  537. data/spec/graphql/schema/enum_spec.rb +0 -83
  538. data/spec/graphql/schema/enum_value_spec.rb +0 -24
  539. data/spec/graphql/schema/field_extension_spec.rb +0 -137
  540. data/spec/graphql/schema/field_spec.rb +0 -301
  541. data/spec/graphql/schema/finder_spec.rb +0 -135
  542. data/spec/graphql/schema/input_object_spec.rb +0 -347
  543. data/spec/graphql/schema/instrumentation_spec.rb +0 -43
  544. data/spec/graphql/schema/interface_spec.rb +0 -215
  545. data/spec/graphql/schema/introspection_system_spec.rb +0 -56
  546. data/spec/graphql/schema/list_spec.rb +0 -46
  547. data/spec/graphql/schema/loader_spec.rb +0 -286
  548. data/spec/graphql/schema/member/accepts_definition_spec.rb +0 -115
  549. data/spec/graphql/schema/member/build_type_spec.rb +0 -63
  550. data/spec/graphql/schema/member/scoped_spec.rb +0 -217
  551. data/spec/graphql/schema/member/type_system_helpers_spec.rb +0 -63
  552. data/spec/graphql/schema/middleware_chain_spec.rb +0 -57
  553. data/spec/graphql/schema/mutation_spec.rb +0 -150
  554. data/spec/graphql/schema/non_null_spec.rb +0 -46
  555. data/spec/graphql/schema/object_spec.rb +0 -315
  556. data/spec/graphql/schema/printer_spec.rb +0 -869
  557. data/spec/graphql/schema/relay_classic_mutation_spec.rb +0 -252
  558. data/spec/graphql/schema/rescue_middleware_spec.rb +0 -88
  559. data/spec/graphql/schema/resolver_spec.rb +0 -714
  560. data/spec/graphql/schema/scalar_spec.rb +0 -101
  561. data/spec/graphql/schema/subscription_spec.rb +0 -440
  562. data/spec/graphql/schema/timeout_middleware_spec.rb +0 -188
  563. data/spec/graphql/schema/traversal_spec.rb +0 -222
  564. data/spec/graphql/schema/type_expression_spec.rb +0 -39
  565. data/spec/graphql/schema/union_spec.rb +0 -72
  566. data/spec/graphql/schema/unique_within_type_spec.rb +0 -44
  567. data/spec/graphql/schema/validation_spec.rb +0 -355
  568. data/spec/graphql/schema/warden_spec.rb +0 -926
  569. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +0 -413
  570. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +0 -44
  571. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +0 -112
  572. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +0 -35
  573. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +0 -42
  574. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +0 -167
  575. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +0 -66
  576. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +0 -740
  577. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +0 -28
  578. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +0 -52
  579. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +0 -42
  580. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +0 -123
  581. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +0 -24
  582. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +0 -56
  583. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +0 -61
  584. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +0 -39
  585. data/spec/graphql/static_validation/rules/no_definitions_are_present_spec.rb +0 -62
  586. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +0 -82
  587. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +0 -73
  588. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +0 -86
  589. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +0 -34
  590. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +0 -188
  591. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +0 -196
  592. data/spec/graphql/static_validation/rules/variable_names_are_unique_spec.rb +0 -23
  593. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +0 -236
  594. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +0 -78
  595. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +0 -81
  596. data/spec/graphql/static_validation/type_stack_spec.rb +0 -29
  597. data/spec/graphql/static_validation/validator_spec.rb +0 -204
  598. data/spec/graphql/string_type_spec.rb +0 -80
  599. data/spec/graphql/subscriptions/serialize_spec.rb +0 -49
  600. data/spec/graphql/subscriptions_spec.rb +0 -540
  601. data/spec/graphql/tracing/new_relic_tracing_spec.rb +0 -84
  602. data/spec/graphql/tracing/platform_tracing_spec.rb +0 -141
  603. data/spec/graphql/tracing/prometheus_tracing_spec.rb +0 -42
  604. data/spec/graphql/tracing/scout_tracing_spec.rb +0 -17
  605. data/spec/graphql/tracing/skylight_tracing_spec.rb +0 -63
  606. data/spec/graphql/tracing_spec.rb +0 -52
  607. data/spec/graphql/types/big_int_spec.rb +0 -24
  608. data/spec/graphql/types/iso_8601_date_time_spec.rb +0 -137
  609. data/spec/graphql/types/relay/base_edge_spec.rb +0 -33
  610. data/spec/graphql/union_type_spec.rb +0 -211
  611. data/spec/graphql/upgrader/member_spec.rb +0 -583
  612. data/spec/graphql/upgrader/schema_spec.rb +0 -82
  613. data/spec/integration/mongoid/graphql/relay/mongo_relation_connection_spec.rb +0 -528
  614. data/spec/integration/mongoid/spec_helper.rb +0 -2
  615. data/spec/integration/mongoid/star_trek/data.rb +0 -126
  616. data/spec/integration/mongoid/star_trek/schema.rb +0 -425
  617. data/spec/integration/rails/data.rb +0 -110
  618. data/spec/integration/rails/generators/base_generator_test.rb +0 -7
  619. data/spec/integration/rails/generators/graphql/enum_generator_spec.rb +0 -30
  620. data/spec/integration/rails/generators/graphql/install_generator_spec.rb +0 -218
  621. data/spec/integration/rails/generators/graphql/interface_generator_spec.rb +0 -34
  622. data/spec/integration/rails/generators/graphql/loader_generator_spec.rb +0 -59
  623. data/spec/integration/rails/generators/graphql/mutation_generator_spec.rb +0 -71
  624. data/spec/integration/rails/generators/graphql/object_generator_spec.rb +0 -54
  625. data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +0 -28
  626. data/spec/integration/rails/generators/graphql/union_generator_spec.rb +0 -67
  627. data/spec/integration/rails/graphql/input_object_type_spec.rb +0 -364
  628. data/spec/integration/rails/graphql/query/variables_spec.rb +0 -375
  629. data/spec/integration/rails/graphql/relay/array_connection_spec.rb +0 -290
  630. data/spec/integration/rails/graphql/relay/base_connection_spec.rb +0 -101
  631. data/spec/integration/rails/graphql/relay/connection_instrumentation_spec.rb +0 -80
  632. data/spec/integration/rails/graphql/relay/connection_resolve_spec.rb +0 -79
  633. data/spec/integration/rails/graphql/relay/connection_type_spec.rb +0 -106
  634. data/spec/integration/rails/graphql/relay/edge_spec.rb +0 -10
  635. data/spec/integration/rails/graphql/relay/mutation_spec.rb +0 -387
  636. data/spec/integration/rails/graphql/relay/node_spec.rb +0 -263
  637. data/spec/integration/rails/graphql/relay/page_info_spec.rb +0 -111
  638. data/spec/integration/rails/graphql/relay/range_add_spec.rb +0 -117
  639. data/spec/integration/rails/graphql/relay/relation_connection_spec.rb +0 -837
  640. data/spec/integration/rails/graphql/schema_spec.rb +0 -489
  641. data/spec/integration/rails/graphql/tracing/active_support_notifications_tracing_spec.rb +0 -62
  642. data/spec/integration/rails/spec_helper.rb +0 -25
  643. data/spec/integration/tmp/app/graphql/types/bird_type.rb +0 -7
  644. data/spec/spec_helper.rb +0 -116
  645. data/spec/support/dummy/data.rb +0 -45
  646. data/spec/support/dummy/schema.rb +0 -511
  647. data/spec/support/error_bubbling_helpers.rb +0 -23
  648. data/spec/support/global_id.rb +0 -23
  649. data/spec/support/jazz.rb +0 -772
  650. data/spec/support/lazy_helpers.rb +0 -192
  651. data/spec/support/magic_cards/schema.graphql +0 -33
  652. data/spec/support/minimum_input_object.rb +0 -21
  653. data/spec/support/new_relic.rb +0 -27
  654. data/spec/support/parser/filename_example.graphql +0 -5
  655. data/spec/support/parser/filename_example_error_1.graphql +0 -4
  656. data/spec/support/parser/filename_example_error_2.graphql +0 -5
  657. data/spec/support/skylight.rb +0 -39
  658. data/spec/support/star_wars/schema.rb +0 -465
  659. data/spec/support/static_validation_helpers.rb +0 -32
@@ -5,10 +5,21 @@ module GraphQL
5
5
  # Query analyzer for query ASTs. Query analyzers respond to visitor style methods
6
6
  # but are prefixed by `enter` and `leave`.
7
7
  #
8
- # @param [GraphQL::Query] The query to analyze
8
+ # When an analyzer is initialized with a Multiplex, you can always get the current query from
9
+ # `visitor.query` in the visit methods.
10
+ #
11
+ # @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
9
12
  class Analyzer
10
- def initialize(query)
11
- @query = query
13
+ def initialize(subject)
14
+ @subject = subject
15
+
16
+ if subject.is_a?(GraphQL::Query)
17
+ @query = subject
18
+ @multiplex = nil
19
+ else
20
+ @multiplex = subject
21
+ @query = nil
22
+ end
12
23
  end
13
24
 
14
25
  # Analyzer hook to decide at analysis time whether a query should
@@ -22,18 +33,21 @@ module GraphQL
22
33
  # in a query error.
23
34
  # @return [Any] The analyzer result
24
35
  def result
25
- raise NotImplementedError
36
+ raise GraphQL::RequiredImplementationMissingError
26
37
  end
27
38
 
28
- # Don't use make_visit_method because it breaks `super`
29
- def self.build_visitor_hooks(member_name)
30
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
31
- def on_enter_#{member_name}(node, parent, visitor)
32
- end
39
+ class << self
40
+ private
41
+
42
+ def build_visitor_hooks(member_name)
43
+ class_eval(<<-EOS, __FILE__, __LINE__ + 1)
44
+ def on_enter_#{member_name}(node, parent, visitor)
45
+ end
33
46
 
34
- def on_leave_#{member_name}(node, parent, visitor)
35
- end
36
- EOS
47
+ def on_leave_#{member_name}(node, parent, visitor)
48
+ end
49
+ EOS
50
+ end
37
51
  end
38
52
 
39
53
  build_visitor_hooks :argument
@@ -55,7 +69,15 @@ module GraphQL
55
69
 
56
70
  protected
57
71
 
72
+ # @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
73
+ attr_reader :subject
74
+
75
+ # @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
76
+ # (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
58
77
  attr_reader :query
78
+
79
+ # @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
80
+ attr_reader :multiplex
59
81
  end
60
82
  end
61
83
  end
@@ -7,21 +7,48 @@ module GraphQL
7
7
  super
8
8
  @used_fields = Set.new
9
9
  @used_deprecated_fields = Set.new
10
+ @used_deprecated_arguments = Set.new
10
11
  end
11
12
 
12
13
  def on_leave_field(node, parent, visitor)
13
14
  field_defn = visitor.field_definition
14
- field = "#{visitor.parent_type_definition.name}.#{field_defn.name}"
15
+ field = "#{visitor.parent_type_definition.graphql_name}.#{field_defn.graphql_name}"
15
16
  @used_fields << field
16
17
  @used_deprecated_fields << field if field_defn.deprecation_reason
18
+ arguments = visitor.query.arguments_for(node, visitor.field_definition)
19
+ # If there was an error when preparing this argument object,
20
+ # then this might be an error or something:
21
+ if arguments.respond_to?(:argument_values)
22
+ extract_deprecated_arguments(arguments.argument_values)
23
+ end
17
24
  end
18
25
 
19
26
  def result
20
27
  {
21
28
  used_fields: @used_fields.to_a,
22
- used_deprecated_fields: @used_deprecated_fields.to_a
29
+ used_deprecated_fields: @used_deprecated_fields.to_a,
30
+ used_deprecated_arguments: @used_deprecated_arguments.to_a,
23
31
  }
24
32
  end
33
+
34
+ private
35
+
36
+ def extract_deprecated_arguments(argument_values)
37
+ argument_values.each_pair do |_argument_name, argument|
38
+ if argument.definition.deprecation_reason
39
+ @used_deprecated_arguments << argument.definition.path
40
+ end
41
+
42
+ if argument.definition.type.kind.input_object?
43
+ extract_deprecated_arguments(argument.value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
44
+ elsif argument.definition.type.list? && !argument.value.nil?
45
+ argument
46
+ .value
47
+ .select { |value| value.respond_to?(:arguments) }
48
+ .each { |value| extract_deprecated_arguments(value.arguments.argument_values) } # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
49
+ end
50
+ end
51
+ end
25
52
  end
26
53
  end
27
54
  end
@@ -7,12 +7,12 @@ module GraphQL
7
7
  # see {Schema#max_complexity} and {Query#max_complexity}
8
8
  class MaxQueryComplexity < QueryComplexity
9
9
  def result
10
- return if query.max_complexity.nil?
10
+ return if subject.max_complexity.nil?
11
11
 
12
12
  total_complexity = max_possible_complexity
13
13
 
14
- if total_complexity > query.max_complexity
15
- GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{query.max_complexity}")
14
+ if total_complexity > subject.max_complexity
15
+ GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
16
16
  else
17
17
  nil
18
18
  end
@@ -4,10 +4,14 @@ module GraphQL
4
4
  module AST
5
5
  class MaxQueryDepth < QueryDepth
6
6
  def result
7
- return unless query.max_depth
7
+ configured_max_depth = if query
8
+ query.max_depth
9
+ else
10
+ multiplex.schema.max_depth
11
+ end
8
12
 
9
- if @max_depth > query.max_depth
10
- GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{query.max_depth}")
13
+ if configured_max_depth && @max_depth > configured_max_depth
14
+ GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
11
15
  else
12
16
  nil
13
17
  end
@@ -4,11 +4,11 @@ module GraphQL
4
4
  # Calculate the complexity of a query, using {Field#complexity} values.
5
5
  module AST
6
6
  class QueryComplexity < Analyzer
7
- # State for the query complexity calcuation:
7
+ # State for the query complexity calculation:
8
8
  # - `complexities_on_type` holds complexity scores for each type in an IRep node
9
9
  def initialize(query)
10
10
  super
11
- @complexities_on_type = [TypeComplexity.new]
11
+ @complexities_on_type_by_query = {}
12
12
  end
13
13
 
14
14
  # Overide this method to use the complexity result
@@ -16,13 +16,68 @@ module GraphQL
16
16
  max_possible_complexity
17
17
  end
18
18
 
19
+ class ScopedTypeComplexity
20
+ # A single proc for {#scoped_children} hashes. Use this to avoid repeated allocations,
21
+ # since the lexical binding isn't important.
22
+ HASH_CHILDREN = ->(h, k) { h[k] = {} }
23
+
24
+ attr_reader :field_definition, :response_path, :query
25
+
26
+ # @param parent_type [Class] The owner of `field_definition`
27
+ # @param field_definition [GraphQL::Field, GraphQL::Schema::Field] Used for getting the `.complexity` configuration
28
+ # @param query [GraphQL::Query] Used for `query.possible_types`
29
+ # @param response_path [Array<String>] The path to the response key for the field
30
+ def initialize(parent_type, field_definition, query, response_path)
31
+ @parent_type = parent_type
32
+ @field_definition = field_definition
33
+ @query = query
34
+ @response_path = response_path
35
+ @scoped_children = nil
36
+ @nodes = []
37
+ end
38
+
39
+ # @return [Array<GraphQL::Language::Nodes::Field>]
40
+ attr_reader :nodes
41
+
42
+ # Returns true if this field has no selections, ie, it's a scalar.
43
+ # We need a quick way to check whether we should continue traversing.
44
+ def terminal?
45
+ @scoped_children.nil?
46
+ end
47
+
48
+ # This value is only calculated when asked for to avoid needless hash allocations.
49
+ # Also, if it's never asked for, we determine that this scope complexity
50
+ # is a scalar field ({#terminal?}).
51
+ # @return [Hash<Hash<Class => ScopedTypeComplexity>]
52
+ def scoped_children
53
+ @scoped_children ||= Hash.new(&HASH_CHILDREN)
54
+ end
55
+
56
+ def own_complexity(child_complexity)
57
+ @field_definition.calculate_complexity(query: @query, nodes: @nodes, child_complexity: child_complexity)
58
+ end
59
+ end
60
+
19
61
  def on_enter_field(node, parent, visitor)
20
62
  # We don't want to visit fragment definitions,
21
63
  # we'll visit them when we hit the spreads instead
22
64
  return if visitor.visiting_fragment_definition?
23
65
  return if visitor.skipping?
24
-
25
- @complexities_on_type.push(TypeComplexity.new)
66
+ parent_type = visitor.parent_type_definition
67
+ field_key = node.alias || node.name
68
+ # Find the complexity calculation for this field --
69
+ # if we're re-entering a selection, we'll already have one.
70
+ # Otherwise, make a new one and store it.
71
+ #
72
+ # `node` and `visitor.field_definition` may appear from a cache,
73
+ # but I think that's ok. If the arguments _didn't_ match,
74
+ # then the query would have been rejected as invalid.
75
+ complexities_on_type = @complexities_on_type_by_query[visitor.query] ||= [ScopedTypeComplexity.new(nil, nil, query, visitor.response_path)]
76
+
77
+ complexity = complexities_on_type.last.scoped_children[parent_type][field_key] ||= ScopedTypeComplexity.new(parent_type, visitor.field_definition, visitor.query, visitor.response_path)
78
+ complexity.nodes.push(node)
79
+ # Push it on the stack.
80
+ complexities_on_type.push(complexity)
26
81
  end
27
82
 
28
83
  def on_leave_field(node, parent, visitor)
@@ -30,84 +85,144 @@ module GraphQL
30
85
  # we'll visit them when we hit the spreads instead
31
86
  return if visitor.visiting_fragment_definition?
32
87
  return if visitor.skipping?
33
-
34
- type_complexities = @complexities_on_type.pop
35
- child_complexity = type_complexities.max_possible_complexity
36
- own_complexity = get_complexity(node, visitor.field_definition, child_complexity, visitor)
37
-
38
- parent_type = visitor.parent_type_definition
39
- possible_types = if parent_type.kind.abstract?
40
- query.possible_types(parent_type)
41
- else
42
- [parent_type]
43
- end
44
-
45
- key = selection_key(visitor.response_path, visitor.query)
46
-
47
- possible_types.each do |type|
48
- @complexities_on_type.last.merge(type, key, own_complexity)
49
- end
88
+ complexities_on_type = @complexities_on_type_by_query[visitor.query]
89
+ complexities_on_type.pop
50
90
  end
51
91
 
52
- def on_enter_fragment_spread(node, _, visitor)
53
- visitor.enter_fragment_spread_inline(node)
54
- end
55
-
56
- def on_leave_fragment_spread(node, _, visitor)
57
- visitor.leave_fragment_spread_inline(node)
58
- end
92
+ private
59
93
 
60
94
  # @return [Integer]
61
95
  def max_possible_complexity
62
- @complexities_on_type.last.max_possible_complexity
96
+ @complexities_on_type_by_query.reduce(0) do |total, (query, complexities_on_type)|
97
+ root_complexity = complexities_on_type.last
98
+ # Use this entry point to calculate the total complexity
99
+ total_complexity_for_query = merged_max_complexity_for_scopes(query, [root_complexity.scoped_children])
100
+ total + total_complexity_for_query
101
+ end
63
102
  end
64
103
 
65
- private
104
+ # @param query [GraphQL::Query] Used for `query.possible_types`
105
+ # @param scoped_children_hashes [Array<Hash>] Array of scoped children hashes
106
+ # @return [Integer]
107
+ def merged_max_complexity_for_scopes(query, scoped_children_hashes)
108
+ # Figure out what scopes are possible here.
109
+ # Use a hash, but ignore the values; it's just a fast way to work with the keys.
110
+ all_scopes = {}
111
+ scoped_children_hashes.each do |h|
112
+ all_scopes.merge!(h)
113
+ end
66
114
 
67
- def selection_key(response_path, query)
68
- # We add the query object id to support multiplex queries
69
- # even if they have the same response path, they should
70
- # always be added.
71
- response_path.join(".") + "-#{query.object_id}"
72
- end
115
+ # If an abstract scope is present, but _all_ of its concrete types
116
+ # are also in the list, remove it from the list of scopes to check,
117
+ # because every possible type is covered by a concrete type.
118
+ # (That is, there are no remainder types to check.)
119
+ prev_keys = all_scopes.keys
120
+ prev_keys.each do |scope|
121
+ next unless scope.kind.abstract?
122
+
123
+ missing_concrete_types = query.possible_types(scope).select { |t| !all_scopes.key?(t) }
124
+ # This concrete type is possible _only_ as a member of the abstract type.
125
+ # So, attribute to it the complexity which belongs to the abstract type.
126
+ missing_concrete_types.each do |concrete_scope|
127
+ all_scopes[concrete_scope] = all_scopes[scope]
128
+ end
129
+ all_scopes.delete(scope)
130
+ end
73
131
 
74
- # Get a complexity value for a field,
75
- # by getting the number or calling its proc
76
- def get_complexity(ast_node, field_defn, child_complexity, visitor)
77
- # Return if we've visited this response path before (not counting duplicates)
78
- defined_complexity = field_defn.complexity
132
+ # This will hold `{ type => int }` pairs, one for each possible branch
133
+ complexity_by_scope = {}
134
+
135
+ # For each scope,
136
+ # find the lexical selections that might apply to it,
137
+ # and gather them together into an array.
138
+ # Then, treat the set of selection hashes
139
+ # as a set and calculate the complexity for them as a unit
140
+ all_scopes.each do |scope, _|
141
+ # These will be the selections on `scope`
142
+ children_for_scope = []
143
+ scoped_children_hashes.each do |sc_h|
144
+ sc_h.each do |inner_scope, children_hash|
145
+ if applies_to?(query, scope, inner_scope)
146
+ children_for_scope << children_hash
147
+ end
148
+ end
149
+ end
150
+
151
+ # Calculate the complexity for `scope`, merging all
152
+ # possible lexical branches.
153
+ complexity_value = merged_max_complexity(query, children_for_scope)
154
+ complexity_by_scope[scope] = complexity_value
155
+ end
79
156
 
80
- arguments = visitor.arguments_for(ast_node, field_defn)
157
+ # Return the max complexity among all scopes
158
+ complexity_by_scope.each_value.max
159
+ end
81
160
 
82
- case defined_complexity
83
- when Proc
84
- defined_complexity.call(query.context, arguments, child_complexity)
85
- when Numeric
86
- defined_complexity + (child_complexity || 0)
161
+ def applies_to?(query, left_scope, right_scope)
162
+ if left_scope == right_scope
163
+ # This can happen when several branches are being analyzed together
164
+ true
87
165
  else
88
- raise("Invalid complexity: #{defined_complexity.inspect} on #{field_defn.name}")
166
+ # Check if these two scopes have _any_ types in common.
167
+ possible_right_types = query.possible_types(right_scope)
168
+ possible_left_types = query.possible_types(left_scope)
169
+ !(possible_right_types & possible_left_types).empty?
89
170
  end
90
171
  end
91
172
 
92
- # Selections on an object may apply differently depending on what is _actually_ returned by the resolve function.
93
- # Find the maximum possible complexity among those combinations.
94
- class TypeComplexity
95
- def initialize
96
- @types = Hash.new { |h, k| h[k] = {} }
97
- end
173
+ # A hook which is called whenever a field's max complexity is calculated.
174
+ # Override this method to capture individual field complexity details.
175
+ #
176
+ # @param scoped_type_complexity [ScopedTypeComplexity]
177
+ # @param max_complexity [Numeric] Field's maximum complexity including child complexity
178
+ # @param child_complexity [Numeric, nil] Field's child complexity
179
+ def field_complexity(scoped_type_complexity, max_complexity:, child_complexity: nil)
180
+ end
98
181
 
99
- # Return the max possible complexity for types in this selection
100
- def max_possible_complexity
101
- @types.map do |type, fields|
102
- fields.values.inject(:+)
103
- end.max
182
+ # @param children_for_scope [Array<Hash>] An array of `scoped_children[scope]` hashes
183
+ # (`{field_key => complexity}`)
184
+ # @return [Integer] Complexity value for all these selections in the current scope
185
+ def merged_max_complexity(query, children_for_scope)
186
+ all_keys = []
187
+ children_for_scope.each do |c|
188
+ all_keys.concat(c.keys)
104
189
  end
105
-
106
- # Store the complexity for the branch on `type_defn`.
107
- # Later we will see if this is the max complexity among branches.
108
- def merge(type_defn, key, complexity)
109
- @types[type_defn][key] = complexity
190
+ all_keys.uniq!
191
+ complexity_for_keys = {}
192
+
193
+ all_keys.each do |child_key|
194
+ scoped_children_for_key = nil
195
+ complexity_for_key = nil
196
+ children_for_scope.each do |children_hash|
197
+ next unless children_hash.key?(child_key)
198
+
199
+ complexity_for_key = children_hash[child_key]
200
+ if complexity_for_key.terminal?
201
+ # Assume that all terminals would return the same complexity
202
+ # Since it's a terminal, its child complexity is zero.
203
+ complexity = complexity_for_key.own_complexity(0)
204
+ complexity_for_keys[child_key] = complexity
205
+
206
+ field_complexity(complexity_for_key, max_complexity: complexity, child_complexity: nil)
207
+ else
208
+ scoped_children_for_key ||= []
209
+ scoped_children_for_key << complexity_for_key.scoped_children
210
+ end
211
+ end
212
+
213
+ next unless scoped_children_for_key
214
+
215
+ child_complexity = merged_max_complexity_for_scopes(query, scoped_children_for_key)
216
+ # This is the _last_ one we visited; assume it's representative.
217
+ max_complexity = complexity_for_key.own_complexity(child_complexity)
218
+
219
+ field_complexity(complexity_for_key, max_complexity: max_complexity, child_complexity: child_complexity)
220
+
221
+ complexity_for_keys[child_key] = max_complexity
110
222
  end
223
+
224
+ # Calculate the child complexity by summing the complexity of all selections
225
+ complexity_for_keys.each_value.inject(0, &:+)
111
226
  end
112
227
  end
113
228
  end
@@ -3,13 +3,24 @@ module GraphQL
3
3
  module Analysis
4
4
  # A query reducer for measuring the depth of a given query.
5
5
  #
6
+ # See https://graphql-ruby.org/queries/ast_analysis.html for more examples.
7
+ #
6
8
  # @example Logging the depth of a query
7
9
  # class LogQueryDepth < GraphQL::Analysis::QueryDepth
8
- # def on_analysis_end
10
+ # def result
9
11
  # log("GraphQL query depth: #{@max_depth}")
10
12
  # end
11
13
  # end
12
14
  #
15
+ # # In your Schema file:
16
+ #
17
+ # class MySchema < GraphQL::Schema
18
+ # use GraphQL::Analysis::AST
19
+ # query_analyzer LogQueryDepth
20
+ # end
21
+ #
22
+ # # When you run the query, the depth will get logged:
23
+ #
13
24
  # Schema.execute(query_str)
14
25
  # # GraphQL query depth: 8
15
26
  #
@@ -18,43 +29,22 @@ module GraphQL
18
29
  def initialize(query)
19
30
  @max_depth = 0
20
31
  @current_depth = 0
21
- @skip_depth = 0
22
32
  super
23
33
  end
24
34
 
25
35
  def on_enter_field(node, parent, visitor)
26
36
  return if visitor.skipping? || visitor.visiting_fragment_definition?
27
37
 
28
- # Don't validate introspection fields or skipped nodes
29
- if GraphQL::Schema::DYNAMIC_FIELDS.include?(visitor.field_definition.name)
30
- @skip_depth += 1
31
- elsif @skip_depth > 0
32
- # we're inside an introspection query or skipped node
33
- else
34
- @current_depth += 1
35
- end
38
+ @current_depth += 1
36
39
  end
37
40
 
38
41
  def on_leave_field(node, parent, visitor)
39
42
  return if visitor.skipping? || visitor.visiting_fragment_definition?
40
43
 
41
- # Don't validate introspection fields or skipped nodes
42
- if GraphQL::Schema::DYNAMIC_FIELDS.include?(visitor.field_definition.name)
43
- @skip_depth -= 1
44
- else
45
- if @max_depth < @current_depth
46
- @max_depth = @current_depth
47
- end
48
- @current_depth -= 1
44
+ if @max_depth < @current_depth
45
+ @max_depth = @current_depth
49
46
  end
50
- end
51
-
52
- def on_enter_fragment_spread(node, _, visitor)
53
- visitor.enter_fragment_spread_inline(node)
54
- end
55
-
56
- def on_leave_fragment_spread(node, _, visitor)
57
- visitor.leave_fragment_spread_inline(node)
47
+ @current_depth -= 1
58
48
  end
59
49
 
60
50
  def result
@@ -19,6 +19,7 @@ module GraphQL
19
19
  @field_definitions = []
20
20
  @argument_definitions = []
21
21
  @directive_definitions = []
22
+ @rescued_errors = []
22
23
  @query = query
23
24
  @schema = query.schema
24
25
  @response_path = []
@@ -32,6 +33,9 @@ module GraphQL
32
33
  # @return [Array<GraphQL::ObjectType>] Types whose scope we've entered
33
34
  attr_reader :object_types
34
35
 
36
+ # @return [Array<GraphQL::AnalysisError]
37
+ attr_reader :rescued_errors
38
+
35
39
  def visit
36
40
  return unless @document
37
41
  super
@@ -96,7 +100,8 @@ module GraphQL
96
100
  def on_field(node, parent)
97
101
  @response_path.push(node.alias || node.name)
98
102
  parent_type = @object_types.last
99
- field_definition = @schema.get_field(parent_type, node.name)
103
+ # This could be nil if the previous field wasn't found:
104
+ field_definition = parent_type && @schema.get_field(parent_type, node.name, @query.context)
100
105
  @field_definitions.push(field_definition)
101
106
  if !field_definition.nil?
102
107
  next_object_type = field_definition.type.unwrap
@@ -134,14 +139,14 @@ module GraphQL
134
139
  argument_defn = if (arg = @argument_definitions.last)
135
140
  arg_type = arg.type.unwrap
136
141
  if arg_type.kind.input_object?
137
- arg_type.input_fields[node.name]
142
+ arg_type.get_argument(node.name, @query.context)
138
143
  else
139
144
  nil
140
145
  end
141
146
  elsif (directive_defn = @directive_definitions.last)
142
- directive_defn.arguments[node.name]
147
+ directive_defn.get_argument(node.name, @query.context)
143
148
  elsif (field_defn = @field_definitions.last)
144
- field_defn.arguments[node.name]
149
+ field_defn.get_argument(node.name, @query.context)
145
150
  else
146
151
  nil
147
152
  end
@@ -158,7 +163,9 @@ module GraphQL
158
163
  def on_fragment_spread(node, parent)
159
164
  @path.push("... #{node.name}")
160
165
  call_analyzers(:on_enter_fragment_spread, node, parent)
166
+ enter_fragment_spread_inline(node)
161
167
  super
168
+ leave_fragment_spread_inline(node)
162
169
  call_analyzers(:on_leave_fragment_spread, node, parent)
163
170
  @path.pop
164
171
  end
@@ -169,30 +176,6 @@ module GraphQL
169
176
  call_analyzers(:on_leave_abstract_node, node, parent)
170
177
  end
171
178
 
172
- # Visit a fragment spread inline instead of visiting the definition
173
- # by itself.
174
- def enter_fragment_spread_inline(fragment_spread)
175
- fragment_def = query.fragments[fragment_spread.name]
176
-
177
- object_type = if fragment_def.type
178
- query.schema.types.fetch(fragment_def.type.name, nil)
179
- else
180
- object_types.last
181
- end
182
-
183
- object_types << object_type
184
-
185
- fragment_def.selections.each do |selection|
186
- visit_node(selection, fragment_def)
187
- end
188
- end
189
-
190
- # Visit a fragment spread inline instead of visiting the definition
191
- # by itself.
192
- def leave_fragment_spread_inline(_fragment_spread)
193
- object_types.pop
194
- end
195
-
196
179
  # @return [GraphQL::BaseType] The current object type
197
180
  def type_definition
198
181
  @object_types.last
@@ -220,13 +203,40 @@ module GraphQL
220
203
 
221
204
  # @return [GraphQL::Argument, nil] The most-recently-entered GraphQL::Argument, if currently inside one
222
205
  def argument_definition
223
- # Don't get the _last_ one because that's the current one.
224
- # Get the second-to-last one, which is the parent of the current one.
206
+ @argument_definitions.last
207
+ end
208
+
209
+ # @return [GraphQL::Argument, nil] The previous GraphQL argument
210
+ def previous_argument_definition
225
211
  @argument_definitions[-2]
226
212
  end
227
213
 
228
214
  private
229
215
 
216
+ # Visit a fragment spread inline instead of visiting the definition
217
+ # by itself.
218
+ def enter_fragment_spread_inline(fragment_spread)
219
+ fragment_def = query.fragments[fragment_spread.name]
220
+
221
+ object_type = if fragment_def.type
222
+ @query.warden.get_type(fragment_def.type.name)
223
+ else
224
+ object_types.last
225
+ end
226
+
227
+ object_types << object_type
228
+
229
+ fragment_def.selections.each do |selection|
230
+ visit_node(selection, fragment_def)
231
+ end
232
+ end
233
+
234
+ # Visit a fragment spread inline instead of visiting the definition
235
+ # by itself.
236
+ def leave_fragment_spread_inline(_fragment_spread)
237
+ object_types.pop
238
+ end
239
+
230
240
  def skip?(ast_node)
231
241
  dir = ast_node.directives
232
242
  dir.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
@@ -234,13 +244,17 @@ module GraphQL
234
244
 
235
245
  def call_analyzers(method, node, parent)
236
246
  @analyzers.each do |analyzer|
237
- analyzer.public_send(method, node, parent, self)
247
+ begin
248
+ analyzer.public_send(method, node, parent, self)
249
+ rescue AnalysisError => err
250
+ @rescued_errors << err
251
+ end
238
252
  end
239
253
  end
240
254
 
241
255
  def on_fragment_with_type(node)
242
256
  object_type = if node.type
243
- @schema.types.fetch(node.type.name, nil)
257
+ @query.warden.get_type(node.type.name)
244
258
  else
245
259
  @object_types.last
246
260
  end