graphql 1.9.0.pre4 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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