graphql 2.6.12 → 2.6.13

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 (382) hide show
  1. checksums.yaml +4 -4
  2. data/.rdoc_options +4 -0
  3. data/lib/generators/graphql/core.rb +1 -0
  4. data/lib/generators/graphql/detailed_trace_generator.rb +1 -0
  5. data/lib/generators/graphql/enum_generator.rb +1 -0
  6. data/lib/generators/graphql/field_extractor.rb +1 -0
  7. data/lib/generators/graphql/input_generator.rb +1 -0
  8. data/lib/generators/graphql/install/mutation_root_generator.rb +1 -0
  9. data/lib/generators/graphql/install_generator.rb +1 -0
  10. data/lib/generators/graphql/interface_generator.rb +1 -0
  11. data/lib/generators/graphql/loader_generator.rb +8 -2
  12. data/lib/generators/graphql/mutation_create_generator.rb +8 -2
  13. data/lib/generators/graphql/mutation_delete_generator.rb +8 -2
  14. data/lib/generators/graphql/mutation_generator.rb +8 -2
  15. data/lib/generators/graphql/mutation_update_generator.rb +8 -2
  16. data/lib/generators/graphql/object_generator.rb +1 -0
  17. data/lib/generators/graphql/orm_mutations_base.rb +8 -2
  18. data/lib/generators/graphql/relay.rb +1 -0
  19. data/lib/generators/graphql/relay_generator.rb +1 -0
  20. data/lib/generators/graphql/scalar_generator.rb +1 -0
  21. data/lib/generators/graphql/type_generator.rb +38 -8
  22. data/lib/generators/graphql/union_generator.rb +1 -0
  23. data/lib/graphql/analysis/analyzer.rb +35 -9
  24. data/lib/graphql/analysis/field_usage.rb +1 -0
  25. data/lib/graphql/analysis/max_query_complexity.rb +2 -1
  26. data/lib/graphql/analysis/max_query_depth.rb +1 -0
  27. data/lib/graphql/analysis/query_complexity.rb +57 -20
  28. data/lib/graphql/analysis/query_depth.rb +17 -12
  29. data/lib/graphql/analysis/visitor.rb +79 -16
  30. data/lib/graphql/analysis.rb +23 -6
  31. data/lib/graphql/analysis_error.rb +1 -0
  32. data/lib/graphql/autoload.rb +30 -7
  33. data/lib/graphql/backtrace/table.rb +21 -5
  34. data/lib/graphql/backtrace/traced_error.rb +8 -3
  35. data/lib/graphql/backtrace.rb +14 -9
  36. data/lib/graphql/coercion_error.rb +1 -0
  37. data/lib/graphql/current.rb +44 -19
  38. data/lib/graphql/dashboard/application_controller.rb +1 -0
  39. data/lib/graphql/dashboard/detailed_traces.rb +1 -0
  40. data/lib/graphql/dashboard/installable.rb +1 -0
  41. data/lib/graphql/dashboard/landings_controller.rb +1 -0
  42. data/lib/graphql/dashboard/limiters.rb +1 -0
  43. data/lib/graphql/dashboard/operation_store.rb +1 -0
  44. data/lib/graphql/dashboard/statics_controller.rb +1 -0
  45. data/lib/graphql/dashboard/subscriptions.rb +1 -0
  46. data/lib/graphql/dashboard.rb +36 -22
  47. data/lib/graphql/dataloader/active_record_association_source.rb +1 -0
  48. data/lib/graphql/dataloader/active_record_source.rb +1 -0
  49. data/lib/graphql/dataloader/async_dataloader.rb +8 -7
  50. data/lib/graphql/dataloader/null_dataloader.rb +4 -3
  51. data/lib/graphql/dataloader/request.rb +8 -2
  52. data/lib/graphql/dataloader/request_all.rb +8 -2
  53. data/lib/graphql/dataloader/source.rb +127 -35
  54. data/lib/graphql/dataloader.rb +91 -42
  55. data/lib/graphql/date_encoding_error.rb +2 -1
  56. data/lib/graphql/dig.rb +12 -3
  57. data/lib/graphql/duration_encoding_error.rb +2 -1
  58. data/lib/graphql/execution/directive_checks.rb +8 -3
  59. data/lib/graphql/execution/errors.rb +20 -6
  60. data/lib/graphql/execution/field_resolve_step.rb +22 -6
  61. data/lib/graphql/execution/finalize.rb +12 -6
  62. data/lib/graphql/execution/input_values.rb +2 -1
  63. data/lib/graphql/execution/interpreter/argument_value.rb +17 -5
  64. data/lib/graphql/execution/interpreter/arguments.rb +24 -9
  65. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -1
  66. data/lib/graphql/execution/interpreter/execution_errors.rb +1 -0
  67. data/lib/graphql/execution/interpreter/handles_raw_value.rb +1 -0
  68. data/lib/graphql/execution/interpreter/resolve.rb +18 -8
  69. data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +4 -1
  70. data/lib/graphql/execution/interpreter/runtime.rb +66 -23
  71. data/lib/graphql/execution/interpreter.rb +15 -6
  72. data/lib/graphql/execution/lazy/lazy_method_map.rb +21 -8
  73. data/lib/graphql/execution/lazy.rb +34 -10
  74. data/lib/graphql/execution/load_argument_step.rb +1 -0
  75. data/lib/graphql/execution/lookahead.rb +137 -54
  76. data/lib/graphql/execution/multiplex.rb +4 -4
  77. data/lib/graphql/execution/next.rb +7 -0
  78. data/lib/graphql/execution/prepare_object_step.rb +1 -0
  79. data/lib/graphql/execution/resolve_type_step.rb +2 -1
  80. data/lib/graphql/execution/runner.rb +9 -3
  81. data/lib/graphql/execution/selections_step.rb +3 -2
  82. data/lib/graphql/execution.rb +2 -2
  83. data/lib/graphql/execution_error.rb +19 -10
  84. data/lib/graphql/float_decoding_error.rb +1 -0
  85. data/lib/graphql/float_encoding_error.rb +7 -2
  86. data/lib/graphql/integer_decoding_error.rb +2 -1
  87. data/lib/graphql/integer_encoding_error.rb +8 -3
  88. data/lib/graphql/introspection/base_object.rb +3 -1
  89. data/lib/graphql/introspection/directive_location_enum.rb +1 -0
  90. data/lib/graphql/introspection/directive_type.rb +1 -0
  91. data/lib/graphql/introspection/dynamic_fields.rb +1 -0
  92. data/lib/graphql/introspection/entry_points.rb +1 -0
  93. data/lib/graphql/introspection/enum_value_type.rb +1 -0
  94. data/lib/graphql/introspection/field_type.rb +1 -0
  95. data/lib/graphql/introspection/input_value_type.rb +1 -0
  96. data/lib/graphql/introspection/introspection_query.rb +1 -0
  97. data/lib/graphql/introspection/schema_type.rb +1 -0
  98. data/lib/graphql/introspection/type_kind_enum.rb +1 -0
  99. data/lib/graphql/introspection/type_type.rb +1 -0
  100. data/lib/graphql/introspection.rb +1 -0
  101. data/lib/graphql/invalid_name_error.rb +1 -0
  102. data/lib/graphql/invalid_null_error.rb +19 -6
  103. data/lib/graphql/language/block_string.rb +2 -1
  104. data/lib/graphql/language/cache.rb +10 -4
  105. data/lib/graphql/language/comment.rb +1 -0
  106. data/lib/graphql/language/definition_slice.rb +1 -0
  107. data/lib/graphql/language/document_from_schema_definition.rb +9 -10
  108. data/lib/graphql/language/generation.rb +23 -9
  109. data/lib/graphql/language/lexer.rb +5 -0
  110. data/lib/graphql/language/nodes.rb +2094 -419
  111. data/lib/graphql/language/parser.rb +17 -11
  112. data/lib/graphql/language/printer.rb +31 -16
  113. data/lib/graphql/language/sanitized_printer.rb +16 -5
  114. data/lib/graphql/language/static_visitor.rb +19 -4
  115. data/lib/graphql/language/visitor.rb +51 -29
  116. data/lib/graphql/language.rb +13 -7
  117. data/lib/graphql/load_application_object_failed_error.rb +14 -5
  118. data/lib/graphql/name_validator.rb +1 -0
  119. data/lib/graphql/pagination/active_record_relation_connection.rb +1 -0
  120. data/lib/graphql/pagination/array_connection.rb +20 -6
  121. data/lib/graphql/pagination/connection.rb +178 -48
  122. data/lib/graphql/pagination/connections.rb +21 -14
  123. data/lib/graphql/pagination/mongoid_relation_connection.rb +1 -0
  124. data/lib/graphql/pagination/relation_connection.rb +118 -21
  125. data/lib/graphql/pagination/sequel_dataset_connection.rb +1 -0
  126. data/lib/graphql/pagination.rb +1 -0
  127. data/lib/graphql/parse_error.rb +1 -0
  128. data/lib/graphql/query/context/scoped_context.rb +2 -1
  129. data/lib/graphql/query/context.rb +106 -35
  130. data/lib/graphql/query/fingerprint.rb +15 -7
  131. data/lib/graphql/query/input_validation_result.rb +1 -0
  132. data/lib/graphql/query/null_context.rb +1 -0
  133. data/lib/graphql/query/partial.rb +28 -15
  134. data/lib/graphql/query/result.rb +15 -5
  135. data/lib/graphql/query/validation_pipeline.rb +16 -6
  136. data/lib/graphql/query/variable_validation_error.rb +1 -0
  137. data/lib/graphql/query/variables.rb +4 -1
  138. data/lib/graphql/query.rb +193 -49
  139. data/lib/graphql/railtie.rb +7 -3
  140. data/lib/graphql/rake_task/validate.rb +72 -17
  141. data/lib/graphql/rake_task.rb +55 -23
  142. data/lib/graphql/relay/range_add.rb +32 -21
  143. data/lib/graphql/relay.rb +1 -0
  144. data/lib/graphql/rubocop/graphql/base_cop.rb +1 -0
  145. data/lib/graphql/rubocop/graphql/default_null_true.rb +9 -6
  146. data/lib/graphql/rubocop/graphql/default_required_true.rb +9 -6
  147. data/lib/graphql/rubocop/graphql/field_type_in_block.rb +12 -8
  148. data/lib/graphql/rubocop/graphql/root_types_in_block.rb +9 -5
  149. data/lib/graphql/rubocop.rb +1 -0
  150. data/lib/graphql/runtime_error.rb +1 -0
  151. data/lib/graphql/runtime_type_error.rb +1 -0
  152. data/lib/graphql/schema/addition.rb +18 -6
  153. data/lib/graphql/schema/always_visible.rb +1 -0
  154. data/lib/graphql/schema/argument.rb +265 -42
  155. data/lib/graphql/schema/base_64_encoder.rb +2 -2
  156. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -0
  157. data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
  158. data/lib/graphql/schema/build_from_definition.rb +94 -27
  159. data/lib/graphql/schema/built_in_types.rb +1 -0
  160. data/lib/graphql/schema/directive/deprecated.rb +1 -0
  161. data/lib/graphql/schema/directive/feature.rb +39 -22
  162. data/lib/graphql/schema/directive/flagged.rb +6 -1
  163. data/lib/graphql/schema/directive/include.rb +1 -0
  164. data/lib/graphql/schema/directive/one_of.rb +1 -0
  165. data/lib/graphql/schema/directive/skip.rb +1 -0
  166. data/lib/graphql/schema/directive/specified_by.rb +1 -0
  167. data/lib/graphql/schema/directive/transform.rb +17 -8
  168. data/lib/graphql/schema/directive.rb +12 -7
  169. data/lib/graphql/schema/enum.rb +99 -38
  170. data/lib/graphql/schema/enum_value.rb +21 -13
  171. data/lib/graphql/schema/field/connection_extension.rb +10 -2
  172. data/lib/graphql/schema/field/scope_extension.rb +1 -0
  173. data/lib/graphql/schema/field.rb +621 -109
  174. data/lib/graphql/schema/field_extension.rb +89 -34
  175. data/lib/graphql/schema/find_inherited_value.rb +5 -3
  176. data/lib/graphql/schema/finder.rb +22 -8
  177. data/lib/graphql/schema/has_single_input_argument.rb +39 -6
  178. data/lib/graphql/schema/input_object.rb +40 -13
  179. data/lib/graphql/schema/interface.rb +33 -17
  180. data/lib/graphql/schema/introspection_system.rb +7 -3
  181. data/lib/graphql/schema/late_bound_type.rb +2 -2
  182. data/lib/graphql/schema/list.rb +15 -4
  183. data/lib/graphql/schema/loader.rb +23 -12
  184. data/lib/graphql/schema/member/base_dsl_methods.rb +58 -12
  185. data/lib/graphql/schema/member/build_type.rb +16 -5
  186. data/lib/graphql/schema/member/graphql_type_names.rb +10 -6
  187. data/lib/graphql/schema/member/has_arguments.rb +115 -48
  188. data/lib/graphql/schema/member/has_ast_node.rb +1 -0
  189. data/lib/graphql/schema/member/has_authorization.rb +5 -0
  190. data/lib/graphql/schema/member/has_dataloader.rb +91 -34
  191. data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -2
  192. data/lib/graphql/schema/member/has_directives.rb +38 -10
  193. data/lib/graphql/schema/member/has_fields.rb +151 -70
  194. data/lib/graphql/schema/member/has_interfaces.rb +10 -2
  195. data/lib/graphql/schema/member/has_path.rb +14 -5
  196. data/lib/graphql/schema/member/has_unresolved_type_error.rb +1 -0
  197. data/lib/graphql/schema/member/has_validators.rb +19 -4
  198. data/lib/graphql/schema/member/relay_shortcuts.rb +10 -2
  199. data/lib/graphql/schema/member/scoped.rb +14 -3
  200. data/lib/graphql/schema/member/type_system_helpers.rb +36 -6
  201. data/lib/graphql/schema/member/validates_input.rb +1 -0
  202. data/lib/graphql/schema/member.rb +9 -2
  203. data/lib/graphql/schema/mutation.rb +50 -46
  204. data/lib/graphql/schema/non_null.rb +21 -5
  205. data/lib/graphql/schema/object.rb +33 -12
  206. data/lib/graphql/schema/printer.rb +52 -31
  207. data/lib/graphql/schema/ractor_shareable.rb +6 -2
  208. data/lib/graphql/schema/relay_classic_mutation.rb +3 -3
  209. data/lib/graphql/schema/resolver/has_payload_type.rb +29 -7
  210. data/lib/graphql/schema/resolver.rb +156 -45
  211. data/lib/graphql/schema/scalar.rb +1 -0
  212. data/lib/graphql/schema/subscription.rb +67 -28
  213. data/lib/graphql/schema/timeout.rb +65 -25
  214. data/lib/graphql/schema/type_expression.rb +14 -5
  215. data/lib/graphql/schema/type_membership.rb +29 -10
  216. data/lib/graphql/schema/union.rb +4 -2
  217. data/lib/graphql/schema/unique_within_type.rb +24 -5
  218. data/lib/graphql/schema/validator/all_validator.rb +17 -9
  219. data/lib/graphql/schema/validator/allow_blank_validator.rb +8 -2
  220. data/lib/graphql/schema/validator/allow_null_validator.rb +8 -2
  221. data/lib/graphql/schema/validator/exclusion_validator.rb +14 -5
  222. data/lib/graphql/schema/validator/format_validator.rb +21 -10
  223. data/lib/graphql/schema/validator/inclusion_validator.rb +15 -6
  224. data/lib/graphql/schema/validator/length_validator.rb +23 -12
  225. data/lib/graphql/schema/validator/numericality_validator.rb +29 -16
  226. data/lib/graphql/schema/validator/required_validator.rb +45 -31
  227. data/lib/graphql/schema/validator.rb +89 -25
  228. data/lib/graphql/schema/visibility/migration.rb +14 -7
  229. data/lib/graphql/schema/visibility/profile.rb +20 -17
  230. data/lib/graphql/schema/visibility/visit.rb +12 -10
  231. data/lib/graphql/schema/visibility.rb +24 -20
  232. data/lib/graphql/schema/warden.rb +117 -31
  233. data/lib/graphql/schema/wrapper.rb +4 -1
  234. data/lib/graphql/schema.rb +1046 -300
  235. data/lib/graphql/static_validation/all_rules.rb +2 -1
  236. data/lib/graphql/static_validation/base_visitor.rb +48 -8
  237. data/lib/graphql/static_validation/definition_dependencies.rb +27 -7
  238. data/lib/graphql/static_validation/error.rb +3 -0
  239. data/lib/graphql/static_validation/interpreter_visitor.rb +1 -0
  240. data/lib/graphql/static_validation/literal_validator.rb +1 -0
  241. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +4 -0
  242. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +1 -0
  243. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +3 -0
  244. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +1 -0
  245. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -0
  246. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +1 -0
  247. data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -0
  248. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +1 -0
  249. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +3 -0
  250. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +1 -0
  251. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +3 -0
  252. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +1 -0
  253. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +9 -1
  254. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +1 -0
  255. data/lib/graphql/static_validation/rules/fields_will_merge.rb +295 -134
  256. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +14 -2
  257. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +3 -0
  258. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +1 -0
  259. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -0
  260. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +1 -0
  261. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +3 -0
  262. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +1 -0
  263. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +3 -0
  264. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +1 -0
  265. data/lib/graphql/static_validation/rules/fragments_are_named.rb +3 -0
  266. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +1 -0
  267. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +3 -0
  268. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +1 -0
  269. data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -0
  270. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +1 -0
  271. data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +3 -0
  272. data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +1 -0
  273. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +3 -0
  274. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +1 -0
  275. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +3 -0
  276. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +1 -0
  277. data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +1 -0
  278. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +4 -0
  279. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +1 -0
  280. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +3 -0
  281. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +1 -0
  282. data/lib/graphql/static_validation/rules/query_root_exists.rb +3 -0
  283. data/lib/graphql/static_validation/rules/query_root_exists_error.rb +1 -0
  284. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -1
  285. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +1 -0
  286. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -0
  287. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +1 -0
  288. data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +4 -1
  289. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +1 -0
  290. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +3 -0
  291. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +1 -0
  292. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -0
  293. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +1 -0
  294. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +3 -0
  295. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +1 -0
  296. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +207 -51
  297. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +1 -0
  298. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +3 -0
  299. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +1 -0
  300. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -3
  301. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +1 -0
  302. data/lib/graphql/static_validation/validation_context.rb +3 -2
  303. data/lib/graphql/static_validation/validation_timeout_error.rb +1 -0
  304. data/lib/graphql/static_validation/validator.rb +41 -16
  305. data/lib/graphql/static_validation.rb +1 -0
  306. data/lib/graphql/string_encoding_error.rb +1 -0
  307. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +85 -65
  308. data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
  309. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +1 -0
  310. data/lib/graphql/subscriptions/event.rb +25 -6
  311. data/lib/graphql/subscriptions/serialize.rb +58 -19
  312. data/lib/graphql/subscriptions.rb +172 -46
  313. data/lib/graphql/testing/helpers.rb +17 -4
  314. data/lib/graphql/testing/mock_action_cable.rb +55 -33
  315. data/lib/graphql/testing.rb +1 -0
  316. data/lib/graphql/tracing/active_support_notifications_trace.rb +17 -9
  317. data/lib/graphql/tracing/active_support_notifications_tracing.rb +2 -1
  318. data/lib/graphql/tracing/appoptics_trace.rb +2 -1
  319. data/lib/graphql/tracing/appoptics_tracing.rb +2 -1
  320. data/lib/graphql/tracing/appsignal_trace.rb +16 -7
  321. data/lib/graphql/tracing/appsignal_tracing.rb +7 -3
  322. data/lib/graphql/tracing/call_legacy_tracers.rb +1 -0
  323. data/lib/graphql/tracing/data_dog_trace.rb +17 -6
  324. data/lib/graphql/tracing/data_dog_tracing.rb +10 -3
  325. data/lib/graphql/tracing/detailed_trace/active_record_backend.rb +1 -0
  326. data/lib/graphql/tracing/detailed_trace/memory_backend.rb +1 -0
  327. data/lib/graphql/tracing/detailed_trace/redis_backend.rb +1 -0
  328. data/lib/graphql/tracing/detailed_trace.rb +105 -42
  329. data/lib/graphql/tracing/legacy_hooks_trace.rb +5 -0
  330. data/lib/graphql/tracing/legacy_trace.rb +1 -0
  331. data/lib/graphql/tracing/monitor_trace.rb +17 -11
  332. data/lib/graphql/tracing/new_relic_trace.rb +17 -8
  333. data/lib/graphql/tracing/new_relic_tracing.rb +7 -3
  334. data/lib/graphql/tracing/notifications_trace.rb +11 -8
  335. data/lib/graphql/tracing/notifications_tracing.rb +23 -7
  336. data/lib/graphql/tracing/null_trace.rb +1 -0
  337. data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +1 -0
  338. data/lib/graphql/tracing/perfetto_trace.rb +41 -19
  339. data/lib/graphql/tracing/platform_trace.rb +3 -1
  340. data/lib/graphql/tracing/platform_tracing.rb +16 -7
  341. data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +1 -0
  342. data/lib/graphql/tracing/prometheus_trace.rb +22 -13
  343. data/lib/graphql/tracing/prometheus_tracing.rb +1 -0
  344. data/lib/graphql/tracing/scout_trace.rb +10 -4
  345. data/lib/graphql/tracing/scout_tracing.rb +7 -3
  346. data/lib/graphql/tracing/sentry_trace.rb +12 -5
  347. data/lib/graphql/tracing/statsd_trace.rb +12 -6
  348. data/lib/graphql/tracing/statsd_tracing.rb +7 -1
  349. data/lib/graphql/tracing/trace.rb +231 -58
  350. data/lib/graphql/tracing.rb +25 -9
  351. data/lib/graphql/type_kinds.rb +2 -1
  352. data/lib/graphql/types/big_int.rb +1 -0
  353. data/lib/graphql/types/boolean.rb +1 -0
  354. data/lib/graphql/types/float.rb +1 -0
  355. data/lib/graphql/types/id.rb +1 -0
  356. data/lib/graphql/types/int.rb +2 -1
  357. data/lib/graphql/types/iso_8601_date.rb +21 -4
  358. data/lib/graphql/types/iso_8601_date_time.rb +33 -6
  359. data/lib/graphql/types/iso_8601_duration.rb +42 -9
  360. data/lib/graphql/types/json.rb +1 -0
  361. data/lib/graphql/types/relay/base_connection.rb +38 -32
  362. data/lib/graphql/types/relay/base_edge.rb +15 -9
  363. data/lib/graphql/types/relay/connection_behaviors.rb +19 -3
  364. data/lib/graphql/types/relay/edge_behaviors.rb +17 -4
  365. data/lib/graphql/types/relay/has_node_field.rb +6 -1
  366. data/lib/graphql/types/relay/has_nodes_field.rb +6 -1
  367. data/lib/graphql/types/relay/node.rb +1 -0
  368. data/lib/graphql/types/relay/node_behaviors.rb +5 -1
  369. data/lib/graphql/types/relay/page_info.rb +1 -0
  370. data/lib/graphql/types/relay/page_info_behaviors.rb +1 -0
  371. data/lib/graphql/types/relay.rb +4 -3
  372. data/lib/graphql/types/string.rb +1 -0
  373. data/lib/graphql/types.rb +1 -0
  374. data/lib/graphql/unauthorized_enum_value_error.rb +4 -1
  375. data/lib/graphql/unauthorized_error.rb +11 -4
  376. data/lib/graphql/unauthorized_field_error.rb +4 -1
  377. data/lib/graphql/unresolved_type_error.rb +16 -5
  378. data/lib/graphql/version.rb +2 -1
  379. data/lib/graphql.rb +37 -9
  380. data/readme.md +1 -1
  381. metadata +89 -5
  382. data/.yardopts +0 -5
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
 
