graphql 1.13.17 → 2.0.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +1 -1
  3. data/lib/generators/graphql/relay.rb +3 -17
  4. data/lib/generators/graphql/templates/schema.erb +3 -0
  5. data/lib/graphql/analysis/ast/field_usage.rb +3 -1
  6. data/lib/graphql/analysis/ast/max_query_complexity.rb +0 -1
  7. data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
  8. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  9. data/lib/graphql/analysis/ast/visitor.rb +43 -36
  10. data/lib/graphql/analysis/ast.rb +2 -12
  11. data/lib/graphql/analysis.rb +0 -7
  12. data/lib/graphql/backtrace/table.rb +2 -20
  13. data/lib/graphql/backtrace/tracer.rb +2 -3
  14. data/lib/graphql/backtrace.rb +2 -8
  15. data/lib/graphql/dataloader/null_dataloader.rb +3 -1
  16. data/lib/graphql/dataloader/source.rb +9 -0
  17. data/lib/graphql/dataloader.rb +4 -1
  18. data/lib/graphql/dig.rb +1 -1
  19. data/lib/graphql/execution/errors.rb +12 -82
  20. data/lib/graphql/execution/interpreter/resolve.rb +26 -0
  21. data/lib/graphql/execution/interpreter/runtime.rb +159 -120
  22. data/lib/graphql/execution/interpreter.rb +187 -78
  23. data/lib/graphql/execution/lazy.rb +7 -21
  24. data/lib/graphql/execution/lookahead.rb +44 -40
  25. data/lib/graphql/execution/multiplex.rb +3 -174
  26. data/lib/graphql/execution.rb +11 -4
  27. data/lib/graphql/introspection/directive_type.rb +2 -2
  28. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  29. data/lib/graphql/introspection/entry_points.rb +2 -15
  30. data/lib/graphql/introspection/field_type.rb +1 -1
  31. data/lib/graphql/introspection/schema_type.rb +2 -2
  32. data/lib/graphql/introspection/type_type.rb +13 -6
  33. data/lib/graphql/introspection.rb +4 -3
  34. data/lib/graphql/language/document_from_schema_definition.rb +18 -35
  35. data/lib/graphql/language/lexer.rb +216 -1488
  36. data/lib/graphql/language/nodes.rb +65 -39
  37. data/lib/graphql/language/parser.rb +376 -364
  38. data/lib/graphql/language/parser.y +49 -44
  39. data/lib/graphql/language/printer.rb +37 -21
  40. data/lib/graphql/language/visitor.rb +191 -83
  41. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  42. data/lib/graphql/pagination/array_connection.rb +4 -2
  43. data/lib/graphql/pagination/connection.rb +31 -4
  44. data/lib/graphql/pagination/connections.rb +3 -28
  45. data/lib/graphql/pagination/relation_connection.rb +2 -0
  46. data/lib/graphql/query/context.rb +155 -196
  47. data/lib/graphql/query/input_validation_result.rb +1 -1
  48. data/lib/graphql/query/null_context.rb +0 -3
  49. data/lib/graphql/query/validation_pipeline.rb +10 -34
  50. data/lib/graphql/query/variables.rb +7 -20
  51. data/lib/graphql/query.rb +32 -42
  52. data/lib/graphql/railtie.rb +0 -104
  53. data/lib/graphql/rake_task/validate.rb +1 -1
  54. data/lib/graphql/rake_task.rb +29 -1
  55. data/lib/graphql/relay/range_add.rb +9 -20
  56. data/lib/graphql/relay.rb +0 -15
  57. data/lib/graphql/schema/addition.rb +7 -9
  58. data/lib/graphql/schema/argument.rb +36 -43
  59. data/lib/graphql/schema/build_from_definition.rb +32 -18
  60. data/lib/graphql/schema/directive/one_of.rb +12 -0
  61. data/lib/graphql/schema/directive/transform.rb +1 -1
  62. data/lib/graphql/schema/directive.rb +12 -23
  63. data/lib/graphql/schema/enum.rb +28 -39
  64. data/lib/graphql/schema/enum_value.rb +5 -25
  65. data/lib/graphql/schema/field/connection_extension.rb +4 -0
  66. data/lib/graphql/schema/field.rb +237 -339
  67. data/lib/graphql/schema/input_object.rb +56 -67
  68. data/lib/graphql/schema/interface.rb +0 -35
  69. data/lib/graphql/schema/introspection_system.rb +3 -8
  70. data/lib/graphql/schema/late_bound_type.rb +8 -2
  71. data/lib/graphql/schema/list.rb +0 -6
  72. data/lib/graphql/schema/loader.rb +1 -2
  73. data/lib/graphql/schema/member/base_dsl_methods.rb +17 -19
  74. data/lib/graphql/schema/member/build_type.rb +5 -7
  75. data/lib/graphql/schema/member/has_arguments.rb +146 -55
  76. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  77. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  78. data/lib/graphql/schema/member/has_directives.rb +81 -59
  79. data/lib/graphql/schema/member/has_fields.rb +17 -4
  80. data/lib/graphql/schema/member/has_interfaces.rb +49 -10
  81. data/lib/graphql/schema/member/has_validators.rb +31 -5
  82. data/lib/graphql/schema/member/relay_shortcuts.rb +47 -2
  83. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  84. data/lib/graphql/schema/member/validates_input.rb +1 -1
  85. data/lib/graphql/schema/member.rb +0 -6
  86. data/lib/graphql/schema/mutation.rb +0 -9
  87. data/lib/graphql/schema/non_null.rb +1 -7
  88. data/lib/graphql/schema/object.rb +15 -52
  89. data/lib/graphql/schema/relay_classic_mutation.rb +53 -42
  90. data/lib/graphql/schema/resolver/has_payload_type.rb +20 -10
  91. data/lib/graphql/schema/resolver.rb +41 -42
  92. data/lib/graphql/schema/scalar.rb +7 -22
  93. data/lib/graphql/schema/subscription.rb +0 -7
  94. data/lib/graphql/schema/timeout.rb +24 -28
  95. data/lib/graphql/schema/type_membership.rb +3 -0
  96. data/lib/graphql/schema/union.rb +10 -17
  97. data/lib/graphql/schema/warden.rb +34 -8
  98. data/lib/graphql/schema/wrapper.rb +0 -5
  99. data/lib/graphql/schema.rb +241 -973
  100. data/lib/graphql/static_validation/all_rules.rb +1 -0
  101. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  102. data/lib/graphql/static_validation/definition_dependencies.rb +7 -1
  103. data/lib/graphql/static_validation/error.rb +2 -2
  104. data/lib/graphql/static_validation/literal_validator.rb +19 -1
  105. data/lib/graphql/static_validation/rules/directives_are_defined.rb +11 -5
  106. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  107. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid.rb +66 -0
  108. data/lib/graphql/static_validation/rules/one_of_input_objects_are_valid_error.rb +29 -0
  109. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +12 -6
  110. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  111. data/lib/graphql/static_validation/validator.rb +3 -25
  112. data/lib/graphql/static_validation.rb +0 -2
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
  114. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  115. data/lib/graphql/subscriptions/event.rb +3 -8
  116. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  117. data/lib/graphql/subscriptions.rb +32 -20
  118. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  119. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  120. data/lib/graphql/tracing/appsignal_trace.rb +71 -0
  121. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  122. data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
  123. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  124. data/lib/graphql/tracing/notifications_trace.rb +41 -0
  125. data/lib/graphql/tracing/platform_trace.rb +107 -0
  126. data/lib/graphql/tracing/platform_tracing.rb +26 -40
  127. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  128. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  129. data/lib/graphql/tracing/scout_trace.rb +72 -0
  130. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  131. data/lib/graphql/tracing.rb +136 -40
  132. data/lib/graphql/type_kinds.rb +6 -3
  133. data/lib/graphql/types/iso_8601_date.rb +4 -1
  134. data/lib/graphql/types/iso_8601_date_time.rb +4 -0
  135. data/lib/graphql/types/relay/base_connection.rb +16 -6
  136. data/lib/graphql/types/relay/connection_behaviors.rb +29 -27
  137. data/lib/graphql/types/relay/edge_behaviors.rb +16 -5
  138. data/lib/graphql/types/relay/node_behaviors.rb +12 -2
  139. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  140. data/lib/graphql/types/relay.rb +0 -3
  141. data/lib/graphql/types/string.rb +1 -1
  142. data/lib/graphql/version.rb +1 -1
  143. data/lib/graphql.rb +13 -74
  144. metadata +30 -133
  145. data/lib/graphql/analysis/analyze_query.rb +0 -98
  146. data/lib/graphql/analysis/field_usage.rb +0 -45
  147. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  148. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  149. data/lib/graphql/analysis/query_complexity.rb +0 -88
  150. data/lib/graphql/analysis/query_depth.rb +0 -43
  151. data/lib/graphql/analysis/reducer_state.rb +0 -48
  152. data/lib/graphql/argument.rb +0 -131
  153. data/lib/graphql/authorization.rb +0 -82
  154. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  155. data/lib/graphql/backwards_compatibility.rb +0 -61
  156. data/lib/graphql/base_type.rb +0 -232
  157. data/lib/graphql/boolean_type.rb +0 -2
  158. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  159. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  160. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  161. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  162. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  163. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  164. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  165. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  166. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  167. data/lib/graphql/compatibility.rb +0 -5
  168. data/lib/graphql/define/assign_argument.rb +0 -12
  169. data/lib/graphql/define/assign_connection.rb +0 -13
  170. data/lib/graphql/define/assign_enum_value.rb +0 -18
  171. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  172. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  173. data/lib/graphql/define/assign_object_field.rb +0 -42
  174. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  175. data/lib/graphql/define/instance_definable.rb +0 -255
  176. data/lib/graphql/define/no_definition_error.rb +0 -7
  177. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  178. data/lib/graphql/define/type_definer.rb +0 -31
  179. data/lib/graphql/define.rb +0 -31
  180. data/lib/graphql/deprecated_dsl.rb +0 -55
  181. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  182. data/lib/graphql/directive/include_directive.rb +0 -2
  183. data/lib/graphql/directive/skip_directive.rb +0 -2
  184. data/lib/graphql/directive.rb +0 -107
  185. data/lib/graphql/enum_type.rb +0 -133
  186. data/lib/graphql/execution/execute.rb +0 -333
  187. data/lib/graphql/execution/flatten.rb +0 -40
  188. data/lib/graphql/execution/instrumentation.rb +0 -92
  189. data/lib/graphql/execution/lazy/resolve.rb +0 -91
  190. data/lib/graphql/execution/typecast.rb +0 -50
  191. data/lib/graphql/field/resolve.rb +0 -59
  192. data/lib/graphql/field.rb +0 -226
  193. data/lib/graphql/float_type.rb +0 -2
  194. data/lib/graphql/function.rb +0 -128
  195. data/lib/graphql/id_type.rb +0 -2
  196. data/lib/graphql/input_object_type.rb +0 -138
  197. data/lib/graphql/int_type.rb +0 -2
  198. data/lib/graphql/interface_type.rb +0 -72
  199. data/lib/graphql/internal_representation/document.rb +0 -27
  200. data/lib/graphql/internal_representation/node.rb +0 -206
  201. data/lib/graphql/internal_representation/print.rb +0 -51
  202. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  203. data/lib/graphql/internal_representation/scope.rb +0 -88
  204. data/lib/graphql/internal_representation/visit.rb +0 -36
  205. data/lib/graphql/internal_representation.rb +0 -7
  206. data/lib/graphql/language/lexer.rl +0 -260
  207. data/lib/graphql/list_type.rb +0 -80
  208. data/lib/graphql/non_null_type.rb +0 -71
  209. data/lib/graphql/object_type.rb +0 -130
  210. data/lib/graphql/query/arguments.rb +0 -189
  211. data/lib/graphql/query/arguments_cache.rb +0 -24
  212. data/lib/graphql/query/executor.rb +0 -52
  213. data/lib/graphql/query/literal_input.rb +0 -136
  214. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  215. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  216. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  217. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  218. data/lib/graphql/query/serial_execution.rb +0 -40
  219. data/lib/graphql/relay/array_connection.rb +0 -83
  220. data/lib/graphql/relay/base_connection.rb +0 -189
  221. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  222. data/lib/graphql/relay/connection_resolve.rb +0 -43
  223. data/lib/graphql/relay/connection_type.rb +0 -54
  224. data/lib/graphql/relay/edge.rb +0 -27
  225. data/lib/graphql/relay/edge_type.rb +0 -19
  226. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  227. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  228. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  229. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  230. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  231. data/lib/graphql/relay/mutation/result.rb +0 -38
  232. data/lib/graphql/relay/mutation.rb +0 -106
  233. data/lib/graphql/relay/node.rb +0 -39
  234. data/lib/graphql/relay/page_info.rb +0 -7
  235. data/lib/graphql/relay/relation_connection.rb +0 -188
  236. data/lib/graphql/relay/type_extensions.rb +0 -32
  237. data/lib/graphql/scalar_type.rb +0 -91
  238. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  239. data/lib/graphql/schema/default_parse_error.rb +0 -10
  240. data/lib/graphql/schema/default_type_error.rb +0 -17
  241. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  242. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  243. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  244. data/lib/graphql/schema/middleware_chain.rb +0 -82
  245. data/lib/graphql/schema/possible_types.rb +0 -44
  246. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  247. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  248. data/lib/graphql/schema/traversal.rb +0 -228
  249. data/lib/graphql/schema/validation.rb +0 -313
  250. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  251. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  252. data/lib/graphql/string_type.rb +0 -2
  253. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  254. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  255. data/lib/graphql/types/relay/default_relay.rb +0 -31
  256. data/lib/graphql/types/relay/node_field.rb +0 -24
  257. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  258. data/lib/graphql/union_type.rb +0 -115
  259. data/lib/graphql/upgrader/member.rb +0 -937
  260. data/lib/graphql/upgrader/schema.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6a026aa1c0479073cf5ab5a306644eba7aad3ed90029b843ada2223758cc80bb
