graphql 1.12.12 → 2.4.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (428) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +3 -8
  3. data/lib/generators/graphql/enum_generator.rb +4 -10
  4. data/lib/generators/graphql/field_extractor.rb +31 -0
  5. data/lib/generators/graphql/input_generator.rb +50 -0
  6. data/lib/generators/graphql/install/mutation_root_generator.rb +34 -0
  7. data/lib/generators/graphql/{templates → install/templates}/base_mutation.erb +2 -0
  8. data/lib/generators/graphql/{templates → install/templates}/mutation_type.erb +2 -0
  9. data/lib/generators/graphql/install_generator.rb +60 -4
  10. data/lib/generators/graphql/interface_generator.rb +7 -7
  11. data/lib/generators/graphql/mutation_create_generator.rb +22 -0
  12. data/lib/generators/graphql/mutation_delete_generator.rb +22 -0
  13. data/lib/generators/graphql/mutation_generator.rb +5 -30
  14. data/lib/generators/graphql/mutation_update_generator.rb +22 -0
  15. data/lib/generators/graphql/object_generator.rb +10 -38
  16. data/lib/generators/graphql/orm_mutations_base.rb +40 -0
  17. data/lib/generators/graphql/relay.rb +23 -12
  18. data/lib/generators/graphql/scalar_generator.rb +4 -2
  19. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  20. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  21. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  22. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  23. data/lib/generators/graphql/templates/base_field.erb +2 -0
  24. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  25. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  26. data/lib/generators/graphql/templates/base_object.erb +2 -0
  27. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  28. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  29. data/lib/generators/graphql/templates/base_union.erb +2 -0
  30. data/lib/generators/graphql/templates/enum.erb +5 -1
  31. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  32. data/lib/generators/graphql/templates/input.erb +9 -0
  33. data/lib/generators/graphql/templates/interface.erb +4 -2
  34. data/lib/generators/graphql/templates/loader.erb +2 -0
  35. data/lib/generators/graphql/templates/mutation.erb +3 -1
  36. data/lib/generators/graphql/templates/mutation_create.erb +20 -0
  37. data/lib/generators/graphql/templates/mutation_delete.erb +20 -0
  38. data/lib/generators/graphql/templates/mutation_update.erb +21 -0
  39. data/lib/generators/graphql/templates/node_type.erb +2 -0
  40. data/lib/generators/graphql/templates/object.erb +4 -2
  41. data/lib/generators/graphql/templates/query_type.erb +2 -0
  42. data/lib/generators/graphql/templates/scalar.erb +3 -1
  43. data/lib/generators/graphql/templates/schema.erb +22 -2
  44. data/lib/generators/graphql/templates/union.erb +4 -2
  45. data/lib/generators/graphql/type_generator.rb +46 -10
  46. data/lib/generators/graphql/union_generator.rb +5 -5
  47. data/lib/graphql/analysis/analyzer.rb +89 -0
  48. data/lib/graphql/analysis/field_usage.rb +65 -28
  49. data/lib/graphql/analysis/max_query_complexity.rb +11 -17
  50. data/lib/graphql/analysis/max_query_depth.rb +13 -19
  51. data/lib/graphql/analysis/query_complexity.rb +156 -61
  52. data/lib/graphql/analysis/query_depth.rb +38 -23
  53. data/lib/graphql/analysis/visitor.rb +283 -0
  54. data/lib/graphql/analysis.rb +90 -6
  55. data/lib/graphql/autoload.rb +38 -0
  56. data/lib/graphql/backtrace/inspect_result.rb +0 -12
  57. data/lib/graphql/backtrace/table.rb +4 -22
  58. data/lib/graphql/backtrace/trace.rb +93 -0
  59. data/lib/graphql/backtrace/tracer.rb +8 -6
  60. data/lib/graphql/backtrace.rb +3 -8
  61. data/lib/graphql/coercion_error.rb +1 -9
  62. data/lib/graphql/current.rb +52 -0
  63. data/lib/graphql/dataloader/async_dataloader.rb +89 -0
  64. data/lib/graphql/dataloader/null_dataloader.rb +4 -2
  65. data/lib/graphql/dataloader/request.rb +5 -0
  66. data/lib/graphql/dataloader/source.rb +125 -33
  67. data/lib/graphql/dataloader.rb +193 -143
  68. data/lib/graphql/date_encoding_error.rb +16 -0
  69. data/lib/graphql/dig.rb +1 -1
  70. data/lib/graphql/duration_encoding_error.rb +16 -0
  71. data/lib/graphql/execution/errors.rb +12 -81
  72. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  73. data/lib/graphql/execution/interpreter/arguments.rb +2 -2
  74. data/lib/graphql/execution/interpreter/arguments_cache.rb +33 -36
  75. data/lib/graphql/execution/interpreter/resolve.rb +38 -4
  76. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +175 -0
  77. data/lib/graphql/execution/interpreter/runtime.rb +447 -403
  78. data/lib/graphql/execution/interpreter.rb +126 -80
  79. data/lib/graphql/execution/lazy.rb +11 -21
  80. data/lib/graphql/execution/lookahead.rb +133 -55
  81. data/lib/graphql/execution/multiplex.rb +4 -172
  82. data/lib/graphql/execution.rb +11 -4
  83. data/lib/graphql/integer_encoding_error.rb +18 -2
  84. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  85. data/lib/graphql/introspection/directive_type.rb +6 -4
  86. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  87. data/lib/graphql/introspection/entry_points.rb +11 -18
  88. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  89. data/lib/graphql/introspection/field_type.rb +4 -4
  90. data/lib/graphql/introspection/input_value_type.rb +10 -4
  91. data/lib/graphql/introspection/schema_type.rb +17 -15
  92. data/lib/graphql/introspection/type_type.rb +29 -16
  93. data/lib/graphql/introspection.rb +6 -2
  94. data/lib/graphql/invalid_null_error.rb +1 -1
  95. data/lib/graphql/language/block_string.rb +37 -25
  96. data/lib/graphql/language/cache.rb +13 -0
  97. data/lib/graphql/language/comment.rb +18 -0
  98. data/lib/graphql/language/definition_slice.rb +1 -1
  99. data/lib/graphql/language/document_from_schema_definition.rb +122 -81
  100. data/lib/graphql/language/lexer.rb +364 -1467
  101. data/lib/graphql/language/nodes.rb +197 -106
  102. data/lib/graphql/language/parser.rb +799 -1920
  103. data/lib/graphql/language/printer.rb +372 -160
  104. data/lib/graphql/language/sanitized_printer.rb +25 -27
  105. data/lib/graphql/language/static_visitor.rb +167 -0
  106. data/lib/graphql/language/visitor.rb +188 -141
  107. data/lib/graphql/language.rb +62 -1
  108. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  109. data/lib/graphql/name_validator.rb +0 -4
  110. data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
  111. data/lib/graphql/pagination/array_connection.rb +8 -6
  112. data/lib/graphql/pagination/connection.rb +61 -7
  113. data/lib/graphql/pagination/connections.rb +22 -23
  114. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  115. data/lib/graphql/pagination/relation_connection.rb +60 -28
  116. data/lib/graphql/query/context/scoped_context.rb +101 -0
  117. data/lib/graphql/query/context.rb +146 -222
  118. data/lib/graphql/query/input_validation_result.rb +10 -1
  119. data/lib/graphql/query/null_context.rb +15 -32
  120. data/lib/graphql/query/validation_pipeline.rb +15 -39
  121. data/lib/graphql/query/variable_validation_error.rb +3 -3
  122. data/lib/graphql/query/variables.rb +35 -17
  123. data/lib/graphql/query.rb +149 -82
  124. data/lib/graphql/railtie.rb +15 -109
  125. data/lib/graphql/rake_task/validate.rb +1 -1
  126. data/lib/graphql/rake_task.rb +30 -11
  127. data/lib/graphql/relay/range_add.rb +9 -16
  128. data/lib/graphql/relay.rb +0 -15
  129. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  130. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  131. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  132. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  133. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  134. data/lib/graphql/rubocop.rb +6 -0
  135. data/lib/graphql/schema/addition.rb +98 -54
  136. data/lib/graphql/schema/always_visible.rb +14 -0
  137. data/lib/graphql/schema/argument.rb +179 -82
  138. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  139. data/lib/graphql/schema/build_from_definition.rb +77 -39
  140. data/lib/graphql/schema/directive/feature.rb +1 -1
  141. data/lib/graphql/schema/directive/flagged.rb +4 -4
  142. data/lib/graphql/schema/directive/include.rb +1 -1
  143. data/lib/graphql/schema/directive/one_of.rb +24 -0
  144. data/lib/graphql/schema/directive/skip.rb +1 -1
  145. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  146. data/lib/graphql/schema/directive/transform.rb +2 -2
  147. data/lib/graphql/schema/directive.rb +36 -22
  148. data/lib/graphql/schema/enum.rb +158 -63
  149. data/lib/graphql/schema/enum_value.rb +12 -21
  150. data/lib/graphql/schema/field/connection_extension.rb +7 -17
  151. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  152. data/lib/graphql/schema/field.rb +521 -359
  153. data/lib/graphql/schema/field_extension.rb +86 -2
  154. data/lib/graphql/schema/find_inherited_value.rb +3 -7
  155. data/lib/graphql/schema/finder.rb +5 -5
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +148 -99
  158. data/lib/graphql/schema/interface.rb +41 -64
  159. data/lib/graphql/schema/introspection_system.rb +12 -26
  160. data/lib/graphql/schema/late_bound_type.rb +12 -2
  161. data/lib/graphql/schema/list.rb +18 -7
  162. data/lib/graphql/schema/loader.rb +6 -5
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
  164. data/lib/graphql/schema/member/build_type.rb +16 -13
  165. data/lib/graphql/schema/member/has_arguments.rb +270 -86
  166. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  167. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  168. data/lib/graphql/schema/member/has_directives.rb +81 -61
  169. data/lib/graphql/schema/member/has_fields.rb +169 -31
  170. data/lib/graphql/schema/member/has_interfaces.rb +143 -0
  171. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  172. data/lib/graphql/schema/member/has_validators.rb +32 -6
  173. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  174. data/lib/graphql/schema/member/scoped.rb +19 -0
  175. data/lib/graphql/schema/member/type_system_helpers.rb +16 -0
  176. data/lib/graphql/schema/member/validates_input.rb +6 -6
  177. data/lib/graphql/schema/member.rb +1 -6
  178. data/lib/graphql/schema/mutation.rb +7 -9
  179. data/lib/graphql/schema/non_null.rb +7 -7
  180. data/lib/graphql/schema/object.rb +38 -119
  181. data/lib/graphql/schema/printer.rb +24 -25
  182. data/lib/graphql/schema/relay_classic_mutation.rb +13 -91
  183. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
  184. data/lib/graphql/schema/resolver.rb +118 -115
  185. data/lib/graphql/schema/scalar.rb +20 -21
  186. data/lib/graphql/schema/subscription.rb +95 -21
  187. data/lib/graphql/schema/timeout.rb +25 -29
  188. data/lib/graphql/schema/type_expression.rb +2 -2
  189. data/lib/graphql/schema/type_membership.rb +21 -4
  190. data/lib/graphql/schema/union.rb +16 -16
  191. data/lib/graphql/schema/unique_within_type.rb +1 -1
  192. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  193. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  194. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  195. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  196. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  197. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  198. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  199. data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
  200. data/lib/graphql/schema/validator/required_validator.rb +56 -18
  201. data/lib/graphql/schema/validator.rb +38 -28
  202. data/lib/graphql/schema/visibility/migration.rb +188 -0
  203. data/lib/graphql/schema/visibility/profile.rb +359 -0
  204. data/lib/graphql/schema/visibility/visit.rb +190 -0
  205. data/lib/graphql/schema/visibility.rb +294 -0
  206. data/lib/graphql/schema/warden.rb +423 -134
  207. data/lib/graphql/schema/wrapper.rb +0 -5
  208. data/lib/graphql/schema.rb +1015 -1057
  209. data/lib/graphql/static_validation/all_rules.rb +3 -1
  210. data/lib/graphql/static_validation/base_visitor.rb +15 -28
  211. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  212. data/lib/graphql/static_validation/error.rb +3 -1
  213. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  214. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  215. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  216. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +4 -3
  217. data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
  218. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +15 -13
  219. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  220. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +13 -5
  221. data/lib/graphql/static_validation/rules/fields_will_merge.rb +62 -35
  222. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  223. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  224. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  225. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  226. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  227. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  228. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  229. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  230. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  231. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  232. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  233. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +7 -5
  234. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  235. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  236. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +14 -8
  237. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  238. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  239. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +14 -8
  240. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  241. data/lib/graphql/static_validation/validation_context.rb +32 -6
  242. data/lib/graphql/static_validation/validator.rb +11 -27
  243. data/lib/graphql/static_validation.rb +0 -3
  244. data/lib/graphql/string_encoding_error.rb +13 -3
  245. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +49 -11
  246. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  247. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
  248. data/lib/graphql/subscriptions/event.rb +87 -38
  249. data/lib/graphql/subscriptions/serialize.rb +27 -3
  250. data/lib/graphql/subscriptions.rb +63 -49
  251. data/lib/graphql/testing/helpers.rb +155 -0
  252. data/lib/graphql/testing.rb +2 -0
  253. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  254. data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
  255. data/lib/graphql/tracing/appoptics_trace.rb +253 -0
  256. data/lib/graphql/tracing/appoptics_tracing.rb +4 -2
  257. data/lib/graphql/tracing/appsignal_trace.rb +79 -0
  258. data/lib/graphql/tracing/appsignal_tracing.rb +17 -0
  259. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  260. data/lib/graphql/tracing/data_dog_trace.rb +185 -0
  261. data/lib/graphql/tracing/data_dog_tracing.rb +27 -15
  262. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
  263. data/lib/graphql/tracing/legacy_trace.rb +12 -0
  264. data/lib/graphql/tracing/new_relic_trace.rb +77 -0
  265. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  266. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  267. data/lib/graphql/tracing/notifications_tracing.rb +61 -0
  268. data/lib/graphql/tracing/null_trace.rb +9 -0
  269. data/lib/graphql/tracing/platform_trace.rb +118 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +46 -49
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
  272. data/lib/graphql/tracing/prometheus_trace.rb +94 -0
  273. data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
  274. data/lib/graphql/tracing/scout_trace.rb +74 -0
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +114 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +58 -0
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +79 -0
  280. data/lib/graphql/tracing.rb +29 -52
  281. data/lib/graphql/type_kinds.rb +7 -4
  282. data/lib/graphql/types/big_int.rb +5 -1
  283. data/lib/graphql/types/int.rb +1 -1
  284. data/lib/graphql/types/iso_8601_date.rb +17 -6
  285. data/lib/graphql/types/iso_8601_date_time.rb +12 -1
  286. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  287. data/lib/graphql/types/relay/base_connection.rb +16 -6
  288. data/lib/graphql/types/relay/connection_behaviors.rb +92 -32
  289. data/lib/graphql/types/relay/edge_behaviors.rb +46 -7
  290. data/lib/graphql/types/relay/has_node_field.rb +2 -2
  291. data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
  292. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  293. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  294. data/lib/graphql/types/relay.rb +0 -3
  295. data/lib/graphql/types/string.rb +2 -2
  296. data/lib/graphql/types.rb +18 -10
  297. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  298. data/lib/graphql/unauthorized_error.rb +1 -1
  299. data/lib/graphql/version.rb +1 -1
  300. data/lib/graphql.rb +82 -137
  301. data/readme.md +13 -6
  302. metadata +127 -186
  303. data/lib/graphql/analysis/analyze_query.rb +0 -98
  304. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  305. data/lib/graphql/analysis/ast/field_usage.rb +0 -28
  306. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
  307. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  308. data/lib/graphql/analysis/ast/query_complexity.rb +0 -234
  309. data/lib/graphql/analysis/ast/query_depth.rb +0 -56
  310. data/lib/graphql/analysis/ast/visitor.rb +0 -268
  311. data/lib/graphql/analysis/ast.rb +0 -91
  312. data/lib/graphql/analysis/reducer_state.rb +0 -48
  313. data/lib/graphql/argument.rb +0 -131
  314. data/lib/graphql/authorization.rb +0 -82
  315. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  316. data/lib/graphql/backwards_compatibility.rb +0 -61
  317. data/lib/graphql/base_type.rb +0 -230
  318. data/lib/graphql/boolean_type.rb +0 -2
  319. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  320. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  321. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  322. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  323. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  324. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  325. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  326. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  327. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  328. data/lib/graphql/compatibility.rb +0 -5
  329. data/lib/graphql/define/assign_argument.rb +0 -12
  330. data/lib/graphql/define/assign_connection.rb +0 -13
  331. data/lib/graphql/define/assign_enum_value.rb +0 -18
  332. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  333. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  334. data/lib/graphql/define/assign_object_field.rb +0 -42
  335. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  336. data/lib/graphql/define/instance_definable.rb +0 -240
  337. data/lib/graphql/define/no_definition_error.rb +0 -7
  338. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  339. data/lib/graphql/define/type_definer.rb +0 -31
  340. data/lib/graphql/define.rb +0 -31
  341. data/lib/graphql/deprecated_dsl.rb +0 -47
  342. data/lib/graphql/deprecation.rb +0 -13
  343. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  344. data/lib/graphql/directive/include_directive.rb +0 -2
  345. data/lib/graphql/directive/skip_directive.rb +0 -2
  346. data/lib/graphql/directive.rb +0 -111
  347. data/lib/graphql/enum_type.rb +0 -129
  348. data/lib/graphql/execution/execute.rb +0 -333
  349. data/lib/graphql/execution/flatten.rb +0 -40
  350. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  351. data/lib/graphql/execution/typecast.rb +0 -50
  352. data/lib/graphql/field/resolve.rb +0 -59
  353. data/lib/graphql/field.rb +0 -226
  354. data/lib/graphql/filter.rb +0 -53
  355. data/lib/graphql/float_type.rb +0 -2
  356. data/lib/graphql/function.rb +0 -128
  357. data/lib/graphql/id_type.rb +0 -2
  358. data/lib/graphql/input_object_type.rb +0 -138
  359. data/lib/graphql/int_type.rb +0 -2
  360. data/lib/graphql/interface_type.rb +0 -72
  361. data/lib/graphql/internal_representation/document.rb +0 -27
  362. data/lib/graphql/internal_representation/node.rb +0 -206
  363. data/lib/graphql/internal_representation/print.rb +0 -51
  364. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  365. data/lib/graphql/internal_representation/scope.rb +0 -88
  366. data/lib/graphql/internal_representation/visit.rb +0 -36
  367. data/lib/graphql/internal_representation.rb +0 -7
  368. data/lib/graphql/language/lexer.rl +0 -262
  369. data/lib/graphql/language/parser.y +0 -543
  370. data/lib/graphql/language/token.rb +0 -38
  371. data/lib/graphql/list_type.rb +0 -80
  372. data/lib/graphql/non_null_type.rb +0 -71
  373. data/lib/graphql/object_type.rb +0 -130
  374. data/lib/graphql/query/arguments.rb +0 -189
  375. data/lib/graphql/query/arguments_cache.rb +0 -24
  376. data/lib/graphql/query/executor.rb +0 -52
  377. data/lib/graphql/query/literal_input.rb +0 -136
  378. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  379. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  380. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  381. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  382. data/lib/graphql/query/serial_execution.rb +0 -40
  383. data/lib/graphql/relay/array_connection.rb +0 -83
  384. data/lib/graphql/relay/base_connection.rb +0 -189
  385. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  386. data/lib/graphql/relay/connection_resolve.rb +0 -43
  387. data/lib/graphql/relay/connection_type.rb +0 -41
  388. data/lib/graphql/relay/edge.rb +0 -27
  389. data/lib/graphql/relay/edge_type.rb +0 -19
  390. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  391. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  392. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  393. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  394. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  395. data/lib/graphql/relay/mutation/result.rb +0 -38
  396. data/lib/graphql/relay/mutation.rb +0 -106
  397. data/lib/graphql/relay/node.rb +0 -39
  398. data/lib/graphql/relay/page_info.rb +0 -7
  399. data/lib/graphql/relay/relation_connection.rb +0 -188
  400. data/lib/graphql/relay/type_extensions.rb +0 -32
  401. data/lib/graphql/scalar_type.rb +0 -91
  402. data/lib/graphql/schema/base_64_bp.rb +0 -26
  403. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  404. data/lib/graphql/schema/default_parse_error.rb +0 -10
  405. data/lib/graphql/schema/default_type_error.rb +0 -17
  406. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  407. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  408. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  409. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  410. data/lib/graphql/schema/middleware_chain.rb +0 -82
  411. data/lib/graphql/schema/possible_types.rb +0 -44
  412. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  413. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  414. data/lib/graphql/schema/traversal.rb +0 -228
  415. data/lib/graphql/schema/validation.rb +0 -313
  416. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  417. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  418. data/lib/graphql/static_validation/type_stack.rb +0 -216
  419. data/lib/graphql/string_type.rb +0 -2
  420. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  421. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  422. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  423. data/lib/graphql/types/relay/default_relay.rb +0 -27
  424. data/lib/graphql/types/relay/node_field.rb +0 -25
  425. data/lib/graphql/types/relay/nodes_field.rb +0 -27
  426. data/lib/graphql/union_type.rb +0 -115
  427. data/lib/graphql/upgrader/member.rb +0 -937
  428. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -15,15 +15,65 @@ module GraphQL
