graphql 1.9.21 → 1.10.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/core.rb +0 -1
  3. data/lib/generators/graphql/install_generator.rb +0 -1
  4. data/lib/generators/graphql/mutation_generator.rb +1 -1
  5. data/lib/generators/graphql/templates/base_field.erb +4 -0
  6. data/lib/generators/graphql/templates/graphql_controller.erb +0 -5
  7. data/lib/generators/graphql/templates/mutation.erb +1 -1
  8. data/lib/generators/graphql/templates/schema.erb +1 -1
  9. data/lib/graphql.rb +1 -11
  10. data/lib/graphql/analysis/ast.rb +2 -2
  11. data/lib/graphql/analysis/ast/analyzer.rb +4 -23
  12. data/lib/graphql/analysis/ast/max_query_complexity.rb +3 -3
  13. data/lib/graphql/analysis/ast/max_query_depth.rb +3 -7
  14. data/lib/graphql/analysis/ast/query_complexity.rb +2 -2
  15. data/lib/graphql/argument.rb +6 -2
  16. data/lib/graphql/backtrace/table.rb +10 -2
  17. data/lib/graphql/base_type.rb +5 -1
  18. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +5 -9
  19. data/lib/graphql/define/assign_object_field.rb +2 -2
  20. data/lib/graphql/define/defined_object_proxy.rb +0 -3
  21. data/lib/graphql/define/instance_definable.rb +3 -14
  22. data/lib/graphql/enum_type.rb +4 -0
  23. data/lib/graphql/execution/directive_checks.rb +2 -2
  24. data/lib/graphql/execution/errors.rb +14 -15
  25. data/lib/graphql/execution/execute.rb +1 -1
  26. data/lib/graphql/execution/interpreter/runtime.rb +17 -39
  27. data/lib/graphql/execution/multiplex.rb +3 -3
  28. data/lib/graphql/field.rb +8 -0
  29. data/lib/graphql/filter.rb +1 -1
  30. data/lib/graphql/function.rb +1 -1
  31. data/lib/graphql/input_object_type.rb +1 -2
  32. data/lib/graphql/introspection/entry_points.rb +1 -2
  33. data/lib/graphql/introspection/input_value_type.rb +27 -9
  34. data/lib/graphql/introspection/schema_type.rb +1 -2
  35. data/lib/graphql/language/block_string.rb +2 -2
  36. data/lib/graphql/language/document_from_schema_definition.rb +5 -11
  37. data/lib/graphql/language/lexer.rb +48 -49
  38. data/lib/graphql/language/lexer.rl +48 -49
  39. data/lib/graphql/language/nodes.rb +11 -14
  40. data/lib/graphql/language/parser.rb +645 -650
  41. data/lib/graphql/language/parser.y +7 -8
  42. data/lib/graphql/language/token.rb +1 -1
  43. data/lib/graphql/non_null_type.rb +0 -10
  44. data/lib/graphql/pagination.rb +6 -0
  45. data/lib/graphql/pagination/active_record_relation_connection.rb +35 -0
  46. data/lib/graphql/pagination/array_connection.rb +78 -0
  47. data/lib/graphql/pagination/connection.rb +150 -0
  48. data/lib/graphql/pagination/connections.rb +103 -0
  49. data/lib/graphql/pagination/mongoid_relation_connection.rb +25 -0
  50. data/lib/graphql/pagination/relation_connection.rb +157 -0
  51. data/lib/graphql/pagination/sequel_dataset_connection.rb +28 -0
  52. data/lib/graphql/query.rb +1 -7
  53. data/lib/graphql/query/arguments.rb +3 -9
  54. data/lib/graphql/query/context.rb +9 -31
  55. data/lib/graphql/query/literal_input.rb +29 -10
  56. data/lib/graphql/query/null_context.rb +0 -4
  57. data/lib/graphql/query/variable_validation_error.rb +1 -1
  58. data/lib/graphql/query/variables.rb +2 -4
  59. data/lib/graphql/relay/base_connection.rb +7 -3
  60. data/lib/graphql/relay/edges_instrumentation.rb +1 -1
  61. data/lib/graphql/relay/node.rb +2 -2
  62. data/lib/graphql/relay/relation_connection.rb +5 -9
  63. data/lib/graphql/schema.rb +27 -68
  64. data/lib/graphql/schema/argument.rb +31 -5
  65. data/lib/graphql/schema/base_64_bp.rb +2 -3
  66. data/lib/graphql/schema/build_from_definition.rb +113 -179
  67. data/lib/graphql/schema/build_from_definition/resolve_map.rb +10 -4
  68. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +1 -1
  69. data/lib/graphql/schema/directive.rb +6 -7
  70. data/lib/graphql/schema/directive/feature.rb +1 -1
  71. data/lib/graphql/schema/enum.rb +1 -0
  72. data/lib/graphql/schema/enum_value.rb +4 -1
  73. data/lib/graphql/schema/field.rb +37 -39
  74. data/lib/graphql/schema/field/connection_extension.rb +11 -1
  75. data/lib/graphql/schema/input_object.rb +2 -5
  76. data/lib/graphql/schema/interface.rb +2 -0
  77. data/lib/graphql/schema/introspection_system.rb +1 -4
  78. data/lib/graphql/schema/loader.rb +6 -12
  79. data/lib/graphql/schema/member.rb +2 -0
  80. data/lib/graphql/schema/member/base_dsl_methods.rb +2 -2
  81. data/lib/graphql/schema/member/build_type.rb +4 -0
  82. data/lib/graphql/schema/member/cached_graphql_definition.rb +5 -0
  83. data/lib/graphql/schema/member/has_ast_node.rb +17 -0
  84. data/lib/graphql/schema/member/has_fields.rb +10 -16
  85. data/lib/graphql/schema/member/instrumentation.rb +1 -6
  86. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  87. data/lib/graphql/schema/mutation.rb +1 -1
  88. data/lib/graphql/schema/object.rb +5 -6
  89. data/lib/graphql/schema/possible_types.rb +3 -3
  90. data/lib/graphql/schema/printer.rb +1 -3
  91. data/lib/graphql/schema/relay_classic_mutation.rb +2 -6
  92. data/lib/graphql/schema/resolver.rb +5 -35
  93. data/lib/graphql/schema/scalar.rb +1 -0
  94. data/lib/graphql/schema/subscription.rb +6 -6
  95. data/lib/graphql/schema/timeout_middleware.rb +2 -3
  96. data/lib/graphql/schema/type_expression.rb +27 -17
  97. data/lib/graphql/schema/union.rb +7 -26
  98. data/lib/graphql/schema/validation.rb +1 -17
  99. data/lib/graphql/schema/warden.rb +3 -77
  100. data/lib/graphql/schema/wrapper.rb +1 -1
  101. data/lib/graphql/static_validation/definition_dependencies.rb +12 -21
  102. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +9 -4
  103. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +10 -7
  104. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  105. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -5
  106. data/lib/graphql/static_validation/rules/fields_will_merge.rb +4 -4
  107. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
  108. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -3
  109. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +5 -6
  110. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  111. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -1
  112. data/lib/graphql/subscriptions.rb +7 -7
  113. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +2 -2
  114. data/lib/graphql/subscriptions/event.rb +5 -19
  115. data/lib/graphql/subscriptions/instrumentation.rb +9 -4
  116. data/lib/graphql/subscriptions/subscription_root.rb +2 -10
  117. data/lib/graphql/tracing/skylight_tracing.rb +0 -1
  118. data/lib/graphql/types/int.rb +1 -1
  119. data/lib/graphql/types/relay/base_connection.rb +3 -1
  120. data/lib/graphql/union_type.rb +23 -58
  121. data/lib/graphql/upgrader/member.rb +1 -1
  122. data/lib/graphql/version.rb +1 -1
  123. metadata +20 -13
  124. data/lib/generators/graphql/templates/base_mutation.erb +0 -8
  125. data/lib/graphql/schema/type_membership.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cc71a5ff7b742541447b08e62f4b0561ae2b7ae3767d9b18000e0cfdcd411a1
