graphql 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/base_type.rb +33 -5
  3. data/lib/graphql/boolean_type.rb +1 -0
  4. data/lib/graphql/compatibility/execution_specification.rb +1 -1
  5. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -0
  6. data/lib/graphql/directive.rb +10 -2
  7. data/lib/graphql/directive/deprecated_directive.rb +1 -0
  8. data/lib/graphql/directive/include_directive.rb +1 -0
  9. data/lib/graphql/directive/skip_directive.rb +1 -0
  10. data/lib/graphql/enum_type.rb +1 -0
  11. data/lib/graphql/execution/execute.rb +1 -13
  12. data/lib/graphql/float_type.rb +1 -0
  13. data/lib/graphql/id_type.rb +1 -0
  14. data/lib/graphql/input_object_type.rb +12 -2
  15. data/lib/graphql/int_type.rb +1 -0
  16. data/lib/graphql/interface_type.rb +1 -0
  17. data/lib/graphql/introspection/directive_location_enum.rb +1 -0
  18. data/lib/graphql/introspection/directive_type.rb +1 -0
  19. data/lib/graphql/introspection/enum_value_type.rb +1 -0
  20. data/lib/graphql/introspection/field_type.rb +1 -0
  21. data/lib/graphql/introspection/input_fields_field.rb +1 -1
  22. data/lib/graphql/introspection/input_value_type.rb +1 -0
  23. data/lib/graphql/introspection/schema_type.rb +2 -0
  24. data/lib/graphql/introspection/type_kind_enum.rb +1 -0
  25. data/lib/graphql/introspection/type_type.rb +1 -0
  26. data/lib/graphql/list_type.rb +1 -0
  27. data/lib/graphql/non_null_type.rb +1 -0
  28. data/lib/graphql/object_type.rb +1 -0
  29. data/lib/graphql/query.rb +50 -13
  30. data/lib/graphql/query/context.rb +5 -4
  31. data/lib/graphql/query/serial_execution/field_resolution.rb +1 -22
  32. data/lib/graphql/relay/array_connection.rb +3 -1
  33. data/lib/graphql/relay/connection_type.rb +15 -1
  34. data/lib/graphql/relay/node.rb +1 -0
  35. data/lib/graphql/relay/page_info.rb +1 -0
  36. data/lib/graphql/relay/relation_connection.rb +2 -0
  37. data/lib/graphql/schema.rb +21 -13
  38. data/lib/graphql/schema/catchall_middleware.rb +2 -2
  39. data/lib/graphql/schema/middleware_chain.rb +71 -13
  40. data/lib/graphql/schema/null_mask.rb +10 -0
  41. data/lib/graphql/schema/printer.rb +85 -59
  42. data/lib/graphql/schema/rescue_middleware.rb +2 -2
  43. data/lib/graphql/schema/timeout_middleware.rb +2 -2
  44. data/lib/graphql/schema/validation.rb +1 -12
  45. data/lib/graphql/schema/warden.rb +48 -24
  46. data/lib/graphql/static_validation/literal_validator.rb +2 -2
  47. data/lib/graphql/string_type.rb +1 -0
  48. data/lib/graphql/union_type.rb +7 -1
  49. data/lib/graphql/version.rb +1 -1
  50. data/readme.md +0 -19
  51. data/spec/graphql/directive/skip_directive_spec.rb +8 -0
  52. data/spec/graphql/directive_spec.rb +9 -3
  53. data/spec/graphql/input_object_type_spec.rb +67 -0
  54. data/spec/graphql/query/variables_spec.rb +1 -1
  55. data/spec/graphql/relay/array_connection_spec.rb +9 -0
  56. data/spec/graphql/relay/connection_type_spec.rb +20 -0
  57. data/spec/graphql/relay/node_spec.rb +6 -0
  58. data/spec/graphql/relay/page_info_spec.rb +4 -0
  59. data/spec/graphql/relay/relation_connection_spec.rb +8 -0
  60. data/spec/graphql/scalar_type_spec.rb +4 -0
  61. data/spec/graphql/schema/middleware_chain_spec.rb +27 -13
  62. data/spec/graphql/schema/printer_spec.rb +121 -6
  63. data/spec/graphql/schema/rescue_middleware_spec.rb +4 -4
  64. data/spec/graphql/schema/warden_spec.rb +16 -12
  65. data/spec/graphql/schema_spec.rb +9 -0
  66. data/spec/graphql/string_type_spec.rb +10 -4
  67. data/spec/spec_helper.rb +2 -1
  68. data/spec/support/star_wars_schema.rb +2 -2
  69. metadata +19 -2
