graphql 1.10.2 → 2.0.21

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

Potentially problematic release.


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

Files changed (402) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +21 -10
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +45 -8
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/loader_generator.rb +1 -0
  12. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  14. data/lib/generators/graphql/mutation_generator.rb +6 -30
  15. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  16. data/lib/generators/graphql/object_generator.rb +28 -12
  17. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  18. data/lib/generators/graphql/relay.rb +49 -0
  19. data/lib/generators/graphql/relay_generator.rb +21 -0
  20. data/lib/generators/graphql/scalar_generator.rb +4 -2
  21. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  22. data/lib/generators/graphql/templates/base_connection.erb +8 -0
  23. data/lib/generators/graphql/templates/base_edge.erb +8 -0
  24. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  25. data/lib/generators/graphql/templates/base_field.erb +2 -0
  26. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  28. data/lib/generators/graphql/templates/base_object.erb +2 -0
  29. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  30. data/lib/generators/graphql/templates/base_union.erb +2 -0
  31. data/lib/generators/graphql/templates/enum.erb +7 -1
  32. data/lib/generators/graphql/templates/graphql_controller.erb +16 -12
  33. data/lib/generators/graphql/templates/input.erb +9 -0
  34. data/lib/generators/graphql/templates/interface.erb +6 -2
  35. data/lib/generators/graphql/templates/loader.erb +2 -0
  36. data/lib/generators/graphql/templates/mutation.erb +3 -1
  37. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  39. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  40. data/lib/generators/graphql/templates/node_type.erb +9 -0
  41. data/lib/generators/graphql/templates/object.erb +7 -3
  42. data/lib/generators/graphql/templates/query_type.erb +3 -3
  43. data/lib/generators/graphql/templates/scalar.erb +5 -1
  44. data/lib/generators/graphql/templates/schema.erb +24 -33
  45. data/lib/generators/graphql/templates/union.erb +6 -2
  46. data/lib/generators/graphql/type_generator.rb +47 -10
  47. data/lib/generators/graphql/union_generator.rb +5 -5
  48. data/lib/graphql/analysis/ast/field_usage.rb +30 -1
  49. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  50. data/lib/graphql/analysis/ast/query_complexity.rb +125 -117
  51. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  52. data/lib/graphql/analysis/ast/visitor.rb +52 -36
  53. data/lib/graphql/analysis/ast.rb +7 -8
  54. data/lib/graphql/analysis.rb +0 -7
  55. data/lib/graphql/backtrace/inspect_result.rb +0 -1
  56. data/lib/graphql/backtrace/table.rb +31 -18
  57. data/lib/graphql/backtrace/trace.rb +96 -0
  58. data/lib/graphql/backtrace/traced_error.rb +0 -1
  59. data/lib/graphql/backtrace/tracer.rb +39 -9
  60. data/lib/graphql/backtrace.rb +26 -18
  61. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  62. data/lib/graphql/dataloader/request.rb +19 -0
  63. data/lib/graphql/dataloader/request_all.rb +19 -0
  64. data/lib/graphql/dataloader/source.rb +164 -0
  65. data/lib/graphql/dataloader.rb +311 -0
  66. data/lib/graphql/date_encoding_error.rb +16 -0
  67. data/lib/graphql/deprecation.rb +9 -0
  68. data/lib/graphql/dig.rb +1 -1
  69. data/lib/graphql/execution/errors.rb +77 -44
  70. data/lib/graphql/execution/interpreter/argument_value.rb +28 -0
  71. data/lib/graphql/execution/interpreter/arguments.rb +88 -0
  72. data/lib/graphql/execution/interpreter/arguments_cache.rb +104 -0
  73. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  74. data/lib/graphql/execution/interpreter/resolve.rb +62 -24
  75. data/lib/graphql/execution/interpreter/runtime.rb +826 -464
  76. data/lib/graphql/execution/interpreter.rb +206 -68
  77. data/lib/graphql/execution/lazy.rb +11 -21
  78. data/lib/graphql/execution/lookahead.rb +55 -136
  79. data/lib/graphql/execution/multiplex.rb +6 -162
  80. data/lib/graphql/execution.rb +11 -4
  81. data/lib/graphql/filter.rb +7 -2
  82. data/lib/graphql/integer_decoding_error.rb +17 -0
  83. data/lib/graphql/integer_encoding_error.rb +18 -2
  84. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  85. data/lib/graphql/introspection/directive_type.rb +11 -5
  86. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  87. data/lib/graphql/introspection/entry_points.rb +4 -17
  88. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  89. data/lib/graphql/introspection/field_type.rb +9 -5
  90. data/lib/graphql/introspection/input_value_type.rb +15 -3
  91. data/lib/graphql/introspection/introspection_query.rb +6 -92
  92. data/lib/graphql/introspection/schema_type.rb +11 -6
  93. data/lib/graphql/introspection/type_type.rb +31 -14
  94. data/lib/graphql/introspection.rb +100 -0
  95. data/lib/graphql/invalid_null_error.rb +18 -0
  96. data/lib/graphql/language/block_string.rb +20 -5
  97. data/lib/graphql/language/cache.rb +37 -0
  98. data/lib/graphql/language/document_from_schema_definition.rb +96 -44
  99. data/lib/graphql/language/lexer.rb +216 -1462
  100. data/lib/graphql/language/nodes.rb +126 -129
  101. data/lib/graphql/language/parser.rb +997 -933
  102. data/lib/graphql/language/parser.y +148 -118
  103. data/lib/graphql/language/printer.rb +48 -23
  104. data/lib/graphql/language/sanitized_printer.rb +222 -0
  105. data/lib/graphql/language/token.rb +0 -4
  106. data/lib/graphql/language/visitor.rb +192 -84
  107. data/lib/graphql/language.rb +2 -0
  108. data/lib/graphql/name_validator.rb +2 -7
  109. data/lib/graphql/pagination/active_record_relation_connection.rb +45 -3
  110. data/lib/graphql/pagination/array_connection.rb +6 -4
  111. data/lib/graphql/pagination/connection.rb +105 -23
  112. data/lib/graphql/pagination/connections.rb +62 -35
  113. data/lib/graphql/pagination/relation_connection.rb +88 -36
  114. data/lib/graphql/parse_error.rb +0 -1
  115. data/lib/graphql/query/context.rb +203 -198
  116. data/lib/graphql/query/fingerprint.rb +26 -0
  117. data/lib/graphql/query/input_validation_result.rb +33 -7
  118. data/lib/graphql/query/null_context.rb +22 -9
  119. data/lib/graphql/query/validation_pipeline.rb +16 -38
  120. data/lib/graphql/query/variable_validation_error.rb +3 -3
  121. data/lib/graphql/query/variables.rb +36 -12
  122. data/lib/graphql/query.rb +92 -44
  123. data/lib/graphql/railtie.rb +6 -102
  124. data/lib/graphql/rake_task/validate.rb +1 -1
  125. data/lib/graphql/rake_task.rb +41 -10
  126. data/lib/graphql/relay/range_add.rb +17 -10
  127. data/lib/graphql/relay.rb +0 -15
  128. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  129. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  130. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  131. data/lib/graphql/rubocop.rb +4 -0
  132. data/lib/graphql/schema/addition.rb +245 -0
  133. data/lib/graphql/schema/argument.rb +250 -46
  134. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  135. data/lib/graphql/schema/build_from_definition/resolve_map.rb +3 -1
  136. data/lib/graphql/schema/build_from_definition.rb +243 -89
  137. data/lib/graphql/schema/directive/deprecated.rb +1 -1
  138. data/lib/graphql/schema/directive/feature.rb +1 -1
  139. data/lib/graphql/schema/directive/flagged.rb +57 -0
  140. data/lib/graphql/schema/directive/include.rb +1 -1
  141. data/lib/graphql/schema/directive/one_of.rb +12 -0
  142. data/lib/graphql/schema/directive/skip.rb +1 -1
  143. data/lib/graphql/schema/directive/transform.rb +14 -2
  144. data/lib/graphql/schema/directive.rb +108 -20
  145. data/lib/graphql/schema/enum.rb +105 -44
  146. data/lib/graphql/schema/enum_value.rb +15 -25
  147. data/lib/graphql/schema/field/connection_extension.rb +50 -30
  148. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  149. data/lib/graphql/schema/field.rb +476 -331
  150. data/lib/graphql/schema/field_extension.rb +86 -2
  151. data/lib/graphql/schema/find_inherited_value.rb +6 -8
  152. data/lib/graphql/schema/finder.rb +5 -5
  153. data/lib/graphql/schema/input_object.rb +133 -121
  154. data/lib/graphql/schema/interface.rb +17 -45
  155. data/lib/graphql/schema/introspection_system.rb +3 -8
  156. data/lib/graphql/schema/late_bound_type.rb +8 -2
  157. data/lib/graphql/schema/list.rb +25 -8
  158. data/lib/graphql/schema/loader.rb +139 -103
  159. data/lib/graphql/schema/member/base_dsl_methods.rb +29 -35
  160. data/lib/graphql/schema/member/build_type.rb +19 -14
  161. data/lib/graphql/schema/member/has_arguments.rb +310 -26
  162. data/lib/graphql/schema/member/has_ast_node.rb +16 -1
  163. data/lib/graphql/schema/member/has_deprecation_reason.rb +24 -0
  164. data/lib/graphql/schema/member/has_directives.rb +118 -0
  165. data/lib/graphql/schema/member/has_fields.rb +164 -42
  166. data/lib/graphql/schema/member/has_interfaces.rb +129 -0
  167. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  168. data/lib/graphql/schema/member/has_validators.rb +57 -0
  169. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  170. data/lib/graphql/schema/member/type_system_helpers.rb +20 -3
  171. data/lib/graphql/schema/member/validates_input.rb +3 -3
  172. data/lib/graphql/schema/member.rb +6 -6
  173. data/lib/graphql/schema/mutation.rb +4 -9
  174. data/lib/graphql/schema/non_null.rb +12 -7
  175. data/lib/graphql/schema/object.rb +35 -69
  176. data/lib/graphql/schema/printer.rb +16 -34
  177. data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
  178. data/lib/graphql/schema/resolver/has_payload_type.rb +51 -11
  179. data/lib/graphql/schema/resolver.rb +144 -79
  180. data/lib/graphql/schema/scalar.rb +27 -18
  181. data/lib/graphql/schema/subscription.rb +55 -26
  182. data/lib/graphql/schema/timeout.rb +45 -35
  183. data/lib/graphql/schema/type_expression.rb +1 -1
  184. data/lib/graphql/schema/type_membership.rb +21 -4
  185. data/lib/graphql/schema/union.rb +48 -13
  186. data/lib/graphql/schema/unique_within_type.rb +1 -2
  187. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  188. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  189. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  190. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  191. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  192. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  193. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  194. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  195. data/lib/graphql/schema/validator.rb +171 -0
  196. data/lib/graphql/schema/warden.rb +185 -32
  197. data/lib/graphql/schema/wrapper.rb +0 -5
  198. data/lib/graphql/schema.rb +471 -1116
  199. data/lib/graphql/static_validation/all_rules.rb +3 -0
  200. data/lib/graphql/static_validation/base_visitor.rb +13 -27
  201. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  202. data/lib/graphql/static_validation/error.rb +3 -1
  203. data/lib/graphql/static_validation/literal_validator.rb +69 -26
  204. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +44 -87
  205. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  206. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +28 -22
  207. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  208. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
  209. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
  210. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  211. data/lib/graphql/static_validation/rules/fields_will_merge.rb +92 -49
  212. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  213. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  214. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  215. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  216. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  217. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  218. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  219. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  220. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  221. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +6 -7
  222. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  223. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +9 -10
  224. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
  225. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
  226. data/lib/graphql/static_validation/validation_context.rb +13 -3
  227. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  228. data/lib/graphql/static_validation/validator.rb +32 -20
  229. data/lib/graphql/static_validation.rb +1 -2
  230. data/lib/graphql/string_encoding_error.rb +13 -3
  231. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +126 -19
  232. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  233. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  234. data/lib/graphql/subscriptions/event.rb +81 -35
  235. data/lib/graphql/subscriptions/instrumentation.rb +0 -52
  236. data/lib/graphql/subscriptions/serialize.rb +53 -6
  237. data/lib/graphql/subscriptions.rb +113 -58
  238. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  239. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -21
  240. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  241. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  242. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  243. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  244. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  245. data/lib/graphql/tracing/data_dog_tracing.rb +26 -2
  246. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  247. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  248. data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
  249. data/lib/graphql/tracing/notifications_trace.rb +42 -0
  250. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  251. data/lib/graphql/tracing/platform_trace.rb +109 -0
  252. data/lib/graphql/tracing/platform_tracing.rb +64 -43
  253. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  254. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +5 -2
  255. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  256. data/lib/graphql/tracing/scout_trace.rb +72 -0
  257. data/lib/graphql/tracing/scout_tracing.rb +11 -0
  258. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  259. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  260. data/lib/graphql/tracing/trace.rb +75 -0
  261. data/lib/graphql/tracing.rb +23 -71
  262. data/lib/graphql/type_kinds.rb +6 -3
  263. data/lib/graphql/types/big_int.rb +5 -1
  264. data/lib/graphql/types/int.rb +10 -3
  265. data/lib/graphql/types/iso_8601_date.rb +20 -9
  266. data/lib/graphql/types/iso_8601_date_time.rb +36 -10
  267. data/lib/graphql/types/relay/base_connection.rb +18 -92
  268. data/lib/graphql/types/relay/base_edge.rb +2 -34
  269. data/lib/graphql/types/relay/connection_behaviors.rb +176 -0
  270. data/lib/graphql/types/relay/edge_behaviors.rb +75 -0
  271. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  272. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  273. data/lib/graphql/types/relay/node.rb +2 -4
  274. data/lib/graphql/types/relay/node_behaviors.rb +25 -0
  275. data/lib/graphql/types/relay/page_info.rb +2 -14
  276. data/lib/graphql/types/relay/page_info_behaviors.rb +30 -0
  277. data/lib/graphql/types/relay.rb +10 -5
  278. data/lib/graphql/types/string.rb +8 -2
  279. data/lib/graphql/unauthorized_error.rb +2 -2
  280. data/lib/graphql/version.rb +1 -1
  281. data/lib/graphql.rb +54 -65
  282. data/readme.md +3 -6
  283. metadata +116 -236
  284. data/lib/graphql/analysis/analyze_query.rb +0 -91
  285. data/lib/graphql/analysis/field_usage.rb +0 -45
  286. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  287. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  288. data/lib/graphql/analysis/query_complexity.rb +0 -88
  289. data/lib/graphql/analysis/query_depth.rb +0 -43
  290. data/lib/graphql/analysis/reducer_state.rb +0 -48
  291. data/lib/graphql/argument.rb +0 -131
  292. data/lib/graphql/authorization.rb +0 -82
  293. data/lib/graphql/backwards_compatibility.rb +0 -60
  294. data/lib/graphql/base_type.rb +0 -230
  295. data/lib/graphql/boolean_type.rb +0 -2
  296. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  297. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  298. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  299. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  300. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  301. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  302. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  303. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  304. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  305. data/lib/graphql/compatibility.rb +0 -5
  306. data/lib/graphql/define/assign_argument.rb +0 -12
  307. data/lib/graphql/define/assign_connection.rb +0 -13
  308. data/lib/graphql/define/assign_enum_value.rb +0 -18
  309. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  310. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  311. data/lib/graphql/define/assign_object_field.rb +0 -42
  312. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  313. data/lib/graphql/define/instance_definable.rb +0 -210
  314. data/lib/graphql/define/no_definition_error.rb +0 -7
  315. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  316. data/lib/graphql/define/type_definer.rb +0 -31
  317. data/lib/graphql/define.rb +0 -31
  318. data/lib/graphql/deprecated_dsl.rb +0 -42
  319. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  320. data/lib/graphql/directive/include_directive.rb +0 -2
  321. data/lib/graphql/directive/skip_directive.rb +0 -2
  322. data/lib/graphql/directive.rb +0 -107
  323. data/lib/graphql/enum_type.rb +0 -127
  324. data/lib/graphql/execution/execute.rb +0 -326
  325. data/lib/graphql/execution/flatten.rb +0 -40
  326. data/lib/graphql/execution/instrumentation.rb +0 -92
  327. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  328. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  329. data/lib/graphql/execution/typecast.rb +0 -50
  330. data/lib/graphql/field/resolve.rb +0 -59
  331. data/lib/graphql/field.rb +0 -222
  332. data/lib/graphql/float_type.rb +0 -2
  333. data/lib/graphql/function.rb +0 -124
  334. data/lib/graphql/id_type.rb +0 -2
  335. data/lib/graphql/input_object_type.rb +0 -132
  336. data/lib/graphql/int_type.rb +0 -2
  337. data/lib/graphql/interface_type.rb +0 -65
  338. data/lib/graphql/internal_representation/document.rb +0 -27
  339. data/lib/graphql/internal_representation/node.rb +0 -206
  340. data/lib/graphql/internal_representation/print.rb +0 -51
  341. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  342. data/lib/graphql/internal_representation/scope.rb +0 -88
  343. data/lib/graphql/internal_representation/visit.rb +0 -36
  344. data/lib/graphql/internal_representation.rb +0 -7
  345. data/lib/graphql/language/lexer.rl +0 -258
  346. data/lib/graphql/list_type.rb +0 -80
  347. data/lib/graphql/literal_validation_error.rb +0 -6
  348. data/lib/graphql/non_null_type.rb +0 -71
  349. data/lib/graphql/object_type.rb +0 -121
  350. data/lib/graphql/query/arguments.rb +0 -188
  351. data/lib/graphql/query/arguments_cache.rb +0 -25
  352. data/lib/graphql/query/executor.rb +0 -53
  353. data/lib/graphql/query/literal_input.rb +0 -136
  354. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  355. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  356. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  357. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  358. data/lib/graphql/query/serial_execution.rb +0 -39
  359. data/lib/graphql/relay/array_connection.rb +0 -85
  360. data/lib/graphql/relay/base_connection.rb +0 -176
  361. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  362. data/lib/graphql/relay/connection_resolve.rb +0 -43
  363. data/lib/graphql/relay/connection_type.rb +0 -41
  364. data/lib/graphql/relay/edge.rb +0 -27
  365. data/lib/graphql/relay/edge_type.rb +0 -19
  366. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  367. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  368. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  369. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  370. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  371. data/lib/graphql/relay/mutation/result.rb +0 -38
  372. data/lib/graphql/relay/mutation.rb +0 -105
  373. data/lib/graphql/relay/node.rb +0 -36
  374. data/lib/graphql/relay/page_info.rb +0 -7
  375. data/lib/graphql/relay/relation_connection.rb +0 -190
  376. data/lib/graphql/relay/type_extensions.rb +0 -30
  377. data/lib/graphql/scalar_type.rb +0 -76
  378. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  379. data/lib/graphql/schema/default_parse_error.rb +0 -10
  380. data/lib/graphql/schema/default_type_error.rb +0 -15
  381. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  382. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  383. data/lib/graphql/schema/member/instrumentation.rb +0 -132
  384. data/lib/graphql/schema/middleware_chain.rb +0 -82
  385. data/lib/graphql/schema/possible_types.rb +0 -39
  386. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  387. data/lib/graphql/schema/timeout_middleware.rb +0 -86
  388. data/lib/graphql/schema/traversal.rb +0 -228
  389. data/lib/graphql/schema/validation.rb +0 -303
  390. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  391. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  392. data/lib/graphql/string_type.rb +0 -2
  393. data/lib/graphql/subscriptions/subscription_root.rb +0 -65
  394. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  395. data/lib/graphql/types/relay/base_field.rb +0 -22
  396. data/lib/graphql/types/relay/base_interface.rb +0 -29
  397. data/lib/graphql/types/relay/base_object.rb +0 -26
  398. data/lib/graphql/types/relay/node_field.rb +0 -43
  399. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  400. data/lib/graphql/union_type.rb +0 -113
  401. data/lib/graphql/upgrader/member.rb +0 -936
  402. data/lib/graphql/upgrader/schema.rb +0 -37
