graphql 1.13.5 → 1.13.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 532fad107d6e2086bf07c1501a5a14aff55bb7dbafb5d6813a2fb902ac9eb1ff
4
- data.tar.gz: 87e0d968351c5e6bf74d0036cfcb87ec0114d575d632794f1b71f2c40e44e4af
3
+ metadata.gz: d4cb09369d39b11ac4ebb242db3da4bc008a850cdd78c88816143cdfd84addd9
4
+ data.tar.gz: 4c5fc1be26724efda2dfc4e0f6ae0ad0ff9593b8708cf38ce3ec3a2ffae759d7
5
5
  SHA512:
6
- metadata.gz: 4721a304fde79ad452e4d6c265841c04c300f34c23c727d374bb584d289277c6352dad5b572d1acc7b79311040b84c49f67a5ab2c34749a27dd366f2fdae3bb3
7
- data.tar.gz: c773bcd7603ab6c665e0058fe9852fa241f91db068fa7b1cdb382ddf36e90ffeb4134891ccb37786c60b95e5efb6dc259338aeecb70138fb74122c49277711bd
6
+ metadata.gz: ea28714d8d623e7591325672a08d031f03877f3744fdc18554ac0be2f2e3149dc2f99ee209f3b91d2d3f82564617d71eee5675a32ea1f60d0d75cc7cdffcf1b3
7
+ data.tar.gz: 492bd5f0312bb01a79175fdf87388e2ffd51a3bbe2d8a485a78e30f89634fd1a5ec28fbb1626ea775b38cd1984a3abfa2cc7ba58bd6189165fc91f923a668e30
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ # This error is raised when `Types::ISO8601Date` is asked to return a value
4
+ # that cannot be parsed to a Ruby Date.
5
+ #
6
+ # @see GraphQL::Types::ISO8601Date which raises this error
7
+ class DateEncodingError < GraphQL::RuntimeTypeError
8
+ # The value which couldn't be encoded
9
+ attr_reader :date_value
10
+
11
+ def initialize(value)
12
+ @date_value = value
13
+ super("Date cannot be parsed: #{value}. \nDate must be be able to be parsed as a Ruby Date object.")
14
+ end
15
+ end
16
+ end
@@ -207,7 +207,7 @@ module GraphQL
207
207
  # Root .authorized? returned false.
208
208
  @response = nil
209
209
  else
210
- resolve_with_directives(object_proxy, root_operation.directives) do # execute query level directives
210
+ call_method_on_directives(:resolve, object_proxy, root_operation.directives) do # execute query level directives
211
211
  gathered_selections = gather_selections(object_proxy, root_type, root_operation.selections)
212
212
  # This is kind of a hack -- `gathered_selections` is an Array if any of the selections
213
213
  # require isolation during execution (because of runtime directives). In that case,
@@ -227,7 +227,7 @@ module GraphQL
227
227
 