3
4
  module GraphQL
4
5
  class Schema
@@ -8,44 +9,57 @@ module GraphQL
8
9
  #
9
10
  # (This is for specifying mutually exclusive sets of arguments.)
10
11
  #
11
- # If you use {GraphQL::Schema::Visibility} to hide all the arguments in a `one_of: [..]` set,
12
- # then a developer-facing {GraphQL::Error} will be raised during execution. Pass `allow_all_hidden: true` to
12
+ # If you use [GraphQL::Schema::Visibility](rdoc-ref:GraphQL::Schema::Visibility) to hide all the arguments in a `one_of: [..]` set,
13
+ # then a developer-facing [GraphQL::Error](rdoc-ref:GraphQL::Error) will be raised during execution. Pass `allow_all_hidden: true` to
13
14
  # skip validation in this case instead.
14
15
  #
15
16
  # This validator also implements `argument ... required: :nullable`. If an argument has `required: :nullable`
16
- # but it's hidden with {GraphQL::Schema::Visibility}, then this validator doesn't run.
17
+ # but it's hidden with [GraphQL::Schema::Visibility](rdoc-ref:GraphQL::Schema::Visibility), then this validator doesn't run.
17
18
  #
18
- # @example Require exactly one of these arguments
19
+ # **Examples**
19
20
  #
