graphql 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graph_ql/{types/input_value.rb → argument.rb} +4 -1
- data/lib/graph_ql/{scalars/boolean_type.rb → boolean_type.rb} +0 -0
- data/lib/graph_ql/definition_helpers.rb +10 -0
- data/lib/graph_ql/definition_helpers/argument_definer.rb +5 -2
- data/lib/graph_ql/definition_helpers/definable.rb +1 -1
- data/lib/graph_ql/definition_helpers/field_definer.rb +4 -1
- data/lib/graph_ql/definition_helpers/non_null_with_bang.rb +3 -1
- data/lib/graph_ql/definition_helpers/string_named_hash.rb +7 -1
- data/lib/graph_ql/definition_helpers/type_definer.rb +13 -1
- data/lib/graph_ql/directive.rb +14 -6
- data/lib/graph_ql/{directives → directive}/include_directive.rb +1 -1
- data/lib/graph_ql/{directives → directive}/skip_directive.rb +1 -1
- data/lib/graph_ql/enum_type.rb +66 -0
- data/lib/graph_ql/field.rb +49 -13
- data/lib/graph_ql/{scalars/float_type.rb → float_type.rb} +0 -0
- data/lib/graph_ql/{scalars/id_type.rb → id_type.rb} +0 -0
- data/lib/graph_ql/input_object_type.rb +33 -0
- data/lib/graph_ql/{scalars/int_type.rb → int_type.rb} +0 -0
- data/lib/graph_ql/interface_type.rb +33 -0
- data/lib/graph_ql/introspection/field_type.rb +1 -0
- data/lib/graph_ql/introspection/fields_field.rb +1 -0
- data/lib/graph_ql/introspection/input_value_type.rb +1 -1
- data/lib/graph_ql/introspection/introspection_query.rb +77 -0
- data/lib/graph_ql/introspection/schema_field.rb +13 -0
- data/lib/graph_ql/introspection/type_by_name_field.rb +14 -0
- data/lib/graph_ql/introspection/type_kind_enum.rb +1 -1
- data/lib/graph_ql/{types/list_type.rb → list_type.rb} +3 -0
- data/lib/graph_ql/{parser/nodes.rb → nodes.rb} +8 -1
- data/lib/graph_ql/{types/non_null_type.rb → non_null_type.rb} +3 -0
- data/lib/graph_ql/object_type.rb +92 -0
- data/lib/graph_ql/parser.rb +107 -6
- data/lib/graph_ql/query.rb +8 -0
- data/lib/graph_ql/query/arguments.rb +13 -4
- data/lib/graph_ql/{directives → query}/directive_chain.rb +2 -2
- data/lib/graph_ql/query/field_resolution_strategy.rb +2 -2
- data/lib/graph_ql/query/operation_resolver.rb +3 -3
- data/lib/graph_ql/query/selection_resolver.rb +1 -1
- data/lib/graph_ql/scalar_type.rb +9 -0
- data/lib/graph_ql/schema.rb +26 -17
- data/lib/graph_ql/schema/type_reducer.rb +7 -0
- data/lib/graph_ql/static_validation/arguments_validator.rb +1 -0
- data/lib/graph_ql/static_validation/message.rb +4 -1
- data/lib/graph_ql/static_validation/rules/fields_are_defined_on_type.rb +1 -0
- data/lib/graph_ql/static_validation/rules/fields_have_appropriate_selections.rb +1 -0
- data/lib/graph_ql/static_validation/type_stack.rb +24 -4
- data/lib/graph_ql/static_validation/validator.rb +27 -0
- data/lib/graph_ql/{scalars/string_type.rb → string_type.rb} +0 -0
- data/lib/graph_ql/transform.rb +87 -0
- data/lib/graph_ql/type_kinds.rb +9 -0
- data/lib/graph_ql/{types/union.rb → union_type.rb} +8 -4
- data/lib/graph_ql/version.rb +1 -1
- data/lib/graph_ql/{parser/visitor.rb → visitor.rb} +29 -4
- data/lib/graphql.rb +28 -11
- data/readme.md +11 -1
- data/spec/graph_ql/{types/enum_spec.rb → enum_type_spec.rb} +1 -1
- data/spec/graph_ql/{fields/field_spec.rb → field_spec.rb} +0 -0
- data/spec/graph_ql/{scalars/id_type_spec.rb → id_type_spec.rb} +0 -0
- data/spec/graph_ql/{types/input_object_type_spec.rb → input_object_type_spec.rb} +0 -0
- data/spec/graph_ql/{types/interface_spec.rb → interface_type_spec.rb} +1 -1
- data/spec/graph_ql/introspection/introspection_query_spec.rb +10 -0
- data/spec/graph_ql/introspection/schema_type_spec.rb +0 -4
- data/spec/graph_ql/introspection/type_type_spec.rb +1 -5
- data/spec/graph_ql/{types/object_type_spec.rb → object_type_spec.rb} +0 -0
- data/spec/graph_ql/{parser/parser_spec.rb → parser_spec.rb} +0 -0
- data/spec/graph_ql/query/operation_resolver_spec.rb +1 -1
- data/spec/graph_ql/query_spec.rb +6 -2
- data/spec/graph_ql/schema/type_validator_spec.rb +1 -1
- data/spec/graph_ql/{parser/transform_spec.rb → transform_spec.rb} +0 -0
- data/spec/graph_ql/{types/union_spec.rb → union_type_spec.rb} +2 -2
- data/spec/graph_ql/{parser/visitor_spec.rb → visitor_spec.rb} +0 -0
- data/spec/support/{dummy_app.rb → dairy_app.rb} +8 -8
- data/spec/support/{dummy_data.rb → dairy_data.rb} +0 -0
- data/spec/support/star_wars_data.rb +71 -0
- data/spec/support/star_wars_schema.rb +87 -0
- metadata +59 -50
- data/lib/graph_ql/definition_helpers/forwardable.rb +0 -10
- data/lib/graph_ql/parser/parser.rb +0 -108
- data/lib/graph_ql/parser/transform.rb +0 -87
- data/lib/graph_ql/scalars/scalar_type.rb +0 -5
- data/lib/graph_ql/types/enum.rb +0 -32
- data/lib/graph_ql/types/input_object_type.rb +0 -14
- data/lib/graph_ql/types/interface.rb +0 -14
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a35f790dd696036b5c7ea909517a2108891d2732
|
4
|
+
data.tar.gz: 795e06d90a94be917cf6ffaf911d00e5c14faade
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e62e25e0fedcbb6509d55d8f539f766d82429bafa3d278dde5fa3ca45420bc2a6cbbc3262b465a6f936ec76fcbb8296f4c7977cb8fdfd4581b818503570be372
|
7
|
+
data.tar.gz: e863e0d3699bb9233f96da31af72e42422cc18c0f1765f2446851f65e76c67a7c16bcd1862b863e048aced999fca335c0a7d1c6dfbbefb3a0981499c74bfa84a
|
@@ -1,4 +1,7 @@
|
|
1
|
-
|
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)
|
File without changes
|
@@ -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
|
-
|
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::
|
8
|
+
GraphQL::Argument.new(type: type, description: desc, default_value: default_value)
|
6
9
|
end
|
7
10
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/graph_ql/directive.rb
CHANGED
@@ -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(
|
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/
|
43
|
-
require 'graph_ql/
|
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
|
data/lib/graph_ql/field.rb
CHANGED
@@ -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(
|
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
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
|
28
|
-
|
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,
|
58
|
+
@resolve_proc.call(proc_or_object, arguments, context)
|
32
59
|
end
|
33
60
|
end
|
34
61
|
|
35
|
-
#
|
36
|
-
#
|
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
|
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 "
|
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
|
+
"
|