@@ -33,7 +33,10 @@ module GraphQL
33
33
  GraphQL::StaticValidation::VariablesAreUsedAndDefined,
34
34
  GraphQL::StaticValidation::VariableUsagesAreAllowed,
35
35
  GraphQL::StaticValidation::MutationRootExists,
36
+ GraphQL::StaticValidation::QueryRootExists,
36
37
  GraphQL::StaticValidation::SubscriptionRootExists,
38
+ GraphQL::StaticValidation::InputObjectNamesAreUnique,
39
+ GraphQL::StaticValidation::OneOfInputObjectsAreValid,
37
40
  ]
38
41
  end
39
42
  end
@@ -14,11 +14,6 @@ module GraphQL
14
14
  super(document)
15
15
  end
16
16
 
17
- # This will be overwritten by {InternalRepresentation::Rewrite} if it's included
18
- def rewrite_document
19
- nil
20
- end
21
-
22
17
  attr_reader :context
23
18
 
24
19
  # @return [Array<GraphQL::ObjectType>] Types whose scope we've entered
@@ -32,22 +27,13 @@ module GraphQL
32
27
  # Build a class to visit the AST and perform validation,
33
28
  # or use a pre-built class if rules is `ALL_RULES` or empty.
34
29
  # @param rules [Array<Module, Class>]