20
- # field :update_amount, IngredientAmount, null: false do
21
- # argument :ingredient_id, ID, required: true
22
- # argument :cups, Integer, required: false
23
- # argument :tablespoons, Integer, required: false
24
- # argument :teaspoons, Integer, required: false
25
- # validates required: { one_of: [:cups, :tablespoons, :teaspoons] }
26
- # end
21
+ # **Example: Require exactly one of these arguments**
27
22
  #
28
- # @example Require one of these _sets_ of arguments
23
+ # ```ruby
24
+ # field :update_amount, IngredientAmount, null: false do
25
+ # argument :ingredient_id, ID, required: true
26
+ # argument :cups, Integer, required: false
27
+ # argument :tablespoons, Integer, required: false
28
+ # argument :teaspoons, Integer, required: false
29
+ # validates required: { one_of: [:cups, :tablespoons, :teaspoons] }
30
+ # end
31
+ # ```
29
32
  #
30
- # field :find_object, Node, null: true do
31
- # argument :node_id, ID, required: false
32
- # argument :object_type, String, required: false
33
- # argument :object_id, Integer, required: false
34
- # # either a global `node_id` or an `object_type`/`object_id` pair is required:
35
- # validates required: { one_of: [:node_id, [:object_type, :object_id]] }
36
- # end
33
+ # **Example: Require one of these _sets_ of arguments**
37
34
  #
