graphql 0.4.0 → 0.5.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/argument.rb +38 -4
  3. data/lib/graph_ql/boolean_type.rb +3 -5
  4. data/lib/graph_ql/definition_helpers.rb +1 -0
  5. data/lib/graph_ql/definition_helpers/defined_by_config.rb +20 -0
  6. data/lib/graph_ql/enum_type.rb +52 -16
  7. data/lib/graph_ql/field.rb +79 -14
  8. data/lib/graph_ql/float_type.rb +3 -3
  9. data/lib/graph_ql/id_type.rb +3 -5
  10. data/lib/graph_ql/input_object_type.rb +41 -4
  11. data/lib/graph_ql/int_type.rb +3 -5
  12. data/lib/graph_ql/interface_type.rb +36 -8
  13. data/lib/graph_ql/introspection/arguments_field.rb +4 -4
  14. data/lib/graph_ql/introspection/directive_type.rb +9 -11
  15. data/lib/graph_ql/introspection/enum_value_type.rb +9 -12
  16. data/lib/graph_ql/introspection/enum_values_field.rb +6 -8
  17. data/lib/graph_ql/introspection/field_type.rb +11 -15
  18. data/lib/graph_ql/introspection/fields_field.rb +5 -7
  19. data/lib/graph_ql/introspection/input_fields_field.rb +5 -5
  20. data/lib/graph_ql/introspection/input_value_type.rb +7 -9
  21. data/lib/graph_ql/introspection/interfaces_field.rb +4 -4
  22. data/lib/graph_ql/introspection/of_type_field.rb +5 -5
  23. data/lib/graph_ql/introspection/possible_types_field.rb +4 -4
  24. data/lib/graph_ql/introspection/schema_field.rb +6 -8
  25. data/lib/graph_ql/introspection/schema_type.rb +19 -25
  26. data/lib/graph_ql/introspection/type_by_name_field.rb +7 -1
  27. data/lib/graph_ql/introspection/type_kind_enum.rb +4 -4
  28. data/lib/graph_ql/introspection/type_type.rb +18 -18
  29. data/lib/graph_ql/introspection/typename_field.rb +6 -10
  30. data/lib/graph_ql/object_type.rb +87 -12
  31. data/lib/graph_ql/scalar_type.rb +22 -0
  32. data/lib/graph_ql/schema.rb +1 -1
  33. data/lib/graph_ql/string_type.rb +3 -5
  34. data/lib/graph_ql/union_type.rb +24 -3
  35. data/lib/graph_ql/version.rb +1 -1
  36. data/lib/graphql.rb +1 -1
  37. data/readme.md +66 -64
  38. data/spec/graph_ql/field_spec.rb +3 -3
  39. data/spec/support/dairy_app.rb +119 -133
  40. data/spec/support/dairy_data.rb +1 -1
  41. data/spec/support/star_wars_schema.rb +50 -57
  42. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a35f790dd696036b5c7ea909517a2108891d2732
4
- data.tar.gz: 795e06d90a94be917cf6ffaf911d00e5c14faade
3
+ metadata.gz: 9a73d6da0ba5269a9b68a0bdd479058ac4b65783
4
+ data.tar.gz: fb49181fff74d8a45fa7ac2d6ef941ce9a20eedd
5
5
  SHA512:
6
- metadata.gz: e62e25e0fedcbb6509d55d8f539f766d82429bafa3d278dde5fa3ca45420bc2a6cbbc3262b465a6f936ec76fcbb8296f4c7977cb8fdfd4581b818503570be372
7
- data.tar.gz: e863e0d3699bb9233f96da31af72e42422cc18c0f1765f2446851f65e76c67a7c16bcd1862b863e048aced999fca335c0a7d1c6dfbbefb3a0981499c74bfa84a
6
+ metadata.gz: 7fc070deec02d1ad30a5f6807692010920a0ee69395205a1cf11f1dd98ec3ebb1ea55ca228c60e5165d03644cdf38a8a1649c9025e00d46cdb72e715acd2e586
7
+ data.tar.gz: b22f2cbe6338c2d30f1a6b1ca6d772d49d6ba396370f519b473105c61ae512e5605e891ca1f53936f8f41d08d49e4e8d1615f759cc34ebb646a22ad20cc0d755
@@ -1,10 +1,44 @@
1
1
  # Used for defined arguments ({Field}, {InputObjectType})
2
2
  #