35
- # @param rewrite [Boolean] if `false`, don't include rewrite
36
30
  # @return [Class] A class for validating `rules` during visitation
37
- def self.including_rules(rules, rewrite: true)
31
+ def self.including_rules(rules)
38
32
  if rules.empty?
39
- if rewrite
40
- NoValidateVisitor
41
- else
42
- # It's not doing _anything?!?_
43
- BaseVisitor
44
- end
33
+ # It's not doing _anything?!?_
34
+ BaseVisitor
45
35
  elsif rules == ALL_RULES
46
- if rewrite
47
- DefaultVisitor
48
- else
49
- InterpreterVisitor
50
- end
36
+ InterpreterVisitor
51
37
  else
52
38
  visitor_class = Class.new(self) do
53
39
  include(GraphQL::StaticValidation::DefinitionDependencies)
@@ -60,9 +46,6 @@ module GraphQL
60
46
  end
61
47
  end
62
48
 
63
- if rewrite
64
- visitor_class.include(GraphQL::InternalRepresentation::Rewrite)
65
- end
66
49
  visitor_class.include(ContextMethods)
67
50
  visitor_class
68
51
  end
@@ -94,7 +77,7 @@ module GraphQL
94
77
 
95
78
  def on_field(node, parent)
96
79
  parent_type = @object_types.last
