graphql 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/{types/input_value.rb → argument.rb} +4 -1
  3. data/lib/graph_ql/{scalars/boolean_type.rb → boolean_type.rb} +0 -0
  4. data/lib/graph_ql/definition_helpers.rb +10 -0
  5. data/lib/graph_ql/definition_helpers/argument_definer.rb +5 -2
  6. data/lib/graph_ql/definition_helpers/definable.rb +1 -1
  7. data/lib/graph_ql/definition_helpers/field_definer.rb +4 -1
  8. data/lib/graph_ql/definition_helpers/non_null_with_bang.rb +3 -1
  9. data/lib/graph_ql/definition_helpers/string_named_hash.rb +7 -1
  10. data/lib/graph_ql/definition_helpers/type_definer.rb +13 -1
  11. data/lib/graph_ql/directive.rb +14 -6
  12. data/lib/graph_ql/{directives → directive}/include_directive.rb +1 -1
  13. data/lib/graph_ql/{directives → directive}/skip_directive.rb +1 -1
  14. data/lib/graph_ql/enum_type.rb +66 -0
  15. data/lib/graph_ql/field.rb +49 -13
  16. data/lib/graph_ql/{scalars/float_type.rb → float_type.rb} +0 -0
  17. data/lib/graph_ql/{scalars/id_type.rb → id_type.rb} +0 -0
  18. data/lib/graph_ql/input_object_type.rb +33 -0
  19. data/lib/graph_ql/{scalars/int_type.rb → int_type.rb} +0 -0
  20. data/lib/graph_ql/interface_type.rb +33 -0
  21. data/lib/graph_ql/introspection/field_type.rb +1 -0
  22. data/lib/graph_ql/introspection/fields_field.rb +1 -0
  23. data/lib/graph_ql/introspection/input_value_type.rb +1 -1
  24. data/lib/graph_ql/introspection/introspection_query.rb +77 -0
  25. data/lib/graph_ql/introspection/schema_field.rb +13 -0
  26. data/lib/graph_ql/introspection/type_by_name_field.rb +14 -0
  27. data/lib/graph_ql/introspection/type_kind_enum.rb +1 -1
  28. data/lib/graph_ql/{types/list_type.rb → list_type.rb} +3 -0
  29. data/lib/graph_ql/{parser/nodes.rb → nodes.rb} +8 -1
  30. data/lib/graph_ql/{types/non_null_type.rb → non_null_type.rb} +3 -0
  31. data/lib/graph_ql/object_type.rb +92 -0
  32. data/lib/graph_ql/parser.rb +107 -6
  33. data/lib/graph_ql/query.rb +8 -0
  34. data/lib/graph_ql/query/arguments.rb +13 -4
  35. data/lib/graph_ql/{directives → query}/directive_chain.rb +2 -2
  36. data/lib/graph_ql/query/field_resolution_strategy.rb +2 -2
  37. data/lib/graph_ql/query/operation_resolver.rb +3 -3
  38. data/lib/graph_ql/query/selection_resolver.rb +1 -1
  39. data/lib/graph_ql/scalar_type.rb +9 -0
  40. data/lib/graph_ql/schema.rb +26 -17
  41. data/lib/graph_ql/schema/type_reducer.rb +7 -0
  42. data/lib/graph_ql/static_validation/arguments_validator.rb +1 -0
  43. data/lib/graph_ql/static_validation/message.rb +4 -1
  44. data/lib/graph_ql/static_validation/rules/fields_are_defined_on_type.rb +1 -0
  45. data/lib/graph_ql/static_validation/rules/fields_have_appropriate_selections.rb +1 -0
  46. data/lib/graph_ql/static_validation/type_stack.rb +24 -4
  47. data/lib/graph_ql/static_validation/validator.rb +27 -0
  48. data/lib/graph_ql/{scalars/string_type.rb → string_type.rb} +0 -0
  49. data/lib/graph_ql/transform.rb +87 -0
  50. data/lib/graph_ql/type_kinds.rb +9 -0
  51. data/lib/graph_ql/{types/union.rb → union_type.rb} +8 -4
  52. data/lib/graph_ql/version.rb +1 -1
  53. data/lib/graph_ql/{parser/visitor.rb → visitor.rb} +29 -4
  54. data/lib/graphql.rb +28 -11
  55. data/readme.md +11 -1
  56. data/spec/graph_ql/{types/enum_spec.rb → enum_type_spec.rb} +1 -1
  57. data/spec/graph_ql/{fields/field_spec.rb → field_spec.rb} +0 -0
  58. data/spec/graph_ql/{scalars/id_type_spec.rb → id_type_spec.rb} +0 -0
  59. data/spec/graph_ql/{types/input_object_type_spec.rb → input_object_type_spec.rb} +0 -0
  60. data/spec/graph_ql/{types/interface_spec.rb → interface_type_spec.rb} +1 -1
  61. data/spec/graph_ql/introspection/introspection_query_spec.rb +10 -0
  62. data/spec/graph_ql/introspection/schema_type_spec.rb +0 -4
  63. data/spec/graph_ql/introspection/type_type_spec.rb +1 -5
  64. data/spec/graph_ql/{types/object_type_spec.rb → object_type_spec.rb} +0 -0
  65. data/spec/graph_ql/{parser/parser_spec.rb → parser_spec.rb} +0 -0
  66. data/spec/graph_ql/query/operation_resolver_spec.rb +1 -1
  67. data/spec/graph_ql/query_spec.rb +6 -2
  68. data/spec/graph_ql/schema/type_validator_spec.rb +1 -1
  69. data/spec/graph_ql/{parser/transform_spec.rb → transform_spec.rb} +0 -0
  70. data/spec/graph_ql/{types/union_spec.rb → union_type_spec.rb} +2 -2
  71. data/spec/graph_ql/{parser/visitor_spec.rb → visitor_spec.rb} +0 -0
  72. data/spec/support/{dummy_app.rb → dairy_app.rb} +8 -8
  73. data/spec/support/{dummy_data.rb → dairy_data.rb} +0 -0
  74. data/spec/support/star_wars_data.rb +71 -0
  75. data/spec/support/star_wars_schema.rb +87 -0
  76. metadata +59 -50
  77. data/lib/graph_ql/definition_helpers/forwardable.rb +0 -10
  78. data/lib/graph_ql/parser/parser.rb +0 -108
  79. data/lib/graph_ql/parser/transform.rb +0 -87
  80. data/lib/graph_ql/scalars/scalar_type.rb +0 -5
  81. data/lib/graph_ql/types/enum.rb +0 -32
  82. data/lib/graph_ql/types/input_object_type.rb +0 -14
  83. data/lib/graph_ql/types/interface.rb +0 -14
  84. data/lib/graph_ql/types/object_type.rb +0 -66
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9cf6add0a41fbbf194c90bd12da917467ae612d7
4
- data.tar.gz: b0e7b7f03eb0e6a9def2f7402f3349e69d07ec33
3
+ metadata.gz: a35f790dd696036b5c7ea909517a2108891d2732
4
+ data.tar.gz: 795e06d90a94be917cf6ffaf911d00e5c14faade
5
5
  SHA512:
6
- metadata.gz: f5d0f097d277cdd8e40976ce87ef5d57edf365c2fadf821de5c90d7dad9f9d7819a21291c6b01a83ab05e1d7850617bbbe0382c492776b04e5fa619e186e8caa
7
- data.tar.gz: ee252ea72993ee9c07ce9d69f6f25c0b6d13e9f7f2bf7cbbb419d8d2b01f48a9c7e57310c6cc05e051c833ee72b42494399bd5252813a4641d1ba3e88be17d16
6
+ metadata.gz: e62e25e0fedcbb6509d55d8f539f766d82429bafa3d278dde5fa3ca45420bc2a6cbbc3262b465a6f936ec76fcbb8296f4c7977cb8fdfd4581b818503570be372
7
+ data.tar.gz: e863e0d3699bb9233f96da31af72e42422cc18c0f1765f2446851f65e76c67a7c16bcd1862b863e048aced999fca335c0a7d1c6dfbbefb3a0981499c74bfa84a
@@ -1,4 +1,7 @@
1
- class GraphQL::InputValue
1
+ # Used for defined arguments ({Field}, {InputObjectType})
2
+ #
3
+ # Created by {ArgumentDefiner}
4
+ class GraphQL::Argument
2
5
  attr_reader :type, :description, :default_value