15
15
  # @return [Object]
16
16
  attr_reader :options
17
17
 
18
+ # @return [Array<Symbol>, nil] `default_argument`s added, if any were added (otherwise, `nil`)
19
+ attr_reader :added_default_arguments
20
+
18
21
  # Called when the extension is mounted with `extension(name, options)`.
19
- # The instance is frozen to avoid improper use of state during execution.
22
+ # The instance will be frozen to avoid improper use of state during execution.
20
23
  # @param field [GraphQL::Schema::Field] The field where this extension was mounted
21
24
  # @param options [Object] The second argument to `extension`, or `{}` if nothing was passed.
22
25
  def initialize(field:, options:)
23
26
  @field = field
24
27
  @options = options || {}
28
+ @added_default_arguments = nil
25
29
  apply
26
- freeze
30
+ end
31
+
32
+ class << self
33
+ # @return [Array(Array, Hash), nil] A list of default argument configs, or `nil` if there aren't any
34
+ def default_argument_configurations
35
+ args = superclass.respond_to?(:default_argument_configurations) ? superclass.default_argument_configurations : nil
36
+ if @own_default_argument_configurations
37
+ if args
38
+ args.concat(@own_default_argument_configurations)
39
+ else
40
+ args = @own_default_argument_configurations.dup
41
+ end
42
+ end
43
+ args
44
+ end
45
+
46
+ # @see Argument#initialize
47
+ # @see HasArguments#argument
48
+ def default_argument(*argument_args, **argument_kwargs)
49
+ configs = @own_default_argument_configurations ||= []
50
+ configs << [argument_args, argument_kwargs]
51
+ end
52
+
53
+ # If configured, these `extras` will be added to the field if they aren't already present,
54
+ # but removed by from `arguments` before the field's `resolve` is called.
55
+ # (The extras _will_ be present for other extensions, though.)
56
+ #
57
+ # @param new_extras [Array<Symbol>] If provided, assign extras used by this extension
58
+ # @return [Array<Symbol>] any extras assigned to this extension
59
+ def extras(new_extras = nil)
60
+ if new_extras
61
+ @own_extras = new_extras
62
+ end
63
+
64
+ inherited_extras = self.superclass.respond_to?(:extras) ? superclass.extras : nil
65
+ if @own_extras
66
+ if inherited_extras
67
+ inherited_extras + @own_extras
68
+ else
69
+ @own_extras
70
+ end
71
+ elsif inherited_extras
72
+ inherited_extras
73
+ else
74
+ GraphQL::EmptyObjects::EMPTY_ARRAY
75
+ end
76
+ end
27
77
  end
