graphql 2.6.12 → 2.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +3 -2
  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 +263 -161
  61. data/lib/graphql/execution/finalize.rb +12 -6
  62. data/lib/graphql/execution/input_values.rb +5 -2
  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 +38 -13
  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 +6 -1
  110. data/lib/graphql/language/nodes.rb +2094 -419
  111. data/lib/graphql/language/parser.rb +22 -12
  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 +137 -29
  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 -16
  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 +69 -50
  153. data/lib/graphql/schema/always_visible.rb +1 -0
  154. data/lib/graphql/schema/argument.rb +279 -45
  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 +507 -178
  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 +28 -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 +622 -110
  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 +21 -7
  186. data/lib/graphql/schema/member/graphql_type_names.rb +10 -6
  187. data/lib/graphql/schema/member/has_arguments.rb +111 -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 +45 -11
  193. data/lib/graphql/schema/member/has_fields.rb +151 -70
  194. data/lib/graphql/schema/member/has_interfaces.rb +8 -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 +44 -15
  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 +1050 -302
  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
  module Pagination
@@ -10,15 +11,33 @@ module GraphQL
10
11
  #
11
12
  # Unlike the previous connection implementation, these default to bidirectional pagination.
12
13
  #
13
- # Pagination arguments and context may be provided at initialization or assigned later (see {Schema::Field::ConnectionExtension}).
14
+ # Pagination arguments and context may be provided at initialization or assigned later (see [Schema::Field::ConnectionExtension](rdoc-ref:Schema::Field::ConnectionExtension)).
14
15
  class Connection
15
16
  class PaginationImplementationMissingError < GraphQL::Error
16
17
  end
17
18
 
18
- # @return [Object] A list object, from the application. This is the unpaginated value passed into the connection.
19
+ class << self
20
+ # Subclasses may override `cursor_for` to build their own cursors (for example, value-based cursors).
21
+ # In that case, position-based cursors from the parent class would be wrong, so `cursor_for_position`
22
+ # should call the overridden `cursor_for` instead.
23
+ #
24
+ # The result is cached on each class, since it's the same for every instance.
25
+ def custom_cursor_for?(default_owner) # :nodoc:
26
+ if !defined?(@custom_cursor_for)
27
+ @custom_cursor_for = instance_method(:cursor_for).owner != default_owner
28
+ end
29
+ @custom_cursor_for
30
+ end
31
+ end
32
+
33
+ # **Returns**
34
+ #
35
+ # - `Object` — A list object, from the application. This is the unpaginated value passed into the connection.
19
36
  attr_reader :items
20
37
 
21
- # @return [GraphQL::Query::Context]
38
+ # **Returns**
39
+ #
40
+ # - `GraphQL::Query::Context`
22
41
  attr_reader :context
23
42
 
24
43
  def context=(new_ctx)
@@ -29,13 +48,20 @@ module GraphQL
29
48
  @context
30
49
  end
31
50
 
32
- # @return [Object] the object this collection belongs to
51
+ # **Returns**
52
+ #
53
+ # - `Object` — the object this collection belongs to
33
54
  attr_accessor :parent
34
55
 
35
56
  # Raw access to client-provided values. (`max_page_size` not applied to first or last.)
36
57
  attr_accessor :before_value, :after_value, :first_value, :last_value
37
58
 
38
- # @return [String, nil] the client-provided cursor. `""` is treated as `nil`.
59
+ # **Returns**
60
+ #
61
+ # - `String, nil` — the client-provided cursor. `""` is treated as `nil`.
62
+ #
63
+ # :call-seq:
64
+ # before() -> String | nil
39
65
  def before
40
66
  if defined?(@before)
41
67
  @before
@@ -44,7 +70,12 @@ module GraphQL
44
70
  end
45
71
  end
46
72
 
47
- # @return [String, nil] the client-provided cursor. `""` is treated as `nil`.
73
+ # **Returns**
74
+ #
75
+ # - `String, nil` — the client-provided cursor. `""` is treated as `nil`.
76
+ #
77
+ # :call-seq:
78
+ # after() -> String | nil
48
79
  def after
