graphql 1.9.0.pre4 → 1.9.0

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
  SHA1:
3
- metadata.gz: 1e4a203b440499962202563a6c4c834e14881c5c
4
- data.tar.gz: 76c0395eb02e5bea7652869c9c665df092cd54ac
3
+ metadata.gz: fb79bf185d3d89d53f50ad5f0ae1cc93e3480acb
4
+ data.tar.gz: 46c04d4e296ea2b3b520d6df50f82d76da5ec641
5
5
  SHA512:
6
- metadata.gz: b689670d32855deefb65dacf51f1ea3e37123e5934b2eb8ca43070ad3ee562405f99ce3c420faee173fa77badde9c11089975238c0de1782a5692ebab1319808
7
- data.tar.gz: 3b48af200dccfdd63783f980e8c808f52823c46bb711d1b7f2c63867ae819e1e458e0dc796034ab703d002bac33723a30816b1e2ad17d6536709523b8f07fd03
6
+ metadata.gz: 78e070c3df4abd9e2d649ba0e5f1e7fdcef9b0241572a30bf233d516fa28b7eee9afa0fd2d650db835556dff87f4eddb344aefce8825019569aa7e55ff28f780
7
+ data.tar.gz: eb138cb5d2274c815ea42ec2eff4371cf34023ad817e4009302cb6de6da7deea213ccfaa2169d86a6a8c2b684f9e4fc8bd0780060163a764960d22af1a48bb25
@@ -89,6 +89,7 @@ require "graphql/runtime_type_error"
89
89
  require "graphql/invalid_null_error"
90
90
  require "graphql/invalid_name_error"
91
91
  require "graphql/unresolved_type_error"
92
+ require "graphql/integer_encoding_error"
92
93
  require "graphql/string_encoding_error"
93
94
  require "graphql/query"
94
95
  require "graphql/internal_representation"
@@ -281,20 +281,22 @@ module GraphQL
281
281
  )
282
282
  when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
283
283
  query = field_ctx.query
284
- resolved_type = field_type.resolve_type(value, field_ctx)
285
- possible_types = query.possible_types(field_type)
286
-
287
- if !possible_types.include?(resolved_type)
288
- parent_type = field_ctx.irep_node.owner_type
289
- type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
290
- field_ctx.schema.type_error(type_error, field_ctx)
291
- PROPAGATE_NULL
292
- else
293
- resolve_value(
294
- value,
295
- resolved_type,
296
- field_ctx,
297
- )
284
+ resolved_type_or_lazy = field_type.resolve_type(value, field_ctx)
285
+ query.schema.after_lazy(resolved_type_or_lazy) do |resolved_type|
286
+ possible_types = query.possible_types(field_type)
287
+
288
+ if !possible_types.include?(resolved_type)
289
+ parent_type = field_ctx.irep_node.owner_type
290
+ type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
291
+ field_ctx.schema.type_error(type_error, field_ctx)
292
+ PROPAGATE_NULL
293
+ else
294
+ resolve_value(
295
+ value,
296
+ resolved_type,
297
+ field_ctx,
298
+ )
299
+ end
298
300
  end
299
301
  else
300
302
  raise("Unknown type kind: #{field_type.kind}")
@@ -270,18 +270,20 @@ module GraphQL
270
270
  write_in_response(path, r)
271
271
  r
272
272
  when "UNION", "INTERFACE"
273
- resolved_type = query.resolve_type(type, value)
274
- possible_types = query.possible_types(type)
275
-
276
- if !possible_types.include?(resolved_type)
277
- parent_type = field.owner
278
- type_error = GraphQL::UnresolvedTypeError.new(value, field, parent_type, resolved_type, possible_types)
279
- schema.type_error(type_error, context)
280
- write_in_response(path, nil)
281
- nil
282
- else
283
- resolved_type = resolved_type.metadata[:type_class]
284
- continue_field(path, value, field, resolved_type, ast_node, next_selections, is_non_null)
273
+ resolved_type_or_lazy = query.resolve_type(type, value)
274
+ after_lazy(resolved_type_or_lazy, path: path, field: field) do |resolved_type|
275
+ possible_types = query.possible_types(type)
276
+
277
+ if !possible_types.include?(resolved_type)
278
+ parent_type = field.owner
279
+ type_error = GraphQL::UnresolvedTypeError.new(value, field, parent_type, resolved_type, possible_types)
280
+ schema.type_error(type_error, context)
281
+ write_in_response(path, nil)
282
+ nil
283
+ else
284
+ resolved_type = resolved_type.metadata[:type_class]
285
+ continue_field(path, value, field, resolved_type, ast_node, next_selections, is_non_null)
286
+ end
285
287
  end