97
- field_definition = @schema.get_field(parent_type, node.name)
80
+ field_definition = @schema.get_field(parent_type, node.name, @context.query.context)
98
81
  @field_definitions.push(field_definition)
99
82
  if !field_definition.nil?
100
83
  next_object_type = field_definition.type.unwrap
@@ -110,7 +93,7 @@ module GraphQL
110
93
  end
111
94
 
112
95
  def on_directive(node, parent)
113
- directive_defn = @schema.directives[node.name]
96
+ directive_defn = @context.schema_directives[node.name]
114
97
  @directive_definitions.push(directive_defn)
115
98
  super
116
99
  @directive_definitions.pop
@@ -120,14 +103,14 @@ module GraphQL
120
103
  argument_defn = if (arg = @argument_definitions.last)
121
104
  arg_type = arg.type.unwrap
122
105
  if arg_type.kind.input_object?
123
- arg_type.arguments[node.name]
106
+ @context.warden.get_argument(arg_type, node.name)
124
107
  else
125
108
  nil
126
109
  end
127
110
  elsif (directive_defn = @directive_definitions.last)
128
- directive_defn.arguments[node.name]
111
+ @context.warden.get_argument(directive_defn, node.name)
129
112
  elsif (field_defn = @field_definitions.last)
130
- field_defn.arguments[node.name]
113
+ @context.warden.get_argument(field_defn, node.name)
131
114
  else