38
- # @example require _some_ value for an argument, even if it's null
39
- # field :update_settings, AccountSettings do
40
- # # `required: :nullable` means this argument must be given, but may be `null`
41
- # argument :age, Integer, required: :nullable
42
- # end
35
+ # ```ruby
36
+ # field :find_object, Node, null: true do
37
+ # argument :node_id, ID, required: false
38
+ # argument :object_type, String, required: false
39
+ # argument :object_id, Integer, required: false
40
+ # # either a global `node_id` or an `object_type`/`object_id` pair is required:
41
+ # validates required: { one_of: [:node_id, [:object_type, :object_id]] }
42
+ # end
43
+ # ```
43
44
  #
45
+ # **Example: require _some_ value for an argument, even if it's null**
46
+ #
47
+ # ```ruby
48
+ # field :update_settings, AccountSettings do
49
+ # # `required: :nullable` means this argument must be given, but may be `null`
50
+ # argument :age, Integer, required: :nullable
51
+ # end
52
+ # ```
44
53
  class RequiredValidator < Validator
45
- # @param one_of [Array<Symbol>] A list of arguments, exactly one of which is required for this field
46
- # @param argument [Symbol] An argument that is required for this field
47
- # @param allow_all_hidden [Boolean] If `true`, then this validator won't run if all the `one_of: ...` arguments have been hidden
48
- # @param message [String]
54
+ # **Parameters**
55
+ #
56
+ # - `one_of` (`Array<Symbol>`) — A list of arguments, exactly one of which is required for this field
57
+ # - `argument` (`Symbol`) — An argument that is required for this field
58
+ # - `allow_all_hidden` (`Boolean`) — If `true`, then this validator won't run if all the `one_of: ...` arguments have been hidden
59
+ # - `message` (`String`)
60
+ #
61
+ # :call-seq:
62
+ # initialize(Array[Symbol] one_of:, Symbol argument:, bool allow_all_hidden:, String message:, **default_options)
49
63
  def initialize(one_of: nil, argument: nil, allow_all_hidden: nil, message: nil, **default_options)