286
288
  when "OBJECT"
287
289
  object_proxy = begin
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class IntegerEncodingError < GraphQL::RuntimeTypeError
4
+ # The value which couldn't be encoded
5
+ attr_reader :integer_value
6
+
7
+ def initialize(value)
8
+ @integer_value = value
9
+ super('Integer out of bounds.')
10
+ end
11
+ end
12
+ end
@@ -509,17 +509,20 @@ module GraphQL
509
509
  yield(type, object, ctx)
510
510
  end
511
511
 
512
- if type_result.respond_to?(:graphql_definition)
513
- type_result = type_result.graphql_definition
514
- end
515
-
516
512
  if type_result.nil?
517
513
  nil
518
- elsif !type_result.is_a?(GraphQL::BaseType)
519
- type_str = "#{type_result} (#{type_result.class.name})"
520
- raise "resolve_type(#{object}) returned #{type_str}, but it should return a GraphQL type"
521
514
  else
522
- type_result
515
+ after_lazy(type_result) do |resolved_type_result|
516
+ if resolved_type_result.respond_to?(:graphql_definition)
517
+ resolved_type_result = resolved_type_result.graphql_definition
518
+ end
519
+ if !resolved_type_result.is_a?(GraphQL::BaseType)
520
+ type_str = "#{resolved_type_result} (#{resolved_type_result.class.name})"
521
+ raise "resolve_type(#{object}) returned #{type_str}, but it should return a GraphQL type"
522
+ else
523
+ resolved_type_result
524
+ end
525
+ end
523
526
  end
524
527
  end
525
528
 
@@ -6,7 +6,7 @@ module GraphQL
6
6
  case type_error
7
7
  when GraphQL::InvalidNullError
8
8
  ctx.errors << type_error
9
- when GraphQL::UnresolvedTypeError, GraphQL::StringEncodingError
9
+ when GraphQL::UnresolvedTypeError, GraphQL::StringEncodingError, GraphQL::IntegerEncodingError
10
10
  raise type_error
11
11
  end
12
12
  end
@@ -91,7 +91,7 @@ module GraphQL
91
91
  # For lists with nil, we need another nil check here
92
92
  nil
93
93
  else
94
- concrete_type = case @inner_return_type
94
+ concrete_type_or_lazy = case @inner_return_type
95
95
  when GraphQL::UnionType, GraphQL::InterfaceType
96
96
  ctx.query.resolve_type(@inner_return_type, inner_obj)
97
97
  when GraphQL::ObjectType
@@ -100,12 +100,15 @@ module GraphQL
100
100
  raise "unexpected proxying type #{@inner_return_type} for #{inner_obj} at #{ctx.owner_type}.#{ctx.field.name}"
101
101
  end
102
102
 
103
- if concrete_type && (object_class = concrete_type.metadata[:type_class])
104
- # use the query-level context here, since it won't be field-specific anyways
105
- query_ctx = ctx.query.context
106
- object_class.authorized_new(inner_obj, query_ctx)
107
- else
108
- inner_obj
103
+ # .resolve_type may have returned a lazy
104
+ ctx.schema.after_lazy(concrete_type_or_lazy) do |concrete_type|
105
+ if concrete_type && (object_class = concrete_type.metadata[:type_class])
106
+ # use the query-level context here, since it won't be field-specific anyways
107
+ query_ctx = ctx.query.context
108
+ object_class.authorized_new(inner_obj, query_ctx)
109
+ else
110
+ inner_obj
111
+ end
109
112
  end
110
113
  end
111
114
  end
@@ -200,13 +200,13 @@ module GraphQL
200
200
  # See if any object can be found for this ID
201
201
  loaded_application_object = object_from_id(lookup_as_type, id, context)
202
202
  context.schema.after_lazy(loaded_application_object) do |application_object|
203
- begin
204
- if application_object.nil?
205
- raise LoadApplicationObjectFailedError.new(argument: argument, id: id, object: application_object)
206
- end
207
- # Double-check that the located object is actually of this type
208
- # (Don't want to allow arbitrary access to objects this way)
209
- application_object_type = context.schema.resolve_type(lookup_as_type, application_object, context)
203
+ if application_object.nil?
204
+ raise LoadApplicationObjectFailedError.new(argument: argument, id: id, object: application_object)
205
+ end
206
+ # Double-check that the located object is actually of this type
207
+ # (Don't want to allow arbitrary access to objects this way)
208
+ resolved_application_object_type = context.schema.resolve_type(lookup_as_type, application_object, context)
209
+ context.schema.after_lazy(resolved_application_object_type) do |application_object_type|
210
210
  possible_object_types = context.schema.possible_types(lookup_as_type)