132
115
  nil
133
116
  end
@@ -187,7 +170,7 @@ module GraphQL
187
170
 
188
171
  def on_fragment_with_type(node)
189
172
  object_type = if node.type
190
- @schema.get_type(node.type.name)
173
+ @context.warden.get_type(node.type.name)
191
174
  else
192
175
  @object_types.last
193
176
  end
@@ -205,6 +188,9 @@ module GraphQL
205
188
  private
206
189
 
207
190
  def add_error(error, path: nil)
191
+ if @context.too_many_errors?
192
+ throw :too_many_validation_errors
193
+ end
208
194
  error.path ||= (path || @path.dup)
209
195
  context.errors << error
210
196
  end
@@ -70,7 +70,6 @@ module GraphQL
70
70
  @dependency_map ||= resolve_dependencies(&block)
71
71
  end
72
72
 
73
-
74
73
  # Map definition AST nodes to the definition AST nodes they depend on.
75
74
  # Expose circular dependencies.
76
75
  class DependencyMap
@@ -128,8 +127,14 @@ module GraphQL
128
127
  # same name as if they were the same name. If _any_ of the fragments
129
128
  # with that name has a dependency, we record it.
130
129
  independent_fragment_nodes = @defdep_fragment_definitions.values.flatten - @defdep_immediate_dependencies.keys
131
-
130
+ visited_fragment_names = Set.new
132
131
  while fragment_node = independent_fragment_nodes.pop
132
+ if visited_fragment_names.add?(fragment_node.name)
133
+ # this is a new fragment name
134
+ else
135
+ # this is a duplicate fragment name
136
+ next
137
+ end
133
138
  loops += 1
134
139
  if loops > max_loops
135
140
  raise("Resolution loops exceeded the number of definitions; infinite loop detected. (Max: #{max_loops}, Current: #{loops})")
@@ -30,10 +30,12 @@ module GraphQL
30
30
  }.tap { |h| h["path"] = path unless path.nil? }
31
31
  end
32
32
 
33
+ attr_reader :nodes
34
+
33
35
  private
34
36
 
35
37
  def locations
36
- @nodes.map do |node|
38
+ nodes.map do |node|
37
39
  h = {"line" => node.line, "column" => node.col}
38
40
  h["filename"] = node.filename if node.filename
39
41
  h
@@ -6,59 +6,87 @@ module GraphQL
6
6
  def initialize(context:)
7
7
  @context = context
8
8
  @warden = context.warden
9
+ @invalid_response = GraphQL::Query::InputValidationResult.new(valid: false, problems: [])
10
+ @valid_response = GraphQL::Query::InputValidationResult.new(valid: true, problems: [])
9
11
  end
10
12
 
11
13
  def validate(ast_value, type)
14
+ catch(:invalid) do
15
+ recursively_validate(ast_value, type)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def replace_nulls_in(ast_value)
22
+ case ast_value
23
+ when Array
24
+ ast_value.map { |v| replace_nulls_in(v) }
25
+ when GraphQL::Language::Nodes::InputObject
26
+ ast_value.to_h
27
+ when GraphQL::Language::Nodes::NullValue
28
+ nil
29
+ else
30
+ ast_value
31
+ end
32
+ end
33
+
34
+ def recursively_validate(ast_value, type)
12
35
  if type.nil?
13
36
  # this means we're an undefined argument, see #present_input_field_values_are_valid
14
37
  maybe_raise_if_invalid(ast_value) do
15
- false
38
+ @invalid_response
16
39
  end
17
40
  elsif ast_value.is_a?(GraphQL::Language::Nodes::NullValue)
18
41
  maybe_raise_if_invalid(ast_value) do
19
- !type.kind.non_null?
42
+ type.kind.non_null? ? @invalid_response : @valid_response
20
43
  end
21
44
  elsif type.kind.non_null?
22
45
  maybe_raise_if_invalid(ast_value) do