3
6
  attr_accessor :name
4
7
  def initialize(type:, description: nil, default_value: nil, name: nil)
@@ -0,0 +1,10 @@
1
+ module GraphQL
2
+ module DefinitionHelpers
3
+ end
4
+ end
5
+ require 'graph_ql/definition_helpers/argument_definer'
6
+ require 'graph_ql/definition_helpers/definable'
7
+ require 'graph_ql/definition_helpers/field_definer'
8
+ require 'graph_ql/definition_helpers/non_null_with_bang'
9
+ require 'graph_ql/definition_helpers/string_named_hash'
10
+ require 'graph_ql/definition_helpers/type_definer'
@@ -1,7 +1,10 @@
1
- class GraphQL::ArgumentDefiner
1
+ # Some conveniences for definining arguments.
2
+ #
3
+ # Passed into initialization blocks, eg {InputObjectType#initialize}, {Field#initialize}
4
+ class GraphQL::DefinitionHelpers::ArgumentDefiner
2
5
  include Singleton
3
6
 
4
7
  def build(type:, desc: "", default_value: nil)
5
- GraphQL::InputValue.new(type: type, description: desc, default_value: default_value)
8
+ GraphQL::Argument.new(type: type, description: desc, default_value: default_value)
6
9
  end
7
10
  end
@@ -4,7 +4,7 @@
4
4
  # @example defining an object's name
5
5
  # object.name("New name")
6
6
  #
7
- module GraphQL::Definable
7
+ module GraphQL::DefinitionHelpers::Definable
8
8
  def attr_definable(*names)
9
9
  attr_accessor(*names)
10
10
  names.each do |name|
@@ -1,4 +1,7 @@
1
- class GraphQL::FieldDefiner
1
+ # Some conveniences for definining fields on {ObjectType}s and {Interface}s.
2
+ #
3
+ # Passed into initialization blocks, eg {ObjectType#initialize}, {Field#initialize}
4
+ class GraphQL::DefinitionHelpers::FieldDefiner
2
5
  include Singleton
3
6
 
4
7
  def build(type:, args: {}, property: nil, desc: "", deprecation_reason: nil)
@@ -2,7 +2,9 @@
2
2
  # @example required Int type
3
3
  # !GraphQL::INT_TYPE
4
4
  #
5
- module GraphQL::NonNullWithBang
5
+ module GraphQL::DefinitionHelpers::NonNullWithBang
6
+ # Make the type non-null
7
+ # @return [GraphQL::NonNullType] a non-null type which wraps the original type
6
8
  def !
7
9
  GraphQL::NonNullType.new(of_type: self)
8
10
  end
@@ -1,8 +1,14 @@
1
1
  # Accepts a hash with symbol keys.
2
2
  # - convert keys to strings
3
3
  # - if the value responds to `name=`, then assign the hash key as `name`
4
- class GraphQL::StringNamedHash
4
+ #
5
+ # Used by {ObjectType#fields}, {Field#arguments} and others.
6
+ class GraphQL::DefinitionHelpers::StringNamedHash
7
+ # Normalized hash for the input
8
+ # @return [Hash] Hash with string keys
5
9
  attr_reader :to_h
10
+
11
+ # @param input_hash [Hash] Hash to be normalized
6
12
  def initialize(input_hash)