211
211
  if !possible_object_types.include?(application_object_type)
212
212
  raise LoadApplicationObjectFailedError.new(argument: argument, id: id, object: application_object)
@@ -230,11 +230,11 @@ module GraphQL
230
230
  application_object
231
231
  end
232
232
  end
233
- rescue LoadApplicationObjectFailedError => err
234
- # pass it to a handler
235
- load_application_object_failed(err)
236
233
  end
237
234
  end
235
+ rescue LoadApplicationObjectFailedError => err
236
+ # pass it to a handler
237
+ load_application_object_failed(err)
238
238
  end
239
239
 
240
240
  def load_application_object_failed(err)
@@ -27,7 +27,7 @@ module GraphQL
27
27
  # tracer MyTracer # <= responds to .trace(key, data, &block)
28
28
  # end
29
29
  #
30
- # @example Adding a tracer to a query
30
+ # @example Adding a tracer to a single query
31
31
  # MySchema.execute(query_str, context: { backtrace: true })
32
32
  #
33
33
  # Events:
@@ -45,6 +45,11 @@ module GraphQL
45
45
  # execute_field | `{ context: GraphQL::Query::Context::FieldResolutionContext?, field: GraphQL::Schema::Field?, path: Array<String, Integer>?}`
46
46
  # execute_field_lazy | `{ context: GraphQL::Query::Context::FieldResolutionContext?, field: GraphQL::Schema::Field?, path: Array<String, Integer>?}`
47
47
  #
48
+ # Note that `execute_field` and `execute_field_lazy` receive different data in different settings:
49
+ #
50
+ # - When using {GraphQL::Execution::Interpreter}, they receive `{field:, path:}`
51
+ # - Otherwise, they receive `{context: ...}`
52
+ #
48
53
  module Tracing
49
54
  # Objects may include traceable to gain a `.trace(...)` method.
50
55
  # The object must have a `@tracers` ivar of type `Array<<#trace(k, d, &b)>>`.
@@ -3,7 +3,7 @@
3
3
  module GraphQL
4
4
  module Types
5
5
  class Float < GraphQL::Schema::Scalar
6
- description "Represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)."
6
+ description "Represents signed double-precision fractional values as specified by [IEEE 754](https://en.wikipedia.org/wiki/IEEE_floating_point)."
7
7
 
8
8
  def self.coerce_input(value, _ctx)
9
9
  value.is_a?(Numeric) ? value.to_f : nil
@@ -5,12 +5,21 @@ module GraphQL
5
5
  class Int < GraphQL::Schema::Scalar
6
6
  description "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
7
7
 
8
+ MIN = -(2**31)
9
+ MAX = (2**31) - 1
10
+
8
11
  def self.coerce_input(value, _ctx)
9
12
  value.is_a?(Numeric) ? value.to_i : nil
10
13
  end
11
14
 
12
- def self.coerce_result(value, _ctx)
13
- value.to_i
15
+ def self.coerce_result(value, ctx)
16
+ value = value.to_i
17
+ if value >= MIN && value <= MAX
18
+ value
19
+ else
20
+ err = GraphQL::IntegerEncodingError.new(value)
21
+ ctx.schema.type_error(err, ctx)
22
+ end
14
23
  end
15
24
 
16
25
  default_scalar true
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.9.0.pre4"
3
+ VERSION = "1.9.0"
4
4
  end