50
64
  @one_of = if one_of
51
65
  one_of
@@ -64,7 +78,7 @@ module GraphQL
64
78
  partially_matched_conditions = 0
65
79
 
66
80
  visible_keywords = context.types.arguments(@validated).map(&:keyword)
67
- no_visible_conditions = true
81
+ no_visible_conditions = true #: bool
68
82
 
69
83
  if !value.nil?
70
84
  validation_parameter(@one_of).each do |one_of_condition|
@@ -79,8 +93,8 @@ module GraphQL
79
93
  fully_matched_conditions += 1
80
94
  end
81
95
  when Array
82
- any_match = false
83
- full_match = true
96
+ any_match = false #: bool
97
+ full_match = true #: bool
84
98
 
85
99
  one_of_condition.each do |k|
86
100
  if no_visible_conditions && visible_keywords.include?(k)
@@ -1,25 +1,42 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
 
3
4
  module GraphQL
4
5
  class Schema
5
6
  class Validator
6
7
  # The thing being validated
7
- # @return [GraphQL::Schema::Argument, GraphQL::Schema::Field, GraphQL::Schema::Resolver, Class<GraphQL::Schema::InputObject>]
8
+ #
9
+ # **Returns**
10
+ #
11
+ # - `GraphQL::Schema::Argument, GraphQL::Schema::Field, GraphQL::Schema::Resolver, Class<GraphQL::Schema::InputObject>`
8
12
  attr_reader :validated
9
13
 
10
- # @param validated [GraphQL::Schema::Argument, GraphQL::Schema::Field, GraphQL::Schema::Resolver, Class<GraphQL::Schema::InputObject>] The argument or argument owner this validator is attached to
11
- # @param allow_blank [Boolean] if `true`, then objects that respond to `.blank?` and return true for `.blank?` will skip this validation
12
- # @param allow_null [Boolean] if `true`, then incoming `null`s will skip this validation
14
+ # **Parameters**
15
+ #
16
+ # - `validated` (`GraphQL::Schema::Argument, GraphQL::Schema::Field, GraphQL::Schema::Resolver, Class<GraphQL::Schema::InputObject>`) — The argument or argument owner this validator is attached to
17
+ # - `allow_blank` (`Boolean`) — if `true`, then objects that respond to `.blank?` and return true for `.blank?` will skip this validation
18
+ # - `allow_null` (`Boolean`) — if `true`, then incoming `null`s will skip this validation
19
+ #
20
+ # :call-seq:
21
+ # initialize(GraphQL::Schema::Argument | GraphQL::Schema::Field | GraphQL::Schema::Resolver | Class[GraphQL::Schema::InputObject] validated:, bool allow_blank:, bool allow_null:)
13
22
  def initialize(validated:, allow_blank: false, allow_null: false)
14
23
  @validated = validated
15
24
  @allow_blank = allow_blank
16
25
  @allow_null = allow_null
17
26
  end
18
27
 
19
- # @param object [Object] The application object that this argument's field is being resolved for
20
- # @param context [GraphQL::Query::Context]
21
- # @param value [Object] The client-provided value for this argument (after parsing and coercing by the input type)
22
- # @return [nil, Array<String>, String] Error message or messages to add
28
+ # **Parameters**
29
+ #
30
+ # - `object` (`Object`) — The application object that this argument's field is being resolved for
31
+ # - `context` (`GraphQL::Query::Context`)
32
+ # - `value` (`Object`) — The client-provided value for this argument (after parsing and coercing by the input type)
33
+ #
34
+ # **Returns**
35
+ #
36
+ # - `nil, Array<String>, String` — Error message or messages to add
37
+ #
38
+ # :call-seq:
39
+ # validate(Object object, GraphQL::Query::Context context, Object value) -> nil | Array[String] | String
23
40
  def validate(object, context, value)
24
41
  raise GraphQL::RequiredImplementationMissingError, "Validator classes should implement #validate"
25
42
  end
@@ -34,7 +51,12 @@ module GraphQL
34
51
  string
35
52
  end
36
53
 
37
- # @return [Object] The current value to use for validation, based on `config_value` from configuration time. If a Proc is given, this calls it and returns it.
54
+ # **Returns**
55
+ #
56
+ # - `Object` — The current value to use for validation, based on `config_value` from configuration time. If a Proc is given, this calls it and returns it.
57
+ #
58
+ # :call-seq:
59
+ # validation_parameter(config_value) -> Object
38
60
  def validation_parameter(config_value)
39
61
  if config_value.is_a?(Proc)
40
62
  config_value.call
@@ -43,15 +65,28 @@ module GraphQL
43
65
  end
44
66
  end
45
67
 
46
- # @return [Boolean] `true` if `value` is `nil` and this validator has `allow_null: true` or if value is `.blank?` and this validator has `allow_blank: true`
68
+ # **Returns**
69
+ #
70
+ # - `Boolean` — `true` if `value` is `nil` and this validator has `allow_null: true` or if value is `.blank?` and this validator has `allow_blank: true`
71
+ #
72
+ # :call-seq:
73
+ # permitted_empty_value?(value) -> bool
47
74
  def permitted_empty_value?(value)
