graphql 1.9.21 → 2.0.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (403) 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 +25 -27
  45. data/lib/generators/graphql/templates/union.erb +6 -2
  46. data/lib/generators/graphql/type_generator.rb +47 -10
  47. data/lib/generators/graphql/union_generator.rb +5 -5
  48. data/lib/graphql/analysis/ast/field_usage.rb +31 -2
  49. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  50. data/lib/graphql/analysis/ast/query_complexity.rb +175 -68
  51. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  52. data/lib/graphql/analysis/ast/visitor.rb +17 -8
  53. data/lib/graphql/analysis/ast.rb +14 -14
  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 +37 -16
  57. data/lib/graphql/backtrace/traced_error.rb +0 -1
  58. data/lib/graphql/backtrace/tracer.rb +39 -9
  59. data/lib/graphql/backtrace.rb +20 -17
  60. data/lib/graphql/dataloader/null_dataloader.rb +24 -0
  61. data/lib/graphql/dataloader/request.rb +19 -0
  62. data/lib/graphql/dataloader/request_all.rb +19 -0
  63. data/lib/graphql/dataloader/source.rb +164 -0
  64. data/lib/graphql/dataloader.rb +311 -0
  65. data/lib/graphql/date_encoding_error.rb +16 -0
  66. data/lib/graphql/deprecation.rb +9 -0
  67. data/lib/graphql/dig.rb +1 -1
  68. data/lib/graphql/execution/directive_checks.rb +2 -2
  69. data/lib/graphql/execution/errors.rb +77 -45
  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 +105 -0
  73. data/lib/graphql/execution/interpreter/handles_raw_value.rb +18 -0
  74. data/lib/graphql/execution/interpreter/resolve.rb +44 -25
  75. data/lib/graphql/execution/interpreter/runtime.rb +755 -395
  76. data/lib/graphql/execution/interpreter.rb +201 -74
  77. data/lib/graphql/execution/lazy/lazy_method_map.rb +4 -0
  78. data/lib/graphql/execution/lazy.rb +5 -9
  79. data/lib/graphql/execution/lookahead.rb +65 -136
  80. data/lib/graphql/execution/multiplex.rb +5 -152
  81. data/lib/graphql/execution.rb +11 -4
  82. data/lib/graphql/filter.rb +1 -1
  83. data/lib/graphql/integer_decoding_error.rb +17 -0
  84. data/lib/graphql/integer_encoding_error.rb +18 -2
  85. data/lib/graphql/introspection/base_object.rb +2 -5
  86. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  87. data/lib/graphql/introspection/directive_type.rb +11 -5
  88. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  89. data/lib/graphql/introspection/entry_points.rb +5 -18
  90. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  91. data/lib/graphql/introspection/field_type.rb +9 -5
  92. data/lib/graphql/introspection/input_value_type.rb +41 -11
  93. data/lib/graphql/introspection/introspection_query.rb +6 -92
  94. data/lib/graphql/introspection/schema_type.rb +10 -10
  95. data/lib/graphql/introspection/type_type.rb +34 -17
  96. data/lib/graphql/introspection.rb +100 -0
  97. data/lib/graphql/invalid_null_error.rb +18 -0
  98. data/lib/graphql/language/block_string.rb +20 -5
  99. data/lib/graphql/language/cache.rb +37 -0
  100. data/lib/graphql/language/definition_slice.rb +21 -10
  101. data/lib/graphql/language/document_from_schema_definition.rb +104 -68
  102. data/lib/graphql/language/lexer.rb +83 -40
  103. data/lib/graphql/language/lexer.rl +31 -9
  104. data/lib/graphql/language/nodes.rb +64 -93
  105. data/lib/graphql/language/parser.rb +940 -896
  106. data/lib/graphql/language/parser.y +130 -103
  107. data/lib/graphql/language/printer.rb +48 -23
  108. data/lib/graphql/language/sanitized_printer.rb +222 -0
  109. data/lib/graphql/language/token.rb +0 -4
  110. data/lib/graphql/language/visitor.rb +2 -2
  111. data/lib/graphql/language.rb +3 -1
  112. data/lib/graphql/name_validator.rb +2 -7
  113. data/lib/graphql/pagination/active_record_relation_connection.rb +85 -0
  114. data/lib/graphql/pagination/array_connection.rb +79 -0
  115. data/lib/graphql/pagination/connection.rb +253 -0
  116. data/lib/graphql/pagination/connections.rb +135 -0
  117. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  118. data/lib/graphql/pagination/relation_connection.rb +228 -0
  119. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  120. data/lib/graphql/pagination.rb +6 -0
  121. data/lib/graphql/parse_error.rb +0 -1
  122. data/lib/graphql/query/context.rb +172 -198
  123. data/lib/graphql/query/fingerprint.rb +26 -0
  124. data/lib/graphql/query/input_validation_result.rb +33 -7
  125. data/lib/graphql/query/null_context.rb +21 -8
  126. data/lib/graphql/query/validation_pipeline.rb +16 -38
  127. data/lib/graphql/query/variable_validation_error.rb +3 -3
  128. data/lib/graphql/query/variables.rb +39 -12
  129. data/lib/graphql/query.rb +74 -38
  130. data/lib/graphql/railtie.rb +6 -102
  131. data/lib/graphql/rake_task/validate.rb +4 -1
  132. data/lib/graphql/rake_task.rb +41 -10
  133. data/lib/graphql/relay/range_add.rb +17 -10
  134. data/lib/graphql/relay.rb +0 -15
  135. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  136. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  137. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  138. data/lib/graphql/rubocop.rb +4 -0
  139. data/lib/graphql/schema/addition.rb +245 -0
  140. data/lib/graphql/schema/argument.rb +286 -31
  141. data/lib/graphql/schema/base_64_encoder.rb +2 -0
  142. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  143. data/lib/graphql/schema/build_from_definition/resolve_map.rb +13 -5
  144. data/lib/graphql/schema/build_from_definition.rb +334 -220
  145. data/lib/graphql/schema/built_in_types.rb +5 -5
  146. data/lib/graphql/schema/directive/deprecated.rb +18 -0
  147. data/lib/graphql/schema/directive/feature.rb +1 -1
  148. data/lib/graphql/schema/directive/flagged.rb +57 -0
  149. data/lib/graphql/schema/directive/include.rb +2 -2
  150. data/lib/graphql/schema/directive/one_of.rb +12 -0
  151. data/lib/graphql/schema/directive/skip.rb +2 -2
  152. data/lib/graphql/schema/directive/transform.rb +14 -2
  153. data/lib/graphql/schema/directive.rb +117 -14
  154. data/lib/graphql/schema/enum.rb +113 -22
  155. data/lib/graphql/schema/enum_value.rb +16 -21
  156. data/lib/graphql/schema/field/connection_extension.rb +50 -20
  157. data/lib/graphql/schema/field/scope_extension.rb +1 -1
  158. data/lib/graphql/schema/field.rb +491 -329
  159. data/lib/graphql/schema/field_extension.rb +89 -2
  160. data/lib/graphql/schema/find_inherited_value.rb +17 -1
  161. data/lib/graphql/schema/finder.rb +16 -14
  162. data/lib/graphql/schema/input_object.rb +182 -60
  163. data/lib/graphql/schema/interface.rb +28 -43
  164. data/lib/graphql/schema/introspection_system.rb +101 -38
  165. data/lib/graphql/schema/late_bound_type.rb +7 -2
  166. data/lib/graphql/schema/list.rb +61 -3
  167. data/lib/graphql/schema/loader.rb +144 -102
  168. data/lib/graphql/schema/member/base_dsl_methods.rb +33 -32
  169. data/lib/graphql/schema/member/build_type.rb +24 -15
  170. data/lib/graphql/schema/member/has_arguments.rb +261 -24
  171. data/lib/graphql/schema/member/has_ast_node.rb +20 -0
  172. data/lib/graphql/schema/member/has_deprecation_reason.rb +25 -0
  173. data/lib/graphql/schema/member/has_directives.rb +113 -0
  174. data/lib/graphql/schema/member/has_fields.rb +99 -34
  175. data/lib/graphql/schema/member/has_interfaces.rb +88 -0
  176. data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
  177. data/lib/graphql/schema/member/has_validators.rb +31 -0
  178. data/lib/graphql/schema/member/relay_shortcuts.rb +28 -2
  179. data/lib/graphql/schema/member/type_system_helpers.rb +3 -3
  180. data/lib/graphql/schema/member/validates_input.rb +33 -0
  181. data/lib/graphql/schema/member.rb +11 -6
  182. data/lib/graphql/schema/mutation.rb +4 -9
  183. data/lib/graphql/schema/non_null.rb +34 -4
  184. data/lib/graphql/schema/object.rb +38 -60
  185. data/lib/graphql/schema/printer.rb +16 -35
  186. data/lib/graphql/schema/relay_classic_mutation.rb +90 -43
  187. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -6
  188. data/lib/graphql/schema/resolver.rb +146 -93
  189. data/lib/graphql/schema/scalar.rb +40 -15
  190. data/lib/graphql/schema/subscription.rb +55 -26
  191. data/lib/graphql/schema/timeout.rb +29 -15
  192. data/lib/graphql/schema/type_expression.rb +21 -13
  193. data/lib/graphql/schema/type_membership.rb +22 -5
  194. data/lib/graphql/schema/union.rb +48 -14
  195. data/lib/graphql/schema/unique_within_type.rb +1 -2
  196. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  197. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  198. data/lib/graphql/schema/validator/exclusion_validator.rb +33 -0
  199. data/lib/graphql/schema/validator/format_validator.rb +48 -0
  200. data/lib/graphql/schema/validator/inclusion_validator.rb +35 -0
  201. data/lib/graphql/schema/validator/length_validator.rb +59 -0
  202. data/lib/graphql/schema/validator/numericality_validator.rb +82 -0
  203. data/lib/graphql/schema/validator/required_validator.rb +82 -0
  204. data/lib/graphql/schema/validator.rb +171 -0
  205. data/lib/graphql/schema/warden.rb +187 -33
  206. data/lib/graphql/schema/wrapper.rb +0 -5
  207. data/lib/graphql/schema.rb +773 -892
  208. data/lib/graphql/static_validation/all_rules.rb +3 -0
  209. data/lib/graphql/static_validation/base_visitor.rb +21 -31
  210. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  211. data/lib/graphql/static_validation/error.rb +3 -1
  212. data/lib/graphql/static_validation/literal_validator.rb +55 -26
  213. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +45 -83
  214. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +22 -6
  215. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +35 -26
  216. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
  217. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -6
  218. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -14
  219. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +4 -4
  220. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  221. data/lib/graphql/static_validation/rules/fields_will_merge.rb +94 -51
  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/fragments_are_finite.rb +2 -2
  225. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
  226. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
  227. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  228. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  229. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  230. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  231. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -2
  232. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +9 -10
  233. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  234. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +12 -13
  235. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +19 -14
  236. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  237. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +5 -3
  238. data/lib/graphql/static_validation/type_stack.rb +2 -2
  239. data/lib/graphql/static_validation/validation_context.rb +13 -3
  240. data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
  241. data/lib/graphql/static_validation/validator.rb +31 -19
  242. data/lib/graphql/static_validation.rb +1 -2
  243. data/lib/graphql/string_encoding_error.rb +13 -3
  244. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +129 -22
  245. data/lib/graphql/subscriptions/broadcast_analyzer.rb +81 -0
  246. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +58 -0
  247. data/lib/graphql/subscriptions/event.rb +85 -31
  248. data/lib/graphql/subscriptions/instrumentation.rb +0 -47
  249. data/lib/graphql/subscriptions/serialize.rb +53 -6
  250. data/lib/graphql/subscriptions.rb +137 -57
  251. data/lib/graphql/tracing/active_support_notifications_tracing.rb +8 -17
  252. data/lib/graphql/tracing/appoptics_tracing.rb +173 -0
  253. data/lib/graphql/tracing/appsignal_tracing.rb +23 -0
  254. data/lib/graphql/tracing/data_dog_tracing.rb +34 -2
  255. data/lib/graphql/tracing/new_relic_tracing.rb +9 -12
  256. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  257. data/lib/graphql/tracing/platform_tracing.rb +67 -38
  258. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
  259. data/lib/graphql/tracing/prometheus_tracing.rb +8 -0
  260. data/lib/graphql/tracing/scout_tracing.rb +19 -0
  261. data/lib/graphql/tracing/statsd_tracing.rb +42 -0
  262. data/lib/graphql/tracing.rb +15 -36
  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 -90
  268. data/lib/graphql/types/relay/base_edge.rb +2 -34
  269. data/lib/graphql/types/relay/connection_behaviors.rb +158 -0
  270. data/lib/graphql/types/relay/default_relay.rb +27 -0
  271. data/lib/graphql/types/relay/edge_behaviors.rb +65 -0
  272. data/lib/graphql/types/relay/has_node_field.rb +41 -0
  273. data/lib/graphql/types/relay/has_nodes_field.rb +41 -0
  274. data/lib/graphql/types/relay/node.rb +2 -4
  275. data/lib/graphql/types/relay/node_behaviors.rb +19 -0
  276. data/lib/graphql/types/relay/page_info.rb +2 -14
  277. data/lib/graphql/types/relay/page_info_behaviors.rb +25 -0
  278. data/lib/graphql/types/relay.rb +11 -5
  279. data/lib/graphql/types/string.rb +8 -2
  280. data/lib/graphql/unauthorized_error.rb +2 -2
  281. data/lib/graphql/unresolved_type_error.rb +2 -2
  282. data/lib/graphql/version.rb +1 -1
  283. data/lib/graphql.rb +41 -58
  284. data/readme.md +3 -6
  285. metadata +103 -237
  286. data/lib/graphql/analysis/analyze_query.rb +0 -91
  287. data/lib/graphql/analysis/field_usage.rb +0 -45
  288. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  289. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  290. data/lib/graphql/analysis/query_complexity.rb +0 -88
  291. data/lib/graphql/analysis/query_depth.rb +0 -43
  292. data/lib/graphql/analysis/reducer_state.rb +0 -48
  293. data/lib/graphql/argument.rb +0 -159
  294. data/lib/graphql/authorization.rb +0 -82
  295. data/lib/graphql/backwards_compatibility.rb +0 -60
  296. data/lib/graphql/base_type.rb +0 -226
  297. data/lib/graphql/boolean_type.rb +0 -2
  298. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  299. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  300. data/lib/graphql/compatibility/execution_specification.rb +0 -435
  301. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  302. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -213
  303. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -91
  304. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  305. data/lib/graphql/compatibility/query_parser_specification.rb +0 -264
  306. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -680
  307. data/lib/graphql/compatibility.rb +0 -5
  308. data/lib/graphql/define/assign_argument.rb +0 -12
  309. data/lib/graphql/define/assign_connection.rb +0 -13
  310. data/lib/graphql/define/assign_enum_value.rb +0 -18
  311. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  312. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  313. data/lib/graphql/define/assign_object_field.rb +0 -42
  314. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  315. data/lib/graphql/define/instance_definable.rb +0 -311
  316. data/lib/graphql/define/no_definition_error.rb +0 -7
  317. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  318. data/lib/graphql/define/type_definer.rb +0 -31
  319. data/lib/graphql/define.rb +0 -31
  320. data/lib/graphql/deprecated_dsl.rb +0 -42
  321. data/lib/graphql/directive/deprecated_directive.rb +0 -13
  322. data/lib/graphql/directive/include_directive.rb +0 -2
  323. data/lib/graphql/directive/skip_directive.rb +0 -2
  324. data/lib/graphql/directive.rb +0 -104
  325. data/lib/graphql/enum_type.rb +0 -193
  326. data/lib/graphql/execution/execute.rb +0 -326
  327. data/lib/graphql/execution/flatten.rb +0 -40
  328. data/lib/graphql/execution/instrumentation.rb +0 -92
  329. data/lib/graphql/execution/interpreter/hash_response.rb +0 -46
  330. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  331. data/lib/graphql/execution/typecast.rb +0 -50
  332. data/lib/graphql/field/resolve.rb +0 -59
  333. data/lib/graphql/field.rb +0 -330
  334. data/lib/graphql/float_type.rb +0 -2
  335. data/lib/graphql/function.rb +0 -153
  336. data/lib/graphql/id_type.rb +0 -2
  337. data/lib/graphql/input_object_type.rb +0 -154
  338. data/lib/graphql/int_type.rb +0 -2
  339. data/lib/graphql/interface_type.rb +0 -86
  340. data/lib/graphql/internal_representation/document.rb +0 -27
  341. data/lib/graphql/internal_representation/node.rb +0 -206
  342. data/lib/graphql/internal_representation/print.rb +0 -51
  343. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  344. data/lib/graphql/internal_representation/scope.rb +0 -88
  345. data/lib/graphql/internal_representation/visit.rb +0 -36
  346. data/lib/graphql/internal_representation.rb +0 -7
  347. data/lib/graphql/list_type.rb +0 -80
  348. data/lib/graphql/literal_validation_error.rb +0 -6
  349. data/lib/graphql/non_null_type.rb +0 -81
  350. data/lib/graphql/object_type.rb +0 -141
  351. data/lib/graphql/query/arguments.rb +0 -187
  352. data/lib/graphql/query/arguments_cache.rb +0 -25
  353. data/lib/graphql/query/executor.rb +0 -53
  354. data/lib/graphql/query/literal_input.rb +0 -116
  355. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  356. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  357. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  358. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  359. data/lib/graphql/query/serial_execution.rb +0 -39
  360. data/lib/graphql/relay/array_connection.rb +0 -85
  361. data/lib/graphql/relay/base_connection.rb +0 -172
  362. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  363. data/lib/graphql/relay/connection_resolve.rb +0 -43
  364. data/lib/graphql/relay/connection_type.rb +0 -40
  365. data/lib/graphql/relay/edge.rb +0 -27
  366. data/lib/graphql/relay/edge_type.rb +0 -18
  367. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  368. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  369. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  370. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  371. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  372. data/lib/graphql/relay/mutation/result.rb +0 -38
  373. data/lib/graphql/relay/mutation.rb +0 -190
  374. data/lib/graphql/relay/node.rb +0 -36
  375. data/lib/graphql/relay/page_info.rb +0 -7
  376. data/lib/graphql/relay/relation_connection.rb +0 -190
  377. data/lib/graphql/relay/type_extensions.rb +0 -30
  378. data/lib/graphql/scalar_type.rb +0 -133
  379. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  380. data/lib/graphql/schema/default_parse_error.rb +0 -10
  381. data/lib/graphql/schema/default_type_error.rb +0 -15
  382. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  383. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -26
  384. data/lib/graphql/schema/member/instrumentation.rb +0 -132
  385. data/lib/graphql/schema/middleware_chain.rb +0 -82
  386. data/lib/graphql/schema/possible_types.rb +0 -39
  387. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  388. data/lib/graphql/schema/timeout_middleware.rb +0 -86
  389. data/lib/graphql/schema/traversal.rb +0 -228
  390. data/lib/graphql/schema/validation.rb +0 -303
  391. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  392. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  393. data/lib/graphql/string_type.rb +0 -2
  394. data/lib/graphql/subscriptions/subscription_root.rb +0 -74
  395. data/lib/graphql/tracing/skylight_tracing.rb +0 -62
  396. data/lib/graphql/types/relay/base_field.rb +0 -22
  397. data/lib/graphql/types/relay/base_interface.rb +0 -29
  398. data/lib/graphql/types/relay/base_object.rb +0 -26
  399. data/lib/graphql/types/relay/node_field.rb +0 -43
  400. data/lib/graphql/types/relay/nodes_field.rb +0 -45
  401. data/lib/graphql/union_type.rb +0 -135
  402. data/lib/graphql/upgrader/member.rb +0 -936
  403. data/lib/graphql/upgrader/schema.rb +0 -37
