graphql 1.3.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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")
|