graphql 1.12.12 → 2.2.14

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

Potentially problematic release.


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

Files changed (392) 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 +14 -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 +6 -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 +19 -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/ast/analyzer.rb +7 -0
  48. data/lib/graphql/analysis/ast/field_usage.rb +55 -1
  49. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  50. data/lib/graphql/analysis/ast/query_complexity.rb +88 -140
  51. data/lib/graphql/analysis/ast/query_depth.rb +7 -3
  52. data/lib/graphql/analysis/ast/visitor.rb +50 -42
  53. data/lib/graphql/analysis/ast.rb +26 -23
  54. data/lib/graphql/analysis.rb +0 -7
  55. data/lib/graphql/backtrace/table.rb +4 -22
  56. data/lib/graphql/backtrace/trace.rb +93 -0
  57. data/lib/graphql/backtrace/tracer.rb +8 -6
  58. data/lib/graphql/backtrace.rb +3 -8
  59. data/lib/graphql/coercion_error.rb +1 -9
  60. data/lib/graphql/dataloader/async_dataloader.rb +85 -0
  61. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  62. data/lib/graphql/dataloader/request.rb +5 -0
  63. data/lib/graphql/dataloader/source.rb +120 -31
  64. data/lib/graphql/dataloader.rb +168 -142
  65. data/lib/graphql/date_encoding_error.rb +16 -0
  66. data/lib/graphql/dig.rb +1 -1
  67. data/lib/graphql/duration_encoding_error.rb +16 -0
  68. data/lib/graphql/execution/errors.rb +12 -81
  69. data/lib/graphql/execution/interpreter/arguments.rb +2 -2
  70. data/lib/graphql/execution/interpreter/arguments_cache.rb +36 -34
  71. data/lib/graphql/execution/interpreter/resolve.rb +32 -2
  72. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +170 -0
  73. data/lib/graphql/execution/interpreter/runtime.rb +414 -341
  74. data/lib/graphql/execution/interpreter.rb +122 -80
  75. data/lib/graphql/execution/lazy.rb +11 -21
  76. data/lib/graphql/execution/lookahead.rb +125 -54
  77. data/lib/graphql/execution/multiplex.rb +4 -172
  78. data/lib/graphql/execution.rb +11 -4
  79. data/lib/graphql/integer_encoding_error.rb +18 -2
  80. data/lib/graphql/introspection/directive_location_enum.rb +2 -2
  81. data/lib/graphql/introspection/directive_type.rb +5 -3
  82. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  83. data/lib/graphql/introspection/entry_points.rb +11 -18
  84. data/lib/graphql/introspection/enum_value_type.rb +2 -2
  85. data/lib/graphql/introspection/field_type.rb +3 -3
  86. data/lib/graphql/introspection/input_value_type.rb +10 -4
  87. data/lib/graphql/introspection/schema_type.rb +12 -5
  88. data/lib/graphql/introspection/type_type.rb +25 -12
  89. data/lib/graphql/introspection.rb +6 -2
  90. data/lib/graphql/language/block_string.rb +37 -25
  91. data/lib/graphql/language/definition_slice.rb +1 -1
  92. data/lib/graphql/language/document_from_schema_definition.rb +78 -65
  93. data/lib/graphql/language/lexer.rb +345 -1467
  94. data/lib/graphql/language/nodes.rb +145 -91
  95. data/lib/graphql/language/parser.rb +701 -1921
  96. data/lib/graphql/language/printer.rb +351 -155
  97. data/lib/graphql/language/sanitized_printer.rb +25 -27
  98. data/lib/graphql/language/static_visitor.rb +167 -0
  99. data/lib/graphql/language/token.rb +0 -4
  100. data/lib/graphql/language/visitor.rb +188 -141
  101. data/lib/graphql/language.rb +1 -0
  102. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  103. data/lib/graphql/name_validator.rb +0 -4
  104. data/lib/graphql/pagination/active_record_relation_connection.rb +37 -8
  105. data/lib/graphql/pagination/array_connection.rb +8 -6
  106. data/lib/graphql/pagination/connection.rb +61 -7
  107. data/lib/graphql/pagination/connections.rb +22 -23
  108. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  109. data/lib/graphql/pagination/relation_connection.rb +60 -28
  110. data/lib/graphql/query/context/scoped_context.rb +101 -0
  111. data/lib/graphql/query/context.rb +109 -189
  112. data/lib/graphql/query/input_validation_result.rb +10 -1
  113. data/lib/graphql/query/null_context.rb +14 -29
  114. data/lib/graphql/query/validation_pipeline.rb +15 -39
  115. data/lib/graphql/query/variable_validation_error.rb +2 -2
  116. data/lib/graphql/query/variables.rb +35 -17
  117. data/lib/graphql/query.rb +78 -65
  118. data/lib/graphql/railtie.rb +8 -109
  119. data/lib/graphql/rake_task/validate.rb +1 -1
  120. data/lib/graphql/rake_task.rb +30 -11
  121. data/lib/graphql/relay/range_add.rb +9 -16
  122. data/lib/graphql/relay.rb +0 -15
  123. data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
  124. data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
  125. data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
  126. data/lib/graphql/rubocop.rb +4 -0
  127. data/lib/graphql/schema/addition.rb +78 -45
  128. data/lib/graphql/schema/always_visible.rb +10 -0
  129. data/lib/graphql/schema/argument.rb +134 -80
  130. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  131. data/lib/graphql/schema/build_from_definition.rb +60 -38
  132. data/lib/graphql/schema/directive/feature.rb +1 -1
  133. data/lib/graphql/schema/directive/flagged.rb +2 -2
  134. data/lib/graphql/schema/directive/include.rb +1 -1
  135. data/lib/graphql/schema/directive/one_of.rb +24 -0
  136. data/lib/graphql/schema/directive/skip.rb +1 -1
  137. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  138. data/lib/graphql/schema/directive/transform.rb +2 -2
  139. data/lib/graphql/schema/directive.rb +33 -21
  140. data/lib/graphql/schema/enum.rb +93 -46
  141. data/lib/graphql/schema/enum_value.rb +4 -21
  142. data/lib/graphql/schema/field/connection_extension.rb +6 -16
  143. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  144. data/lib/graphql/schema/field.rb +432 -337
  145. data/lib/graphql/schema/field_extension.rb +86 -2
  146. data/lib/graphql/schema/find_inherited_value.rb +3 -7
  147. data/lib/graphql/schema/finder.rb +5 -5
  148. data/lib/graphql/schema/has_single_input_argument.rb +156 -0
  149. data/lib/graphql/schema/input_object.rb +88 -90
  150. data/lib/graphql/schema/interface.rb +19 -59
  151. data/lib/graphql/schema/introspection_system.rb +6 -9
  152. data/lib/graphql/schema/late_bound_type.rb +8 -2
  153. data/lib/graphql/schema/list.rb +18 -7
  154. data/lib/graphql/schema/loader.rb +3 -3
  155. data/lib/graphql/schema/member/base_dsl_methods.rb +18 -19
  156. data/lib/graphql/schema/member/build_type.rb +16 -13
  157. data/lib/graphql/schema/member/has_arguments.rb +288 -84
  158. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  159. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  160. data/lib/graphql/schema/member/has_directives.rb +81 -61
  161. data/lib/graphql/schema/member/has_fields.rb +149 -31
  162. data/lib/graphql/schema/member/has_interfaces.rb +143 -0
  163. data/lib/graphql/schema/member/has_validators.rb +32 -6
  164. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  165. data/lib/graphql/schema/member/scoped.rb +19 -0
  166. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  167. data/lib/graphql/schema/member/validates_input.rb +6 -6
  168. data/lib/graphql/schema/member.rb +1 -6
  169. data/lib/graphql/schema/mutation.rb +0 -9
  170. data/lib/graphql/schema/non_null.rb +7 -7
  171. data/lib/graphql/schema/object.rb +30 -119
  172. data/lib/graphql/schema/printer.rb +23 -25
  173. data/lib/graphql/schema/relay_classic_mutation.rb +13 -90
  174. data/lib/graphql/schema/resolver/has_payload_type.rb +46 -11
  175. data/lib/graphql/schema/resolver.rb +101 -102
  176. data/lib/graphql/schema/scalar.rb +20 -21
  177. data/lib/graphql/schema/subscription.rb +45 -17
  178. data/lib/graphql/schema/timeout.rb +25 -29
  179. data/lib/graphql/schema/type_expression.rb +1 -1
  180. data/lib/graphql/schema/type_membership.rb +21 -4
  181. data/lib/graphql/schema/union.rb +15 -15
  182. data/lib/graphql/schema/unique_within_type.rb +1 -1
  183. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  184. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  185. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  186. data/lib/graphql/schema/validator/format_validator.rb +4 -5
  187. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  188. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  189. data/lib/graphql/schema/validator/numericality_validator.rb +13 -2
  190. data/lib/graphql/schema/validator/required_validator.rb +29 -15
  191. data/lib/graphql/schema/validator.rb +35 -27
  192. data/lib/graphql/schema/warden.rb +259 -132
  193. data/lib/graphql/schema/wrapper.rb +0 -5
  194. data/lib/graphql/schema.rb +658 -989
  195. data/lib/graphql/static_validation/all_rules.rb +3 -1
  196. data/lib/graphql/static_validation/base_visitor.rb +14 -28
  197. data/lib/graphql/static_validation/definition_dependencies.rb +7 -2
  198. data/lib/graphql/static_validation/error.rb +3 -1
  199. data/lib/graphql/static_validation/literal_validator.rb +21 -4
  200. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  201. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
  202. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  203. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +13 -13
  204. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  205. data/lib/graphql/static_validation/rules/fields_will_merge.rb +54 -28
  206. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  207. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  208. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  209. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  210. data/lib/graphql/static_validation/rules/query_root_exists.rb +17 -0
  211. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +26 -0
  212. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -3
  213. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
  214. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +13 -7
  215. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  216. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +13 -7
  217. data/lib/graphql/static_validation/validation_context.rb +16 -6
  218. data/lib/graphql/static_validation/validator.rb +11 -27
  219. data/lib/graphql/static_validation.rb +0 -3
  220. data/lib/graphql/string_encoding_error.rb +13 -3
  221. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +46 -9
  222. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  223. data/lib/graphql/subscriptions/event.rb +75 -37
  224. data/lib/graphql/subscriptions/serialize.rb +25 -3
  225. data/lib/graphql/subscriptions.rb +59 -47
  226. data/lib/graphql/testing/helpers.rb +129 -0
  227. data/lib/graphql/testing.rb +2 -0
  228. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  229. data/lib/graphql/tracing/active_support_notifications_tracing.rb +6 -20
  230. data/lib/graphql/tracing/appoptics_trace.rb +251 -0
  231. data/lib/graphql/tracing/appoptics_tracing.rb +2 -2
  232. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  233. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  234. data/lib/graphql/tracing/data_dog_trace.rb +183 -0
  235. data/lib/graphql/tracing/data_dog_tracing.rb +25 -15
  236. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +10 -28
  237. data/lib/graphql/tracing/legacy_trace.rb +69 -0
  238. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  239. data/lib/graphql/tracing/notifications_trace.rb +45 -0
  240. data/lib/graphql/tracing/notifications_tracing.rb +59 -0
  241. data/lib/graphql/tracing/platform_trace.rb +118 -0
  242. data/lib/graphql/tracing/platform_tracing.rb +46 -49
  243. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +4 -2
  244. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  245. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  246. data/lib/graphql/tracing/scout_trace.rb +72 -0
  247. data/lib/graphql/tracing/sentry_trace.rb +112 -0
  248. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  249. data/lib/graphql/tracing/trace.rb +76 -0
  250. data/lib/graphql/tracing.rb +20 -41
  251. data/lib/graphql/type_kinds.rb +6 -3
  252. data/lib/graphql/types/big_int.rb +5 -1
  253. data/lib/graphql/types/int.rb +1 -1
  254. data/lib/graphql/types/iso_8601_date.rb +17 -6
  255. data/lib/graphql/types/iso_8601_date_time.rb +12 -1
  256. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  257. data/lib/graphql/types/relay/base_connection.rb +16 -6
  258. data/lib/graphql/types/relay/connection_behaviors.rb +82 -32
  259. data/lib/graphql/types/relay/edge_behaviors.rb +36 -7
  260. data/lib/graphql/types/relay/has_node_field.rb +2 -2
  261. data/lib/graphql/types/relay/has_nodes_field.rb +2 -2
  262. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  263. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  264. data/lib/graphql/types/relay.rb +0 -3
  265. data/lib/graphql/types/string.rb +2 -2
  266. data/lib/graphql/types.rb +1 -0
  267. data/lib/graphql/unauthorized_error.rb +1 -1
  268. data/lib/graphql/version.rb +1 -1
  269. data/lib/graphql.rb +33 -95
  270. data/readme.md +13 -6
  271. metadata +102 -185
  272. data/lib/graphql/analysis/analyze_query.rb +0 -98
  273. data/lib/graphql/analysis/field_usage.rb +0 -45
  274. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  275. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  276. data/lib/graphql/analysis/query_complexity.rb +0 -88
  277. data/lib/graphql/analysis/query_depth.rb +0 -43
  278. data/lib/graphql/analysis/reducer_state.rb +0 -48
  279. data/lib/graphql/argument.rb +0 -131
  280. data/lib/graphql/authorization.rb +0 -82
  281. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  282. data/lib/graphql/backwards_compatibility.rb +0 -61
  283. data/lib/graphql/base_type.rb +0 -230
  284. data/lib/graphql/boolean_type.rb +0 -2
  285. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  286. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  287. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  288. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  289. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  290. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  291. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  292. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  293. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  294. data/lib/graphql/compatibility.rb +0 -5
  295. data/lib/graphql/define/assign_argument.rb +0 -12
  296. data/lib/graphql/define/assign_connection.rb +0 -13
  297. data/lib/graphql/define/assign_enum_value.rb +0 -18
  298. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  299. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  300. data/lib/graphql/define/assign_object_field.rb +0 -42
  301. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  302. data/lib/graphql/define/instance_definable.rb +0 -240
  303. data/lib/graphql/define/no_definition_error.rb +0 -7
  304. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  305. data/lib/graphql/define/type_definer.rb +0 -31
  306. data/lib/graphql/define.rb +0 -31
  307. data/lib/graphql/deprecated_dsl.rb +0 -47
  308. data/lib/graphql/deprecation.rb +0 -13
  309. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  310. data/lib/graphql/directive/include_directive.rb +0 -2
  311. data/lib/graphql/directive/skip_directive.rb +0 -2
  312. data/lib/graphql/directive.rb +0 -111
  313. data/lib/graphql/enum_type.rb +0 -129
  314. data/lib/graphql/execution/execute.rb +0 -333
  315. data/lib/graphql/execution/flatten.rb +0 -40
  316. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  317. data/lib/graphql/execution/typecast.rb +0 -50
  318. data/lib/graphql/field/resolve.rb +0 -59
  319. data/lib/graphql/field.rb +0 -226
  320. data/lib/graphql/filter.rb +0 -53
  321. data/lib/graphql/float_type.rb +0 -2
  322. data/lib/graphql/function.rb +0 -128
  323. data/lib/graphql/id_type.rb +0 -2
  324. data/lib/graphql/input_object_type.rb +0 -138
  325. data/lib/graphql/int_type.rb +0 -2
  326. data/lib/graphql/interface_type.rb +0 -72
  327. data/lib/graphql/internal_representation/document.rb +0 -27
  328. data/lib/graphql/internal_representation/node.rb +0 -206
  329. data/lib/graphql/internal_representation/print.rb +0 -51
  330. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  331. data/lib/graphql/internal_representation/scope.rb +0 -88
  332. data/lib/graphql/internal_representation/visit.rb +0 -36
  333. data/lib/graphql/internal_representation.rb +0 -7
  334. data/lib/graphql/language/lexer.rl +0 -262
  335. data/lib/graphql/language/parser.y +0 -543
  336. data/lib/graphql/list_type.rb +0 -80
  337. data/lib/graphql/non_null_type.rb +0 -71
  338. data/lib/graphql/object_type.rb +0 -130
  339. data/lib/graphql/query/arguments.rb +0 -189
  340. data/lib/graphql/query/arguments_cache.rb +0 -24
  341. data/lib/graphql/query/executor.rb +0 -52
  342. data/lib/graphql/query/literal_input.rb +0 -136
  343. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  344. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  345. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  346. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  347. data/lib/graphql/query/serial_execution.rb +0 -40
  348. data/lib/graphql/relay/array_connection.rb +0 -83
  349. data/lib/graphql/relay/base_connection.rb +0 -189
  350. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  351. data/lib/graphql/relay/connection_resolve.rb +0 -43
  352. data/lib/graphql/relay/connection_type.rb +0 -41
  353. data/lib/graphql/relay/edge.rb +0 -27
  354. data/lib/graphql/relay/edge_type.rb +0 -19
  355. data/lib/graphql/relay/edges_instrumentation.rb +0 -40
  356. data/lib/graphql/relay/global_id_resolve.rb +0 -18
  357. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  358. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  359. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  360. data/lib/graphql/relay/mutation/result.rb +0 -38
  361. data/lib/graphql/relay/mutation.rb +0 -106
  362. data/lib/graphql/relay/node.rb +0 -39
  363. data/lib/graphql/relay/page_info.rb +0 -7
  364. data/lib/graphql/relay/relation_connection.rb +0 -188
  365. data/lib/graphql/relay/type_extensions.rb +0 -32
  366. data/lib/graphql/scalar_type.rb +0 -91
  367. data/lib/graphql/schema/base_64_bp.rb +0 -26
  368. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  369. data/lib/graphql/schema/default_parse_error.rb +0 -10
  370. data/lib/graphql/schema/default_type_error.rb +0 -17
  371. data/lib/graphql/schema/member/accepts_definition.rb +0 -152
  372. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -31
  373. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  374. data/lib/graphql/schema/middleware_chain.rb +0 -82
  375. data/lib/graphql/schema/possible_types.rb +0 -44
  376. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  377. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  378. data/lib/graphql/schema/traversal.rb +0 -228
  379. data/lib/graphql/schema/validation.rb +0 -313
  380. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  381. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  382. data/lib/graphql/static_validation/type_stack.rb +0 -216
  383. data/lib/graphql/string_type.rb +0 -2
  384. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  385. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  386. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  387. data/lib/graphql/types/relay/default_relay.rb +0 -27
  388. data/lib/graphql/types/relay/node_field.rb +0 -25
  389. data/lib/graphql/types/relay/nodes_field.rb +0 -27
  390. data/lib/graphql/union_type.rb +0 -115
  391. data/lib/graphql/upgrader/member.rb +0 -937
  392. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -4,6 +4,16 @@ module GraphQL