@@ -15,23 +15,110 @@ 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
27
30
  end
28
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
+ NO_EXTRAS
75
+ end
76
+ end
77
+ end
78
+
79
+ NO_EXTRAS = [].freeze
80
+ private_constant :NO_EXTRAS
81
+
29
82
  # Called when this extension is attached to a field.
30
83
  # The field definition may be extended during this method.
31
84
  # @return [void]
32
85
  def apply
33
86
  end
34
87
 
88
+ # Called after the field's definition block has been executed.
89
+ # (Any arguments from the block are present on `field`)
90
+ # @return [void]
91
+ def after_define
92
+ end
93
+
94
+ # @api private
95
+ def after_define_apply
96
+ after_define
97
+ if (configs = self.class.default_argument_configurations)
98
+ existing_keywords = field.all_argument_definitions.map(&:keyword)
99
+ existing_keywords.uniq!
100
+ @added_default_arguments = []
101
+ configs.each do |config|
102
+ argument_args, argument_kwargs = config
103
+ arg_name = argument_args[0]
104
+ if !existing_keywords.include?(arg_name)
105
+ @added_default_arguments << arg_name
106
+ field.argument(*argument_args, **argument_kwargs)
107
+ end
108
+ end
109
+ end
110
+ if (extras = self.class.extras).any?
111
+ @added_extras = extras - field.extras
112
+ field.extras(@added_extras)
113
+ else
114
+ @added_extras = nil
115
+ end
116
+ freeze
117
+ end
118
+
119
+ # @api private
120
+ attr_reader :added_extras
121
+
35
122
  # Called before resolving {#field}. It should either:
36
123
  #
37
124
  # - `yield` values to continue execution; OR
@@ -1,13 +1,29 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  class Schema
3
4
  module FindInheritedValue
5
+ module EmptyObjects
6
+ EMPTY_HASH = {}.freeze
7
+ EMPTY_ARRAY = [].freeze
8
+ end
9
+
10
+ def self.extended(child_cls)
11
+ child_cls.singleton_class.include(EmptyObjects)
12
+ end
13
+
14
+ def self.included(child_cls)
15
+ child_cls.include(EmptyObjects)
16
+ end
17
+
4
18
  private
5
19
 
6
20
  def find_inherited_value(method_name, default_value = nil)
7
21
  if self.is_a?(Class)
8
22
  superclass.respond_to?(method_name, true) ? superclass.send(method_name) : default_value
9
23
  else
10
- ancestors[1..-1].each do |ancestor|
24
+ ancestors_except_self = ancestors
25
+ ancestors_except_self.delete(self)
26
+ ancestors_except_self.each do |ancestor|
11
27
  if ancestor.respond_to?(method_name, true)
12
28
  return ancestor.send(method_name)
13
29
  end
@@ -38,7 +38,7 @@ module GraphQL
38
38
 
39
39
  find_in_directive(directive, path: path)
40
40
  else