28
78
 
29
79
  # Called when this extension is attached to a field.
@@ -32,6 +82,40 @@ module GraphQL
32
82
  def apply
33
83
  end
34
84
 
85
+ # Called after the field's definition block has been executed.
86
+ # (Any arguments from the block are present on `field`)
87
+ # @return [void]
88
+ def after_define
89
+ end
90
+
91
+ # @api private
92
+ def after_define_apply
93
+ after_define
94
+ if (configs = self.class.default_argument_configurations)
95
+ existing_keywords = field.all_argument_definitions.map(&:keyword)
96
+ existing_keywords.uniq!
97
+ @added_default_arguments = []
98
+ configs.each do |config|
99
+ argument_args, argument_kwargs = config
100
+ arg_name = argument_args[0]
101
+ if !existing_keywords.include?(arg_name)
102
+ @added_default_arguments << arg_name
103
+ field.argument(*argument_args, **argument_kwargs)
104
+ end
105
+ end
106
+ end
107
+ if !(extras = self.class.extras).empty?
108
+ @added_extras = extras - field.extras
109
+ field.extras(@added_extras)
110
+ else
111
+ @added_extras = nil
112
+ end
113
+ freeze
114
+ end
115
+
116
+ # @api private
117
+ attr_reader :added_extras
118
+
35
119
  # Called before resolving {#field}. It should either:
36
120
  #
37
121
  # - `yield` values to continue execution; OR
@@ -1,17 +1,13 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  class Schema
3
4
  module FindInheritedValue
4
- module EmptyObjects
5
- EMPTY_HASH = {}.freeze
6
- EMPTY_ARRAY = [].freeze
7
- end
8
-
9
5
  def self.extended(child_cls)
10
- child_cls.singleton_class.include(EmptyObjects)
6
+ child_cls.singleton_class.include(GraphQL::EmptyObjects)
11
7
  end
12
8
 
13
9
  def self.included(child_cls)
14
- child_cls.include(EmptyObjects)
10
+ child_cls.include(GraphQL::EmptyObjects)
15
11
  end
16
12
 
17
13
  private
@@ -38,7 +38,7 @@ module GraphQL
38
38
 
39
39
  find_in_directive(directive, path: path)
40
40
  else
41
- type = schema.get_type(type_or_directive)
41
+ type = schema.get_type(type_or_directive) # rubocop:disable Development/ContextIsPassedCop -- build-time
42
42
 
43
43
  if type.nil?
44
44
  raise MemberNotFoundError, "Could not find type `#{type_or_directive}` in schema."
@@ -56,7 +56,7 @@ module GraphQL
56
56
 
57
57
  def find_in_directive(directive, path:)
