graphql 1.13.24 → 2.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
  3. data/lib/generators/graphql/install/templates/base_mutation.erb +2 -0
  4. data/lib/generators/graphql/install/templates/mutation_type.erb +2 -0
  5. data/lib/generators/graphql/install_generator.rb +50 -1
  6. data/lib/generators/graphql/mutation_delete_generator.rb +1 -1
  7. data/lib/generators/graphql/mutation_update_generator.rb +1 -1
  8. data/lib/generators/graphql/orm_mutations_base.rb +1 -1
  9. data/lib/generators/graphql/relay.rb +21 -18
  10. data/lib/generators/graphql/templates/base_argument.erb +2 -0
  11. data/lib/generators/graphql/templates/base_connection.erb +2 -0
  12. data/lib/generators/graphql/templates/base_edge.erb +2 -0
  13. data/lib/generators/graphql/templates/base_enum.erb +2 -0
  14. data/lib/generators/graphql/templates/base_field.erb +2 -0
  15. data/lib/generators/graphql/templates/base_input_object.erb +2 -0
  16. data/lib/generators/graphql/templates/base_interface.erb +2 -0
  17. data/lib/generators/graphql/templates/base_object.erb +2 -0
  18. data/lib/generators/graphql/templates/base_resolver.erb +8 -0
  19. data/lib/generators/graphql/templates/base_scalar.erb +2 -0
  20. data/lib/generators/graphql/templates/base_union.erb +2 -0
  21. data/lib/generators/graphql/templates/graphql_controller.erb +2 -0
  22. data/lib/generators/graphql/templates/loader.erb +2 -0
  23. data/lib/generators/graphql/templates/mutation.erb +2 -0
  24. data/lib/generators/graphql/templates/node_type.erb +2 -0
  25. data/lib/generators/graphql/templates/query_type.erb +2 -0
  26. data/lib/generators/graphql/templates/schema.erb +8 -0
  27. data/lib/generators/graphql/type_generator.rb +1 -1
  28. data/lib/graphql/analysis/analyzer.rb +90 -0
  29. data/lib/graphql/analysis/field_usage.rb +65 -28
  30. data/lib/graphql/analysis/max_query_complexity.rb +11 -17
  31. data/lib/graphql/analysis/max_query_depth.rb +13 -19
  32. data/lib/graphql/analysis/query_complexity.rb +236 -61
  33. data/lib/graphql/analysis/query_depth.rb +38 -23
  34. data/lib/graphql/analysis/visitor.rb +280 -0
  35. data/lib/graphql/analysis.rb +93 -6
  36. data/lib/graphql/autoload.rb +38 -0
  37. data/lib/graphql/backtrace/table.rb +118 -73
  38. data/lib/graphql/backtrace.rb +2 -25
  39. data/lib/graphql/coercion_error.rb +1 -9
  40. data/lib/graphql/current.rb +57 -0
  41. data/lib/graphql/dashboard/detailed_traces.rb +47 -0
  42. data/lib/graphql/dashboard/installable.rb +22 -0
  43. data/lib/graphql/dashboard/limiters.rb +93 -0
  44. data/lib/graphql/dashboard/operation_store.rb +199 -0
  45. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
  46. data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
  47. data/lib/graphql/dashboard/statics/charts.min.css +1 -0
  48. data/lib/graphql/dashboard/statics/dashboard.css +30 -0
  49. data/lib/graphql/dashboard/statics/dashboard.js +143 -0
  50. data/lib/graphql/dashboard/statics/header-icon.png +0 -0
  51. data/lib/graphql/dashboard/statics/icon.png +0 -0
  52. data/lib/graphql/dashboard/subscriptions.rb +96 -0
  53. data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
  54. data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
  55. data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
  56. data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
  57. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
  58. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
  59. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
  60. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
  61. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
  62. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
  63. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
  64. data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
  65. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
  66. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
  67. data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
  68. data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
  69. data/lib/graphql/dashboard.rb +158 -0
  70. data/lib/graphql/dataloader/active_record_association_source.rb +84 -0
  71. data/lib/graphql/dataloader/active_record_source.rb +47 -0
  72. data/lib/graphql/dataloader/async_dataloader.rb +101 -0
  73. data/lib/graphql/dataloader/null_dataloader.rb +11 -2
  74. data/lib/graphql/dataloader/request.rb +5 -0
  75. data/lib/graphql/dataloader/source.rb +103 -47
  76. data/lib/graphql/dataloader.rb +174 -148
  77. data/lib/graphql/dig.rb +3 -2
  78. data/lib/graphql/duration_encoding_error.rb +16 -0
  79. data/lib/graphql/execution/errors.rb +12 -82
  80. data/lib/graphql/execution/interpreter/argument_value.rb +5 -1
  81. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  82. data/lib/graphql/execution/interpreter/arguments_cache.rb +30 -35
  83. data/lib/graphql/execution/interpreter/resolve.rb +32 -2
  84. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +215 -0
  85. data/lib/graphql/execution/interpreter/runtime.rb +525 -502
  86. data/lib/graphql/execution/interpreter.rb +127 -81
  87. data/lib/graphql/execution/lazy.rb +7 -21
  88. data/lib/graphql/execution/lookahead.rb +133 -55
  89. data/lib/graphql/execution/multiplex.rb +6 -176
  90. data/lib/graphql/execution.rb +11 -4
  91. data/lib/graphql/introspection/directive_location_enum.rb +1 -1
  92. data/lib/graphql/introspection/directive_type.rb +1 -1
  93. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  94. data/lib/graphql/introspection/entry_points.rb +10 -17
  95. data/lib/graphql/introspection/field_type.rb +1 -1
  96. data/lib/graphql/introspection/schema_type.rb +8 -11
  97. data/lib/graphql/introspection/type_type.rb +13 -6
  98. data/lib/graphql/introspection.rb +4 -3
  99. data/lib/graphql/invalid_name_error.rb +1 -1
  100. data/lib/graphql/invalid_null_error.rb +20 -17
  101. data/lib/graphql/language/block_string.rb +34 -18
  102. data/lib/graphql/language/cache.rb +13 -0
  103. data/lib/graphql/language/comment.rb +18 -0
  104. data/lib/graphql/language/definition_slice.rb +1 -1
  105. data/lib/graphql/language/document_from_schema_definition.rb +114 -80
  106. data/lib/graphql/language/lexer.rb +375 -1489
  107. data/lib/graphql/language/nodes.rb +189 -104
  108. data/lib/graphql/language/parser.rb +807 -1941
  109. data/lib/graphql/language/printer.rb +366 -163
  110. data/lib/graphql/language/sanitized_printer.rb +21 -23
  111. data/lib/graphql/language/static_visitor.rb +171 -0
  112. data/lib/graphql/language/visitor.rb +189 -138
  113. data/lib/graphql/language.rb +62 -1
  114. data/lib/graphql/load_application_object_failed_error.rb +5 -1
  115. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  116. data/lib/graphql/pagination/array_connection.rb +8 -6
  117. data/lib/graphql/pagination/connection.rb +61 -7
  118. data/lib/graphql/pagination/connections.rb +3 -28
  119. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -2
  120. data/lib/graphql/pagination/relation_connection.rb +2 -0
  121. data/lib/graphql/query/context/scoped_context.rb +101 -0
  122. data/lib/graphql/query/context.rb +131 -225
  123. data/lib/graphql/query/input_validation_result.rb +1 -1
  124. data/lib/graphql/query/null_context.rb +11 -33
  125. data/lib/graphql/query/partial.rb +179 -0
  126. data/lib/graphql/query/validation_pipeline.rb +14 -37
  127. data/lib/graphql/query/variable_validation_error.rb +1 -1
  128. data/lib/graphql/query/variables.rb +6 -19
  129. data/lib/graphql/query.rb +162 -98
  130. data/lib/graphql/railtie.rb +15 -109
  131. data/lib/graphql/rake_task/validate.rb +1 -1
  132. data/lib/graphql/rake_task.rb +30 -11
  133. data/lib/graphql/relay/range_add.rb +9 -20
  134. data/lib/graphql/relay.rb +0 -15
  135. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
  136. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
  137. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
  138. data/lib/graphql/rubocop.rb +2 -0
  139. data/lib/graphql/schema/addition.rb +70 -33
  140. data/lib/graphql/schema/always_visible.rb +15 -0
  141. data/lib/graphql/schema/argument.rb +104 -59
  142. data/lib/graphql/schema/base_64_encoder.rb +3 -5
  143. data/lib/graphql/schema/build_from_definition.rb +154 -74
  144. data/lib/graphql/schema/directive/flagged.rb +4 -2
  145. data/lib/graphql/schema/directive/one_of.rb +24 -0
  146. data/lib/graphql/schema/directive/specified_by.rb +14 -0
  147. data/lib/graphql/schema/directive/transform.rb +1 -1
  148. data/lib/graphql/schema/directive.rb +47 -24
  149. data/lib/graphql/schema/enum.rb +137 -65
  150. data/lib/graphql/schema/enum_value.rb +11 -26
  151. data/lib/graphql/schema/field/connection_extension.rb +6 -16
  152. data/lib/graphql/schema/field/scope_extension.rb +8 -1
  153. data/lib/graphql/schema/field.rb +399 -404
  154. data/lib/graphql/schema/field_extension.rb +2 -5
  155. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  156. data/lib/graphql/schema/has_single_input_argument.rb +160 -0
  157. data/lib/graphql/schema/input_object.rb +144 -99
  158. data/lib/graphql/schema/interface.rb +34 -51
  159. data/lib/graphql/schema/introspection_system.rb +12 -26
  160. data/lib/graphql/schema/late_bound_type.rb +12 -2
  161. data/lib/graphql/schema/list.rb +3 -9
  162. data/lib/graphql/schema/loader.rb +4 -6
  163. data/lib/graphql/schema/member/base_dsl_methods.rb +32 -18
  164. data/lib/graphql/schema/member/build_type.rb +15 -9
  165. data/lib/graphql/schema/member/has_arguments.rb +192 -96
  166. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  167. data/lib/graphql/schema/member/has_dataloader.rb +62 -0
  168. data/lib/graphql/schema/member/has_deprecation_reason.rb +18 -4
  169. data/lib/graphql/schema/member/has_directives.rb +81 -61
  170. data/lib/graphql/schema/member/has_fields.rb +119 -39
  171. data/lib/graphql/schema/member/has_interfaces.rb +66 -23
  172. data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
  173. data/lib/graphql/schema/member/has_validators.rb +32 -6
  174. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  175. data/lib/graphql/schema/member/scoped.rb +19 -0
  176. data/lib/graphql/schema/member/type_system_helpers.rb +32 -2
  177. data/lib/graphql/schema/member/validates_input.rb +4 -4
  178. data/lib/graphql/schema/member.rb +1 -6
  179. data/lib/graphql/schema/mutation.rb +7 -9
  180. data/lib/graphql/schema/non_null.rb +1 -7
  181. data/lib/graphql/schema/object.rb +42 -49
  182. data/lib/graphql/schema/printer.rb +12 -8
  183. data/lib/graphql/schema/ractor_shareable.rb +79 -0
  184. data/lib/graphql/schema/relay_classic_mutation.rb +12 -124
  185. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  186. data/lib/graphql/schema/resolver.rb +96 -81
  187. data/lib/graphql/schema/scalar.rb +10 -30
  188. data/lib/graphql/schema/subscription.rb +60 -14
  189. data/lib/graphql/schema/timeout.rb +44 -31
  190. data/lib/graphql/schema/type_expression.rb +2 -2
  191. data/lib/graphql/schema/type_membership.rb +3 -0
  192. data/lib/graphql/schema/union.rb +12 -19
  193. data/lib/graphql/schema/unique_within_type.rb +1 -1
  194. data/lib/graphql/schema/validator/all_validator.rb +62 -0
  195. data/lib/graphql/schema/validator/required_validator.rb +60 -10
  196. data/lib/graphql/schema/validator.rb +5 -3
  197. data/lib/graphql/schema/visibility/migration.rb +188 -0
  198. data/lib/graphql/schema/visibility/profile.rb +445 -0
  199. data/lib/graphql/schema/visibility/visit.rb +190 -0
  200. data/lib/graphql/schema/visibility.rb +311 -0
  201. data/lib/graphql/schema/warden.rb +318 -94
  202. data/lib/graphql/schema/wrapper.rb +0 -5
  203. data/lib/graphql/schema.rb +1148 -1085
  204. data/lib/graphql/static_validation/all_rules.rb +4 -3
  205. data/lib/graphql/static_validation/base_visitor.rb +11 -27
  206. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  207. data/lib/graphql/static_validation/error.rb +2 -2
  208. data/lib/graphql/static_validation/literal_validator.rb +24 -7
  209. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
  210. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
  211. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
  212. data/lib/graphql/static_validation/rules/directives_are_defined.rb +13 -7
  213. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +14 -12
  214. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
  215. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +48 -6
  216. data/lib/graphql/static_validation/rules/fields_will_merge.rb +90 -27
  217. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +10 -2
  218. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  219. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
  220. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  221. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  222. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
  223. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
  224. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  225. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  226. data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
  227. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +5 -5
  228. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +5 -5
  229. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
  230. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +19 -9
  231. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
  232. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
  233. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  234. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
  235. data/lib/graphql/static_validation/validation_context.rb +21 -5
  236. data/lib/graphql/static_validation/validator.rb +12 -26
  237. data/lib/graphql/static_validation.rb +0 -3
  238. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +14 -6
  239. data/lib/graphql/subscriptions/broadcast_analyzer.rb +11 -5
  240. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +40 -1
  241. data/lib/graphql/subscriptions/event.rb +24 -12
  242. data/lib/graphql/subscriptions/serialize.rb +3 -1
  243. data/lib/graphql/subscriptions.rb +48 -32
  244. data/lib/graphql/testing/helpers.rb +158 -0
  245. data/lib/graphql/testing.rb +2 -0
  246. data/lib/graphql/tracing/active_support_notifications_trace.rb +27 -0
  247. data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
  248. data/lib/graphql/tracing/appoptics_trace.rb +259 -0
  249. data/lib/graphql/tracing/appoptics_tracing.rb +9 -2
  250. data/lib/graphql/tracing/appsignal_trace.rb +54 -0
  251. data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
  252. data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
  253. data/lib/graphql/tracing/data_dog_trace.rb +71 -0
  254. data/lib/graphql/tracing/data_dog_tracing.rb +3 -0
  255. data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
  256. data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
  257. data/lib/graphql/tracing/detailed_trace.rb +93 -0
  258. data/lib/graphql/{execution/instrumentation.rb → tracing/legacy_hooks_trace.rb} +11 -28
  259. data/lib/graphql/tracing/legacy_trace.rb +12 -0
  260. data/lib/graphql/tracing/monitor_trace.rb +283 -0
  261. data/lib/graphql/tracing/new_relic_trace.rb +68 -0
  262. data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
  263. data/lib/graphql/tracing/notifications_trace.rb +195 -0
  264. data/lib/graphql/tracing/notifications_tracing.rb +2 -0
  265. data/lib/graphql/tracing/null_trace.rb +9 -0
  266. data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
  267. data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
  268. data/lib/graphql/tracing/perfetto_trace.rb +734 -0
  269. data/lib/graphql/tracing/platform_trace.rb +123 -0
  270. data/lib/graphql/tracing/platform_tracing.rb +28 -41
  271. data/lib/graphql/tracing/{prometheus_tracing → prometheus_trace}/graphql_collector.rb +6 -2
  272. data/lib/graphql/tracing/prometheus_trace.rb +93 -0
  273. data/lib/graphql/tracing/prometheus_tracing.rb +5 -3
  274. data/lib/graphql/tracing/scout_trace.rb +49 -0
  275. data/lib/graphql/tracing/scout_tracing.rb +2 -0
  276. data/lib/graphql/tracing/sentry_trace.rb +80 -0
  277. data/lib/graphql/tracing/statsd_trace.rb +48 -0
  278. data/lib/graphql/tracing/statsd_tracing.rb +2 -0
  279. data/lib/graphql/tracing/trace.rb +186 -0
  280. data/lib/graphql/tracing.rb +32 -52
  281. data/lib/graphql/type_kinds.rb +8 -4
  282. data/lib/graphql/types/iso_8601_date.rb +4 -1
  283. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  284. data/lib/graphql/types/iso_8601_duration.rb +77 -0
  285. data/lib/graphql/types/relay/base_connection.rb +16 -6
  286. data/lib/graphql/types/relay/connection_behaviors.rb +65 -23
  287. data/lib/graphql/types/relay/edge_behaviors.rb +33 -5
  288. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  289. data/lib/graphql/types/relay/page_info_behaviors.rb +11 -2
  290. data/lib/graphql/types/relay.rb +0 -3
  291. data/lib/graphql/types/string.rb +1 -1
  292. data/lib/graphql/types.rb +18 -10
  293. data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
  294. data/lib/graphql/version.rb +1 -1
  295. data/lib/graphql.rb +76 -123
  296. data/readme.md +13 -3
  297. metadata +225 -142
  298. data/lib/graphql/analysis/analyze_query.rb +0 -98
  299. data/lib/graphql/analysis/ast/analyzer.rb +0 -84
  300. data/lib/graphql/analysis/ast/field_usage.rb +0 -55
  301. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -23
  302. data/lib/graphql/analysis/ast/max_query_depth.rb +0 -22
  303. data/lib/graphql/analysis/ast/query_complexity.rb +0 -230
  304. data/lib/graphql/analysis/ast/query_depth.rb +0 -56
  305. data/lib/graphql/analysis/ast/visitor.rb +0 -269
  306. data/lib/graphql/analysis/ast.rb +0 -91
  307. data/lib/graphql/analysis/reducer_state.rb +0 -48
  308. data/lib/graphql/argument.rb +0 -131
  309. data/lib/graphql/authorization.rb +0 -82
  310. data/lib/graphql/backtrace/inspect_result.rb +0 -50
  311. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  312. data/lib/graphql/backtrace/tracer.rb +0 -81
  313. data/lib/graphql/backwards_compatibility.rb +0 -61
  314. data/lib/graphql/base_type.rb +0 -232
  315. data/lib/graphql/boolean_type.rb +0 -2
  316. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  317. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  318. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  319. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  320. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  321. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  322. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  323. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  324. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  325. data/lib/graphql/compatibility.rb +0 -5
  326. data/lib/graphql/define/assign_argument.rb +0 -12
  327. data/lib/graphql/define/assign_connection.rb +0 -13
  328. data/lib/graphql/define/assign_enum_value.rb +0 -18
  329. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  330. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  331. data/lib/graphql/define/assign_object_field.rb +0 -42
  332. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  333. data/lib/graphql/define/instance_definable.rb +0 -255
  334. data/lib/graphql/define/no_definition_error.rb +0 -7
  335. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  336. data/lib/graphql/define/type_definer.rb +0 -31
  337. data/lib/graphql/define.rb +0 -31
  338. data/lib/graphql/deprecated_dsl.rb +0 -55
  339. data/lib/graphql/deprecation.rb +0 -9
  340. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  341. data/lib/graphql/directive/include_directive.rb +0 -2
  342. data/lib/graphql/directive/skip_directive.rb +0 -2
  343. data/lib/graphql/directive.rb +0 -107
  344. data/lib/graphql/enum_type.rb +0 -133
  345. data/lib/graphql/execution/execute.rb +0 -333
  346. data/lib/graphql/execution/flatten.rb +0 -40
  347. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  348. data/lib/graphql/execution/typecast.rb +0 -50
  349. data/lib/graphql/field/resolve.rb +0 -59
  350. data/lib/graphql/field.rb +0 -226
  351. data/lib/graphql/filter.rb +0 -53
  352. data/lib/graphql/float_type.rb +0 -2
  353. data/lib/graphql/function.rb +0 -128
  354. data/lib/graphql/id_type.rb +0 -2
  355. data/lib/graphql/input_object_type.rb +0 -138
  356. data/lib/graphql/int_type.rb +0 -2
  357. data/lib/graphql/interface_type.rb +0 -72
  358. data/lib/graphql/internal_representation/document.rb +0 -27
  359. data/lib/graphql/internal_representation/node.rb +0 -206
  360. data/lib/graphql/internal_representation/print.rb +0 -51
  361. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  362. data/lib/graphql/internal_representation/scope.rb +0 -88
  363. data/lib/graphql/internal_representation/visit.rb +0 -36
  364. data/lib/graphql/internal_representation.rb +0 -7
  365. data/lib/graphql/language/lexer.rl +0 -260
  366. data/lib/graphql/language/parser.y +0 -550
  367. data/lib/graphql/language/token.rb +0 -34
  368. data/lib/graphql/list_type.rb +0 -80
  369. data/lib/graphql/non_null_type.rb +0 -71
  370. data/lib/graphql/object_type.rb +0 -130
  371. data/lib/graphql/query/arguments.rb +0 -189
  372. data/lib/graphql/query/arguments_cache.rb +0 -24
  373. data/lib/graphql/query/executor.rb +0 -52
  374. data/lib/graphql/query/literal_input.rb +0 -136
  375. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  376. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  377. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  378. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  379. data/lib/graphql/query/serial_execution.rb +0 -40
  380. data/lib/graphql/relay/array_connection.rb +0 -83
  381. data/lib/graphql/relay/base_connection.rb +0 -189
  382. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  383. data/lib/graphql/relay/connection_resolve.rb +0 -43
  384. data/lib/graphql/relay/connection_type.rb +0 -54
  385. data/lib/graphql/relay/edge.rb +0 -27
  386. data/lib/graphql/relay/edge_type.rb +0 -19
  387. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  388. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  389. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  390. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  391. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  392. data/lib/graphql/relay/mutation/result.rb +0 -38
  393. data/lib/graphql/relay/mutation.rb +0 -106
  394. data/lib/graphql/relay/node.rb +0 -39
  395. data/lib/graphql/relay/page_info.rb +0 -7
  396. data/lib/graphql/relay/relation_connection.rb +0 -188
  397. data/lib/graphql/relay/type_extensions.rb +0 -32
  398. data/lib/graphql/scalar_type.rb +0 -91
  399. data/lib/graphql/schema/base_64_bp.rb +0 -26
  400. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  401. data/lib/graphql/schema/default_parse_error.rb +0 -10
  402. data/lib/graphql/schema/default_type_error.rb +0 -17
  403. data/lib/graphql/schema/invalid_type_error.rb +0 -7
  404. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  405. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  406. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  407. data/lib/graphql/schema/middleware_chain.rb +0 -82
  408. data/lib/graphql/schema/null_mask.rb +0 -11
  409. data/lib/graphql/schema/possible_types.rb +0 -44
  410. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  411. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  412. data/lib/graphql/schema/traversal.rb +0 -228
  413. data/lib/graphql/schema/validation.rb +0 -313
  414. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  415. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  416. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
  417. data/lib/graphql/static_validation/type_stack.rb +0 -216
  418. data/lib/graphql/string_type.rb +0 -2
  419. data/lib/graphql/subscriptions/instrumentation.rb +0 -79
  420. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  421. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  422. data/lib/graphql/types/relay/default_relay.rb +0 -31
  423. data/lib/graphql/types/relay/node_field.rb +0 -24
  424. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  425. data/lib/graphql/union_type.rb +0 -115
  426. data/lib/graphql/upgrader/member.rb +0 -937
  427. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -4,41 +4,30 @@ require 'set'