4
- data.tar.gz: decb826d15ed416571e152b108698a326803cadf45cc78d9a823344bc156b3f4
3
+ metadata.gz: 6d8cd9472c04900ca59a46d06eedf501e09d1f0561a5df1c902faada7c9536df
4
+ data.tar.gz: 409d5ef50405fe5f6ca2f1c197e9c98696c3b89bbf35323e325e7a4bc157419c
5
5
  SHA512:
6
- metadata.gz: ef0ce5989f626b9907fd77c0c54dd42f695e4484236da24f689a160fc521614d7cdc9600f0c9044c2e3b547afc1d862efa23da45b2bc13b0173f3c3af2683059
7
- data.tar.gz: e45810e9c2e0f885e42bfe90c4daf9383e0860543ac9a6ecf6215f994b7af43c0d8d46b74da78a43f9159e3c9fe3882c5ac97257f67a5272407eb6f9b80bbe87
6
+ metadata.gz: '0511959efa6a890699def5ea1d681ed9000435903f078955ecdf0a4f4c1be409ea542cd8e8b9cced7f22e22df49115038bbb544d611b9f66a6fdb5ae75c92566'
7
+ data.tar.gz: cb29aa9f21e13c65d4b700720cd2079968f6f6b709712e464133f78c383841c219c24bce7a5ffe6b6dd6577c6e7c03f282f259dca73896b669d2cfcaaa072abe
@@ -25,7 +25,6 @@ module Graphql
25
25
 