4
- data.tar.gz: '05851e52f3cfe034ee8f50b12cb3cd9d31185b6737868230aee88fa4ad911814'
3
+ metadata.gz: 7b2e44f17a5ec90e92b165e06f843931585a3775096c7404966a51703a65fdb9
4
+ data.tar.gz: b79ce54109470f38f6cd50cd8ff79af7beaefbea4564ec7e876c3a58ffd0249f
5
5
  SHA512:
6
- metadata.gz: c552afdbecebded43cc1e95c51a644259198ebd464ea0439404a7b3bece415b4af60bacd5e25cef6ead8e8ad64ec00f8f0361dfbd5f7dfe4447a292a63856d8c
7
- data.tar.gz: d7bc2037a7601d565ae0e0c5a9c086849ca8667b9eba48d5add6effb7f59df12adeed520e75c3220af6b781ffe1084256266afc726b0f232270747dc6fd7c6e9
6
+ metadata.gz: 59c16753d159b0d25862dfa72e84a72037e19da288db049297d90ede697d4b4eb0456b5bd9b65b7517ef1f375a94c9d0d3cb246a34f5b6100fc347665f94f688
7
+ data.tar.gz: 96fb931b54905ee12fd04ac76847e7f20c69f66023b6241e39e69b6de862b7cb8b7ff2dc4db53725e11b0625c55c2c73fbe070a4278ce6eb839a99c2847ac306
@@ -47,7 +47,7 @@ module Graphql
47
47
  #
