graphql 0.0.4 → 0.1.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 (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
+ # }