58
58
  argument_name = path.shift
59
- argument = directive.arguments[argument_name]
59
+ argument = directive.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
60
60
 
61
61
  if argument.nil?
62
62
  raise MemberNotFoundError, "Could not find argument `#{argument_name}` on directive #{directive}."
@@ -102,7 +102,7 @@ module GraphQL
102
102
 
103
103
  def find_in_field(field, path:)
104
104
  argument_name = path.shift
105
- argument = field.arguments[argument_name]
105
+ argument = field.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
106
106
 
107
107
  if argument.nil?
108
108
  raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
@@ -119,7 +119,7 @@ module GraphQL
119
119
 
120
120
  def find_in_input_object(input_object, path:)
121
121
  field_name = path.shift
122
- input_field = input_object.arguments[field_name]
122
+ input_field = input_object.get_argument(field_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
123
123
 
124
124
  if input_field.nil?
125
125
  raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object.graphql_name}`."
@@ -136,7 +136,7 @@ module GraphQL
136
136
 
137
137
  def find_in_enum_type(enum_type, path:)
138
138
  value_name = path.shift
139
- enum_value = enum_type.values[value_name]
139
+ enum_value = enum_type.enum_values.find { |v| v.graphql_name == value_name } # rubocop:disable Development/ContextIsPassedCop -- build-time, not runtime
140
140
 
141
141
  if enum_value.nil?
142
142
  raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type.graphql_name}`."