48
48
  # Accept a `--batch` option which adds `GraphQL::Batch` setup.
49
49
  #
50
- # Use `--no-graphiql` to skip `graphiql-rails` installation.
50
+ # Use `--skip-graphiql` to skip `graphiql-rails` installation.
51
51
  #
52
52
  # TODO: also add base classes
53
53
  class InstallGenerator < Rails::Generators::Base
@@ -33,27 +33,13 @@ module Graphql
33
33
  # Return a string UUID for `object`
34
34
  def self.id_from_object(object, type_definition, query_ctx)
35
35
  # For example, use Rails' GlobalID library (https://github.com/rails/globalid):
36
- object_id = object.to_global_id.to_s
37
- # Remove this redundant prefix to make IDs shorter:
38
- object_id = object_id.sub("gid://\#{GlobalID.app}/", "")
39
- encoded_id = Base64.urlsafe_encode64(object_id)
40
- # Remove the "=" padding
41
- encoded_id = encoded_id.sub(/=+/, "")
42
- # Add a type hint
43
- type_hint = type_definition.graphql_name.first
44
- "\#{type_hint}_\#{encoded_id}"
36
+ object.to_gid_param
45
37
  end
46
38
 
47
39
  # Given a string UUID, find the object
48
- def self.object_from_id(encoded_id_with_hint, query_ctx)
40
+ def self.object_from_id(global_id, query_ctx)
49
41
  # For example, use Rails' GlobalID library (https://github.com/rails/globalid):