4
4
  class Schema
5
5
  class Member
6
6
  module HasDirectives
7
+ def self.extended(child_cls)
8
+ super
9
+ child_cls.module_eval { self.own_directives = nil }
10
+ end
11
+
12
+ def inherited(child_cls)
13
+ super
14
+ child_cls.own_directives = nil
15
+ end
16
+
7
17
  # Create an instance of `dir_class` for `self`, using `options`.
8
18
  #
9
19
  # It removes a previously-attached instance of `dir_class`, if there is one.
@@ -11,8 +21,7 @@ module GraphQL
11
21
  # @return [void]
12
22
  def directive(dir_class, **options)
13
23
  @own_directives ||= []
14
- remove_directive(dir_class)
15
- @own_directives << dir_class.new(self, **options)
24
+ HasDirectives.add_directive(self, @own_directives, dir_class, options)
16
25
  nil
17
26
  end
18
27
 
@@ -20,78 +29,89 @@ module GraphQL
20
29
  # @param dir_class [Class<GraphQL::Schema::Directive>]
21
30
  # @return [viod]
22
31
  def remove_directive(dir_class)
23
- @own_directives && @own_directives.reject! { |d| d.is_a?(dir_class) }
32
+ HasDirectives.remove_directive(@own_directives, dir_class)
24
33
  nil