@@ -77,33 +77,12 @@ module GraphQL
77
77
  # If the middleware chain returns a GraphQL::ExecutionError, its message
78
78
  # is added to the "errors" key.
79
79
  def get_raw_value
80
- middlewares = @query.schema.middleware
81
-
82
- resolve_arguments = [parent_type, target, field, arguments, @field_ctx]
83
-
84
80
  begin
85
- # only run a middleware chain if there are any middleware
86
- if middlewares.any?
87
- chain = GraphQL::Schema::MiddlewareChain.new(
88
- steps: middlewares + [FieldResolveStep],
89
- arguments: resolve_arguments
90
- )
91
- chain.call
92
- else
93
- FieldResolveStep.call(*resolve_arguments)
94
- end
81
+ @field_ctx.schema.middleware.invoke([parent_type, target, field, arguments, @field_ctx])
95
82
  rescue GraphQL::ExecutionError => err
96
83
  err
97
84
  end
98
85
  end
99
-
100
- # A `.call`-able suitable to be the last step in a middleware chain
101
- module FieldResolveStep
102
- # Execute the field's resolve method
103
- def self.call(_parent_type, parent_object, field_definition, field_args, context, _next = nil)
104
- field_definition.resolve(parent_object, field_args, context)
105
- end
106
- end
107
86
  end
108
87
  end
109
88
  end
@@ -32,7 +32,7 @@ module GraphQL
32
32
 
33
33
  # Apply cursors to edges
34
34
  def sliced_nodes
35
- @sliced_nodes ||= nodes[starting_offset..-1]
35
+ @sliced_nodes ||= nodes[starting_offset..-1] || []
36
36
  end
37
37
 
38
38
  def index_from_cursor(cursor)
@@ -42,6 +42,8 @@ module GraphQL
42
42
  def starting_offset
43
43
  @starting_offset = if before
44
44
  [previous_offset, 0].max
45
+ elsif last
46
+ nodes.count - last
45
47
  else
46
48
  previous_offset
47
49
  end
@@ -2,8 +2,14 @@
2
2
  module GraphQL
3
3
  module Relay
4
4
  module ConnectionType
5
+ class << self
6
+ attr_accessor :default_nodes_field
7
+ end
8
+
9
+ self.default_nodes_field = false
10
+
5
11
  # Create a connection which exposes edges of this type
6
- def self.create_type(wrapped_type, edge_type: nil, edge_class: nil, &block)
12
+ def self.create_type(wrapped_type, edge_type: nil, edge_class: nil, nodes_field: ConnectionType.default_nodes_field, &block)
7
13
  edge_type ||= wrapped_type.edge_type
8
14
  edge_class ||= GraphQL::Relay::Edge
9
15
  connection_type_name = "#{wrapped_type.name}Connection"
@@ -16,6 +22,14 @@ module GraphQL
16
22
  obj.edge_nodes.map { |item| edge_class.new(item, obj) }
17
23
  }
18
24
  end
25
+ if nodes_field
26
+ field :nodes, types[wrapped_type] do
27
+ description "A list of nodes."
28
+ resolve ->(obj, args, ctx) {
29
+ obj.edge_nodes
30
+ }
31
+ end
32
+ end
19
33
  field :pageInfo, !PageInfo, "Information to aid in pagination.", property: :page_info
20
34
  block && instance_eval(&block)
21
35
  end
@@ -23,6 +23,7 @@ module GraphQL
23
23
  name "Node"
24
24
  description "An object with an ID."
25
25
  field :id, !types.ID, "ID of the object."
26
+ default_relay true
26
27
  end
27
28
  end
28
29
 
@@ -9,6 +9,7 @@ module GraphQL
9
9
  field :hasPreviousPage, !types.Boolean, "Indicates if there are any pages prior to the current page", property: :has_previous_page