41
- type = schema.types[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}."
@@ -66,22 +66,24 @@ module GraphQL
66
66
  end
67
67
 
68
68
  def find_in_type(type, path:)
69
- case type
70
- when GraphQL::ObjectType
69
+ case type.kind.name
70
+ when "OBJECT"
71
71
  find_in_fields_type(type, kind: "object", path: path)
72
- when GraphQL::InterfaceType
72
+ when "INTERFACE"
73
73
  find_in_fields_type(type, kind: "interface", path: path)
74
- when GraphQL::InputObjectType
74
+ when "INPUT_OBJECT"
75
75
  find_in_input_object(type, path: path)
76
- when GraphQL::UnionType
76
+ when "UNION"
77
77
  # Error out if path that was provided is too long
78
78
  # i.e UnionType.PossibleType.aField
79
79
  # Use PossibleType.aField instead.
80
80
  if invalid = path.first
81
81
  raise MemberNotFoundError, "Cannot select union possible type `#{invalid}`. Select the type directly instead."
82
82
  end
83
- when GraphQL::EnumType
83
+ when "ENUM"
84
84
  find_in_enum_type(type, path: path)
85
+ else
86
+ raise "Unexpected find_in_type: #{type.inspect} (#{path})"
85
87
  end
86
88
  end
