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.
- checksums.yaml +4 -4
- data/lib/graphql/base_type.rb +33 -5
- data/lib/graphql/boolean_type.rb +1 -0
- data/lib/graphql/compatibility/execution_specification.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -0
- data/lib/graphql/directive.rb +10 -2
- data/lib/graphql/directive/deprecated_directive.rb +1 -0
- data/lib/graphql/directive/include_directive.rb +1 -0
- data/lib/graphql/directive/skip_directive.rb +1 -0
- data/lib/graphql/enum_type.rb +1 -0
- data/lib/graphql/execution/execute.rb +1 -13
- data/lib/graphql/float_type.rb +1 -0
- data/lib/graphql/id_type.rb +1 -0
- data/lib/graphql/input_object_type.rb +12 -2
- data/lib/graphql/int_type.rb +1 -0
- data/lib/graphql/interface_type.rb +1 -0
- data/lib/graphql/introspection/directive_location_enum.rb +1 -0
- data/lib/graphql/introspection/directive_type.rb +1 -0
- data/lib/graphql/introspection/enum_value_type.rb +1 -0
- data/lib/graphql/introspection/field_type.rb +1 -0
- data/lib/graphql/introspection/input_fields_field.rb +1 -1
- data/lib/graphql/introspection/input_value_type.rb +1 -0
- data/lib/graphql/introspection/schema_type.rb +2 -0
- data/lib/graphql/introspection/type_kind_enum.rb +1 -0
- data/lib/graphql/introspection/type_type.rb +1 -0
- data/lib/graphql/list_type.rb +1 -0
- data/lib/graphql/non_null_type.rb +1 -0
- data/lib/graphql/object_type.rb +1 -0
- data/lib/graphql/query.rb +50 -13
- data/lib/graphql/query/context.rb +5 -4
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -22
- data/lib/graphql/relay/array_connection.rb +3 -1
- data/lib/graphql/relay/connection_type.rb +15 -1
- data/lib/graphql/relay/node.rb +1 -0
- data/lib/graphql/relay/page_info.rb +1 -0
- data/lib/graphql/relay/relation_connection.rb +2 -0
- data/lib/graphql/schema.rb +21 -13
- data/lib/graphql/schema/catchall_middleware.rb +2 -2
- data/lib/graphql/schema/middleware_chain.rb +71 -13
- data/lib/graphql/schema/null_mask.rb +10 -0
- data/lib/graphql/schema/printer.rb +85 -59
- data/lib/graphql/schema/rescue_middleware.rb +2 -2
- data/lib/graphql/schema/timeout_middleware.rb +2 -2
- data/lib/graphql/schema/validation.rb +1 -12
- data/lib/graphql/schema/warden.rb +48 -24
- data/lib/graphql/static_validation/literal_validator.rb +2 -2
- data/lib/graphql/string_type.rb +1 -0
- data/lib/graphql/union_type.rb +7 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +0 -19
- data/spec/graphql/directive/skip_directive_spec.rb +8 -0
- data/spec/graphql/directive_spec.rb +9 -3
- data/spec/graphql/input_object_type_spec.rb +67 -0
- data/spec/graphql/query/variables_spec.rb +1 -1
- data/spec/graphql/relay/array_connection_spec.rb +9 -0
- data/spec/graphql/relay/connection_type_spec.rb +20 -0
- data/spec/graphql/relay/node_spec.rb +6 -0
- data/spec/graphql/relay/page_info_spec.rb +4 -0
- data/spec/graphql/relay/relation_connection_spec.rb +8 -0
- data/spec/graphql/scalar_type_spec.rb +4 -0
- data/spec/graphql/schema/middleware_chain_spec.rb +27 -13
- data/spec/graphql/schema/printer_spec.rb +121 -6
- data/spec/graphql/schema/rescue_middleware_spec.rb +4 -4
- data/spec/graphql/schema/warden_spec.rb +16 -12
- data/spec/graphql/schema_spec.rb +9 -0
- data/spec/graphql/string_type_spec.rb +10 -4
- data/spec/spec_helper.rb +2 -1
- data/spec/support/star_wars_schema.rb +2 -2
- 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
|
-
|
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
|
data/lib/graphql/relay/node.rb
CHANGED
@@ -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
|
data/lib/graphql/schema.rb
CHANGED
@@ -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.
|
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, :
|
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
|
-
@
|
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
|
-
@
|
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
|
-
#
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
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
|
29
|
-
|
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
|
-
|
12
|
-
|
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
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
@@ -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
|
-
|
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
|
22
|
-
name "Root"
|
23
|
-
end
|
34
|
+
query_root = ObjectType.define(name: "Root")
|
24
35
|
schema = GraphQL::Schema.define(query: query_root)
|
25
|
-
|
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
|
-
|
31
|
-
|
32
|
-
|
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
|
-
|
35
|
-
type_definitions = types.map{ |type| print_type(type) }
|
62
|
+
printable_types = warden.types.reject(&:default_scalar?)
|
36
63
|
|
37
|
-
|
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
|
-
|
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
|
-
|
57
|
-
|
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
|
72
|
-
TypeKindPrinters::
|
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
|
-
|
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
|
112
|
-
return "(#{
|
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 <<
|
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
|
-
|
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
|
-
|
203
|
-
|
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} = #{
|
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
|
-
|
237
|
-
|
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
|
-
|
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")
|