10
10
  field :startCursor, types.String, "When paginating backwards, the cursor to continue", property: :start_cursor
11
11
  field :endCursor, types.String, "When paginating forwards, the cursor to continue", property: :end_cursor
12
+ default_relay true
12
13
  end
13
14
  end
14
15
  end
@@ -44,6 +44,8 @@ module GraphQL
44
44
  @starting_offset ||= begin
45
45
  if before
46
46
  [previous_offset, 0].max
47
+ elsif last
48
+ nodes.count - last
47
49
  else
48
50
  previous_offset
49
51
  end
@@ -5,6 +5,7 @@ require "graphql/schema/default_type_error"
5
5
  require "graphql/schema/invalid_type_error"
6
6
  require "graphql/schema/instrumented_field_map"
7
7
  require "graphql/schema/middleware_chain"
8
+ require "graphql/schema/null_mask"
8
9
  require "graphql/schema/possible_types"
9
10
  require "graphql/schema/rescue_middleware"
10
11
  require "graphql/schema/reduce_types"
@@ -56,11 +57,12 @@ module GraphQL
56
57
  :max_depth, :max_complexity,
57
58
  :orphan_types, :resolve_type, :type_error,
58
59
  :object_from_id, :id_from_object,
60
+ :default_mask,
59
61
  :cursor_encoder,
60
62
  directives: ->(schema, directives) { schema.directives = directives.reduce({}) { |m, d| m[d.name] = d; m }},
61
63
  instrument: -> (schema, type, instrumenter) { schema.instrumenters[type] << instrumenter },
62
64
  query_analyzer: ->(schema, analyzer) { schema.query_analyzers << analyzer },
63
- middleware: ->(schema, middleware) { schema.user_middleware << middleware },
65
+ middleware: ->(schema, middleware) { schema.middleware << middleware },
64
66
  lazy_resolve: ->(schema, lazy_class, lazy_value_method) { schema.lazy_methods.set(lazy_class, lazy_value_method) },
65
67
  rescue_from: ->(schema, err_class, &block) { schema.rescue_from(err_class, &block)}
66
68
 
@@ -69,9 +71,16 @@ module GraphQL
69
71
  :query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
70
72
  :max_depth, :max_complexity,
71
73
  :orphan_types, :directives,
72
- :query_analyzers, :user_middleware, :instrumenters, :lazy_methods,
74
+ :query_analyzers, :instrumenters, :lazy_methods,
73
75
  :cursor_encoder
74
76
 
77
+ # @return [MiddlewareChain] MiddlewareChain which is applied to fields during execution
78
+ attr_accessor :middleware
79
+
80
+ # @return [<#call(member, ctx)>] A callable for filtering members of the schema
81
+ # @see {Query.new} for query-specific filters with `except:`
82
+ attr_accessor :default_mask
83
+
75
84
  class << self
76
85
  attr_accessor :default_execution_strategy
77
86
  end
@@ -88,7 +97,7 @@ module GraphQL
88
97
  @orphan_types = []
89
98
  @directives = DIRECTIVES.reduce({}) { |m, d| m[d.name] = d; m }
90
99
  @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
91
- @user_middleware = []
100
+ @middleware = MiddlewareChain.new(final_step: GraphQL::Execution::Execute::FieldResolveStep)
92
101
  @query_analyzers = []
93
102
  @resolve_type_proc = nil
94
103
  @object_from_id_proc = nil
@@ -101,6 +110,7 @@ module GraphQL
101
110
  @query_execution_strategy = self.class.default_execution_strategy
102
111
  @mutation_execution_strategy = self.class.default_execution_strategy
103
112
  @subscription_execution_strategy = self.class.default_execution_strategy
113
+ @default_mask = GraphQL::Schema::NullMask
104
114
  end
105
115
 
106
116
  def initialize_copy(other)
@@ -108,8 +118,7 @@ module GraphQL
108
118
  @orphan_types = other.orphan_types.dup
109
119
  @directives = other.directives.dup
110
120
  @static_validator = GraphQL::StaticValidation::Validator.new(schema: self)
111
- @user_middleware = other.user_middleware.dup
112
- @middleware = nil
121
+ @middleware = other.middleware.dup
113
122
  @query_analyzers = other.query_analyzers.dup