4
4
 
5
5
  module GraphQL
6
6
  class Schema
7
- # Restrict access to a {GraphQL::Schema} with a user-defined filter.
7
+ # Restrict access to a {GraphQL::Schema} with a user-defined `visible?` implementations.
8
8
  #
9
9
  # When validating and executing a query, all access to schema members
10
10
  # should go through a warden. If you access the schema directly,
11
11
  # you may show a client something that it shouldn't be allowed to see.
12
12
  #
13
- # @example Hidding private fields
14
- # private_members = -> (member, ctx) { member.metadata[:private] }
15
- # result = Schema.execute(query_string, except: private_members)
16
- #
17
- # @example Custom filter implementation
18
- # # It must respond to `#call(member)`.
19
- # class MissingRequiredFlags
20
- # def initialize(user)
21
- # @user = user
22
- # end
23
- #
24
- # # Return `false` if any required flags are missing
25
- # def call(member, ctx)
26
- # member.metadata[:required_flags].any? do |flag|
27
- # !@user.has_flag?(flag)
28
- # end
29
- # end
30
- # end
31
- #
32
- # # Then, use the custom filter in query:
33
- # missing_required_flags = MissingRequiredFlags.new(current_user)
34
- #
35
- # # This query can only access members which match the user's flags
36
- # result = Schema.execute(query_string, except: missing_required_flags)
37
- #
38
13
  # @api private