25
34
  end
26
35
 
27
- NO_DIRECTIVES = [].freeze
28
-
29
36
  def directives
30
- case self
31
- when Class
32
- inherited_directives = if superclass.respond_to?(:directives)
33
- superclass.directives
34
- else
35
- NO_DIRECTIVES
36
- end
37
- if inherited_directives.any? && @own_directives
38
- dirs = []
39
- merge_directives(dirs, inherited_directives)
40
- merge_directives(dirs, @own_directives)
41
- dirs
42
- elsif @own_directives
43
- @own_directives
44
- elsif inherited_directives.any?
45
- inherited_directives
46
- else
47
- NO_DIRECTIVES
48
- end
49
- when Module
50
- dirs = nil
51
- self.ancestors.reverse_each do |ancestor|
52
- if ancestor.respond_to?(:own_directives) &&
53
- (anc_dirs = ancestor.own_directives).any?
37
+ HasDirectives.get_directives(self, @own_directives, :directives)
38
+ end
39
+
40
+ class << self
41
+ def add_directive(schema_member, directives, directive_class, directive_options)
42
+ remove_directive(directives, directive_class) unless directive_class.repeatable?
43
+ directives << directive_class.new(schema_member, **directive_options)
44
+ end
45
+
46
+ def remove_directive(directives, directive_class)
47
+ directives && directives.reject! { |d| d.is_a?(directive_class) }
48
+ end
49
+
50
+ def get_directives(schema_member, directives, directives_method)
51
+ case schema_member
52
+ when Class
53
+ inherited_directives = if schema_member.superclass.respond_to?(directives_method)
54
+ get_directives(schema_member.superclass, schema_member.superclass.public_send(directives_method), directives_method)
55
+ else
56
+ GraphQL::EmptyObjects::EMPTY_ARRAY
57
+ end
58
+ if inherited_directives.any? && directives
59
+ dirs = []
60
+ merge_directives(dirs, inherited_directives)
61
+ merge_directives(dirs, directives)
62
+ dirs
63
+ elsif directives
64
+ directives
65
+ elsif inherited_directives.any?
66
+ inherited_directives
67
+ else
68
+ GraphQL::EmptyObjects::EMPTY_ARRAY
69
+ end
70
+ when Module
71
+ dirs = nil
72
+ schema_member.ancestors.reverse_each do |ancestor|
73
+ if ancestor.respond_to?(:own_directives) &&
74
+ (anc_dirs = ancestor.own_directives).any?
75
+ dirs ||= []
76
+ merge_directives(dirs, anc_dirs)
77
+ end
78
+ end
79
+ if directives
54
80
  dirs ||= []