114
123
 
115
124
  @possible_types = GraphQL::Schema::PossibleTypes.new(self)
@@ -349,13 +358,12 @@ module GraphQL
349
358
  !!lazy_method_name(obj)
350
359
  end
351
360
 
352
- # @return [Array<#call>] Middlewares suitable for MiddlewareChain, applied to fields during execution
353
- def middleware
354
- @middleware ||= if @rescue_middleware
355
- [@rescue_middleware].concat(@user_middleware)
356
- else
357
- @user_middleware
358
- end
361
+ # Return a GraphQL schema string for the defined types in the schema
362
+ # @param context [Hash]
363
+ # @param only [<#call(member, ctx)>]
364
+ # @param except [<#call(member, ctx)>]
365
+ def to_definition(only: nil, except: nil, context: {})
366
+ GraphQL::Schema::Printer.print_schema(self, only: only, except: except, context: context)
359
367
  end
360
368
 
361
369
  protected
@@ -367,7 +375,7 @@ module GraphQL
367
375
  # Lazily create a middleware and add it to the schema
368
376
  # (Don't add it if it's not used)
369
377
  def rescue_middleware
370
- @rescue_middleware ||= GraphQL::Schema::RescueMiddleware.new
378
+ @rescue_middleware ||= GraphQL::Schema::RescueMiddleware.new.tap { |m| middleware.insert(0, m) }
371
379
  end
372
380
 
373
381
  private
@@ -25,8 +25,8 @@ module GraphQL
25
25
 
26
26
  # Rescue any error and replace it with a {GraphQL::ExecutionError}
27
27
  # whose message is {MESSAGE}
28
- def self.call(parent_type, parent_object, field_definition, field_args, query_context, next_middleware)
29
- next_middleware.call
28
+ def self.call(parent_type, parent_object, field_definition, field_args, query_context)
29
+ yield
30
30
  rescue StandardError => err
31
31
  GraphQL::ExecutionError.new(MESSAGE)
32
32
  end
@@ -5,24 +5,82 @@ module GraphQL
5
5
  #
6
6
  # Steps should call `next_step.call` to continue the chain, or _not_ call it to stop the chain.
7
7
  class MiddlewareChain
8
+ extend Forwardable
9
+
8
10
  # @return [Array<#call(*args)>] Steps in this chain, will be called with arguments and `next_middleware`
9
- attr_reader :steps
11
+ attr_reader :steps, :final_step
12
+
13
+ def initialize(steps: [], final_step: nil)
14
+ @steps = steps
15
+ @final_step = final_step
16
+ end
17
+
18
+ def initialize_copy(other)
19
+ super
20
+ @steps = other.steps.dup
21
+ end
22
+
23
+ def_delegators :@steps, :[], :first, :insert, :delete
10
24
 
11
- # @return [Array] Arguments passed to steps (followed by `next_middleware`)
12
- attr_reader :arguments
25
+ def <<(callable)
26
+ add_middleware(callable)
27
+ end
28
+
29
+ def push(callable)
30
+ add_middleware(callable)
31
+ end
32
+
33
+ def ==(other)
34
+ steps == other.steps && final_step == other.final_step
35
+ end
36
+
37
+ def invoke(arguments)
38
+ invoke_core(0, arguments)
39
+ end
40
+
41
+ private
42
+
43
+ def invoke_core(index, arguments)
44
+ if index >= steps.length
45
+ final_step.call(*arguments)
46
+ else
47
+ steps[index].call(*arguments) { |next_args = arguments| invoke_core(index + 1, next_args) }
48
+ end
49
+ end
50
+
51
+ def add_middleware(callable)
52
+ # TODO: Stop wrapping callables once deprecated middleware becomes unsupported
53
+ steps << wrap(callable)
54
+ end
55
+
56
+ # TODO: Remove this code once deprecated middleware becomes unsupported
57
+ class MiddlewareWrapper
58
+ attr_reader :callable
59
+ def initialize(callable)
60
+ @callable = callable
61
+ end
62
+
63
+ def call(*args, &next_middleware)
64
+ callable.call(*args, next_middleware)
65
+ end
66
+ end
13
67
 