39
14
  class Warden
40
15
  def self.from_context(context)
41
- (context.respond_to?(:warden) && context.warden) || PassThruWarden
16
+ context.warden || PassThruWarden
17
+ rescue NoMethodError
18
+ # this might be a hash which won't respond to #warden
19
+ PassThruWarden
20
+ end
21
+
22
+ def self.types_from_context(context)
23
+ context.types || PassThruWarden
24
+ rescue NoMethodError
25
+ # this might be a hash which won't respond to #warden
26
+ PassThruWarden
27
+ end
28
+
29
+ def self.use(schema)
30
+ # no-op
42
31
  end
43
32
 
44
33
  # @param visibility_method [Symbol] a Warden method to call for this entry
@@ -55,7 +44,9 @@ module GraphQL
55
44
  if visible_item.nil?
56
45
  visible_item = item
57
46
  else
58
- raise Schema::DuplicateNamesError, "Found two visible definitions for `#{item.path}`: #{visible_item.inspect}, #{item.inspect}"
47
+ raise DuplicateNamesError.new(
48
+ duplicated_name: item.path, duplicated_definition_1: visible_item.inspect, duplicated_definition_2: item.inspect
49
+ )
59
50
  end
60
51
  end
61
52
  end
@@ -80,22 +71,152 @@ module GraphQL
80
71
  def visible_type_membership?(tm, ctx); tm.visible?(ctx); end