26
26
  def create_mutation_root_type
27
27
  create_dir("#{options[:directory]}/mutations")
28
- template("base_mutation.erb", "#{options[:directory]}/mutations/base_mutation.rb", { skip: true })
29
28
  template("mutation_type.erb", "#{options[:directory]}/types/mutation_type.rb", { skip: true })
30
29
  insert_root_type('mutation', 'MutationType')
31
30
  end
@@ -24,7 +24,6 @@ module Graphql
24
24
  # - query_type.rb
25
25
  # - loaders/
26
26
  # - mutations/
27
- # - base_mutation.rb
28
27
  # - {app_name}_schema.rb
29
28
  # ```
30
29
  #
@@ -45,7 +45,7 @@ module Graphql
45
45
  private
46
46
 
47
47
  def assign_names!(name)
48
- @field_name = name.camelize.underscore
48
+ @field_name = name.camelize(:lower)
49
49
  @mutation_name = name.camelize(:upper)
50
50
  @file_name = name.camelize.underscore
51
51
  end
@@ -1,5 +1,9 @@
1
1
  module Types
2
2
  class BaseField < GraphQL::Schema::Field
3
3
  argument_class Types::BaseArgument
4
+
5
+ def resolve_field(obj, args, ctx)
6
+ resolve(obj, args, ctx)
7
+ end
4
8
  end
5
9
  end
@@ -1,9 +1,4 @@
1
1
  class GraphqlController < ApplicationController
2
- # If accessing from outside this domain, nullify the session
3
- # This allows for outside API access while preventing CSRF attacks,
4
- # but you'll have to authenticate your user separately
5
- # protect_from_forgery with: :null_session
6
-
7
2
  def execute
8
3
  variables = ensure_hash(params[:variables])
9
4
  query = params[:query]
@@ -1,5 +1,5 @@
1
1
  module Mutations
2
- class <%= mutation_name %> < BaseMutation
2
+ class <%= mutation_name %> < GraphQL::Schema::RelayClassicMutation
3
3
  # TODO: define return fields
4
4
  # field :post, Types::PostType, null: false
5
5
 
@@ -24,7 +24,7 @@ class <%= schema_name %> < GraphQL::Schema
24
24
  def self.resolve_type(type, obj, ctx)
25
25
  # TODO: Implement this function
26
26
  # to return the correct type for `obj`