23
- (!ast_value.nil?)
24
- end && validate(ast_value, type.of_type)
46
+ ast_value.nil? ?
47
+ @invalid_response :
48
+ recursively_validate(ast_value, type.of_type)
49
+ end
25
50
  elsif type.kind.list?
26
51
  item_type = type.of_type
27
- ensure_array(ast_value).all? { |val| validate(val, item_type) }
52
+ results = ensure_array(ast_value).map { |val| recursively_validate(val, item_type) }
53
+ merge_results(results)
28
54
  elsif ast_value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
29
- true
55
+ @valid_response
30
56
  elsif type.kind.scalar? && constant_scalar?(ast_value)
31
57
  maybe_raise_if_invalid(ast_value) do
32
- type.valid_input?(ast_value, @context)
58
+ ruby_value = replace_nulls_in(ast_value)
59
+ type.validate_input(ruby_value, @context)
33
60
  end
34
61
  elsif type.kind.enum?
35
62
  maybe_raise_if_invalid(ast_value) do
36
63
  if ast_value.is_a?(GraphQL::Language::Nodes::Enum)
37
- type.valid_input?(ast_value.name, @context)
64
+ type.validate_input(ast_value.name, @context)
38
65
  else
39
66
  # if our ast_value isn't an Enum it's going to be invalid so return false
40
- false
67
+ @invalid_response
41
68
  end
42
69
  end
43
70
  elsif type.kind.input_object? && ast_value.is_a?(GraphQL::Language::Nodes::InputObject)
44
71
  maybe_raise_if_invalid(ast_value) do
45
- required_input_fields_are_present(type, ast_value) && present_input_field_values_are_valid(type, ast_value)
72
+ merge_results([
73
+ required_input_fields_are_present(type, ast_value),
74
+ present_input_field_values_are_valid(type, ast_value)
75
+ ])
46
76
  end
47
77
  else
48
78
  maybe_raise_if_invalid(ast_value) do
49
- false
79
+ @invalid_response
50
80
  end
51
81
  end
52
82
  end
53
83
 
54
- private
55
-
84
+ # When `error_bubbling` is false, we want to bail on the first failure that we find.
85
+ # Use `throw` to escape the current call stack, returning the invalid response.
56
86
  def maybe_raise_if_invalid(ast_value)
57
87
  ret = yield
58
- if !@context.schema.error_bubbling && !ret
59
- e = LiteralValidationError.new
60
- e.ast_value = ast_value
61
- raise e
88
+ if !@context.schema.error_bubbling && !ret.valid?
89
+ throw(:invalid, ret)
62
90
  else
63
91
  ret
64
92
  end
@@ -82,33 +110,48 @@ module GraphQL
82
110
  # TODO - would be nice to use these to create an error message so the caller knows
83
111
  # that required fields are missing
84
112
  required_field_names = @warden.arguments(type)
85
- .select { |f| f.type.kind.non_null? }
113
+ .select { |argument| argument.type.kind.non_null? && @warden.get_argument(type, argument.name) }
86
114
  .map(&:name)
115
+
87
116
  present_field_names = ast_node.arguments.map(&:name)
88
117
  missing_required_field_names = required_field_names - present_field_names
89
118
  if @context.schema.error_bubbling
90
- missing_required_field_names.empty?
119
+ missing_required_field_names.empty? ? @valid_response : @invalid_response
91
120
  else
92
- missing_required_field_names.all? do |name|
93
- validate(GraphQL::Language::Nodes::NullValue.new(name: name), @warden.arguments(type).find { |f| f.name == name }.type )
121
+ results = missing_required_field_names.map do |name|
122
+ arg_type = @warden.get_argument(type, name).type
123
+ recursively_validate(GraphQL::Language::Nodes::NullValue.new(name: name), arg_type)
94
124
  end
125
+
126
+ if type.one_of? && ast_node.arguments.size != 1
127
+ results << Query::InputValidationResult.from_problem("`#{type.graphql_name}` is a OneOf type, so only one argument may be given (instead of #{ast_node.arguments.size})")
128
+ end
129
+ merge_results(results)
95
130
  end
96
131
  end
97
132
 
98
133
  def present_input_field_values_are_valid(type, ast_node)
99
- field_map = @warden.arguments(type).reduce({}) { |m, f| m[f.name] = f; m}
100
- ast_node.arguments.all? do |value|
101
- field = field_map[value.name]
134
+ results = ast_node.arguments.map do |value|
135
+ field = @warden.get_argument(type, value.name)
102
136
  # we want to call validate on an argument even if it's an invalid one
103
137
  # so that our raise exception is on it instead of the entire InputObject
104
- type = field && field.type
105
- validate(value.value, type)
138
+ field_type = field && field.type
139
+ recursively_validate(value.value, field_type)
106
140
  end
141
+ merge_results(results)
107
142
  end
108
143
 
109
144
  def ensure_array(value)
110
145
  value.is_a?(Array) ? value : [value]
111
146
  end
147
+
148
+ def merge_results(results_list)
149
+ merged_result = Query::InputValidationResult.new
150
+ results_list.each do |inner_result|
151
+ merged_result.merge_result!([], inner_result)
152
+ end
153
+ merged_result
154
+ end
112
155
  end
113
156
  end
114
157
  end
@@ -2,108 +2,65 @@
2
2
  module GraphQL
3
3
  module StaticValidation
4
4
  module ArgumentLiteralsAreCompatible
5
- # TODO dedup with ArgumentsAreDefined
6
5
  def on_argument(node, parent)