81
72
  def interface_type_memberships(obj_t, ctx); obj_t.interface_type_memberships; end
82
73
  def arguments(owner, ctx); owner.arguments(ctx); end
74
+ def loadable?(type, ctx); type.visible?(ctx); end
75
+ def loadable_possible_types(type, ctx); type.possible_types(ctx); end
76
+ def visibility_profile
77
+ @visibility_profile ||= Warden::VisibilityProfile.new(self)
78
+ end
79
+ end
80
+ end
81
+
82
+ class NullWarden
83
+ def initialize(_filter = nil, context:, schema:)
84
+ @schema = schema
85
+ @visibility_profile = Warden::VisibilityProfile.new(self)
86
+ end
87
+
88
+ # No-op, but for compatibility:
89
+ attr_writer :skip_warning
90
+
91
+ attr_reader :visibility_profile
92
+
93
+ def visible_field?(field_defn, _ctx = nil, owner = nil); true; end
94
+ def visible_argument?(arg_defn, _ctx = nil); true; end
95
+ def visible_type?(type_defn, _ctx = nil); true; end
96
+ def visible_enum_value?(enum_value, _ctx = nil); enum_value.visible?(Query::NullContext.instance); end
97
+ def visible_type_membership?(type_membership, _ctx = nil); true; end
98
+ def interface_type_memberships(obj_type, _ctx = nil); obj_type.interface_type_memberships; end
99
+ def get_type(type_name); @schema.get_type(type_name, Query::NullContext.instance, false); end # rubocop:disable Development/ContextIsPassedCop
100
+ def arguments(argument_owner, ctx = nil); argument_owner.all_argument_definitions; end
101
+ def enum_values(enum_defn); enum_defn.enum_values(Query::NullContext.instance); end # rubocop:disable Development/ContextIsPassedCop
102
+ def get_argument(parent_type, argument_name); parent_type.get_argument(argument_name); end # rubocop:disable Development/ContextIsPassedCop
103
+ def types; @schema.types; end # rubocop:disable Development/ContextIsPassedCop
104
+ def root_type_for_operation(op_name); @schema.root_type_for_operation(op_name); end
105
+ def directives; @schema.directives.values; end
106
+ def fields(type_defn); type_defn.all_field_definitions; end # rubocop:disable Development/ContextIsPassedCop
107
+ def get_field(parent_type, field_name); @schema.get_field(parent_type, field_name); end
108
+ def reachable_type?(type_name); true; end
109
+ def loadable?(type, _ctx); true; end
110
+ def loadable_possible_types(abstract_type, _ctx); union_type.possible_types; end
111
+ def reachable_types; @schema.types.values; end # rubocop:disable Development/ContextIsPassedCop
112
+ def possible_types(type_defn); @schema.possible_types(type_defn, Query::NullContext.instance, false); end
113
+ def interfaces(obj_type); obj_type.interfaces; end
114
+ end
115
+
116
+ def visibility_profile
117
+ @visibility_profile ||= VisibilityProfile.new(self)
118
+ end
119
+
120
+ class VisibilityProfile
121
+ def initialize(warden)
122
+ @warden = warden
123
+ end
124
+
125
+ def directives
126
+ @warden.directives
127
+ end
128
+
129
+ def directive_exists?(dir_name)
130
+ @warden.directives.any? { |d| d.graphql_name == dir_name }
131
+ end
132
+
133
+ def type(name)
134
+ @warden.get_type(name)
135
+ end
136
+
137
+ def field(owner, field_name)
138
+ @warden.get_field(owner, field_name)
139
+ end
140
+
141
+ def argument(owner, arg_name)
142
+ @warden.get_argument(owner, arg_name)
143
+ end
144
+
145
+ def query_root
146
+ @warden.root_type_for_operation("query")
147
+ end
148
+
149
+ def mutation_root
150
+ @warden.root_type_for_operation("mutation")
151
+ end
152
+
153
+ def subscription_root
154
+ @warden.root_type_for_operation("subscription")
155
+ end
156
+
157
+ def arguments(owner)
158
+ @warden.arguments(owner)
159
+ end
160
+
161
+ def fields(owner)
162
+ @warden.fields(owner)
163
+ end
164
+
165
+ def possible_types(type)
166
+ @warden.possible_types(type)
167
+ end
168
+
169
+ def enum_values(enum_type)
170
+ @warden.enum_values(enum_type)
171
+ end
172
+
173
+ def all_types
174
+ @warden.reachable_types
175
+ end
176
+
177
+ def interfaces(obj_type)
178
+ @warden.interfaces(obj_type)
179
+ end
180
+
181
+ def loadable?(t, ctx) # TODO remove ctx here?
182
+ @warden.loadable?(t, ctx)
183
+ end
184
+
185
+ def loadable_possible_types(t, ctx)
186
+ @warden.loadable_possible_types(t, ctx)
187
+ end
188
+
189
+ def reachable_type?(type_name)
190
+ !!@warden.reachable_type?(type_name)
191
+ end
192
+
193
+ def visible_enum_value?(enum_value, ctx = nil)
194
+ @warden.visible_enum_value?(enum_value, ctx)
83
195
  end