49
80
  if defined?(@after)
50
81
  @after
@@ -53,19 +84,26 @@ module GraphQL
53
84
  end
54
85
  end
55
86
 
56
- # @return [Hash<Symbol => Object>] The field arguments from the field that returned this connection
87
+ # **Returns**
88
+ #
89
+ # - `Hash<Symbol => Object>` — The field arguments from the field that returned this connection
57
90
  attr_accessor :arguments
58
91
 
59
- # @param items [Object] some unpaginated collection item, like an `Array` or `ActiveRecord::Relation`
60
- # @param context [Query::Context]
61
- # @param parent [Object] The object this collection belongs to
62
- # @param first [Integer, nil] The limit parameter from the client, if it provided one
63
- # @param after [String, nil] A cursor for pagination, if the client provided one
64
- # @param last [Integer, nil] Limit parameter from the client, if provided
65
- # @param before [String, nil] A cursor for pagination, if the client provided one.
66
- # @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
67
- # @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
68
- # @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
92
+ # **Parameters**
93
+ #
94
+ # - `items` (`Object`) — some unpaginated collection item, like an `Array` or `ActiveRecord::Relation`
95
+ # - `context` (`Query::Context`)
96
+ # - `parent` (`Object`) — The object this collection belongs to
97
+ # - `first` (`Integer, nil`) — The limit parameter from the client, if it provided one
98
+ # - `after` (`String, nil`) — A cursor for pagination, if the client provided one
99
+ # - `last` (`Integer, nil`) — Limit parameter from the client, if provided
100
+ # - `before` (`String, nil`) — A cursor for pagination, if the client provided one.
101
+ # - `arguments` (`Hash`) — The arguments to the field that returned the collection wrapped by this connection
102
+ # - `max_page_size` (`Integer, nil`) — A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
103
+ # - `default_page_size` (`Integer, nil`) — A configured value to determine the result size when neither first or last are given.
104
+ #
105
+ # :call-seq:
106
+ # initialize(Object items, Object parent:, field:, Query::Context context:, Integer | nil first:, String | nil after:, Integer | nil max_page_size:, Integer | nil default_page_size:, Integer | nil last:, String | nil before:, edge_class:, Hash arguments:)
69
107
  def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil)
70
108
  @items = items
71
109
  @parent = parent
@@ -76,7 +114,7 @@ module GraphQL
76
114
  @last_value = last
77
115
  @before_value = before
78
116
  @arguments = arguments
79
- @edge_class = edge_class || self.class::Edge
117
+ @edge_class = edge_class || self.class.const_get(:Edge)
80
118
  # This is only true if the object was _initialized_ with an override
81
119
  # or if one is assigned later.
82
120
  @has_max_page_size_override = max_page_size != NOT_CONFIGURED
@@ -135,13 +173,12 @@ module GraphQL
135
173
  end
136
174
 
137
175
  attr_writer :first
138
- # @return [Integer, nil]
139
- # A clamped `first` value.
140
- # (The underlying instance variable doesn't have limits on it.)
141
- # If neither `first` nor `last` is given, but `default_page_size` is
142
- # present, default_page_size is used for first. If `default_page_size`
143
- # is greater than `max_page_size``, it'll be clamped down to
144
- # `max_page_size`. If `default_page_size` is nil, use `max_page_size`.
176
+ # **Returns**
177
+ #
178
+ # - `Integer, nil` — A clamped `first` value. (The underlying instance variable doesn't have limits on it.) If neither `first` nor `last` is given, but `default_page_size` is present, default_page_size is used for first. If `default_page_size` is greater than `max_page_size``, it'll be clamped down to `max_page_size`. If `default_page_size` is nil, use `max_page_size`.
179
+ #
180
+ # :call-seq:
181
+ # first() -> Integer | nil
145
182
  def first
146
183
  @first ||= begin
147
184
  capped = limit_pagination_argument(@first_value, max_page_size)