228
228
  @dataloader.append_job {
229
229
  set_all_interpreter_context(query.root_value, nil, nil, path)
230
- resolve_with_directives(object_proxy, selections.graphql_directives) do
230
+ call_method_on_directives(:resolve, object_proxy, selections.graphql_directives) do
231
231
  evaluate_selections(
232
232
  path,
233
233
  context.scoped_context,
@@ -503,7 +503,7 @@ module GraphQL
503
503
  }
504
504
  end
505
505
 
506
- field_result = resolve_with_directives(object, directives) do
506
+ field_result = call_method_on_directives(:resolve, object, directives) do
507
507
  # Actually call the field resolver and capture the result
508
508
  app_result = begin
509
509
  query.with_error_handling do
@@ -735,7 +735,7 @@ module GraphQL
735
735
  final_result = nil
736
736
  end
737
737
  set_all_interpreter_context(continue_value, nil, nil, path) # reset this mutable state
738
- resolve_with_directives(continue_value, selections.graphql_directives) do
738
+ call_method_on_directives(:resolve, continue_value, selections.graphql_directives) do
739
739
  evaluate_selections(
740
740
  path,
741
741
  context.scoped_context,
@@ -754,6 +754,8 @@ module GraphQL
754
754
  end
755
755
  when "LIST"
756
756
  inner_type = current_type.of_type
757
+ # This is true for objects, unions, and interfaces
758
+ use_dataloader_job = !inner_type.unwrap.kind.input?
757
759
  response_list = GraphQLResultArray.new(result_name, selection_result)
758
760
  response_list.graphql_non_null_list_items = inner_type.non_null?
759
761
  set_result(selection_result, result_name, response_list)
@@ -768,12 +770,12 @@ module GraphQL
768
770
  this_idx = idx
769
771
  next_path.freeze
770
772
  idx += 1
771
- # This will update `response_list` with the lazy
772
- after_lazy(inner_value, owner: inner_type, path: next_path, ast_node: ast_node, scoped_context: scoped_context, field: field, owner_object: owner_object, arguments: arguments, result_name: this_idx, result: response_list) do |inner_inner_value|
773
- continue_value = continue_value(next_path, inner_inner_value, owner_type, field, inner_type.non_null?, ast_node, this_idx, response_list)
774
- if HALT != continue_value
775
- continue_field(next_path, continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list)
773
+ if use_dataloader_job
774
+ @dataloader.append_job do
775
+ resolve_list_item(inner_value, inner_type, next_path, ast_node, scoped_context, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
776
776
  end
777
+ else
778
+ resolve_list_item(inner_value, inner_type, next_path, ast_node, scoped_context, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type)
777
779
  end
778
780
  end
779
781
  rescue NoMethodError => err
@@ -793,12 +795,25 @@ module GraphQL
793
795
  end
794
796
  end
795
797
 
796
- def resolve_with_directives(object, directives, &block)
798
+ def resolve_list_item(inner_value, inner_type, next_path, ast_node, scoped_context, field, owner_object, arguments, this_idx, response_list, next_selections, owner_type) # rubocop:disable Metrics/ParameterLists
799
+ set_all_interpreter_context(nil, nil, nil, next_path)
800
+ call_method_on_directives(:resolve_each, owner_object, ast_node.directives) do
801
+ # This will update `response_list` with the lazy
802
+ after_lazy(inner_value, owner: inner_type, path: next_path, ast_node: ast_node, scoped_context: scoped_context, field: field, owner_object: owner_object, arguments: arguments, result_name: this_idx, result: response_list) do |inner_inner_value|
803
+ continue_value = continue_value(next_path, inner_inner_value, owner_type, field, inner_type.non_null?, ast_node, this_idx, response_list)
804
+ if HALT != continue_value
805
+ continue_field(next_path, continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list)
806
+ end
807
+ end
808
+ end
809
+ end
810
+
811
+ def call_method_on_directives(method_name, object, directives, &block)
797
812
  return yield if directives.nil? || directives.empty?
798
- run_directive(object, directives, 0, &block)
813
+ run_directive(method_name, object, directives, 0, &block)
799
814
  end
800
815
 
801
- def run_directive(object, directives, idx, &block)
816
+ def run_directive(method_name, object, directives, idx, &block)
802
817
  dir_node = directives[idx]
803
818
  if !dir_node
804
819
  yield
@@ -822,8 +837,8 @@ module GraphQL
822
837
  if dir_args == HALT
823
838
  nil
824
839
  else
825
- dir_defn.resolve(object, dir_args, context) do
826
- run_directive(object, directives, idx + 1, &block)
840
+ dir_defn.public_send(method_name, object, dir_args, context) do
841
+ run_directive(method_name, object, directives, idx + 1, &block)
827
842
  end
828
843
  end
829
844
  end
@@ -6,8 +6,8 @@ module GraphQL
6
6
  description "A Directive can be adjacent to many parts of the GraphQL language, "\
7
7
  "a __DirectiveLocation describes one such possible adjacencies."
8
8
 
9
- GraphQL::Directive::LOCATIONS.each do |location|
10
- value(location.to_s, GraphQL::Directive::LOCATION_DESCRIPTIONS[location], value: location)
9
+ GraphQL::Schema::Directive::LOCATIONS.each do |location|
10
+ value(location.to_s, GraphQL::Schema::Directive::LOCATION_DESCRIPTIONS[location], value: location)
11
11
  end
12
12
  introspection true
13
13
  end
@@ -19,6 +19,8 @@ module GraphQL
19
19
  field :on_fragment, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_fragment?
20
20
  field :on_field, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_field?
21
21
 
22
+ field :is_repeatable, Boolean, method: :repeatable?
23
+
22
24
  def args(include_deprecated:)
23
25
  args = @context.warden.arguments(@object)
24
26
  args = args.reject(&:deprecation_reason) unless include_deprecated
@@ -13,6 +13,11 @@ module GraphQL
13
13
  field :mutation_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server supports mutation, the type that mutation operations will be rooted at."
14
14
  field :subscription_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server support subscription, the type that subscription operations will be rooted at."
15
15
  field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false
16
+ field :description, String, resolver_method: :schema_description
17
+
18
+ def schema_description
19
+ context.schema.description
20
+ end
16
21
 
17
22
  def types
18
23
  @context.warden.reachable_types.sort_by(&:graphql_name)
@@ -12,7 +12,7 @@ module GraphQL
12
12
  "possible at runtime. List and NonNull types compose other types."
13
13
 
14
14
  field :kind, GraphQL::Schema::LateBoundType.new("__TypeKind"), null: false
15
- field :name, String
15
+ field :name, String, method: :graphql_name
16
16
  field :description, String
17
17
  field :fields, [GraphQL::Schema::LateBoundType.new("__Field")] do
18
18
  argument :include_deprecated, Boolean, required: false, default_value: false
@@ -27,8 +27,14 @@ module GraphQL
27
27
  end
28
28
  field :of_type, GraphQL::Schema::LateBoundType.new("__Type")
29
29
 
30
- def name
31
- object.graphql_name
30
+ field :specified_by_url, String
31
+
32
+ def specified_by_url
33
+ if object.kind.scalar?
34
+ object.specified_by_url
35
+ else
36
+ nil
37
+ end
32
38
  end
33
39
 
34
40
  def kind
@@ -7,6 +7,7 @@ module GraphQL
7
7
  <<-QUERY
8
8
  query IntrospectionQuery {
9
9
  __schema {
10
+ description
10
11
  queryType { name }
11
12
  mutationType { name }
12
13
  subscriptionType { name }
@@ -17,6 +18,7 @@ query IntrospectionQuery {
17
18
  name
18
19
  description
19
20
  locations
21
+ isRepeatable
20
22
  args#{include_deprecated_args ? '(includeDeprecated: true)' : ''} {
21
23
  ...InputValue
22
24
  }
@@ -27,6 +29,7 @@ fragment FullType on __Type {
27
29
  kind
28
30
  name
29
31
  description
32
+ specifiedByUrl
30
33
  fields(includeDeprecated: true) {
31
34
  name
32
35
  description
@@ -47,7 +47,7 @@ module GraphQL
47
47
  def cursor_for(item)
48
48
  load_nodes
49
49
  # index in nodes + existing offset + 1 (because it's offset, not index)
50
- offset = nodes.index(item) + 1 + (@paged_nodes_offset || 0) + (relation_offset(items) || 0)
50
+ offset = nodes.index(item) + 1 + (@paged_nodes_offset || 0) - (relation_offset(items) || 0)
51
51
  encode(offset.to_s)
52
52
  end
53
53
 
@@ -116,9 +116,9 @@ module GraphQL
116
116
  if defined?(@sliced_nodes_limit)
117
117
  return
118
118
  else
119
+ next_offset = relation_offset(items) || 0
119
120
  if after_offset
120
- previous_offset = relation_offset(items) || 0
121
- relation_offset = previous_offset + after_offset
121
+ next_offset += after_offset
122
122
  end
123
123
 
124
124
  if before_offset && after_offset
@@ -136,7 +136,7 @@ module GraphQL
136
136
  end
137
137
 
138
138
  @sliced_nodes_limit = relation_limit
139
- @sliced_nodes_offset = relation_offset || 0
139
+ @sliced_nodes_offset = next_offset
140
140
  end
141
141
  end
142
142
 
@@ -90,6 +90,11 @@ module GraphQL
90
90
  yield
91
91
  end
92
92
 
93
+ # Continuing is passed as a block, yield to continue.
94
+ def resolve_each(object, arguments, context)
95
+ yield
96
+ end
97
+
93
98
  def on_field?
94
99
  locations.include?(FIELD)
95
100
  end
@@ -147,6 +152,7 @@ module GraphQL
147
152
  ENUM_VALUE = :ENUM_VALUE,
148
153
  INPUT_OBJECT = :INPUT_OBJECT,
149
154
  INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
155
+ VARIABLE_DEFINITION = :VARIABLE_DEFINITION,
150
156
  ]
151
157
 
152
158
  DEFAULT_DEPRECATION_REASON = 'No longer supported'
@@ -169,6 +175,7 @@ module GraphQL
169
175
  ENUM_VALUE: 'Location adjacent to an enum value definition.',
170
176
  INPUT_OBJECT: 'Location adjacent to an input object type definition.',
171
177
  INPUT_FIELD_DEFINITION: 'Location adjacent to an input object field definition.',
178
+ VARIABLE_DEFINITION: 'Location adjacent to a variable definition.',
172
179
  }
173
180
 
174
181
  private
@@ -34,6 +34,7 @@ module GraphQL
34
34
  Class.new(GraphQL::Schema) do
35
35
  orphan_types(types.values)
36
36
  directives(directives)
37
+ description(schema["description"])
37
38
 
38
39
  def self.resolve_type(*)
39
40
  raise(GraphQL::RequiredImplementationMissingError, "This schema was loaded from string, so it can't resolve types for objects")
@@ -141,6 +142,7 @@ module GraphQL
141
142
  Class.new(GraphQL::Schema::Scalar) do
142
143
  graphql_name(type["name"])
143
144
  description(type["description"])
145
+ specified_by_url(type["specifiedByUrl"])
144
146
  end
145
147
  end
146
148
  when "UNION"
@@ -160,6 +162,7 @@ module GraphQL
160
162
  graphql_name(directive["name"])
161
163
  description(directive["description"])
162
164
  locations(*directive["locations"].map(&:to_sym))
165
+ repeatable(directive["isRepeatable"])
163
166
  loader.build_arguments(self, directive["args"], type_resolver)
164
167
  end
165
168
  end
@@ -32,6 +32,18 @@ module GraphQL
32
32
  GraphQL::TypeKinds::SCALAR
33
33
  end
34
34
 
35
+ def specified_by_url(new_url = nil)
36
+ if new_url
37
+ @specified_by_url = new_url
38
+ elsif defined?(@specified_by_url)
39
+ @specified_by_url
40
+ elsif superclass.respond_to?(:specified_by_url)
41
+ superclass.specified_by_url
42
+ else
43
+ nil
44
+ end
45
+ end
46
+
35
47
  def default_scalar(is_default = nil)
36
48
  if !is_default.nil?
37
49
  @default_scalar = is_default
@@ -892,6 +892,17 @@ module GraphQL
892
892
  GraphQL::Language::DocumentFromSchemaDefinition.new(self).document
893
893
  end
894
894
 
895
+ # @return [String, nil]
896
+ def description(new_description = nil)
897
+ if new_description
898
+ @description = new_description
899
+ elsif defined?(@description)
900
+ @description
901
+ else
902
+ find_inherited_value(:description, nil)
903
+ end
904
+ end
905
+
895
906
  def find(path)
896
907
  if !@finder
897
908
  @find_cache = {}
@@ -21,13 +21,21 @@ module GraphQL
21
21
  Date.parse(value.to_s).iso8601
22
22
  end
23
23
 
24
- # @param str_value [String]
24
+ # @param str_value [String, Date, DateTime, Time]
25
25
  # @return [Date]
26
- def self.coerce_input(str_value, _ctx)
27
- Date.iso8601(str_value)
26
+ def self.coerce_input(value, ctx)
27
+ if value.is_a?(::Date)
28
+ value
29
+ elsif value.is_a?(::DateTime)
30
+ value.to_date
31
+ elsif value.is_a?(::Time)
32
+ value.to_date
33
+ else
34
+ Date.iso8601(value)
35
+ end
28
36
  rescue ArgumentError, TypeError
29
- # Invalid input
30
- nil
37
+ err = GraphQL::DateEncodingError.new(value)
38
+ ctx.schema.type_error(err, ctx)
31
39
  end
32
40
  end
33
41
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.13.5"
3
+ VERSION = "1.13.6"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -69,6 +69,7 @@ require "graphql/invalid_name_error"
69
69
  require "graphql/integer_decoding_error"
70
70
  require "graphql/integer_encoding_error"
71
71
  require "graphql/string_encoding_error"
72
+ require "graphql/date_encoding_error"
72
73
 
73
74
  require "graphql/define"
74
75
  require "graphql/base_type"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.5
4
+ version: 1.13.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-13 00:00:00.000000000 Z
11
+ date: 2022-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -323,6 +323,7 @@ files:
323
323
  - lib/graphql/dataloader/request.rb
324
324
  - lib/graphql/dataloader/request_all.rb
325
325
  - lib/graphql/dataloader/source.rb
326
+ - lib/graphql/date_encoding_error.rb
326
327
  - lib/graphql/define.rb
327
328
  - lib/graphql/define/assign_argument.rb
328
329
  - lib/graphql/define/assign_connection.rb
@@ -695,7 +696,7 @@ metadata:
695
696
  source_code_uri: https://github.com/rmosolgo/graphql-ruby
696
697
  bug_tracker_uri: https://github.com/rmosolgo/graphql-ruby/issues
697
698
  mailing_list_uri: https://tinyletter.com/graphql-ruby
698
- post_install_message:
699
+ post_install_message:
699
700
  rdoc_options: []
700
701
  require_paths:
701
702
  - lib
@@ -710,8 +711,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
710
711
  - !ruby/object:Gem::Version
711
712
  version: '0'
712
713
  requirements: []
713
- rubygems_version: 3.3.3
714
- signing_key:
714
+ rubygems_version: 3.1.6
715
+ signing_key:
715
716
  specification_version: 4
716
717
  summary: A GraphQL language and runtime for Ruby
717
718
  test_files: []