84
196
  end
85
197
 
86
- # @param filter [<#call(member)>] Objects are hidden when `.call(member, ctx)` returns true
87
198
  # @param context [GraphQL::Query::Context]
88
199
  # @param schema [GraphQL::Schema]
89
- def initialize(filter, context:, schema:)
90
- @schema = schema.interpreter? ? schema : schema.graphql_definition
200
+ def initialize(context:, schema:)
201
+ @schema = schema
91
202
  # Cache these to avoid repeated hits to the inheritance chain when one isn't present
92
203
  @query = @schema.query
93
204
  @mutation = @schema.mutation
94
205
  @subscription = @schema.subscription
95
206
  @context = context
96
- @visibility_cache = read_through { |m| filter.call(m, context) }
207
+ @visibility_cache = read_through { |m| check_visible(schema, m) }
208
+ # Initialize all ivars to improve object shape consistency:
209
+ @types = @visible_types = @reachable_types = @visible_parent_fields =
210
+ @visible_possible_types = @visible_fields = @visible_arguments = @visible_enum_arrays =
211
+ @visible_enum_values = @visible_interfaces = @type_visibility = @type_memberships =
212
+ @visible_and_reachable_type = @unions = @unfiltered_interfaces =
213
+ @reachable_type_set = @visibility_profile = @loadable_possible_types =
214
+ nil
215
+ @skip_warning = schema.plugins.any? { |(plugin, _opts)| plugin == GraphQL::Schema::Warden }
97
216
  end
