graphql 1.9.18 → 1.13.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (353) 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 +44 -7
  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 +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 +22 -27
  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/field_usage.rb +29 -2
  50. data/lib/graphql/analysis/ast/query_complexity.rb +174 -67
  51. data/lib/graphql/analysis/ast/visitor.rb +16 -7
  52. data/lib/graphql/analysis/ast.rb +21 -11
  53. data/lib/graphql/argument.rb +8 -36
  54. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  55. data/lib/graphql/backtrace/legacy_tracer.rb +56 -0
  56. data/lib/graphql/backtrace/table.rb +44 -5
  57. data/lib/graphql/backtrace/traced_error.rb +0 -1
  58. data/lib/graphql/backtrace/tracer.rb +40 -9
  59. data/lib/graphql/backtrace.rb +28 -19
  60. data/lib/graphql/backwards_compatibility.rb +2 -1
  61. data/lib/graphql/base_type.rb +10 -4
  62. data/lib/graphql/boolean_type.rb +1 -1
  63. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +2 -2
  64. data/lib/graphql/compatibility/execution_specification.rb +1 -0
  65. data/lib/graphql/compatibility/lazy_execution_specification.rb +2 -0
  66. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  67. data/lib/graphql/compatibility/query_parser_specification.rb +2 -0
  68. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -0
  69. data/lib/graphql/dataloader/null_dataloader.rb +22 -0
  70. data/lib/graphql/dataloader/request.rb +19 -0
  71. data/lib/graphql/dataloader/request_all.rb +19 -0
  72. data/lib/graphql/dataloader/source.rb +155 -0
  73. data/lib/graphql/dataloader.rb +308 -0
  74. data/lib/graphql/date_encoding_error.rb +16 -0
  75. data/lib/graphql/define/assign_enum_value.rb +1 -1
  76. data/lib/graphql/define/assign_global_id_field.rb +2 -2
  77. data/lib/graphql/define/assign_object_field.rb +1 -1
  78. data/lib/graphql/define/defined_object_proxy.rb +5 -8
  79. data/lib/graphql/define/instance_definable.rb +60 -110
  80. data/lib/graphql/define/type_definer.rb +5 -5
  81. data/lib/graphql/deprecated_dsl.rb +18 -5
  82. data/lib/graphql/deprecation.rb +9 -0
  83. data/lib/graphql/directive/deprecated_directive.rb +1 -12
  84. data/lib/graphql/directive/include_directive.rb +1 -1
  85. data/lib/graphql/directive/skip_directive.rb +1 -1
  86. data/lib/graphql/directive.rb +9 -6
  87. data/lib/graphql/enum_type.rb +14 -74
  88. data/lib/graphql/execution/directive_checks.rb +2 -2
  89. data/lib/graphql/execution/errors.rb +110 -8
  90. data/lib/graphql/execution/execute.rb +8 -1
  91. data/lib/graphql/execution/instrumentation.rb +1 -1
  92. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  93. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  94. data/lib/graphql/execution/interpreter/arguments_cache.rb +105 -0
  95. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  96. data/lib/graphql/execution/interpreter/resolve.rb +37 -25
  97. data/lib/graphql/execution/interpreter/runtime.rb +721 -386
  98. data/lib/graphql/execution/interpreter.rb +42 -19
  99. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  100. data/lib/graphql/execution/lazy.rb +5 -1
  101. data/lib/graphql/execution/lookahead.rb +39 -114
  102. data/lib/graphql/execution/multiplex.rb +50 -25
  103. data/lib/graphql/field.rb +15 -119
  104. data/lib/graphql/filter.rb +1 -1
  105. data/lib/graphql/float_type.rb +1 -1
  106. data/lib/graphql/function.rb +5 -30
  107. data/lib/graphql/id_type.rb +1 -1
  108. data/lib/graphql/input_object_type.rb +9 -25
  109. data/lib/graphql/int_type.rb +1 -1
  110. data/lib/graphql/integer_decoding_error.rb +17 -0
  111. data/lib/graphql/integer_encoding_error.rb +18 -2
  112. data/lib/graphql/interface_type.rb +10 -24
  113. data/lib/graphql/internal_representation/document.rb +2 -2
  114. data/lib/graphql/internal_representation/rewrite.rb +1 -1
  115. data/lib/graphql/internal_representation/scope.rb +2 -2
  116. data/lib/graphql/internal_representation/visit.rb +2 -2
  117. data/lib/graphql/introspection/base_object.rb +2 -5
  118. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  119. data/lib/graphql/introspection/directive_type.rb +12 -6
  120. data/lib/graphql/introspection/entry_points.rb +9 -9
  121. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  122. data/lib/graphql/introspection/field_type.rb +9 -5
  123. data/lib/graphql/introspection/input_value_type.rb +41 -11
  124. data/lib/graphql/introspection/introspection_query.rb +6 -92
  125. data/lib/graphql/introspection/schema_type.rb +12 -12
  126. data/lib/graphql/introspection/type_type.rb +27 -17
  127. data/lib/graphql/introspection.rb +99 -0
  128. data/lib/graphql/invalid_null_error.rb +18 -0
  129. data/lib/graphql/language/block_string.rb +20 -5
  130. data/lib/graphql/language/cache.rb +37 -0
  131. data/lib/graphql/language/definition_slice.rb +21 -10
  132. data/lib/graphql/language/document_from_schema_definition.rb +116 -63
  133. data/lib/graphql/language/lexer.rb +53 -27
  134. data/lib/graphql/language/lexer.rl +5 -3
  135. data/lib/graphql/language/nodes.rb +67 -93
  136. data/lib/graphql/language/parser.rb +929 -896
  137. data/lib/graphql/language/parser.y +125 -102
  138. data/lib/graphql/language/printer.rb +11 -2
  139. data/lib/graphql/language/sanitized_printer.rb +222 -0
  140. data/lib/graphql/language/token.rb +0 -4
  141. data/lib/graphql/language/visitor.rb +2 -2
  142. data/lib/graphql/language.rb +3 -1
  143. data/lib/graphql/name_validator.rb +2 -7
  144. data/lib/graphql/non_null_type.rb +0 -10
  145. data/lib/graphql/object_type.rb +47 -58
  146. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  147. data/lib/graphql/pagination/array_connection.rb +77 -0
  148. data/lib/graphql/pagination/connection.rb +226 -0
  149. data/lib/graphql/pagination/connections.rb +160 -0
  150. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  151. data/lib/graphql/pagination/relation_connection.rb +226 -0
  152. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  153. data/lib/graphql/pagination.rb +6 -0
  154. data/lib/graphql/parse_error.rb +0 -1
  155. data/lib/graphql/query/arguments.rb +6 -4
  156. data/lib/graphql/query/arguments_cache.rb +1 -2
  157. data/lib/graphql/query/context.rb +52 -7
  158. data/lib/graphql/query/executor.rb +0 -1
  159. data/lib/graphql/query/fingerprint.rb +26 -0
  160. data/lib/graphql/query/input_validation_result.rb +32 -6
  161. data/lib/graphql/query/literal_input.rb +31 -11
  162. data/lib/graphql/query/null_context.rb +24 -8
  163. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
  164. data/lib/graphql/query/serial_execution.rb +1 -0
  165. data/lib/graphql/query/validation_pipeline.rb +6 -4
  166. data/lib/graphql/query/variable_validation_error.rb +3 -3
  167. data/lib/graphql/query/variables.rb +50 -10
  168. data/lib/graphql/query.rb +77 -18
  169. data/lib/graphql/railtie.rb +9 -1
  170. data/lib/graphql/rake_task/validate.rb +3 -0
  171. data/lib/graphql/rake_task.rb +12 -9
  172. data/lib/graphql/relay/array_connection.rb +10 -12
  173. data/lib/graphql/relay/base_connection.rb +30 -13
  174. data/lib/graphql/relay/connection_instrumentation.rb +4 -4
  175. data/lib/graphql/relay/connection_type.rb +18 -4
  176. data/lib/graphql/relay/edge_type.rb +1 -0
  177. data/lib/graphql/relay/edges_instrumentation.rb +1 -2
  178. data/lib/graphql/relay/global_id_resolve.rb +1 -2
  179. data/lib/graphql/relay/mutation.rb +3 -87
  180. data/lib/graphql/relay/node.rb +3 -0
  181. data/lib/graphql/relay/page_info.rb +1 -1
  182. data/lib/graphql/relay/range_add.rb +27 -9
  183. data/lib/graphql/relay/relation_connection.rb +8 -10
  184. data/lib/graphql/relay/type_extensions.rb +2 -0
  185. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  186. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  187. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  188. data/lib/graphql/rubocop.rb +4 -0
  189. data/lib/graphql/scalar_type.rb +18 -60
  190. data/lib/graphql/schema/addition.rb +247 -0
  191. data/lib/graphql/schema/argument.rb +274 -18
  192. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  193. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  194. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  195. data/lib/graphql/schema/build_from_definition.rb +320 -219
  196. data/lib/graphql/schema/built_in_types.rb +5 -5
  197. data/lib/graphql/schema/default_type_error.rb +2 -0
  198. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  199. data/lib/graphql/schema/directive/feature.rb +1 -1
  200. data/lib/graphql/schema/directive/flagged.rb +57 -0
  201. data/lib/graphql/schema/directive/include.rb +2 -2
  202. data/lib/graphql/schema/directive/skip.rb +2 -2
  203. data/lib/graphql/schema/directive/transform.rb +14 -2
  204. data/lib/graphql/schema/directive.rb +130 -6
  205. data/lib/graphql/schema/enum.rb +121 -12
  206. data/lib/graphql/schema/enum_value.rb +24 -7
  207. data/lib/graphql/schema/field/connection_extension.rb +46 -20
  208. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  209. data/lib/graphql/schema/field.rb +465 -181
  210. data/lib/graphql/schema/field_extension.rb +89 -2
  211. data/lib/graphql/schema/find_inherited_value.rb +17 -1
  212. data/lib/graphql/schema/finder.rb +16 -14
  213. data/lib/graphql/schema/input_object.rb +172 -37
  214. data/lib/graphql/schema/interface.rb +39 -25
  215. data/lib/graphql/schema/introspection_system.rb +106 -38
  216. data/lib/graphql/schema/late_bound_type.rb +3 -2
  217. data/lib/graphql/schema/list.rb +65 -1
  218. data/lib/graphql/schema/loader.rb +145 -102
  219. data/lib/graphql/schema/member/accepts_definition.rb +15 -3
  220. data/lib/graphql/schema/member/base_dsl_methods.rb +34 -28
  221. data/lib/graphql/schema/member/build_type.rb +19 -8
  222. data/lib/graphql/schema/member/cached_graphql_definition.rb +34 -2
  223. data/lib/graphql/schema/member/has_arguments.rb +206 -13
  224. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  225. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  226. data/lib/graphql/schema/member/has_directives.rb +98 -0
  227. data/lib/graphql/schema/member/has_fields.rb +97 -32
  228. data/lib/graphql/schema/member/has_interfaces.rb +100 -0
  229. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  230. data/lib/graphql/schema/member/has_validators.rb +31 -0
  231. data/lib/graphql/schema/member/instrumentation.rb +0 -1
  232. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  233. data/lib/graphql/schema/member/validates_input.rb +33 -0
  234. data/lib/graphql/schema/member.rb +11 -0
  235. data/lib/graphql/schema/middleware_chain.rb +1 -1
  236. data/lib/graphql/schema/mutation.rb +4 -0
  237. data/lib/graphql/schema/non_null.rb +37 -1
  238. data/lib/graphql/schema/object.rb +51 -38
  239. data/lib/graphql/schema/possible_types.rb +9 -4
  240. data/lib/graphql/schema/printer.rb +16 -35
  241. data/lib/graphql/schema/relay_classic_mutation.rb +40 -4
  242. data/lib/graphql/schema/resolver/has_payload_type.rb +34 -4
  243. data/lib/graphql/schema/resolver.rb +133 -79
  244. data/lib/graphql/schema/scalar.rb +43 -3
  245. data/lib/graphql/schema/subscription.rb +57 -21
  246. data/lib/graphql/schema/timeout.rb +29 -15
  247. data/lib/graphql/schema/timeout_middleware.rb +3 -1
  248. data/lib/graphql/schema/traversal.rb +2 -2
  249. data/lib/graphql/schema/type_expression.rb +21 -13
  250. data/lib/graphql/schema/type_membership.rb +19 -5
  251. data/lib/graphql/schema/union.rb +44 -3
  252. data/lib/graphql/schema/unique_within_type.rb +1 -2
  253. data/lib/graphql/schema/validation.rb +14 -4
  254. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  255. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  256. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  257. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  258. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  259. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  260. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  261. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  262. data/lib/graphql/schema/validator.rb +171 -0
  263. data/lib/graphql/schema/warden.rb +193 -34
  264. data/lib/graphql/schema.rb +882 -247
  265. data/lib/graphql/static_validation/all_rules.rb +2 -0
  266. data/lib/graphql/static_validation/base_visitor.rb +17 -10
  267. data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
  268. data/lib/graphql/static_validation/error.rb +3 -1
  269. data/lib/graphql/static_validation/literal_validator.rb +51 -26
  270. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
  271. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  272. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  273. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  274. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  275. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -2
  276. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  277. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  278. data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
  279. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  280. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  281. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  282. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  283. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  284. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  285. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  286. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  287. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  288. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
  289. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  290. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  291. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  292. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  293. data/lib/graphql/static_validation/type_stack.rb +2 -2
  294. data/lib/graphql/static_validation/validation_context.rb +13 -3
  295. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  296. data/lib/graphql/static_validation/validator.rb +43 -9
  297. data/lib/graphql/static_validation.rb +1 -0
  298. data/lib/graphql/string_encoding_error.rb +13 -3
  299. data/lib/graphql/string_type.rb +1 -1
  300. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +123 -22
  301. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  302. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
  303. data/lib/graphql/subscriptions/event.rb +84 -30
  304. data/lib/graphql/subscriptions/instrumentation.rb +10 -6
  305. data/lib/graphql/subscriptions/serialize.rb +53 -6
  306. data/lib/graphql/subscriptions/subscription_root.rb +15 -5
  307. data/lib/graphql/subscriptions.rb +117 -49
  308. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  309. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  310. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  311. data/lib/graphql/tracing/data_dog_tracing.rb +32 -15
  312. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  313. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  314. data/lib/graphql/tracing/platform_tracing.rb +66 -10
  315. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  316. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  317. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  318. data/lib/graphql/tracing/skylight_tracing.rb +9 -1
  319. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  320. data/lib/graphql/tracing.rb +15 -35
  321. data/lib/graphql/types/big_int.rb +5 -1
  322. data/lib/graphql/types/int.rb +10 -3
  323. data/lib/graphql/types/iso_8601_date.rb +16 -8
  324. data/lib/graphql/types/iso_8601_date_time.rb +32 -10
  325. data/lib/graphql/types/relay/base_connection.rb +6 -88
  326. data/lib/graphql/types/relay/base_edge.rb +2 -34
  327. data/lib/graphql/types/relay/connection_behaviors.rb +174 -0
  328. data/lib/graphql/types/relay/default_relay.rb +31 -0
  329. data/lib/graphql/types/relay/edge_behaviors.rb +64 -0
  330. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  331. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  332. data/lib/graphql/types/relay/node.rb +2 -4
  333. data/lib/graphql/types/relay/node_behaviors.rb +15 -0
  334. data/lib/graphql/types/relay/node_field.rb +3 -22
  335. data/lib/graphql/types/relay/nodes_field.rb +16 -18
  336. data/lib/graphql/types/relay/page_info.rb +2 -14
  337. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  338. data/lib/graphql/types/relay.rb +11 -3
  339. data/lib/graphql/types/string.rb +8 -2
  340. data/lib/graphql/unauthorized_error.rb +2 -2
  341. data/lib/graphql/union_type.rb +5 -25
  342. data/lib/graphql/unresolved_type_error.rb +2 -2
  343. data/lib/graphql/upgrader/member.rb +1 -0
  344. data/lib/graphql/upgrader/schema.rb +1 -0
  345. data/lib/graphql/version.rb +1 -1
  346. data/lib/graphql.rb +87 -31
  347. data/readme.md +3 -6
  348. metadata +126 -124
  349. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  350. data/lib/graphql/literal_validation_error.rb +0 -6
  351. data/lib/graphql/types/relay/base_field.rb +0 -22
  352. data/lib/graphql/types/relay/base_interface.rb +0 -29
  353. data/lib/graphql/types/relay/base_object.rb +0 -26