7
- parent_defn = case parent
8
- when GraphQL::Language::Nodes::InputObject
9
- arg_defn = context.argument_definition
10
- if arg_defn.nil?
11
- nil
12
- else
13
- arg_ret_type = arg_defn.type.unwrap
14
- if !arg_ret_type.kind.input_object?
15
- nil
16
- else
17
- arg_ret_type
18
- end
19
- end
20
- when GraphQL::Language::Nodes::Directive
21
- context.schema.directives[parent.name]
22
- when GraphQL::Language::Nodes::Field
23
- context.field_definition
24
- else
25
- raise "Unexpected argument parent: #{parent.class} (##{parent})"
6
+ # Check the child arguments first;
7
+ # don't add a new error if one of them reports an error
8
+ super
9
+
10
+ # Don't validate variables here
11
+ if node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
12
+ return
26
13
  end
27
14
 
28
- if parent_defn && !node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
29
- arg_defn = parent_defn.arguments[node.name]
30
- if arg_defn
31
- begin
32
- valid = context.valid_literal?(node.value, arg_defn.type)
33
- rescue GraphQL::CoercionError => err
34
- context.schema.error_bubbling
35
- if !context.schema.error_bubbling && !arg_defn.type.unwrap.kind.scalar?
36
- # if error bubbling is disabled and the arg that caused this error isn't a scalar then
37
- # short-circuit here so we avoid bubbling this up to whatever input_object / array contains us
38
- return super
39
- end
40
- error = GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(err.message, nodes: parent, type: "CoercionError", extensions: err.extensions)
41
- rescue GraphQL::LiteralValidationError => err
42
- # check to see if the ast node that caused the error to be raised is
43
- # the same as the node we were checking here.
44
- arg_type = arg_defn.type
45
- if arg_type.kind.non_null?
46
- arg_type = arg_type.of_type
47
- end
15
+ if @context.schema.error_bubbling || context.errors.none? { |err| err.path.take(@path.size) == @path }
16
+ parent_defn = parent_definition(parent)
48
17
 
49
- matched = if arg_type.kind.list?
50
- # for a list we claim an error if the node is contained in our list
51
- Array(node.value).include?(err.ast_value)
52
- elsif arg_type.kind.input_object? && node.value.is_a?(GraphQL::Language::Nodes::InputObject)
53
- # for an input object we check the arguments
54
- node.value.arguments.include?(err.ast_value)
18
+ if parent_defn && (arg_defn = context.warden.get_argument(parent_defn, node.name))
19
+ validation_result = context.validate_literal(node.value, arg_defn.type)
20
+ if !validation_result.valid?
21
+ kind_of_node = node_type(parent)
22
+ error_arg_name = parent_name(parent, parent_defn)
23
+ string_value = if node.value == Float::INFINITY
24
+ ""
55
25
  else
56
- # otherwise we just check equality
57
- node.value == err.ast_value
26
+ " (#{GraphQL::Language::Printer.new.print(node.value)})"
58
27
  end
59
- if !matched
60
- # This node isn't the node that caused the error,
61
- # So halt this visit but continue visiting the rest of the tree
62
- return super
63
- end
64
- end
65
28
 
66
- if !valid
67
- error ||= begin
68
- kind_of_node = node_type(parent)
69
- error_arg_name = parent_name(parent, parent_defn)
70
- string_value = if node.value == Float::INFINITY
71
- ""
72
- else
73
- " (#{GraphQL::Language::Printer.new.print(node.value)})"
29
+ problems = validation_result.problems
30
+ first_problem = problems && problems.first
31
+ if first_problem
32
+ message = first_problem["message"]
33
+ # This is some legacy stuff from when `CoercionError` was raised thru the stack
34
+ if message
35
+ coerce_extensions = first_problem["extensions"] || {
36
+ "code" => "argumentLiteralsIncompatible"
37
+ }
74
38
  end
75
-
76
- GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(
77
- "Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value#{string_value}. Expected type '#{arg_defn.type.to_type_signature}'.",
78
- nodes: parent,
79
- type: kind_of_node,
80
- argument: node.name
81
- )
82
39
  end
83
- add_error(error)
84
- end
85
- end
86
- end
87
40
 
88
- super
89
- end
41
+ error_options = {
42
+ nodes: parent,
43
+ type: kind_of_node,
44
+ argument_name: node.name,
45
+ argument: arg_defn,
46
+ value: node.value
47
+ }
48
+ if coerce_extensions
49
+ error_options[:coerce_extensions] = coerce_extensions
50
+ end
90
51
 
52
+ message ||= "Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value#{string_value}. Expected type '#{arg_defn.type.to_type_signature}'."
91
53
 
92
- private
54
+ error = GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(
55
+ message,
56
+ **error_options
57
+ )
93
58
 
94
- def parent_name(parent, type_defn)
95
- if parent.is_a?(GraphQL::Language::Nodes::Field)
96
- parent.alias || parent.name
97
- elsif parent.is_a?(GraphQL::Language::Nodes::InputObject)
98
- type_defn.name
99
- else
100
- parent.graphql_name
59
+ add_error(error)
60
+ end
61
+ end
101
62
  end
102
63
  end
103
-
104
- def node_type(parent)
105
- parent.class.name.split("::").last
106
- end
107
64
  end
108
65
  end
109
66
  end
@@ -4,20 +4,36 @@ module GraphQL
4
4
  class ArgumentLiteralsAreCompatibleError < StaticValidation::Error
5
5
  attr_reader :type_name
6
6
  attr_reader :argument_name
7
+ attr_reader :argument
8
+ attr_reader :value
7
9
 
8
- def initialize(message, path: nil, nodes: [], type:, argument: nil, extensions: nil)
10
+ def initialize(message, path: nil, nodes: [], type:, argument_name: nil, extensions: nil, coerce_extensions: nil, argument: nil, value: nil)
9
11
  super(message, path: path, nodes: nodes)