3
- # Created by {ArgumentDefiner}
3
+ # @example defining an argument for a field
4
+ # GraphQL::Field.define do
5
+ # # ...
6
+ # argument :favoriteFood, types.String, "Favorite thing to eat", default_value: "pizza"
7
+ # end
8
+ #
9
+ # @example defining an input field for an {InputObjectType}
10
+ # GraphQL::InputObjectType.define do
11
+ # input_field :newName, !types.String
12
+ # end
13
+ #
4
14
  class GraphQL::Argument
5
- attr_reader :type, :description, :default_value
6
- attr_accessor :name
7
- def initialize(type:, description: nil, default_value: nil, name: nil)
15
+ attr_accessor :name, :type, :description, :default_value
16
+
17
+ include GraphQL::DefinitionHelpers::DefinedByConfig
18
+
19
+ # This object is `self` when you're defining arguments with a block.
20
+ # @example `argument` helper's `self` is a DefinitionConfig
21
+ #
22
+ # argument :name do
23
+ # puts self.class.name
24
+ # end
25
+ # # => GraphQL::Argument::DefinitionConfig
26
+ #
27
+ class DefinitionConfig
28
+ extend GraphQL::DefinitionHelpers::Definable
29
+ attr_definable :type, :description, :default_value, :name
30
+
31
+ def to_instance
32
+ GraphQL::Argument.new(
33
+ type: type,
34
+ description: description,
35
+ default_value: default_value,
36
+ name: name,
37
+ )
38
+ end
39
+ end
40
+
41
+ def initialize(type: nil, description: nil, default_value: nil, name: nil)
8
42
  @type = type
9
43
  @description = description,
10
44
  @default_value = default_value
@@ -1,6 +1,4 @@
1
- GraphQL::BOOLEAN_TYPE = GraphQL::ScalarType.new do |t|
2
- t.name "Boolean"
3
- def t.coerce(value)
4
- !!value
5
- end
1
+ GraphQL::BOOLEAN_TYPE = GraphQL::ScalarType.define do
2
+ name "Boolean"
3
+ coerce -> (value) { !!value }
6
4
  end
@@ -6,5 +6,6 @@ require 'graph_ql/definition_helpers/argument_definer'
6
6
  require 'graph_ql/definition_helpers/definable'
7
7
  require 'graph_ql/definition_helpers/field_definer'
8
8
  require 'graph_ql/definition_helpers/non_null_with_bang'
9
+ require 'graph_ql/definition_helpers/defined_by_config'
9
10
  require 'graph_ql/definition_helpers/string_named_hash'
10
11
  require 'graph_ql/definition_helpers/type_definer'
@@ -0,0 +1,20 @@
1
+ # Provide a two-step definition process.
2
+ #
3
+ # 1. Use a config object to gather definitions
4
+ # 2. Transfer definitions to an actual instance of an object
5
+ #
6
+ module GraphQL::DefinitionHelpers::DefinedByConfig
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ # Pass the block to this class's `DefinitionConfig`,
13
+ # The return the result of {DefinitionConfig#to_instance}
14
+ def define(&block)
15
+ config = self.const_get(:DefinitionConfig).new
16
+ block && config.instance_eval(&block)
17
+ config.to_instance
18
+ end
19
+ end
20
+ end
@@ -3,36 +3,68 @@
3
3
  #
4
4
  # @example An enum of programming languages
5
5
  #
6
- # LanguageEnum = GraphQL::EnumType.new do |e|
7
- # e.name("Languages")
8
- # e.descriptions("Programming languages for Web projects")
9
- # e.value("PYTHON", "A dynamic, function-oriented language")
10
- # e.value("RUBY", "A very dynamic language aimed at programmer happiness")
11
- # e.value("JAVASCRIPT", "Accidental lingua franca of the web")
6
+ # LanguageEnum = GraphQL::EnumType.define do
7
+ # name "Languages"
8
+ # description "Programming languages for Web projects"
9
+ # value("PYTHON", "A dynamic, function-oriented language")
10
+ # value("RUBY", "A very dynamic language aimed at programmer happiness")
11
+ # value("JAVASCRIPT", "Accidental lingua franca of the web")
12
12
  # end
13
13
  class GraphQL::EnumType
14
14
  include GraphQL::DefinitionHelpers::NonNullWithBang
15
+ include GraphQL::DefinitionHelpers::DefinedByConfig
15
16
  extend GraphQL::DefinitionHelpers::Definable
16
17
  attr_definable :name, :description