14
- def initialize(steps:, arguments:)
15
- # We're gonna destroy this array, so copy it:
16
- @steps = steps.dup
17
- @arguments = arguments
68
+ def wrap(callable)
69
+ if get_arity(callable) == 6
70
+ warn("Middleware that takes a next_middleware parameter is deprecated (#{callable.inspect}); instead, accept a block and use yield.")
71
+ MiddlewareWrapper.new(callable)
72
+ else
73
+ callable
74
+ end
18
75
  end
19
76
 
20
- # Run the next step in the chain, passing in arguments and handle to the next step
21
- def call(next_arguments = @arguments)
22
- @arguments = next_arguments
23
- next_step = steps.shift
24
- next_middleware = self
25
- next_step.call(*arguments, next_middleware)
77
+ def get_arity(callable)
78
+ case callable
79
+ when Proc, Method
80
+ callable.arity
81
+ else
82
+ callable.method(:call).arity
83
+ end
26
84
  end
27
85
  end
28
86
  end
@@ -0,0 +1,10 @@
1
+ module GraphQL
2
+ class Schema
3
+ # @api private
4
+ module NullMask
5
+ def self.call(member, ctx)
6
+ false
7
+ end
8
+ end
9
+ end
10
+ end
@@ -11,35 +11,66 @@ module GraphQL
11
11
  extend self
12
12
 
13
13
  # Return a GraphQL schema string for the defined types in the schema
14
+ # @param context [Hash]
15
+ # @param only [<#call(member, ctx)>]
16
+ # @param except [<#call(member, ctx)>]
14
17
  # @param schema [GraphQL::Schema]
15
- def print_schema(schema)
16
- print_filtered_schema(schema, lambda { |n| !is_spec_directive(n) }, method(:is_defined_type))
18
+ def print_schema(schema, context: nil, only: nil, except: nil)
19
+ blacklist = if only
20
+ ->(m, ctx) { !(IS_USER_DEFINED_MEMBER.call(m) && only.call(m, ctx)) }
21
+ elsif except
22
+ ->(m, ctx) { !IS_USER_DEFINED_MEMBER.call(m) || except.call(m, ctx) }
23
+ else
24
+ ->(m, ctx) { !IS_USER_DEFINED_MEMBER.call(m) }
25
+ end
26
+
27
+ warden = GraphQL::Schema::Warden.new(blacklist, schema: schema, context: context)
28
+
29
+ print_filtered_schema(schema, warden: warden)
17
30
  end
18
31
 
19
32
  # Return the GraphQL schema string for the introspection type system
20
33
  def print_introspection_schema
21
- query_root = ObjectType.define do
22
- name "Root"
23
- end
34
+ query_root = ObjectType.define(name: "Root")
24
35
  schema = GraphQL::Schema.define(query: query_root)
25
- print_filtered_schema(schema, method(:is_spec_directive), method(:is_introspection_type))
36
+ blacklist = ->(m, ctx) { m == query_root }
37
+
38
+ warden = GraphQL::Schema::Warden.new(blacklist, schema: schema, context: nil)
39
+
40
+ print_filtered_schema(schema, warden: warden)
26
41
  end
27
42
 
28
43
  private
29
44
 
30
- def print_filtered_schema(schema, directive_filter, type_filter)
31
- directives = schema.directives.values.select{ |directive| directive_filter.call(directive) }
32
- directive_definitions = directives.map{ |directive| print_directive(directive) }
45
+ # By default, these are included in a schema printout
46
+ IS_USER_DEFINED_MEMBER = ->(member) {
47
+ case member
48
+ when GraphQL::BaseType
49
+ !member.introspection?
50
+ when GraphQL::Directive
51
+ !member.default_directive?
52
+ else
53
+ true
54
+ end
55
+ }
56
+
57
+ private_constant :IS_USER_DEFINED_MEMBER
58
+
59
+ def print_filtered_schema(schema, warden:)
60
+ directive_definitions = warden.directives.map { |directive| print_directive(warden, directive) }
33
61
 
34
- types = schema.types.values.select{ |type| type_filter.call(type) }.sort_by(&:name)
35
- type_definitions = types.map{ |type| print_type(type) }
62
+ printable_types = warden.types.reject(&:default_scalar?)
36
63
 