7
13
  @to_h = input_hash
8
14
  .reduce({}) { |memo, (key, value)| memo[key.to_s] = value; memo }
@@ -1,4 +1,7 @@
1
- class GraphQL::TypeDefiner
1
+ # Some conveniences for definining return & argument types.
2
+ #
3
+ # Passed into initialization blocks, eg {ObjectType#initialize}, {Field#initialize}
4
+ class GraphQL::DefinitionHelpers::TypeDefiner
2
5
  include Singleton
3
6
 
4
7
  def Int; GraphQL::INT_TYPE; end
@@ -7,6 +10,15 @@ class GraphQL::TypeDefiner
7
10
  def Boolean; GraphQL::BOOLEAN_TYPE; end
8
11
  def ID; GraphQL::ID_TYPE; end
9
12
 
13
+ # Make a {ListType} which wraps the input type
14
+ #
15
+ # @example making a list type
16
+ # list_of_strings = types[types.String]
17
+ # list_of_strings.inspect
18
+ # # => "[String]"
19
+ #
20
+ # @param type [Type] A type to be wrapped in a ListType
21
+ # @return [GraphQL::ListType] A ListType wrapping `type`
10
22
  def [](type)
11
23
  GraphQL::ListType.new(of_type: type)
12
24
  end
@@ -1,5 +1,9 @@
1
+ # This implementation of `Directive` is ... not robust.
2
+ # It seems like this area of the spec is still getting worked out, so
3
+ # {Directive} & {DirectiveChain} implement `@skip` and `@include` with
4
+ # minimal impact on query execution.
1
5
  class GraphQL::Directive
2
- extend GraphQL::Definable
6
+ extend GraphQL::DefinitionHelpers::Definable
3
7
  attr_definable :on, :arguments, :name, :description
4
8
 