10
12
  @type_name = type
11
- @argument_name = argument
13
+ @argument_name = argument_name
12
14
  @extensions = extensions
15
+ @coerce_extensions = coerce_extensions
16
+ @argument = argument
17
+ @value = value
13
18
  end
14
19
 
15
20
  # A hash representation of this Message
16
21
  def to_h
17
- extensions = {
18
- "code" => code,
19
- "typeName" => type_name
20
- }.tap { |h| h["argumentName"] = argument_name unless argument_name.nil? }
22
+ if @coerce_extensions
23
+ extensions = @coerce_extensions
24
+ # This is for legacy compat -- but this key is supposed to be a GraphQL type name :confounded:
25
+ extensions["typeName"] = "CoercionError"
26
+ else
27
+ extensions = {
28
+ "code" => code,
29
+ "typeName" => type_name
30
+ }
31
+
32
+ if argument_name
33
+ extensions["argumentName"] = argument_name
34
+ end
35
+ end
36
+
21
37
  extensions.merge!(@extensions) unless @extensions.nil?
22
38
  super.merge({
23
39
  "extensions" => extensions
@@ -3,28 +3,9 @@ module GraphQL
3
3
  module StaticValidation
4
4
  module ArgumentsAreDefined
5
5
  def on_argument(node, parent)
6
- parent_defn = case parent
7
- when GraphQL::Language::Nodes::InputObject
8
- arg_defn = context.argument_definition
9
- if arg_defn.nil?
10
- nil
11
- else
12
- arg_ret_type = arg_defn.type.unwrap
13
- if arg_ret_type.kind.input_object?
14
- arg_ret_type
15
- else
16
- nil
17
- end
18
- end
19
- when GraphQL::Language::Nodes::Directive
20
- context.schema.directives[parent.name]
21
- when GraphQL::Language::Nodes::Field
22
- context.field_definition
23
- else
24
- raise "Unexpected argument parent: #{parent.class} (##{parent})"
25
- end
6
+ parent_defn = parent_definition(parent)
26
7
 
27
- if parent_defn && context.warden.arguments(parent_defn).any? { |arg| arg.name == node.name }
8
+ if parent_defn && context.warden.get_argument(parent_defn, node.name)
28
9
  super
29
10
  elsif parent_defn
30
11
  kind_of_node = node_type(parent)
@@ -34,7 +15,8 @@ module GraphQL
34
15
  nodes: node,
35
16
  name: error_arg_name,
36
17
  type: kind_of_node,
37
- argument: node.name
18
+ argument_name: node.name,
19
+ parent: parent_defn
38
20
  ))
39
21
  else
40
22
  # Some other weird error
@@ -44,6 +26,7 @@ module GraphQL
44
26
 
45
27
  private
46
28
 
29
+ # TODO smell: these methods are added to all visitors, since they're included in a module.
47
30
  def parent_name(parent, type_defn)
48
31
  case parent
49
32
  when GraphQL::Language::Nodes::Field
@@ -60,6 +43,29 @@ module GraphQL
60
43
  def node_type(parent)
61
44
  parent.class.name.split("::").last
62
45
  end
46
+
47
+ def parent_definition(parent)
48
+ case parent
49
+ when GraphQL::Language::Nodes::InputObject
50
+ arg_defn = context.argument_definition
51
+ if arg_defn.nil?
52
+ nil
53
+ else
54
+ arg_ret_type = arg_defn.type.unwrap
55
+ if arg_ret_type.kind.input_object?
56
+ arg_ret_type
57
+ else
58
+ nil
59
+ end
60
+ end
61
+ when GraphQL::Language::Nodes::Directive
62
+ context.schema_directives[parent.name]
63
+ when GraphQL::Language::Nodes::Field
64
+ context.field_definition
65
+ else
66
+ raise "Unexpected argument parent: #{parent.class} (##{parent})"
67
+ end
68
+ end
63
69
  end
64
70
  end
65
71
  end
@@ -5,12 +5,14 @@ module GraphQL
5
5
  attr_reader :name
6
6
  attr_reader :type_name
7
7
  attr_reader :argument_name
8
+ attr_reader :parent
8
9
 
9
- def initialize(message, path: nil, nodes: [], name:, type:, argument:)
10
+ def initialize(message, path: nil, nodes: [], name:, type:, argument_name:, parent:)
10
11
  super(message, path: path, nodes: nodes)
11
12
  @name = name
12
13
  @type_name = type
13
- @argument_name = argument
14
+ @argument_name = argument_name
15
+ @parent = parent
14
16
  end
15
17
 
16
18
  # A hash representation of this Message
@@ -4,16 +4,22 @@ module GraphQL
4
4
  module DirectivesAreDefined
5
5
  def initialize(*)
6
6
  super
7
- @directive_names = context.schema.directives.keys
7
+ @directive_names = context.warden.directives.map(&:graphql_name)
8
8
  end
9
9
 
10
10
  def on_directive(node, parent)
11
11
  if !@directive_names.include?(node.name)
12
- add_error(GraphQL::StaticValidation::DirectivesAreDefinedError.new(
13
- "Directive @#{node.name} is not defined",
14
- nodes: node,
15
- directive: node.name
16
- ))
12
+ @directives_are_defined_errors_by_name ||= {}
13
+ error = @directives_are_defined_errors_by_name[node.name] ||= begin
14
+ err = GraphQL::StaticValidation::DirectivesAreDefinedError.new(
15
+ "Directive @#{node.name} is not defined",
16
+ nodes: [],
17
+ directive: node.name
18
+ )
19
+ add_error(err)
20
+ err
21
+ end
22
+ error.nodes << node
17
23
  else
18
24
  super
19
25
  end