37
- [print_schema_definition(schema)].compact
64
+ type_definitions = printable_types
65
+ .sort_by(&:name)
66
+ .map { |type| print_type(warden, type) }
67
+
68
+ [print_schema_definition(warden, schema)].compact
38
69
  .concat(directive_definitions)
39
70
  .concat(type_definitions).join("\n\n")
40
71
  end
41
72
 
42
- def print_schema_definition(schema)
73
+ def print_schema_definition(warden, schema)
43
74
  if (schema.query.nil? || schema.query.name == 'Query') &&
44
75
  (schema.mutation.nil? || schema.mutation.name == 'Mutation') &&
45
76
  (schema.subscription.nil? || schema.subscription.name == 'Subscription')
@@ -48,32 +79,22 @@ module GraphQL
48
79
 
49
80
  operations = [:query, :mutation, :subscription].map do |operation_type|
50
81
  object_type = schema.public_send(operation_type)
51
- " #{operation_type}: #{object_type.name}\n" if object_type
82
+ # Special treatment for the introspection schema, which prints `{ query: "Root" }`
83
+ if object_type && (warden.get_type(object_type.name) || (object_type.name == "Root" && schema.query == object_type))
84
+ " #{operation_type}: #{object_type.name}\n"
85
+ else
86
+ nil
87
+ end
52
88
  end.compact.join
53
89
  "schema {\n#{operations}}"
54
90
  end
55
91
 
56
- BUILTIN_SCALARS = Set.new(["String", "Boolean", "Int", "Float", "ID"])
57
- private_constant :BUILTIN_SCALARS
58
-
59
- def is_spec_directive(directive)
60
- ['skip', 'include', 'deprecated'].include?(directive.name)
61
- end
62
-
63
- def is_introspection_type(type)
64
- type.name.start_with?("__")
65
- end
66
-
67
- def is_defined_type(type)
68
- !is_introspection_type(type) && !BUILTIN_SCALARS.include?(type.name)
92
+ def print_type(warden, type)
93
+ TypeKindPrinters::STRATEGIES.fetch(type.kind).print(warden, type)
69
94
  end
70
95
 
71
- def print_type(type)
72
- TypeKindPrinters::STRATEGIES.fetch(type.kind).print(type)
73
- end
74
-
75
- def print_directive(directive)
76
- TypeKindPrinters::DirectivePrinter.print(directive)
96
+ def print_directive(warden, directive)
97
+ TypeKindPrinters::DirectivePrinter.print(warden, directive)
77
98
  end
78
99
 
79
100
  module TypeKindPrinters
@@ -103,17 +124,16 @@ module GraphQL
103
124
 
104
125
  module ArgsPrinter
105
126
  include DescriptionPrinter
106
- def print_args(field, indentation = '')
107
- return if field.arguments.empty?
108
-
109
- field_arguments = field.arguments.values
127
+ def print_args(warden, field, indentation = '')
128
+ arguments = warden.arguments(field)
129
+ return if arguments.empty?
110
130
 
111
- if field_arguments.all?{ |arg| !arg.description }
112
- return "(#{field_arguments.map{ |arg| print_input_value(arg) }.join(", ")})"
131
+ if arguments.all?{ |arg| !arg.description }
132
+ return "(#{arguments.map{ |arg| print_input_value(arg) }.join(", ")})"
113
133
  end
114
134
 
115
135
  out = "(\n".dup