87
89
 
@@ -90,7 +92,7 @@ module GraphQL
90
92
  field = schema.get_field(type, field_name)
91
93
 
92
94
  if field.nil?
93
- raise MemberNotFoundError, "Could not find field `#{field_name}` on #{kind} type `#{type}`."
95
+ raise MemberNotFoundError, "Could not find field `#{field_name}` on #{kind} type `#{type.graphql_name}`."
94
96
  end
95
97
 
96
98
  return field if path.empty?
@@ -100,7 +102,7 @@ module GraphQL
100
102
 
101
103
  def find_in_field(field, path:)
102
104
  argument_name = path.shift
103
- argument = field.arguments[argument_name]
105
+ argument = field.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
104
106
 
105
107
  if argument.nil?
106
108
  raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
@@ -117,10 +119,10 @@ module GraphQL
117
119
 
118
120
  def find_in_input_object(input_object, path:)
119
121
  field_name = path.shift
120
- input_field = input_object.input_fields[field_name]
122
+ input_field = input_object.get_argument(field_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
121
123
 
122
124
  if input_field.nil?
123
- raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object}`."
125
+ raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object.graphql_name}`."
124
126
  end
125
127
 
126
128
  # Error out if path that was provided is too long
@@ -134,10 +136,10 @@ module GraphQL
134
136
 
135
137
  def find_in_enum_type(enum_type, path:)
136
138
  value_name = path.shift
137
- 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
138
140
 
139
141
  if enum_value.nil?
140
- raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type}`."
142
+ raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type.graphql_name}`."
141
143
  end
142
144
 
143
145
  # Error out if path that was provided is too long
@@ -2,55 +2,42 @@
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
7
+ extend GraphQL::Schema::Member::HasArguments::ArgumentObjectLoader
8
+ extend GraphQL::Schema::Member::ValidatesInput
9
+ extend GraphQL::Schema::Member::HasValidators
10
+
8
11
  include GraphQL::Dig
9
12
 
10
- def initialize(values = nil, ruby_kwargs: nil, context:, defaults_used:)
13
+ # @return [GraphQL::Query::Context] The context for this query
14
+ attr_reader :context
15
+ # @return [GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
16
+ attr_reader :arguments
17
+
18
+ # Ruby-like hash behaviors, read-only
19
+ def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
20
+
21
+ def initialize(arguments, ruby_kwargs:, context:, defaults_used:)
11
22
  @context = context