98
217
 
218
+ attr_writer :skip_warning
219
+
99
220
  # @return [Hash<String, GraphQL::BaseType>] Visible types in the schema
100
221
  def types
101
222
  @types ||= begin
@@ -109,10 +230,30 @@ module GraphQL
109
230
  end
110
231
  end
111
232
 
233
+ # @return [Boolean] True if this type is used for `loads:` but not in the schema otherwise and not _explicitly_ hidden.
234
+ def loadable?(type, _ctx)
235
+ visible_type?(type) &&
236
+ !referenced?(type) &&
237
+ (type.respond_to?(:interfaces) ? interfaces(type).all? { |i| loadable?(i, _ctx) } : true)
238
+ end
239
+
240
+ # This abstract type was determined to be used for `loads` only.
241
+ # All its possible types are valid possibilities here -- no filtering.
242
+ def loadable_possible_types(abstract_type, _ctx)
243
+ @loadable_possible_types ||= read_through do |t|
244
+ if t.is_a?(Class) # union
245
+ t.possible_types
246
+ else
247
+ @schema.possible_types(abstract_type)
248
+ end
249
+ end
250
+ @loadable_possible_types[abstract_type]
251
+ end
252
+
112
253
  # @return [GraphQL::BaseType, nil] The type named `type_name`, if it exists (else `nil`)
113
254
  def get_type(type_name)
114
255
  @visible_types ||= read_through do |name|
115
- type_defn = @schema.get_type(name, @context)
256
+ type_defn = @schema.get_type(name, @context, false)
116
257
  if type_defn && visible_and_reachable_type?(type_defn)
117
258
  type_defn
118
259
  else
@@ -159,7 +300,7 @@ module GraphQL
159
300
  # @return [Array<GraphQL::BaseType>] The types which may be member of `type_defn`
160
301
  def possible_types(type_defn)
161
302
  @visible_possible_types ||= read_through { |type_defn|
162
- pt = @schema.possible_types(type_defn, @context)
303
+ pt = @schema.possible_types(type_defn, @context, false)
163
304
  pt.select { |t| visible_and_reachable_type?(t) }
164
305
  }
165
306
  @visible_possible_types[type_defn]