17
- attr_reader :values
18
+ attr_accessor :values
19
+
20
+ class DefinitionConfig
21
+ extend GraphQL::DefinitionHelpers::Definable
22
+ # These are deprecated:
23
+ attr_definable :name, :description
24
+ attr_reader :values
25
+ def initialize
26
+ @values = {}
27
+ end
28
+
29
+ def types
30
+ GraphQL::DefinitionHelpers::TypeDefiner.instance
31
+ end
32
+
33
+ def value(name, desc = nil, deprecation_reason: nil, value: name)
34
+ value = EnumValue.new(name: name, description: description, deprecation_reason: deprecation_reason, value: value)
35
+ values[name] = value
36
+ end
37
+
38
+ def to_instance
39
+ object = GraphQL::EnumType.new
40
+ object.name = name
41
+ object.description = description
42
+ object.values = values
43
+ object
44
+ end
45
+ end
46
+
18
47
  def initialize
19
48
  @values = {}
20
- yield(
21
- self,
22
- GraphQL::DefinitionHelpers::TypeDefiner.instance,
23
- GraphQL::DefinitionHelpers::FieldDefiner.instance,
24
- GraphQL::DefinitionHelpers::ArgumentDefiner.instance
25
- )
49
+ if block_given?
50
+ yield(
51
+ self,
52
+ GraphQL::DefinitionHelpers::TypeDefiner.instance,
53
+ GraphQL::DefinitionHelpers::FieldDefiner.instance,
54
+ GraphQL::DefinitionHelpers::ArgumentDefiner.instance
55
+ )
56
+ warn("Initializing with .new is deprecated, use .define instead! (see #{self})")
57
+ end
26
58
  end
27
59
 
28
60
  # Define a value within this enum
29
- #
61
+ # @deprecated use {.define} API instead
30
62
  # @param name [String] the string representation of this value
31
63
  # @param description [String]
32
64
  # @param deprecation_reason [String] if provided, `deprecated?` will be true
33
65
  # @param value [Object] the underlying value for this enum value
34
66
  def value(name, description=nil, deprecation_reason: nil, value: name)
35
- @values[name] = EnumValue.new(name: name, description: description, deprecation_reason: deprecation_reason, value: value)
67
+ values[name] = EnumValue.new(name: name, description: description, deprecation_reason: deprecation_reason, value: value)
36
68
  end
37
69
 
38
70
  def kind
@@ -48,7 +80,11 @@ class GraphQL::EnumType
48
80
  # @param value_name [String] the string representation of this enum value
49
81
  # @return [Object] the underlying value for this enum value
50
82
  def coerce(value_name)
51
- @values[value_name].value
83
+ values[value_name].value
84
+ end
85
+
86
+ def to_s
87
+ name
52
88
  end
53
89
 
54
90
  # A value within an {EnumType}
@@ -1,28 +1,83 @@
1
- # These are valid values for a type's `fields` hash.
1
+ # {Field}s belong to {ObjectType}s and {InterfaceType}s.
2
+ #
3
+ # They're usually created with the `field` helper.
2
4
  #
3
- # You can also use {FieldDefiner#build} to create fields.
4
5
  #
5
6
  # @example creating a field
6
- # name_field = GraphQL::Field.new do |f, types|
7
- # f.name("Name")
8
- # f.type(!types.String)
9
- # f.description("The name of this thing")
10
- # f.resolve -> (object, arguments, context) { object.name }
7
+ # GraphQL::ObjectType.define do
8
+ # field :name, types.String, "The name of this thing "
9
+ # end
10
+ #
11
+ # @example creating a field that accesses a different property on the object
12
+ # GraphQL::ObjectType.define do
13
+ # # use the `property` option:
14
+ # field :firstName, types.String, property: :first_name
15
+ # end
16
+ #
17
+ # @example defining a field, then attaching it to a type
18
+ # name_field = GraphQL::Field.define do
19
+ # name("Name")
20
+ # type(!types.String)
21
+ # description("The name of this thing")
22
+ # resolve -> (object, arguments, context) { object.name }
23
+ # end
24
+ #
25
+ # NamedType = GraphQL::ObjectType.define do
26
+ # # use the `field` option:
27
+ # field :name, field: name_field
11
28
  # end
12
29
  #
13
30
  class GraphQL::Field
31
+ DEFAULT_RESOLVE = -> (o, a, c) { GraphQL::Query::DEFAULT_RESOLVE }
32
+ include GraphQL::DefinitionHelpers::DefinedByConfig
33
+ # These are deprecated:
14
34
  extend GraphQL::DefinitionHelpers::Definable