27
- raise(GraphQL::RequiredImplementationMissingError)
27
+ raise(NotImplementedError)
28
28
  end
29
29
  <% end %><% if options[:batch] %>
30
30
  # GraphQL::Batch setup:
@@ -7,20 +7,9 @@ require "forwardable"
7
7
  require_relative "./graphql/railtie" if defined? Rails::Railtie
8
8
 
9
9
  module GraphQL
10
- # forwards-compat for argument handling
11
- module Ruby2Keywords
12
- if RUBY_VERSION < "2.7"
13
- def ruby2_keywords(*)
14
- end
15
- end
16
- end
17
-
18
10
  class Error < StandardError
19
11
  end
20
12
 
21
- class RequiredImplementationMissingError < Error
22
- end
23
-
24
13
  # Turn a query string or schema definition into an AST
25
14
  # @param graphql_string [String] a GraphQL query string or schema definition
26
15
  # @return [GraphQL::Language::Nodes::Document]
@@ -131,3 +120,4 @@ require "graphql/authorization"
131
120
  require "graphql/unauthorized_error"
132
121
  require "graphql/unauthorized_field_error"
133
122
  require "graphql/load_application_object_failed_error"
123
+ require "graphql/pagination"
@@ -23,7 +23,7 @@ module GraphQL
23
23
  #
24
24
  # @param multiplex [GraphQL::Execution::Multiplex]
25
25
  # @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
26
- # @return [Array<Any>] Results from multiplex analyzers
26
+ # @return [void]
27
27
  def analyze_multiplex(multiplex, analyzers)
28
28
  multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
29
29
 
@@ -46,8 +46,8 @@ module GraphQL
46
46
  multiplex.queries.each_with_index do |query, idx|
47
47
  query.analysis_errors = multiplex_errors + analysis_errors(query_results[idx])
48
48
  end
49
- multiplex_results
50
49
  end
50
+ nil
51
51
  end
52
52
 
53
53
  # @param query [GraphQL::Query]
@@ -5,21 +5,10 @@ module GraphQL
5
5
  # Query analyzer for query ASTs. Query analyzers respond to visitor style methods
6
6
  # but are prefixed by `enter` and `leave`.
7
7
  #
8
- # When an analyzer is initialized with a Multiplex, you can always get the current query from
9
- # `visitor.query` in the visit methods.
10
- #
11
- # @param [GraphQL::Query, GraphQL::Execution::Multiplex] The query or multiplex to analyze
8
+ # @param [GraphQL::Query] The query to analyze
12
9
  class Analyzer
13
- def initialize(subject)
14
- @subject = subject
15
-
16
- if subject.is_a?(GraphQL::Query)
17
- @query = subject
18
- @multiplex = nil
19
- else
20
- @multiplex = subject
21
- @query = nil
22
- end
10
+ def initialize(query)
11
+ @query = query
23
12
  end
24
13
 
25
14
  # Analyzer hook to decide at analysis time whether a query should
@@ -33,7 +22,7 @@ module GraphQL
33
22
  # in a query error.
34
23
  # @return [Any] The analyzer result
35
24
  def result
36
- raise GraphQL::RequiredImplementationMissingError
25
+ raise NotImplementedError
37
26
  end
38
27
 
39
28
  class << self
@@ -69,15 +58,7 @@ module GraphQL
69
58
 
70
59
  protected
71
60
 
72
- # @return [GraphQL::Query, GraphQL::Execution::Multiplex] Whatever this analyzer is analyzing
73
- attr_reader :subject
74
-
75
- # @return [GraphQL::Query, nil] `nil` if this analyzer is visiting a multiplex
76
- # (When this is `nil`, use `visitor.query` inside visit methods to get the current query)
77
61
  attr_reader :query
78
-
79
- # @return [GraphQL::Execution::Multiplex, nil] `nil` if this analyzer is visiting a query
80
- attr_reader :multiplex
81
62
  end
82
63
  end
83
64
  end
@@ -7,12 +7,12 @@ module GraphQL
7
7
  # see {Schema#max_complexity} and {Query#max_complexity}