@@ -175,13 +316,28 @@ module GraphQL
175
316
  # @param argument_owner [GraphQL::Field, GraphQL::InputObjectType]
176
317
  # @return [Array<GraphQL::Argument>] Visible arguments on `argument_owner`
177
318
  def arguments(argument_owner, ctx = nil)
178
- @visible_arguments ||= read_through { |o| o.arguments(@context).each_value.select { |a| visible_argument?(a, @context) } }
319
+ @visible_arguments ||= read_through { |o|
320
+ args = o.arguments(@context)
321
+ if !args.empty?
322
+ args = args.values
323
+ args.select! { |a| visible_argument?(a, @context) }
324
+ args
325
+ else
326
+ EmptyObjects::EMPTY_ARRAY
327
+ end
328
+ }
179
329
  @visible_arguments[argument_owner]
180
330
  end
181
331
 
182
332
  # @return [Array<GraphQL::EnumType::EnumValue>] Visible members of `enum_defn`
183
333
  def enum_values(enum_defn)
184
- @visible_enum_arrays ||= read_through { |e| e.enum_values(@context) }
334
+ @visible_enum_arrays ||= read_through { |e|
335
+ values = e.enum_values(@context)
336
+ if values.size == 0
337
+ raise GraphQL::Schema::Enum::MissingValuesError.new(e)
338
+ end
339
+ values
340
+ }
185
341
  @visible_enum_arrays[enum_defn]
186
342
  end
187
343
 
@@ -192,7 +348,13 @@ module GraphQL
192
348
 
193
349
  # @return [Array<GraphQL::InterfaceType>] Visible interfaces implemented by `obj_type`
194
350
  def interfaces(obj_type)
195
- @visible_interfaces ||= read_through { |t| t.interfaces(@context).select { |i| visible_type?(i) } }
351
+ @visible_interfaces ||= read_through { |t|
352
+ ints = t.interfaces(@context)
353
+ if !ints.empty?
354
+ ints.select! { |i| visible_type?(i) }
355
+ end
356
+ ints
357
+ }
196
358
  @visible_interfaces[obj_type]
197
359
  end
198
360
 
@@ -248,11 +410,26 @@ module GraphQL
248
410
  next true if root_type?(type_defn) || type_defn.introspection?
249
411
 
250
412
  if type_defn.kind.union?
251
- visible_possible_types?(type_defn) && (referenced?(type_defn) || orphan_type?(type_defn))
413
+ !possible_types(type_defn).empty? && (referenced?(type_defn) || orphan_type?(type_defn))
252
414
  elsif type_defn.kind.interface?
253
- visible_possible_types?(type_defn)
415
+ if !possible_types(type_defn).empty?
416
+ true
417
+ else
418
+ if @context.respond_to?(:logger) && (logger = @context.logger)
419
+ logger.debug { "Interface `#{type_defn.graphql_name}` hidden because it has no visible implementers" }
420
+ end
421
+ false
422
+ end
254
423
  else
255
- referenced?(type_defn) || visible_abstract_type?(type_defn)
424
+ if referenced?(type_defn)
425
+ true
426
+ elsif type_defn.kind.object?
427
+ # Show this object if it belongs to ...
428
+ interfaces(type_defn).any? { |t| referenced?(t) } || # an interface which is referenced in the schema
429
+ union_memberships(type_defn).any? { |t| referenced?(t) || orphan_type?(t) } # or a union which is referenced or added via orphan_types
430
+ else
431
+ false
432
+ end
256
433
  end
257
434
  end
258
435
 
@@ -307,39 +484,76 @@ module GraphQL
307
484
  end
308
485
 
309
486
  def referenced?(type_defn)
310
- @references_to ||= @schema.references_to
311
- graphql_name = type_defn.unwrap.graphql_name
312
- members = @references_to[graphql_name] || NO_REFERENCES
487
+ members = @schema.references_to(type_defn)
313
488
  members.any? { |m| visible?(m) }
314
489
  end
315
490
 
316
- NO_REFERENCES = [].freeze
317
-
318
491
  def orphan_type?(type_defn)
319
492
  @schema.orphan_types.include?(type_defn)
320
493
  end
321
494
 
322
- def visible_abstract_type?(type_defn)
323
- type_defn.kind.object? && (
324
- interfaces(type_defn).any? ||
325
- union_memberships(type_defn).any?
326
- )
327
- end
328
-
329
- def visible_possible_types?(type_defn)
330
- possible_types(type_defn).any? { |t| visible_and_reachable_type?(t) }
331
- end
332
-
333
495
  def visible?(member)
334
496
  @visibility_cache[member]
335
497
  end
336
498
 
337
499
  def read_through
338
- Hash.new { |h, k| h[k] = yield(k) }
500
+ Hash.new { |h, k| h[k] = yield(k) }.compare_by_identity
501
+ end
502
+
503
+ def check_visible(schema, member)
504
+ if schema.visible?(member, @context)
505
+ true
506
+ elsif @skip_warning
507
+ false
508
+ else
509
+ member_s = member.respond_to?(:path) ? member.path : member.inspect
510
+ member_type = case member
511
+ when Module
512
+ if member.respond_to?(:kind)
513
+ member.kind.name.downcase
514
+ else
515
+ ""
516
+ end
517
+ when GraphQL::Schema::Field
518
+ "field"
519
+ when GraphQL::Schema::EnumValue
520
+ "enum value"
521
+ when GraphQL::Schema::Argument
522
+ "argument"
523
+ else
524
+ ""
525
+ end
526
+
527
+ schema_s = schema.name ? "#{schema.name}'s" : ""
528
+ schema_name = schema.name ? "#{schema.name}" : "your schema"
529
+ warn(ADD_WARDEN_WARNING % { schema_s: schema_s, schema_name: schema_name, member: member_s, member_type: member_type })
530
+ @skip_warning = true # only warn once per query
531
+ # If there's no schema name, add the backtrace for additional context:
532
+ if schema_s == ""
533
+ puts caller.map { |l| " #{l}"}
534
+ end
535
+ false
536
+ end
339
537
  end