5
9
  LOCATIONS = [
@@ -15,7 +19,12 @@ class GraphQL::Directive
15
19
  def initialize
16
20
  @arguments = {}
17
21
  @on = []
18
- yield(self, GraphQL::TypeDefiner.instance, GraphQL::FieldDefiner.instance, GraphQL::ArgumentDefiner.instance)
22
+ yield(
23
+ self,
24
+ GraphQL::DefinitionHelpers::TypeDefiner.instance,
25
+ GraphQL::DefinitionHelpers::FieldDefiner.instance,
26
+ GraphQL::DefinitionHelpers::ArgumentDefiner.instance
27
+ )
19
28
  end
20
29
 
21
30
  def resolve(proc_or_arguments, proc=nil)
@@ -29,7 +38,7 @@ class GraphQL::Directive
29
38
 
30
39
  def arguments(new_arguments=nil)
31
40
  if !new_arguments.nil?
32
- @arguments = GraphQL::StringNamedHash.new(new_arguments).to_h
41
+ @arguments = GraphQL::DefinitionHelpers::StringNamedHash.new(new_arguments).to_h
33
42
  end
34
43
  @arguments
35
44
  end
@@ -39,6 +48,5 @@ class GraphQL::Directive
39
48
  end
40
49
  end
41
50
 
42
- require 'graph_ql/directives/directive_chain'
43
- require 'graph_ql/directives/include_directive'
44
- require 'graph_ql/directives/skip_directive'
51
+ require 'graph_ql/directive/include_directive'
52
+ require 'graph_ql/directive/skip_directive'
@@ -1,4 +1,4 @@
1
- GraphQL::IncludeDirective = GraphQL::Directive.new do |d, type, field, arg|
1
+ GraphQL::Directive::IncludeDirective = GraphQL::Directive.new do |d, type, field, arg|
2
2
  d.name "include"
3
3
  d.description "Include this part of the query if `if` is true"
4
4
  d.on([GraphQL::Directive::ON_FIELD, GraphQL::Directive::ON_FRAGMENT])
@@ -1,4 +1,4 @@
1
- GraphQL::SkipDirective = GraphQL::Directive.new do |d, type, field, arg|
1
+ GraphQL::Directive::SkipDirective = GraphQL::Directive.new do |d, type, field, arg|
2
2
  d.name "skip"
3
3
  d.description "Ignore this part of the query if `if` is true"
4
4
  d.on([GraphQL::Directive::ON_FIELD, GraphQL::Directive::ON_FRAGMENT])
@@ -0,0 +1,66 @@
1
+ # A finite set of possible values, represented in query strings with
2
+ # SCREAMING_CASE_NAMES
3
+ #
4
+ # @example An enum of programming languages
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")
12
+ # end
13
+ class GraphQL::EnumType
14
+ include GraphQL::DefinitionHelpers::NonNullWithBang
15
+ extend GraphQL::DefinitionHelpers::Definable
16
+ attr_definable :name, :description
17
+ attr_reader :values
18
+ def initialize
19
+ @values = {}
20
+ yield(
21
+ self,
22
+ GraphQL::DefinitionHelpers::TypeDefiner.instance,
23
+ GraphQL::DefinitionHelpers::FieldDefiner.instance,
24
+ GraphQL::DefinitionHelpers::ArgumentDefiner.instance
25
+ )
26
+ end
27
+
28
+ # Define a value within this enum
29
+ #
30
+ # @param name [String] the string representation of this value
31
+ # @param description [String]
32
+ # @param deprecation_reason [String] if provided, `deprecated?` will be true
33
+ # @param value [Object] the underlying value for this enum value
34
+ 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)
36
+ end
37
+
38
+ def kind
39
+ GraphQL::TypeKinds::ENUM
40
+ end
41
+
42
+ # Get the underlying value for this enum value
43
+ #
44
+ # @example get episode value from Enum
45
+ # episode = EpisodeEnum.coerce("NEWHOPE")
46
+ # episode # => 6
47
+ #
48
+ # @param value_name [String] the string representation of this enum value
49
+ # @return [Object] the underlying value for this enum value
50
+ def coerce(value_name)
51
+ @values[value_name].value
52
+ end
53
+
54
+ # A value within an {EnumType}
55
+ #
56
+ # Created with {EnumType#value}
57
+ class EnumValue
58
+ attr_reader :name, :description, :deprecation_reason, :value
59
+ def initialize(name:, description:, deprecation_reason:, value:)
60
+ @name = name
61
+ @description = description
62
+ @deprecation_reason = deprecation_reason
63
+ @value = value
64
+ end
65
+ end
66
+ end
@@ -1,11 +1,28 @@
1
+ # These are valid values for a type's `fields` hash.
2
+ #
3
+ # You can also use {FieldDefiner#build} to create fields.
4
+ #
5
+ # @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 }
11
+ # end
12
+ #
1
13
  class GraphQL::Field
2
- extend GraphQL::Definable
14
+ extend GraphQL::DefinitionHelpers::Definable
3
15
  attr_definable(:arguments, :deprecation_reason, :name, :description, :type)
4
16
 
5
17
  def initialize
6
18
  @arguments = {}
7
19
  @resolve_proc = -> (o, a, c) { GraphQL::Query::DEFAULT_RESOLVE }
8
- yield(self, GraphQL::TypeDefiner.instance, GraphQL::FieldDefiner.instance, GraphQL::ArgumentDefiner.instance)
20
+ yield(
21
+ self,
22
+ GraphQL::DefinitionHelpers::TypeDefiner.instance,
23
+ GraphQL::DefinitionHelpers::FieldDefiner.instance,
24
+ GraphQL::DefinitionHelpers::ArgumentDefiner.instance
25
+ )
9
26
  end
10
27
 
11
28
  def arguments(new_arguments=nil)
@@ -15,25 +32,44 @@ class GraphQL::Field
15
32
  @arguments
16
33
  end
17
34
 