8
8
  class MaxQueryComplexity < QueryComplexity
9
9
  def result
10
- return if subject.max_complexity.nil?
10
+ return if query.max_complexity.nil?
11
11
 
12
12
  total_complexity = max_possible_complexity
13
13
 
14
- if total_complexity > subject.max_complexity
15
- GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{subject.max_complexity}")
14
+ if total_complexity > query.max_complexity
15
+ GraphQL::AnalysisError.new("Query has complexity of #{total_complexity}, which exceeds max complexity of #{query.max_complexity}")
16
16
  else
17
17
  nil
18
18
  end
@@ -4,14 +4,10 @@ module GraphQL
4
4
  module AST
5
5
  class MaxQueryDepth < QueryDepth
6
6
  def result
7
- configured_max_depth = if query
8
- query.max_depth
9
- else
10
- multiplex.schema.max_depth
11
- end
7
+ return unless query.max_depth
12
8
 
13
- if configured_max_depth && @max_depth > configured_max_depth
14
- GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{configured_max_depth}")
9
+ if @max_depth > query.max_depth
10
+ GraphQL::AnalysisError.new("Query has depth of #{@max_depth}, which exceeds max depth of #{query.max_depth}")
15
11
  else
16
12
  nil
17
13
  end
@@ -42,7 +42,7 @@ module GraphQL
42
42
  if @complexities_on_type.last.is_a?(AbstractTypeComplexity)
43
43
  key = selection_key(visitor.response_path, visitor.query)
44
44
  parent_type = visitor.parent_type_definition
45
- visitor.query.possible_types(parent_type).each do |type|
45
+ query.possible_types(parent_type).each do |type|
46
46
  @complexities_on_type.last.merge(type, key, own_complexity)
47
47
  end
48
48
  else
@@ -74,7 +74,7 @@ module GraphQL
74
74
 
75
75
  case defined_complexity
76
76
  when Proc
77
- defined_complexity.call(visitor.query.context, arguments, child_complexity)
77
+ defined_complexity.call(query.context, arguments, child_complexity)
78
78
  when Numeric
79
79
  defined_complexity + (child_complexity || 0)
80
80
  else
@@ -113,6 +113,10 @@ module GraphQL
113
113
  @prepare_proc = BackwardsCompatibility.wrap_arity(prepare_proc, from: 1, to: 2, name: "Argument#prepare(value, ctx)")
114
114
  end
115
115
 
116
+ def type_class
117
+ metadata[:type_class]
118
+ end
119
+
116
120
  NO_DEFAULT_VALUE = Object.new
117
121
  # @api private
118
122
  def self.from_dsl(name, type_or_argument = nil, description = nil, default_value: NO_DEFAULT_VALUE, as: nil, prepare: DefaultPrepare, **kwargs, &block)
@@ -134,9 +138,9 @@ module GraphQL
134
138
  end
135
139
 
136
140
  if type_or_argument.is_a?(GraphQL::Argument)
137
- type_or_argument.redefine(**kwargs, &block)
141
+ type_or_argument.redefine(kwargs, &block)
138
142
  else
139
- GraphQL::Argument.define(**kwargs, &block)
143
+ GraphQL::Argument.define(kwargs, &block)
140
144
  end
141
145
  end
142
146
 
@@ -84,10 +84,14 @@ module GraphQL
84
84
  field_name = "#{ctx.irep_node.owner_type.name}.#{ctx.field.name}"
85
85
  position = "#{ctx.ast_node.line}:#{ctx.ast_node.col}"
86
86
  field_alias = ctx.ast_node.alias
87
+ object = ctx.object
88
+ if object.is_a?(GraphQL::Schema::Object)
89
+ object = object.object
90
+ end
87
91
  rows << [
88
92
  "#{position}",
89
93
  "#{field_name}#{field_alias ? " as #{field_alias}" : ""}",
90
- "#{ctx.object.inspect}",
94
+ "#{object.inspect}",
91
95
  ctx.irep_node.arguments.to_h.inspect,
92
96
  Backtrace::InspectResult.inspect_result(top && @override_value ? @override_value : ctx.value),
93
97
  ]