48
75
  (value.nil? && @allow_null) ||
49
76
  (@allow_blank && value.respond_to?(:blank?) && value.blank?)
50
77
  end
51
78
 
52
- # @param schema_member [GraphQL::Schema::Field, GraphQL::Schema::Argument, Class<GraphQL::Schema::InputObject>]
53
- # @param validates_hash [Hash{Symbol => Hash}, Hash{Class => Hash} nil] A configuration passed as `validates:`
54
- # @return [Array<Validator>]
79
+ # **Parameters**
80
+ #
81
+ # - `schema_member` (`GraphQL::Schema::Field, GraphQL::Schema::Argument, Class<GraphQL::Schema::InputObject>`)
82
+ # - `validates_hash` (`Hash{Symbol => Hash}, Hash{Class => Hash} nil`) — A configuration passed as `validates:`
83
+ #
84
+ # **Returns**
85
+ #
86
+ # - `Array<Validator>`
87
+ #
88
+ # :call-seq:
89
+ # from_config(GraphQL::Schema::Field | GraphQL::Schema::Argument | Class[GraphQL::Schema::InputObject] schema_member, Hash[Symbol, Hash] | Hash[Class, Hash] nil validates_hash) -> Array[Validator]
55
90
  def self.from_config(schema_member, validates_hash)
56
91
  if validates_hash.nil? || validates_hash.empty?
57
92
  EMPTY_ARRAY
@@ -89,17 +124,35 @@ module GraphQL
89
124
 
90
125
  # Add `validator_class` to be initialized when `validates:` is given `name`.
91
126
  # (It's initialized with whatever options are given by the key `name`).
92
- # @param name [Symbol]
93
- # @param validator_class [Class]
94
- # @return [void]
127
+ #
128
+ # **Parameters**
129
+ #
130
+ # - `name` (`Symbol`)
131
+ # - `validator_class` (`Class`)
132
+ #
133
+ # **Returns**
134
+ #
135
+ # - `void`
136
+ #
137
+ # :call-seq:
138
+ # install(Symbol name, Class validator_class) -> void
95
139
  def self.install(name, validator_class)
96
140
  all_validators[name] = validator_class
97
141
  nil
98
142
  end
99
143
 
100
- # Remove whatever validator class is {.install}ed at `name`, if there is one
101
- # @param name [Symbol]
102
- # @return [void]
144
+ # Remove whatever validator class is [.install](rdoc-ref:.install)ed at `name`, if there is one
145
+ #
146
+ # **Parameters**
147
+ #
148
+ # - `name` (`Symbol`)
149
+ #
150
+ # **Returns**
151
+ #
152
+ # - `void`
153
+ #
154
+ # :call-seq:
155
+ # uninstall(Symbol name) -> void
103
156
  def self.uninstall(name)
104
157
  all_validators.delete(name)
105
158
  nil
@@ -122,12 +175,23 @@ module GraphQL
122
175
  end
123
176
  end
124
177
 
125
- # @param validators [Array<Validator>]
126
- # @param object [Object]
127
- # @param context [Query::Context]
128
- # @param value [Object]
129
- # @return [void]
130
- # @raises [ValidationFailedError]
178
+ # **Parameters**
179
+ #
180
+ # - `validators` (`Array<Validator>`)
181
+ # - `object` (`Object`)
182
+ # - `context` (`Query::Context`)
183
+ # - `value` (`Object`)
184
+ #
185
+ # **Returns**
186
+ #
187
+ # - `void`
188
+ #
189
+ # **Raises**
190
+ #
191
+ # - `ValidationFailedError`
192
+ #
193
+ # :call-seq:
194
+ # validate!(Array[Validator] validators, Object object, Query::Context context, Object value, as:) -> void | ValidationFailedError
131
195
  def self.validate!(validators, object, context, value, as: nil)
132
196
  # Assuming the default case is no errors, reduce allocations in that case.
133
197
  # This will be replaced with a mutable array if we actually get any errors.
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
  module GraphQL
3
4
  class Schema
4
5
  class Visibility
5
- # You can use this to see how {GraphQL::Schema::Warden} and {GraphQL::Schema::Visibility::Profile}
6
+ # You can use this to see how [GraphQL::Schema::Warden](rdoc-ref:GraphQL::Schema::Warden) and [GraphQL::Schema::Visibility::Profile](rdoc-ref:GraphQL::Schema::Visibility::Profile)
6
7
  # handle `.visible?` differently in your schema.
7
8
  #
8
9
  # It runs the same method on both implementations and raises an error when the results diverge.
@@ -15,17 +16,20 @@ module GraphQL
15
16
  # This plugin adds two keys to `context` when running:
16
17
  #
17
18
  # - `visibility_migration_running: true`
18
- # - For the {Schema::Warden} which it instantiates, it adds `visibility_migration_warden_running: true`.
19
+ # - For the [Schema::Warden](rdoc-ref:Schema::Warden) which it instantiates, it adds `visibility_migration_warden_running: true`.
19
20
  #
20
21
  # Use those keys to modify your `visible?` behavior as needed.
21
22
  #
22
23
  # Also, in a pinch, you can set `skip_visibility_migration_error: true` in context to turn off this behavior per-query.
23
- # (In that case, it uses {Profile} directly.)
24
+ # (In that case, it uses [Profile](rdoc-ref:Profile) directly.)
24
25
  #
25
- # @example Adding this plugin
26
+ # **Examples**
26
27
  #
27
- # use GraphQL::Schema::Visibility, migration_errors: true
28
+ # **Example: Adding this plugin**
28
29
  #
30
+ # ```ruby
31
+ # use GraphQL::Schema::Visibility, migration_errors: true
32
+ # ```
29
33
  class Migration < GraphQL::Schema::Visibility::Profile
30
34
  class RuntimeTypesMismatchError < GraphQL::Error
31
35
  def initialize(method_called, warden_result, profile_result, method_args)
@@ -46,7 +50,7 @@ module GraphQL
46
50
  all_results = warden_result | profile_result
47
51
  all_results.sort_by!(&:graphql_name)
48
52
 
49
- entries_text = all_results.map { |entry| "#{entry.graphql_name} (#{entry})"}
53
+ entries_text = all_results.map { |entry| "#{entry.graphql_name} (#{entry})"} #: untyped
50
54
  width = entries_text.map(&:size).max
51
55
  yes = " ✔ "
52
56
  no = " "
@@ -66,6 +70,7 @@ module GraphQL
66
70
  "#{val.size}: #{val.map { |v| humanize(v) }.sort.inspect}"
67
71
  when Module
68
72
  if val.respond_to?(:graphql_name)
