graphql 1.3.0 → 1.4.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 (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")