@@ -104,10 +108,14 @@ module GraphQL
104
108
  position = "?:?"
105
109
  end
106
110
  op_name = query.selected_operation_name
111
+ object = query.root_value
112
+ if object.is_a?(GraphQL::Schema::Object)
113
+ object = object.object
114
+ end
107
115
  rows << [
108
116
  "#{position}",
109
117
  "#{op_type}#{op_name ? " #{op_name}" : ""}",
110
- "#{query.root_value.inspect}",
118
+ "#{object.inspect}",
111
119
  query.variables.to_h.inspect,
112
120
  Backtrace::InspectResult.inspect_result(query.context.value),
113
121
  ]
@@ -43,6 +43,10 @@ module GraphQL
43
43
  # @see {GraphQL::SchemaMember}
44
44
  alias :graphql_definition :itself
45
45
 
46
+ def type_class
47
+ metadata[:type_class]
48
+ end
49
+
46
50
  def name=(name)
47
51
  GraphQL::NameValidator.validate!(name)
48
52
  @name = name
@@ -167,7 +171,7 @@ module GraphQL
167
171
  end
168
172
 
169
173
  def coerce_result(value, ctx)
170
- raise GraphQL::RequiredImplementationMissingError
174
+ raise NotImplementedError
171
175
  end
172
176
 
173
177
  # Types with fields may override this
@@ -70,15 +70,11 @@ module GraphQL
70
70
  ")
71
71
  end
72
72
 
73
- def assert_empty_document(query_string)
74
- doc = parse(query_string)
75
- assert_equal 0, doc.definitions.length
76
- end
77
-
78
- def test_it_parses_blank_queries
79
- assert_empty_document("")
80
- assert_empty_document(" ")
81
- assert_empty_document("\t \t")
73
+ def test_it_rejects_blank_queries
74
+ assert_raises_parse_error("")
75
+ assert_raises_parse_error(" ")
76
+ assert_raises_parse_error("\t \t")
77
+ assert_raises_parse_error(" # comment ")
82
78
  end
83
79
 
84
80
  def test_it_restricts_on
@@ -28,9 +28,9 @@ module GraphQL
28
28
  end
29
29
 
30
30
  obj_field = if base_field
31
- base_field.redefine(**kwargs, &block)
31
+ base_field.redefine(kwargs, &block)
32
32
  else
33
- GraphQL::Field.define(**kwargs, &block)
33
+ GraphQL::Field.define(kwargs, &block)
34
34
  end
35
35
 
36
36
 
@@ -1,12 +1,10 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  module GraphQL
4
3
  module Define
5
4
  # This object delegates most methods to a dictionary of functions, {@dictionary}.
6
5
  # {@target} is passed to the specified function, along with any arguments and block.
7
6
  # This allows a method-based DSL without adding methods to the defined class.
8
7
  class DefinedObjectProxy
9
- extend GraphQL::Ruby2Keywords
10
8
  # The object which will be defined by definition functions
11
9
  attr_reader :target
12
10
 
@@ -34,7 +32,6 @@ module GraphQL
34
32
  end
35
33
 
36
34
  # Lookup a function from the dictionary and call it if it's found.
37
- ruby2_keywords
38
35
  def method_missing(name, *args, &block)
39
36
  definition = @dictionary[name]
40
37
  if definition
@@ -154,12 +154,7 @@ module GraphQL
154
154
  defn_proxy = DefinedObjectProxy.new(self)
155
155
  # Apply definition from `define(...)` kwargs
156
156
  defn.define_keywords.each do |keyword, value|
157
- # Don't splat string hashes, which blows up on Rubies before 2.7
158
- if value.is_a?(Hash) && !value.empty? && value.each_key.all? { |k| k.is_a?(Symbol) }
159
- defn_proxy.public_send(keyword, **value)
160
- else
161
- defn_proxy.public_send(keyword, value)
162
- end
157
+ defn_proxy.public_send(keyword, value)
163
158
  end