55
- merge_directives(dirs, anc_dirs)
81
+ merge_directives(dirs, directives)
56
82
  end
83
+ dirs || GraphQL::EmptyObjects::EMPTY_ARRAY
84
+ when HasDirectives
85
+ directives || GraphQL::EmptyObjects::EMPTY_ARRAY
86
+ else
87
+ raise "Invariant: how could #{schema_member} not be a Class, Module, or instance of HasDirectives?"
57
88
  end
58
- if own_directives
59
- dirs ||= []
60
- merge_directives(dirs, own_directives)
61
- end
62
- dirs || NO_DIRECTIVES
63
- when HasDirectives
64
- @own_directives || NO_DIRECTIVES
65
- else
66
- raise "Invariant: how could #{self} not be a Class, Module, or instance of HasDirectives?"
67
89
  end
68
- end
69
-
70
- protected
71
-
72
- def own_directives
73
- @own_directives
74
- end
75
90
 
76
- private
91
+ private
77
92
 
78
- # Modify `target` by adding items from `dirs` such that:
79
- # - Any name conflict is overriden by the incoming member of `dirs`
80
- # - Any other member of `dirs` is appended
81
- # @param target [Array<GraphQL::Schema::Directive>]
82
- # @param dirs [Array<GraphQL::Schema::Directive>]
83
- # @return [void]
84
- def merge_directives(target, dirs)
85
- dirs.each do |dir|
86
- if (idx = target.find_index { |d| d.graphql_name == dir.graphql_name })
87
- target.slice!(idx)
88
- target.insert(idx, dir)
89
- else
90
- target << dir
93
+ # Modify `target` by adding items from `dirs` such that:
94
+ # - Any name conflict is overriden by the incoming member of `dirs`
95
+ # - Any other member of `dirs` is appended
96
+ # @param target [Array<GraphQL::Schema::Directive>]
97
+ # @param dirs [Array<GraphQL::Schema::Directive>]
98
+ # @return [void]
99
+ def merge_directives(target, dirs)
100
+ dirs.each do |dir|
101
+ if (idx = target.find_index { |d| d.graphql_name == dir.graphql_name })
102
+ target.slice!(idx)
103
+ target.insert(idx, dir)
104
+ else
105
+ target << dir
106
+ end
91
107
  end