35
+ # Define the arguments for this field using {StringNamedHash}
18
36
  def arguments=(new_arguments)
19
- @arguments = GraphQL::StringNamedHash.new(new_arguments).to_h
37
+ @arguments = GraphQL::DefinitionHelpers::StringNamedHash.new(new_arguments).to_h
20
38
  end
21
39
 
22
-
23
- # Used when defining:
24
- # resolve -> (obj, args, ctx) { obj.get_value }
25
- # Also used when executing queries:
26
- # field.resolve(obj, args, ctx)
27
- def resolve(proc_or_object, arguments=nil, ctx=nil)
28
- if arguments.nil? && ctx.nil?
40
+ # @overload resolve(definition_proc)
41
+ # Define this field to return a value with `definition_proc`
42
+ # @example defining the resolve method
43
+ # field.resolve -> (obj, args, ctx) { obj.get_value }
44
+ # @param definition_proc [Proc] The proc to evaluate to get a value
45
+ #
46
+ # @overload resolve(object, arguments, context)
47
+ # Get a value for this field
48
+ # @example resolving a field value
49
+ # field.resolve(obj, args, ctx)
50
+ #
51
+ # @param object [Object] The object this field belongs to
52
+ # @param arguments [Hash] Arguments declared in the query
53
+ # @param context [GraphQL::Query::Context]
54
+ def resolve(proc_or_object, arguments=nil, context=nil)
55
+ if arguments.nil? && context.nil?
29
56
  @resolve_proc = proc_or_object
30
57
  else
31
- @resolve_proc.call(proc_or_object, arguments, ctx)
58
+ @resolve_proc.call(proc_or_object, arguments, context)
32
59
  end
33
60
  end
34
61
 
35
- # You can pass a proc which will cause the type to be lazy-evaled,
36
- # That's nice if you have load-order issues
62
+ # @overload type(return_type)
63
+ # Define the return type for this field
64
+ # @param return_type [GraphQL::ObjectType, GraphQL::ScalarType] The type this field returns
65
+ #
66
+ # @overload type(return_type_proc)
67
+ # Wrap the return type in a proc,which will cause the type to be lazy-evaled,
68
+ #
69
+ # That's nice if you have load-order issues.
70
+ # @example lazy-evaled return type
71
+ # field.type(-> { MyCircularDependentType })
72
+ # @param return_type_proc [Proc] A proc which returns the return type for this field
37
73
  def type(type_or_proc=nil)
38
74
  if !type_or_proc.nil?
39
75
  @type = type_or_proc
File without changes
@@ -0,0 +1,33 @@
1
+ # A complex input type for a field argument.
2
+ #
3
+ # @example An input type with name and number
4
+ # PlayerInput = GraphQL::InputObjectType.new do |i, types, fields, args|
5
+ # i.name("Player")
6
+ # i.input_fields({
7
+ # name: args.build(type: !types.String)
8
+ # number: args.build(type: !types.Int)
9
+ # })
10
+ # end
11
+ #
12
+ class GraphQL::InputObjectType < GraphQL::ObjectType
13
+ attr_definable :input_fields
14
+
15
+ # @overload input_fields(new_fields)
16
+ # Define allowed fields, normalized with {StringNamedHash}
17
+ # @param new_fields [Hash] allowed fields for this input object type
18
+ #
19
+ # @overload input_fields()
20
+ # Read the defined fields for this input type
21
+ # @return [Hash] allowed fields for this input object type
22
+ #
23
+ 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
28
+ end
29
+
30
+ def kind
31
+ GraphQL::TypeKinds::INPUT_OBJECT
32
+ end
33
+ end
File without changes
@@ -0,0 +1,33 @@
1
+ # A collection of types which implement the same fields
2
+ #
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
+ # })
12
+ # end
13
+ #
14
+ class GraphQL::InterfaceType < GraphQL::ObjectType
15
+ def kind
16
+ GraphQL::TypeKinds::INTERFACE
17
+ end
18
+
19
+ # @return [Array<GraphQL::ObjectType>] Types which declare that they implement this interface
20
+ def possible_types
21
+ @possible_types ||= []
22
+ end
23
+
24
+ # Return the implementing type for `object`.
25
+ # The default implementation assumes that there's a type with the same name as `object.class.name`.
26
+ # Maybe you'll need to override this in your own interfaces!
27
+ #
28
+ # @param object [Object] the object which needs a type to expose it
29
+ # @return [GraphQL::ObjectType] the type which should expose `object`
30
+ def resolve_type(object)
31
+ @possible_types.find {|t| t.name == object.class.name }
32
+ end
33
+ end
@@ -10,6 +10,7 @@ GraphQL::Introspection::FieldType = GraphQL::ObjectType.new do |t, type, field|
10
10
  f.description "Is this field deprecated?"