164
159
  # and/or apply definition from `define { ... }` block
165
160
  if defn.define_proc
@@ -292,18 +287,12 @@ module GraphQL
292
287
  end
293
288
 
294
289
  class AssignAttribute
295
- extend GraphQL::Ruby2Keywords
296
-
297
290
  def initialize(attr_name)
298
291
  @attr_assign_method = :"#{attr_name}="
299
292
  end
300
293
 
301
- # Even though we're just using the first value here,
302
- # We have to add a splat here to use `ruby2_keywords`,
303
- # so that it will accept a `[{}]` input from the caller.
304
- ruby2_keywords
305
- def call(defn, *value)
306
- defn.public_send(@attr_assign_method, value.first)
294
+ def call(defn, value)
295
+ defn.public_send(@attr_assign_method, value)
307
296
  end
308
297
  end
309
298
  end
@@ -151,6 +151,10 @@ module GraphQL
151
151
  def graphql_name
152
152
  name
153
153
  end
154
+
155
+ def type_class
156
+ metadata[:type_class]
157
+ end
154
158
  end
155
159
 
156
160
  class UnresolvedValueError < GraphQL::Error
@@ -18,12 +18,12 @@ module GraphQL
18
18
  case name
19
19
  when SKIP
20
20
  args = query.arguments_for(directive_ast_node, directive_defn)
21
- if args['if'] == true
21
+ if args[:if] == true
22
22
  return false
23
23
  end
24
24
  when INCLUDE
25
25
  args = query.arguments_for(directive_ast_node, directive_defn)
26
- if args['if'] == false
26
+ if args[:if] == false
27
27
  return false
28
28
  end
29
29
  else
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GraphQL
4
4
  module Execution
5
- # A plugin that wraps query execution with error handling.
5
+ # A tracer that wraps query execution with error handling.
6
6
  # Supports class-based schemas and the new {Interpreter} runtime only.
7
7
  #
8
8
  # @example Handling ActiveRecord::NotFound
@@ -19,35 +19,34 @@ module GraphQL
19
19
  class Errors
20
20
  def self.use(schema)
21
21
  schema_class = schema.is_a?(Class) ? schema : schema.target.class
22
- schema_class.error_handler = self.new(schema_class)
22
+ schema.tracer(self.new(schema_class))
23
23
  end
24
24
 
25
25
  def initialize(schema)
26
26
  @schema = schema
27
27
  end
28
28
 
29
- class NullErrorHandler
30
- def self.with_error_handling(_ctx)
29
+ def trace(event, data)
30
+ case event
31
+ when "execute_field", "execute_field_lazy"
32
+ with_error_handling(data) { yield }
33
+ else
31
34
  yield
32
35
  end
33
36
  end
34
37
 
35
- # Call the given block with the schema's configured error handlers.
36
- #
37
- # If the block returns a lazy value, it's not wrapped with error handling. That area will have to be wrapped itself.
38
- #
39
- # @param ctx [GraphQL::Query::Context]
40
- # @return [Object] Either the result of the given block, or some object to replace the result, in case of error handling.
41
- def with_error_handling(ctx)
38
+ private
39
+
40
+ def with_error_handling(trace_data)
42
41
  yield
43
42
  rescue StandardError => err
44
43
  rescues = @schema.rescues
45
44
  _err_class, handler = rescues.find { |err_class, handler| err.is_a?(err_class) }
46
45
  if handler
47
- runtime_info = ctx.namespace(:interpreter) || {}
48
- obj = runtime_info[:current_object]
49
- args = runtime_info[:current_arguments]
50
- field = runtime_info[:current_field]
46
+ obj = trace_data[:object]
47
+ args = trace_data[:arguments]
48
+ ctx = trace_data[:query].context
49
+ field = trace_data[:field]
51
50
  if obj.is_a?(GraphQL::Schema::Object)
52
51
  obj = obj.object
53
52
  end