108
+ nil
92
109
  end
93
- nil
94
110
  end
111
+
112
+ protected
113
+
114
+ attr_accessor :own_directives
95
115
  end
96
116
  end
97
117
  end
@@ -3,7 +3,7 @@
3
3
  module GraphQL
4
4
  class Schema
5
5
  class Member
6
- # Shared code for Object and Interface
6
+ # Shared code for Objects, Interfaces, Mutations, Subscriptions
7
7
  module HasFields
8
8
  # Add a field to this object or interface with the given definition
9
9
  # @see {GraphQL::Schema::Field#initialize} for method signature
@@ -14,31 +14,6 @@ module GraphQL
14
14
  field_defn
15
15
  end
16
16
 
17
- # @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
18
- def fields
19
- # Local overrides take precedence over inherited fields
20
- all_fields = {}
21
- ancestors.reverse_each do |ancestor|
22
- if ancestor.respond_to?(:own_fields)
23
- all_fields.merge!(ancestor.own_fields)
24
- end
25
- end
26
- all_fields
27
- end
28
-
29
- def get_field(field_name)
30
- if (f = own_fields[field_name])
31
- f
32
- else
33
- for ancestor in ancestors
34
- if ancestor.respond_to?(:own_fields) && f = ancestor.own_fields[field_name]
35
- return f
36
- end
37
- end
38
- nil
39
- end
40
- end
41
-
42
17
  # A list of Ruby keywords.
43
18
  #
44
19
  # @api private
@@ -61,10 +36,27 @@ module GraphQL
61
36
  def add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?)
62
37
  # Check that `field_defn.original_name` equals `resolver_method` and `method_sym` --
63
38
  # that shows that no override value was given manually.