@@ -0,0 +1,160 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Schema
5
+ module HasSingleInputArgument
6
+ def resolve_with_support(**inputs)
7
+ if inputs[:input].is_a?(InputObject)
8
+ input = inputs[:input].to_kwargs
9
+ else
10
+ input = inputs[:input]
11
+ end
12
+
13
+ new_extras = field ? field.extras : []
14
+ all_extras = self.class.extras + new_extras
15
+
16
+ # Transfer these from the top-level hash to the
17
+ # shortcutted `input:` object
18
+ all_extras.each do |ext|
19
+ # It's possible that the `extra` was not passed along by this point,
20
+ # don't re-add it if it wasn't given here.
21
+ if inputs.key?(ext)
22
+ input[ext] = inputs[ext]
23
+ end
24
+ end
25
+
26
+ if input
27
+ # This is handled by Relay::Mutation::Resolve, a bit hacky, but here we are.
28
+ input_kwargs = input.to_h
29
+ else
30
+ # Relay Classic Mutations with no `argument`s
31
+ # don't require `input:`
32
+ input_kwargs = {}
33
+ end
34
+
35
+ if !input_kwargs.empty?
36
+ super(**input_kwargs)
37
+ else
38
+ super()
39
+ end
40
+ end
41
+
42
+ def self.included(base)
43
+ base.extend(ClassMethods)
44
+ end
45
+
46
+ module ClassMethods
47
+ def dummy
48
+ @dummy ||= begin
49
+ d = Class.new(GraphQL::Schema::Resolver)
50
+ d.graphql_name "#{self.graphql_name}DummyResolver"
51
+ d.argument_class(self.argument_class)
52
+ # TODO make this lazier?
53
+ d.argument(:input, input_type, description: "Parameters for #{self.graphql_name}")
54
+ d
55
+ end
56
+ end
57
+
58
+ def field_arguments(context = GraphQL::Query::NullContext.instance)
59
+ dummy.arguments(context)
60
+ end
61
+
62
+ def get_field_argument(name, context = GraphQL::Query::NullContext.instance)
63
+ dummy.get_argument(name, context)
64
+ end
65
+
66
+ def own_field_arguments
67
+ dummy.own_arguments
68
+ end
69
+
70
+ def any_field_arguments?
71
+ dummy.any_arguments?
72
+ end
73
+
74
+ def all_field_argument_definitions
75
+ dummy.all_argument_definitions
76
+ end
77
+
78
+ # Also apply this argument to the input type:
79
+ def argument(*args, own_argument: false, **kwargs, &block)
80
+ it = input_type # make sure any inherited arguments are already added to it
81
+ arg = super(*args, **kwargs, &block)
82
+
83
+ # This definition might be overriding something inherited;
84
+ # if it is, remove the inherited definition so it's not confused at runtime as having multiple definitions
85
+ prev_args = it.own_arguments[arg.graphql_name]
86
+ case prev_args
87
+ when GraphQL::Schema::Argument
88
+ if prev_args.owner != self
89
+ it.own_arguments.delete(arg.graphql_name)
90
+ end
91
+ when Array
92
+ prev_args.reject! { |a| a.owner != self }
93
+ if prev_args.empty?
94
+ it.own_arguments.delete(arg.graphql_name)
95
+ end
96
+ end
97
+
98
+ it.add_argument(arg)
99
+ arg
100
+ end
101
+
102
+ # The base class for generated input object types
103
+ # @param new_class [Class] The base class to use for generating input object definitions
104
+ # @return [Class] The base class for this mutation's generated input object (default is {GraphQL::Schema::InputObject})
105
+ def input_object_class(new_class = nil)
106
+ if new_class
107
+ @input_object_class = new_class
108
+ end
109
+ @input_object_class || (superclass.respond_to?(:input_object_class) ? superclass.input_object_class : GraphQL::Schema::InputObject)
110
+ end
111
+
112
+ # @param new_input_type [Class, nil] If provided, it configures this mutation to accept `new_input_type` instead of generating an input type
113
+ # @return [Class] The generated {Schema::InputObject} class for this mutation's `input`
114
+ def input_type(new_input_type = nil)
115
+ if new_input_type
116
+ @input_type = new_input_type
117
+ end
118
+ @input_type ||= generate_input_type
119
+ end
120
+
121
+ private
122
+
123
+ # Generate the input type for the `input:` argument
124
+ # To customize how input objects are generated, override this method
125
+ # @return [Class] a subclass of {.input_object_class}
126
+ def generate_input_type
127
+ mutation_args = all_argument_definitions
128
+ mutation_class = self
129
+ Class.new(input_object_class) do
130
+ class << self
131
+ def default_graphql_name
132
+ "#{self.mutation.graphql_name}Input"
133
+ end
134
+
135
+ def description(new_desc = nil)
136
+ super || "Autogenerated input type of #{self.mutation.graphql_name}"
137
+ end
138
+ end
139
+ # For compatibility, in case no arguments are defined:
140
+ has_no_arguments(true)
141
+ mutation(mutation_class)
142
+ # these might be inherited:
143
+ mutation_args.each do |arg|
144
+ add_argument(arg)
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ private
151
+
152
+ def authorize_arguments(args, values)
153
+ # remove the `input` wrapper to match values
154
+ input_type = args.find { |a| a.graphql_name == "input" }.type.unwrap
155
+ input_args = context.types.arguments(input_type)
156
+ super(input_args, values)
157
+ end
158
+ end
159
+ end
160
+ end
@@ -2,7 +2,6 @@
2
2
  module GraphQL
3
3
  class Schema
4
4
  class InputObject < GraphQL::Schema::Member
5
- extend GraphQL::Schema::Member::AcceptsDefinition
6
5
  extend Forwardable
7
6
  extend GraphQL::Schema::Member::HasArguments
8
7
  extend GraphQL::Schema::Member::HasArguments::ArgumentObjectLoader
@@ -11,76 +10,65 @@ module GraphQL
11
10
 
12
11
  include GraphQL::Dig
13
12
 
14
- def initialize(arguments = nil, ruby_kwargs: nil, context:, defaults_used:)
15
- @context = context
16
- if ruby_kwargs
17
- @ruby_style_hash = ruby_kwargs
18
- @arguments = arguments
19
- else
20
- @arguments = self.class.arguments_class.new(arguments, context: context, defaults_used: defaults_used)
21
- # Symbolized, underscored hash:
22
- @ruby_style_hash = @arguments.to_kwargs
13
+ # Raised when an InputObject doesn't have any arguments defined and hasn't explicitly opted out of this requirement
14
+ class ArgumentsAreRequiredError < GraphQL::Error
15
+ def initialize(input_object_type)
16
+ message = "Input Object types must have arguments, but #{input_object_type.graphql_name} doesn't have any. Define an argument for this type, remove it from your schema, or add `has_no_arguments(true)` to its definition."
17
+ super(message)
23
18
  end