@@ -155,36 +192,72 @@ module GraphQL
155
192
  # This is called by `Relay::RangeAdd` -- it can be overridden
156
193
  # when `item` needs some modifications based on this connection's state.
157
194
  #
158
- # @param item [Object] An item newly added to `items`
159
- # @return [Edge]
195
+ # **Parameters**
196
+ #
197
+ # - `item` (`Object`) — An item newly added to `items`
198
+ #
199
+ # **Returns**
200
+ #
201
+ # - `Edge`
202
+ #
203
+ # :call-seq:
204
+ # range_add_edge(Object item) -> Edge
160
205
  def range_add_edge(item)
161
206
  edge_class.new(item, self)
162
207
  end
163
208
 
164
209
  attr_writer :last
165
- # @return [Integer, nil] A clamped `last` value. (The underlying instance variable doesn't have limits on it)
210
+ # **Returns**
211
+ #
212
+ # - `Integer, nil` — A clamped `last` value. (The underlying instance variable doesn't have limits on it)
213
+ #
214
+ # :call-seq:
215
+ # last() -> Integer | nil
166
216
  def last
167
217
  @last ||= limit_pagination_argument(@last_value, max_page_size)
168
218
  end
169
219
 
170
- # @return [Array<Edge>] {nodes}, but wrapped with Edge instances
220
+ # **Returns**
221
+ #
222
+ # - `Array<Edge>` — [nodes](rdoc-ref:nodes), but wrapped with Edge instances
223
+ #
224
+ # :call-seq:
225
+ # edges() -> Array[Edge]
171
226
  def edges
172
- @edges ||= nodes.map { |n| @edge_class.new(n, self) }
227
+ @edges ||= nodes.each_with_index.map do |n, index|
228
+ edge = @edge_class.new(n, self)
229
+ edge.graphql_connection_position = index
230
+ edge
231
+ end
173
232
  end
174
233
 
175
- # @return [Class] A wrapper class for edges of this connection
234
+ # **Returns**
235
+ #
236
+ # - `Class` — A wrapper class for edges of this connection
176
237
  attr_accessor :edge_class
177
238
 
178
- # @return [GraphQL::Schema::Field] The field this connection was returned by
239
+ # **Returns**
240
+ #
241
+ # - `GraphQL::Schema::Field` — The field this connection was returned by
179
242
  attr_accessor :field
243
+
244
+ # **Returns**
245
+ #
246
+ # - `GraphQL::Execution::Lookahead` Selections on this connection, set by connection fields
247
+ attr_accessor :lookahead
180
248
 
181
- # @return [Array<Object>] A slice of {items}, constrained by {@first_value}/{@after_value}/{@last_value}/{@before_value}
249
+ # **Returns**
250
+ #
251
+ # - `Array<Object>` — A slice of [items](rdoc-ref:items), constrained by `@first_value`/`@after_value`/`@last_value`/`@before_value`
252
+ #
253
+ # :call-seq:
254
+ # nodes() -> Array[Object]
182
255
  def nodes
183
256
  raise PaginationImplementationMissingError, "Implement #{self.class}#nodes to paginate `@items`"
184
257
  end
185
258
 
186
- # A dynamic alias for compatibility with {Relay::BaseConnection}.
187
- # @deprecated use {#nodes} instead
259
+ # A dynamic alias for compatibility with [GraphQL::Types::Relay::BaseConnection](rdoc-ref:GraphQL::Types::Relay::BaseConnection).
260
+ # **Deprecated:** use [nodes](rdoc-ref:#nodes) instead
188
261
  def edge_nodes
189
262
  nodes
190
263
  end
@@ -194,35 +267,77 @@ module GraphQL
194
267
  self
195
268
  end
196
269
 
197
- # @return [Boolean] True if there are more items after this page
270
+ # **Returns**
271
+ #
272
+ # - `Boolean` — True if there are more items after this page
273
+ #
274
+ # :call-seq:
275
+ # has_next_page() -> bool
198
276
  def has_next_page