64
- if method_conflict_warning && CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) && field_defn.original_name == field_defn.resolver_method && field_defn.original_name == field_defn.method_sym
39
+ if method_conflict_warning &&
40
+ CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) &&
41
+ field_defn.original_name == field_defn.resolver_method &&
42
+ field_defn.original_name == field_defn.method_sym &&
43
+ field_defn.hash_key == NOT_CONFIGURED &&
44
+ field_defn.dig_keys.nil?
65
45
  warn(conflict_field_name_warning(field_defn))
66
46
  end
67
- own_fields[field_defn.name] = field_defn
47
+ prev_defn = own_fields[field_defn.name]
48
+
49
+ case prev_defn
50
+ when nil
51
+ own_fields[field_defn.name] = field_defn
52
+ when Array
53
+ prev_defn << field_defn
54
+ when GraphQL::Schema::Field
55
+ own_fields[field_defn.name] = [prev_defn, field_defn]
56
+ else
57
+ raise "Invariant: unexpected previous field definition for #{field_defn.name.inspect}: #{prev_defn.inspect}"
58
+ end
59
+
68
60
  nil
69
61
  end
70
62
 
@@ -80,20 +72,146 @@ module GraphQL
80
72
  end
81
73
 
82
74
  def global_id_field(field_name, **kwargs)
83
- id_resolver = GraphQL::Relay::GlobalIdResolve.new(type: self)
75
+ type = self
84
76
  field field_name, "ID", **kwargs, null: false
85
77
  define_method(field_name) do
86
- id_resolver.call(object, {}, context)
78
+ context.schema.id_from_object(object, type, context)
87
79
  end
88
80
  end
89
81
 
90
- # @return [Array<GraphQL::Schema::Field>] Fields defined on this class _specifically_, not parent classes
82
+ # @return [Hash<String => GraphQL::Schema::Field, Array<GraphQL::Schema::Field>>] Fields defined on this class _specifically_, not parent classes
91
83
  def own_fields
92
84
  @own_fields ||= {}
93
85
  end
94
86
 