73
+ val = val #: as GraphQL::Schema::Member::type_definition
69
74
  "#{val.graphql_name} (#{val.inspect})"
70
75
  else
71
76
  val.inspect
@@ -87,7 +92,7 @@ module GraphQL
87
92
  if schema.const_defined?(:WardenCompatSchema, false) # don't use a defn from a superclass
88
93
  warden_schema = schema.const_get(:WardenCompatSchema, false)
89
94
  else
90
- warden_schema = Class.new(schema)
95
+ warden_schema = Class.new(schema) #: as singleton(GraphQL::Schema)
91
96
  warden_schema.use_visibility_profile = false
92
97
  # TODO public API
93
98
  warden_schema.send(:add_type_and_traverse, [warden_schema.query, warden_schema.mutation, warden_schema.subscription].compact, root: true)
@@ -129,6 +134,7 @@ module GraphQL
129
134
 
130
135
  PUBLIC_PROFILE_METHODS.each do |profile_method|
131
136
  define_method(profile_method) do |*args|
137
+ #: self as GraphQL::Schema::Visibility::Migration
132
138
  call_method_and_compare(profile_method, args)
133
139
  end
134
140
  end
@@ -173,6 +179,7 @@ module GraphQL
173
179
  member1 == member2
174
180
  end
175
181
  when Module
182
+ member1 = member1 #: as GraphQL::Schema::Member::type_definition
176
183
  if member1.introspection? && member2.introspection?
177
184
  member1.graphql_name == member2.graphql_name
178
185
  else
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
 
3
4
  module GraphQL
4
5
  class Schema
@@ -6,14 +7,19 @@ module GraphQL
6
7
  # This class filters the types, fields, arguments, enum values, and directives in a schema
7
8
  # based on the given `context`.
8
9
  #
9
- # It's like {Warden}, but has some differences:
10
+ # It's like `Warden`, but has some differences:
10
11
  #
11
- # - It doesn't use {Schema}'s top-level caches (eg {Schema.references_to}, {Schema.possible_types}, {Schema.types})
12
+ # - It doesn't use [Schema](rdoc-ref:GraphQL::Schema)'s top-level caches (eg [Schema.references_to](rdoc-ref:GraphQL::Schema.references_to), [Schema.possible_types](rdoc-ref:GraphQL::Schema.possible_types), [Schema.types](rdoc-ref:GraphQL::Schema.types))
12
13
  # - It doesn't hide Interface or Union types when all their possible types are hidden. (Instead, those types should implement `.visible?` to hide in that case.)
13
14
  # - It checks `.visible?` on root introspection types
14
15
  # - It can be used to cache profiles by name for re-use across queries
15
16
  class Profile
16
- # @return [Schema::Visibility::Profile]
17
+ # **Returns**
18
+ #
19
+ # - `Schema::Visibility::Profile`
20
+ #
21
+ # :call-seq:
22
+ # from_context(ctx, schema) -> Schema::Visibility::Profile
17
23
  def self.from_context(ctx, schema)
18
24
  if ctx.respond_to?(:types) && (types = ctx.types).is_a?(self)
19
25
  types
@@ -22,13 +28,9 @@ module GraphQL
22
28
  end
23
29
  end
24
30
 
25
- def self.null_profile(context:, schema:)
26
- profile = self.new(name: "NullProfile", context: context, schema: schema)
27
- profile.instance_variable_set(:@cached_visible, Hash.new { |k, v| k[v] = true }.compare_by_identity)
28
- profile
29
- end
30
-
31
- # @return [Symbol, nil]
31
+ # **Returns**
32
+ #
33
+ # - `Symbol, nil`
32
34
  attr_reader :name
33
35
 
34
36
  def freeze
@@ -158,8 +160,8 @@ module GraphQL
158
160
  ints = owner.interface_type_memberships.map(&:abstract_type)
159
161
  field_name = field.graphql_name
160
162
  filtered_ints = interfaces(owner)
161
- any_interface_has_field = false
162
- any_interface_has_visible_field = false
163
+ any_interface_has_field = false #: bool
164
+ any_interface_has_visible_field = false #: bool
163
165
  ints.each do |int_t|
164
166
  if (_int_f_defn = @cached_parent_fields[int_t][field_name])
165
167
  any_interface_has_field = true
@@ -197,7 +199,7 @@ module GraphQL
197
199
  def argument(owner, arg_name)
198
200
  arg = @cached_parent_arguments[owner][arg_name]
199
201
  if arg.is_a?(Array)
200
- visible_arg = nil
202
+ visible_arg = nil #: untyped
201
203
  arg.each do |arg_defn|
202
204
  if @cached_visible_arguments[owner][arg_defn]
203
205
  if visible_arg.nil?
@@ -363,7 +365,7 @@ module GraphQL
363
365
  t = @visibility.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
364
366
  if t
365
367
  if t.is_a?(Array)
366
- vis_t = nil
368
+ vis_t = nil #: untyped
367
369
  t.each do |t_defn|
368
370
  if @cached_visible[t_defn] && referenced?(t_defn)
369
371
  if vis_t.nil?
@@ -375,7 +377,7 @@ module GraphQL
375
377
  end
376
378
  vis_t
377
379
  else
378
- if t && @cached_visible[t] && referenced?(t)
380
+ if @cached_visible[t] && referenced?(t)
379
381
  t
380
382
  else
381
383
  nil
@@ -395,7 +397,7 @@ module GraphQL
395
397
  nil
396
398
  end
397
399
  if f.is_a?(Array)
398
- visible_f = nil
400
+ visible_f = nil #: untyped
399
401
  f.each do |f_defn|
400
402
  if @cached_visible_fields[owner][f_defn]
401
403
  if visible_f.nil?
@@ -438,7 +440,8 @@ module GraphQL
438
440
  visit = Visibility::Visit.new(@schema) do |member|
439
441
  if member.is_a?(Module) && member.respond_to?(:kind)
440
442
  if @cached_visible[member] && referenced?(member)
441
- type_name = member.graphql_name
443
+ type_name = member #: as untyped
444
+ .graphql_name
442
445
  if (prev_t = @all_types[type_name]) && !prev_t.equal?(member)
443
446
  raise_duplicate_definition(member, prev_t)
444
447
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
  module GraphQL
3
4
  class Schema
4
5
  class Visibility
@@ -42,7 +43,8 @@ module GraphQL
42
43
  case type.kind.name
43
44
  when "OBJECT", "INTERFACE"
44
45
  type.interface_type_memberships.each do |itm|
45
- append_unvisited_type(type, itm.abstract_type)
46
+ # Late-bound interfaces are stored as a String or LateBoundType instead of a TypeMembership
47
+ append_unvisited_type(type, itm.respond_to?(:abstract_type) ? itm.abstract_type : itm)
46
48
  end
47
49
  if type.kind.interface?