15
35
  attr_definable(:arguments, :deprecation_reason, :name, :description, :type)
16
36
 
37
+ class DefinitionConfig
38
+ extend GraphQL::DefinitionHelpers::Definable
39
+ attr_definable :name, :description, :type, :deprecation_reason, :resolve
40
+ def initialize
41
+ @arguments = {}
42
+ end
43
+
44
+ def types
45
+ GraphQL::DefinitionHelpers::TypeDefiner.instance
46
+ end
47
+
48
+ def argument(name, type, description = nil, default_value: nil)
49
+ @arguments[name.to_s] = GraphQL::Argument.new(
50
+ name: name.to_s,
51
+ type: type,
52
+ description: description,
53
+ default_value: nil,
54
+ )
55
+ end
56
+
57
+ def to_instance
58
+ object = GraphQL::Field.new
59
+ object.name = name
60
+ object.type = type
61
+ object.description = description
62
+ object.deprecation_reason = deprecation_reason
63
+ object.resolve = resolve
64
+ object.arguments = @arguments
65
+ object
66
+ end
67
+ end
68
+
17
69
  def initialize
18
70
  @arguments = {}
19
- @resolve_proc = -> (o, a, c) { GraphQL::Query::DEFAULT_RESOLVE }
20
- yield(
21
- self,
22
- GraphQL::DefinitionHelpers::TypeDefiner.instance,
23
- GraphQL::DefinitionHelpers::FieldDefiner.instance,
24
- GraphQL::DefinitionHelpers::ArgumentDefiner.instance
25
- )
71
+ @resolve_proc = DEFAULT_RESOLVE
72
+ if block_given?
73
+ yield(
74
+ self,
75
+ GraphQL::DefinitionHelpers::TypeDefiner.instance,
76
+ GraphQL::DefinitionHelpers::FieldDefiner.instance,
77
+ GraphQL::DefinitionHelpers::ArgumentDefiner.instance
78
+ )
79
+ warn("Initializing with .new is deprecated, use .define instead! (see #{self})")
80
+ end
26
81
  end
27
82
 
28
83
  def arguments(new_arguments=nil)
@@ -38,6 +93,7 @@ class GraphQL::Field
38
93
  end
39
94
 
40
95
  # @overload resolve(definition_proc)
96
+ # @deprecated use {.define} API instead
41
97
  # Define this field to return a value with `definition_proc`
42
98
  # @example defining the resolve method
43
99
  # field.resolve -> (obj, args, ctx) { obj.get_value }
@@ -59,7 +115,12 @@ class GraphQL::Field
59
115
  end
60
116
  end
61
117
 
118
+ def resolve=(resolve_proc)
119
+ @resolve_proc = resolve_proc || DEFAULT_RESOLVE
120
+ end
121
+
62
122
  # @overload type(return_type)
123
+ # @deprecated use {.define} API instead
63
124
  # Define the return type for this field
64
125
  # @param return_type [GraphQL::ObjectType, GraphQL::ScalarType] The type this field returns
65
126
  #
@@ -79,4 +140,8 @@ class GraphQL::Field
79
140
  end
80
141
  @type
81
142
  end
143
+
144
+ def to_s
145
+ "<Field: #{name || "not-named"}>"
146
+ end
82
147
  end
@@ -1,6 +1,6 @@
1
- GraphQL::FLOAT_TYPE = GraphQL::ScalarType.new do |t|
2
- t.name "Float"
3
- def t.coerce(value)
1
+ GraphQL::FLOAT_TYPE = GraphQL::ScalarType.define do
2
+ name "Float"
3
+ coerce -> (value) do
4
4
  value.respond_to?(:to_f) ? value.to_f : nil
5
5
  end
6
6
  end
@@ -1,6 +1,4 @@
1
- GraphQL::ID_TYPE = GraphQL::ScalarType.new do |t|
2
- t.name "ID"
3
- def t.coerce(value)
4
- value.to_s
5
- end
1
+ GraphQL::ID_TYPE = GraphQL::ScalarType.define do
2
+ name "ID"
3
+ coerce -> (value) { value.to_s }
6
4
  end
@@ -10,9 +10,44 @@
10
10
  # end
11
11
  #
12
12
  class GraphQL::InputObjectType < GraphQL::ObjectType
13
+ # Deprecated:
13
14
  attr_definable :input_fields
14
15
 