50
- # Split off the type hint
51
- _type_hint, encoded_id = encoded_id_with_hint.split("_", 2)
52
- # Decode the ID
53
- id = Base64.urlsafe_decode64(encoded_id)
54
- # Rebuild it for Rails then find the object:
55
- full_global_id = "gid://\#{GlobalID.app}/\#{id}"
56
- GlobalID::Locator.locate(full_global_id)
42
+ GlobalID.find(global_id)
57
43
  end
58
44
  RUBY
59
45
  inject_into_file schema_file_path, schema_code, before: /^end\n/m, force: false
@@ -23,5 +23,8 @@ class <%= schema_name %> < GraphQL::Schema
23
23
  # to return the correct GraphQL object type for `obj`
24
24
  raise(GraphQL::RequiredImplementationMissingError)
25
25
  end
26
+
27
+ # Stop validating when it encounters this many errors:
28
+ validate_max_errors(100)
26
29
  end
27
30
  <% end -%>
@@ -39,9 +39,11 @@ module GraphQL
39
39
  @used_deprecated_arguments << argument.definition.path
40
40
  end
41
41
 
42
+ next if argument.value.nil?
43
+
42
44
  if argument.definition.type.kind.input_object?
43
45
  extract_deprecated_arguments(argument.value.arguments.argument_values) # rubocop:disable Development/ContextIsPassedCop -- runtime args instance
44
- elsif argument.definition.type.list? && !argument.value.nil?
46
+ elsif argument.definition.type.list?
45
47
  argument
46
48
  .value
47
49
  .select { |value| value.respond_to?(:arguments) }
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- require_relative "./query_complexity"
3
2
  module GraphQL
4
3
  module Analysis
5
4
  module AST
@@ -5,7 +5,7 @@ module GraphQL
5
5
  module AST
6
6
  class QueryComplexity < Analyzer
7
7
  # State for the query complexity calculation:
8
- # - `complexities_on_type` holds complexity scores for each type in an IRep node
8
+ # - `complexities_on_type` holds complexity scores for each type
9
9
  def initialize(query)
10
10
  super
11
11
  @complexities_on_type_by_query = {}
@@ -15,7 +15,6 @@ module GraphQL
15
15
  # # In your Schema file:
16
16
  #
17
17
  # class MySchema < GraphQL::Schema
18
- # use GraphQL::Analysis::AST
19
18
  # query_analyzer LogQueryDepth
20
19
  # end
21
20
  #
@@ -43,7 +43,7 @@ module GraphQL
43
43
 
44
44
  # Visit Helpers
45
45
 
46
- # @return [GraphQL::Query::Arguments] Arguments for this node, merging default values, literal values and query variables
46
+ # @return [GraphQL::Execution::Interpreter::Arguments] Arguments for this node, merging default values, literal values and query variables
47
47
  # @see {GraphQL::Query#arguments_for}
48
48
  def arguments_for(ast_node, field_definition)
49
49
  @query.arguments_for(ast_node, field_definition)
@@ -65,14 +65,41 @@ module GraphQL
65
65
  end
66
66
 
67
67
  # Visitor Hooks
68
+ [
69
+ :operation_definition, :fragment_definition,
70
+ :inline_fragment, :field, :directive, :argument, :fragment_spread
71
+ ].each do |node_type|
72
+ module_eval <<-RUBY, __FILE__, __LINE__
73
+ def call_on_enter_#{node_type}(node, parent)
74
+ @analyzers.each do |a|
75
+ begin
76
+ a.on_enter_#{node_type}(node, parent, self)
77
+ rescue AnalysisError => err
78
+ @rescued_errors << err
79
+ end
80
+ end
81
+ end
82
+
83
+ def call_on_leave_#{node_type}(node, parent)
84
+ @analyzers.each do |a|
85
+ begin
86
+ a.on_leave_#{node_type}(node, parent, self)
87
+ rescue AnalysisError => err
88
+ @rescued_errors << err
89
+ end
90
+ end
91
+ end
92
+
93
+ RUBY
94
+ end
68
95
 