340
538
 
539
+ ADD_WARDEN_WARNING = <<~WARNING
540
+ DEPRECATION: %{schema_s} "%{member}" %{member_type} returned `false` for `.visible?` but `GraphQL::Schema::Visibility` isn't configured yet.
541
+
542
+ Address this warning by adding:
543
+
544
+ use GraphQL::Schema::Visibility
545
+
546
+ to the definition for %{schema_name}. (Future GraphQL-Ruby versions won't check `.visible?` methods by default.)
547
+
548
+ Alternatively, for legacy behavior, add:
549
+
550
+ use GraphQL::Schema::Warden # legacy visibility behavior
551
+
552
+ For more information see: https://graphql-ruby.org/authorization/visibility.html
553
+ WARNING
554
+
341
555
  def reachable_type_set
342
- return @reachable_type_set if defined?(@reachable_type_set)
556
+ return @reachable_type_set if @reachable_type_set
343
557
 
344
558
  @reachable_type_set = Set.new
345
559
  rt_hash = {}
@@ -366,52 +580,62 @@ module GraphQL
366
580
  end
367
581
  end
368
582
 
583
+ included_interface_possible_types_set = Set.new
584
+
369
585
  until unvisited_types.empty?
370
586
  type = unvisited_types.pop
371
- if @reachable_type_set.add?(type)
372
- type_by_name = rt_hash[type.graphql_name] ||= type
373
- if type_by_name != type
374
- raise DuplicateNamesError, "Found two visible type definitions for `#{type.graphql_name}`: #{type.inspect}, #{type_by_name.inspect}"
587
+ visit_type(type, unvisited_types, @reachable_type_set, rt_hash, included_interface_possible_types_set, include_interface_possible_types: false)
588
+ end
589
+
590
+ @reachable_type_set
591
+ end
592
+
593
+ def visit_type(type, unvisited_types, visited_type_set, type_by_name_hash, included_interface_possible_types_set, include_interface_possible_types:)
594
+ if visited_type_set.add?(type) || (include_interface_possible_types && type.kind.interface? && included_interface_possible_types_set.add?(type))
595
+ type_by_name = type_by_name_hash[type.graphql_name] ||= type
596
+ if type_by_name != type
597
+ name_1, name_2 = [type.inspect, type_by_name.inspect].sort
598
+ raise DuplicateNamesError.new(
599
+ duplicated_name: type.graphql_name, duplicated_definition_1: name_1, duplicated_definition_2: name_2
600
+ )
601
+ end
602
+ if type.kind.input_object?
603
+ # recurse into visible arguments
604
+ arguments(type).each do |argument|
605
+ argument_type = argument.type.unwrap
606
+ unvisited_types << argument_type
375
607
  end
376
- if type.kind.input_object?
377
- # recurse into visible arguments
378
- arguments(type).each do |argument|
379
- argument_type = argument.type.unwrap
380
- unvisited_types << argument_type
381
- end
382
- elsif type.kind.union?
383
- # recurse into visible possible types
384
- possible_types(type).each do |possible_type|
385
- unvisited_types << possible_type
608
+ elsif type.kind.union?
609
+ # recurse into visible possible types
610
+ possible_types(type).each do |possible_type|
611
+ unvisited_types << possible_type
612
+ end
613
+ elsif type.kind.fields?
614
+ if type.kind.object?
615
+ # recurse into visible implemented interfaces
616
+ interfaces(type).each do |interface|
617
+ unvisited_types << interface
386
618
  end
387
- elsif type.kind.fields?
388
- if type.kind.interface?
389
- # recurse into visible possible types
390
- possible_types(type).each do |possible_type|
391
- unvisited_types << possible_type
392
- end
393
- elsif type.kind.object?
394
- # recurse into visible implemented interfaces
395
- interfaces(type).each do |interface|
396
- unvisited_types << interface
397
- end
619
+ elsif include_interface_possible_types
620
+ possible_types(type).each do |pt|
621
+ unvisited_types << pt
398
622
  end
623
+ end
624
+ # Don't visit interface possible types -- it's not enough to justify visibility
399
625
 
400
- # recurse into visible fields
401
- fields(type).each do |field|
402
- field_type = field.type.unwrap
403
- unvisited_types << field_type
404
- # recurse into visible arguments
405
- arguments(field).each do |argument|
406
- argument_type = argument.type.unwrap
407
- unvisited_types << argument_type
408
- end
626
+ # recurse into visible fields
627
+ fields(type).each do |field|
628
+ field_type = field.type.unwrap
629
+ # In this case, if it's an interface, we want to include
630
+ visit_type(field_type, unvisited_types, visited_type_set, type_by_name_hash, included_interface_possible_types_set, include_interface_possible_types: true)
631
+ # recurse into visible arguments
632
+ arguments(field).each do |argument|
633
+ argument_type = argument.type.unwrap
634
+ unvisited_types << argument_type
409
635
  end
410
636
  end
411
637
  end
412
638
  end
413
-
414
- @reachable_type_set
415
639
  end
416
640
  end
417
641
  end
@@ -3,7 +3,6 @@
3
3
  module GraphQL
4
4
  class Schema
5
5
  class Wrapper
6
- include GraphQL::Schema::Member::CachedGraphQLDefinition
7
6
  include GraphQL::Schema::Member::TypeSystemHelpers
8
7
 
9
8
  # @return [Class, Module] The inner type of this wrapping type, the type of which one or more objects may be present.
@@ -13,10 +12,6 @@ module GraphQL
13
12
  @of_type = of_type
14
13
  end
15
14
 
16
- def to_graphql
17
- raise GraphQL::RequiredImplementationMissingError
18
- end
19
-
20
15
  def unwrap
21
16
  @of_type.unwrap
22
17
  end