199
277
  raise PaginationImplementationMissingError, "Implement #{self.class}#has_next_page to return the next-page check"
200
278
  end
201
279
 
202
- # @return [Boolean] True if there were items before these items
280
+ # **Returns**
281
+ #
282
+ # - `Boolean` — True if there were items before these items
283
+ #
284
+ # :call-seq:
285
+ # has_previous_page() -> bool
203
286
  def has_previous_page
204
287
  raise PaginationImplementationMissingError, "Implement #{self.class}#has_previous_page to return the previous-page check"
205
288
  end
206
289
 
207
- # @return [String] The cursor of the first item in {nodes}
290
+ # **Returns**
291
+ #
292
+ # - `String` — The cursor of the first item in [nodes](rdoc-ref:nodes)
293
+ #
294
+ # :call-seq:
295
+ # start_cursor() -> String
208
296
  def start_cursor
209
- nodes.first && cursor_for(nodes.first)
297
+ nodes.first && cursor_for_position(nodes.first, 0)
210
298
  end
211
299
 
212
- # @return [String] The cursor of the last item in {nodes}
300
+ # **Returns**
301
+ #
302
+ # - `String` — The cursor of the last item in [nodes](rdoc-ref:nodes)
303
+ #
304
+ # :call-seq:
305
+ # end_cursor() -> String
213
306
  def end_cursor
214
- nodes.last && cursor_for(nodes.last)
307
+ nodes.last && cursor_for_position(nodes.last, nodes.length - 1)
215
308
  end
216
309
 
217
310
  # Return a cursor for this item.
218
- # @param item [Object] one of the passed in {items}, taken from {nodes}
219
- # @return [String]
311
+ #
312
+ # **Parameters**
313
+ #
314
+ # - `item` (`Object`) — one of the passed in [items](rdoc-ref:items), taken from [nodes](rdoc-ref:nodes)
315
+ #
316
+ # **Returns**
317
+ #
318
+ # - `String`
319
+ #
320
+ # :call-seq:
321
+ # cursor_for(Object item) -> String
220
322
  def cursor_for(item)
221
323
  raise PaginationImplementationMissingError, "Implement #{self.class}#cursor_for(item) to return the cursor for #{item.inspect}"
222
324
  end
223
325
 
326
+ def cursor_for_position(item, _position) # :nodoc:
327
+ cursor_for(item)
328
+ end
329
+
224
330
  private
225
331
 
332
+ def cursor_index_for(item, collection)
333
+ @cursor_indexes ||= {}.compare_by_identity.tap do |indexes|
334
+ collection.each_with_index { |node, index| indexes[node] ||= index }
335
+ end
336
+ @cursor_indexes.fetch(item) do
337
+ raise GraphQL::ExecutionError, "Can't generate a cursor for an item outside this connection"
338
+ end
339
+ end
340
+
226
341
  def detect_was_authorized_by_scope_items
227
342
  if @context &&
228
343
  (current_runtime_state = Fiber[:__graphql_runtime_info]) &&
@@ -233,9 +348,17 @@ module GraphQL
233
348
  end
234
349
  end
235
350
 
236
- # @param argument [nil, Integer] `first` or `last`, as provided by the client
237
- # @param max_page_size [nil, Integer]
238
- # @return [nil, Integer] `nil` if the input was `nil`, otherwise a value between `0` and `max_page_size`
351
+ # **Parameters**
352
+ #
353
+ # - `argument` (`nil, Integer`) — `first` or `last`, as provided by the client
354
+ # - `max_page_size` (`nil, Integer`)
355
+ #
356
+ # **Returns**
357
+ #
358
+ # - `nil, Integer` — `nil` if the input was `nil`, otherwise a value between `0` and `max_page_size`
359
+ #
360
+ # :call-seq:
361
+ # limit_pagination_argument(nil | Integer argument, nil | Integer max_page_size) -> nil | Integer
239
362
  def limit_pagination_argument(argument, max_page_size)
240
363
  if argument
241
364
  if argument < 0