19
+ end
20
+
21
+ # @return [GraphQL::Query::Context] The context for this query
22
+ attr_reader :context
23
+ # @return [GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
24
+ attr_reader :arguments
25
+
26
+ # Ruby-like hash behaviors, read-only
27
+ def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
28
+
29
+ def initialize(arguments, ruby_kwargs:, context:, defaults_used:)
30
+ @context = context
31
+ @ruby_style_hash = ruby_kwargs
32
+ @arguments = arguments
24
33
  # Apply prepares, not great to have it duplicated here.
25
- maybe_lazies = []
26
- self.class.arguments.each_value do |arg_defn|
34
+ arg_defns = context ? context.types.arguments(self.class) : self.class.arguments(context).each_value
35
+ arg_defns.each do |arg_defn|
27
36
  ruby_kwargs_key = arg_defn.keyword
28
-
29
37
  if @ruby_style_hash.key?(ruby_kwargs_key)
30
- loads = arg_defn.loads
31
- # Resolvers do this loading themselves;
32
- # With the interpreter, it's done during `coerce_arguments`
33
- if loads && !arg_defn.from_resolver? && !context.interpreter?
34
- value = @ruby_style_hash[ruby_kwargs_key]
35
- loaded_value = if arg_defn.type.list?
36
- value.map { |val| load_application_object(arg_defn, loads, val, context) }
37
- else
38
- load_application_object(arg_defn, loads, value, context)
39
- end
40
- maybe_lazies << context.schema.after_lazy(loaded_value) do |loaded_value|
41
- overwrite_argument(ruby_kwargs_key, loaded_value)
42
- end
43
- end
44
-
45
38
  # Weirdly, procs are applied during coercion, but not methods.
46
39
  # Probably because these methods require a `self`.
47
- if arg_defn.prepare.is_a?(Symbol) || context.nil? || !context.interpreter?
40
+ if arg_defn.prepare.is_a?(Symbol) || context.nil?
48
41
  prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
49
42
  overwrite_argument(ruby_kwargs_key, prepared_value)
50
43
  end
51
44
  end
52
45
  end
53
-
54
- @maybe_lazies = maybe_lazies
55
46
  end
56
47
 
57
- # @return [GraphQL::Query::Context] The context for this query
58
- attr_reader :context
59
-
60
- # @return [GraphQL::Query::Arguments, GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
61
- attr_reader :arguments
62
-
63
- # Ruby-like hash behaviors, read-only
64
- def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
65
-
66
48
  def to_h
67
- @ruby_style_hash.inject({}) do |h, (key, value)|
68
- h.merge(key => unwrap_value(value))
69
- end
49
+ unwrap_value(@ruby_style_hash)
70
50
  end
71
51
 
72
52
  def to_hash
73
53
  to_h
74
54
  end
75
55
 
56
+ def deconstruct_keys(keys = nil)
57
+ if keys.nil?
58
+ @ruby_style_hash
59
+ else
60
+ new_h = {}
61
+ keys.each { |k| @ruby_style_hash.key?(k) && new_h[k] = @ruby_style_hash[k] }
62
+ new_h
63
+ end
64
+ end
65
+
76
66
  def prepare
77
- if context
78
- context.schema.after_any_lazies(@maybe_lazies) do
79
- object = context[:current_object]
80
- # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
81
- Schema::Validator.validate!(self.class.validators, object, context, @ruby_style_hash, as: self.class)
82
- self
83
- end
67
+ if @context
68
+ object = @context[:current_object]
69
+ # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
70
+ Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
71
+ self
84
72
  else
85
73
  self
86
74
  end
@@ -91,8 +79,8 @@ module GraphQL
91
79
  when Array
92
80
  value.map { |item| unwrap_value(item) }
93
81
  when Hash
94
- value.inject({}) do |h, (key, value)|
95
- h.merge(key => unwrap_value(value))
82
+ value.reduce({}) do |h, (key, value)|
83
+ h.merge!(key => unwrap_value(value))
96
84
  end
97
85
  when InputObject
98
86
  value.to_h
@@ -124,35 +112,54 @@ module GraphQL
124
112
  end
125
113
 
126
114
  class << self
127
- # @return [Class<GraphQL::Arguments>]
128
- attr_accessor :arguments_class
115
+ def authorized?(obj, value, ctx)
116
+ # Authorize each argument (but this doesn't apply if `prepare` is implemented):
117
+ if value.respond_to?(:key?)
118
+ ctx.types.arguments(self).each do |input_obj_arg|
119
+ if value.key?(input_obj_arg.keyword) &&
120
+ !input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
121
+ return false
122
+ end
123
+ end
124
+ end
125
+ # It didn't early-return false:
126
+ true
127
+ end
128
+
129
+ def one_of
130
+ if !one_of?
131
+ if all_argument_definitions.any? { |arg| arg.type.non_null? }
132
+ raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
133
+ end
134
+ directive(GraphQL::Schema::Directive::OneOf)
135
+ end
136
+ end
137
+
138
+ def one_of?
139
+ false # Re-defined when `OneOf` is added
140
+ end
129
141
 
130
142
  def argument(*args, **kwargs, &block)
131
143
  argument_defn = super(*args, **kwargs, &block)
144
+ if one_of?
145
+ if argument_defn.type.non_null?
146
+ raise ArgumentError, "Argument '#{argument_defn.path}' must be nullable because it is part of a OneOf type, add `required: false`."
147
+ end
148
+ if argument_defn.default_value?
149
+ raise ArgumentError, "Argument '#{argument_defn.path}' cannot have a default value because it is part of a OneOf type, remove `default_value: ...`."
150
+ end
151
+ end
132
152
  # Add a method access
133
153
  method_name = argument_defn.keyword