12
- if ruby_kwargs
13
- @ruby_style_hash = ruby_kwargs
14
- else
15
- @arguments = self.class.arguments_class.new(values, context: context, defaults_used: defaults_used)
16
- # Symbolized, underscored hash:
17
- @ruby_style_hash = @arguments.to_kwargs
18
- end
23
+ @ruby_style_hash = ruby_kwargs
24
+ @arguments = arguments
19
25
  # Apply prepares, not great to have it duplicated here.
20
- @arguments_by_keyword = {}
21
- self.class.arguments.each do |name, arg_defn|
22
- @arguments_by_keyword[arg_defn.keyword] = arg_defn
26
+ self.class.arguments(context).each_value do |arg_defn|
23
27
  ruby_kwargs_key = arg_defn.keyword
24
- loads = arg_defn.loads
25
-
26
- if @ruby_style_hash.key?(ruby_kwargs_key) && loads && !arg_defn.from_resolver?
27
- value = @ruby_style_hash[ruby_kwargs_key]
28
- @ruby_style_hash[ruby_kwargs_key] = if arg_defn.type.list?
29
- GraphQL::Execution::Lazy.all(value.map { |val| load_application_object(arg_defn, loads, val) })
30
- else
31
- load_application_object(arg_defn, loads, value)
28
+ if @ruby_style_hash.key?(ruby_kwargs_key)
29
+ # Weirdly, procs are applied during coercion, but not methods.
30
+ # Probably because these methods require a `self`.
31
+ if arg_defn.prepare.is_a?(Symbol) || context.nil?
32
+ prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
33
+ overwrite_argument(ruby_kwargs_key, prepared_value)
32
34
  end
33
35
  end
34
-
35
- if @ruby_style_hash.key?(ruby_kwargs_key) && arg_defn.prepare
36
- @ruby_style_hash[ruby_kwargs_key] = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
37
- end
38
36
  end
39
37
  end
40
38
 
41
- # @return [GraphQL::Query::Context] The context for this query
42
- attr_reader :context
43
-
44
- # @return [GraphQL::Query::Arguments] The underlying arguments instance
45
- attr_reader :arguments
46
-
47
- # Ruby-like hash behaviors, read-only
48
- def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
49
-
50
39
  def to_h
51
- @ruby_style_hash.inject({}) do |h, (key, value)|
52
- h.merge(key => unwrap_value(value))
53
- end
40
+ unwrap_value(@ruby_style_hash)
54
41
  end
55
42
 
56
43
  def to_hash
@@ -58,7 +45,41 @@ module GraphQL
58
45
  end
59
46
 
60
47
  def prepare
61
- self
48
+ if @context
49
+ object = @context[:current_object]
50
+ # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
51
+ Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
52
+ self
53
+ else
54
+ self
55
+ end
56
+ end
57
+
58
+ def self.authorized?(obj, value, ctx)
59
+ # Authorize each argument (but this doesn't apply if `prepare` is implemented):
60
+ if value.respond_to?(:key?)
61
+ arguments(ctx).each do |_name, input_obj_arg|
62
+ if value.key?(input_obj_arg.keyword) &&
63
+ !input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
64
+ return false
65
+ end
66
+ end
67
+ end
68
+ # It didn't early-return false:
69
+ true
70
+ end
71
+
72
+ def self.one_of
73
+ if !one_of?
74
+ if all_argument_definitions.any? { |arg| arg.type.non_null? }
75
+ raise ArgumentError, "`one_of` may not be used with required arguments -- add `required: false` to argument definitions to use `one_of`"
76
+ end
77
+ directive(GraphQL::Schema::Directive::OneOf)
78
+ end
79
+ end
80
+
81
+ def self.one_of?
82
+ directives.any? { |d| d.is_a?(GraphQL::Schema::Directive::OneOf) }
62
83
  end
63
84
 
64
85
  def unwrap_value(value)
@@ -66,8 +87,8 @@ module GraphQL
66
87
  when Array
67
88
  value.map { |item| unwrap_value(item) }
68
89
  when Hash
69
- value.inject({}) do |h, (key, value)|
70
- h.merge(key => unwrap_value(value))
90
+ value.reduce({}) do |h, (key, value)|
91
+ h.merge!(key => unwrap_value(value))
71
92
  end
72
93
  when InputObject
73
94
  value.to_h
@@ -90,7 +111,7 @@ module GraphQL
90
111
  end
91
112
 
92
113
  def key?(key)
93
- @ruby_style_hash.key?(key) || (@arguments && @arguments.key?(key))
114
+ @ruby_style_hash.key?(key) || (@arguments && @arguments.key?(key)) || false
94
115
  end
95
116
 
96
117
  # A copy of the Ruby-style hash
@@ -99,37 +120,138 @@ module GraphQL
99
120
  end
100
121
 
101
122
  class << self
102
- # @return [Class<GraphQL::Arguments>]
103
- attr_accessor :arguments_class
104
-
105
123
  def argument(*args, **kwargs, &block)
106
124
  argument_defn = super(*args, **kwargs, &block)