@@ -255,11 +378,14 @@ module GraphQL
255
378
  context.schema.cursor_encoder.encode(cursor, nonce: true)
256
379
  end
257
380
 
258
- # A wrapper around paginated items. It includes a {cursor} for pagination
381
+ # A wrapper around paginated items. It includes a [cursor](rdoc-ref:#cursor) for pagination
259
382
  # and could be extended with custom relationship-level data.
260
383
  class Edge
261
384
  attr_reader :node
262
385
 
386
+ # The zero-based position of this edge in the page
387
+ attr_accessor :graphql_connection_position # :nodoc:
388
+
263
389
  def initialize(node, connection)
264
390
  @connection = connection
265
391
  @node = node
@@ -270,7 +396,11 @@ module GraphQL
270
396
  end
271
397
 
272
398
  def cursor
273
- @cursor ||= @connection.cursor_for(@node)
399
+ @cursor ||= if @graphql_connection_position
400
+ @connection.cursor_for_position(@node, @graphql_connection_position)
401
+ else
402
+ @connection.cursor_for(@node)
403
+ end
274
404
  end
275
405
 
276
406
  def was_authorized_by_scope_items?
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
 
3
4
  module GraphQL
4
5
  module Pagination
@@ -6,17 +7,25 @@ module GraphQL
6
7
  #
7
8
  # Attach as a plugin.
8
9
  #
9
- # @example Adding a custom wrapper
10
- # class MySchema < GraphQL::Schema
11
- # connections.add(MyApp::SearchResults, MyApp::SearchResultsConnection)
12
- # end
10
+ # See [Schema.connections](rdoc-ref:Schema.connections)
13
11
  #
14
- # @example Removing default connection support for arrays (they can still be manually wrapped)
15
- # class MySchema < GraphQL::Schema
16
- # connections.delete(Array)
17
- # end
12
+ # **Examples**
18
13
  #
19
- # @see {Schema.connections}
14
+ # **Example: Adding a custom wrapper**
15
+ #
16
+ # ```ruby
17
+ # class MySchema < GraphQL::Schema
18
+ # connections.add(MyApp::SearchResults, MyApp::SearchResultsConnection)
19
+ # end
20
+ # ```
21
+ #
22
+ # **Example: Removing default connection support for arrays (they can still be manually wrapped)**
23
+ #
24
+ # ```ruby
25
+ # class MySchema < GraphQL::Schema
26
+ # connections.delete(Array)
27
+ # end
28
+ # ```
20
29
  class Connections
21
30
  class ImplementationMissingError < GraphQL::Error
22
31
  end
@@ -46,7 +55,7 @@ module GraphQL
46
55
  end
47
56
 
48
57
  def wrapper_for(items, wrappers: all_wrappers)
49
- impl = nil
58
+ impl = nil #: untyped
50
59
 
51
60
  items.class.ancestors.each { |cls|
52
61
  impl = wrappers[cls]
@@ -57,8 +66,7 @@ module GraphQL
57
66
  end
58
67
 
59
68
  # Used by the runtime to wrap values in connection wrappers.
60
- # @api Private
61
- def wrap(field, parent, items, arguments, context)
69
+ def wrap(field, parent, items, arguments, context) # :nodoc:
62
70
  return items if GraphQL::Execution::Interpreter::RawValue === items
63
71
  wrappers = context ? context.namespace(:connections)[:all_wrappers] : all_wrappers
64
72
  impl = wrapper_for(items, wrappers: wrappers)
@@ -114,8 +122,7 @@ module GraphQL
114
122
  end
115
123
  end
116
124
  # use an override if there is one
117
- # @api private
118
- def edge_class_for_field(field)
125
+ def edge_class_for_field(field) # :nodoc:
119
126
  conn_type = field.type.unwrap
120
127
  conn_type_edge_type = conn_type.respond_to?(:edge_class) && conn_type.edge_class
121
128
  if conn_type_edge_type && conn_type_edge_type != Pagination::Connection::Edge
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
  require "graphql/pagination/relation_connection"
3
4
 
4
5
  module GraphQL