134
- class_eval <<-RUBY, __FILE__, __LINE__
135
- def #{method_name}
136
- self[#{method_name.inspect}]
137
- end
138
- RUBY
139
- end
140
-
141
- def to_graphql
142
- type_defn = GraphQL::InputObjectType.new
143
- type_defn.name = graphql_name
144
- type_defn.description = description
145
- type_defn.metadata[:type_class] = self
146
- type_defn.mutation = mutation
147
- type_defn.ast_node = ast_node
148
- arguments.each do |name, arg|
149
- type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
154
+ suppress_redefinition_warning do
155
+ class_eval <<-RUBY, __FILE__, __LINE__
156
+ def #{method_name}
157
+ self[#{method_name.inspect}]
158
+ end
159
+ alias_method :#{method_name}, :#{method_name}
160
+ RUBY
150
161
  end
151
- # Make a reference to a classic-style Arguments class
152
- self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
153
- # But use this InputObject class at runtime
154
- type_defn.arguments_class = self
155
- type_defn
162
+ argument_defn
156
163
  end
157
164
 
158
165
  def kind
@@ -160,46 +167,59 @@ module GraphQL
160
167
  end
161
168
 
162
169
  # @api private
163
- INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
164
-
170
+ INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object."
165
171
 
166
- def validate_non_null_input(input, ctx)
167
- result = GraphQL::Query::InputValidationResult.new
168
-
169
- warden = ctx.warden
172
+ def validate_non_null_input(input, ctx, max_errors: nil)
173
+ types = ctx.types
170
174
 
171
175
  if input.is_a?(Array)
172
- result.add_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
173
- return result
176
+ return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
174
177
  end
175
178
 
176
179
  if !(input.respond_to?(:to_h) || input.respond_to?(:to_unsafe_h))
177
180
  # We're not sure it'll act like a hash, so reject it:
178
- result.add_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
179
- return result
181
+ return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
180
182
  end
181
183
 
182
184
  # Inject missing required arguments
183
- missing_required_inputs = self.arguments.reduce({}) do |m, (argument_name, argument)|
184
- if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
185
- m[argument_name] = nil
185
+ missing_required_inputs = ctx.types.arguments(self).reduce({}) do |m, (argument)|
186
+ if !input.key?(argument.graphql_name) && argument.type.non_null? && !argument.default_value? && types.argument(self, argument.graphql_name)
187
+ m[argument.graphql_name] = nil
186
188
  end
187
189
 
188
190
  m
189
191
  end
190
192
 
191
-
193
+ result = nil
192
194
  [input, missing_required_inputs].each do |args_to_validate|
193
195
  args_to_validate.each do |argument_name, value|
194
- argument = warden.get_argument(self, argument_name)
196
+ argument = types.argument(self, argument_name)
195
197
  # Items in the input that are unexpected
196
- unless argument
198
+ if argument.nil?
199
+ result ||= Query::InputValidationResult.new
197
200
  result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
198
- next
201
+ else
202
+ # Items in the input that are expected, but have invalid values
203
+ argument_result = argument.type.validate_input(value, ctx)
204
+ result ||= Query::InputValidationResult.new
205
+ if !argument_result.valid?
206
+ result.merge_result!(argument_name, argument_result)
207
+ end
199
208
  end
200
- # Items in the input that are expected, but have invalid values
201
- argument_result = argument.type.validate_input(value, ctx)
202
- result.merge_result!(argument_name, argument_result) unless argument_result.valid?
209
+ end
210
+ end
211
+
212
+ if one_of?
213
+ if input.size == 1
214
+ input.each do |name, value|
215
+ if value.nil?
216
+ result ||= Query::InputValidationResult.new
217
+ result.add_problem("'#{graphql_name}' requires exactly one argument, but '#{name}' was `null`.")
218
+ end
219
+ end
220
+ else
221
+ result ||= Query::InputValidationResult.new
222
+ result.add_problem("'#{graphql_name}' requires exactly one argument, but #{input.size} were provided.")
203
223
  end
204
224
  end
205
225
 
@@ -213,12 +233,11 @@ module GraphQL
213
233
 
214
234
  arguments = coerce_arguments(nil, value, ctx)
215
235
 
216
- ctx.schema.after_lazy(arguments) do |resolved_arguments|
236
+ ctx.query.after_lazy(arguments) do |resolved_arguments|
217
237
  if resolved_arguments.is_a?(GraphQL::Error)
218
238
  raise resolved_arguments
219
239
  else
220
- input_obj_instance = self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
221
- input_obj_instance.prepare
240
+ self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
222
241
  end
223
242
  end
224
243
  end
@@ -231,7 +250,7 @@ module GraphQL
231
250
 
232
251
  result = {}
233
252
 
234
- arguments.each do |input_key, input_field_defn|
253
+ arguments(ctx).each do |input_key, input_field_defn|
235
254
  input_value = value[input_key]
236
255
  if value.key?(input_key)
237
256
  result[input_key] = if input_value.nil?
@@ -244,6 +263,36 @@ module GraphQL
244
263
 
245
264
  result
246
265
  end
266
+
267
+ # @param new_has_no_arguments [Boolean] Call with `true` to make this InputObject type ignore the requirement to have any defined arguments.
268
+ # @return [void]
269
+ def has_no_arguments(new_has_no_arguments)
270
+ @has_no_arguments = new_has_no_arguments
271
+ nil
272
+ end
273
+
274
+ # @return [Boolean] `true` if `has_no_arguments(true)` was configued
275
+ def has_no_arguments?
276
+ @has_no_arguments
277
+ end
278
+
279
+ def arguments(context = GraphQL::Query::NullContext.instance, require_defined_arguments = true)
280
+ if require_defined_arguments && !has_no_arguments? && !any_arguments?
281
+ warn(GraphQL::Schema::InputObject::ArgumentsAreRequiredError.new(self).message + "\n\nThis will raise an error in a future GraphQL-Ruby version.")
282
+ end
283
+ super(context, false)
284
+ end
285
+
286
+ private
287
+
288
+ # Suppress redefinition warning for objectId arguments
289
+ def suppress_redefinition_warning
290
+ verbose = $VERBOSE
291
+ $VERBOSE = nil
292
+ yield
293
+ ensure
294
+ $VERBOSE = verbose
295
+ end
247
296
  end
248
297
 
249
298
  private