48
50
  type.orphan_types.each do |orphan_type|
@@ -135,11 +137,14 @@ module GraphQL
135
137
  def update_type_owner(owner, type)
136
138
  case owner
137
139
  when Module
140
+ owner = owner #: as GraphQL::Schema::Member::type_definition
138
141
  if owner.kind.union?
139
- owner.assign_type_membership_object_type(type)
142
+ union_type = owner #: as singleton(GraphQL::Schema::Union)
143
+ union_type.assign_type_membership_object_type(type)
140
144
  elsif type.kind.interface?
145
+ implementing_type = owner #: as GraphQL::Schema::Member::HasInterfaces
141
146
  new_interfaces = []
142
- owner.interfaces.each do |int_t|
147
+ implementing_type.interfaces.each do |int_t|
143
148
  if int_t.is_a?(String) && int_t == type.graphql_name
144
149
  new_interfaces << type
145
150
  elsif int_t.is_a?(LateBoundType) && int_t.graphql_name == type.graphql_name
@@ -149,15 +154,12 @@ module GraphQL
149
154
  # they were probably already added, maybe with options.
150
155
  end
151
156
  end
152
- owner.implements(*new_interfaces)
157
+ implementing_type.implements(*new_interfaces)
153
158
  new_interfaces.each do |int|
154
- pt = @possible_types[int] ||= []
155
- if !pt.include?(owner) && owner.is_a?(Class)
156
- pt << owner
157
- end
158
159
  int.interfaces.each do |indirect_int|
159
- if indirect_int.is_a?(LateBoundType) && (indirect_int_type = get_type(indirect_int.graphql_name)) # rubocop:disable Development/ContextIsPassedCop
160
- update_type_owner(owner, indirect_int_type)
160
+ if indirect_int.is_a?(LateBoundType) || indirect_int.is_a?(String)
161
+ # Resolve it like any other late-bound type, then add it to `owner`, too
162
+ append_unvisited_type(owner, indirect_int)
161
163
  end
162
164
  end
163
165
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
  require "graphql/schema/visibility/profile"
3
4
  require "graphql/schema/visibility/migration"
4
5
  require "graphql/schema/visibility/visit"
@@ -14,10 +15,15 @@ module GraphQL
14
15
  super(message)
15
16
  end
16
17
  end
17
- # @param schema [Class<GraphQL::Schema>]
18
- # @param profiles [Hash<Symbol => Hash>] A hash of `name => context` pairs for preloading visibility profiles
19
- # @param preload [Boolean] if `true`, load the default schema profile and all named profiles immediately (defaults to `true` for `Rails.env.production?` and `Rails.env.staging?`)
20
- # @param migration_errors [Boolean] if `true`, raise an error when `Visibility` and `Warden` return different results
18
+ # **Parameters**
19
+ #
20
+ # - `schema` (`Class<GraphQL::Schema>`)
21
+ # - `profiles` (`Hash<Symbol => Hash>`) — A hash of `name => context` pairs for preloading visibility profiles
22
+ # - `preload` (`Boolean`) — if `true`, load the default schema profile and all named profiles immediately (defaults to `true` for `Rails.env.production?` and `Rails.env.staging?`)
23
+ # - `migration_errors` (`Boolean`) — if `true`, raise an error when `Visibility` and `Warden` return different results
24
+ #
25
+ # :call-seq:
26
+ # use(Class[GraphQL::Schema] schema, dynamic:, Hash[Symbol, Hash] profiles:, bool preload:)
21
27
  def self.use(schema, dynamic: false, profiles: EmptyObjects::EMPTY_HASH, preload: (defined?(Rails.env) ? (Rails.env.production? || Rails.env.staging? || nil) : false), migration_errors: false)
22
28
  profiles&.each { |name, ctx|
23
29
  ctx[:visibility_profile] = name
@@ -108,35 +114,32 @@ module GraphQL
108
114
  end
109
115
  end
110
116
 
111
- # @api private
112
- def query_configured(query_type)
117
+ def query_configured(query_type) # :nodoc:
113
118
  require_if_preloaded("a query type was", "query(...)")
114
119
  end
115
120
 
116
- # @api private
117
- def mutation_configured(mutation_type)
121
+ def mutation_configured(mutation_type) # :nodoc:
118
122
  require_if_preloaded("a mutation type was", "mutation(...)")
119
123
  end
120
124
 
121
- # @api private
122
- def subscription_configured(subscription_type)
125
+ def subscription_configured(subscription_type) # :nodoc:
123
126
  require_if_preloaded("a mutation type was", "subscription(...)")
124
127
  end
125
128
 
126
- # @api private
127
- def orphan_types_configured(orphan_types)
129
+ def orphan_types_configured(orphan_types) # :nodoc:
128
130
  require_if_preloaded("orphan types were", "orphan_types(...)")
129
131
  end
130
132
 
131
- # @api private
132
- def introspection_system_configured(introspection_system)
133
+ def introspection_system_configured(introspection_system) # :nodoc:
133
134
  require_if_preloaded("custom introspection was", "introspection(...)")
134
135
  end
135
136
 
136
137
  # Make another Visibility for `schema` based on this one
137
- # @return [Visibility]
138
- # @api private
139
- def dup_for(other_schema)
138
+ #
139
+ # **Returns**
140
+ #
141
+ # - `Visibility`
142
+ def dup_for(other_schema) # :nodoc:
140
143
  self.class.new(
141
144
  other_schema,
142
145
  dynamic: @dynamic,
@@ -179,8 +182,7 @@ module GraphQL
179
182
 
180
183
  attr_reader :top_level
181
184
 
182
- # @api private
183
- attr_reader :unfiltered_interface_type_memberships
185
+ attr_reader :unfiltered_interface_type_memberships # :nodoc:
184
186
 
185
187
  def top_level_profile(refresh: false)
186
188
  if refresh
@@ -231,6 +233,7 @@ module GraphQL
231
233
  @unions_for_references = Set.new
232
234
  @visit = Visibility::Visit.new(@schema) do |member|
233
235
  if member.is_a?(Module)
236
+ member = member #: as GraphQL::Schema::Member::type_definition
234
237
  type_name = member.graphql_name
235
238
  if (prev_t = @types[type_name])
236
239
  if prev_t.is_a?(Array)
@@ -245,7 +248,8 @@ module GraphQL
245
248
  if member < GraphQL::Schema::Directive
246
249
  @directives << member
247
250
  elsif member.respond_to?(:interface_type_memberships)
248
- member.interface_type_memberships.each do |itm|
251
+ implementing_type = member #: as GraphQL::Schema::Member::HasInterfaces
252
+ implementing_type.interface_type_memberships.each do |itm|
249
253
  @all_references[itm.abstract_type] << member
250
254
  # `itm.object_type` may not actually be `member` if this implementation
251
255
  # is inherited from a superclass