125
+ if one_of?
126
+ if argument_defn.type.non_null?
127
+ raise ArgumentError, "Argument '#{argument_defn.path}' must be nullable because it is part of a OneOf type, add `required: false`."
128
+ end
129
+ if argument_defn.default_value?
130
+ raise ArgumentError, "Argument '#{argument_defn.path}' cannot have a default value because it is part of a OneOf type, remove `default_value: ...`."
131
+ end
132
+ end
107
133
  # Add a method access
108
134
  method_name = argument_defn.keyword
109
- define_method(method_name) do
110
- self[method_name]
135
+ class_eval <<-RUBY, __FILE__, __LINE__
136
+ def #{method_name}
137
+ self[#{method_name.inspect}]
138
+ end
139
+ RUBY
140
+ argument_defn
141
+ end
142
+
143
+ def kind
144
+ GraphQL::TypeKinds::INPUT_OBJECT
145
+ end
146
+
147
+ # @api private
148
+ INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
149
+
150
+ def validate_non_null_input(input, ctx, max_errors: nil)
151
+ warden = ctx.warden
152
+
153
+ if input.is_a?(Array)
154
+ return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
155
+ end
156
+
157
+ if !(input.respond_to?(:to_h) || input.respond_to?(:to_unsafe_h))
158
+ # We're not sure it'll act like a hash, so reject it:
159
+ return GraphQL::Query::InputValidationResult.from_problem(INVALID_OBJECT_MESSAGE % { object: JSON.generate(input, quirks_mode: true) })
160
+ end
161
+
162
+ # Inject missing required arguments
163
+ missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
164
+ if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
165
+ m[argument_name] = nil
166
+ end
167
+
168
+ m
111
169
  end
170
+
171
+ result = nil
172
+ [input, missing_required_inputs].each do |args_to_validate|
173
+ args_to_validate.each do |argument_name, value|
174
+ argument = warden.get_argument(self, argument_name)
175
+ # Items in the input that are unexpected
176
+ if argument.nil?
177
+ result ||= Query::InputValidationResult.new
178
+ result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
179
+ else
180
+ # Items in the input that are expected, but have invalid values
181
+ argument_result = argument.type.validate_input(value, ctx)
182
+ result ||= Query::InputValidationResult.new
183
+ if !argument_result.valid?
184
+ result.merge_result!(argument_name, argument_result)
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ if one_of?
191
+ if input.size == 1
192
+ input.each do |name, value|
193
+ if value.nil?
194
+ result ||= Query::InputValidationResult.new
195
+ result.add_problem("'#{graphql_name}' requires exactly one argument, but '#{name}' was `null`.")
196
+ end
197
+ end
198
+ else
199
+ result ||= Query::InputValidationResult.new
200
+ result.add_problem("'#{graphql_name}' requires exactly one argument, but #{input.size} were provided.")
201
+ end
202
+ end
203
+
204
+ result
112
205
  end
113
206
 
114
- def to_graphql
115
- type_defn = GraphQL::InputObjectType.new
116
- type_defn.name = graphql_name
117
- type_defn.description = description
118
- type_defn.metadata[:type_class] = self
119
- type_defn.mutation = mutation
120
- arguments.each do |name, arg|
121
- type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
207
+ def coerce_input(value, ctx)
208
+ if value.nil?
209
+ return nil
210
+ end
211
+
212
+ arguments = coerce_arguments(nil, value, ctx)
213
+
214
+ ctx.schema.after_lazy(arguments) do |resolved_arguments|
215
+ if resolved_arguments.is_a?(GraphQL::Error)
216
+ raise resolved_arguments
217
+ else
218
+ input_obj_instance = self.new(resolved_arguments, ruby_kwargs: resolved_arguments.keyword_arguments, context: ctx, defaults_used: nil)
219
+ input_obj_instance.prepare
220
+ end
122
221
  end
123
- # Make a reference to a classic-style Arguments class
124
- self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
125
- # But use this InputObject class at runtime
126
- type_defn.arguments_class = self
127
- type_defn
128
222
  end
129
223
 
130
- def kind
131
- GraphQL::TypeKinds::INPUT_OBJECT
224
+ # It's funny to think of a _result_ of an input object.
225
+ # This is used for rendering the default value in introspection responses.
226
+ def coerce_result(value, ctx)
227
+ # Allow the application to provide values as :snake_symbols, and convert them to the camelStrings
228
+ value = value.reduce({}) { |memo, (k, v)| memo[Member::BuildType.camelize(k.to_s)] = v; memo }
229
+
230
+ result = {}
231
+
232
+ arguments(ctx).each do |input_key, input_field_defn|
233
+ input_value = value[input_key]
234
+ if value.key?(input_key)
235
+ result[input_key] = if input_value.nil?
236
+ nil
237
+ else
238
+ input_field_defn.type.coerce_result(input_value, ctx)
239
+ end
240
+ end
241
+ end
242
+
243
+ result
244
+ end
245
+ end
246
+
247
+ private
248
+
249
+ def overwrite_argument(key, value)
250
+ # Argument keywords come in frozen from the interpreter, dup them before modifying them.
251
+ if @ruby_style_hash.frozen?
252
+ @ruby_style_hash = @ruby_style_hash.dup
132
253
  end
254
+ @ruby_style_hash[key] = value
133
255
  end
134
256
  end
135
257
  end
@@ -4,14 +4,17 @@ module GraphQL
4
4
  module Interface
5
5
  include GraphQL::Schema::Member::GraphQLTypeNames
6
6
  module DefinitionMethods
7
- include GraphQL::Schema::Member::CachedGraphQLDefinition
8
- include GraphQL::Relay::TypeExtensions
9
7
  include GraphQL::Schema::Member::BaseDSLMethods
8
+ # ConfigurationExtension's responsibilities are in `def included` below
10
9
  include GraphQL::Schema::Member::TypeSystemHelpers
11
10
  include GraphQL::Schema::Member::HasFields
12
11
  include GraphQL::Schema::Member::HasPath
13
12
  include GraphQL::Schema::Member::RelayShortcuts
14
13
  include GraphQL::Schema::Member::Scoped
14
+ include GraphQL::Schema::Member::HasAstNode
15
+ include GraphQL::Schema::Member::HasUnresolvedTypeError
16
+ include GraphQL::Schema::Member::HasDirectives
17
+ include GraphQL::Schema::Member::HasInterfaces
15
18
 
16
19
  # Methods defined in this block will be:
17
20
  # - Added as class methods to this interface
@@ -20,19 +23,14 @@ module GraphQL
20
23
  self::DefinitionMethods.module_eval(&block)
21
24
  end
22
25
 
23
- # The interface is visible if any of its possible types are visible
26
+ # @see {Schema::Warden} hides interfaces without visible implementations
24
27
  def visible?(context)
25
- context.schema.possible_types(self).each do |type|
26
- if context.schema.visible?(type, context)
27
- return true
28
- end
29
- end
30
- false
28
+ true
31
29
  end
32
30
 
33
31
  # The interface is accessible if any of its possible types are accessible
34
32
  def accessible?(context)
35
- context.schema.possible_types(self).each do |type|
33
+ context.schema.possible_types(self, context).each do |type|
36
34
  if context.schema.accessible?(type, context)
37
35
  return true
38
36
  end
@@ -40,6 +38,14 @@ module GraphQL
40
38
  false
41
39
  end
42
40
 
41
+ def type_membership_class(membership_class = nil)
42
+ if membership_class
43
+ @type_membership_class = membership_class
44
+ else
45
+ @type_membership_class || find_inherited_value(:type_membership_class, GraphQL::Schema::TypeMembership)
46
+ end
47
+ end
48
+
43
49
  # Here's the tricky part. Make sure behavior keeps making its way down the inheritance chain.
44
50
  def included(child_class)
45
51
  if !child_class.is_a?(Class)
@@ -49,9 +55,11 @@ module GraphQL
49
55
  # We need this before we can call `own_interfaces`
50
56
  child_class.extend(Schema::Interface::DefinitionMethods)
51
57
 
52
- child_class.own_interfaces << self
53
- child_class.interfaces.reverse_each do |interface_defn|
54
- child_class.extend(interface_defn::DefinitionMethods)
58
+ child_class.type_membership_class(self.type_membership_class)
59
+ child_class.ancestors.reverse_each do |ancestor|
60
+ if ancestor.const_defined?(:DefinitionMethods)
61
+ child_class.extend(ancestor::DefinitionMethods)
62
+ end
55
63
  end
56
64
 
57
65
  # Use an instance variable to tell whether it's been included previously or not;
@@ -63,9 +71,15 @@ module GraphQL
63
71
  child_class.const_set(:DefinitionMethods, defn_methods_module)
64
72
  child_class.extend(child_class::DefinitionMethods)
65
73
  end
74
+ child_class.introspection(introspection)
75
+ child_class.description(description)
76
+ # If interfaces are mixed into each other, only define this class once
77
+ if !child_class.const_defined?(:UnresolvedTypeError, false)
78
+ add_unresolved_type_error(child_class)
79
+ end
66
80
  elsif child_class < GraphQL::Schema::Object
67
81
  # This is being included into an object type, make sure it's using `implements(...)`
68
- backtrace_line = caller(0, 10).find { |line| line.include?("schema/object.rb") && line.include?("in `implements'")}
82
+ backtrace_line = caller(0, 10).find { |line| line.include?("schema/member/has_interfaces.rb") && line.include?("in `implements'")}
69
83
  if !backtrace_line
70
84
  raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
71
85
  end
@@ -84,40 +98,11 @@ module GraphQL
84
98
  end
85
99
  end
86
100
 
87
- def to_graphql
88
- type_defn = GraphQL::InterfaceType.new
89
- type_defn.name = graphql_name
90
- type_defn.description = description
91
- type_defn.orphan_types = orphan_types
92
- fields.each do |field_name, field_inst|
93
- field_defn = field_inst.graphql_definition
94
- type_defn.fields[field_defn.name] = field_defn
95
- end
96
- type_defn.metadata[:type_class] = self
97
- if respond_to?(:resolve_type)
98
- type_defn.resolve_type = method(:resolve_type)
99
- end
100
- type_defn
101
- end
102
-
103
101
  def kind
104
102
  GraphQL::TypeKinds::INTERFACE
105
103
  end
106
-
107
- protected
108
-
109
- def own_interfaces
110
- @own_interfaces ||= []
111
- end
112
-
113
- def interfaces
114
- own_interfaces + (own_interfaces.map { |i| i.own_interfaces }).flatten
115
- end
116
104
  end
117
105
 
118
- # Extend this _after_ `DefinitionMethods` is defined, so it will be used
119
- extend GraphQL::Schema::Member::AcceptsDefinition
120
-
121
106
  extend DefinitionMethods
122
107
 
123
108
  def unwrap