data/readme.md CHANGED
@@ -4,12 +4,12 @@
4
4
  [![Gem Version](https://badge.fury.io/rb/graphql.svg)](https://rubygems.org/gems/graphql)
5
5
  [![Code Climate](https://codeclimate.com/github/rmosolgo/graphql-ruby/badges/gpa.svg)](https://codeclimate.com/github/rmosolgo/graphql-ruby)
6
6
  [![Test Coverage](https://codeclimate.com/github/rmosolgo/graphql-ruby/badges/coverage.svg)](https://codeclimate.com/github/rmosolgo/graphql-ruby)
7
- [![built with love](https://cloud.githubusercontent.com/assets/2231765/6766607/d07992c6-cfc9-11e4-813f-d9240714dd50.png)](http://rmosolgo.github.io/react-badges/)
7
+ [![built with love](https://cloud.githubusercontent.com/assets/2231765/6766607/d07992c6-cfc9-11e4-813f-d9240714dd50.png)](https://rmosolgo.github.io/react-badges/)
8
8
 
9
- A Ruby implementation of [GraphQL](http://graphql.org/).
9
+ A Ruby implementation of [GraphQL](https://graphql.org/).
10
10
 
11
- - [Website](https://rmosolgo.github.io/graphql-ruby)
12
- - [API Documentation](http://www.rubydoc.info/gems/graphql)
11
+ - [Website](https://graphql-ruby.org/)
12
+ - [API Documentation](https://www.rubydoc.info/gems/graphql)
13
13
  - [Newsletter](https://tinyletter.com/graphql-ruby)
14
14
 
15
15
  ## Installation
@@ -33,11 +33,11 @@ $ rails generate graphql:install
33
33
 
34
34
  After this, you may need to run `bundle install` again, as by default graphiql-rails is added on installation.
35
35
 
36
- Or, see ["Getting Started"](https://rmosolgo.github.io/graphql-ruby/).
36
+ Or, see ["Getting Started"](https://graphql-ruby.org/).
37
37
 
38
38
  ## Upgrade
39
39
 
40
- I also sell [GraphQL::Pro](http://graphql.pro) which provides several features on top of the GraphQL runtime, including [Pundit authorization](http://rmosolgo.github.io/graphql-ruby/authorization/pundit_integration), [CanCan authorization](http://rmosolgo.github.io/graphql-ruby/authorization/can_can_integration), [Pusher-based subscriptions](http://graphql-ruby.org/subscriptions/pusher_implementation) and [persisted queries](http://rmosolgo.github.io/graphql-ruby/operation_store/overview). Besides that, Pro customers get email support and an opportunity to support graphql-ruby's development!
40
+ I also sell [GraphQL::Pro](https://graphql.pro) which provides several features on top of the GraphQL runtime, including [Pundit authorization](https://graphql-ruby.org/authorization/pundit_integration), [CanCan authorization](https://graphql-ruby.org/authorization/can_can_integration), [Pusher-based subscriptions](https://graphql-ruby.org/subscriptions/pusher_implementation) and [persisted queries](https://graphql-ruby.org/operation_store/overview). Besides that, Pro customers get email support and an opportunity to support graphql-ruby's development!
41
41
 
42
42
  ## Goals
43
43
 
@@ -49,4 +49,4 @@ I also sell [GraphQL::Pro](http://graphql.pro) which provides several features o
49
49
 
50
50
  - __Say hi & ask questions__ in the [#ruby channel on Slack](https://graphql-slack.herokuapp.com/) or [on Twitter](https://twitter.com/rmosolgo)!
51
51
  - __Report bugs__ by posting a description, full stack trace, and all relevant code in a [GitHub issue](https://github.com/rmosolgo/graphql-ruby/issues).
52
- - __Start hacking__ with the [Development guide](http://graphql-ruby.org/development).
52
+ - __Start hacking__ with the [Development guide](https://graphql-ruby.org/development).
@@ -27,7 +27,7 @@
27
27
  # 'true': 'foo'
28
28
  #
29
29
  # To learn more, please read the Rails Internationalization guide
30
- # available at http://guides.rubyonrails.org/i18n.html.
30
+ # available at https://guides.rubyonrails.org/i18n.html.
31
31
 
32
32
  en:
33
33
  hello: "Hello world"
@@ -12,5 +12,24 @@ describe GraphQL::INT_TYPE do
12
12
  assert_nil GraphQL::INT_TYPE.coerce_isolated_input("55")
13
13
  assert_nil GraphQL::INT_TYPE.coerce_isolated_input(true)
14
14
  end
15
+
16
+ describe "handling boundaries" do
17
+ let(:context) { GraphQL::Query.new(Dummy::Schema, "{ __typename }").context }
18
+
19
+ it "accepts result values in bounds" do
20
+ assert_equal 0, GraphQL::INT_TYPE.coerce_result(0, context)
21
+ assert_equal (2**31) - 1, GraphQL::INT_TYPE.coerce_result((2**31) - 1, context)
22
+ assert_equal -(2**31), GraphQL::INT_TYPE.coerce_result(-(2**31), context)
23
+ end
24
+
25
+ it "replaces values, if configured to do so" do
26
+ assert_equal Dummy::Schema::MAGIC_INT_COERCE_VALUE, GraphQL::INT_TYPE.coerce_result(99**99, context)
27
+ end
28
+
29
+ it "raises on values out of bounds" do
30
+ assert_raises(GraphQL::IntegerEncodingError) { GraphQL::INT_TYPE.coerce_result(2**31, context) }
31
+ assert_raises(GraphQL::IntegerEncodingError) { GraphQL::INT_TYPE.coerce_result(-(2**31 + 1), context) }
32
+ end
33
+ end
15
34
  end
16
35
  end
@@ -433,7 +433,7 @@ describe GraphQL::Language::DocumentFromSchemaDefinition do
433
433
  }
434
434
 
435
435
  # Represents signed double-precision fractional values as specified by [IEEE
436
- # 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
436
+ # 754](https://en.wikipedia.org/wiki/IEEE_floating_point).
437
437
  scalar Float
438
438
 
439
439
  # Represents a unique identifier that is Base64 obfuscated. It is often used to
@@ -698,7 +698,7 @@ describe GraphQL::Language::DocumentFromSchemaDefinition do
698
698
  }
699
699
 
700
700
  # Represents signed double-precision fractional values as specified by [IEEE
701
- # 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
701
+ # 754](https://en.wikipedia.org/wiki/IEEE_floating_point).
702
702
  scalar Float
703
703
 
704
704
  # Represents a unique identifier that is Base64 obfuscated. It is often used to
@@ -473,6 +473,18 @@ module Dummy
473
473
  def self.resolve_type(type, obj, ctx)
474
474
  Schema.types[obj.class.name.split("::").last]
475
475
  end
476
+
477
+ # This is used to confirm that the hook is called:
478
+ MAGIC_INT_COERCE_VALUE = -1
479
+
480
+ def self.type_error(err, ctx)
481
+ if err.is_a?(GraphQL::IntegerEncodingError) && err.integer_value == 99**99
482
+ MAGIC_INT_COERCE_VALUE
483
+ else
484
+ super
485
+ end
486
+ end
487
+
476
488
  if TESTING_INTERPRETER
477
489
  use GraphQL::Execution::Interpreter
478
490
  end
@@ -320,10 +320,12 @@ module Jazz
320
320
  possible_types Musician, Ensemble
321
321
 
322
322
  def self.resolve_type(object, context)
323
- if object.is_a?(Models::Ensemble)
324
- Ensemble
325
- else
326
- Musician
323
+ GraphQL::Execution::Lazy.new do
324
+ if object.is_a?(Models::Ensemble)
325
+ Ensemble
326
+ else
327
+ Musician
328
+ end
327
329
  end
328
330
  end
329
331
  end
@@ -352,7 +354,7 @@ module Jazz
352
354
  def now_playing; Models.data["Ensemble"].first; end
353
355
 
354
356
  # For asserting that the object is initialized once:
355
- field :object_id, Integer, null: false
357
+ field :object_id, String, null: false
356
358
  field :inspect_context, [String], null: false
357
359
  field :hashyEnsemble, Ensemble, null: false
358
360
 
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.9.0.pre4
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-11 00:00:00.000000000 Z
11
+ date: 2019-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -437,6 +437,7 @@ files:
437
437
  - lib/graphql/id_type.rb
438
438
  - lib/graphql/input_object_type.rb
439
439
  - lib/graphql/int_type.rb
440
+ - lib/graphql/integer_encoding_error.rb
440
441
  - lib/graphql/interface_type.rb
441
442
  - lib/graphql/internal_representation.rb
442
443
  - lib/graphql/internal_representation/document.rb
@@ -986,7 +987,7 @@ files:
986
987
  - spec/support/skylight.rb
987
988
  - spec/support/star_wars/schema.rb
988
989
  - spec/support/static_validation_helpers.rb
989
- homepage: http://github.com/rmosolgo/graphql-ruby
990
+ homepage: https://github.com/rmosolgo/graphql-ruby
990
991
  licenses:
991
992
  - MIT
992
993
  metadata: {}
@@ -1001,9 +1002,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
1001
1002
  version: 2.2.0
1002
1003
  required_rubygems_version: !ruby/object:Gem::Requirement
1003
1004
  requirements:
1004
- - - ">"
1005
+ - - ">="
1005
1006
  - !ruby/object:Gem::Version
1006
- version: 1.3.1
1007
+ version: '0'
1007
1008
  requirements: []
1008
1009
  rubyforge_project:
1009
1010
  rubygems_version: 2.6.13