11
11
  f.resolve -> (obj, a, c) { !!obj.deprecation_reason }
12
12
  },
13
+ args: GraphQL::Introspection::ArgumentsField,
13
14
  deprecationReason: field.build(type: type.String, property: :deprecation_reason, desc: "Why this field was deprecated"),
14
15
  })
15
16
  end
@@ -5,6 +5,7 @@ GraphQL::Introspection::FieldsField = GraphQL::Field.new do |f, type, field, arg
5
5
  includeDeprecated: arg.build({type: GraphQL::BOOLEAN_TYPE, default_value: false})
6
6
  })
7
7
  f.resolve -> (object, arguments, context) {
8
+ return nil if !object.kind.fields?
8
9
  fields = object.fields.values
9
10
  if !arguments["includeDeprecated"]
10
11
  fields = fields.select {|f| !f.deprecation_reason }
@@ -1,5 +1,5 @@
1
1
  GraphQL::Introspection::InputValueType = GraphQL::ObjectType.new do |t, type, field|
2
- t.name "InputValue"
2
+ t.name "__InputValue"
3
3
  t.description "An input for a field or InputObject"
4
4
  t.fields({
5
5
  name: field.build(type: !type.String, desc: "The key for this value"),
@@ -0,0 +1,77 @@
1
+ # The introspection query to end all introspection queries, copied from
2
+ # https://github.com/graphql/graphql-js/blob/master/src/utilities/introspectionQuery.js
3
+ GraphQL::Introspection::INTROSPECTION_QUERY = "
4
+ query IntrospectionQuery {
5
+ __schema {
6
+ queryType { name }
7
+ mutationType { name }
8
+ types {
9
+ ...FullType
10
+ }
11
+ directives {
12
+ name
13
+ description
14
+ args {
15
+ ...InputValue
16
+ }
17
+ onOperation
18
+ onFragment
19
+ onField
20
+ }
21
+ }
22
+ }
23
+ fragment FullType on __Type {
24
+ kind
25
+ name
26
+ description
27
+ fields {
28
+ name
29
+ description
30
+ args {
31
+ ...InputValue
32
+ }
33
+ type {
34
+ ...TypeRef
35
+ }
36
+ isDeprecated
37
+ deprecationReason
38
+ }
39
+ inputFields {
40
+ ...InputValue
41
+ }
42
+ interfaces {
43
+ ...TypeRef
44
+ }
45
+ enumValues {
46
+ name
47
+ description
48
+ isDeprecated
49
+ deprecationReason
50
+ }
51
+ possibleTypes {
52
+ ...TypeRef
53
+ }
54
+ }
55
+ fragment InputValue on __InputValue {
56
+ name
57
+ description
58
+ type { ...TypeRef }
59
+ defaultValue
60
+ }
61
+ fragment TypeRef on __Type {
62
+ kind
63
+ name
64
+ ofType {
65
+ kind
66
+ name
67
+ ofType {
68
+ kind
69
+ name
70
+ ofType {
71
+ kind
72
+ name
73
+ }
74
+ }
75
+ }
76
+ }
77
+ "