16
+ class DefinitionConfig
17
+ extend GraphQL::DefinitionHelpers::Definable
18
+ attr_definable :name, :description, :input_fields
19
+ def initialize
20
+ @input_fields = {}
21
+ end
22
+
23
+ def types
24
+ GraphQL::DefinitionHelpers::TypeDefiner.instance
25
+ end
26
+
27
+ def input_field(name, type = nil, desc = nil, default_value: nil, &block)
28
+ argument = if block_given?
29
+ GraphQL::Argument.define(&block)
30
+ else
31
+ GraphQL::Argument.new
32
+ end
33
+ argument.name = name
34
+ type && argument.type = type
35
+ desc && argument.desc = desc
36
+ default_value && argument.default_value = default_value
37
+ @input_fields[name.to_s] = argument
38
+ end
39
+
40
+ def to_instance
41
+ object = GraphQL::InputObjectType.new
42
+ object.name = name
43
+ object.description = description
44
+ object.input_fields = @input_fields
45
+ object
46
+ end
47
+ end
48
+
15
49
  # @overload input_fields(new_fields)
50
+ # @deprecated use {.define} API instead
16
51
  # Define allowed fields, normalized with {StringNamedHash}
17
52
  # @param new_fields [Hash] allowed fields for this input object type
18
53
  #
@@ -21,10 +56,12 @@ class GraphQL::InputObjectType < GraphQL::ObjectType
21
56
  # @return [Hash] allowed fields for this input object type
22
57
  #
23
58
  def input_fields(new_fields=nil)
24
- if !new_fields.nil?
25
- @new_fields = GraphQL::DefinitionHelpers::StringNamedHash.new(new_fields).to_h
26
- end
27
- @new_fields
59
+ new_fields && self.input_fields = new_fields
60
+ @input_fields
61
+ end
62
+
63
+ def input_fields=(new_fields)
64
+ @input_fields = GraphQL::DefinitionHelpers::StringNamedHash.new(new_fields).to_h
28
65
  end
29
66
 
30
67
  def kind
@@ -1,6 +1,4 @@
1
- GraphQL::INT_TYPE = GraphQL::ScalarType.new do |t|
2
- t.name "Int"
3
- def t.coerce(value)
4
- value.is_a?(Numeric) ? value.to_i : nil
5
- end
1
+ GraphQL::INT_TYPE = GraphQL::ScalarType.define do
2
+ name "Int"
3
+ coerce -> (value) { value.is_a?(Numeric) ? value.to_i : nil }
6
4
  end
@@ -1,14 +1,13 @@
1
1
  # A collection of types which implement the same fields
2
2
  #
3
3
  # @example An interface with three required fields
4
- # DeviceInterface = GraphQL::InterfaceType.new do |i, types, fields|
5
- # i.name("Device")
6
- # i.description("Hardware devices for computing")
7
- # i.fields({
8
- # ram: fields.build(type: types.String),
9
- # processor: fields.build(type: ProcessorType),
10
- # release_year: fields.build(type: types.Int),
11
- # })
4
+ # DeviceInterface = GraphQL::InterfaceType.define do
5
+ # name("Device")
6
+ # description("Hardware devices for computing")
7
+ #
8
+ # field :ram, types.String
9
+ # field :processor, ProcessorType
10
+ # field :release_year, types.Int
12
11
  # end
13
12
  #
14
13
  class GraphQL::InterfaceType < GraphQL::ObjectType
@@ -16,6 +15,35 @@ class GraphQL::InterfaceType < GraphQL::ObjectType
16
15
  GraphQL::TypeKinds::INTERFACE
17
16
  end
18
17
 
18
+ class DefinitionConfig
19
+ extend GraphQL::DefinitionHelpers::Definable
20
+ attr_definable :name, :description
21
+
22
+ def initialize
23
+ @fields = {}
24
+ end
25
+
26
+ def types
27
+ GraphQL::DefinitionHelpers::TypeDefiner.instance
28
+ end
29
+
30
+ def field(name, type = nil, desc = nil, property: nil, field: nil, &block)
31
+ field ||= GraphQL::Field.define(&block)
32
+ type && field.type = type
33
+ desc && field.description = desc
34
+ field.name ||= name.to_s
35
+ @fields[name.to_s] = field
36
+ end
37
+
38
+ def to_instance
39
+ object = GraphQL::InterfaceType.new
40
+ object.name = name
41
+ object.description = description
42
+ object.fields = @fields
43
+ object
44
+ end
45
+ end
46
+
19
47
  # @return [Array<GraphQL::ObjectType>] Types which declare that they implement this interface
20
48
  def possible_types
21
49
  @possible_types ||= []