graphql 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graph_ql/directive.rb +36 -0
  3. data/lib/graph_ql/directives/directive_chain.rb +33 -0
  4. data/lib/graph_ql/directives/include_directive.rb +15 -0
  5. data/lib/graph_ql/directives/skip_directive.rb +15 -0
  6. data/lib/graph_ql/enum.rb +34 -0
  7. data/lib/graph_ql/fields/abstract_field.rb +37 -0
  8. data/lib/graph_ql/fields/access_field.rb +24 -0
  9. data/lib/graph_ql/fields/field.rb +34 -0
  10. data/lib/graph_ql/interface.rb +14 -0
  11. data/lib/graph_ql/introspection/arguments_field.rb +5 -0
  12. data/lib/graph_ql/introspection/directive_type.rb +12 -0
  13. data/lib/graph_ql/introspection/enum_value_type.rb +10 -0
  14. data/lib/graph_ql/introspection/enum_values_field.rb +15 -0
  15. data/lib/graph_ql/introspection/field_type.rb +11 -0
  16. data/lib/graph_ql/introspection/fields_field.rb +14 -0
  17. data/lib/graph_ql/introspection/input_fields_field.rb +12 -0
  18. data/lib/graph_ql/introspection/input_value_type.rb +10 -0
  19. data/lib/graph_ql/introspection/of_type_field.rb +12 -0
  20. data/lib/graph_ql/introspection/possible_types_field.rb +12 -0
  21. data/lib/graph_ql/introspection/schema_type.rb +32 -0
  22. data/lib/graph_ql/introspection/type_kind_enum.rb +7 -0
  23. data/lib/graph_ql/introspection/type_type.rb +22 -0
  24. data/lib/graph_ql/parser/nodes.rb +72 -0
  25. data/lib/graph_ql/parser/parser.rb +108 -0
  26. data/lib/graph_ql/parser/transform.rb +86 -0
  27. data/lib/graph_ql/parser/visitor.rb +47 -0
  28. data/lib/graph_ql/query.rb +50 -0
  29. data/lib/graph_ql/query/arguments.rb +25 -0
  30. data/lib/graph_ql/query/field_resolution_strategy.rb +83 -0
  31. data/lib/graph_ql/query/fragment_spread_resolution_strategy.rb +16 -0
  32. data/lib/graph_ql/query/inline_fragment_resolution_strategy.rb +14 -0
  33. data/lib/graph_ql/query/operation_resolver.rb +28 -0
  34. data/lib/graph_ql/query/selection_resolver.rb +20 -0
  35. data/lib/graph_ql/query/type_resolver.rb +19 -0
  36. data/lib/graph_ql/repl.rb +27 -0
  37. data/lib/graph_ql/schema.rb +30 -0
  38. data/lib/graph_ql/schema/type_reducer.rb +44 -0
  39. data/lib/graph_ql/type_kinds.rb +15 -0
  40. data/lib/graph_ql/types/abstract_type.rb +14 -0
  41. data/lib/graph_ql/types/boolean_type.rb +6 -0
  42. data/lib/graph_ql/types/float_type.rb +6 -0
  43. data/lib/graph_ql/types/input_object_type.rb +17 -0
  44. data/lib/graph_ql/types/input_value.rb +10 -0
  45. data/lib/graph_ql/types/int_type.rb +6 -0
  46. data/lib/graph_ql/types/list_type.rb +10 -0
  47. data/lib/graph_ql/types/non_null_type.rb +18 -0
  48. data/lib/graph_ql/types/non_null_with_bang.rb +5 -0
  49. data/lib/graph_ql/types/object_type.rb +62 -0
  50. data/lib/graph_ql/types/scalar_type.rb +5 -0
  51. data/lib/graph_ql/types/string_type.rb +6 -0
  52. data/lib/graph_ql/types/type_definer.rb +16 -0
  53. data/lib/graph_ql/union.rb +35 -0
  54. data/lib/graph_ql/validations/fields_are_defined_on_type.rb +44 -0
  55. data/lib/graph_ql/validations/fields_will_merge.rb +80 -0
  56. data/lib/graph_ql/validations/fragments_are_used.rb +24 -0
  57. data/lib/graph_ql/validator.rb +29 -0
  58. data/lib/graph_ql/version.rb +3 -0
  59. data/lib/graphql.rb +92 -99
  60. data/readme.md +17 -177
  61. data/spec/graph_ql/directive_spec.rb +81 -0
  62. data/spec/graph_ql/enum_spec.rb +5 -0
  63. data/spec/graph_ql/fields/field_spec.rb +10 -0
  64. data/spec/graph_ql/interface_spec.rb +13 -0
  65. data/spec/graph_ql/introspection/directive_type_spec.rb +40 -0
  66. data/spec/graph_ql/introspection/schema_type_spec.rb +39 -0
  67. data/spec/graph_ql/introspection/type_type_spec.rb +104 -0
  68. data/spec/graph_ql/parser/parser_spec.rb +120 -0
  69. data/spec/graph_ql/parser/transform_spec.rb +109 -0
  70. data/spec/graph_ql/parser/visitor_spec.rb +31 -0
  71. data/spec/graph_ql/query/operation_resolver_spec.rb +14 -0
  72. data/spec/graph_ql/query_spec.rb +82 -0
  73. data/spec/graph_ql/schema/type_reducer_spec.rb +24 -0
  74. data/spec/graph_ql/types/input_object_type_spec.rb +12 -0
  75. data/spec/graph_ql/types/object_type_spec.rb +35 -0
  76. data/spec/graph_ql/union_spec.rb +27 -0
  77. data/spec/graph_ql/validations/fields_are_defined_on_type_spec.rb +28 -0
  78. data/spec/graph_ql/validations/fields_will_merge_spec.rb +40 -0
  79. data/spec/graph_ql/validations/fragments_are_used_spec.rb +28 -0
  80. data/spec/graph_ql/validator_spec.rb +24 -0
  81. data/spec/spec_helper.rb +2 -2
  82. data/spec/support/dummy_app.rb +123 -63
  83. data/spec/support/dummy_data.rb +11 -0
  84. metadata +107 -59
  85. data/lib/graphql/call.rb +0 -8
  86. data/lib/graphql/connection.rb +0 -65
  87. data/lib/graphql/field.rb +0 -12
  88. data/lib/graphql/field_definer.rb +0 -25
  89. data/lib/graphql/introspection/call_type.rb +0 -13
  90. data/lib/graphql/introspection/connection.rb +0 -9
  91. data/lib/graphql/introspection/field_type.rb +0 -10
  92. data/lib/graphql/introspection/root_call_argument_node.rb +0 -5
  93. data/lib/graphql/introspection/root_call_type.rb +0 -20
  94. data/lib/graphql/introspection/schema_call.rb +0 -8
  95. data/lib/graphql/introspection/schema_type.rb +0 -17
  96. data/lib/graphql/introspection/type_call.rb +0 -8
  97. data/lib/graphql/introspection/type_type.rb +0 -18
  98. data/lib/graphql/node.rb +0 -244
  99. data/lib/graphql/parser/parser.rb +0 -39
  100. data/lib/graphql/parser/transform.rb +0 -22
  101. data/lib/graphql/query.rb +0 -109
  102. data/lib/graphql/root_call.rb +0 -202
  103. data/lib/graphql/root_call_argument.rb +0 -11
  104. data/lib/graphql/root_call_argument_definer.rb +0 -17
  105. data/lib/graphql/schema/all.rb +0 -46
  106. data/lib/graphql/schema/schema.rb +0 -87
  107. data/lib/graphql/schema/schema_validation.rb +0 -32
  108. data/lib/graphql/syntax/call.rb +0 -8
  109. data/lib/graphql/syntax/field.rb +0 -9
  110. data/lib/graphql/syntax/fragment.rb +0 -7
  111. data/lib/graphql/syntax/node.rb +0 -8
  112. data/lib/graphql/syntax/query.rb +0 -8
  113. data/lib/graphql/syntax/variable.rb +0 -7
  114. data/lib/graphql/types/boolean_type.rb +0 -3
  115. data/lib/graphql/types/number_type.rb +0 -3
  116. data/lib/graphql/types/object_type.rb +0 -6
  117. data/lib/graphql/types/string_type.rb +0 -3
  118. data/lib/graphql/version.rb +0 -3
  119. data/spec/graphql/node_spec.rb +0 -69
  120. data/spec/graphql/parser/parser_spec.rb +0 -168
  121. data/spec/graphql/parser/transform_spec.rb +0 -157
  122. data/spec/graphql/query_spec.rb +0 -274
  123. data/spec/graphql/root_call_spec.rb +0 -69
  124. data/spec/graphql/schema/schema_spec.rb +0 -93
  125. data/spec/graphql/schema/schema_validation_spec.rb +0 -48
  126. data/spec/support/nodes.rb +0 -175
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea9221c87a055fadbddc1b61de970e61b993e074
4
- data.tar.gz: 289bff890b6c2fb4ff3487cd74f8333375dcdbe9
3
+ metadata.gz: 7b1fdc7f41a30030c670d131b5725c04e6a19090
4
+ data.tar.gz: 5a6326377c36595c319f710c2f2e429188589266
5
5
  SHA512:
6
- metadata.gz: 28d366cd1a906295fe885728ad08f1b13bcbd3b36ad35ac3aed6603d54a680a9e01ed048393f040f59d3b649c261e82958ef2432f652fa78d8a97d88ea69ca2b
7
- data.tar.gz: eb17ca9aa091ccc42a85ecbf59b45bbbe61fa9dc154cb0794cbe59cae6bdc0a1e082fe35f95f8878c6b0dbe59432a420c58068f00f40eb594c00ef083d5c73a6
6
+ metadata.gz: 12d6d135cde8e87dc9ba32dab2c5e02bb418dd76922c086de95223f62fa544b87049dc15845a5f03818492324cc963715259a926e234263fd00e0ae336970fb4
7
+ data.tar.gz: 25e46e69f7210ace996eb2c2d93c52a03ae75944c58d269709e61200a6a872479edbe5ede7b7e446f30f3dd458abbbf736881da13b4969c8daaa1c3be99da1d5
@@ -0,0 +1,36 @@
1
+ class GraphQL::Directive < GraphQL::ObjectType
2
+ LOCATIONS = [
3
+ ON_OPERATION = :on_operation?,
4
+ ON_FRAGMENT = :on_fragment?,
5
+ ON_FIELD = :on_field?,
6
+ ]
7
+ LOCATIONS.each do |location|
8
+ define_method(location) { self.on.include?(location) }
9
+ end
10
+
11
+ attr_definable :on, :arguments
12
+
13
+ def initialize(&block)
14
+ @arguments = {}
15
+ @on = []
16
+ yield(self) if block_given?
17
+ end
18
+
19
+ def resolve(proc_or_arguments, proc=nil)
20
+ if proc.nil?
21
+ @resolve_proc = proc_or_arguments
22
+ else
23
+ @resolve_proc.call(proc_or_arguments, proc)
24
+ end
25
+ end
26
+
27
+ def arguments(new_arguments=nil)
28
+ if new_arguments.nil?
29
+ @arguments
30
+ else
31
+ @arguments = new_arguments
32
+ .reduce({}) {|memo, (k, v)| memo[k.to_s] = v; memo}
33
+ .each { |k, v| v.respond_to?("name=") && v.name = k}
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ class GraphQL::DirectiveChain
2
+ DIRECTIVE_ON = {
3
+ GraphQL::Nodes::Field => GraphQL::Directive::ON_FIELD,
4
+ GraphQL::Nodes::InlineFragment => GraphQL::Directive::ON_FRAGMENT,
5
+ GraphQL::Nodes::FragmentSpread => GraphQL::Directive::ON_FRAGMENT,
6
+ }
7
+
8
+ GET_DIRECTIVES = {
9
+ GraphQL::Nodes::Field => Proc.new { |n, f| n.directives },
10
+ GraphQL::Nodes::InlineFragment => Proc.new { |n, f| n.directives },
11
+ GraphQL::Nodes::FragmentSpread => Proc.new { |n, f| n.directives + f[n.name].directives }, # get directives from definition too
12
+ }
13
+
14
+ attr_reader :result
15
+ def initialize(ast_node, operation_resolver, &block)
16
+ directives = operation_resolver.query.schema.directives
17
+ on_what = DIRECTIVE_ON[ast_node.class]
18
+ ast_directives = GET_DIRECTIVES[ast_node.class].call(ast_node, operation_resolver.query.fragments)
19
+ applicable_directives = ast_directives
20
+ .map { |ast_directive| [ast_directive, directives[ast_directive.name]] }
21
+ .select { |directive_pair| directive_pair.last.on.include?(on_what) }
22
+
23
+ if applicable_directives.none?
24
+ @result = block.call
25
+ else
26
+ applicable_directives.map do |(ast_directive, directive)|
27
+ args = GraphQL::Query::Arguments.new(ast_directive.arguments, operation_resolver.variables).to_h
28
+ @result = directive.resolve(args, block)
29
+ end
30
+ @result ||= {}
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ GraphQL::IncludeDirective = GraphQL::Directive.new do |d|
2
+ d.name "include"
3
+ d.description "Include this part of the query if `if` is true"
4
+ d.on([GraphQL::Directive::ON_FIELD, GraphQL::Directive::ON_FRAGMENT])
5
+ d.arguments({
6
+ if: d.arg({type: !GraphQL::BOOLEAN_TYPE})
7
+ })
8
+ d.resolve -> (arguments, proc) {
9
+ if arguments["if"]
10
+ proc.call
11
+ else
12
+ nil
13
+ end
14
+ }
15
+ end
@@ -0,0 +1,15 @@
1
+ GraphQL::SkipDirective = GraphQL::Directive.new do |d|
2
+ d.name "skip"
3
+ d.description "Ignore this part of the query if `if` is true"
4
+ d.on([GraphQL::Directive::ON_FIELD, GraphQL::Directive::ON_FRAGMENT])
5
+ d.arguments({
6
+ if: d.arg({type: !GraphQL::BOOLEAN_TYPE})
7
+ })
8
+ d.resolve -> (arguments, proc) {
9
+ if !arguments["if"]
10
+ proc.call
11
+ else
12
+ nil
13
+ end
14
+ }
15
+ end
@@ -0,0 +1,34 @@
1
+ class GraphQL::Enum
2
+ include GraphQL::NonNullWithBang
3
+ extend GraphQL::Definable
4
+ attr_definable :name, :description
5
+ attr_reader :values
6
+ def initialize
7
+ @values = {}
8
+ yield(self) if block_given?
9
+ end
10
+
11
+ def value(name, description=nil, deprecation_reason: nil)
12
+ @values[name] = EnumValue.new(name: name, description: description, deprecation_reason: deprecation_reason)
13
+ end
14
+
15
+ def [](val)
16
+ @values[val]
17
+ end
18
+
19
+ def kind
20
+ GraphQL::TypeKinds::ENUM
21
+ end
22
+
23
+ class EnumValue
24
+ attr_reader :name, :description, :deprecation_reason
25
+ def initialize(name:, description:, deprecation_reason:)
26
+ @name = name
27
+ @description = description
28
+ @deprecation_reason = deprecation_reason
29
+ end
30
+ def deprecated?
31
+ !!deprecation_reason
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,37 @@
1
+ # Anything can be a Field as long as it responds to:
2
+ # - #name: String the name to access this field in a query
3
+ # - #type: Type returned by this field's resolve function
4
+ # - #description: String
5
+ # - #resolve(object, arguments, context): Object of Type `type`
6
+ # - #arguments: ???
7
+ # - #deprecation_reason
8
+ class GraphQL::AbstractField
9
+ def name
10
+ raise NotImplementedError, "#{self.class.name}#name should return the name for accessing this field"
11
+ end
12
+
13
+ def type
14
+ raise NotImplementedError, "#{self.class.name}#type should return the type class which this field returns"
15
+ end
16
+
17
+ def description
18
+ raise NotImplementedError, "#{self.class.name}#description should return this field's description"
19
+ end
20
+
21
+
22
+ def resolve(object, arguments, context)
23
+ raise NotImplementedError, "#{self.class.name}#resolve(object, arguments, context) should execute this field for object"
24
+ end
25
+
26
+ def arguments
27
+ {}
28
+ end
29
+
30
+ def deprecated?
31
+ !!deprecation_reason
32
+ end
33
+
34
+ def deprecation_reason
35
+ nil
36
+ end
37
+ end
@@ -0,0 +1,24 @@
1
+ # Implement {AbstractField} by calling the field name on its object
2
+ # and returning the result.
3
+ class GraphQL::AccessField < GraphQL::AbstractField
4
+ attr_accessor :name, :type
5
+ attr_reader :description, :arguments, :deprecation_reason
6
+ def initialize(type:, arguments:, description:, property: nil, deprecation_reason: nil)
7
+ @type = type
8
+ @arguments = arguments
9
+ @description = description
10
+ @property = property
11
+ @deprecation_reason = deprecation_reason
12
+ end
13
+
14
+ def resolve(object, args, context)
15
+ @property.nil? ? GraphQL::Query::DEFAULT_RESOLVE : object.send(@property)
16
+ end
17
+
18
+ def type
19
+ if @type.is_a?(Proc)
20
+ @type = @type.call
21
+ end
22
+ @type
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ class GraphQL::Field < GraphQL::AbstractField
2
+ extend GraphQL::Definable
3
+ REQUIRED_DEFINITIONS = [:name, :description, :type]
4
+ attr_definable(:arguments, :deprecation_reason, *REQUIRED_DEFINITIONS)
5
+
6
+ def initialize(&block)
7
+ @arguments = {}
8
+ @resolve_proc = -> (o, a, c) { GraphQL::Query::DEFAULT_RESOLVE }
9
+ yield(self) if block_given?
10
+ end
11
+
12
+ # Used when defining:
13
+ # resolve -> (obj, args, ctx) { obj.get_value }
14
+ # Also used when executing queries:
15
+ # field.resolve(obj, args, ctx)
16
+ def resolve(proc_or_object, arguments=nil, ctx=nil)
17
+ if arguments.nil? && ctx.nil?
18
+ @resolve_proc = proc_or_object
19
+ else
20
+ @resolve_proc.call(proc_or_object, arguments, ctx)
21
+ end
22
+ end
23
+
24
+ def type(type_or_proc=nil)
25
+ if type_or_proc.nil?
26
+ if @type.is_a?(Proc)
27
+ @type = @type.call
28
+ end
29
+ @type
30
+ else
31
+ @type = type_or_proc
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ class GraphQL::Interface < GraphQL::ObjectType
2
+ def kind
3
+ GraphQL::TypeKinds::INTERFACE
4
+ end
5
+
6
+ def possible_types
7
+ @possible_types ||= []
8
+ end
9
+
10
+ # Might have to override this in your own interface
11
+ def resolve_type(object)
12
+ @possible_types.find {|t| t.name == object.class.name }
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ GraphQL::ArgumentsField = GraphQL::Field.new do |f|
2
+ f.description "Arguments allowed to this object"
3
+ f.type GraphQL::ListType.new(of_type: GraphQL::InputValueType)
4
+ f.resolve -> (target, a, c) { target.arguments.values }
5
+ end
@@ -0,0 +1,12 @@
1
+ GraphQL::DirectiveType = GraphQL::ObjectType.new do
2
+ name "__Directive"
3
+ description "A query directive in this schema"
4
+ fields({
5
+ name: field(type: !type.String, desc: "The name of this directive"),
6
+ description: field(type: type.String, desc: "The description for this type"),
7
+ args: GraphQL::ArgumentsField,
8
+ onOperation: field(type: !type.Boolean, property: :on_operation?, desc: "Does this directive apply to operations?"),
9
+ onFragment: field(type: !type.Boolean, property: :on_fragment?, desc: "Does this directive apply to fragments?"),
10
+ onField: field(type: !type.Boolean, property: :on_field?, desc: "Does this directive apply to fields?"),
11
+ })
12
+ end
@@ -0,0 +1,10 @@
1
+ GraphQL::EnumValueType = GraphQL::ObjectType.new do
2
+ name "__EnumValue"
3
+ description "A possible value for an Enum"
4
+ fields({
5
+ name: field(type: !type.String),
6
+ description: field(type: !type.String),
7
+ deprecationReason: field(type: !type.String, property: :deprecation_reason),
8
+ isDeprecated: field(type: !type.Boolean, property: :deprecated?),
9
+ })
10
+ end
@@ -0,0 +1,15 @@
1
+ GraphQL::EnumValuesField = GraphQL::Field.new do |f|
2
+ f.description "Values for this enum"
3
+ f.type GraphQL::ListType.new(of_type: GraphQL::NonNullType.new(of_type: GraphQL::EnumValueType))
4
+ f.arguments({
5
+ includeDeprecated: {type: GraphQL::BOOLEAN_TYPE, default_value: false}
6
+ })
7
+ f.resolve -> (object, arguments, context) {
8
+ return nil if object.kind != GraphQL::TypeKinds::ENUM
9
+ fields = object.values.values
10
+ if !arguments["includeDeprecated"]
11
+ fields = fields.select {|f| !f.deprecated? }
12
+ end
13
+ fields
14
+ }
15
+ end
@@ -0,0 +1,11 @@
1
+ GraphQL::FieldType = GraphQL::ObjectType.new do
2
+ name "__Field"
3
+ description "Field on a GraphQL type"
4
+ self.fields = {
5
+ name: field(type: !type.String, desc: "The name for accessing this field"),
6
+ description: field(type: !type.String, desc: "The description of this field"),
7
+ type: field(type: !GraphQL::TypeType, desc: "The return type of this field"),
8
+ isDeprecated: field(type: !type.Boolean, property: :deprecated?, desc: "Is this field deprecated?"),
9
+ deprecationReason: field(type: type.String, property: :deprecation_reason, desc: "Why this field was deprecated"),
10
+ }
11
+ end
@@ -0,0 +1,14 @@
1
+ GraphQL::FieldsField = GraphQL::Field.new do |f|
2
+ f.description "List of fields on this object"
3
+ f.type -> { GraphQL::ListType.new(of_type: GraphQL::NonNullType.new(of_type: GraphQL::FieldType)) }
4
+ f.arguments({
5
+ includeDeprecated: {type: GraphQL::BOOLEAN_TYPE, default_value: false}
6
+ })
7
+ f.resolve -> (object, arguments, context) {
8
+ fields = object.fields.values
9
+ if !arguments["includeDeprecated"]
10
+ fields = fields.select {|f| !f.deprecated? }
11
+ end
12
+ fields
13
+ }
14
+ end
@@ -0,0 +1,12 @@
1
+ GraphQL::InputFieldsField = GraphQL::Field.new do |f|
2
+ f.name "inputFields"
3
+ f.description "fields on this input object"
4
+ f.type GraphQL::ListType.new(of_type: GraphQL::InputValueType)
5
+ f.resolve -> (target, a, c) {
6
+ if target.kind == GraphQL::TypeKinds::INPUT_OBJECT
7
+ target.input_fields.values
8
+ else
9
+ nil
10
+ end
11
+ }
12
+ end
@@ -0,0 +1,10 @@
1
+ GraphQL::InputValueType = GraphQL::ObjectType.new do
2
+ name "InputValue"
3
+ description "An input for a field or InputObject"
4
+ fields({
5
+ name: field(type: !type.String, desc: "The key for this value"),
6
+ description: field(type: type.String, desc: "What this value is used for"),
7
+ type: field(type: -> { GraphQL::TypeType }, desc: "The expected type for this value"),
8
+ defaultValue: field(type: type.String, property: :default_value, desc: "The value applied if no other value is provided")
9
+ })
10
+ end
@@ -0,0 +1,12 @@
1
+ GraphQL::OfTypeField = GraphQL::Field.new do |f|
2
+ f.name "ofType"
3
+ f.description "The modified type of this type"
4
+ f.type -> { GraphQL::TypeType }
5
+ f.resolve -> (obj, args, ctx) {
6
+ if [GraphQL::TypeKinds::LIST, GraphQL::TypeKinds::NON_NULL].include?(obj.kind)
7
+ obj.of_type
8
+ else
9
+ nil
10
+ end
11
+ }
12
+ end
@@ -0,0 +1,12 @@
1
+ GraphQL::PossibleTypesField = GraphQL::Field.new do |f|
2
+ POSSIBLE_TYPE_KINDS = [GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE]
3
+ f.description "Types which compose this Union or Interface"
4
+ f.type -> { GraphQL::ListType.new(of_type: GraphQL::TypeType) }
5
+ f.resolve -> (target, a, c) {
6
+ if POSSIBLE_TYPE_KINDS.include?(target.kind)
7
+ target.possible_types
8
+ else
9
+ nil
10
+ end
11
+ }
12
+ end
@@ -0,0 +1,32 @@
1
+ GraphQL::SchemaType = GraphQL::ObjectType.new do
2
+ name "__Schema"
3
+ description "A GraphQL schema"
4
+ fields({
5
+ types: GraphQL::Field.new { |f|
6
+ f.type !type[!GraphQL::TypeType]
7
+ f.description "Types in this schema"
8
+ f.resolve -> (obj, arg, ctx) { obj.types.values }
9
+ },
10
+ directives: GraphQL::Field.new { |f|
11
+ f.type !type[!GraphQL::DirectiveType]
12
+ f.description "Directives in this schema"
13
+ f.resolve -> (obj, arg, ctx) { obj.directives.values }
14
+ },
15
+ queryType: GraphQL::Field.new { |f|
16
+ f.type !GraphQL::TypeType
17
+ f.description "The query root of this schema"
18
+ f.resolve -> (obj, arg, ctx) { obj.query }
19
+ },
20
+ mutationType: GraphQL::Field.new { |f|
21
+ f.type GraphQL::TypeType
22
+ f.description "The mutation root of this schema"
23
+ f.resolve -> (obj, arg, ctx) { obj.mutation }
24
+ },
25
+ })
26
+ end
27
+ # type __Schema {
28
+ # types: [__Type!]!
29
+ # queryType: __Type!
30
+ # mutationType: __Type
31
+ # directives: [__Directive!]!
32
+ # }
@@ -0,0 +1,7 @@
1
+ GraphQL::TypeKindEnum = GraphQL::Enum.new do |e|
2
+ e.name "__TypeKind"
3
+ e.description "The kinds of types in this GraphQL system"
4
+ GraphQL::TypeKinds::KIND_NAMES.each do |kind_name|
5
+ e.value(kind_name)
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ GraphQL::TypeType = GraphQL::ObjectType.new do
2
+ name "__Type"
3
+ description "A type in the GraphQL schema"
4
+
5
+ self.fields = {
6
+ name: field(type: !type.String, desc: "The name of this type"),
7
+ kind: field(type: GraphQL::TypeKindEnum, desc: "The kind of this type"),
8
+ description: field(type: type.String, desc: "The description for this type"),
9
+ fields: GraphQL::FieldsField,
10
+ ofType: GraphQL::OfTypeField,
11
+ inputFields: GraphQL::InputFieldsField,
12
+ possibleTypes: GraphQL::PossibleTypesField,
13
+ enumValues: GraphQL::EnumValuesField
14
+ }
15
+ end
16
+ # type __Type {
17
+ # # OBJECT only
18
+ # interfaces: [__Type!]
19
+ #
20
+ # # ENUM only
21
+ # enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
22
+ # }