69
96
  def on_operation_definition(node, parent)
70
97
  object_type = @schema.root_type_for_operation(node.operation_type)
71
98
  @object_types.push(object_type)
72
99
  @path.push("#{node.operation_type}#{node.name ? " #{node.name}" : ""}")
73
- call_analyzers(:on_enter_operation_definition, node, parent)
100
+ call_on_enter_operation_definition(node, parent)
74
101
  super
75
- call_analyzers(:on_leave_operation_definition, node, parent)
102
+ call_on_leave_operation_definition(node, parent)
76
103
  @object_types.pop
77
104
  @path.pop
78
105
  end
@@ -81,19 +108,19 @@ module GraphQL
81
108
  on_fragment_with_type(node) do
82
109
  @path.push("fragment #{node.name}")
83
110
  @in_fragment_def = false
84
- call_analyzers(:on_enter_fragment_definition, node, parent)
111
+ call_on_enter_fragment_definition(node, parent)
85
112
  super
86
113
  @in_fragment_def = false
87
- call_analyzers(:on_leave_fragment_definition, node, parent)
114
+ call_on_leave_fragment_definition(node, parent)
88
115
  end
89
116
  end
90
117
 
91
118
  def on_inline_fragment(node, parent)
92
119
  on_fragment_with_type(node) do
93
120
  @path.push("...#{node.type ? " on #{node.type.name}" : ""}")
94
- call_analyzers(:on_enter_inline_fragment, node, parent)
121
+ call_on_enter_inline_fragment(node, parent)
95
122
  super
96
- call_analyzers(:on_leave_inline_fragment, node, parent)
123
+ call_on_leave_inline_fragment(node, parent)
97
124
  end
98
125
  end
99
126
 
@@ -114,12 +141,10 @@ module GraphQL
114
141
  @skipping = @skip_stack.last || skip?(node)
115
142
  @skip_stack << @skipping
116
143
 
117
- call_analyzers(:on_enter_field, node, parent)
144
+ call_on_enter_field(node, parent)
118
145
  super
119
-
120
146
  @skipping = @skip_stack.pop
121
-
122
- call_analyzers(:on_leave_field, node, parent)
147
+ call_on_leave_field(node, parent)
123
148
  @response_path.pop
124
149
  @field_definitions.pop
125
150
  @object_types.pop
@@ -129,9 +154,9 @@ module GraphQL
129
154
  def on_directive(node, parent)
130
155
  directive_defn = @schema.directives[node.name]
131
156
  @directive_definitions.push(directive_defn)
132
- call_analyzers(:on_enter_directive, node, parent)
157
+ call_on_enter_directive(node, parent)
133
158
  super
134
- call_analyzers(:on_leave_directive, node, parent)
159
+ call_on_leave_directive(node, parent)
135
160
  @directive_definitions.pop
136
161
  end
137
162
 
@@ -153,29 +178,23 @@ module GraphQL
153
178
 
154
179
  @argument_definitions.push(argument_defn)
155
180
  @path.push(node.name)
156
- call_analyzers(:on_enter_argument, node, parent)
181
+ call_on_enter_argument(node, parent)
157
182
  super
158
- call_analyzers(:on_leave_argument, node, parent)
183
+ call_on_leave_argument(node, parent)
159
184
  @argument_definitions.pop
160
185
  @path.pop
161
186
  end
162
187
 
163
188
  def on_fragment_spread(node, parent)
164
189
  @path.push("... #{node.name}")
165
- call_analyzers(:on_enter_fragment_spread, node, parent)
190
+ call_on_enter_fragment_spread(node, parent)
166
191
  enter_fragment_spread_inline(node)
167
192
  super
168
193
  leave_fragment_spread_inline(node)
169
- call_analyzers(:on_leave_fragment_spread, node, parent)
194
+ call_on_leave_fragment_spread(node, parent)
170
195
  @path.pop
171
196
  end
172
197
 
173
- def on_abstract_node(node, parent)
174
- call_analyzers(:on_enter_abstract_node, node, parent)
175
- super
176
- call_analyzers(:on_leave_abstract_node, node, parent)
177
- end
178
-
179
198
  # @return [GraphQL::BaseType] The current object type
180
199
  def type_definition
181
200
  @object_types.last
@@ -226,9 +245,7 @@ module GraphQL
226
245
 
227
246
  object_types << object_type
228
247
 
229
- fragment_def.selections.each do |selection|
230
- visit_node(selection, fragment_def)
231
- end
248
+ on_fragment_definition_children(fragment_def)
232
249
  end
233
250
 
234
251
  # Visit a fragment spread inline instead of visiting the definition
@@ -242,16 +259,6 @@ module GraphQL
242
259
  dir.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
243
260
  end
244
261
 
245
- def call_analyzers(method, node, parent)
246
- @analyzers.each do |analyzer|
247
- begin
248
- analyzer.public_send(method, node, parent, self)
249
- rescue AnalysisError => err
250
- @rescued_errors << err
251
- end
252
- end
253
- end
254
-
255
262
  def on_fragment_with_type(node)
256
263
  object_type = if node.type
257
264
  @query.warden.get_type(node.type.name)
@@ -11,16 +11,6 @@ module GraphQL
11
11
  module Analysis
12
12
  module AST
13
13
  module_function
14
-
15
- def use(schema_class)
16
- if schema_class.analysis_engine == self
17
- definition_line = caller(2, 1).first
18
- GraphQL::Deprecation.warn("GraphQL::Analysis::AST is now the default; remove `use GraphQL::Analysis::AST` from the schema definition (#{definition_line})")
19
- else
20
- schema_class.analysis_engine = self
21
- end
22
- end
23
-
24
14
  # Analyze a multiplex, and all queries within.
25
15
  # Multiplex analyzers are ran for all queries, keeping state.
26
16
  # Query analyzers are ran per query, without carrying state between queries.
@@ -31,7 +21,7 @@ module GraphQL
31
21
  def analyze_multiplex(multiplex, analyzers)
32
22
  multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
33
23
 
34
- multiplex.trace("analyze_multiplex", { multiplex: multiplex }) do
24
+ multiplex.current_trace.analyze_multiplex(multiplex: multiplex) do
35
25
  query_results = multiplex.queries.map do |query|
36
26
  if query.valid?
37
27
  analyze_query(
@@ -58,7 +48,7 @@ module GraphQL
58
48
  # @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
59
49
  # @return [Array<Any>] Results from those analyzers
60
50
  def analyze_query(query, analyzers, multiplex_analyzers: [])
61
- query.trace("analyze_query", { query: query }) do
51
+ query.current_trace.analyze_query(query: query) do
62
52
  query_analyzers = analyzers
63
53
  .map { |analyzer| analyzer.new(query) }
64
54
  .select { |analyzer| analyzer.analyze? }
@@ -1,9 +1,2 @@
1
1
  # frozen_string_literal: true
2
2
  require "graphql/analysis/ast"
3
- require "graphql/analysis/max_query_complexity"
4
- require "graphql/analysis/max_query_depth"
5
- require "graphql/analysis/query_complexity"
6
- require "graphql/analysis/query_depth"
7
- require "graphql/analysis/reducer_state"
8
- require "graphql/analysis/analyze_query"
9
- require "graphql/analysis/field_usage"
@@ -83,7 +83,7 @@ module GraphQL
83
83
  value = if top && @override_value
84
84
  @override_value
85
85
  else
86
- value_at(@context.query.context.namespace(:interpreter)[:runtime], context_entry.path)
86
+ value_at(@context.query.context.namespace(:interpreter_runtime)[:runtime], context_entry.path)
87
87
  end
88
88
  rows << [
89
89
  "#{context_entry.ast_node ? context_entry.ast_node.position.join(":") : ""}",
@@ -97,24 +97,6 @@ module GraphQL
97
97
  else
98
98
  rows
99
99
  end
100
- when GraphQL::Query::Context::FieldResolutionContext
101
- ctx = context_entry
102
- field_name = "#{ctx.irep_node.owner_type.name}.#{ctx.field.name}"
103
- position = "#{ctx.ast_node.line}:#{ctx.ast_node.col}"
104
- field_alias = ctx.ast_node.alias
105
- object = ctx.object
106
- if object.is_a?(GraphQL::Schema::Object)
107
- object = object.object
108
- end
109
- rows << [
110
- "#{position}",
111
- "#{field_name}#{field_alias ? " as #{field_alias}" : ""}",
112
- "#{object.inspect}",
113
- ctx.irep_node.arguments.to_h.inspect,
114
- Backtrace::InspectResult.inspect_result(top && @override_value ? @override_value : ctx.value),
115
- ]
116
-
117
- build_rows(ctx.parent, rows: rows)
118
100
  when GraphQL::Query::Context
119
101
  query = context_entry.query
120
102
  op = query.selected_operation
@@ -130,7 +112,7 @@ module GraphQL
130
112
  if object.is_a?(GraphQL::Schema::Object)
131
113
  object = object.object
132
114
  end
133
- value = value_at(context_entry.namespace(:interpreter)[:runtime], [])
115
+ value = value_at(context_entry.namespace(:interpreter_runtime)[:runtime], [])
134
116
  rows << [
135
117
  "#{position}",
136
118
  "#{op_type}#{op_name ? " #{op_name}" : ""}",
@@ -23,9 +23,9 @@ module GraphQL
23
23
  push_data = multiplex.queries.first
24
24
  end
25
25
  when "execute_field", "execute_field_lazy"
26
- query = metadata[:query] || raise(ArgumentError, "Add `legacy: true` to use GraphQL::Backtrace without the interpreter runtime.")
26
+ query = metadata[:query]
27
27
  multiplex = query.multiplex
28
- push_key = metadata[:path]
28
+ push_key = query.context[:current_path]
29
29
  parent_frame = multiplex.context[:graphql_backtrace_contexts][push_key[0..-2]]
30
30
 
31
31
  if parent_frame.is_a?(GraphQL::Query)
@@ -62,7 +62,6 @@ module GraphQL
62
62
  potential_context = multiplex_context[:last_graphql_backtrace_context]
63
63
 
64
64
  if potential_context.is_a?(GraphQL::Query::Context) ||
65
- potential_context.is_a?(GraphQL::Query::Context::FieldResolutionContext) ||
66
65
  potential_context.is_a?(Backtrace::Frame)
67
66
  raise TracedError.new(err, potential_context)
68
67
  else
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  require "graphql/backtrace/inspect_result"
3
- require "graphql/backtrace/legacy_tracer"
4
3
  require "graphql/backtrace/table"
5
4
  require "graphql/backtrace/traced_error"
6
5
  require "graphql/backtrace/tracer"
@@ -23,13 +22,8 @@ module GraphQL
23
22
 
24
23
  def_delegators :to_a, :each, :[]
25
24
 
26
- def self.use(schema_defn, legacy: false)
27
- tracer = if legacy
28
- self::LegacyTracer
29
- else
30
- self::Tracer
31
- end
32
- schema_defn.tracer(tracer)
25
+ def self.use(schema_defn)
26
+ schema_defn.tracer(self::Tracer)
33
27
  end
34
28
 
35
29
  def initialize(context, value: nil)
@@ -11,7 +11,9 @@ module GraphQL
11
11
  # executed sychronously.
12
12
  def run; end
13
13
  def run_isolated; yield; end
14
- def yield; end
14
+ def yield
15
+ raise GraphQL::Error, "GraphQL::Dataloader is not running -- add `use GraphQL::Dataloader` to your schema to use Dataloader sources."
16
+ end
15
17
 
16
18
  def append_job
17
19
  yield
@@ -86,6 +86,15 @@ module GraphQL
86
86
  !@pending_keys.empty?
87
87
  end
88
88
 
89
+ # Add these key-value pairs to this source's cache
90
+ # (future loads will use these merged values).
91
+ # @param results [Hash<Object => Object>] key-value pairs to cache in this source
92
+ # @return [void]
93
+ def merge(results)
94
+ @results.merge!(results)
95
+ nil
96
+ end
97
+
89
98
  # Called by {GraphQL::Dataloader} to resolve and pending requests to this source.
90
99
  # @api private
91
100
  # @return [void]
@@ -289,7 +289,10 @@ module GraphQL
289
289
  fiber_locals = {}
290
290
 
291
291
  Thread.current.keys.each do |fiber_var_key|
292
- fiber_locals[fiber_var_key] = Thread.current[fiber_var_key]
292
+ # This variable should be fresh in each new fiber
293
+ if fiber_var_key != :__graphql_runtime_info
294
+ fiber_locals[fiber_var_key] = Thread.current[fiber_var_key]
295
+ end
293
296
  end
294
297
 
295
298
  if @nonblocking
data/lib/graphql/dig.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  module GraphQL
3
3
  module Dig
4
4
  # implemented using the old activesupport #dig instead of the ruby built-in
5
- # so we can use some of the magic in Schema::InputObject and Query::Arguments
5
+ # so we can use some of the magic in Schema::InputObject and Interpreter::Arguments
6
6
  # to handle stringified/symbolized keys.
7
7
  #
8
8
  # @param args [Array<[String, Symbol>] Retrieves the value object corresponding to the each key objects repeatedly
@@ -2,59 +2,15 @@
2
2
 
3
3
  module GraphQL
4
4
  module Execution
5
- # A plugin that wraps query execution with error handling.
6
- # Supports class-based schemas and the new {Interpreter} runtime only.
7
- #
8
- # @example Handling ActiveRecord::NotFound
9
- #
10
- # class MySchema < GraphQL::Schema
11
- # use GraphQL::Execution::Errors
12
- #
13
- # rescue_from(ActiveRecord::NotFound) do |err, obj, args, ctx, field|
14
- # ErrorTracker.log("Not Found: #{err.message}")
15
- # nil
16
- # end
17
- # end
18
- #
19
5
  class Errors
20
- def self.use(schema)
21
- definition_line = caller(2, 1).first
22
- GraphQL::Deprecation.warn("GraphQL::Execution::Errors is now installed by default, remove `use GraphQL::Execution::Errors` from #{definition_line}")
23
- end
24
-
25
- NEW_HANDLER_HASH = ->(h, k) {
26
- h[k] = {
27
- class: k,
28
- handler: nil,
29
- subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
30
- }
31
- }
32
-
33
- def initialize(schema)
34
- @schema = schema
35
- @handlers = {
36
- class: nil,
37
- handler: nil,
38
- subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
39
- }
40
- end
41
-
42
- # @api private
43
- def each_rescue
44
- handlers = @handlers.values
45
- while (handler = handlers.shift) do
46
- yield(handler[:class], handler[:handler])
47
- handlers.concat(handler[:subclass_handlers].values)
48
- end
49
- end
50
-
51
6
  # Register this handler, updating the
52
7
  # internal handler index to maintain least-to-most specific.
53
8
  #
54
9
  # @param error_class [Class<Exception>]
10
+ # @param error_handlers [Hash]
55
11
  # @param error_handler [Proc]
56
12
  # @return [void]
57
- def rescue_from(error_class, error_handler)
13
+ def self.register_rescue_from(error_class, error_handlers, error_handler)
58
14
  subclasses_handlers = {}
59
15
  this_level_subclasses = []
60
16
  # During this traversal, do two things:
@@ -62,13 +18,12 @@ module GraphQL
62
18
  # and gather them up to be inserted _under_ this class
63
19
  # - Find the point in the index where this handler should be inserted
64
20
  # (That is, _under_ any superclasses, or at top-level, if there are no superclasses registered)
65
- handlers = @handlers[:subclass_handlers]
66
- while (handlers) do
21
+ while (error_handlers) do
67
22
  this_level_subclasses.clear
68
23
  # First, identify already-loaded handlers that belong
69
24
  # _under_ this one. (That is, they're handlers
70
25
  # for subclasses of `error_class`.)
71
- handlers.each do |err_class, handler|
26
+ error_handlers.each do |err_class, handler|
72
27
  if err_class < error_class
73
28
  subclasses_handlers[err_class] = handler
74
29
  this_level_subclasses << err_class
@@ -76,13 +31,13 @@ module GraphQL
76
31
  end
77
32
  # Any handlers that we'll be moving, delete them from this point in the index
78
33
  this_level_subclasses.each do |err_class|
79
- handlers.delete(err_class)
34
+ error_handlers.delete(err_class)
80
35
  end
81
36
 
82
37
  # See if any keys in this hash are superclasses of this new class:
83
- next_index_point = handlers.find { |err_class, handler| error_class < err_class }
38
+ next_index_point = error_handlers.find { |err_class, handler| error_class < err_class }
84
39
  if next_index_point
85
- handlers = next_index_point[1][:subclass_handlers]
40
+ error_handlers = next_index_point[1][:subclass_handlers]
86
41
  else
87
42
  # this new handler doesn't belong to any sub-handlers,
88
43
  # so insert it in the current set of `handlers`
@@ -91,40 +46,15 @@ module GraphQL
91
46
  end
92
47
  # Having found the point at which to insert this handler,
93
48
  # register it and merge any subclass handlers back in at this point.
94
- this_class_handlers = handlers[error_class]
49
+ this_class_handlers = error_handlers[error_class]
95
50
  this_class_handlers[:handler] = error_handler
96
51
  this_class_handlers[:subclass_handlers].merge!(subclasses_handlers)
97
52
  nil
98
53
  end
99
54
 
100
- # Call the given block with the schema's configured error handlers.
101
- #
102
- # If the block returns a lazy value, it's not wrapped with error handling. That area will have to be wrapped itself.
103
- #
104
- # @param ctx [GraphQL::Query::Context]
105
- # @return [Object] Either the result of the given block, or some object to replace the result, in case of error handling.
106
- def with_error_handling(ctx)
107
- yield
108
- rescue StandardError => err
109
- handler = find_handler_for(err.class)
110
- if handler
111
- runtime_info = ctx.namespace(:interpreter) || {}
112
- obj = runtime_info[:current_object]
113
- args = runtime_info[:current_arguments]
114
- args = args && args.keyword_arguments
115
- field = runtime_info[:current_field]
116
- if obj.is_a?(GraphQL::Schema::Object)
117
- obj = obj.object
118
- end
119
- handler[:handler].call(err, obj, args, ctx, field)
120
- else
121
- raise err
122
- end
123
- end
124
-
125
55
  # @return [Proc, nil] The handler for `error_class`, if one was registered on this schema or inherited
126
- def find_handler_for(error_class)
127
- handlers = @handlers[:subclass_handlers]
56
+ def self.find_handler_for(schema, error_class)
57
+ handlers = schema.error_handlers[:subclass_handlers]
128
58
  handler = nil
129
59
  while (handlers) do
130
60
  _err_class, next_handler = handlers.find { |err_class, handler| error_class <= err_class }
@@ -139,8 +69,8 @@ module GraphQL
139
69
  end
140
70
 
141
71
  # check for a handler from a parent class:
142
- if @schema.superclass.respond_to?(:error_handler) && (parent_errors = @schema.superclass.error_handler)
143
- parent_handler = parent_errors.find_handler_for(error_class)
72
+ if schema.superclass.respond_to?(:error_handlers)
73
+ parent_handler = find_handler_for(schema.superclass, error_class)
144
74
  end
145
75
 
146
76
  # If the inherited handler is more specific than the one defined here,
@@ -11,6 +11,25 @@ module GraphQL
11
11
  nil
12
12
  end
13
13
 
14
+ def self.resolve_each_depth(lazies_at_depth, dataloader)
15
+ depths = lazies_at_depth.keys
16
+ depths.sort!
17
+ next_depth = depths.first
18
+ if next_depth
19
+ lazies = lazies_at_depth[next_depth]
20
+ lazies_at_depth.delete(next_depth)
21
+ if lazies.any?
22
+ dataloader.append_job {
23
+ lazies.each(&:value) # resolve these Lazy instances
24
+ }
25
+ # Run lazies _and_ dataloader, see if more are enqueued
26
+ dataloader.run
27
+ resolve_each_depth(lazies_at_depth, dataloader)
28
+ end
29
+ end
30
+ nil
31
+ end
32
+
14
33
  # After getting `results` back from an interpreter evaluation,
15
34
  # continue it until you get a response-ready Ruby value.
16
35
  #
@@ -59,6 +78,13 @@ module GraphQL
59
78
  end
60
79
 
61
80
  if next_results.any?
81
+ # Any pending data loader jobs may populate the
82
+ # resutl arrays or result hashes accumulated in
83
+ # `next_results``. Run those **to completion**
84
+ # before continuing to resolve `next_results`.
85
+ # (Just `.append_job` doesn't work if any pending
86
+ # jobs require multiple passes.)
87
+ dataloader.run
62
88
  dataloader.append_job { resolve(next_results, dataloader) }
63
89
  end
64
90