graphql 2.6.11 → 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 +10 -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 +93 -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 +40 -13
  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 +72 -25
  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 +24 -17
  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 +123 -22
  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 +9 -2
  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 +65 -20
  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 +59 -9
  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 +43 -5
  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,41 +28,56 @@ 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
35
37
  @cached_visible.default_proc = nil
38
+ @cached_visible.freeze
36
39
  @cached_visible_fields.default_proc = nil
37
40
  @cached_visible_fields.each do |type, fields|
38
41
  fields.default_proc = nil
42
+ fields.freeze
39
43
  end
44
+ @cached_visible_fields.freeze
40
45
  @cached_visible_arguments.default_proc = nil
41
46
  @cached_visible_arguments.each do |type, fields|
42
47
  fields.default_proc = nil
48
+ fields.freeze
43
49
  end
50
+ @cached_visible_arguments.freeze
44
51
  @cached_parent_fields.default_proc = nil
45
52
  @cached_parent_fields.each do |type, fields|
46
53
  fields.default_proc = nil
54
+ fields.freeze
47
55
  end
56
+ @cached_parent_fields.freeze
48
57
  @cached_parent_arguments.default_proc = nil
49
58
  @cached_parent_arguments.each do |type, args|
50
59
  args.default_proc = nil
60
+ args.freeze
51
61
  end
62
+ @cached_parent_arguments.freeze
52
63
  @cached_possible_types.default_proc = nil
64
+ @cached_possible_types.freeze
53
65
  @cached_enum_values.default_proc = nil
66
+ @cached_enum_values.freeze
54
67
  @cached_fields.default_proc = nil
68
+ @cached_fields.freeze
55
69
  @cached_arguments.default_proc = nil
70
+ @cached_arguments.freeze
56
71
  @loadable_possible_types.default_proc = nil
72
+ @loadable_possible_types.freeze
57
73
  @cached_field_result.default_proc = nil
58
- @cached_field_result.each { |_, h| h.default_proc = nil }
74
+ @cached_field_result.each do |_, h|
75
+ h.default_proc = nil
76
+ h.freeze
77
+ end
78
+ @cached_field_result.freeze
59
79
  @cached_type_result.default_proc = nil
80
+ @cached_type_result.freeze
60
81
  super
61
82
  end
62
83
 
@@ -139,8 +160,8 @@ module GraphQL
139
160
  ints = owner.interface_type_memberships.map(&:abstract_type)
140
161
  field_name = field.graphql_name
141
162
  filtered_ints = interfaces(owner)
142
- any_interface_has_field = false
143
- any_interface_has_visible_field = false
163
+ any_interface_has_field = false #: bool
164
+ any_interface_has_visible_field = false #: bool
144
165
  ints.each do |int_t|
145
166
  if (_int_f_defn = @cached_parent_fields[int_t][field_name])
146
167
  any_interface_has_field = true
@@ -178,7 +199,7 @@ module GraphQL
178
199
  def argument(owner, arg_name)
179
200
  arg = @cached_parent_arguments[owner][arg_name]
180
201
  if arg.is_a?(Array)
181
- visible_arg = nil
202
+ visible_arg = nil #: untyped
182
203
  arg.each do |arg_defn|
183
204
  if @cached_visible_arguments[owner][arg_defn]
184
205
  if visible_arg.nil?
@@ -277,10 +298,18 @@ module GraphQL
277
298
  arguments(f).each do |arg|
278
299
  argument(f, arg.graphql_name)
279
300
  end
301
+
302
+ resolver_class = f.resolver
303
+ if resolver_class
304
+ arguments(resolver_class).each do |arg|
305
+ argument(resolver_class, arg.graphql_name)
306
+ end
307
+ end
280
308
  end
281
309
  @schema.introspection_system.dynamic_fields.each do |f|
282
310
  field(type_defn, f.graphql_name)
283
311
  end
312
+ interfaces(type_defn)
284
313
  elsif type_defn.kind.input_object?
285
314
  arguments(type_defn).each do |arg|
286
315
  argument(type_defn, arg.graphql_name)
@@ -289,8 +318,9 @@ module GraphQL
289
318
  enum_values(type_defn)
290
319
  elsif type_defn.kind.union?
291
320
  loadable_possible_types(type_defn, @context)
292
- elsif type_defn.kind.object? || type_defn.kind.interface?
293
- interfaces(type_defn)
321
+ @schema.introspection_system.dynamic_fields.each do |f|
322
+ field(type_defn, f.graphql_name)
323
+ end
294
324
  end
295
325
  possible_types(type_defn)
296
326
  end
@@ -313,6 +343,20 @@ module GraphQL
313
343
  argument(directive, directive_argument.graphql_name)
314
344
  end
315
345
  end
346
+
347
+ @cached_arguments.each do |owner, args|
348
+ @cached_parent_arguments[owner]
349
+
350
+ args.each do |arg|
351
+ if (loads_type = arg.loads)
352
+ loadable?(loads_type, @context)
353
+ possible_types(loads_type)
354
+ if loads_type.kind.union?
355
+ loadable_possible_types(loads_type, @context)
356
+ end
357
+ end
358
+ end
359
+ end
316
360
  end
317
361
 
318
362
  private
@@ -321,7 +365,7 @@ module GraphQL
321
365
  t = @visibility.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
322
366
  if t
323
367
  if t.is_a?(Array)
324
- vis_t = nil
368
+ vis_t = nil #: untyped
325
369
  t.each do |t_defn|
326
370
  if @cached_visible[t_defn] && referenced?(t_defn)
327
371
  if vis_t.nil?
@@ -333,7 +377,7 @@ module GraphQL
333
377
  end
334
378
  vis_t
335
379
  else
336
- if t && @cached_visible[t] && referenced?(t)
380
+ if @cached_visible[t] && referenced?(t)
337
381
  t
338
382
  else
339
383
  nil
@@ -353,7 +397,7 @@ module GraphQL
353
397
  nil
354
398
  end
355
399
  if f.is_a?(Array)
356
- visible_f = nil
400
+ visible_f = nil #: untyped
357
401
  f.each do |f_defn|
358
402
  if @cached_visible_fields[owner][f_defn]
359
403
  if visible_f.nil?
@@ -396,7 +440,8 @@ module GraphQL
396
440
  visit = Visibility::Visit.new(@schema) do |member|
397
441
  if member.is_a?(Module) && member.respond_to?(:kind)
398
442
  if @cached_visible[member] && referenced?(member)
399
- type_name = member.graphql_name
443
+ type_name = member #: as untyped
444
+ .graphql_name
400
445
  if (prev_t = @all_types[type_name]) && !prev_t.equal?(member)
401
446
  raise_duplicate_definition(member, prev_t)
402
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