116
- out << field_arguments.map.with_index{ |arg, i|
136
+ out << arguments.map.with_index{ |arg, i|
117
137
  "#{print_description(arg, " #{indentation}", i == 0)} #{indentation}"\
118
138
  "#{print_input_value(arg)}"
119
139
  }.join("\n")
@@ -169,10 +189,11 @@ module GraphQL
169
189
  include DeprecatedPrinter
170
190
  include ArgsPrinter
171
191
  include DescriptionPrinter
172
- def print_fields(type)
173
- type.all_fields.map.with_index { |field, i|
192
+ def print_fields(warden, type)
193
+ fields = warden.fields(type)
194
+ fields.map.with_index { |field, i|
174
195
  "#{print_description(field, ' ', i == 0)}"\
175
- " #{field.name}#{print_args(field, ' ')}: #{field.type}#{print_deprecated(field)}"
196
+ " #{field.name}#{print_args(warden, field, ' ')}: #{field.type}#{print_deprecated(field)}"
176
197
  }.join("\n")
177
198
  end
178
199
  end
@@ -180,16 +201,16 @@ module GraphQL
180
201
  class DirectivePrinter
181
202
  extend ArgsPrinter
182
203
  extend DescriptionPrinter
183
- def self.print(directive)
204
+ def self.print(warden, directive)
184
205
  "#{print_description(directive)}"\
185
- "directive @#{directive.name}#{print_args(directive)} "\
206
+ "directive @#{directive.name}#{print_args(warden, directive)} "\
186
207
  "on #{directive.locations.join(' | ')}"
187
208
  end
188
209
  end
189
210
 
190
211
  class ScalarPrinter
191
212
  extend DescriptionPrinter
192
- def self.print(type)
213
+ def self.print(warden, type)
193
214
  "#{print_description(type)}"\
194
215
  "scalar #{type.name}"
195
216
  end
@@ -198,16 +219,17 @@ module GraphQL
198
219
  class ObjectPrinter
199
220
  extend FieldPrinter
200
221
  extend DescriptionPrinter
201
- def self.print(type)
202
- if type.interfaces.any?
203
- implementations = " implements #{type.interfaces.map(&:to_s).join(", ")}"
222
+ def self.print(warden, type)
223
+ interfaces = warden.interfaces(type)
224
+ if interfaces.any?
225
+ implementations = " implements #{interfaces.map(&:to_s).join(", ")}"
204
226
  else
205
227
  implementations = nil
206
228
  end
207
229
 
208
230
  "#{print_description(type)}"\
209
231
  "type #{type.name}#{implementations} {\n"\
210
- "#{print_fields(type)}\n"\
232
+ "#{print_fields(warden, type)}\n"\
211
233
  "}"
212
234
  end
213
235
  end
@@ -215,29 +237,32 @@ module GraphQL
215
237
  class InterfacePrinter
216
238
  extend FieldPrinter
217
239
  extend DescriptionPrinter
218
- def self.print(type)
240
+ def self.print(warden, type)
219
241
  "#{print_description(type)}"\
220
- "interface #{type.name} {\n#{print_fields(type)}\n}"
242
+ "interface #{type.name} {\n#{print_fields(warden, type)}\n}"
221
243
  end
222
244
  end
223
245
 
224
246
  class UnionPrinter
225
247
  extend DescriptionPrinter
226
- def self.print(type)
248
+ def self.print(warden, type)
249
+ possible_types = warden.possible_types(type)
227
250
  "#{print_description(type)}"\
228
- "union #{type.name} = #{type.possible_types.map(&:to_s).join(" | ")}"
251
+ "union #{type.name} = #{possible_types.map(&:to_s).join(" | ")}"
229
252
  end
230
253
  end
231
254
 
232
255
  class EnumPrinter
233
256
  extend DeprecatedPrinter
234
257
  extend DescriptionPrinter
235
- def self.print(type)
236
- values = type.values.values.map{ |v| " #{v.name}#{print_deprecated(v)}" }.join("\n")
237
- values = type.values.values.map.with_index { |v, i|
258
+ def self.print(warden, type)
259
+ enum_values = warden.enum_values(type)
260
+
261
+ values = enum_values.map.with_index { |v, i|
238
262
  "#{print_description(v, ' ', i == 0)}"\
239
263
  " #{v.name}#{print_deprecated(v)}"
240
264
  }.join("\n")
265
+
241
266
  "#{print_description(type)}"\
242
267
  "enum #{type.name} {\n#{values}\n}"
243
268
  end
@@ -246,8 +271,9 @@ module GraphQL
246
271
  class InputObjectPrinter
247
272
  extend FieldPrinter
248
273
  extend DescriptionPrinter
249
- def self.print(type)
250
- fields = type.input_fields.values.map.with_index{ |field, i|
274
+ def self.print(warden, type)
275
+ arguments = warden.arguments(type)
276
+ fields = arguments.map.with_index{ |field, i|
251
277
  "#{print_description(field, " ", i == 0)}"\
252
278
  " #{print_input_value(field)}"
253
279
  }.join("\n")