@@ -9,8 +9,9 @@ module GraphQL
9
9
  include GraphQL::Dig
10
10
 
11
11
  def self.construct_arguments_class(argument_owner)
12
- argument_definitions = argument_owner.arguments
12
+ argument_definitions = argument_owner.arguments # rubocop:disable Development/ContextIsPassedCop -- legacy-related
13
13
  argument_owner.arguments_class = Class.new(self) do
14
+ self.argument_owner = argument_owner
14
15
  self.argument_definitions = argument_definitions
15
16
 
16
17
  argument_definitions.each do |_arg_name, arg_definition|
@@ -21,7 +22,7 @@ module GraphQL
21
22
  method_names.each do |method_name|
22
23
  # Don't define a helper method if it would override something.
23
24
  if method_defined?(method_name)
24
- warn(
25
+ GraphQL::Deprecation.warn(
25
26
  "Unable to define a helper for argument with name '#{method_name}' "\
26
27
  "as this is a reserved name. Add `method_access: false` to stop this warning."
27
28
  )
@@ -85,7 +86,8 @@ module GraphQL
85
86
  end
86
87
  end
87
88
 
88
- def_delegators :to_h, :keys, :values, :each, :any?
89
+ def_delegators :to_h, :keys, :values, :each
90
+ def_delegators :@argument_values, :any?
89
91
 
90
92
  def prepare
91
93
  self
@@ -101,7 +103,7 @@ module GraphQL
101
103
  end
102
104
 
103
105
  class << self
104
- attr_accessor :argument_definitions
106
+ attr_accessor :argument_definitions, :argument_owner
105
107
  end
106
108
 
107
109
  NoArguments = Class.new(self) do
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # test_via: ../query.rb
3
2
  module GraphQL
4
3
  class Query
5
4
  module ArgumentsCache
@@ -8,7 +7,7 @@ module GraphQL
8
7
  Hash.new do |h1, irep_or_ast_node|
9
8
  h1[irep_or_ast_node] = Hash.new do |h2, definition|
10
9
  ast_node = irep_or_ast_node.is_a?(GraphQL::InternalRepresentation::Node) ? irep_or_ast_node.ast_node : irep_or_ast_node
11
- h2[definition] = if definition.arguments.empty?
10
+ h2[definition] = if definition.arguments(query.context).empty?
12
11
  GraphQL::Query::Arguments::NO_ARGS
13
12
  else
14
13
  GraphQL::Query::LiteralInput.from_arguments(
@@ -1,6 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # test_via: ../execution/execute.rb
3
- # test_via: ../execution/lazy.rb
4
2
  module GraphQL
5
3
  class Query
6
4
  # Expose some query-specific info to field resolve functions.
@@ -34,7 +32,7 @@ module GraphQL
34
32
  # Remove this child from the result value
35
33
  # (used for null propagation and skip)
36
34
  # @api private
37
- def delete(child_ctx)
35
+ def delete_child(child_ctx)
38
36
  @value.delete(child_ctx.key)
39
37
  end
40
38
 
@@ -158,6 +156,15 @@ module GraphQL
158
156
  @scoped_context = {}
159
157
  end
160
158
 
159
+ # @return [Hash] A hash that will be added verbatim to the result hash, as `"extensions" => { ... }`
160
+ def response_extensions
161
+ namespace(:__query_result_extensions__)
162
+ end
163
+
164
+ def dataloader
165
+ @dataloader ||= self[:dataloader] || (query.multiplex ? query.multiplex.dataloader : schema.dataloader_class.new)
166
+ end
167
+
161
168
  # @api private
162
169
  attr_writer :interpreter
163
170
 
@@ -167,8 +174,10 @@ module GraphQL
167
174
  # @api private
168
175
  attr_accessor :scoped_context
169
176
 
170
- def_delegators :@provided_values, :[]=
171
- def_delegators :to_h, :fetch, :dig
177
+ def []=(key, value)
178
+ @provided_values[key] = value
179
+ end
180
+
172
181
  def_delegators :@query, :trace, :interpreter?
173
182
 
174
183
  # @!method []=(key, value)
@@ -180,6 +189,34 @@ module GraphQL
180
189
  @provided_values[key]
181
190
  end
182
191
 
192
+ def delete(key)
193
+ if @scoped_context.key?(key)
194
+ @scoped_context.delete(key)
195
+ else
196
+ @provided_values.delete(key)
197
+ end
198
+ end
199
+
200
+ UNSPECIFIED_FETCH_DEFAULT = Object.new
201
+
202
+ def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
203
+ if @scoped_context.key?(key)
204
+ @scoped_context[key]
205
+ elsif @provided_values.key?(key)
206
+ @provided_values[key]
207
+ elsif default != UNSPECIFIED_FETCH_DEFAULT
208
+ default
209
+ elsif block_given?
210
+ yield(self, key)
211
+ else
212
+ raise KeyError.new(key: key)
213
+ end
214
+ end
215
+
216
+ def dig(key, *other_keys)
217
+ @scoped_context.key?(key) ? @scoped_context.dig(key, *other_keys) : @provided_values.dig(key, *other_keys)
218
+ end
219
+
183
220
  def to_h
184
221
  @provided_values.merge(@scoped_context)
185
222
  end
@@ -191,9 +228,12 @@ module GraphQL
191
228
 
192
229
  # @return [GraphQL::Schema::Warden]
193
230
  def warden
194
- @warden ||= @query.warden
231
+ @warden ||= (@query && @query.warden)
195
232
  end
196
233
 
234
+ # @api private
235
+ attr_writer :warden
236
+
197
237
  # Get an isolated hash for `ns`. Doesn't affect user-provided storage.
198
238
  # @param ns [Object] a usage-specific namespace identifier
199
239
  # @return [Hash] namespaced storage
@@ -201,6 +241,11 @@ module GraphQL
201
241
  @storage[ns]
202
242
  end
203
243
 
244
+ # @return [Boolean] true if this namespace was accessed before
245
+ def namespace?(ns)
246
+ @storage.key?(ns)
247
+ end
248
+
204
249
  def inspect
205
250
  "#<Query::Context ...>"
206
251
  end
@@ -293,7 +338,7 @@ module GraphQL
293
338
  end
294
339
  when GraphQL::Execution::Execute::SKIP
295
340
  @parent.skipped = true
296
- @parent.delete(self)
341
+ @parent.delete_child(self)
297
342
  else
298
343
  @value = new_value
299
344
  end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # test_via: ../query.rb
3
2
  module GraphQL
4
3
  class Query
5
4
  class Executor
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest/sha2'
4
+
5
+ module GraphQL
6
+ class Query
7
+ # @api private
8
+ # @see Query#query_fingerprint
9
+ # @see Query#variables_fingerprint
10
+ # @see Query#fingerprint
11
+ module Fingerprint
12
+ # Make an obfuscated hash of the given string (either a query string or variables JSON)
13
+ # @param string [String]
14
+ # @return [String] A normalized, opaque hash
15
+ def self.generate(input_str)
16
+ # Implemented to be:
17
+ # - Short (and uniform) length
18
+ # - Stable
19
+ # - Irreversibly Opaque (don't want to leak variable values)
20
+ # - URL-friendly
21
+ bytes = Digest::SHA256.digest(input_str)
22
+ Base64.urlsafe_encode64(bytes)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -4,23 +4,49 @@ module GraphQL
4
4
  class InputValidationResult
5
5
  attr_accessor :problems
6
6
 
7
+ def self.from_problem(explanation, path = nil, extensions: nil, message: nil)
8
+ result = self.new
9
+ result.add_problem(explanation, path, extensions: extensions, message: message)
10
+ result
11
+ end
12
+
13
+ def initialize(valid: true, problems: nil)
14
+ @valid = valid
15
+ @problems = problems
16
+ end
17
+
7
18
  def valid?
8
- @problems.nil?
19
+ @valid
9
20
  end
10
21
 
11
- def add_problem(explanation, path = nil)
22
+ def add_problem(explanation, path = nil, extensions: nil, message: nil)
12
23
  @problems ||= []
13
- @problems.push({ "path" => path || [], "explanation" => explanation })
24
+ @valid = false
25
+ problem = { "path" => path || [], "explanation" => explanation }
26
+ if extensions
27
+ problem["extensions"] = extensions
28
+ end
29
+ if message
30
+ problem["message"] = message
31
+ end
32
+ @problems.push(problem)
14
33
  end
15
34
 
16
35
  def merge_result!(path, inner_result)
17
36
  return if inner_result.valid?
18
37
 
19
- inner_result.problems.each do |p|
20
- item_path = [path, *p["path"]]
21
- add_problem(p["explanation"], item_path)
38
+ if inner_result.problems
39
+ inner_result.problems.each do |p|
40
+ item_path = [path, *p["path"]]
41
+ add_problem(p["explanation"], item_path, message: p["message"], extensions: p["extensions"])
42
+ end
22
43
  end
44
+ # It could have been explicitly set on inner_result (if it had no problems)
45
+ @valid = false
23
46
  end
47
+
48
+ VALID = self.new
49
+ VALID.freeze
24
50
  end
25
51
  end
26
52
  end
@@ -12,8 +12,8 @@ module GraphQL
12
12
  when Language::Nodes::VariableIdentifier
13
13
  variables[ast_node.name]
14
14
  else
15
- case type
16
- when GraphQL::ScalarType
15
+ case type.kind.name
16
+ when "SCALAR"
17
17
  # TODO smell
18
18
  # This gets used for plain values during subscriber.trigger
19
19
  if variables
@@ -21,7 +21,7 @@ module GraphQL
21
21
  else
22
22
  type.coerce_isolated_input(ast_node)
23
23
  end
24
- when GraphQL::EnumType
24
+ when "ENUM"
25
25
  # TODO smell
26
26
  # This gets used for plain values sometimes
27
27
  v = ast_node.is_a?(GraphQL::Language::Nodes::Enum) ? ast_node.name : ast_node
@@ -30,18 +30,20 @@ module GraphQL
30
30
  else
31
31
  type.coerce_isolated_input(v)
32
32
  end
33
- when GraphQL::NonNullType
33
+ when "NON_NULL"
34
34
  LiteralInput.coerce(type.of_type, ast_node, variables)
35
- when GraphQL::ListType
35
+ when "LIST"
36
36
  if ast_node.is_a?(Array)
37
37
  ast_node.map { |element_ast| LiteralInput.coerce(type.of_type, element_ast, variables) }
38
38
  else
39
39
  [LiteralInput.coerce(type.of_type, ast_node, variables)]
40
40
  end
41
- when GraphQL::InputObjectType
41
+ when "INPUT_OBJECT"
42
42
  # TODO smell: handling AST vs handling plain Ruby
43
43
  next_args = ast_node.is_a?(Hash) ? ast_node : ast_node.arguments
44
44
  from_arguments(next_args, type, variables)
45
+ else
46
+ raise "Invariant: unexpected type to coerce to: #{type}"
45
47
  end
46
48
  end
47
49
  end
@@ -60,7 +62,7 @@ module GraphQL
60
62
  raise ArgumentError, "Unexpected ast_arguments: #{ast_arguments}"
61
63
  end
62
64
 
63
- argument_defns = argument_owner.arguments
65
+ argument_defns = argument_owner.arguments(context || GraphQL::Query::NullContext)
64
66
  argument_defns.each do |arg_name, arg_defn|
65
67
  ast_arg = indexed_arguments[arg_name]
66
68
  # First, check the argument in the AST.
@@ -78,7 +80,10 @@ module GraphQL
78
80
  if (!value_is_a_variable || (value_is_a_variable && variables.key?(arg_value.name)))
79
81
 
80
82
  value = coerce(arg_defn.type, arg_value, variables)
81
- value = arg_defn.prepare(value, context)
83
+ # Legacy `prepare` application
84
+ if arg_defn.is_a?(GraphQL::Argument)
85
+ value = arg_defn.prepare(value, context)
86
+ end
82
87
 
83
88
  if value.is_a?(GraphQL::ExecutionError)
84
89
  value.ast_node = ast_arg
@@ -98,7 +103,9 @@ module GraphQL
98
103
  defaults_used << arg_name
99
104
  # `context` isn't present when pre-calculating defaults
100
105
  if context
101
- value = arg_defn.prepare(value, context)
106
+ if arg_defn.is_a?(GraphQL::Argument)
107
+ value = arg_defn.prepare(value, context)
108
+ end
102
109
  if value.is_a?(GraphQL::ExecutionError)
103
110
  value.ast_node = ast_arg
104
111
  raise value
@@ -108,8 +115,21 @@ module GraphQL
108
115
  end
109
116
  end
110
117
 
111
- result = argument_owner.arguments_class.new(values_hash, context: context, defaults_used: defaults_used)
112
- result.prepare
118
+ if argument_owner.is_a?(Class) || argument_owner.is_a?(GraphQL::Schema::Field)
119
+ # A Schema::InputObject, Schema::GraphQL::Field, Schema::Directive, logic from Query::Arguments#to_kwargs
120
+ ruby_kwargs = {}
121
+ values_hash.each do |key, value|
122
+ ruby_kwargs[Schema::Member::BuildType.underscore(key).to_sym] = value
123
+ end
124
+ if argument_owner.is_a?(Class) && argument_owner < GraphQL::Schema::InputObject
125
+ argument_owner.new(ruby_kwargs: ruby_kwargs, context: context, defaults_used: defaults_used)
126
+ else
127
+ ruby_kwargs
128
+ end
129
+ else
130
+ result = argument_owner.arguments_class.new(values_hash, context: context, defaults_used: defaults_used)
131
+ result.prepare
132
+ end
113
133
  end
114
134
  end
115
135
  end
@@ -4,16 +4,28 @@ module GraphQL
4
4
  # This object can be `ctx` in places where there is no query
5
5
  class NullContext
6
6
  class NullWarden < GraphQL::Schema::Warden
7
- def visible?(t); true; end
8
- def visible_field?(t); true; end
9
- def visible_type?(t); true; end
7
+ def visible_field?(field, ctx); true; end
8
+ def visible_argument?(arg, ctx); true; end
9
+ def visible_type?(type, ctx); true; end
10
+ def visible_enum_value?(ev, ctx); true; end
11
+ def visible_type_membership?(tm, ctx); true; end
10
12
  end
11
13
 
12
- attr_reader :schema, :query, :warden
14
+ class NullQuery
15
+ def with_error_handling
16
+ yield
17
+ end
18
+ end
19
+
20
+ class NullSchema < GraphQL::Schema
21
+ end
22
+
23
+ attr_reader :schema, :query, :warden, :dataloader
13
24
 
14
25
  def initialize
15
- @query = nil
16
- @schema = GraphQL::Schema.new
26
+ @query = NullQuery.new
27
+ @dataloader = GraphQL::Dataloader::NullDataloader.new
28
+ @schema = NullSchema
17
29
  @warden = NullWarden.new(
18
30
  GraphQL::Filter.new,
19
31
  context: self,
@@ -23,16 +35,20 @@ module GraphQL
23
35
 
24
36
  def [](key); end
25
37
 
38
+ def interpreter?
39
+ true
40
+ end
41
+
26
42
  class << self
27
43
  extend Forwardable
28
44
 
29
45
  def [](key); end
30
46
 
31
47
  def instance
32
- @instance = self.new
48
+ @instance ||= self.new
33
49
  end
34
50
 
35
- def_delegators :instance, :query, :schema, :warden
51
+ def_delegators :instance, :query, :warden, :schema, :interpreter?, :dataloader
36
52
  end
37
53
  end
38
54
  end
@@ -81,7 +81,7 @@ module GraphQL
81
81
  # is added to the "errors" key.
82
82
  def get_raw_value
83
83
  begin
84
- @field_ctx.schema.middleware.invoke([parent_type, target, field, arguments, @field_ctx])
84
+ @field_ctx.schema.middleware.invoke([parent_type, target, field, arguments, @field_ctx]) # rubocop:disable Development/ContextIsPassedCop -- unrelated
85
85
  rescue GraphQL::ExecutionError => err
86
86
  err
87
87
  end
@@ -16,6 +16,7 @@ module GraphQL
16
16
  # @param query_object [GraphQL::Query] the query object for this execution
17
17
  # @return [Hash] a spec-compliant GraphQL result, as a hash
18
18
  def execute(ast_operation, root_type, query_object)
19
+ GraphQL::Deprecation.warn "#{self.class} will be removed in GraphQL-Ruby 2.0, please upgrade to the Interpreter: https://graphql-ruby.org/queries/interpreter.html"
19
20
  operation_resolution.resolve(
20
21
  query_object.irep_selection,
21
22
  root_type,
@@ -16,10 +16,9 @@ module GraphQL
16
16
  class ValidationPipeline
17
17
  attr_reader :max_depth, :max_complexity
18
18
 
19
- def initialize(query:, validate:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
19
+ def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
20
20
  @validation_errors = []
21
21
  @internal_representation = nil
22
- @validate = validate
23
22
  @parse_error = parse_error
24
23
  @operation_name_error = operation_name_error
25
24
  @query = query
@@ -36,7 +35,7 @@ module GraphQL
36
35
  @valid
37
36
  end
38
37
 
39
- # @return [Array<GraphQL::StaticValidation::Error >] Static validation errors for the query string
38
+ # @return [Array<GraphQL::StaticValidation::Error, GraphQL::Query::VariableValidationError>] Static validation errors for the query string
40
39
  def validation_errors
41
40
  ensure_has_validated
42
41
  @validation_errors
@@ -72,7 +71,7 @@ module GraphQL
72
71
  elsif @operation_name_error
73
72
  @validation_errors << @operation_name_error
74
73
  else
75
- validation_result = @schema.static_validator.validate(@query, validate: @validate)
74
+ validation_result = @schema.static_validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
76
75
  @validation_errors.concat(validation_result[:errors])
77
76
  @internal_representation = validation_result[:irep]
78
77
 
@@ -90,6 +89,9 @@ module GraphQL
90
89
  end
91
90
 
92
91
  @valid = @validation_errors.empty?
92
+ rescue SystemStackError => err
93
+ @valid = false
94
+ @schema.query_stack_error(@query, err)
93
95
  end
94
96
 
95
97
  # If there are max_* values, add them,
@@ -4,11 +4,11 @@ module GraphQL
4
4
  class VariableValidationError < GraphQL::ExecutionError
5
5
  attr_accessor :value, :validation_result
6
6
 
7
- def initialize(variable_ast, type, value, validation_result)
7
+ def initialize(variable_ast, type, value, validation_result, msg: nil)
8
8
  @value = value
9
9
  @validation_result = validation_result
10
10
 
11
- msg = "Variable #{variable_ast.name} of type #{type} was provided invalid value"
11
+ msg ||= "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
12
12
 
13
13
  if problem_fields.any?
14
14
  msg += " for #{problem_fields.join(", ")}"
@@ -23,7 +23,7 @@ module GraphQL
23
23
  # a one level deep merge explicitly. However beyond that only show the
24
24
  # latest value and problems.
25
25
  super.merge({ "extensions" => { "value" => value, "problems" => validation_result.problems }}) do |key, oldValue, newValue|
26
- if oldValue.respond_to? merge
26
+ if oldValue.respond_to?(:merge)
27
27
  oldValue.merge(newValue)
28
28
  else
29
29
  newValue
@@ -17,11 +17,15 @@ module GraphQL
17
17
  @provided_variables = GraphQL::Argument.deep_stringify(provided_variables)
18
18
  @errors = []
19
19
  @storage = ast_variables.each_with_object({}) do |ast_variable, memo|
20
+ if schema.validate_max_errors && schema.validate_max_errors <= @errors.count
21
+ add_max_errors_reached_message
22
+ break
23
+ end
20
24
  # Find the right value for this variable:
21
25
  # - First, use the value provided at runtime
22
26
  # - Then, fall back to the default value from the query string
23
27
  # If it's still nil, raise an error if it's required.
24
- variable_type = schema.type_from_ast(ast_variable.type)
28
+ variable_type = schema.type_from_ast(ast_variable.type, context: ctx)
25
29
  if variable_type.nil?
26
30
  # Pass -- it will get handled by a validator
27
31
  else
@@ -29,27 +33,40 @@ module GraphQL
29
33
  default_value = ast_variable.default_value
30
34
  provided_value = @provided_variables[variable_name]
31
35
  value_was_provided = @provided_variables.key?(variable_name)
32
-
36
+ max_errors = schema.validate_max_errors - @errors.count if schema.validate_max_errors
33
37
  begin
34
- validation_result = variable_type.validate_input(provided_value, ctx)
38
+ validation_result = variable_type.validate_input(provided_value, ctx, max_errors: max_errors)
35
39
  if validation_result.valid?
36
40
  if value_was_provided
37
41
  # Add the variable if a value was provided
38
- memo[variable_name] = schema.error_handler.with_error_handling(context) do
39
- variable_type.coerce_input(provided_value, ctx)
42
+ memo[variable_name] = if ctx.interpreter?
43
+ provided_value
44
+ elsif provided_value.nil?
45
+ nil
46
+ else
47
+ schema.error_handler.with_error_handling(context) do
48
+ variable_type.coerce_input(provided_value, ctx)
49
+ end
40
50
  end
41
51
  elsif default_value != nil
42
- # Add the variable if it wasn't provided but it has a default value (including `null`)
43
- memo[variable_name] = GraphQL::Query::LiteralInput.coerce(variable_type, default_value, self)
52
+ memo[variable_name] = if ctx.interpreter?
53
+ if default_value.is_a?(Language::Nodes::NullValue)
54
+ nil
55
+ else
56
+ default_value
57
+ end
58
+ else
59
+ # Add the variable if it wasn't provided but it has a default value (including `null`)
60
+ GraphQL::Query::LiteralInput.coerce(variable_type, default_value, self)
61
+ end
44
62
  end
45
63
  end
46
- rescue GraphQL::CoercionError, GraphQL::ExecutionError => ex
64
+ rescue GraphQL::ExecutionError => ex
47
65
  # TODO: This should really include the path to the problematic node in the variable value
48
66
  # like InputValidationResults generated by validate_non_null_input but unfortunately we don't
49
67
  # have this information available in the coerce_input call chain. Note this path is the path
50
68
  # that appears under errors.extensions.problems.path and NOT the result path under errors.path.
51
- validation_result = GraphQL::Query::InputValidationResult.new
52
- validation_result.add_problem(ex.message)
69
+ validation_result = GraphQL::Query::InputValidationResult.from_problem(ex.message)
53
70
  end
54
71
 
55
72
  if !validation_result.valid?
@@ -60,6 +77,29 @@ module GraphQL
60
77
  end
61
78
 
62
79
  def_delegators :@storage, :length, :key?, :[], :fetch, :to_h
80
+
81
+ private
82
+
83
+ def deep_stringify(val)
84
+ case val
85
+ when Array
86
+ val.map { |v| deep_stringify(v) }
87
+ when Hash
88
+ new_val = {}
89
+ val.each do |k, v|
90
+ new_val[k.to_s] = deep_stringify(v)
91
+ end
92
+ new_val
93
+ else
94
+ val
95
+ end
96
+ end
97
+
98
+ def add_max_errors_reached_message
99
+ message = "Too many errors processing variables, max validation error limit reached. Execution aborted"
100
+ validation_result = GraphQL::Query::InputValidationResult.from_problem(message)
101
+ errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
102
+ end
63
103
  end
64
104
  end
65
105
  end