87
+ def all_field_definitions
88
+ all_fields = {}
89
+ ancestors.reverse_each do |ancestor|
90
+ if ancestor.respond_to?(:own_fields)
91
+ all_fields.merge!(ancestor.own_fields)
92
+ end
93
+ end
94
+ all_fields = all_fields.values
95
+ all_fields.flatten!
96
+ all_fields
97
+ end
98
+
99
+ module InterfaceMethods
100
+ def get_field(field_name, context = GraphQL::Query::NullContext.instance)
101
+ warden = Warden.from_context(context)
102
+ for ancestor in ancestors
103
+ if ancestor.respond_to?(:own_fields) &&
104
+ (f_entry = ancestor.own_fields[field_name]) &&
105
+ (f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
106
+ return f
107
+ end
108
+ end
109
+ nil
110
+ end
111
+
112
+ # @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
113
+ def fields(context = GraphQL::Query::NullContext.instance)
114
+ warden = Warden.from_context(context)
115
+ # Local overrides take precedence over inherited fields
116
+ visible_fields = {}
117
+ for ancestor in ancestors
118
+ if ancestor.respond_to?(:own_fields)
119
+ ancestor.own_fields.each do |field_name, fields_entry|
120
+ # Choose the most local definition that passes `.visible?` --
121
+ # stop checking for fields by name once one has been found.
122
+ if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
123
+ visible_fields[field_name] = f
124
+ end
125
+ end
126
+ end
127
+ end
128
+ visible_fields
129
+ end
130
+ end
131
+
132
+ module ObjectMethods
133
+ def get_field(field_name, context = GraphQL::Query::NullContext.instance)
134
+ # Objects need to check that the interface implementation is visible, too
135
+ warden = Warden.from_context(context)
136
+ ancs = ancestors
137
+ i = 0
138
+ while (ancestor = ancs[i])
139
+ if ancestor.respond_to?(:own_fields) &&
140
+ visible_interface_implementation?(ancestor, context, warden) &&
141
+ (f_entry = ancestor.own_fields[field_name]) &&
142
+ (f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
143
+ return f
144
+ end
145
+ i += 1
146
+ end
147
+ nil
148
+ end
149
+
150
+ # @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
151
+ def fields(context = GraphQL::Query::NullContext.instance)
152
+ # Objects need to check that the interface implementation is visible, too
153
+ warden = Warden.from_context(context)
154
+ # Local overrides take precedence over inherited fields
155
+ visible_fields = {}
156
+ for ancestor in ancestors
157
+ if ancestor.respond_to?(:own_fields) && visible_interface_implementation?(ancestor, context, warden)
158
+ ancestor.own_fields.each do |field_name, fields_entry|
159
+ # Choose the most local definition that passes `.visible?` --
160
+ # stop checking for fields by name once one has been found.
161
+ if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
162
+ visible_fields[field_name] = f
163
+ end
164
+ end
165
+ end
166
+ end
167
+ visible_fields
168
+ end
169
+ end
170
+
171
+ def self.included(child_class)
172
+ # Included in an interface definition methods module
173
+ child_class.include(InterfaceMethods)
174
+ super
175
+ end
176
+
177
+ def self.extended(child_class)
178
+ child_class.extend(ObjectMethods)
179
+ super
180
+ end
181
+
95
182
  private
96
183
 
184
+ def inherited(subclass)
185
+ super
186
+ subclass.class_eval do
187
+ @own_fields ||= nil
188
+ @field_class ||= nil
189
+ end
190
+ end
191
+
192
+ # If `type` is an interface, and `self` has a type membership for `type`, then make sure it's visible.
193
+ def visible_interface_implementation?(type, context, warden)
194
+ if type.respond_to?(:kind) && type.kind.interface?
195
+ implements_this_interface = false
196
+ implementation_is_visible = false
197
+ warden.interface_type_memberships(self, context).each do |tm|
198
+ if tm.abstract_type == type
199
+ implements_this_interface ||= true
200
+ if warden.visible_type_membership?(tm, context)
201
+ implementation_is_visible = true
202
+ break
203
+ end
204
+ end
205
+ end
206
+ # It's possible this interface came by way of `include` in another interface which this
207
+ # object type _does_ implement, and that's ok
208
+ implements_this_interface ? implementation_is_visible : true
209
+ else
210
+ # If there's no implementation, then we're looking at Ruby-style inheritance instead
211
+ true
212
+ end
213
+ end
214
+
97
215
  # @param [GraphQL::Schema::Field]
98
216
  # @return [String] A warning to give when this field definition might conflict with a built-in method
99
217
  def conflict_field_name_warning(field_defn)
@@ -0,0 +1,143 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphQL
4
+ class Schema
5
+ class Member
6
+ module HasInterfaces
7
+ def implements(*new_interfaces, **options)
8
+ new_memberships = []
9
+ new_interfaces.each do |int|
10
+ if int.is_a?(Module)
11
+ unless int.include?(GraphQL::Schema::Interface)
12
+ raise "#{int} cannot be implemented since it's not a GraphQL Interface. Use `include` for plain Ruby modules."
13
+ end
14
+
15
+ new_memberships << int.type_membership_class.new(int, self, **options)
16
+
17
+ # Include the methods here,
18
+ # `.fields` will use the inheritance chain
19
+ # to find inherited fields
20
+ include(int)
21
+
22
+ # If this interface has interfaces of its own, add those, too
23
+ int.interfaces.each do |next_interface|
24
+ implements(next_interface)
25
+ end
26
+ elsif int.is_a?(String) || int.is_a?(GraphQL::Schema::LateBoundType)
27
+ if options.any?
28
+ raise ArgumentError, "`implements(...)` doesn't support options with late-loaded types yet. Remove #{options} and open an issue to request this feature."
29
+ end
30
+ new_memberships << int
31
+ else
32
+ raise ArgumentError, "Unexpected interface definition (expected module): #{int} (#{int.class})"
33
+ end
34
+ end
35
+
36
+ # Remove any String or late-bound interfaces which are being replaced
37
+ own_interface_type_memberships.reject! { |old_i_m|
38
+ if !(old_i_m.respond_to?(:abstract_type) && old_i_m.abstract_type.is_a?(Module))
39
+ old_int_type = old_i_m.respond_to?(:abstract_type) ? old_i_m.abstract_type : old_i_m
40
+ old_name = Schema::Member::BuildType.to_type_name(old_int_type)
41
+
42
+ new_memberships.any? { |new_i_m|
43
+ new_int_type = new_i_m.respond_to?(:abstract_type) ? new_i_m.abstract_type : new_i_m
44
+ new_name = Schema::Member::BuildType.to_type_name(new_int_type)
45
+
46
+ new_name == old_name
47
+ }
48
+ end
49
+ }
50
+ own_interface_type_memberships.concat(new_memberships)
51
+ end
52
+
53
+ def own_interface_type_memberships
54
+ @own_interface_type_memberships ||= []
55
+ end
56
+
57
+ def interface_type_memberships
58
+ own_interface_type_memberships
59
+ end
60
+
61
+ module ClassConfigured
62
+ # This combination of extended -> inherited -> extended
63
+ # means that the base class (`Schema::Object`) *won't*
64
+ # have the superclass-related code in `InheritedInterfaces`,
65
+ # but child classes of `Schema::Object` will have it.
66
+ # That way, we don't need a `superclass.respond_to?(...)` check.
67
+ def inherited(child_class)
68
+ super
69
+ child_class.extend(InheritedInterfaces)
70
+ end
71
+
72
+ module InheritedInterfaces
73
+ def interfaces(context = GraphQL::Query::NullContext.instance)
74
+ visible_interfaces = super
75
+ inherited_interfaces = superclass.interfaces(context)
76
+ if visible_interfaces.any?
77
+ if inherited_interfaces.any?
78
+ visible_interfaces.concat(inherited_interfaces)
79
+ visible_interfaces.uniq!
80
+ end
81
+ visible_interfaces
82
+ elsif inherited_interfaces.any?
83
+ inherited_interfaces
84
+ else
85
+ EmptyObjects::EMPTY_ARRAY
86
+ end
87
+ end
88
+
89
+ def interface_type_memberships
90
+ own_tms = super
91
+ inherited_tms = superclass.interface_type_memberships
92
+ if inherited_tms.size > 0
93
+ own_tms + inherited_tms
94
+ else
95
+ own_tms
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ # param context [Query::Context] If omitted, skip filtering.
102
+ def interfaces(context = GraphQL::Query::NullContext.instance)
103
+ warden = Warden.from_context(context)
104
+ visible_interfaces = nil
105
+ own_interface_type_memberships.each do |type_membership|
106
+ case type_membership
107
+ when Schema::TypeMembership
108
+ if warden.visible_type_membership?(type_membership, context)
109
+ visible_interfaces ||= []
110
+ visible_interfaces << type_membership.abstract_type
111
+ end
112
+ when String, Schema::LateBoundType
113
+ # During initialization, `type_memberships` can hold late-bound types
114
+ visible_interfaces ||= []
115
+ visible_interfaces << type_membership
116
+ else
117
+ raise "Invariant: Unexpected type_membership #{type_membership.class}: #{type_membership.inspect}"
118
+ end
119
+ end
120
+ if visible_interfaces
121
+ visible_interfaces.uniq!
122
+ visible_interfaces
123
+ else
124
+ EmptyObjects::EMPTY_ARRAY
125
+ end
126
+ end
127
+
128
+ private
129
+
130
+ def self.extended(child_class)
131
+ child_class.extend(ClassConfigured)
132
+ end
133
+
134
+ def inherited(subclass)
135
+ super
136
+ subclass.class_eval do
137
+ @own_interface_type_memberships ||= nil
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
@@ -3,7 +3,7 @@ module GraphQL
3
3
  class Schema
4
4
  class Member
5
5
  module HasValidators
6
- include Schema::FindInheritedValue::EmptyObjects
6
+ include GraphQL::EmptyObjects
7
7
 
8
8
  # Build {GraphQL::Schema::Validator}s based on the given configuration
9
9
  # and use them for this schema member
@@ -18,12 +18,38 @@ module GraphQL
18
18
 
19
19
  # @return [Array<GraphQL::Schema::Validator>]
20
20
  def validators
21
- own_validators = @own_validators || EMPTY_ARRAY
22
- if self.is_a?(Class) && superclass.respond_to?(:validators) && (inherited_validators = superclass.validators).any?
23
- inherited_validators + own_validators
24
- else
25
- own_validators
21
+ @own_validators || EMPTY_ARRAY
22
+ end
23
+
24
+ module ClassConfigured
25
+ def inherited(child_cls)
26
+ super
27
+ child_cls.extend(ClassValidators)
26
28
  end
29
+
30
+ module ClassValidators
31
+ include GraphQL::EmptyObjects
32
+
33
+ def validators
34
+ inherited_validators = superclass.validators
35
+ if inherited_validators.any?
36
+ if @own_validators.nil?
37
+ inherited_validators
38
+ else
39
+ inherited_validators + @own_validators
40
+ end
41
+ elsif @own_validators.nil?
42
+ EMPTY_ARRAY
43
+ else
44
+ @own_validators
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def self.extended(child_cls)
51
+ super
52
+ child_cls.extend(ClassConfigured)
27
53
  end
28
54
  end
29
55
  end
@@ -6,21 +6,40 @@ module GraphQL
6
6
  module RelayShortcuts
7
7
  def edge_type_class(new_edge_type_class = nil)
8
8
  if new_edge_type_class
9
+ initialize_relay_metadata
9
10
  @edge_type_class = new_edge_type_class
10
11
  else
11
- @edge_type_class || find_inherited_value(:edge_type_class, Types::Relay::BaseEdge)
12
+ # Don't call `ancestor.edge_type_class`
13
+ # because we don't want a fallback from any ancestors --
14
+ # only apply the fallback if _no_ ancestor has a configured value!
15
+ for ancestor in self.ancestors
16
+ if ancestor.respond_to?(:configured_edge_type_class, true) && (etc = ancestor.configured_edge_type_class)
17
+ return etc
18
+ end
19
+ end
20
+ Types::Relay::BaseEdge
12
21
  end
13
22
  end
14
23
 
15
24
  def connection_type_class(new_connection_type_class = nil)
16
25
  if new_connection_type_class
26
+ initialize_relay_metadata
17
27
  @connection_type_class = new_connection_type_class
18
28
  else
19
- @connection_type_class || find_inherited_value(:connection_type_class, Types::Relay::BaseConnection)
29
+ # Don't call `ancestor.connection_type_class`
30
+ # because we don't want a fallback from any ancestors --
31
+ # only apply the fallback if _no_ ancestor has a configured value!
32
+ for ancestor in self.ancestors
33
+ if ancestor.respond_to?(:configured_connection_type_class, true) && (ctc = ancestor.configured_connection_type_class)
34
+ return ctc
35
+ end
36
+ end
37
+ Types::Relay::BaseConnection
20
38
  end
21
39
  end
22
40
 
23
41
  def edge_type
42
+ initialize_relay_metadata
24
43
  @edge_type ||= begin
25
44
  edge_name = self.graphql_name + "Edge"
26
45
  node_type_class = self
@@ -32,6 +51,7 @@ module GraphQL
32
51
  end
33
52
 
34
53
  def connection_type
54
+ initialize_relay_metadata
35
55
  @connection_type ||= begin
36
56
  conn_name = self.graphql_name + "Connection"
37
57
  edge_type_class = self.edge_type
@@ -41,6 +61,31 @@ module GraphQL
41
61
  end
42
62
  end
43
63
  end
64
+
65
+ protected
66
+
67
+ def configured_connection_type_class
68
+ @connection_type_class
69
+ end
70
+
71
+ def configured_edge_type_class
72
+ @edge_type_class
73
+ end
74
+
75
+ attr_writer :edge_type, :connection_type, :connection_type_class, :edge_type_class
76
+
77
+ private
78
+
79
+ # If one of thse values is accessed, initialize all the instance variables to retain
80
+ # a consistent object shape.
81
+ def initialize_relay_metadata
82
+ if !defined?(@connection_type)
83
+ @connection_type = nil
84
+ @edge_type = nil
85
+ @connection_type_class = nil
86
+ @edge_type_class = nil
87
+ end
88
+ end
44
89
  end
45
90
  end
46
91
  end